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"
31 #include "qemu/qemu-print.h"
33 #include "hw/semihosting/semihost.h"
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
38 #include "trace-tcg.h"
42 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
43 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
44 /* currently all emulated v5 cores are also v5TE, so don't bother */
45 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
46 #define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
47 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
48 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
49 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
50 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
51 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
53 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
55 #include "translate.h"
57 #if defined(CONFIG_USER_ONLY)
60 #define IS_USER(s) (s->user)
63 /* We reuse the same 64-bit temporaries for efficiency. */
64 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
65 static TCGv_i32 cpu_R
[16];
66 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
67 TCGv_i64 cpu_exclusive_addr
;
68 TCGv_i64 cpu_exclusive_val
;
70 /* FIXME: These should be removed. */
71 static TCGv_i32 cpu_F0s
, cpu_F1s
;
72 static TCGv_i64 cpu_F0d
, cpu_F1d
;
74 #include "exec/gen-icount.h"
76 static const char * const regnames
[] =
77 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
78 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
80 /* Function prototypes for gen_ functions calling Neon helpers. */
81 typedef void NeonGenThreeOpEnvFn(TCGv_i32
, TCGv_env
, TCGv_i32
,
84 /* initialize TCG globals. */
85 void arm_translate_init(void)
89 for (i
= 0; i
< 16; i
++) {
90 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
91 offsetof(CPUARMState
, regs
[i
]),
94 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
95 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
96 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
97 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
99 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
100 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
101 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
102 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
104 a64_translate_init();
107 /* Flags for the disas_set_da_iss info argument:
108 * lower bits hold the Rt register number, higher bits are flags.
110 typedef enum ISSInfo
{
113 ISSInvalid
= (1 << 5),
114 ISSIsAcqRel
= (1 << 6),
115 ISSIsWrite
= (1 << 7),
116 ISSIs16Bit
= (1 << 8),
119 /* Save the syndrome information for a Data Abort */
120 static void disas_set_da_iss(DisasContext
*s
, TCGMemOp memop
, ISSInfo issinfo
)
123 int sas
= memop
& MO_SIZE
;
124 bool sse
= memop
& MO_SIGN
;
125 bool is_acqrel
= issinfo
& ISSIsAcqRel
;
126 bool is_write
= issinfo
& ISSIsWrite
;
127 bool is_16bit
= issinfo
& ISSIs16Bit
;
128 int srt
= issinfo
& ISSRegMask
;
130 if (issinfo
& ISSInvalid
) {
131 /* Some callsites want to conditionally provide ISS info,
132 * eg "only if this was not a writeback"
138 /* For AArch32, insns where the src/dest is R15 never generate
139 * ISS information. Catching that here saves checking at all
145 syn
= syn_data_abort_with_iss(0, sas
, sse
, srt
, 0, is_acqrel
,
146 0, 0, 0, is_write
, 0, is_16bit
);
147 disas_set_insn_syndrome(s
, syn
);
150 static inline int get_a32_user_mem_index(DisasContext
*s
)
152 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
154 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
155 * otherwise, access as if at PL0.
157 switch (s
->mmu_idx
) {
158 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
159 case ARMMMUIdx_S12NSE0
:
160 case ARMMMUIdx_S12NSE1
:
161 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0
);
163 case ARMMMUIdx_S1SE0
:
164 case ARMMMUIdx_S1SE1
:
165 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0
);
166 case ARMMMUIdx_MUser
:
167 case ARMMMUIdx_MPriv
:
168 return arm_to_core_mmu_idx(ARMMMUIdx_MUser
);
169 case ARMMMUIdx_MUserNegPri
:
170 case ARMMMUIdx_MPrivNegPri
:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri
);
172 case ARMMMUIdx_MSUser
:
173 case ARMMMUIdx_MSPriv
:
174 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser
);
175 case ARMMMUIdx_MSUserNegPri
:
176 case ARMMMUIdx_MSPrivNegPri
:
177 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri
);
180 g_assert_not_reached();
184 static inline TCGv_i32
load_cpu_offset(int offset
)
186 TCGv_i32 tmp
= tcg_temp_new_i32();
187 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
191 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
193 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
195 tcg_gen_st_i32(var
, cpu_env
, offset
);
196 tcg_temp_free_i32(var
);
199 #define store_cpu_field(var, name) \
200 store_cpu_offset(var, offsetof(CPUARMState, name))
202 /* Set a variable to the value of a CPU register. */
203 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
207 /* normally, since we updated PC, we need only to add one insn */
209 addr
= (long)s
->pc
+ 2;
211 addr
= (long)s
->pc
+ 4;
212 tcg_gen_movi_i32(var
, addr
);
214 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
218 /* Create a new temporary and set it to the value of a CPU register. */
219 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
221 TCGv_i32 tmp
= tcg_temp_new_i32();
222 load_reg_var(s
, tmp
, reg
);
226 /* Set a CPU register. The source must be a temporary and will be
228 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
231 /* In Thumb mode, we must ignore bit 0.
232 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
233 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
234 * We choose to ignore [1:0] in ARM mode for all architecture versions.
236 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
237 s
->base
.is_jmp
= DISAS_JUMP
;
239 tcg_gen_mov_i32(cpu_R
[reg
], var
);
240 tcg_temp_free_i32(var
);
244 * Variant of store_reg which applies v8M stack-limit checks before updating
245 * SP. If the check fails this will result in an exception being taken.
246 * We disable the stack checks for CONFIG_USER_ONLY because we have
247 * no idea what the stack limits should be in that case.
248 * If stack checking is not being done this just acts like store_reg().
250 static void store_sp_checked(DisasContext
*s
, TCGv_i32 var
)
252 #ifndef CONFIG_USER_ONLY
253 if (s
->v8m_stackcheck
) {
254 gen_helper_v8m_stackcheck(cpu_env
, var
);
257 store_reg(s
, 13, var
);
260 /* Value extensions. */
261 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
262 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
263 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
264 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
266 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
267 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
270 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
272 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
273 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
274 tcg_temp_free_i32(tmp_mask
);
276 /* Set NZCV flags from the high 4 bits of var. */
277 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
279 static void gen_exception_internal(int excp
)
281 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
283 assert(excp_is_internal(excp
));
284 gen_helper_exception_internal(cpu_env
, tcg_excp
);
285 tcg_temp_free_i32(tcg_excp
);
288 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
290 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
291 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
292 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
294 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
297 tcg_temp_free_i32(tcg_el
);
298 tcg_temp_free_i32(tcg_syn
);
299 tcg_temp_free_i32(tcg_excp
);
302 static void gen_step_complete_exception(DisasContext
*s
)
304 /* We just completed step of an insn. Move from Active-not-pending
305 * to Active-pending, and then also take the swstep exception.
306 * This corresponds to making the (IMPDEF) choice to prioritize
307 * swstep exceptions over asynchronous exceptions taken to an exception
308 * level where debug is disabled. This choice has the advantage that
309 * we do not need to maintain internal state corresponding to the
310 * ISV/EX syndrome bits between completion of the step and generation
311 * of the exception, and our syndrome information is always correct.
314 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
315 default_exception_el(s
));
316 s
->base
.is_jmp
= DISAS_NORETURN
;
319 static void gen_singlestep_exception(DisasContext
*s
)
321 /* Generate the right kind of exception for singlestep, which is
322 * either the architectural singlestep or EXCP_DEBUG for QEMU's
323 * gdb singlestepping.
326 gen_step_complete_exception(s
);
328 gen_exception_internal(EXCP_DEBUG
);
332 static inline bool is_singlestepping(DisasContext
*s
)
334 /* Return true if we are singlestepping either because of
335 * architectural singlestep or QEMU gdbstub singlestep. This does
336 * not include the command line '-singlestep' mode which is rather
337 * misnamed as it only means "one instruction per TB" and doesn't
338 * affect the code we generate.
340 return s
->base
.singlestep_enabled
|| s
->ss_active
;
343 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
345 TCGv_i32 tmp1
= tcg_temp_new_i32();
346 TCGv_i32 tmp2
= tcg_temp_new_i32();
347 tcg_gen_ext16s_i32(tmp1
, a
);
348 tcg_gen_ext16s_i32(tmp2
, b
);
349 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
350 tcg_temp_free_i32(tmp2
);
351 tcg_gen_sari_i32(a
, a
, 16);
352 tcg_gen_sari_i32(b
, b
, 16);
353 tcg_gen_mul_i32(b
, b
, a
);
354 tcg_gen_mov_i32(a
, tmp1
);
355 tcg_temp_free_i32(tmp1
);
358 /* Byteswap each halfword. */
359 static void gen_rev16(TCGv_i32 var
)
361 TCGv_i32 tmp
= tcg_temp_new_i32();
362 TCGv_i32 mask
= tcg_const_i32(0x00ff00ff);
363 tcg_gen_shri_i32(tmp
, var
, 8);
364 tcg_gen_and_i32(tmp
, tmp
, mask
);
365 tcg_gen_and_i32(var
, var
, mask
);
366 tcg_gen_shli_i32(var
, var
, 8);
367 tcg_gen_or_i32(var
, var
, tmp
);
368 tcg_temp_free_i32(mask
);
369 tcg_temp_free_i32(tmp
);
372 /* Byteswap low halfword and sign extend. */
373 static void gen_revsh(TCGv_i32 var
)
375 tcg_gen_ext16u_i32(var
, var
);
376 tcg_gen_bswap16_i32(var
, var
);
377 tcg_gen_ext16s_i32(var
, var
);
380 /* Return (b << 32) + a. Mark inputs as dead */
381 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
383 TCGv_i64 tmp64
= tcg_temp_new_i64();
385 tcg_gen_extu_i32_i64(tmp64
, b
);
386 tcg_temp_free_i32(b
);
387 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
388 tcg_gen_add_i64(a
, tmp64
, a
);
390 tcg_temp_free_i64(tmp64
);
394 /* Return (b << 32) - a. Mark inputs as dead. */
395 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
397 TCGv_i64 tmp64
= tcg_temp_new_i64();
399 tcg_gen_extu_i32_i64(tmp64
, b
);
400 tcg_temp_free_i32(b
);
401 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
402 tcg_gen_sub_i64(a
, tmp64
, a
);
404 tcg_temp_free_i64(tmp64
);
408 /* 32x32->64 multiply. Marks inputs as dead. */
409 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
411 TCGv_i32 lo
= tcg_temp_new_i32();
412 TCGv_i32 hi
= tcg_temp_new_i32();
415 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
416 tcg_temp_free_i32(a
);
417 tcg_temp_free_i32(b
);
419 ret
= tcg_temp_new_i64();
420 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
421 tcg_temp_free_i32(lo
);
422 tcg_temp_free_i32(hi
);
427 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
429 TCGv_i32 lo
= tcg_temp_new_i32();
430 TCGv_i32 hi
= tcg_temp_new_i32();
433 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
434 tcg_temp_free_i32(a
);
435 tcg_temp_free_i32(b
);
437 ret
= tcg_temp_new_i64();
438 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
439 tcg_temp_free_i32(lo
);
440 tcg_temp_free_i32(hi
);
445 /* Swap low and high halfwords. */
446 static void gen_swap_half(TCGv_i32 var
)
448 TCGv_i32 tmp
= tcg_temp_new_i32();
449 tcg_gen_shri_i32(tmp
, var
, 16);
450 tcg_gen_shli_i32(var
, var
, 16);
451 tcg_gen_or_i32(var
, var
, tmp
);
452 tcg_temp_free_i32(tmp
);
455 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
456 tmp = (t0 ^ t1) & 0x8000;
459 t0 = (t0 + t1) ^ tmp;
462 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
464 TCGv_i32 tmp
= tcg_temp_new_i32();
465 tcg_gen_xor_i32(tmp
, t0
, t1
);
466 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
467 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
468 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
469 tcg_gen_add_i32(t0
, t0
, t1
);
470 tcg_gen_xor_i32(t0
, t0
, tmp
);
471 tcg_temp_free_i32(tmp
);
472 tcg_temp_free_i32(t1
);
475 /* Set CF to the top bit of var. */
476 static void gen_set_CF_bit31(TCGv_i32 var
)
478 tcg_gen_shri_i32(cpu_CF
, var
, 31);
481 /* Set N and Z flags from var. */
482 static inline void gen_logic_CC(TCGv_i32 var
)
484 tcg_gen_mov_i32(cpu_NF
, var
);
485 tcg_gen_mov_i32(cpu_ZF
, var
);
489 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
491 tcg_gen_add_i32(t0
, t0
, t1
);
492 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
495 /* dest = T0 + T1 + CF. */
496 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
498 tcg_gen_add_i32(dest
, t0
, t1
);
499 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
502 /* dest = T0 - T1 + CF - 1. */
503 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
505 tcg_gen_sub_i32(dest
, t0
, t1
);
506 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
507 tcg_gen_subi_i32(dest
, dest
, 1);
510 /* dest = T0 + T1. Compute C, N, V and Z flags */
511 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
513 TCGv_i32 tmp
= tcg_temp_new_i32();
514 tcg_gen_movi_i32(tmp
, 0);
515 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
516 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
517 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
518 tcg_gen_xor_i32(tmp
, t0
, t1
);
519 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
520 tcg_temp_free_i32(tmp
);
521 tcg_gen_mov_i32(dest
, cpu_NF
);
524 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
525 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
527 TCGv_i32 tmp
= tcg_temp_new_i32();
528 if (TCG_TARGET_HAS_add2_i32
) {
529 tcg_gen_movi_i32(tmp
, 0);
530 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
531 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
533 TCGv_i64 q0
= tcg_temp_new_i64();
534 TCGv_i64 q1
= tcg_temp_new_i64();
535 tcg_gen_extu_i32_i64(q0
, t0
);
536 tcg_gen_extu_i32_i64(q1
, t1
);
537 tcg_gen_add_i64(q0
, q0
, q1
);
538 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
539 tcg_gen_add_i64(q0
, q0
, q1
);
540 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
541 tcg_temp_free_i64(q0
);
542 tcg_temp_free_i64(q1
);
544 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
545 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
546 tcg_gen_xor_i32(tmp
, t0
, t1
);
547 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
548 tcg_temp_free_i32(tmp
);
549 tcg_gen_mov_i32(dest
, cpu_NF
);
552 /* dest = T0 - T1. Compute C, N, V and Z flags */
553 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
556 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
557 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
558 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
559 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
560 tmp
= tcg_temp_new_i32();
561 tcg_gen_xor_i32(tmp
, t0
, t1
);
562 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
563 tcg_temp_free_i32(tmp
);
564 tcg_gen_mov_i32(dest
, cpu_NF
);
567 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
568 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
570 TCGv_i32 tmp
= tcg_temp_new_i32();
571 tcg_gen_not_i32(tmp
, t1
);
572 gen_adc_CC(dest
, t0
, tmp
);
573 tcg_temp_free_i32(tmp
);
576 #define GEN_SHIFT(name) \
577 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
579 TCGv_i32 tmp1, tmp2, tmp3; \
580 tmp1 = tcg_temp_new_i32(); \
581 tcg_gen_andi_i32(tmp1, t1, 0xff); \
582 tmp2 = tcg_const_i32(0); \
583 tmp3 = tcg_const_i32(0x1f); \
584 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
585 tcg_temp_free_i32(tmp3); \
586 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
587 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
588 tcg_temp_free_i32(tmp2); \
589 tcg_temp_free_i32(tmp1); \
595 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
598 tmp1
= tcg_temp_new_i32();
599 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
600 tmp2
= tcg_const_i32(0x1f);
601 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
602 tcg_temp_free_i32(tmp2
);
603 tcg_gen_sar_i32(dest
, t0
, tmp1
);
604 tcg_temp_free_i32(tmp1
);
607 static void shifter_out_im(TCGv_i32 var
, int shift
)
610 tcg_gen_andi_i32(cpu_CF
, var
, 1);
612 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
614 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
619 /* Shift by immediate. Includes special handling for shift == 0. */
620 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
621 int shift
, int flags
)
627 shifter_out_im(var
, 32 - shift
);
628 tcg_gen_shli_i32(var
, var
, shift
);
634 tcg_gen_shri_i32(cpu_CF
, var
, 31);
636 tcg_gen_movi_i32(var
, 0);
639 shifter_out_im(var
, shift
- 1);
640 tcg_gen_shri_i32(var
, var
, shift
);
647 shifter_out_im(var
, shift
- 1);
650 tcg_gen_sari_i32(var
, var
, shift
);
652 case 3: /* ROR/RRX */
655 shifter_out_im(var
, shift
- 1);
656 tcg_gen_rotri_i32(var
, var
, shift
); break;
658 TCGv_i32 tmp
= tcg_temp_new_i32();
659 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
661 shifter_out_im(var
, 0);
662 tcg_gen_shri_i32(var
, var
, 1);
663 tcg_gen_or_i32(var
, var
, tmp
);
664 tcg_temp_free_i32(tmp
);
669 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
670 TCGv_i32 shift
, int flags
)
674 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
675 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
676 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
677 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
682 gen_shl(var
, var
, shift
);
685 gen_shr(var
, var
, shift
);
688 gen_sar(var
, var
, shift
);
690 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
691 tcg_gen_rotr_i32(var
, var
, shift
); break;
694 tcg_temp_free_i32(shift
);
697 #define PAS_OP(pfx) \
699 case 0: gen_pas_helper(glue(pfx,add16)); break; \
700 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
701 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
702 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
703 case 4: gen_pas_helper(glue(pfx,add8)); break; \
704 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
706 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
711 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
713 tmp
= tcg_temp_new_ptr();
714 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
716 tcg_temp_free_ptr(tmp
);
719 tmp
= tcg_temp_new_ptr();
720 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
722 tcg_temp_free_ptr(tmp
);
724 #undef gen_pas_helper
725 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
738 #undef gen_pas_helper
743 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
744 #define PAS_OP(pfx) \
746 case 0: gen_pas_helper(glue(pfx,add8)); break; \
747 case 1: gen_pas_helper(glue(pfx,add16)); break; \
748 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
749 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
750 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
751 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
753 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
758 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
760 tmp
= tcg_temp_new_ptr();
761 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
763 tcg_temp_free_ptr(tmp
);
766 tmp
= tcg_temp_new_ptr();
767 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
769 tcg_temp_free_ptr(tmp
);
771 #undef gen_pas_helper
772 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
785 #undef gen_pas_helper
791 * Generate a conditional based on ARM condition code cc.
792 * This is common between ARM and Aarch64 targets.
794 void arm_test_cc(DisasCompare
*cmp
, int cc
)
825 case 8: /* hi: C && !Z */
826 case 9: /* ls: !C || Z -> !(C && !Z) */
828 value
= tcg_temp_new_i32();
830 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
831 ZF is non-zero for !Z; so AND the two subexpressions. */
832 tcg_gen_neg_i32(value
, cpu_CF
);
833 tcg_gen_and_i32(value
, value
, cpu_ZF
);
836 case 10: /* ge: N == V -> N ^ V == 0 */
837 case 11: /* lt: N != V -> N ^ V != 0 */
838 /* Since we're only interested in the sign bit, == 0 is >= 0. */
840 value
= tcg_temp_new_i32();
842 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
845 case 12: /* gt: !Z && N == V */
846 case 13: /* le: Z || N != V */
848 value
= tcg_temp_new_i32();
850 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
851 * the sign bit then AND with ZF to yield the result. */
852 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
853 tcg_gen_sari_i32(value
, value
, 31);
854 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
857 case 14: /* always */
858 case 15: /* always */
859 /* Use the ALWAYS condition, which will fold early.
860 * It doesn't matter what we use for the value. */
861 cond
= TCG_COND_ALWAYS
;
866 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
871 cond
= tcg_invert_cond(cond
);
877 cmp
->value_global
= global
;
880 void arm_free_cc(DisasCompare
*cmp
)
882 if (!cmp
->value_global
) {
883 tcg_temp_free_i32(cmp
->value
);
887 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
889 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
892 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
895 arm_test_cc(&cmp
, cc
);
896 arm_jump_cc(&cmp
, label
);
900 static const uint8_t table_logic_cc
[16] = {
919 static inline void gen_set_condexec(DisasContext
*s
)
921 if (s
->condexec_mask
) {
922 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
923 TCGv_i32 tmp
= tcg_temp_new_i32();
924 tcg_gen_movi_i32(tmp
, val
);
925 store_cpu_field(tmp
, condexec_bits
);
929 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
931 tcg_gen_movi_i32(cpu_R
[15], val
);
934 /* Set PC and Thumb state from an immediate address. */
935 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
939 s
->base
.is_jmp
= DISAS_JUMP
;
940 if (s
->thumb
!= (addr
& 1)) {
941 tmp
= tcg_temp_new_i32();
942 tcg_gen_movi_i32(tmp
, addr
& 1);
943 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
944 tcg_temp_free_i32(tmp
);
946 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
949 /* Set PC and Thumb state from var. var is marked as dead. */
950 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
952 s
->base
.is_jmp
= DISAS_JUMP
;
953 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
954 tcg_gen_andi_i32(var
, var
, 1);
955 store_cpu_field(var
, thumb
);
958 /* Set PC and Thumb state from var. var is marked as dead.
959 * For M-profile CPUs, include logic to detect exception-return
960 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
961 * and BX reg, and no others, and happens only for code in Handler mode.
963 static inline void gen_bx_excret(DisasContext
*s
, TCGv_i32 var
)
965 /* Generate the same code here as for a simple bx, but flag via
966 * s->base.is_jmp that we need to do the rest of the work later.
969 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
) ||
970 (s
->v7m_handler_mode
&& arm_dc_feature(s
, ARM_FEATURE_M
))) {
971 s
->base
.is_jmp
= DISAS_BX_EXCRET
;
975 static inline void gen_bx_excret_final_code(DisasContext
*s
)
977 /* Generate the code to finish possible exception return and end the TB */
978 TCGLabel
*excret_label
= gen_new_label();
981 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
)) {
982 /* Covers FNC_RETURN and EXC_RETURN magic */
983 min_magic
= FNC_RETURN_MIN_MAGIC
;
985 /* EXC_RETURN magic only */
986 min_magic
= EXC_RETURN_MIN_MAGIC
;
989 /* Is the new PC value in the magic range indicating exception return? */
990 tcg_gen_brcondi_i32(TCG_COND_GEU
, cpu_R
[15], min_magic
, excret_label
);
991 /* No: end the TB as we would for a DISAS_JMP */
992 if (is_singlestepping(s
)) {
993 gen_singlestep_exception(s
);
995 tcg_gen_exit_tb(NULL
, 0);
997 gen_set_label(excret_label
);
998 /* Yes: this is an exception return.
999 * At this point in runtime env->regs[15] and env->thumb will hold
1000 * the exception-return magic number, which do_v7m_exception_exit()
1001 * will read. Nothing else will be able to see those values because
1002 * the cpu-exec main loop guarantees that we will always go straight
1003 * from raising the exception to the exception-handling code.
1005 * gen_ss_advance(s) does nothing on M profile currently but
1006 * calling it is conceptually the right thing as we have executed
1007 * this instruction (compare SWI, HVC, SMC handling).
1010 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
1013 static inline void gen_bxns(DisasContext
*s
, int rm
)
1015 TCGv_i32 var
= load_reg(s
, rm
);
1017 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1018 * we need to sync state before calling it, but:
1019 * - we don't need to do gen_set_pc_im() because the bxns helper will
1020 * always set the PC itself
1021 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1022 * unless it's outside an IT block or the last insn in an IT block,
1023 * so we know that condexec == 0 (already set at the top of the TB)
1024 * is correct in the non-UNPREDICTABLE cases, and we can choose
1025 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1027 gen_helper_v7m_bxns(cpu_env
, var
);
1028 tcg_temp_free_i32(var
);
1029 s
->base
.is_jmp
= DISAS_EXIT
;
1032 static inline void gen_blxns(DisasContext
*s
, int rm
)
1034 TCGv_i32 var
= load_reg(s
, rm
);
1036 /* We don't need to sync condexec state, for the same reason as bxns.
1037 * We do however need to set the PC, because the blxns helper reads it.
1038 * The blxns helper may throw an exception.
1040 gen_set_pc_im(s
, s
->pc
);
1041 gen_helper_v7m_blxns(cpu_env
, var
);
1042 tcg_temp_free_i32(var
);
1043 s
->base
.is_jmp
= DISAS_EXIT
;
1046 /* Variant of store_reg which uses branch&exchange logic when storing
1047 to r15 in ARM architecture v7 and above. The source must be a temporary
1048 and will be marked as dead. */
1049 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
1051 if (reg
== 15 && ENABLE_ARCH_7
) {
1054 store_reg(s
, reg
, var
);
1058 /* Variant of store_reg which uses branch&exchange logic when storing
1059 * to r15 in ARM architecture v5T and above. This is used for storing
1060 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1061 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1062 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
1064 if (reg
== 15 && ENABLE_ARCH_5
) {
1065 gen_bx_excret(s
, var
);
1067 store_reg(s
, reg
, var
);
1071 #ifdef CONFIG_USER_ONLY
1072 #define IS_USER_ONLY 1
1074 #define IS_USER_ONLY 0
1077 /* Abstractions of "generate code to do a guest load/store for
1078 * AArch32", where a vaddr is always 32 bits (and is zero
1079 * extended if we're a 64 bit core) and data is also
1080 * 32 bits unless specifically doing a 64 bit access.
1081 * These functions work like tcg_gen_qemu_{ld,st}* except
1082 * that the address argument is TCGv_i32 rather than TCGv.
1085 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, TCGMemOp op
)
1087 TCGv addr
= tcg_temp_new();
1088 tcg_gen_extu_i32_tl(addr
, a32
);
1090 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1091 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
1092 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
1097 static void gen_aa32_ld_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1098 int index
, TCGMemOp opc
)
1102 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
1103 !arm_dc_feature(s
, ARM_FEATURE_M_MAIN
)) {
1107 addr
= gen_aa32_addr(s
, a32
, opc
);
1108 tcg_gen_qemu_ld_i32(val
, addr
, index
, opc
);
1109 tcg_temp_free(addr
);
1112 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1113 int index
, TCGMemOp opc
)
1117 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
1118 !arm_dc_feature(s
, ARM_FEATURE_M_MAIN
)) {
1122 addr
= gen_aa32_addr(s
, a32
, opc
);
1123 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
1124 tcg_temp_free(addr
);
1127 #define DO_GEN_LD(SUFF, OPC) \
1128 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1129 TCGv_i32 a32, int index) \
1131 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1133 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1135 TCGv_i32 a32, int index, \
1138 gen_aa32_ld##SUFF(s, val, a32, index); \
1139 disas_set_da_iss(s, OPC, issinfo); \
1142 #define DO_GEN_ST(SUFF, OPC) \
1143 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1144 TCGv_i32 a32, int index) \
1146 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1148 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1150 TCGv_i32 a32, int index, \
1153 gen_aa32_st##SUFF(s, val, a32, index); \
1154 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1157 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
1159 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1160 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1161 tcg_gen_rotri_i64(val
, val
, 32);
1165 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1166 int index
, TCGMemOp opc
)
1168 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1169 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
1170 gen_aa32_frob64(s
, val
);
1171 tcg_temp_free(addr
);
1174 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1175 TCGv_i32 a32
, int index
)
1177 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1180 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1181 int index
, TCGMemOp opc
)
1183 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1185 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1186 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1187 TCGv_i64 tmp
= tcg_temp_new_i64();
1188 tcg_gen_rotri_i64(tmp
, val
, 32);
1189 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
1190 tcg_temp_free_i64(tmp
);
1192 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
1194 tcg_temp_free(addr
);
1197 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1198 TCGv_i32 a32
, int index
)
1200 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1203 DO_GEN_LD(8s
, MO_SB
)
1204 DO_GEN_LD(8u, MO_UB
)
1205 DO_GEN_LD(16s
, MO_SW
)
1206 DO_GEN_LD(16u, MO_UW
)
1207 DO_GEN_LD(32u, MO_UL
)
1209 DO_GEN_ST(16, MO_UW
)
1210 DO_GEN_ST(32, MO_UL
)
1212 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1214 /* The pre HVC helper handles cases when HVC gets trapped
1215 * as an undefined insn by runtime configuration (ie before
1216 * the insn really executes).
1218 gen_set_pc_im(s
, s
->pc
- 4);
1219 gen_helper_pre_hvc(cpu_env
);
1220 /* Otherwise we will treat this as a real exception which
1221 * happens after execution of the insn. (The distinction matters
1222 * for the PC value reported to the exception handler and also
1223 * for single stepping.)
1226 gen_set_pc_im(s
, s
->pc
);
1227 s
->base
.is_jmp
= DISAS_HVC
;
1230 static inline void gen_smc(DisasContext
*s
)
1232 /* As with HVC, we may take an exception either before or after
1233 * the insn executes.
1237 gen_set_pc_im(s
, s
->pc
- 4);
1238 tmp
= tcg_const_i32(syn_aa32_smc());
1239 gen_helper_pre_smc(cpu_env
, tmp
);
1240 tcg_temp_free_i32(tmp
);
1241 gen_set_pc_im(s
, s
->pc
);
1242 s
->base
.is_jmp
= DISAS_SMC
;
1245 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1247 gen_set_condexec(s
);
1248 gen_set_pc_im(s
, s
->pc
- offset
);
1249 gen_exception_internal(excp
);
1250 s
->base
.is_jmp
= DISAS_NORETURN
;
1253 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1254 int syn
, uint32_t target_el
)
1256 gen_set_condexec(s
);
1257 gen_set_pc_im(s
, s
->pc
- offset
);
1258 gen_exception(excp
, syn
, target_el
);
1259 s
->base
.is_jmp
= DISAS_NORETURN
;
1262 static void gen_exception_bkpt_insn(DisasContext
*s
, int offset
, uint32_t syn
)
1266 gen_set_condexec(s
);
1267 gen_set_pc_im(s
, s
->pc
- offset
);
1268 tcg_syn
= tcg_const_i32(syn
);
1269 gen_helper_exception_bkpt_insn(cpu_env
, tcg_syn
);
1270 tcg_temp_free_i32(tcg_syn
);
1271 s
->base
.is_jmp
= DISAS_NORETURN
;
1274 /* Force a TB lookup after an instruction that changes the CPU state. */
1275 static inline void gen_lookup_tb(DisasContext
*s
)
1277 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1278 s
->base
.is_jmp
= DISAS_EXIT
;
1281 static inline void gen_hlt(DisasContext
*s
, int imm
)
1283 /* HLT. This has two purposes.
1284 * Architecturally, it is an external halting debug instruction.
1285 * Since QEMU doesn't implement external debug, we treat this as
1286 * it is required for halting debug disabled: it will UNDEF.
1287 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1288 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1289 * must trigger semihosting even for ARMv7 and earlier, where
1290 * HLT was an undefined encoding.
1291 * In system mode, we don't allow userspace access to
1292 * semihosting, to provide some semblance of security
1293 * (and for consistency with our 32-bit semihosting).
1295 if (semihosting_enabled() &&
1296 #ifndef CONFIG_USER_ONLY
1297 s
->current_el
!= 0 &&
1299 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1300 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1304 gen_exception_insn(s
, s
->thumb
? 2 : 4, EXCP_UDEF
, syn_uncategorized(),
1305 default_exception_el(s
));
1308 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1311 int val
, rm
, shift
, shiftop
;
1314 if (!(insn
& (1 << 25))) {
1317 if (!(insn
& (1 << 23)))
1320 tcg_gen_addi_i32(var
, var
, val
);
1322 /* shift/register */
1324 shift
= (insn
>> 7) & 0x1f;
1325 shiftop
= (insn
>> 5) & 3;
1326 offset
= load_reg(s
, rm
);
1327 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1328 if (!(insn
& (1 << 23)))
1329 tcg_gen_sub_i32(var
, var
, offset
);
1331 tcg_gen_add_i32(var
, var
, offset
);
1332 tcg_temp_free_i32(offset
);
1336 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1337 int extra
, TCGv_i32 var
)
1342 if (insn
& (1 << 22)) {
1344 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1345 if (!(insn
& (1 << 23)))
1349 tcg_gen_addi_i32(var
, var
, val
);
1353 tcg_gen_addi_i32(var
, var
, extra
);
1355 offset
= load_reg(s
, rm
);
1356 if (!(insn
& (1 << 23)))
1357 tcg_gen_sub_i32(var
, var
, offset
);
1359 tcg_gen_add_i32(var
, var
, offset
);
1360 tcg_temp_free_i32(offset
);
1364 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1366 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1369 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1371 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1373 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1377 #define VFP_OP2(name) \
1378 static inline void gen_vfp_##name(int dp) \
1380 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1382 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1384 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1386 tcg_temp_free_ptr(fpst); \
1396 static inline void gen_vfp_F1_mul(int dp
)
1398 /* Like gen_vfp_mul() but put result in F1 */
1399 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1401 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1403 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1405 tcg_temp_free_ptr(fpst
);
1408 static inline void gen_vfp_F1_neg(int dp
)
1410 /* Like gen_vfp_neg() but put result in F1 */
1412 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1414 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1418 static inline void gen_vfp_abs(int dp
)
1421 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1423 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1426 static inline void gen_vfp_neg(int dp
)
1429 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1431 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1434 static inline void gen_vfp_sqrt(int dp
)
1437 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1439 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1442 static inline void gen_vfp_cmp(int dp
)
1445 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1447 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1450 static inline void gen_vfp_cmpe(int dp
)
1453 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1455 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1458 static inline void gen_vfp_F1_ld0(int dp
)
1461 tcg_gen_movi_i64(cpu_F1d
, 0);
1463 tcg_gen_movi_i32(cpu_F1s
, 0);
1466 #define VFP_GEN_ITOF(name) \
1467 static inline void gen_vfp_##name(int dp, int neon) \
1469 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1471 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1473 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1475 tcg_temp_free_ptr(statusptr); \
1482 #define VFP_GEN_FTOI(name) \
1483 static inline void gen_vfp_##name(int dp, int neon) \
1485 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1487 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1489 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1491 tcg_temp_free_ptr(statusptr); \
1500 #define VFP_GEN_FIX(name, round) \
1501 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1503 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1504 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1506 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1509 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1512 tcg_temp_free_i32(tmp_shift); \
1513 tcg_temp_free_ptr(statusptr); \
1515 VFP_GEN_FIX(tosh
, _round_to_zero
)
1516 VFP_GEN_FIX(tosl
, _round_to_zero
)
1517 VFP_GEN_FIX(touh
, _round_to_zero
)
1518 VFP_GEN_FIX(toul
, _round_to_zero
)
1525 static inline long vfp_reg_offset(bool dp
, unsigned reg
)
1528 return offsetof(CPUARMState
, vfp
.zregs
[reg
>> 1].d
[reg
& 1]);
1530 long ofs
= offsetof(CPUARMState
, vfp
.zregs
[reg
>> 2].d
[(reg
>> 1) & 1]);
1532 ofs
+= offsetof(CPU_DoubleU
, l
.upper
);
1534 ofs
+= offsetof(CPU_DoubleU
, l
.lower
);
1540 /* Return the offset of a 32-bit piece of a NEON register.
1541 zero is the least significant end of the register. */
1543 neon_reg_offset (int reg
, int n
)
1547 return vfp_reg_offset(0, sreg
);
1550 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1551 * where 0 is the least significant end of the register.
1554 neon_element_offset(int reg
, int element
, TCGMemOp size
)
1556 int element_size
= 1 << size
;
1557 int ofs
= element
* element_size
;
1558 #ifdef HOST_WORDS_BIGENDIAN
1559 /* Calculate the offset assuming fully little-endian,
1560 * then XOR to account for the order of the 8-byte units.
1562 if (element_size
< 8) {
1563 ofs
^= 8 - element_size
;
1566 return neon_reg_offset(reg
, 0) + ofs
;
1569 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1571 TCGv_i32 tmp
= tcg_temp_new_i32();
1572 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1576 static void neon_load_element(TCGv_i32 var
, int reg
, int ele
, TCGMemOp mop
)
1578 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1582 tcg_gen_ld8u_i32(var
, cpu_env
, offset
);
1585 tcg_gen_ld16u_i32(var
, cpu_env
, offset
);
1588 tcg_gen_ld_i32(var
, cpu_env
, offset
);
1591 g_assert_not_reached();
1595 static void neon_load_element64(TCGv_i64 var
, int reg
, int ele
, TCGMemOp mop
)
1597 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1601 tcg_gen_ld8u_i64(var
, cpu_env
, offset
);
1604 tcg_gen_ld16u_i64(var
, cpu_env
, offset
);
1607 tcg_gen_ld32u_i64(var
, cpu_env
, offset
);
1610 tcg_gen_ld_i64(var
, cpu_env
, offset
);
1613 g_assert_not_reached();
1617 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1619 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1620 tcg_temp_free_i32(var
);
1623 static void neon_store_element(int reg
, int ele
, TCGMemOp size
, TCGv_i32 var
)
1625 long offset
= neon_element_offset(reg
, ele
, size
);
1629 tcg_gen_st8_i32(var
, cpu_env
, offset
);
1632 tcg_gen_st16_i32(var
, cpu_env
, offset
);
1635 tcg_gen_st_i32(var
, cpu_env
, offset
);
1638 g_assert_not_reached();
1642 static void neon_store_element64(int reg
, int ele
, TCGMemOp size
, TCGv_i64 var
)
1644 long offset
= neon_element_offset(reg
, ele
, size
);
1648 tcg_gen_st8_i64(var
, cpu_env
, offset
);
1651 tcg_gen_st16_i64(var
, cpu_env
, offset
);
1654 tcg_gen_st32_i64(var
, cpu_env
, offset
);
1657 tcg_gen_st_i64(var
, cpu_env
, offset
);
1660 g_assert_not_reached();
1664 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1666 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1669 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1671 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1674 static inline void neon_load_reg32(TCGv_i32 var
, int reg
)
1676 tcg_gen_ld_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1679 static inline void neon_store_reg32(TCGv_i32 var
, int reg
)
1681 tcg_gen_st_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1684 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1686 TCGv_ptr ret
= tcg_temp_new_ptr();
1687 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1691 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1692 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1693 #define tcg_gen_st_f32 tcg_gen_st_i32
1694 #define tcg_gen_st_f64 tcg_gen_st_i64
1696 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1699 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1701 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1704 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1707 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1709 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1712 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1715 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1717 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1720 #define ARM_CP_RW_BIT (1 << 20)
1722 /* Include the VFP decoder */
1723 #include "translate-vfp.inc.c"
1725 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1727 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1730 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1732 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1735 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1737 TCGv_i32 var
= tcg_temp_new_i32();
1738 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1742 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1744 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1745 tcg_temp_free_i32(var
);
1748 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1750 iwmmxt_store_reg(cpu_M0
, rn
);
1753 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1755 iwmmxt_load_reg(cpu_M0
, rn
);
1758 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1760 iwmmxt_load_reg(cpu_V1
, rn
);
1761 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1764 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1766 iwmmxt_load_reg(cpu_V1
, rn
);
1767 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1770 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1772 iwmmxt_load_reg(cpu_V1
, rn
);
1773 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1776 #define IWMMXT_OP(name) \
1777 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1779 iwmmxt_load_reg(cpu_V1, rn); \
1780 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1783 #define IWMMXT_OP_ENV(name) \
1784 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1786 iwmmxt_load_reg(cpu_V1, rn); \
1787 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1790 #define IWMMXT_OP_ENV_SIZE(name) \
1791 IWMMXT_OP_ENV(name##b) \
1792 IWMMXT_OP_ENV(name##w) \
1793 IWMMXT_OP_ENV(name##l)
1795 #define IWMMXT_OP_ENV1(name) \
1796 static inline void gen_op_iwmmxt_##name##_M0(void) \
1798 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1812 IWMMXT_OP_ENV_SIZE(unpackl
)
1813 IWMMXT_OP_ENV_SIZE(unpackh
)
1815 IWMMXT_OP_ENV1(unpacklub
)
1816 IWMMXT_OP_ENV1(unpackluw
)
1817 IWMMXT_OP_ENV1(unpacklul
)
1818 IWMMXT_OP_ENV1(unpackhub
)
1819 IWMMXT_OP_ENV1(unpackhuw
)
1820 IWMMXT_OP_ENV1(unpackhul
)
1821 IWMMXT_OP_ENV1(unpacklsb
)
1822 IWMMXT_OP_ENV1(unpacklsw
)
1823 IWMMXT_OP_ENV1(unpacklsl
)
1824 IWMMXT_OP_ENV1(unpackhsb
)
1825 IWMMXT_OP_ENV1(unpackhsw
)
1826 IWMMXT_OP_ENV1(unpackhsl
)
1828 IWMMXT_OP_ENV_SIZE(cmpeq
)
1829 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1830 IWMMXT_OP_ENV_SIZE(cmpgts
)
1832 IWMMXT_OP_ENV_SIZE(mins
)
1833 IWMMXT_OP_ENV_SIZE(minu
)
1834 IWMMXT_OP_ENV_SIZE(maxs
)
1835 IWMMXT_OP_ENV_SIZE(maxu
)
1837 IWMMXT_OP_ENV_SIZE(subn
)
1838 IWMMXT_OP_ENV_SIZE(addn
)
1839 IWMMXT_OP_ENV_SIZE(subu
)
1840 IWMMXT_OP_ENV_SIZE(addu
)
1841 IWMMXT_OP_ENV_SIZE(subs
)
1842 IWMMXT_OP_ENV_SIZE(adds
)
1844 IWMMXT_OP_ENV(avgb0
)
1845 IWMMXT_OP_ENV(avgb1
)
1846 IWMMXT_OP_ENV(avgw0
)
1847 IWMMXT_OP_ENV(avgw1
)
1849 IWMMXT_OP_ENV(packuw
)
1850 IWMMXT_OP_ENV(packul
)
1851 IWMMXT_OP_ENV(packuq
)
1852 IWMMXT_OP_ENV(packsw
)
1853 IWMMXT_OP_ENV(packsl
)
1854 IWMMXT_OP_ENV(packsq
)
1856 static void gen_op_iwmmxt_set_mup(void)
1859 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1860 tcg_gen_ori_i32(tmp
, tmp
, 2);
1861 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1864 static void gen_op_iwmmxt_set_cup(void)
1867 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1868 tcg_gen_ori_i32(tmp
, tmp
, 1);
1869 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1872 static void gen_op_iwmmxt_setpsr_nz(void)
1874 TCGv_i32 tmp
= tcg_temp_new_i32();
1875 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1876 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1879 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1881 iwmmxt_load_reg(cpu_V1
, rn
);
1882 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1883 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1886 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1893 rd
= (insn
>> 16) & 0xf;
1894 tmp
= load_reg(s
, rd
);
1896 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1897 if (insn
& (1 << 24)) {
1899 if (insn
& (1 << 23))
1900 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1902 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1903 tcg_gen_mov_i32(dest
, tmp
);
1904 if (insn
& (1 << 21))
1905 store_reg(s
, rd
, tmp
);
1907 tcg_temp_free_i32(tmp
);
1908 } else if (insn
& (1 << 21)) {
1910 tcg_gen_mov_i32(dest
, tmp
);
1911 if (insn
& (1 << 23))
1912 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1914 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1915 store_reg(s
, rd
, tmp
);
1916 } else if (!(insn
& (1 << 23)))
1921 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1923 int rd
= (insn
>> 0) & 0xf;
1926 if (insn
& (1 << 8)) {
1927 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1930 tmp
= iwmmxt_load_creg(rd
);
1933 tmp
= tcg_temp_new_i32();
1934 iwmmxt_load_reg(cpu_V0
, rd
);
1935 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1937 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1938 tcg_gen_mov_i32(dest
, tmp
);
1939 tcg_temp_free_i32(tmp
);
1943 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1944 (ie. an undefined instruction). */
1945 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1948 int rdhi
, rdlo
, rd0
, rd1
, i
;
1950 TCGv_i32 tmp
, tmp2
, tmp3
;
1952 if ((insn
& 0x0e000e00) == 0x0c000000) {
1953 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1955 rdlo
= (insn
>> 12) & 0xf;
1956 rdhi
= (insn
>> 16) & 0xf;
1957 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1958 iwmmxt_load_reg(cpu_V0
, wrd
);
1959 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1960 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1961 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1962 } else { /* TMCRR */
1963 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1964 iwmmxt_store_reg(cpu_V0
, wrd
);
1965 gen_op_iwmmxt_set_mup();
1970 wrd
= (insn
>> 12) & 0xf;
1971 addr
= tcg_temp_new_i32();
1972 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1973 tcg_temp_free_i32(addr
);
1976 if (insn
& ARM_CP_RW_BIT
) {
1977 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1978 tmp
= tcg_temp_new_i32();
1979 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1980 iwmmxt_store_creg(wrd
, tmp
);
1983 if (insn
& (1 << 8)) {
1984 if (insn
& (1 << 22)) { /* WLDRD */
1985 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1987 } else { /* WLDRW wRd */
1988 tmp
= tcg_temp_new_i32();
1989 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1992 tmp
= tcg_temp_new_i32();
1993 if (insn
& (1 << 22)) { /* WLDRH */
1994 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1995 } else { /* WLDRB */
1996 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2000 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
2001 tcg_temp_free_i32(tmp
);
2003 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2006 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
2007 tmp
= iwmmxt_load_creg(wrd
);
2008 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
2010 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2011 tmp
= tcg_temp_new_i32();
2012 if (insn
& (1 << 8)) {
2013 if (insn
& (1 << 22)) { /* WSTRD */
2014 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
2015 } else { /* WSTRW wRd */
2016 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2017 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
2020 if (insn
& (1 << 22)) { /* WSTRH */
2021 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2022 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
2023 } else { /* WSTRB */
2024 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2025 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
2029 tcg_temp_free_i32(tmp
);
2031 tcg_temp_free_i32(addr
);
2035 if ((insn
& 0x0f000000) != 0x0e000000)
2038 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
2039 case 0x000: /* WOR */
2040 wrd
= (insn
>> 12) & 0xf;
2041 rd0
= (insn
>> 0) & 0xf;
2042 rd1
= (insn
>> 16) & 0xf;
2043 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2044 gen_op_iwmmxt_orq_M0_wRn(rd1
);
2045 gen_op_iwmmxt_setpsr_nz();
2046 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2047 gen_op_iwmmxt_set_mup();
2048 gen_op_iwmmxt_set_cup();
2050 case 0x011: /* TMCR */
2053 rd
= (insn
>> 12) & 0xf;
2054 wrd
= (insn
>> 16) & 0xf;
2056 case ARM_IWMMXT_wCID
:
2057 case ARM_IWMMXT_wCASF
:
2059 case ARM_IWMMXT_wCon
:
2060 gen_op_iwmmxt_set_cup();
2062 case ARM_IWMMXT_wCSSF
:
2063 tmp
= iwmmxt_load_creg(wrd
);
2064 tmp2
= load_reg(s
, rd
);
2065 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
2066 tcg_temp_free_i32(tmp2
);
2067 iwmmxt_store_creg(wrd
, tmp
);
2069 case ARM_IWMMXT_wCGR0
:
2070 case ARM_IWMMXT_wCGR1
:
2071 case ARM_IWMMXT_wCGR2
:
2072 case ARM_IWMMXT_wCGR3
:
2073 gen_op_iwmmxt_set_cup();
2074 tmp
= load_reg(s
, rd
);
2075 iwmmxt_store_creg(wrd
, tmp
);
2081 case 0x100: /* WXOR */
2082 wrd
= (insn
>> 12) & 0xf;
2083 rd0
= (insn
>> 0) & 0xf;
2084 rd1
= (insn
>> 16) & 0xf;
2085 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2086 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
2087 gen_op_iwmmxt_setpsr_nz();
2088 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2089 gen_op_iwmmxt_set_mup();
2090 gen_op_iwmmxt_set_cup();
2092 case 0x111: /* TMRC */
2095 rd
= (insn
>> 12) & 0xf;
2096 wrd
= (insn
>> 16) & 0xf;
2097 tmp
= iwmmxt_load_creg(wrd
);
2098 store_reg(s
, rd
, tmp
);
2100 case 0x300: /* WANDN */
2101 wrd
= (insn
>> 12) & 0xf;
2102 rd0
= (insn
>> 0) & 0xf;
2103 rd1
= (insn
>> 16) & 0xf;
2104 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2105 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
2106 gen_op_iwmmxt_andq_M0_wRn(rd1
);
2107 gen_op_iwmmxt_setpsr_nz();
2108 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2109 gen_op_iwmmxt_set_mup();
2110 gen_op_iwmmxt_set_cup();
2112 case 0x200: /* WAND */
2113 wrd
= (insn
>> 12) & 0xf;
2114 rd0
= (insn
>> 0) & 0xf;
2115 rd1
= (insn
>> 16) & 0xf;
2116 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2117 gen_op_iwmmxt_andq_M0_wRn(rd1
);
2118 gen_op_iwmmxt_setpsr_nz();
2119 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2120 gen_op_iwmmxt_set_mup();
2121 gen_op_iwmmxt_set_cup();
2123 case 0x810: case 0xa10: /* WMADD */
2124 wrd
= (insn
>> 12) & 0xf;
2125 rd0
= (insn
>> 0) & 0xf;
2126 rd1
= (insn
>> 16) & 0xf;
2127 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2128 if (insn
& (1 << 21))
2129 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
2131 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
2132 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2133 gen_op_iwmmxt_set_mup();
2135 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2136 wrd
= (insn
>> 12) & 0xf;
2137 rd0
= (insn
>> 16) & 0xf;
2138 rd1
= (insn
>> 0) & 0xf;
2139 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2140 switch ((insn
>> 22) & 3) {
2142 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
2145 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
2148 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
2153 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2154 gen_op_iwmmxt_set_mup();
2155 gen_op_iwmmxt_set_cup();
2157 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2158 wrd
= (insn
>> 12) & 0xf;
2159 rd0
= (insn
>> 16) & 0xf;
2160 rd1
= (insn
>> 0) & 0xf;
2161 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2162 switch ((insn
>> 22) & 3) {
2164 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
2167 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
2170 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
2175 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2176 gen_op_iwmmxt_set_mup();
2177 gen_op_iwmmxt_set_cup();
2179 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2180 wrd
= (insn
>> 12) & 0xf;
2181 rd0
= (insn
>> 16) & 0xf;
2182 rd1
= (insn
>> 0) & 0xf;
2183 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2184 if (insn
& (1 << 22))
2185 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2187 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2188 if (!(insn
& (1 << 20)))
2189 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2190 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2191 gen_op_iwmmxt_set_mup();
2193 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2194 wrd
= (insn
>> 12) & 0xf;
2195 rd0
= (insn
>> 16) & 0xf;
2196 rd1
= (insn
>> 0) & 0xf;
2197 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2198 if (insn
& (1 << 21)) {
2199 if (insn
& (1 << 20))
2200 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2202 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2204 if (insn
& (1 << 20))
2205 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2207 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2209 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2210 gen_op_iwmmxt_set_mup();
2212 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2213 wrd
= (insn
>> 12) & 0xf;
2214 rd0
= (insn
>> 16) & 0xf;
2215 rd1
= (insn
>> 0) & 0xf;
2216 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2217 if (insn
& (1 << 21))
2218 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2220 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2221 if (!(insn
& (1 << 20))) {
2222 iwmmxt_load_reg(cpu_V1
, wrd
);
2223 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2225 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2226 gen_op_iwmmxt_set_mup();
2228 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2229 wrd
= (insn
>> 12) & 0xf;
2230 rd0
= (insn
>> 16) & 0xf;
2231 rd1
= (insn
>> 0) & 0xf;
2232 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2233 switch ((insn
>> 22) & 3) {
2235 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2238 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2241 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2246 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2247 gen_op_iwmmxt_set_mup();
2248 gen_op_iwmmxt_set_cup();
2250 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2251 wrd
= (insn
>> 12) & 0xf;
2252 rd0
= (insn
>> 16) & 0xf;
2253 rd1
= (insn
>> 0) & 0xf;
2254 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2255 if (insn
& (1 << 22)) {
2256 if (insn
& (1 << 20))
2257 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2259 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2261 if (insn
& (1 << 20))
2262 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2264 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2266 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2267 gen_op_iwmmxt_set_mup();
2268 gen_op_iwmmxt_set_cup();
2270 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2271 wrd
= (insn
>> 12) & 0xf;
2272 rd0
= (insn
>> 16) & 0xf;
2273 rd1
= (insn
>> 0) & 0xf;
2274 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2275 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2276 tcg_gen_andi_i32(tmp
, tmp
, 7);
2277 iwmmxt_load_reg(cpu_V1
, rd1
);
2278 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2279 tcg_temp_free_i32(tmp
);
2280 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2281 gen_op_iwmmxt_set_mup();
2283 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2284 if (((insn
>> 6) & 3) == 3)
2286 rd
= (insn
>> 12) & 0xf;
2287 wrd
= (insn
>> 16) & 0xf;
2288 tmp
= load_reg(s
, rd
);
2289 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2290 switch ((insn
>> 6) & 3) {
2292 tmp2
= tcg_const_i32(0xff);
2293 tmp3
= tcg_const_i32((insn
& 7) << 3);
2296 tmp2
= tcg_const_i32(0xffff);
2297 tmp3
= tcg_const_i32((insn
& 3) << 4);
2300 tmp2
= tcg_const_i32(0xffffffff);
2301 tmp3
= tcg_const_i32((insn
& 1) << 5);
2307 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2308 tcg_temp_free_i32(tmp3
);
2309 tcg_temp_free_i32(tmp2
);
2310 tcg_temp_free_i32(tmp
);
2311 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2312 gen_op_iwmmxt_set_mup();
2314 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2315 rd
= (insn
>> 12) & 0xf;
2316 wrd
= (insn
>> 16) & 0xf;
2317 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2319 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2320 tmp
= tcg_temp_new_i32();
2321 switch ((insn
>> 22) & 3) {
2323 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2324 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2326 tcg_gen_ext8s_i32(tmp
, tmp
);
2328 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2332 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2333 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2335 tcg_gen_ext16s_i32(tmp
, tmp
);
2337 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2341 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2342 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2345 store_reg(s
, rd
, tmp
);
2347 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2348 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2350 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2351 switch ((insn
>> 22) & 3) {
2353 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2356 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2359 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2362 tcg_gen_shli_i32(tmp
, tmp
, 28);
2364 tcg_temp_free_i32(tmp
);
2366 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2367 if (((insn
>> 6) & 3) == 3)
2369 rd
= (insn
>> 12) & 0xf;
2370 wrd
= (insn
>> 16) & 0xf;
2371 tmp
= load_reg(s
, rd
);
2372 switch ((insn
>> 6) & 3) {
2374 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2377 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2380 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2383 tcg_temp_free_i32(tmp
);
2384 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2385 gen_op_iwmmxt_set_mup();
2387 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2388 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2390 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2391 tmp2
= tcg_temp_new_i32();
2392 tcg_gen_mov_i32(tmp2
, tmp
);
2393 switch ((insn
>> 22) & 3) {
2395 for (i
= 0; i
< 7; i
++) {
2396 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2397 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2401 for (i
= 0; i
< 3; i
++) {
2402 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2403 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2407 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2408 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2412 tcg_temp_free_i32(tmp2
);
2413 tcg_temp_free_i32(tmp
);
2415 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2416 wrd
= (insn
>> 12) & 0xf;
2417 rd0
= (insn
>> 16) & 0xf;
2418 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2419 switch ((insn
>> 22) & 3) {
2421 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2424 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2427 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2432 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2433 gen_op_iwmmxt_set_mup();
2435 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2436 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2438 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2439 tmp2
= tcg_temp_new_i32();
2440 tcg_gen_mov_i32(tmp2
, tmp
);
2441 switch ((insn
>> 22) & 3) {
2443 for (i
= 0; i
< 7; i
++) {
2444 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2445 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2449 for (i
= 0; i
< 3; i
++) {
2450 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2451 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2455 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2456 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2460 tcg_temp_free_i32(tmp2
);
2461 tcg_temp_free_i32(tmp
);
2463 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2464 rd
= (insn
>> 12) & 0xf;
2465 rd0
= (insn
>> 16) & 0xf;
2466 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2468 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2469 tmp
= tcg_temp_new_i32();
2470 switch ((insn
>> 22) & 3) {
2472 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2475 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2478 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2481 store_reg(s
, rd
, tmp
);
2483 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2484 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2485 wrd
= (insn
>> 12) & 0xf;
2486 rd0
= (insn
>> 16) & 0xf;
2487 rd1
= (insn
>> 0) & 0xf;
2488 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2489 switch ((insn
>> 22) & 3) {
2491 if (insn
& (1 << 21))
2492 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2494 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2497 if (insn
& (1 << 21))
2498 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2500 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2503 if (insn
& (1 << 21))
2504 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2506 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2511 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2512 gen_op_iwmmxt_set_mup();
2513 gen_op_iwmmxt_set_cup();
2515 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2516 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2517 wrd
= (insn
>> 12) & 0xf;
2518 rd0
= (insn
>> 16) & 0xf;
2519 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2520 switch ((insn
>> 22) & 3) {
2522 if (insn
& (1 << 21))
2523 gen_op_iwmmxt_unpacklsb_M0();
2525 gen_op_iwmmxt_unpacklub_M0();
2528 if (insn
& (1 << 21))
2529 gen_op_iwmmxt_unpacklsw_M0();
2531 gen_op_iwmmxt_unpackluw_M0();
2534 if (insn
& (1 << 21))
2535 gen_op_iwmmxt_unpacklsl_M0();
2537 gen_op_iwmmxt_unpacklul_M0();
2542 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2543 gen_op_iwmmxt_set_mup();
2544 gen_op_iwmmxt_set_cup();
2546 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2547 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2548 wrd
= (insn
>> 12) & 0xf;
2549 rd0
= (insn
>> 16) & 0xf;
2550 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2551 switch ((insn
>> 22) & 3) {
2553 if (insn
& (1 << 21))
2554 gen_op_iwmmxt_unpackhsb_M0();
2556 gen_op_iwmmxt_unpackhub_M0();
2559 if (insn
& (1 << 21))
2560 gen_op_iwmmxt_unpackhsw_M0();
2562 gen_op_iwmmxt_unpackhuw_M0();
2565 if (insn
& (1 << 21))
2566 gen_op_iwmmxt_unpackhsl_M0();
2568 gen_op_iwmmxt_unpackhul_M0();
2573 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2574 gen_op_iwmmxt_set_mup();
2575 gen_op_iwmmxt_set_cup();
2577 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2578 case 0x214: case 0x614: case 0xa14: case 0xe14:
2579 if (((insn
>> 22) & 3) == 0)
2581 wrd
= (insn
>> 12) & 0xf;
2582 rd0
= (insn
>> 16) & 0xf;
2583 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2584 tmp
= tcg_temp_new_i32();
2585 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2586 tcg_temp_free_i32(tmp
);
2589 switch ((insn
>> 22) & 3) {
2591 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2594 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2597 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2600 tcg_temp_free_i32(tmp
);
2601 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2602 gen_op_iwmmxt_set_mup();
2603 gen_op_iwmmxt_set_cup();
2605 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2606 case 0x014: case 0x414: case 0x814: case 0xc14:
2607 if (((insn
>> 22) & 3) == 0)
2609 wrd
= (insn
>> 12) & 0xf;
2610 rd0
= (insn
>> 16) & 0xf;
2611 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2612 tmp
= tcg_temp_new_i32();
2613 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2614 tcg_temp_free_i32(tmp
);
2617 switch ((insn
>> 22) & 3) {
2619 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2622 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2625 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2628 tcg_temp_free_i32(tmp
);
2629 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2630 gen_op_iwmmxt_set_mup();
2631 gen_op_iwmmxt_set_cup();
2633 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2634 case 0x114: case 0x514: case 0x914: case 0xd14:
2635 if (((insn
>> 22) & 3) == 0)
2637 wrd
= (insn
>> 12) & 0xf;
2638 rd0
= (insn
>> 16) & 0xf;
2639 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2640 tmp
= tcg_temp_new_i32();
2641 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2642 tcg_temp_free_i32(tmp
);
2645 switch ((insn
>> 22) & 3) {
2647 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2650 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2653 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2656 tcg_temp_free_i32(tmp
);
2657 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2658 gen_op_iwmmxt_set_mup();
2659 gen_op_iwmmxt_set_cup();
2661 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2662 case 0x314: case 0x714: case 0xb14: case 0xf14:
2663 if (((insn
>> 22) & 3) == 0)
2665 wrd
= (insn
>> 12) & 0xf;
2666 rd0
= (insn
>> 16) & 0xf;
2667 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2668 tmp
= tcg_temp_new_i32();
2669 switch ((insn
>> 22) & 3) {
2671 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2672 tcg_temp_free_i32(tmp
);
2675 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2678 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2679 tcg_temp_free_i32(tmp
);
2682 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2685 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2686 tcg_temp_free_i32(tmp
);
2689 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2692 tcg_temp_free_i32(tmp
);
2693 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2694 gen_op_iwmmxt_set_mup();
2695 gen_op_iwmmxt_set_cup();
2697 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2698 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2699 wrd
= (insn
>> 12) & 0xf;
2700 rd0
= (insn
>> 16) & 0xf;
2701 rd1
= (insn
>> 0) & 0xf;
2702 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2703 switch ((insn
>> 22) & 3) {
2705 if (insn
& (1 << 21))
2706 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2708 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2711 if (insn
& (1 << 21))
2712 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2714 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2717 if (insn
& (1 << 21))
2718 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2720 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2725 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2726 gen_op_iwmmxt_set_mup();
2728 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2729 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2730 wrd
= (insn
>> 12) & 0xf;
2731 rd0
= (insn
>> 16) & 0xf;
2732 rd1
= (insn
>> 0) & 0xf;
2733 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2734 switch ((insn
>> 22) & 3) {
2736 if (insn
& (1 << 21))
2737 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2739 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2742 if (insn
& (1 << 21))
2743 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2745 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2748 if (insn
& (1 << 21))
2749 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2751 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2756 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2757 gen_op_iwmmxt_set_mup();
2759 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2760 case 0x402: case 0x502: case 0x602: case 0x702:
2761 wrd
= (insn
>> 12) & 0xf;
2762 rd0
= (insn
>> 16) & 0xf;
2763 rd1
= (insn
>> 0) & 0xf;
2764 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2765 tmp
= tcg_const_i32((insn
>> 20) & 3);
2766 iwmmxt_load_reg(cpu_V1
, rd1
);
2767 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2768 tcg_temp_free_i32(tmp
);
2769 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2770 gen_op_iwmmxt_set_mup();
2772 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2773 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2774 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2775 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2776 wrd
= (insn
>> 12) & 0xf;
2777 rd0
= (insn
>> 16) & 0xf;
2778 rd1
= (insn
>> 0) & 0xf;
2779 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2780 switch ((insn
>> 20) & 0xf) {
2782 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2785 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2788 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2791 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2794 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2797 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2800 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2803 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2806 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2811 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2812 gen_op_iwmmxt_set_mup();
2813 gen_op_iwmmxt_set_cup();
2815 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2816 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2817 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2818 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2819 wrd
= (insn
>> 12) & 0xf;
2820 rd0
= (insn
>> 16) & 0xf;
2821 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2822 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2823 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2824 tcg_temp_free_i32(tmp
);
2825 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2826 gen_op_iwmmxt_set_mup();
2827 gen_op_iwmmxt_set_cup();
2829 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2830 case 0x418: case 0x518: case 0x618: case 0x718:
2831 case 0x818: case 0x918: case 0xa18: case 0xb18:
2832 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2833 wrd
= (insn
>> 12) & 0xf;
2834 rd0
= (insn
>> 16) & 0xf;
2835 rd1
= (insn
>> 0) & 0xf;
2836 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2837 switch ((insn
>> 20) & 0xf) {
2839 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2842 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2845 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2848 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2851 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2854 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2857 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2860 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2863 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2868 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2869 gen_op_iwmmxt_set_mup();
2870 gen_op_iwmmxt_set_cup();
2872 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2873 case 0x408: case 0x508: case 0x608: case 0x708:
2874 case 0x808: case 0x908: case 0xa08: case 0xb08:
2875 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2876 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2878 wrd
= (insn
>> 12) & 0xf;
2879 rd0
= (insn
>> 16) & 0xf;
2880 rd1
= (insn
>> 0) & 0xf;
2881 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2882 switch ((insn
>> 22) & 3) {
2884 if (insn
& (1 << 21))
2885 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2887 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2890 if (insn
& (1 << 21))
2891 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2893 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2896 if (insn
& (1 << 21))
2897 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2899 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2902 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2903 gen_op_iwmmxt_set_mup();
2904 gen_op_iwmmxt_set_cup();
2906 case 0x201: case 0x203: case 0x205: case 0x207:
2907 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2908 case 0x211: case 0x213: case 0x215: case 0x217:
2909 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2910 wrd
= (insn
>> 5) & 0xf;
2911 rd0
= (insn
>> 12) & 0xf;
2912 rd1
= (insn
>> 0) & 0xf;
2913 if (rd0
== 0xf || rd1
== 0xf)
2915 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2916 tmp
= load_reg(s
, rd0
);
2917 tmp2
= load_reg(s
, rd1
);
2918 switch ((insn
>> 16) & 0xf) {
2919 case 0x0: /* TMIA */
2920 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2922 case 0x8: /* TMIAPH */
2923 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2925 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2926 if (insn
& (1 << 16))
2927 tcg_gen_shri_i32(tmp
, tmp
, 16);
2928 if (insn
& (1 << 17))
2929 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2930 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2933 tcg_temp_free_i32(tmp2
);
2934 tcg_temp_free_i32(tmp
);
2937 tcg_temp_free_i32(tmp2
);
2938 tcg_temp_free_i32(tmp
);
2939 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2940 gen_op_iwmmxt_set_mup();
2949 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2950 (ie. an undefined instruction). */
2951 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2953 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2956 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2957 /* Multiply with Internal Accumulate Format */
2958 rd0
= (insn
>> 12) & 0xf;
2960 acc
= (insn
>> 5) & 7;
2965 tmp
= load_reg(s
, rd0
);
2966 tmp2
= load_reg(s
, rd1
);
2967 switch ((insn
>> 16) & 0xf) {
2969 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2971 case 0x8: /* MIAPH */
2972 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2974 case 0xc: /* MIABB */
2975 case 0xd: /* MIABT */
2976 case 0xe: /* MIATB */
2977 case 0xf: /* MIATT */
2978 if (insn
& (1 << 16))
2979 tcg_gen_shri_i32(tmp
, tmp
, 16);
2980 if (insn
& (1 << 17))
2981 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2982 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2987 tcg_temp_free_i32(tmp2
);
2988 tcg_temp_free_i32(tmp
);
2990 gen_op_iwmmxt_movq_wRn_M0(acc
);
2994 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2995 /* Internal Accumulator Access Format */
2996 rdhi
= (insn
>> 16) & 0xf;
2997 rdlo
= (insn
>> 12) & 0xf;
3003 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
3004 iwmmxt_load_reg(cpu_V0
, acc
);
3005 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
3006 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
3007 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
3008 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
3010 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
3011 iwmmxt_store_reg(cpu_V0
, acc
);
3019 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
3020 #define VFP_SREG(insn, bigbit, smallbit) \
3021 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
3022 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
3023 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
3024 reg = (((insn) >> (bigbit)) & 0x0f) \
3025 | (((insn) >> ((smallbit) - 4)) & 0x10); \
3027 if (insn & (1 << (smallbit))) \
3029 reg = ((insn) >> (bigbit)) & 0x0f; \
3032 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
3033 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
3034 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
3035 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
3036 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
3037 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
3039 /* Move between integer and VFP cores. */
3040 static TCGv_i32
gen_vfp_mrs(void)
3042 TCGv_i32 tmp
= tcg_temp_new_i32();
3043 tcg_gen_mov_i32(tmp
, cpu_F0s
);
3047 static void gen_vfp_msr(TCGv_i32 tmp
)
3049 tcg_gen_mov_i32(cpu_F0s
, tmp
);
3050 tcg_temp_free_i32(tmp
);
3053 static void gen_neon_dup_low16(TCGv_i32 var
)
3055 TCGv_i32 tmp
= tcg_temp_new_i32();
3056 tcg_gen_ext16u_i32(var
, var
);
3057 tcg_gen_shli_i32(tmp
, var
, 16);
3058 tcg_gen_or_i32(var
, var
, tmp
);
3059 tcg_temp_free_i32(tmp
);
3062 static void gen_neon_dup_high16(TCGv_i32 var
)
3064 TCGv_i32 tmp
= tcg_temp_new_i32();
3065 tcg_gen_andi_i32(var
, var
, 0xffff0000);
3066 tcg_gen_shri_i32(tmp
, var
, 16);
3067 tcg_gen_or_i32(var
, var
, tmp
);
3068 tcg_temp_free_i32(tmp
);
3072 * Disassemble a VFP instruction. Returns nonzero if an error occurred
3073 * (ie. an undefined instruction).
3075 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3077 uint32_t rd
, rn
, rm
, op
, i
, n
, delta_d
, delta_m
, bank_mask
;
3082 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3087 * If the decodetree decoder handles this insn it will always
3088 * emit code to either execute the insn or generate an appropriate
3089 * exception; so we don't need to ever return non-zero to tell
3090 * the calling code to emit an UNDEF exception.
3092 if (extract32(insn
, 28, 4) == 0xf) {
3093 if (disas_vfp_uncond(s
, insn
)) {
3097 if (disas_vfp(s
, insn
)) {
3102 if (extract32(insn
, 28, 4) == 0xf) {
3104 * Encodings with T=1 (Thumb) or unconditional (ARM): these
3105 * were all handled by the decodetree decoder, so any insn
3106 * patterns which get here must be UNDEF.
3112 * FIXME: this access check should not take precedence over UNDEF
3113 * for invalid encodings; we will generate incorrect syndrome information
3114 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3116 if (!vfp_access_check(s
)) {
3120 dp
= ((insn
& 0xf00) == 0xb00);
3121 switch ((insn
>> 24) & 0xf) {
3123 if (insn
& (1 << 4)) {
3124 /* already handled by decodetree */
3127 /* data processing */
3130 bool no_output
= false;
3132 /* The opcode is in bits 23, 21, 20 and 6. */
3133 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3134 rn
= VFP_SREG_N(insn
);
3138 /* Already handled by decodetree */
3145 /* rn is opcode, encoded as per VFP_SREG_N. */
3147 case 0x00: /* vmov */
3148 case 0x01: /* vabs */
3149 case 0x02: /* vneg */
3150 case 0x03: /* vsqrt */
3153 case 0x04: /* vcvtb.f64.f16, vcvtb.f32.f16 */
3154 case 0x05: /* vcvtt.f64.f16, vcvtt.f32.f16 */
3156 * VCVTB, VCVTT: only present with the halfprec extension
3157 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3158 * (we choose to UNDEF)
3161 if (!dc_isar_feature(aa32_fp16_dpconv
, s
)) {
3165 if (!dc_isar_feature(aa32_fp16_spconv
, s
)) {
3171 case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3172 case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3174 if (!dc_isar_feature(aa32_fp16_dpconv
, s
)) {
3178 if (!dc_isar_feature(aa32_fp16_spconv
, s
)) {
3185 case 0x08: case 0x0a: /* vcmp, vcmpz */
3186 case 0x09: case 0x0b: /* vcmpe, vcmpez */
3190 case 0x0c: /* vrintr */
3191 case 0x0d: /* vrintz */
3192 case 0x0e: /* vrintx */
3195 case 0x0f: /* vcvt double<->single */
3199 case 0x10: /* vcvt.fxx.u32 */
3200 case 0x11: /* vcvt.fxx.s32 */
3203 case 0x18: /* vcvtr.u32.fxx */
3204 case 0x19: /* vcvtz.u32.fxx */
3205 case 0x1a: /* vcvtr.s32.fxx */
3206 case 0x1b: /* vcvtz.s32.fxx */
3210 case 0x14: /* vcvt fp <-> fixed */
3218 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3221 /* Immediate frac_bits has same format as SREG_M. */
3225 case 0x13: /* vjcvt */
3226 if (!dp
|| !dc_isar_feature(aa32_jscvt
, s
)) {
3236 /* rn is register number */
3237 VFP_DREG_N(rn
, insn
);
3241 VFP_DREG_D(rd
, insn
);
3243 rd
= VFP_SREG_D(insn
);
3246 VFP_DREG_M(rm
, insn
);
3248 rm
= VFP_SREG_M(insn
);
3251 veclen
= s
->vec_len
;
3252 if (op
== 15 && rn
> 3) {
3256 /* Shut up compiler warnings. */
3267 /* Figure out what type of vector operation this is. */
3268 if ((rd
& bank_mask
) == 0) {
3273 delta_d
= (s
->vec_stride
>> 1) + 1;
3275 delta_d
= s
->vec_stride
+ 1;
3277 if ((rm
& bank_mask
) == 0) {
3278 /* mixed scalar/vector */
3287 /* Load the initial operands. */
3290 case 0x08: case 0x09: /* Compare */
3291 gen_mov_F0_vreg(dp
, rd
);
3292 gen_mov_F1_vreg(dp
, rm
);
3294 case 0x0a: case 0x0b: /* Compare with zero */
3295 gen_mov_F0_vreg(dp
, rd
);
3298 case 0x14: /* vcvt fp <-> fixed */
3306 /* Source and destination the same. */
3307 gen_mov_F0_vreg(dp
, rd
);
3310 /* One source operand. */
3311 gen_mov_F0_vreg(rm_is_dp
, rm
);
3315 /* Two source operands. */
3316 gen_mov_F0_vreg(dp
, rn
);
3317 gen_mov_F1_vreg(dp
, rm
);
3321 /* Perform the calculation. */
3323 case 2: /* VNMLS: -fd + (fn * fm) */
3324 /* Note that it isn't valid to replace (-A + B) with (B - A)
3325 * or similar plausible looking simplifications
3326 * because this will give wrong results for NaNs.
3329 gen_mov_F0_vreg(dp
, rd
);
3333 case 3: /* VNMLA: -fd + -(fn * fm) */
3336 gen_mov_F0_vreg(dp
, rd
);
3340 case 4: /* mul: fn * fm */
3343 case 5: /* nmul: -(fn * fm) */
3347 case 6: /* add: fn + fm */
3350 case 7: /* sub: fn - fm */
3353 case 8: /* div: fn / fm */
3356 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3357 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3358 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3359 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3360 /* These are fused multiply-add, and must be done as one
3361 * floating point operation with no rounding between the
3362 * multiplication and addition steps.
3363 * NB that doing the negations here as separate steps is
3364 * correct : an input NaN should come out with its sign bit
3365 * flipped if it is a negated-input.
3367 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3375 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3377 frd
= tcg_temp_new_i64();
3378 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3381 gen_helper_vfp_negd(frd
, frd
);
3383 fpst
= get_fpstatus_ptr(0);
3384 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3385 cpu_F1d
, frd
, fpst
);
3386 tcg_temp_free_ptr(fpst
);
3387 tcg_temp_free_i64(frd
);
3393 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3395 frd
= tcg_temp_new_i32();
3396 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3398 gen_helper_vfp_negs(frd
, frd
);
3400 fpst
= get_fpstatus_ptr(0);
3401 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3402 cpu_F1s
, frd
, fpst
);
3403 tcg_temp_free_ptr(fpst
);
3404 tcg_temp_free_i32(frd
);
3407 case 14: /* fconst */
3408 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3412 n
= (insn
<< 12) & 0x80000000;
3413 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3420 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3427 tcg_gen_movi_i32(cpu_F0s
, n
);
3430 case 15: /* extension space */
3444 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3446 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3447 TCGv_i32 ahp_mode
= get_ahp_flag();
3448 tmp
= gen_vfp_mrs();
3449 tcg_gen_ext16u_i32(tmp
, tmp
);
3451 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3454 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3457 tcg_temp_free_i32(ahp_mode
);
3458 tcg_temp_free_ptr(fpst
);
3459 tcg_temp_free_i32(tmp
);
3462 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3464 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3465 TCGv_i32 ahp
= get_ahp_flag();
3466 tmp
= gen_vfp_mrs();
3467 tcg_gen_shri_i32(tmp
, tmp
, 16);
3469 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3472 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3475 tcg_temp_free_i32(tmp
);
3476 tcg_temp_free_i32(ahp
);
3477 tcg_temp_free_ptr(fpst
);
3480 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3482 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3483 TCGv_i32 ahp
= get_ahp_flag();
3484 tmp
= tcg_temp_new_i32();
3487 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3490 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3493 tcg_temp_free_i32(ahp
);
3494 tcg_temp_free_ptr(fpst
);
3495 gen_mov_F0_vreg(0, rd
);
3496 tmp2
= gen_vfp_mrs();
3497 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3498 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3499 tcg_temp_free_i32(tmp2
);
3503 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3505 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3506 TCGv_i32 ahp
= get_ahp_flag();
3507 tmp
= tcg_temp_new_i32();
3509 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3512 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3515 tcg_temp_free_i32(ahp
);
3516 tcg_temp_free_ptr(fpst
);
3517 tcg_gen_shli_i32(tmp
, tmp
, 16);
3518 gen_mov_F0_vreg(0, rd
);
3519 tmp2
= gen_vfp_mrs();
3520 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3521 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3522 tcg_temp_free_i32(tmp2
);
3535 case 11: /* cmpez */
3539 case 12: /* vrintr */
3541 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3543 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3545 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3547 tcg_temp_free_ptr(fpst
);
3550 case 13: /* vrintz */
3552 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3554 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3555 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3557 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3559 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3561 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3562 tcg_temp_free_i32(tcg_rmode
);
3563 tcg_temp_free_ptr(fpst
);
3566 case 14: /* vrintx */
3568 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3570 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3572 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3574 tcg_temp_free_ptr(fpst
);
3577 case 15: /* single<->double conversion */
3579 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3581 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3584 case 16: /* fuito */
3585 gen_vfp_uito(dp
, 0);
3587 case 17: /* fsito */
3588 gen_vfp_sito(dp
, 0);
3590 case 19: /* vjcvt */
3591 gen_helper_vjcvt(cpu_F0s
, cpu_F0d
, cpu_env
);
3593 case 20: /* fshto */
3594 gen_vfp_shto(dp
, 16 - rm
, 0);
3596 case 21: /* fslto */
3597 gen_vfp_slto(dp
, 32 - rm
, 0);
3599 case 22: /* fuhto */
3600 gen_vfp_uhto(dp
, 16 - rm
, 0);
3602 case 23: /* fulto */
3603 gen_vfp_ulto(dp
, 32 - rm
, 0);
3605 case 24: /* ftoui */
3606 gen_vfp_toui(dp
, 0);
3608 case 25: /* ftouiz */
3609 gen_vfp_touiz(dp
, 0);
3611 case 26: /* ftosi */
3612 gen_vfp_tosi(dp
, 0);
3614 case 27: /* ftosiz */
3615 gen_vfp_tosiz(dp
, 0);
3617 case 28: /* ftosh */
3618 gen_vfp_tosh(dp
, 16 - rm
, 0);
3620 case 29: /* ftosl */
3621 gen_vfp_tosl(dp
, 32 - rm
, 0);
3623 case 30: /* ftouh */
3624 gen_vfp_touh(dp
, 16 - rm
, 0);
3626 case 31: /* ftoul */
3627 gen_vfp_toul(dp
, 32 - rm
, 0);
3629 default: /* undefined */
3630 g_assert_not_reached();
3633 default: /* undefined */
3637 /* Write back the result, if any. */
3639 gen_mov_vreg_F0(rd_is_dp
, rd
);
3642 /* break out of the loop if we have finished */
3647 if (op
== 15 && delta_m
== 0) {
3648 /* single source one-many */
3650 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3652 gen_mov_vreg_F0(dp
, rd
);
3656 /* Setup the next operands. */
3658 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3662 /* One source operand. */
3663 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3665 gen_mov_F0_vreg(dp
, rm
);
3667 /* Two source operands. */
3668 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3670 gen_mov_F0_vreg(dp
, rn
);
3672 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3674 gen_mov_F1_vreg(dp
, rm
);
3682 /* Already handled by decodetree */
3685 /* Should never happen. */
3691 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
3693 #ifndef CONFIG_USER_ONLY
3694 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
3695 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
3701 static void gen_goto_ptr(void)
3703 tcg_gen_lookup_and_goto_ptr();
3706 /* This will end the TB but doesn't guarantee we'll return to
3707 * cpu_loop_exec. Any live exit_requests will be processed as we
3708 * enter the next TB.
3710 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3712 if (use_goto_tb(s
, dest
)) {
3714 gen_set_pc_im(s
, dest
);
3715 tcg_gen_exit_tb(s
->base
.tb
, n
);
3717 gen_set_pc_im(s
, dest
);
3720 s
->base
.is_jmp
= DISAS_NORETURN
;
3723 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3725 if (unlikely(is_singlestepping(s
))) {
3726 /* An indirect jump so that we still trigger the debug exception. */
3731 gen_goto_tb(s
, 0, dest
);
3735 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3738 tcg_gen_sari_i32(t0
, t0
, 16);
3742 tcg_gen_sari_i32(t1
, t1
, 16);
3745 tcg_gen_mul_i32(t0
, t0
, t1
);
3748 /* Return the mask of PSR bits set by a MSR instruction. */
3749 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
3754 if (flags
& (1 << 0))
3756 if (flags
& (1 << 1))
3758 if (flags
& (1 << 2))
3760 if (flags
& (1 << 3))
3763 /* Mask out undefined bits. */
3764 mask
&= ~CPSR_RESERVED
;
3765 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
3768 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
3769 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3771 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
3772 mask
&= ~(CPSR_E
| CPSR_GE
);
3774 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
3777 /* Mask out execution state and reserved bits. */
3779 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
3781 /* Mask out privileged bits. */
3787 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3788 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3792 /* ??? This is also undefined in system mode. */
3796 tmp
= load_cpu_field(spsr
);
3797 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3798 tcg_gen_andi_i32(t0
, t0
, mask
);
3799 tcg_gen_or_i32(tmp
, tmp
, t0
);
3800 store_cpu_field(tmp
, spsr
);
3802 gen_set_cpsr(t0
, mask
);
3804 tcg_temp_free_i32(t0
);
3809 /* Returns nonzero if access to the PSR is not permitted. */
3810 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3813 tmp
= tcg_temp_new_i32();
3814 tcg_gen_movi_i32(tmp
, val
);
3815 return gen_set_psr(s
, mask
, spsr
, tmp
);
3818 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
3819 int *tgtmode
, int *regno
)
3821 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3822 * the target mode and register number, and identify the various
3823 * unpredictable cases.
3824 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3825 * + executed in user mode
3826 * + using R15 as the src/dest register
3827 * + accessing an unimplemented register
3828 * + accessing a register that's inaccessible at current PL/security state*
3829 * + accessing a register that you could access with a different insn
3830 * We choose to UNDEF in all these cases.
3831 * Since we don't know which of the various AArch32 modes we are in
3832 * we have to defer some checks to runtime.
3833 * Accesses to Monitor mode registers from Secure EL1 (which implies
3834 * that EL3 is AArch64) must trap to EL3.
3836 * If the access checks fail this function will emit code to take
3837 * an exception and return false. Otherwise it will return true,
3838 * and set *tgtmode and *regno appropriately.
3840 int exc_target
= default_exception_el(s
);
3842 /* These instructions are present only in ARMv8, or in ARMv7 with the
3843 * Virtualization Extensions.
3845 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
3846 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
3850 if (IS_USER(s
) || rn
== 15) {
3854 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3855 * of registers into (r, sysm).
3858 /* SPSRs for other modes */
3860 case 0xe: /* SPSR_fiq */
3861 *tgtmode
= ARM_CPU_MODE_FIQ
;
3863 case 0x10: /* SPSR_irq */
3864 *tgtmode
= ARM_CPU_MODE_IRQ
;
3866 case 0x12: /* SPSR_svc */
3867 *tgtmode
= ARM_CPU_MODE_SVC
;
3869 case 0x14: /* SPSR_abt */
3870 *tgtmode
= ARM_CPU_MODE_ABT
;
3872 case 0x16: /* SPSR_und */
3873 *tgtmode
= ARM_CPU_MODE_UND
;
3875 case 0x1c: /* SPSR_mon */
3876 *tgtmode
= ARM_CPU_MODE_MON
;
3878 case 0x1e: /* SPSR_hyp */
3879 *tgtmode
= ARM_CPU_MODE_HYP
;
3881 default: /* unallocated */
3884 /* We arbitrarily assign SPSR a register number of 16. */
3887 /* general purpose registers for other modes */
3889 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3890 *tgtmode
= ARM_CPU_MODE_USR
;
3893 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3894 *tgtmode
= ARM_CPU_MODE_FIQ
;
3897 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3898 *tgtmode
= ARM_CPU_MODE_IRQ
;
3899 *regno
= sysm
& 1 ? 13 : 14;
3901 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3902 *tgtmode
= ARM_CPU_MODE_SVC
;
3903 *regno
= sysm
& 1 ? 13 : 14;
3905 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3906 *tgtmode
= ARM_CPU_MODE_ABT
;
3907 *regno
= sysm
& 1 ? 13 : 14;
3909 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3910 *tgtmode
= ARM_CPU_MODE_UND
;
3911 *regno
= sysm
& 1 ? 13 : 14;
3913 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3914 *tgtmode
= ARM_CPU_MODE_MON
;
3915 *regno
= sysm
& 1 ? 13 : 14;
3917 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3918 *tgtmode
= ARM_CPU_MODE_HYP
;
3919 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3920 *regno
= sysm
& 1 ? 13 : 17;
3922 default: /* unallocated */
3927 /* Catch the 'accessing inaccessible register' cases we can detect
3928 * at translate time.
3931 case ARM_CPU_MODE_MON
:
3932 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
3935 if (s
->current_el
== 1) {
3936 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3937 * then accesses to Mon registers trap to EL3
3943 case ARM_CPU_MODE_HYP
:
3945 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3946 * (and so we can forbid accesses from EL2 or below). elr_hyp
3947 * can be accessed also from Hyp mode, so forbid accesses from
3950 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 2 ||
3951 (s
->current_el
< 3 && *regno
!= 17)) {
3962 /* If we get here then some access check did not pass */
3963 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
3967 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
3969 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
3970 int tgtmode
= 0, regno
= 0;
3972 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
3976 /* Sync state because msr_banked() can raise exceptions */
3977 gen_set_condexec(s
);
3978 gen_set_pc_im(s
, s
->pc
- 4);
3979 tcg_reg
= load_reg(s
, rn
);
3980 tcg_tgtmode
= tcg_const_i32(tgtmode
);
3981 tcg_regno
= tcg_const_i32(regno
);
3982 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
3983 tcg_temp_free_i32(tcg_tgtmode
);
3984 tcg_temp_free_i32(tcg_regno
);
3985 tcg_temp_free_i32(tcg_reg
);
3986 s
->base
.is_jmp
= DISAS_UPDATE
;
3989 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
3991 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
3992 int tgtmode
= 0, regno
= 0;
3994 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
3998 /* Sync state because mrs_banked() can raise exceptions */
3999 gen_set_condexec(s
);
4000 gen_set_pc_im(s
, s
->pc
- 4);
4001 tcg_reg
= tcg_temp_new_i32();
4002 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4003 tcg_regno
= tcg_const_i32(regno
);
4004 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4005 tcg_temp_free_i32(tcg_tgtmode
);
4006 tcg_temp_free_i32(tcg_regno
);
4007 store_reg(s
, rn
, tcg_reg
);
4008 s
->base
.is_jmp
= DISAS_UPDATE
;
4011 /* Store value to PC as for an exception return (ie don't
4012 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4013 * will do the masking based on the new value of the Thumb bit.
4015 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4017 tcg_gen_mov_i32(cpu_R
[15], pc
);
4018 tcg_temp_free_i32(pc
);
4021 /* Generate a v6 exception return. Marks both values as dead. */
4022 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4024 store_pc_exc_ret(s
, pc
);
4025 /* The cpsr_write_eret helper will mask the low bits of PC
4026 * appropriately depending on the new Thumb bit, so it must
4027 * be called after storing the new PC.
4029 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
4032 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4033 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
4036 tcg_temp_free_i32(cpsr
);
4037 /* Must exit loop to check un-masked IRQs */
4038 s
->base
.is_jmp
= DISAS_EXIT
;
4041 /* Generate an old-style exception return. Marks pc as dead. */
4042 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4044 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4048 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4049 * only call the helper when running single threaded TCG code to ensure
4050 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4051 * just skip this instruction. Currently the SEV/SEVL instructions
4052 * which are *one* of many ways to wake the CPU from WFE are not
4053 * implemented so we can't sleep like WFI does.
4055 static void gen_nop_hint(DisasContext
*s
, int val
)
4058 /* When running in MTTCG we don't generate jumps to the yield and
4059 * WFE helpers as it won't affect the scheduling of other vCPUs.
4060 * If we wanted to more completely model WFE/SEV so we don't busy
4061 * spin unnecessarily we would need to do something more involved.
4064 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4065 gen_set_pc_im(s
, s
->pc
);
4066 s
->base
.is_jmp
= DISAS_YIELD
;
4070 gen_set_pc_im(s
, s
->pc
);
4071 s
->base
.is_jmp
= DISAS_WFI
;
4074 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4075 gen_set_pc_im(s
, s
->pc
);
4076 s
->base
.is_jmp
= DISAS_WFE
;
4081 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4087 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4089 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4092 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4093 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4094 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4099 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4102 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4103 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4104 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4109 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4110 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
4111 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
4112 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
4113 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
4115 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4116 switch ((size << 1) | u) { \
4118 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4121 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4124 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4127 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4130 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4133 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4135 default: return 1; \
4138 #define GEN_NEON_INTEGER_OP(name) do { \
4139 switch ((size << 1) | u) { \
4141 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4144 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4147 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4150 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4153 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4156 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4158 default: return 1; \
4161 static TCGv_i32
neon_load_scratch(int scratch
)
4163 TCGv_i32 tmp
= tcg_temp_new_i32();
4164 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4168 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4170 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4171 tcg_temp_free_i32(var
);
4174 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4178 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4180 gen_neon_dup_high16(tmp
);
4182 gen_neon_dup_low16(tmp
);
4185 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4190 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4194 if (!q
&& size
== 2) {
4197 pd
= vfp_reg_ptr(true, rd
);
4198 pm
= vfp_reg_ptr(true, rm
);
4202 gen_helper_neon_qunzip8(pd
, pm
);
4205 gen_helper_neon_qunzip16(pd
, pm
);
4208 gen_helper_neon_qunzip32(pd
, pm
);
4216 gen_helper_neon_unzip8(pd
, pm
);
4219 gen_helper_neon_unzip16(pd
, pm
);
4225 tcg_temp_free_ptr(pd
);
4226 tcg_temp_free_ptr(pm
);
4230 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4234 if (!q
&& size
== 2) {
4237 pd
= vfp_reg_ptr(true, rd
);
4238 pm
= vfp_reg_ptr(true, rm
);
4242 gen_helper_neon_qzip8(pd
, pm
);
4245 gen_helper_neon_qzip16(pd
, pm
);
4248 gen_helper_neon_qzip32(pd
, pm
);
4256 gen_helper_neon_zip8(pd
, pm
);
4259 gen_helper_neon_zip16(pd
, pm
);
4265 tcg_temp_free_ptr(pd
);
4266 tcg_temp_free_ptr(pm
);
4270 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4274 rd
= tcg_temp_new_i32();
4275 tmp
= tcg_temp_new_i32();
4277 tcg_gen_shli_i32(rd
, t0
, 8);
4278 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4279 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4280 tcg_gen_or_i32(rd
, rd
, tmp
);
4282 tcg_gen_shri_i32(t1
, t1
, 8);
4283 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4284 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4285 tcg_gen_or_i32(t1
, t1
, tmp
);
4286 tcg_gen_mov_i32(t0
, rd
);
4288 tcg_temp_free_i32(tmp
);
4289 tcg_temp_free_i32(rd
);
4292 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4296 rd
= tcg_temp_new_i32();
4297 tmp
= tcg_temp_new_i32();
4299 tcg_gen_shli_i32(rd
, t0
, 16);
4300 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4301 tcg_gen_or_i32(rd
, rd
, tmp
);
4302 tcg_gen_shri_i32(t1
, t1
, 16);
4303 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4304 tcg_gen_or_i32(t1
, t1
, tmp
);
4305 tcg_gen_mov_i32(t0
, rd
);
4307 tcg_temp_free_i32(tmp
);
4308 tcg_temp_free_i32(rd
);
4316 } const neon_ls_element_type
[11] = {
4330 /* Translate a NEON load/store element instruction. Return nonzero if the
4331 instruction is invalid. */
4332 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4352 /* FIXME: this access check should not take precedence over UNDEF
4353 * for invalid encodings; we will generate incorrect syndrome information
4354 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4356 if (s
->fp_excp_el
) {
4357 gen_exception_insn(s
, 4, EXCP_UDEF
,
4358 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
4362 if (!s
->vfp_enabled
)
4364 VFP_DREG_D(rd
, insn
);
4365 rn
= (insn
>> 16) & 0xf;
4367 load
= (insn
& (1 << 21)) != 0;
4368 endian
= s
->be_data
;
4369 mmu_idx
= get_mem_index(s
);
4370 if ((insn
& (1 << 23)) == 0) {
4371 /* Load store all elements. */
4372 op
= (insn
>> 8) & 0xf;
4373 size
= (insn
>> 6) & 3;
4376 /* Catch UNDEF cases for bad values of align field */
4379 if (((insn
>> 5) & 1) == 1) {
4384 if (((insn
>> 4) & 3) == 3) {
4391 nregs
= neon_ls_element_type
[op
].nregs
;
4392 interleave
= neon_ls_element_type
[op
].interleave
;
4393 spacing
= neon_ls_element_type
[op
].spacing
;
4394 if (size
== 3 && (interleave
| spacing
) != 1) {
4397 /* For our purposes, bytes are always little-endian. */
4401 /* Consecutive little-endian elements from a single register
4402 * can be promoted to a larger little-endian operation.
4404 if (interleave
== 1 && endian
== MO_LE
) {
4407 tmp64
= tcg_temp_new_i64();
4408 addr
= tcg_temp_new_i32();
4409 tmp2
= tcg_const_i32(1 << size
);
4410 load_reg_var(s
, addr
, rn
);
4411 for (reg
= 0; reg
< nregs
; reg
++) {
4412 for (n
= 0; n
< 8 >> size
; n
++) {
4414 for (xs
= 0; xs
< interleave
; xs
++) {
4415 int tt
= rd
+ reg
+ spacing
* xs
;
4418 gen_aa32_ld_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
4419 neon_store_element64(tt
, n
, size
, tmp64
);
4421 neon_load_element64(tmp64
, tt
, n
, size
);
4422 gen_aa32_st_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
4424 tcg_gen_add_i32(addr
, addr
, tmp2
);
4428 tcg_temp_free_i32(addr
);
4429 tcg_temp_free_i32(tmp2
);
4430 tcg_temp_free_i64(tmp64
);
4431 stride
= nregs
* interleave
* 8;
4433 size
= (insn
>> 10) & 3;
4435 /* Load single element to all lanes. */
4436 int a
= (insn
>> 4) & 1;
4440 size
= (insn
>> 6) & 3;
4441 nregs
= ((insn
>> 8) & 3) + 1;
4444 if (nregs
!= 4 || a
== 0) {
4447 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4450 if (nregs
== 1 && a
== 1 && size
== 0) {
4453 if (nregs
== 3 && a
== 1) {
4456 addr
= tcg_temp_new_i32();
4457 load_reg_var(s
, addr
, rn
);
4459 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
4460 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
4462 stride
= (insn
& (1 << 5)) ? 2 : 1;
4463 vec_size
= nregs
== 1 ? stride
* 8 : 8;
4465 tmp
= tcg_temp_new_i32();
4466 for (reg
= 0; reg
< nregs
; reg
++) {
4467 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
4469 if ((rd
& 1) && vec_size
== 16) {
4470 /* We cannot write 16 bytes at once because the
4471 * destination is unaligned.
4473 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
4475 tcg_gen_gvec_mov(0, neon_reg_offset(rd
+ 1, 0),
4476 neon_reg_offset(rd
, 0), 8, 8);
4478 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
4479 vec_size
, vec_size
, tmp
);
4481 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4484 tcg_temp_free_i32(tmp
);
4485 tcg_temp_free_i32(addr
);
4486 stride
= (1 << size
) * nregs
;
4488 /* Single element. */
4489 int idx
= (insn
>> 4) & 0xf;
4493 reg_idx
= (insn
>> 5) & 7;
4497 reg_idx
= (insn
>> 6) & 3;
4498 stride
= (insn
& (1 << 5)) ? 2 : 1;
4501 reg_idx
= (insn
>> 7) & 1;
4502 stride
= (insn
& (1 << 6)) ? 2 : 1;
4507 nregs
= ((insn
>> 8) & 3) + 1;
4508 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4511 if (((idx
& (1 << size
)) != 0) ||
4512 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4517 if ((idx
& 1) != 0) {
4522 if (size
== 2 && (idx
& 2) != 0) {
4527 if ((size
== 2) && ((idx
& 3) == 3)) {
4534 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4535 /* Attempts to write off the end of the register file
4536 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4537 * the neon_load_reg() would write off the end of the array.
4541 tmp
= tcg_temp_new_i32();
4542 addr
= tcg_temp_new_i32();
4543 load_reg_var(s
, addr
, rn
);
4544 for (reg
= 0; reg
< nregs
; reg
++) {
4546 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
4548 neon_store_element(rd
, reg_idx
, size
, tmp
);
4549 } else { /* Store */
4550 neon_load_element(tmp
, rd
, reg_idx
, size
);
4551 gen_aa32_st_i32(s
, tmp
, addr
, get_mem_index(s
),
4555 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4557 tcg_temp_free_i32(addr
);
4558 tcg_temp_free_i32(tmp
);
4559 stride
= nregs
* (1 << size
);
4565 base
= load_reg(s
, rn
);
4567 tcg_gen_addi_i32(base
, base
, stride
);
4570 index
= load_reg(s
, rm
);
4571 tcg_gen_add_i32(base
, base
, index
);
4572 tcg_temp_free_i32(index
);
4574 store_reg(s
, rn
, base
);
4579 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4582 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4583 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4584 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4589 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4592 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4593 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4594 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4599 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4602 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4603 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4604 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4609 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4612 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4613 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4614 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4619 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4625 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4626 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4631 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4632 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4639 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4640 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4645 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4646 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4653 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4657 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4658 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4659 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4664 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4665 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4666 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4670 tcg_temp_free_i32(src
);
4673 static inline void gen_neon_addl(int size
)
4676 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4677 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4678 case 2: tcg_gen_add_i64(CPU_V001
); break;
4683 static inline void gen_neon_subl(int size
)
4686 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4687 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4688 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4693 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4696 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4697 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4699 tcg_gen_neg_i64(var
, var
);
4705 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4708 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4709 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4714 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4719 switch ((size
<< 1) | u
) {
4720 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4721 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4722 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4723 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4725 tmp
= gen_muls_i64_i32(a
, b
);
4726 tcg_gen_mov_i64(dest
, tmp
);
4727 tcg_temp_free_i64(tmp
);
4730 tmp
= gen_mulu_i64_i32(a
, b
);
4731 tcg_gen_mov_i64(dest
, tmp
);
4732 tcg_temp_free_i64(tmp
);
4737 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4738 Don't forget to clean them now. */
4740 tcg_temp_free_i32(a
);
4741 tcg_temp_free_i32(b
);
4745 static void gen_neon_narrow_op(int op
, int u
, int size
,
4746 TCGv_i32 dest
, TCGv_i64 src
)
4750 gen_neon_unarrow_sats(size
, dest
, src
);
4752 gen_neon_narrow(size
, dest
, src
);
4756 gen_neon_narrow_satu(size
, dest
, src
);
4758 gen_neon_narrow_sats(size
, dest
, src
);
4763 /* Symbolic constants for op fields for Neon 3-register same-length.
4764 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4767 #define NEON_3R_VHADD 0
4768 #define NEON_3R_VQADD 1
4769 #define NEON_3R_VRHADD 2
4770 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4771 #define NEON_3R_VHSUB 4
4772 #define NEON_3R_VQSUB 5
4773 #define NEON_3R_VCGT 6
4774 #define NEON_3R_VCGE 7
4775 #define NEON_3R_VSHL 8
4776 #define NEON_3R_VQSHL 9
4777 #define NEON_3R_VRSHL 10
4778 #define NEON_3R_VQRSHL 11
4779 #define NEON_3R_VMAX 12
4780 #define NEON_3R_VMIN 13
4781 #define NEON_3R_VABD 14
4782 #define NEON_3R_VABA 15
4783 #define NEON_3R_VADD_VSUB 16
4784 #define NEON_3R_VTST_VCEQ 17
4785 #define NEON_3R_VML 18 /* VMLA, VMLS */
4786 #define NEON_3R_VMUL 19
4787 #define NEON_3R_VPMAX 20
4788 #define NEON_3R_VPMIN 21
4789 #define NEON_3R_VQDMULH_VQRDMULH 22
4790 #define NEON_3R_VPADD_VQRDMLAH 23
4791 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4792 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
4793 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4794 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4795 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4796 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4797 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4798 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4800 static const uint8_t neon_3r_sizes
[] = {
4801 [NEON_3R_VHADD
] = 0x7,
4802 [NEON_3R_VQADD
] = 0xf,
4803 [NEON_3R_VRHADD
] = 0x7,
4804 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4805 [NEON_3R_VHSUB
] = 0x7,
4806 [NEON_3R_VQSUB
] = 0xf,
4807 [NEON_3R_VCGT
] = 0x7,
4808 [NEON_3R_VCGE
] = 0x7,
4809 [NEON_3R_VSHL
] = 0xf,
4810 [NEON_3R_VQSHL
] = 0xf,
4811 [NEON_3R_VRSHL
] = 0xf,
4812 [NEON_3R_VQRSHL
] = 0xf,
4813 [NEON_3R_VMAX
] = 0x7,
4814 [NEON_3R_VMIN
] = 0x7,
4815 [NEON_3R_VABD
] = 0x7,
4816 [NEON_3R_VABA
] = 0x7,
4817 [NEON_3R_VADD_VSUB
] = 0xf,
4818 [NEON_3R_VTST_VCEQ
] = 0x7,
4819 [NEON_3R_VML
] = 0x7,
4820 [NEON_3R_VMUL
] = 0x7,
4821 [NEON_3R_VPMAX
] = 0x7,
4822 [NEON_3R_VPMIN
] = 0x7,
4823 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4824 [NEON_3R_VPADD_VQRDMLAH
] = 0x7,
4825 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4826 [NEON_3R_VFM_VQRDMLSH
] = 0x7, /* For VFM, size bit 1 encodes op */
4827 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4828 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4829 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4830 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4831 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4832 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4835 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4836 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4839 #define NEON_2RM_VREV64 0
4840 #define NEON_2RM_VREV32 1
4841 #define NEON_2RM_VREV16 2
4842 #define NEON_2RM_VPADDL 4
4843 #define NEON_2RM_VPADDL_U 5
4844 #define NEON_2RM_AESE 6 /* Includes AESD */
4845 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4846 #define NEON_2RM_VCLS 8
4847 #define NEON_2RM_VCLZ 9
4848 #define NEON_2RM_VCNT 10
4849 #define NEON_2RM_VMVN 11
4850 #define NEON_2RM_VPADAL 12
4851 #define NEON_2RM_VPADAL_U 13
4852 #define NEON_2RM_VQABS 14
4853 #define NEON_2RM_VQNEG 15
4854 #define NEON_2RM_VCGT0 16
4855 #define NEON_2RM_VCGE0 17
4856 #define NEON_2RM_VCEQ0 18
4857 #define NEON_2RM_VCLE0 19
4858 #define NEON_2RM_VCLT0 20
4859 #define NEON_2RM_SHA1H 21
4860 #define NEON_2RM_VABS 22
4861 #define NEON_2RM_VNEG 23
4862 #define NEON_2RM_VCGT0_F 24
4863 #define NEON_2RM_VCGE0_F 25
4864 #define NEON_2RM_VCEQ0_F 26
4865 #define NEON_2RM_VCLE0_F 27
4866 #define NEON_2RM_VCLT0_F 28
4867 #define NEON_2RM_VABS_F 30
4868 #define NEON_2RM_VNEG_F 31
4869 #define NEON_2RM_VSWP 32
4870 #define NEON_2RM_VTRN 33
4871 #define NEON_2RM_VUZP 34
4872 #define NEON_2RM_VZIP 35
4873 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4874 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4875 #define NEON_2RM_VSHLL 38
4876 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4877 #define NEON_2RM_VRINTN 40
4878 #define NEON_2RM_VRINTX 41
4879 #define NEON_2RM_VRINTA 42
4880 #define NEON_2RM_VRINTZ 43
4881 #define NEON_2RM_VCVT_F16_F32 44
4882 #define NEON_2RM_VRINTM 45
4883 #define NEON_2RM_VCVT_F32_F16 46
4884 #define NEON_2RM_VRINTP 47
4885 #define NEON_2RM_VCVTAU 48
4886 #define NEON_2RM_VCVTAS 49
4887 #define NEON_2RM_VCVTNU 50
4888 #define NEON_2RM_VCVTNS 51
4889 #define NEON_2RM_VCVTPU 52
4890 #define NEON_2RM_VCVTPS 53
4891 #define NEON_2RM_VCVTMU 54
4892 #define NEON_2RM_VCVTMS 55
4893 #define NEON_2RM_VRECPE 56
4894 #define NEON_2RM_VRSQRTE 57
4895 #define NEON_2RM_VRECPE_F 58
4896 #define NEON_2RM_VRSQRTE_F 59
4897 #define NEON_2RM_VCVT_FS 60
4898 #define NEON_2RM_VCVT_FU 61
4899 #define NEON_2RM_VCVT_SF 62
4900 #define NEON_2RM_VCVT_UF 63
4902 static int neon_2rm_is_float_op(int op
)
4904 /* Return true if this neon 2reg-misc op is float-to-float */
4905 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4906 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4907 op
== NEON_2RM_VRINTM
||
4908 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4909 op
>= NEON_2RM_VRECPE_F
);
4912 static bool neon_2rm_is_v8_op(int op
)
4914 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4916 case NEON_2RM_VRINTN
:
4917 case NEON_2RM_VRINTA
:
4918 case NEON_2RM_VRINTM
:
4919 case NEON_2RM_VRINTP
:
4920 case NEON_2RM_VRINTZ
:
4921 case NEON_2RM_VRINTX
:
4922 case NEON_2RM_VCVTAU
:
4923 case NEON_2RM_VCVTAS
:
4924 case NEON_2RM_VCVTNU
:
4925 case NEON_2RM_VCVTNS
:
4926 case NEON_2RM_VCVTPU
:
4927 case NEON_2RM_VCVTPS
:
4928 case NEON_2RM_VCVTMU
:
4929 case NEON_2RM_VCVTMS
:
4936 /* Each entry in this array has bit n set if the insn allows
4937 * size value n (otherwise it will UNDEF). Since unallocated
4938 * op values will have no bits set they always UNDEF.
4940 static const uint8_t neon_2rm_sizes
[] = {
4941 [NEON_2RM_VREV64
] = 0x7,
4942 [NEON_2RM_VREV32
] = 0x3,
4943 [NEON_2RM_VREV16
] = 0x1,
4944 [NEON_2RM_VPADDL
] = 0x7,
4945 [NEON_2RM_VPADDL_U
] = 0x7,
4946 [NEON_2RM_AESE
] = 0x1,
4947 [NEON_2RM_AESMC
] = 0x1,
4948 [NEON_2RM_VCLS
] = 0x7,
4949 [NEON_2RM_VCLZ
] = 0x7,
4950 [NEON_2RM_VCNT
] = 0x1,
4951 [NEON_2RM_VMVN
] = 0x1,
4952 [NEON_2RM_VPADAL
] = 0x7,
4953 [NEON_2RM_VPADAL_U
] = 0x7,
4954 [NEON_2RM_VQABS
] = 0x7,
4955 [NEON_2RM_VQNEG
] = 0x7,
4956 [NEON_2RM_VCGT0
] = 0x7,
4957 [NEON_2RM_VCGE0
] = 0x7,
4958 [NEON_2RM_VCEQ0
] = 0x7,
4959 [NEON_2RM_VCLE0
] = 0x7,
4960 [NEON_2RM_VCLT0
] = 0x7,
4961 [NEON_2RM_SHA1H
] = 0x4,
4962 [NEON_2RM_VABS
] = 0x7,
4963 [NEON_2RM_VNEG
] = 0x7,
4964 [NEON_2RM_VCGT0_F
] = 0x4,
4965 [NEON_2RM_VCGE0_F
] = 0x4,
4966 [NEON_2RM_VCEQ0_F
] = 0x4,
4967 [NEON_2RM_VCLE0_F
] = 0x4,
4968 [NEON_2RM_VCLT0_F
] = 0x4,
4969 [NEON_2RM_VABS_F
] = 0x4,
4970 [NEON_2RM_VNEG_F
] = 0x4,
4971 [NEON_2RM_VSWP
] = 0x1,
4972 [NEON_2RM_VTRN
] = 0x7,
4973 [NEON_2RM_VUZP
] = 0x7,
4974 [NEON_2RM_VZIP
] = 0x7,
4975 [NEON_2RM_VMOVN
] = 0x7,
4976 [NEON_2RM_VQMOVN
] = 0x7,
4977 [NEON_2RM_VSHLL
] = 0x7,
4978 [NEON_2RM_SHA1SU1
] = 0x4,
4979 [NEON_2RM_VRINTN
] = 0x4,
4980 [NEON_2RM_VRINTX
] = 0x4,
4981 [NEON_2RM_VRINTA
] = 0x4,
4982 [NEON_2RM_VRINTZ
] = 0x4,
4983 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4984 [NEON_2RM_VRINTM
] = 0x4,
4985 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4986 [NEON_2RM_VRINTP
] = 0x4,
4987 [NEON_2RM_VCVTAU
] = 0x4,
4988 [NEON_2RM_VCVTAS
] = 0x4,
4989 [NEON_2RM_VCVTNU
] = 0x4,
4990 [NEON_2RM_VCVTNS
] = 0x4,
4991 [NEON_2RM_VCVTPU
] = 0x4,
4992 [NEON_2RM_VCVTPS
] = 0x4,
4993 [NEON_2RM_VCVTMU
] = 0x4,
4994 [NEON_2RM_VCVTMS
] = 0x4,
4995 [NEON_2RM_VRECPE
] = 0x4,
4996 [NEON_2RM_VRSQRTE
] = 0x4,
4997 [NEON_2RM_VRECPE_F
] = 0x4,
4998 [NEON_2RM_VRSQRTE_F
] = 0x4,
4999 [NEON_2RM_VCVT_FS
] = 0x4,
5000 [NEON_2RM_VCVT_FU
] = 0x4,
5001 [NEON_2RM_VCVT_SF
] = 0x4,
5002 [NEON_2RM_VCVT_UF
] = 0x4,
5006 /* Expand v8.1 simd helper. */
5007 static int do_v81_helper(DisasContext
*s
, gen_helper_gvec_3_ptr
*fn
,
5008 int q
, int rd
, int rn
, int rm
)
5010 if (dc_isar_feature(aa32_rdm
, s
)) {
5011 int opr_sz
= (1 + q
) * 8;
5012 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
5013 vfp_reg_offset(1, rn
),
5014 vfp_reg_offset(1, rm
), cpu_env
,
5015 opr_sz
, opr_sz
, 0, fn
);
5021 static void gen_ssra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5023 tcg_gen_vec_sar8i_i64(a
, a
, shift
);
5024 tcg_gen_vec_add8_i64(d
, d
, a
);
5027 static void gen_ssra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5029 tcg_gen_vec_sar16i_i64(a
, a
, shift
);
5030 tcg_gen_vec_add16_i64(d
, d
, a
);
5033 static void gen_ssra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5035 tcg_gen_sari_i32(a
, a
, shift
);
5036 tcg_gen_add_i32(d
, d
, a
);
5039 static void gen_ssra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5041 tcg_gen_sari_i64(a
, a
, shift
);
5042 tcg_gen_add_i64(d
, d
, a
);
5045 static void gen_ssra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5047 tcg_gen_sari_vec(vece
, a
, a
, sh
);
5048 tcg_gen_add_vec(vece
, d
, d
, a
);
5051 static const TCGOpcode vecop_list_ssra
[] = {
5052 INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
5055 const GVecGen2i ssra_op
[4] = {
5056 { .fni8
= gen_ssra8_i64
,
5057 .fniv
= gen_ssra_vec
,
5059 .opt_opc
= vecop_list_ssra
,
5061 { .fni8
= gen_ssra16_i64
,
5062 .fniv
= gen_ssra_vec
,
5064 .opt_opc
= vecop_list_ssra
,
5066 { .fni4
= gen_ssra32_i32
,
5067 .fniv
= gen_ssra_vec
,
5069 .opt_opc
= vecop_list_ssra
,
5071 { .fni8
= gen_ssra64_i64
,
5072 .fniv
= gen_ssra_vec
,
5073 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5074 .opt_opc
= vecop_list_ssra
,
5079 static void gen_usra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5081 tcg_gen_vec_shr8i_i64(a
, a
, shift
);
5082 tcg_gen_vec_add8_i64(d
, d
, a
);
5085 static void gen_usra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5087 tcg_gen_vec_shr16i_i64(a
, a
, shift
);
5088 tcg_gen_vec_add16_i64(d
, d
, a
);
5091 static void gen_usra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5093 tcg_gen_shri_i32(a
, a
, shift
);
5094 tcg_gen_add_i32(d
, d
, a
);
5097 static void gen_usra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5099 tcg_gen_shri_i64(a
, a
, shift
);
5100 tcg_gen_add_i64(d
, d
, a
);
5103 static void gen_usra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5105 tcg_gen_shri_vec(vece
, a
, a
, sh
);
5106 tcg_gen_add_vec(vece
, d
, d
, a
);
5109 static const TCGOpcode vecop_list_usra
[] = {
5110 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
5113 const GVecGen2i usra_op
[4] = {
5114 { .fni8
= gen_usra8_i64
,
5115 .fniv
= gen_usra_vec
,
5117 .opt_opc
= vecop_list_usra
,
5119 { .fni8
= gen_usra16_i64
,
5120 .fniv
= gen_usra_vec
,
5122 .opt_opc
= vecop_list_usra
,
5124 { .fni4
= gen_usra32_i32
,
5125 .fniv
= gen_usra_vec
,
5127 .opt_opc
= vecop_list_usra
,
5129 { .fni8
= gen_usra64_i64
,
5130 .fniv
= gen_usra_vec
,
5131 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5133 .opt_opc
= vecop_list_usra
,
5137 static void gen_shr8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5139 uint64_t mask
= dup_const(MO_8
, 0xff >> shift
);
5140 TCGv_i64 t
= tcg_temp_new_i64();
5142 tcg_gen_shri_i64(t
, a
, shift
);
5143 tcg_gen_andi_i64(t
, t
, mask
);
5144 tcg_gen_andi_i64(d
, d
, ~mask
);
5145 tcg_gen_or_i64(d
, d
, t
);
5146 tcg_temp_free_i64(t
);
5149 static void gen_shr16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5151 uint64_t mask
= dup_const(MO_16
, 0xffff >> shift
);
5152 TCGv_i64 t
= tcg_temp_new_i64();
5154 tcg_gen_shri_i64(t
, a
, shift
);
5155 tcg_gen_andi_i64(t
, t
, mask
);
5156 tcg_gen_andi_i64(d
, d
, ~mask
);
5157 tcg_gen_or_i64(d
, d
, t
);
5158 tcg_temp_free_i64(t
);
5161 static void gen_shr32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5163 tcg_gen_shri_i32(a
, a
, shift
);
5164 tcg_gen_deposit_i32(d
, d
, a
, 0, 32 - shift
);
5167 static void gen_shr64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5169 tcg_gen_shri_i64(a
, a
, shift
);
5170 tcg_gen_deposit_i64(d
, d
, a
, 0, 64 - shift
);
5173 static void gen_shr_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5176 tcg_gen_mov_vec(d
, a
);
5178 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
5179 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
5181 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK((8 << vece
) - sh
, sh
));
5182 tcg_gen_shri_vec(vece
, t
, a
, sh
);
5183 tcg_gen_and_vec(vece
, d
, d
, m
);
5184 tcg_gen_or_vec(vece
, d
, d
, t
);
5186 tcg_temp_free_vec(t
);
5187 tcg_temp_free_vec(m
);
5191 static const TCGOpcode vecop_list_sri
[] = { INDEX_op_shri_vec
, 0 };
5193 const GVecGen2i sri_op
[4] = {
5194 { .fni8
= gen_shr8_ins_i64
,
5195 .fniv
= gen_shr_ins_vec
,
5197 .opt_opc
= vecop_list_sri
,
5199 { .fni8
= gen_shr16_ins_i64
,
5200 .fniv
= gen_shr_ins_vec
,
5202 .opt_opc
= vecop_list_sri
,
5204 { .fni4
= gen_shr32_ins_i32
,
5205 .fniv
= gen_shr_ins_vec
,
5207 .opt_opc
= vecop_list_sri
,
5209 { .fni8
= gen_shr64_ins_i64
,
5210 .fniv
= gen_shr_ins_vec
,
5211 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5213 .opt_opc
= vecop_list_sri
,
5217 static void gen_shl8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5219 uint64_t mask
= dup_const(MO_8
, 0xff << shift
);
5220 TCGv_i64 t
= tcg_temp_new_i64();
5222 tcg_gen_shli_i64(t
, a
, shift
);
5223 tcg_gen_andi_i64(t
, t
, mask
);
5224 tcg_gen_andi_i64(d
, d
, ~mask
);
5225 tcg_gen_or_i64(d
, d
, t
);
5226 tcg_temp_free_i64(t
);
5229 static void gen_shl16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5231 uint64_t mask
= dup_const(MO_16
, 0xffff << shift
);
5232 TCGv_i64 t
= tcg_temp_new_i64();
5234 tcg_gen_shli_i64(t
, a
, shift
);
5235 tcg_gen_andi_i64(t
, t
, mask
);
5236 tcg_gen_andi_i64(d
, d
, ~mask
);
5237 tcg_gen_or_i64(d
, d
, t
);
5238 tcg_temp_free_i64(t
);
5241 static void gen_shl32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5243 tcg_gen_deposit_i32(d
, d
, a
, shift
, 32 - shift
);
5246 static void gen_shl64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5248 tcg_gen_deposit_i64(d
, d
, a
, shift
, 64 - shift
);
5251 static void gen_shl_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5254 tcg_gen_mov_vec(d
, a
);
5256 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
5257 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
5259 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK(0, sh
));
5260 tcg_gen_shli_vec(vece
, t
, a
, sh
);
5261 tcg_gen_and_vec(vece
, d
, d
, m
);
5262 tcg_gen_or_vec(vece
, d
, d
, t
);
5264 tcg_temp_free_vec(t
);
5265 tcg_temp_free_vec(m
);
5269 static const TCGOpcode vecop_list_sli
[] = { INDEX_op_shli_vec
, 0 };
5271 const GVecGen2i sli_op
[4] = {
5272 { .fni8
= gen_shl8_ins_i64
,
5273 .fniv
= gen_shl_ins_vec
,
5275 .opt_opc
= vecop_list_sli
,
5277 { .fni8
= gen_shl16_ins_i64
,
5278 .fniv
= gen_shl_ins_vec
,
5280 .opt_opc
= vecop_list_sli
,
5282 { .fni4
= gen_shl32_ins_i32
,
5283 .fniv
= gen_shl_ins_vec
,
5285 .opt_opc
= vecop_list_sli
,
5287 { .fni8
= gen_shl64_ins_i64
,
5288 .fniv
= gen_shl_ins_vec
,
5289 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5291 .opt_opc
= vecop_list_sli
,
5295 static void gen_mla8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5297 gen_helper_neon_mul_u8(a
, a
, b
);
5298 gen_helper_neon_add_u8(d
, d
, a
);
5301 static void gen_mls8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5303 gen_helper_neon_mul_u8(a
, a
, b
);
5304 gen_helper_neon_sub_u8(d
, d
, a
);
5307 static void gen_mla16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5309 gen_helper_neon_mul_u16(a
, a
, b
);
5310 gen_helper_neon_add_u16(d
, d
, a
);
5313 static void gen_mls16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5315 gen_helper_neon_mul_u16(a
, a
, b
);
5316 gen_helper_neon_sub_u16(d
, d
, a
);
5319 static void gen_mla32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5321 tcg_gen_mul_i32(a
, a
, b
);
5322 tcg_gen_add_i32(d
, d
, a
);
5325 static void gen_mls32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5327 tcg_gen_mul_i32(a
, a
, b
);
5328 tcg_gen_sub_i32(d
, d
, a
);
5331 static void gen_mla64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5333 tcg_gen_mul_i64(a
, a
, b
);
5334 tcg_gen_add_i64(d
, d
, a
);
5337 static void gen_mls64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5339 tcg_gen_mul_i64(a
, a
, b
);
5340 tcg_gen_sub_i64(d
, d
, a
);
5343 static void gen_mla_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5345 tcg_gen_mul_vec(vece
, a
, a
, b
);
5346 tcg_gen_add_vec(vece
, d
, d
, a
);
5349 static void gen_mls_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5351 tcg_gen_mul_vec(vece
, a
, a
, b
);
5352 tcg_gen_sub_vec(vece
, d
, d
, a
);
5355 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
5356 * these tables are shared with AArch64 which does support them.
5359 static const TCGOpcode vecop_list_mla
[] = {
5360 INDEX_op_mul_vec
, INDEX_op_add_vec
, 0
5363 static const TCGOpcode vecop_list_mls
[] = {
5364 INDEX_op_mul_vec
, INDEX_op_sub_vec
, 0
5367 const GVecGen3 mla_op
[4] = {
5368 { .fni4
= gen_mla8_i32
,
5369 .fniv
= gen_mla_vec
,
5371 .opt_opc
= vecop_list_mla
,
5373 { .fni4
= gen_mla16_i32
,
5374 .fniv
= gen_mla_vec
,
5376 .opt_opc
= vecop_list_mla
,
5378 { .fni4
= gen_mla32_i32
,
5379 .fniv
= gen_mla_vec
,
5381 .opt_opc
= vecop_list_mla
,
5383 { .fni8
= gen_mla64_i64
,
5384 .fniv
= gen_mla_vec
,
5385 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5387 .opt_opc
= vecop_list_mla
,
5391 const GVecGen3 mls_op
[4] = {
5392 { .fni4
= gen_mls8_i32
,
5393 .fniv
= gen_mls_vec
,
5395 .opt_opc
= vecop_list_mls
,
5397 { .fni4
= gen_mls16_i32
,
5398 .fniv
= gen_mls_vec
,
5400 .opt_opc
= vecop_list_mls
,
5402 { .fni4
= gen_mls32_i32
,
5403 .fniv
= gen_mls_vec
,
5405 .opt_opc
= vecop_list_mls
,
5407 { .fni8
= gen_mls64_i64
,
5408 .fniv
= gen_mls_vec
,
5409 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5411 .opt_opc
= vecop_list_mls
,
5415 /* CMTST : test is "if (X & Y != 0)". */
5416 static void gen_cmtst_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5418 tcg_gen_and_i32(d
, a
, b
);
5419 tcg_gen_setcondi_i32(TCG_COND_NE
, d
, d
, 0);
5420 tcg_gen_neg_i32(d
, d
);
5423 void gen_cmtst_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5425 tcg_gen_and_i64(d
, a
, b
);
5426 tcg_gen_setcondi_i64(TCG_COND_NE
, d
, d
, 0);
5427 tcg_gen_neg_i64(d
, d
);
5430 static void gen_cmtst_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5432 tcg_gen_and_vec(vece
, d
, a
, b
);
5433 tcg_gen_dupi_vec(vece
, a
, 0);
5434 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, d
, d
, a
);
5437 static const TCGOpcode vecop_list_cmtst
[] = { INDEX_op_cmp_vec
, 0 };
5439 const GVecGen3 cmtst_op
[4] = {
5440 { .fni4
= gen_helper_neon_tst_u8
,
5441 .fniv
= gen_cmtst_vec
,
5442 .opt_opc
= vecop_list_cmtst
,
5444 { .fni4
= gen_helper_neon_tst_u16
,
5445 .fniv
= gen_cmtst_vec
,
5446 .opt_opc
= vecop_list_cmtst
,
5448 { .fni4
= gen_cmtst_i32
,
5449 .fniv
= gen_cmtst_vec
,
5450 .opt_opc
= vecop_list_cmtst
,
5452 { .fni8
= gen_cmtst_i64
,
5453 .fniv
= gen_cmtst_vec
,
5454 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5455 .opt_opc
= vecop_list_cmtst
,
5459 static void gen_uqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5460 TCGv_vec a
, TCGv_vec b
)
5462 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5463 tcg_gen_add_vec(vece
, x
, a
, b
);
5464 tcg_gen_usadd_vec(vece
, t
, a
, b
);
5465 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5466 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5467 tcg_temp_free_vec(x
);
5470 static const TCGOpcode vecop_list_uqadd
[] = {
5471 INDEX_op_usadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
5474 const GVecGen4 uqadd_op
[4] = {
5475 { .fniv
= gen_uqadd_vec
,
5476 .fno
= gen_helper_gvec_uqadd_b
,
5478 .opt_opc
= vecop_list_uqadd
,
5480 { .fniv
= gen_uqadd_vec
,
5481 .fno
= gen_helper_gvec_uqadd_h
,
5483 .opt_opc
= vecop_list_uqadd
,
5485 { .fniv
= gen_uqadd_vec
,
5486 .fno
= gen_helper_gvec_uqadd_s
,
5488 .opt_opc
= vecop_list_uqadd
,
5490 { .fniv
= gen_uqadd_vec
,
5491 .fno
= gen_helper_gvec_uqadd_d
,
5493 .opt_opc
= vecop_list_uqadd
,
5497 static void gen_sqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5498 TCGv_vec a
, TCGv_vec b
)
5500 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5501 tcg_gen_add_vec(vece
, x
, a
, b
);
5502 tcg_gen_ssadd_vec(vece
, t
, a
, b
);
5503 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5504 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5505 tcg_temp_free_vec(x
);
5508 static const TCGOpcode vecop_list_sqadd
[] = {
5509 INDEX_op_ssadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
5512 const GVecGen4 sqadd_op
[4] = {
5513 { .fniv
= gen_sqadd_vec
,
5514 .fno
= gen_helper_gvec_sqadd_b
,
5515 .opt_opc
= vecop_list_sqadd
,
5518 { .fniv
= gen_sqadd_vec
,
5519 .fno
= gen_helper_gvec_sqadd_h
,
5520 .opt_opc
= vecop_list_sqadd
,
5523 { .fniv
= gen_sqadd_vec
,
5524 .fno
= gen_helper_gvec_sqadd_s
,
5525 .opt_opc
= vecop_list_sqadd
,
5528 { .fniv
= gen_sqadd_vec
,
5529 .fno
= gen_helper_gvec_sqadd_d
,
5530 .opt_opc
= vecop_list_sqadd
,
5535 static void gen_uqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5536 TCGv_vec a
, TCGv_vec b
)
5538 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5539 tcg_gen_sub_vec(vece
, x
, a
, b
);
5540 tcg_gen_ussub_vec(vece
, t
, a
, b
);
5541 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5542 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5543 tcg_temp_free_vec(x
);
5546 static const TCGOpcode vecop_list_uqsub
[] = {
5547 INDEX_op_ussub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
5550 const GVecGen4 uqsub_op
[4] = {
5551 { .fniv
= gen_uqsub_vec
,
5552 .fno
= gen_helper_gvec_uqsub_b
,
5553 .opt_opc
= vecop_list_uqsub
,
5556 { .fniv
= gen_uqsub_vec
,
5557 .fno
= gen_helper_gvec_uqsub_h
,
5558 .opt_opc
= vecop_list_uqsub
,
5561 { .fniv
= gen_uqsub_vec
,
5562 .fno
= gen_helper_gvec_uqsub_s
,
5563 .opt_opc
= vecop_list_uqsub
,
5566 { .fniv
= gen_uqsub_vec
,
5567 .fno
= gen_helper_gvec_uqsub_d
,
5568 .opt_opc
= vecop_list_uqsub
,
5573 static void gen_sqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5574 TCGv_vec a
, TCGv_vec b
)
5576 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5577 tcg_gen_sub_vec(vece
, x
, a
, b
);
5578 tcg_gen_sssub_vec(vece
, t
, a
, b
);
5579 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5580 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5581 tcg_temp_free_vec(x
);
5584 static const TCGOpcode vecop_list_sqsub
[] = {
5585 INDEX_op_sssub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
5588 const GVecGen4 sqsub_op
[4] = {
5589 { .fniv
= gen_sqsub_vec
,
5590 .fno
= gen_helper_gvec_sqsub_b
,
5591 .opt_opc
= vecop_list_sqsub
,
5594 { .fniv
= gen_sqsub_vec
,
5595 .fno
= gen_helper_gvec_sqsub_h
,
5596 .opt_opc
= vecop_list_sqsub
,
5599 { .fniv
= gen_sqsub_vec
,
5600 .fno
= gen_helper_gvec_sqsub_s
,
5601 .opt_opc
= vecop_list_sqsub
,
5604 { .fniv
= gen_sqsub_vec
,
5605 .fno
= gen_helper_gvec_sqsub_d
,
5606 .opt_opc
= vecop_list_sqsub
,
5611 /* Translate a NEON data processing instruction. Return nonzero if the
5612 instruction is invalid.
5613 We process data in a mixture of 32-bit and 64-bit chunks.
5614 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5616 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5620 int rd
, rn
, rm
, rd_ofs
, rn_ofs
, rm_ofs
;
5629 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5630 TCGv_ptr ptr1
, ptr2
, ptr3
;
5633 /* FIXME: this access check should not take precedence over UNDEF
5634 * for invalid encodings; we will generate incorrect syndrome information
5635 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5637 if (s
->fp_excp_el
) {
5638 gen_exception_insn(s
, 4, EXCP_UDEF
,
5639 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
5643 if (!s
->vfp_enabled
)
5645 q
= (insn
& (1 << 6)) != 0;
5646 u
= (insn
>> 24) & 1;
5647 VFP_DREG_D(rd
, insn
);
5648 VFP_DREG_N(rn
, insn
);
5649 VFP_DREG_M(rm
, insn
);
5650 size
= (insn
>> 20) & 3;
5651 vec_size
= q
? 16 : 8;
5652 rd_ofs
= neon_reg_offset(rd
, 0);
5653 rn_ofs
= neon_reg_offset(rn
, 0);
5654 rm_ofs
= neon_reg_offset(rm
, 0);
5656 if ((insn
& (1 << 23)) == 0) {
5657 /* Three register same length. */
5658 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5659 /* Catch invalid op and bad size combinations: UNDEF */
5660 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5663 /* All insns of this form UNDEF for either this condition or the
5664 * superset of cases "Q==1"; we catch the latter later.
5666 if (q
&& ((rd
| rn
| rm
) & 1)) {
5671 /* The SHA-1/SHA-256 3-register instructions require special
5672 * treatment here, as their size field is overloaded as an
5673 * op type selector, and they all consume their input in a
5679 if (!u
) { /* SHA-1 */
5680 if (!dc_isar_feature(aa32_sha1
, s
)) {
5683 ptr1
= vfp_reg_ptr(true, rd
);
5684 ptr2
= vfp_reg_ptr(true, rn
);
5685 ptr3
= vfp_reg_ptr(true, rm
);
5686 tmp4
= tcg_const_i32(size
);
5687 gen_helper_crypto_sha1_3reg(ptr1
, ptr2
, ptr3
, tmp4
);
5688 tcg_temp_free_i32(tmp4
);
5689 } else { /* SHA-256 */
5690 if (!dc_isar_feature(aa32_sha2
, s
) || size
== 3) {
5693 ptr1
= vfp_reg_ptr(true, rd
);
5694 ptr2
= vfp_reg_ptr(true, rn
);
5695 ptr3
= vfp_reg_ptr(true, rm
);
5698 gen_helper_crypto_sha256h(ptr1
, ptr2
, ptr3
);
5701 gen_helper_crypto_sha256h2(ptr1
, ptr2
, ptr3
);
5704 gen_helper_crypto_sha256su1(ptr1
, ptr2
, ptr3
);
5708 tcg_temp_free_ptr(ptr1
);
5709 tcg_temp_free_ptr(ptr2
);
5710 tcg_temp_free_ptr(ptr3
);
5713 case NEON_3R_VPADD_VQRDMLAH
:
5720 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s16
,
5723 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s32
,
5728 case NEON_3R_VFM_VQRDMLSH
:
5739 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s16
,
5742 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s32
,
5747 case NEON_3R_LOGIC
: /* Logic ops. */
5748 switch ((u
<< 2) | size
) {
5750 tcg_gen_gvec_and(0, rd_ofs
, rn_ofs
, rm_ofs
,
5751 vec_size
, vec_size
);
5754 tcg_gen_gvec_andc(0, rd_ofs
, rn_ofs
, rm_ofs
,
5755 vec_size
, vec_size
);
5758 tcg_gen_gvec_or(0, rd_ofs
, rn_ofs
, rm_ofs
,
5759 vec_size
, vec_size
);
5762 tcg_gen_gvec_orc(0, rd_ofs
, rn_ofs
, rm_ofs
,
5763 vec_size
, vec_size
);
5766 tcg_gen_gvec_xor(0, rd_ofs
, rn_ofs
, rm_ofs
,
5767 vec_size
, vec_size
);
5770 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rd_ofs
, rn_ofs
, rm_ofs
,
5771 vec_size
, vec_size
);
5774 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rn_ofs
, rd_ofs
,
5775 vec_size
, vec_size
);
5778 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rd_ofs
, rn_ofs
,
5779 vec_size
, vec_size
);
5784 case NEON_3R_VADD_VSUB
:
5786 tcg_gen_gvec_sub(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5787 vec_size
, vec_size
);
5789 tcg_gen_gvec_add(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5790 vec_size
, vec_size
);
5795 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
5796 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5797 (u
? uqadd_op
: sqadd_op
) + size
);
5801 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
5802 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5803 (u
? uqsub_op
: sqsub_op
) + size
);
5806 case NEON_3R_VMUL
: /* VMUL */
5808 /* Polynomial case allows only P8 and is handled below. */
5813 tcg_gen_gvec_mul(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5814 vec_size
, vec_size
);
5819 case NEON_3R_VML
: /* VMLA, VMLS */
5820 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5821 u
? &mls_op
[size
] : &mla_op
[size
]);
5824 case NEON_3R_VTST_VCEQ
:
5826 tcg_gen_gvec_cmp(TCG_COND_EQ
, size
, rd_ofs
, rn_ofs
, rm_ofs
,
5827 vec_size
, vec_size
);
5829 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
,
5830 vec_size
, vec_size
, &cmtst_op
[size
]);
5835 tcg_gen_gvec_cmp(u
? TCG_COND_GTU
: TCG_COND_GT
, size
,
5836 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
5840 tcg_gen_gvec_cmp(u
? TCG_COND_GEU
: TCG_COND_GE
, size
,
5841 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
5846 tcg_gen_gvec_umax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5847 vec_size
, vec_size
);
5849 tcg_gen_gvec_smax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5850 vec_size
, vec_size
);
5855 tcg_gen_gvec_umin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5856 vec_size
, vec_size
);
5858 tcg_gen_gvec_smin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5859 vec_size
, vec_size
);
5865 /* 64-bit element instructions. */
5866 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5867 neon_load_reg64(cpu_V0
, rn
+ pass
);
5868 neon_load_reg64(cpu_V1
, rm
+ pass
);
5872 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5874 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5879 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5882 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5888 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5890 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5893 case NEON_3R_VQRSHL
:
5895 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5898 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5905 neon_store_reg64(cpu_V0
, rd
+ pass
);
5914 case NEON_3R_VQRSHL
:
5917 /* Shift instruction operands are reversed. */
5923 case NEON_3R_VPADD_VQRDMLAH
:
5928 case NEON_3R_FLOAT_ARITH
:
5929 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5931 case NEON_3R_FLOAT_MINMAX
:
5932 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5934 case NEON_3R_FLOAT_CMP
:
5936 /* no encoding for U=0 C=1x */
5940 case NEON_3R_FLOAT_ACMP
:
5945 case NEON_3R_FLOAT_MISC
:
5946 /* VMAXNM/VMINNM in ARMv8 */
5947 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5951 case NEON_3R_VFM_VQRDMLSH
:
5952 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
5960 if (pairwise
&& q
) {
5961 /* All the pairwise insns UNDEF if Q is set */
5965 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5970 tmp
= neon_load_reg(rn
, 0);
5971 tmp2
= neon_load_reg(rn
, 1);
5973 tmp
= neon_load_reg(rm
, 0);
5974 tmp2
= neon_load_reg(rm
, 1);
5978 tmp
= neon_load_reg(rn
, pass
);
5979 tmp2
= neon_load_reg(rm
, pass
);
5983 GEN_NEON_INTEGER_OP(hadd
);
5985 case NEON_3R_VRHADD
:
5986 GEN_NEON_INTEGER_OP(rhadd
);
5989 GEN_NEON_INTEGER_OP(hsub
);
5992 GEN_NEON_INTEGER_OP(shl
);
5995 GEN_NEON_INTEGER_OP_ENV(qshl
);
5998 GEN_NEON_INTEGER_OP(rshl
);
6000 case NEON_3R_VQRSHL
:
6001 GEN_NEON_INTEGER_OP_ENV(qrshl
);
6004 GEN_NEON_INTEGER_OP(abd
);
6007 GEN_NEON_INTEGER_OP(abd
);
6008 tcg_temp_free_i32(tmp2
);
6009 tmp2
= neon_load_reg(rd
, pass
);
6010 gen_neon_add(size
, tmp
, tmp2
);
6013 /* VMUL.P8; other cases already eliminated. */
6014 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
6017 GEN_NEON_INTEGER_OP(pmax
);
6020 GEN_NEON_INTEGER_OP(pmin
);
6022 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
6023 if (!u
) { /* VQDMULH */
6026 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6029 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6033 } else { /* VQRDMULH */
6036 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6039 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6045 case NEON_3R_VPADD_VQRDMLAH
:
6047 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
6048 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
6049 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
6053 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
6055 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6056 switch ((u
<< 2) | size
) {
6059 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6062 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
6065 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
6070 tcg_temp_free_ptr(fpstatus
);
6073 case NEON_3R_FLOAT_MULTIPLY
:
6075 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6076 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6078 tcg_temp_free_i32(tmp2
);
6079 tmp2
= neon_load_reg(rd
, pass
);
6081 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6083 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6086 tcg_temp_free_ptr(fpstatus
);
6089 case NEON_3R_FLOAT_CMP
:
6091 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6093 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6096 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6098 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6101 tcg_temp_free_ptr(fpstatus
);
6104 case NEON_3R_FLOAT_ACMP
:
6106 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6108 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6110 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6112 tcg_temp_free_ptr(fpstatus
);
6115 case NEON_3R_FLOAT_MINMAX
:
6117 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6119 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6121 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6123 tcg_temp_free_ptr(fpstatus
);
6126 case NEON_3R_FLOAT_MISC
:
6129 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6131 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6133 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6135 tcg_temp_free_ptr(fpstatus
);
6138 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6140 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6144 case NEON_3R_VFM_VQRDMLSH
:
6146 /* VFMA, VFMS: fused multiply-add */
6147 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6148 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6151 gen_helper_vfp_negs(tmp
, tmp
);
6153 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6154 tcg_temp_free_i32(tmp3
);
6155 tcg_temp_free_ptr(fpstatus
);
6161 tcg_temp_free_i32(tmp2
);
6163 /* Save the result. For elementwise operations we can put it
6164 straight into the destination register. For pairwise operations
6165 we have to be careful to avoid clobbering the source operands. */
6166 if (pairwise
&& rd
== rm
) {
6167 neon_store_scratch(pass
, tmp
);
6169 neon_store_reg(rd
, pass
, tmp
);
6173 if (pairwise
&& rd
== rm
) {
6174 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6175 tmp
= neon_load_scratch(pass
);
6176 neon_store_reg(rd
, pass
, tmp
);
6179 /* End of 3 register same size operations. */
6180 } else if (insn
& (1 << 4)) {
6181 if ((insn
& 0x00380080) != 0) {
6182 /* Two registers and shift. */
6183 op
= (insn
>> 8) & 0xf;
6184 if (insn
& (1 << 7)) {
6192 while ((insn
& (1 << (size
+ 19))) == 0)
6195 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6197 /* Shift by immediate:
6198 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6199 if (q
&& ((rd
| rm
) & 1)) {
6202 if (!u
&& (op
== 4 || op
== 6)) {
6205 /* Right shifts are encoded as N - shift, where N is the
6206 element size in bits. */
6208 shift
= shift
- (1 << (size
+ 3));
6213 /* Right shift comes here negative. */
6215 /* Shifts larger than the element size are architecturally
6216 * valid. Unsigned results in all zeros; signed results
6220 tcg_gen_gvec_sari(size
, rd_ofs
, rm_ofs
,
6221 MIN(shift
, (8 << size
) - 1),
6222 vec_size
, vec_size
);
6223 } else if (shift
>= 8 << size
) {
6224 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
6226 tcg_gen_gvec_shri(size
, rd_ofs
, rm_ofs
, shift
,
6227 vec_size
, vec_size
);
6232 /* Right shift comes here negative. */
6234 /* Shifts larger than the element size are architecturally
6235 * valid. Unsigned results in all zeros; signed results
6239 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6240 MIN(shift
, (8 << size
) - 1),
6242 } else if (shift
>= 8 << size
) {
6245 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6246 shift
, &usra_op
[size
]);
6254 /* Right shift comes here negative. */
6256 /* Shift out of range leaves destination unchanged. */
6257 if (shift
< 8 << size
) {
6258 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6259 shift
, &sri_op
[size
]);
6263 case 5: /* VSHL, VSLI */
6265 /* Shift out of range leaves destination unchanged. */
6266 if (shift
< 8 << size
) {
6267 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
,
6268 vec_size
, shift
, &sli_op
[size
]);
6271 /* Shifts larger than the element size are
6272 * architecturally valid and results in zero.
6274 if (shift
>= 8 << size
) {
6275 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
6277 tcg_gen_gvec_shli(size
, rd_ofs
, rm_ofs
, shift
,
6278 vec_size
, vec_size
);
6290 /* To avoid excessive duplication of ops we implement shift
6291 * by immediate using the variable shift operations.
6293 imm
= dup_const(size
, shift
);
6295 for (pass
= 0; pass
< count
; pass
++) {
6297 neon_load_reg64(cpu_V0
, rm
+ pass
);
6298 tcg_gen_movi_i64(cpu_V1
, imm
);
6303 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6305 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6307 case 6: /* VQSHLU */
6308 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6313 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6316 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6321 g_assert_not_reached();
6325 neon_load_reg64(cpu_V1
, rd
+ pass
);
6326 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6328 neon_store_reg64(cpu_V0
, rd
+ pass
);
6329 } else { /* size < 3 */
6330 /* Operands in T0 and T1. */
6331 tmp
= neon_load_reg(rm
, pass
);
6332 tmp2
= tcg_temp_new_i32();
6333 tcg_gen_movi_i32(tmp2
, imm
);
6337 GEN_NEON_INTEGER_OP(rshl
);
6339 case 6: /* VQSHLU */
6342 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6346 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6350 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6358 GEN_NEON_INTEGER_OP_ENV(qshl
);
6361 g_assert_not_reached();
6363 tcg_temp_free_i32(tmp2
);
6367 tmp2
= neon_load_reg(rd
, pass
);
6368 gen_neon_add(size
, tmp
, tmp2
);
6369 tcg_temp_free_i32(tmp2
);
6371 neon_store_reg(rd
, pass
, tmp
);
6374 } else if (op
< 10) {
6375 /* Shift by immediate and narrow:
6376 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6377 int input_unsigned
= (op
== 8) ? !u
: u
;
6381 shift
= shift
- (1 << (size
+ 3));
6384 tmp64
= tcg_const_i64(shift
);
6385 neon_load_reg64(cpu_V0
, rm
);
6386 neon_load_reg64(cpu_V1
, rm
+ 1);
6387 for (pass
= 0; pass
< 2; pass
++) {
6395 if (input_unsigned
) {
6396 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6398 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6401 if (input_unsigned
) {
6402 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6404 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6407 tmp
= tcg_temp_new_i32();
6408 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6409 neon_store_reg(rd
, pass
, tmp
);
6411 tcg_temp_free_i64(tmp64
);
6414 imm
= (uint16_t)shift
;
6418 imm
= (uint32_t)shift
;
6420 tmp2
= tcg_const_i32(imm
);
6421 tmp4
= neon_load_reg(rm
+ 1, 0);
6422 tmp5
= neon_load_reg(rm
+ 1, 1);
6423 for (pass
= 0; pass
< 2; pass
++) {
6425 tmp
= neon_load_reg(rm
, 0);
6429 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6432 tmp3
= neon_load_reg(rm
, 1);
6436 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6438 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6439 tcg_temp_free_i32(tmp
);
6440 tcg_temp_free_i32(tmp3
);
6441 tmp
= tcg_temp_new_i32();
6442 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6443 neon_store_reg(rd
, pass
, tmp
);
6445 tcg_temp_free_i32(tmp2
);
6447 } else if (op
== 10) {
6449 if (q
|| (rd
& 1)) {
6452 tmp
= neon_load_reg(rm
, 0);
6453 tmp2
= neon_load_reg(rm
, 1);
6454 for (pass
= 0; pass
< 2; pass
++) {
6458 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6461 /* The shift is less than the width of the source
6462 type, so we can just shift the whole register. */
6463 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6464 /* Widen the result of shift: we need to clear
6465 * the potential overflow bits resulting from
6466 * left bits of the narrow input appearing as
6467 * right bits of left the neighbour narrow
6469 if (size
< 2 || !u
) {
6472 imm
= (0xffu
>> (8 - shift
));
6474 } else if (size
== 1) {
6475 imm
= 0xffff >> (16 - shift
);
6478 imm
= 0xffffffff >> (32 - shift
);
6481 imm64
= imm
| (((uint64_t)imm
) << 32);
6485 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6488 neon_store_reg64(cpu_V0
, rd
+ pass
);
6490 } else if (op
>= 14) {
6491 /* VCVT fixed-point. */
6492 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6495 /* We have already masked out the must-be-1 top bit of imm6,
6496 * hence this 32-shift where the ARM ARM has 64-imm6.
6499 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6500 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6503 gen_vfp_ulto(0, shift
, 1);
6505 gen_vfp_slto(0, shift
, 1);
6508 gen_vfp_toul(0, shift
, 1);
6510 gen_vfp_tosl(0, shift
, 1);
6512 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6517 } else { /* (insn & 0x00380080) == 0 */
6518 int invert
, reg_ofs
, vec_size
;
6520 if (q
&& (rd
& 1)) {
6524 op
= (insn
>> 8) & 0xf;
6525 /* One register and immediate. */
6526 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6527 invert
= (insn
& (1 << 5)) != 0;
6528 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6529 * We choose to not special-case this and will behave as if a
6530 * valid constant encoding of 0 had been given.
6549 imm
= (imm
<< 8) | (imm
<< 24);
6552 imm
= (imm
<< 8) | 0xff;
6555 imm
= (imm
<< 16) | 0xffff;
6558 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6567 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6568 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6575 reg_ofs
= neon_reg_offset(rd
, 0);
6576 vec_size
= q
? 16 : 8;
6578 if (op
& 1 && op
< 12) {
6580 /* The immediate value has already been inverted,
6581 * so BIC becomes AND.
6583 tcg_gen_gvec_andi(MO_32
, reg_ofs
, reg_ofs
, imm
,
6584 vec_size
, vec_size
);
6586 tcg_gen_gvec_ori(MO_32
, reg_ofs
, reg_ofs
, imm
,
6587 vec_size
, vec_size
);
6591 if (op
== 14 && invert
) {
6592 TCGv_i64 t64
= tcg_temp_new_i64();
6594 for (pass
= 0; pass
<= q
; ++pass
) {
6598 for (n
= 0; n
< 8; n
++) {
6599 if (imm
& (1 << (n
+ pass
* 8))) {
6600 val
|= 0xffull
<< (n
* 8);
6603 tcg_gen_movi_i64(t64
, val
);
6604 neon_store_reg64(t64
, rd
+ pass
);
6606 tcg_temp_free_i64(t64
);
6608 tcg_gen_gvec_dup32i(reg_ofs
, vec_size
, vec_size
, imm
);
6612 } else { /* (insn & 0x00800010 == 0x00800000) */
6614 op
= (insn
>> 8) & 0xf;
6615 if ((insn
& (1 << 6)) == 0) {
6616 /* Three registers of different lengths. */
6620 /* undefreq: bit 0 : UNDEF if size == 0
6621 * bit 1 : UNDEF if size == 1
6622 * bit 2 : UNDEF if size == 2
6623 * bit 3 : UNDEF if U == 1
6624 * Note that [2:0] set implies 'always UNDEF'
6627 /* prewiden, src1_wide, src2_wide, undefreq */
6628 static const int neon_3reg_wide
[16][4] = {
6629 {1, 0, 0, 0}, /* VADDL */
6630 {1, 1, 0, 0}, /* VADDW */
6631 {1, 0, 0, 0}, /* VSUBL */
6632 {1, 1, 0, 0}, /* VSUBW */
6633 {0, 1, 1, 0}, /* VADDHN */
6634 {0, 0, 0, 0}, /* VABAL */
6635 {0, 1, 1, 0}, /* VSUBHN */
6636 {0, 0, 0, 0}, /* VABDL */
6637 {0, 0, 0, 0}, /* VMLAL */
6638 {0, 0, 0, 9}, /* VQDMLAL */
6639 {0, 0, 0, 0}, /* VMLSL */
6640 {0, 0, 0, 9}, /* VQDMLSL */
6641 {0, 0, 0, 0}, /* Integer VMULL */
6642 {0, 0, 0, 1}, /* VQDMULL */
6643 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6644 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6647 prewiden
= neon_3reg_wide
[op
][0];
6648 src1_wide
= neon_3reg_wide
[op
][1];
6649 src2_wide
= neon_3reg_wide
[op
][2];
6650 undefreq
= neon_3reg_wide
[op
][3];
6652 if ((undefreq
& (1 << size
)) ||
6653 ((undefreq
& 8) && u
)) {
6656 if ((src1_wide
&& (rn
& 1)) ||
6657 (src2_wide
&& (rm
& 1)) ||
6658 (!src2_wide
&& (rd
& 1))) {
6662 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6663 * outside the loop below as it only performs a single pass.
6665 if (op
== 14 && size
== 2) {
6666 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6668 if (!dc_isar_feature(aa32_pmull
, s
)) {
6671 tcg_rn
= tcg_temp_new_i64();
6672 tcg_rm
= tcg_temp_new_i64();
6673 tcg_rd
= tcg_temp_new_i64();
6674 neon_load_reg64(tcg_rn
, rn
);
6675 neon_load_reg64(tcg_rm
, rm
);
6676 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6677 neon_store_reg64(tcg_rd
, rd
);
6678 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6679 neon_store_reg64(tcg_rd
, rd
+ 1);
6680 tcg_temp_free_i64(tcg_rn
);
6681 tcg_temp_free_i64(tcg_rm
);
6682 tcg_temp_free_i64(tcg_rd
);
6686 /* Avoid overlapping operands. Wide source operands are
6687 always aligned so will never overlap with wide
6688 destinations in problematic ways. */
6689 if (rd
== rm
&& !src2_wide
) {
6690 tmp
= neon_load_reg(rm
, 1);
6691 neon_store_scratch(2, tmp
);
6692 } else if (rd
== rn
&& !src1_wide
) {
6693 tmp
= neon_load_reg(rn
, 1);
6694 neon_store_scratch(2, tmp
);
6697 for (pass
= 0; pass
< 2; pass
++) {
6699 neon_load_reg64(cpu_V0
, rn
+ pass
);
6702 if (pass
== 1 && rd
== rn
) {
6703 tmp
= neon_load_scratch(2);
6705 tmp
= neon_load_reg(rn
, pass
);
6708 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6712 neon_load_reg64(cpu_V1
, rm
+ pass
);
6715 if (pass
== 1 && rd
== rm
) {
6716 tmp2
= neon_load_scratch(2);
6718 tmp2
= neon_load_reg(rm
, pass
);
6721 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6725 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6726 gen_neon_addl(size
);
6728 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6729 gen_neon_subl(size
);
6731 case 5: case 7: /* VABAL, VABDL */
6732 switch ((size
<< 1) | u
) {
6734 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6737 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6740 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6743 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6746 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6749 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6753 tcg_temp_free_i32(tmp2
);
6754 tcg_temp_free_i32(tmp
);
6756 case 8: case 9: case 10: case 11: case 12: case 13:
6757 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6758 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6760 case 14: /* Polynomial VMULL */
6761 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6762 tcg_temp_free_i32(tmp2
);
6763 tcg_temp_free_i32(tmp
);
6765 default: /* 15 is RESERVED: caught earlier */
6770 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6771 neon_store_reg64(cpu_V0
, rd
+ pass
);
6772 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6774 neon_load_reg64(cpu_V1
, rd
+ pass
);
6776 case 10: /* VMLSL */
6777 gen_neon_negl(cpu_V0
, size
);
6779 case 5: case 8: /* VABAL, VMLAL */
6780 gen_neon_addl(size
);
6782 case 9: case 11: /* VQDMLAL, VQDMLSL */
6783 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6785 gen_neon_negl(cpu_V0
, size
);
6787 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6792 neon_store_reg64(cpu_V0
, rd
+ pass
);
6793 } else if (op
== 4 || op
== 6) {
6794 /* Narrowing operation. */
6795 tmp
= tcg_temp_new_i32();
6799 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6802 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6805 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6806 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6813 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6816 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6819 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6820 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6821 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6829 neon_store_reg(rd
, 0, tmp3
);
6830 neon_store_reg(rd
, 1, tmp
);
6833 /* Write back the result. */
6834 neon_store_reg64(cpu_V0
, rd
+ pass
);
6838 /* Two registers and a scalar. NB that for ops of this form
6839 * the ARM ARM labels bit 24 as Q, but it is in our variable
6846 case 1: /* Float VMLA scalar */
6847 case 5: /* Floating point VMLS scalar */
6848 case 9: /* Floating point VMUL scalar */
6853 case 0: /* Integer VMLA scalar */
6854 case 4: /* Integer VMLS scalar */
6855 case 8: /* Integer VMUL scalar */
6856 case 12: /* VQDMULH scalar */
6857 case 13: /* VQRDMULH scalar */
6858 if (u
&& ((rd
| rn
) & 1)) {
6861 tmp
= neon_get_scalar(size
, rm
);
6862 neon_store_scratch(0, tmp
);
6863 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6864 tmp
= neon_load_scratch(0);
6865 tmp2
= neon_load_reg(rn
, pass
);
6868 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6870 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6872 } else if (op
== 13) {
6874 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6876 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6878 } else if (op
& 1) {
6879 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6880 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6881 tcg_temp_free_ptr(fpstatus
);
6884 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6885 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6886 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6890 tcg_temp_free_i32(tmp2
);
6893 tmp2
= neon_load_reg(rd
, pass
);
6896 gen_neon_add(size
, tmp
, tmp2
);
6900 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6901 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6902 tcg_temp_free_ptr(fpstatus
);
6906 gen_neon_rsb(size
, tmp
, tmp2
);
6910 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6911 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6912 tcg_temp_free_ptr(fpstatus
);
6918 tcg_temp_free_i32(tmp2
);
6920 neon_store_reg(rd
, pass
, tmp
);
6923 case 3: /* VQDMLAL scalar */
6924 case 7: /* VQDMLSL scalar */
6925 case 11: /* VQDMULL scalar */
6930 case 2: /* VMLAL sclar */
6931 case 6: /* VMLSL scalar */
6932 case 10: /* VMULL scalar */
6936 tmp2
= neon_get_scalar(size
, rm
);
6937 /* We need a copy of tmp2 because gen_neon_mull
6938 * deletes it during pass 0. */
6939 tmp4
= tcg_temp_new_i32();
6940 tcg_gen_mov_i32(tmp4
, tmp2
);
6941 tmp3
= neon_load_reg(rn
, 1);
6943 for (pass
= 0; pass
< 2; pass
++) {
6945 tmp
= neon_load_reg(rn
, 0);
6950 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6952 neon_load_reg64(cpu_V1
, rd
+ pass
);
6956 gen_neon_negl(cpu_V0
, size
);
6959 gen_neon_addl(size
);
6962 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6964 gen_neon_negl(cpu_V0
, size
);
6966 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6972 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6977 neon_store_reg64(cpu_V0
, rd
+ pass
);
6980 case 14: /* VQRDMLAH scalar */
6981 case 15: /* VQRDMLSH scalar */
6983 NeonGenThreeOpEnvFn
*fn
;
6985 if (!dc_isar_feature(aa32_rdm
, s
)) {
6988 if (u
&& ((rd
| rn
) & 1)) {
6993 fn
= gen_helper_neon_qrdmlah_s16
;
6995 fn
= gen_helper_neon_qrdmlah_s32
;
6999 fn
= gen_helper_neon_qrdmlsh_s16
;
7001 fn
= gen_helper_neon_qrdmlsh_s32
;
7005 tmp2
= neon_get_scalar(size
, rm
);
7006 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
7007 tmp
= neon_load_reg(rn
, pass
);
7008 tmp3
= neon_load_reg(rd
, pass
);
7009 fn(tmp
, cpu_env
, tmp
, tmp2
, tmp3
);
7010 tcg_temp_free_i32(tmp3
);
7011 neon_store_reg(rd
, pass
, tmp
);
7013 tcg_temp_free_i32(tmp2
);
7017 g_assert_not_reached();
7020 } else { /* size == 3 */
7023 imm
= (insn
>> 8) & 0xf;
7028 if (q
&& ((rd
| rn
| rm
) & 1)) {
7033 neon_load_reg64(cpu_V0
, rn
);
7035 neon_load_reg64(cpu_V1
, rn
+ 1);
7037 } else if (imm
== 8) {
7038 neon_load_reg64(cpu_V0
, rn
+ 1);
7040 neon_load_reg64(cpu_V1
, rm
);
7043 tmp64
= tcg_temp_new_i64();
7045 neon_load_reg64(cpu_V0
, rn
);
7046 neon_load_reg64(tmp64
, rn
+ 1);
7048 neon_load_reg64(cpu_V0
, rn
+ 1);
7049 neon_load_reg64(tmp64
, rm
);
7051 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
7052 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
7053 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7055 neon_load_reg64(cpu_V1
, rm
);
7057 neon_load_reg64(cpu_V1
, rm
+ 1);
7060 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7061 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
7062 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
7063 tcg_temp_free_i64(tmp64
);
7066 neon_load_reg64(cpu_V0
, rn
);
7067 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
7068 neon_load_reg64(cpu_V1
, rm
);
7069 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7070 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7072 neon_store_reg64(cpu_V0
, rd
);
7074 neon_store_reg64(cpu_V1
, rd
+ 1);
7076 } else if ((insn
& (1 << 11)) == 0) {
7077 /* Two register misc. */
7078 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
7079 size
= (insn
>> 18) & 3;
7080 /* UNDEF for unknown op values and bad op-size combinations */
7081 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
7084 if (neon_2rm_is_v8_op(op
) &&
7085 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7088 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
7089 q
&& ((rm
| rd
) & 1)) {
7093 case NEON_2RM_VREV64
:
7094 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
7095 tmp
= neon_load_reg(rm
, pass
* 2);
7096 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
7098 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7099 case 1: gen_swap_half(tmp
); break;
7100 case 2: /* no-op */ break;
7103 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
7105 neon_store_reg(rd
, pass
* 2, tmp2
);
7108 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
7109 case 1: gen_swap_half(tmp2
); break;
7112 neon_store_reg(rd
, pass
* 2, tmp2
);
7116 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
7117 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
7118 for (pass
= 0; pass
< q
+ 1; pass
++) {
7119 tmp
= neon_load_reg(rm
, pass
* 2);
7120 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
7121 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
7122 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
7124 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
7125 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
7126 case 2: tcg_gen_add_i64(CPU_V001
); break;
7129 if (op
>= NEON_2RM_VPADAL
) {
7131 neon_load_reg64(cpu_V1
, rd
+ pass
);
7132 gen_neon_addl(size
);
7134 neon_store_reg64(cpu_V0
, rd
+ pass
);
7140 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7141 tmp
= neon_load_reg(rm
, n
);
7142 tmp2
= neon_load_reg(rd
, n
+ 1);
7143 neon_store_reg(rm
, n
, tmp2
);
7144 neon_store_reg(rd
, n
+ 1, tmp
);
7151 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7156 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7160 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7161 /* also VQMOVUN; op field and mnemonics don't line up */
7166 for (pass
= 0; pass
< 2; pass
++) {
7167 neon_load_reg64(cpu_V0
, rm
+ pass
);
7168 tmp
= tcg_temp_new_i32();
7169 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7174 neon_store_reg(rd
, 0, tmp2
);
7175 neon_store_reg(rd
, 1, tmp
);
7179 case NEON_2RM_VSHLL
:
7180 if (q
|| (rd
& 1)) {
7183 tmp
= neon_load_reg(rm
, 0);
7184 tmp2
= neon_load_reg(rm
, 1);
7185 for (pass
= 0; pass
< 2; pass
++) {
7188 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7189 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7190 neon_store_reg64(cpu_V0
, rd
+ pass
);
7193 case NEON_2RM_VCVT_F16_F32
:
7198 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
7202 tmp
= tcg_temp_new_i32();
7203 tmp2
= tcg_temp_new_i32();
7204 fpst
= get_fpstatus_ptr(true);
7205 ahp
= get_ahp_flag();
7206 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7207 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, fpst
, ahp
);
7208 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7209 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, cpu_F0s
, fpst
, ahp
);
7210 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7211 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7212 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7213 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, fpst
, ahp
);
7214 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7215 neon_store_reg(rd
, 0, tmp2
);
7216 tmp2
= tcg_temp_new_i32();
7217 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, cpu_F0s
, fpst
, ahp
);
7218 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7219 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7220 neon_store_reg(rd
, 1, tmp2
);
7221 tcg_temp_free_i32(tmp
);
7222 tcg_temp_free_i32(ahp
);
7223 tcg_temp_free_ptr(fpst
);
7226 case NEON_2RM_VCVT_F32_F16
:
7230 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
7234 fpst
= get_fpstatus_ptr(true);
7235 ahp
= get_ahp_flag();
7236 tmp3
= tcg_temp_new_i32();
7237 tmp
= neon_load_reg(rm
, 0);
7238 tmp2
= neon_load_reg(rm
, 1);
7239 tcg_gen_ext16u_i32(tmp3
, tmp
);
7240 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7241 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7242 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7243 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7244 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7245 tcg_temp_free_i32(tmp
);
7246 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7247 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7248 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7249 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7250 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7251 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7252 tcg_temp_free_i32(tmp2
);
7253 tcg_temp_free_i32(tmp3
);
7254 tcg_temp_free_i32(ahp
);
7255 tcg_temp_free_ptr(fpst
);
7258 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7259 if (!dc_isar_feature(aa32_aes
, s
) || ((rm
| rd
) & 1)) {
7262 ptr1
= vfp_reg_ptr(true, rd
);
7263 ptr2
= vfp_reg_ptr(true, rm
);
7265 /* Bit 6 is the lowest opcode bit; it distinguishes between
7266 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7268 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7270 if (op
== NEON_2RM_AESE
) {
7271 gen_helper_crypto_aese(ptr1
, ptr2
, tmp3
);
7273 gen_helper_crypto_aesmc(ptr1
, ptr2
, tmp3
);
7275 tcg_temp_free_ptr(ptr1
);
7276 tcg_temp_free_ptr(ptr2
);
7277 tcg_temp_free_i32(tmp3
);
7279 case NEON_2RM_SHA1H
:
7280 if (!dc_isar_feature(aa32_sha1
, s
) || ((rm
| rd
) & 1)) {
7283 ptr1
= vfp_reg_ptr(true, rd
);
7284 ptr2
= vfp_reg_ptr(true, rm
);
7286 gen_helper_crypto_sha1h(ptr1
, ptr2
);
7288 tcg_temp_free_ptr(ptr1
);
7289 tcg_temp_free_ptr(ptr2
);
7291 case NEON_2RM_SHA1SU1
:
7292 if ((rm
| rd
) & 1) {
7295 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7297 if (!dc_isar_feature(aa32_sha2
, s
)) {
7300 } else if (!dc_isar_feature(aa32_sha1
, s
)) {
7303 ptr1
= vfp_reg_ptr(true, rd
);
7304 ptr2
= vfp_reg_ptr(true, rm
);
7306 gen_helper_crypto_sha256su0(ptr1
, ptr2
);
7308 gen_helper_crypto_sha1su1(ptr1
, ptr2
);
7310 tcg_temp_free_ptr(ptr1
);
7311 tcg_temp_free_ptr(ptr2
);
7315 tcg_gen_gvec_not(0, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7318 tcg_gen_gvec_neg(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7321 tcg_gen_gvec_abs(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7326 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7327 if (neon_2rm_is_float_op(op
)) {
7328 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7329 neon_reg_offset(rm
, pass
));
7332 tmp
= neon_load_reg(rm
, pass
);
7335 case NEON_2RM_VREV32
:
7337 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7338 case 1: gen_swap_half(tmp
); break;
7342 case NEON_2RM_VREV16
:
7347 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7348 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7349 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7355 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7356 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7357 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7362 gen_helper_neon_cnt_u8(tmp
, tmp
);
7364 case NEON_2RM_VQABS
:
7367 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7370 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7373 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7378 case NEON_2RM_VQNEG
:
7381 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7384 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7387 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7392 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7393 tmp2
= tcg_const_i32(0);
7395 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7396 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7397 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7400 tcg_temp_free_i32(tmp2
);
7401 if (op
== NEON_2RM_VCLE0
) {
7402 tcg_gen_not_i32(tmp
, tmp
);
7405 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7406 tmp2
= tcg_const_i32(0);
7408 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7409 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7410 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7413 tcg_temp_free_i32(tmp2
);
7414 if (op
== NEON_2RM_VCLT0
) {
7415 tcg_gen_not_i32(tmp
, tmp
);
7418 case NEON_2RM_VCEQ0
:
7419 tmp2
= tcg_const_i32(0);
7421 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7422 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7423 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7426 tcg_temp_free_i32(tmp2
);
7428 case NEON_2RM_VCGT0_F
:
7430 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7431 tmp2
= tcg_const_i32(0);
7432 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7433 tcg_temp_free_i32(tmp2
);
7434 tcg_temp_free_ptr(fpstatus
);
7437 case NEON_2RM_VCGE0_F
:
7439 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7440 tmp2
= tcg_const_i32(0);
7441 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7442 tcg_temp_free_i32(tmp2
);
7443 tcg_temp_free_ptr(fpstatus
);
7446 case NEON_2RM_VCEQ0_F
:
7448 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7449 tmp2
= tcg_const_i32(0);
7450 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7451 tcg_temp_free_i32(tmp2
);
7452 tcg_temp_free_ptr(fpstatus
);
7455 case NEON_2RM_VCLE0_F
:
7457 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7458 tmp2
= tcg_const_i32(0);
7459 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7460 tcg_temp_free_i32(tmp2
);
7461 tcg_temp_free_ptr(fpstatus
);
7464 case NEON_2RM_VCLT0_F
:
7466 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7467 tmp2
= tcg_const_i32(0);
7468 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7469 tcg_temp_free_i32(tmp2
);
7470 tcg_temp_free_ptr(fpstatus
);
7473 case NEON_2RM_VABS_F
:
7476 case NEON_2RM_VNEG_F
:
7480 tmp2
= neon_load_reg(rd
, pass
);
7481 neon_store_reg(rm
, pass
, tmp2
);
7484 tmp2
= neon_load_reg(rd
, pass
);
7486 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7487 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7490 neon_store_reg(rm
, pass
, tmp2
);
7492 case NEON_2RM_VRINTN
:
7493 case NEON_2RM_VRINTA
:
7494 case NEON_2RM_VRINTM
:
7495 case NEON_2RM_VRINTP
:
7496 case NEON_2RM_VRINTZ
:
7499 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7502 if (op
== NEON_2RM_VRINTZ
) {
7503 rmode
= FPROUNDING_ZERO
;
7505 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7508 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7509 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7511 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7512 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7514 tcg_temp_free_ptr(fpstatus
);
7515 tcg_temp_free_i32(tcg_rmode
);
7518 case NEON_2RM_VRINTX
:
7520 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7521 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7522 tcg_temp_free_ptr(fpstatus
);
7525 case NEON_2RM_VCVTAU
:
7526 case NEON_2RM_VCVTAS
:
7527 case NEON_2RM_VCVTNU
:
7528 case NEON_2RM_VCVTNS
:
7529 case NEON_2RM_VCVTPU
:
7530 case NEON_2RM_VCVTPS
:
7531 case NEON_2RM_VCVTMU
:
7532 case NEON_2RM_VCVTMS
:
7534 bool is_signed
= !extract32(insn
, 7, 1);
7535 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7536 TCGv_i32 tcg_rmode
, tcg_shift
;
7537 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7539 tcg_shift
= tcg_const_i32(0);
7540 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7541 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7545 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7548 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7552 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7554 tcg_temp_free_i32(tcg_rmode
);
7555 tcg_temp_free_i32(tcg_shift
);
7556 tcg_temp_free_ptr(fpst
);
7559 case NEON_2RM_VRECPE
:
7561 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7562 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7563 tcg_temp_free_ptr(fpstatus
);
7566 case NEON_2RM_VRSQRTE
:
7568 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7569 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7570 tcg_temp_free_ptr(fpstatus
);
7573 case NEON_2RM_VRECPE_F
:
7575 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7576 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7577 tcg_temp_free_ptr(fpstatus
);
7580 case NEON_2RM_VRSQRTE_F
:
7582 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7583 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7584 tcg_temp_free_ptr(fpstatus
);
7587 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7590 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7593 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7594 gen_vfp_tosiz(0, 1);
7596 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7597 gen_vfp_touiz(0, 1);
7600 /* Reserved op values were caught by the
7601 * neon_2rm_sizes[] check earlier.
7605 if (neon_2rm_is_float_op(op
)) {
7606 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7607 neon_reg_offset(rd
, pass
));
7609 neon_store_reg(rd
, pass
, tmp
);
7614 } else if ((insn
& (1 << 10)) == 0) {
7616 int n
= ((insn
>> 8) & 3) + 1;
7617 if ((rn
+ n
) > 32) {
7618 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7619 * helper function running off the end of the register file.
7624 if (insn
& (1 << 6)) {
7625 tmp
= neon_load_reg(rd
, 0);
7627 tmp
= tcg_temp_new_i32();
7628 tcg_gen_movi_i32(tmp
, 0);
7630 tmp2
= neon_load_reg(rm
, 0);
7631 ptr1
= vfp_reg_ptr(true, rn
);
7632 tmp5
= tcg_const_i32(n
);
7633 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, ptr1
, tmp5
);
7634 tcg_temp_free_i32(tmp
);
7635 if (insn
& (1 << 6)) {
7636 tmp
= neon_load_reg(rd
, 1);
7638 tmp
= tcg_temp_new_i32();
7639 tcg_gen_movi_i32(tmp
, 0);
7641 tmp3
= neon_load_reg(rm
, 1);
7642 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, ptr1
, tmp5
);
7643 tcg_temp_free_i32(tmp5
);
7644 tcg_temp_free_ptr(ptr1
);
7645 neon_store_reg(rd
, 0, tmp2
);
7646 neon_store_reg(rd
, 1, tmp3
);
7647 tcg_temp_free_i32(tmp
);
7648 } else if ((insn
& 0x380) == 0) {
7653 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7656 if (insn
& (1 << 16)) {
7658 element
= (insn
>> 17) & 7;
7659 } else if (insn
& (1 << 17)) {
7661 element
= (insn
>> 18) & 3;
7664 element
= (insn
>> 19) & 1;
7666 tcg_gen_gvec_dup_mem(size
, neon_reg_offset(rd
, 0),
7667 neon_element_offset(rm
, element
, size
),
7668 q
? 16 : 8, q
? 16 : 8);
7677 /* Advanced SIMD three registers of the same length extension.
7678 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7679 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7680 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7681 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7683 static int disas_neon_insn_3same_ext(DisasContext
*s
, uint32_t insn
)
7685 gen_helper_gvec_3
*fn_gvec
= NULL
;
7686 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
7687 int rd
, rn
, rm
, opr_sz
;
7690 bool is_long
= false, q
= extract32(insn
, 6, 1);
7691 bool ptr_is_env
= false;
7693 if ((insn
& 0xfe200f10) == 0xfc200800) {
7694 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7695 int size
= extract32(insn
, 20, 1);
7696 data
= extract32(insn
, 23, 2); /* rot */
7697 if (!dc_isar_feature(aa32_vcma
, s
)
7698 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
7701 fn_gvec_ptr
= size
? gen_helper_gvec_fcmlas
: gen_helper_gvec_fcmlah
;
7702 } else if ((insn
& 0xfea00f10) == 0xfc800800) {
7703 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7704 int size
= extract32(insn
, 20, 1);
7705 data
= extract32(insn
, 24, 1); /* rot */
7706 if (!dc_isar_feature(aa32_vcma
, s
)
7707 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
7710 fn_gvec_ptr
= size
? gen_helper_gvec_fcadds
: gen_helper_gvec_fcaddh
;
7711 } else if ((insn
& 0xfeb00f00) == 0xfc200d00) {
7712 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
7713 bool u
= extract32(insn
, 4, 1);
7714 if (!dc_isar_feature(aa32_dp
, s
)) {
7717 fn_gvec
= u
? gen_helper_gvec_udot_b
: gen_helper_gvec_sdot_b
;
7718 } else if ((insn
& 0xff300f10) == 0xfc200810) {
7719 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
7720 int is_s
= extract32(insn
, 23, 1);
7721 if (!dc_isar_feature(aa32_fhm
, s
)) {
7725 data
= is_s
; /* is_2 == 0 */
7726 fn_gvec_ptr
= gen_helper_gvec_fmlal_a32
;
7732 VFP_DREG_D(rd
, insn
);
7736 if (q
|| !is_long
) {
7737 VFP_DREG_N(rn
, insn
);
7738 VFP_DREG_M(rm
, insn
);
7739 if ((rn
| rm
) & q
& !is_long
) {
7742 off_rn
= vfp_reg_offset(1, rn
);
7743 off_rm
= vfp_reg_offset(1, rm
);
7745 rn
= VFP_SREG_N(insn
);
7746 rm
= VFP_SREG_M(insn
);
7747 off_rn
= vfp_reg_offset(0, rn
);
7748 off_rm
= vfp_reg_offset(0, rm
);
7751 if (s
->fp_excp_el
) {
7752 gen_exception_insn(s
, 4, EXCP_UDEF
,
7753 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
7756 if (!s
->vfp_enabled
) {
7760 opr_sz
= (1 + q
) * 8;
7766 ptr
= get_fpstatus_ptr(1);
7768 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
7769 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
7771 tcg_temp_free_ptr(ptr
);
7774 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
7775 opr_sz
, opr_sz
, data
, fn_gvec
);
7780 /* Advanced SIMD two registers and a scalar extension.
7781 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7782 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7783 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7784 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7788 static int disas_neon_insn_2reg_scalar_ext(DisasContext
*s
, uint32_t insn
)
7790 gen_helper_gvec_3
*fn_gvec
= NULL
;
7791 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
7792 int rd
, rn
, rm
, opr_sz
, data
;
7794 bool is_long
= false, q
= extract32(insn
, 6, 1);
7795 bool ptr_is_env
= false;
7797 if ((insn
& 0xff000f10) == 0xfe000800) {
7798 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7799 int rot
= extract32(insn
, 20, 2);
7800 int size
= extract32(insn
, 23, 1);
7803 if (!dc_isar_feature(aa32_vcma
, s
)) {
7807 if (!dc_isar_feature(aa32_fp16_arith
, s
)) {
7810 /* For fp16, rm is just Vm, and index is M. */
7811 rm
= extract32(insn
, 0, 4);
7812 index
= extract32(insn
, 5, 1);
7814 /* For fp32, rm is the usual M:Vm, and index is 0. */
7815 VFP_DREG_M(rm
, insn
);
7818 data
= (index
<< 2) | rot
;
7819 fn_gvec_ptr
= (size
? gen_helper_gvec_fcmlas_idx
7820 : gen_helper_gvec_fcmlah_idx
);
7821 } else if ((insn
& 0xffb00f00) == 0xfe200d00) {
7822 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7823 int u
= extract32(insn
, 4, 1);
7825 if (!dc_isar_feature(aa32_dp
, s
)) {
7828 fn_gvec
= u
? gen_helper_gvec_udot_idx_b
: gen_helper_gvec_sdot_idx_b
;
7829 /* rm is just Vm, and index is M. */
7830 data
= extract32(insn
, 5, 1); /* index */
7831 rm
= extract32(insn
, 0, 4);
7832 } else if ((insn
& 0xffa00f10) == 0xfe000810) {
7833 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7834 int is_s
= extract32(insn
, 20, 1);
7835 int vm20
= extract32(insn
, 0, 3);
7836 int vm3
= extract32(insn
, 3, 1);
7837 int m
= extract32(insn
, 5, 1);
7840 if (!dc_isar_feature(aa32_fhm
, s
)) {
7845 index
= m
* 2 + vm3
;
7851 data
= (index
<< 2) | is_s
; /* is_2 == 0 */
7852 fn_gvec_ptr
= gen_helper_gvec_fmlal_idx_a32
;
7858 VFP_DREG_D(rd
, insn
);
7862 if (q
|| !is_long
) {
7863 VFP_DREG_N(rn
, insn
);
7864 if (rn
& q
& !is_long
) {
7867 off_rn
= vfp_reg_offset(1, rn
);
7868 off_rm
= vfp_reg_offset(1, rm
);
7870 rn
= VFP_SREG_N(insn
);
7871 off_rn
= vfp_reg_offset(0, rn
);
7872 off_rm
= vfp_reg_offset(0, rm
);
7874 if (s
->fp_excp_el
) {
7875 gen_exception_insn(s
, 4, EXCP_UDEF
,
7876 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
7879 if (!s
->vfp_enabled
) {
7883 opr_sz
= (1 + q
) * 8;
7889 ptr
= get_fpstatus_ptr(1);
7891 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
7892 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
7894 tcg_temp_free_ptr(ptr
);
7897 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
7898 opr_sz
, opr_sz
, data
, fn_gvec
);
7903 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7905 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7906 const ARMCPRegInfo
*ri
;
7908 cpnum
= (insn
>> 8) & 0xf;
7910 /* First check for coprocessor space used for XScale/iwMMXt insns */
7911 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7912 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7915 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7916 return disas_iwmmxt_insn(s
, insn
);
7917 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7918 return disas_dsp_insn(s
, insn
);
7923 /* Otherwise treat as a generic register access */
7924 is64
= (insn
& (1 << 25)) == 0;
7925 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7933 opc1
= (insn
>> 4) & 0xf;
7935 rt2
= (insn
>> 16) & 0xf;
7937 crn
= (insn
>> 16) & 0xf;
7938 opc1
= (insn
>> 21) & 7;
7939 opc2
= (insn
>> 5) & 7;
7942 isread
= (insn
>> 20) & 1;
7943 rt
= (insn
>> 12) & 0xf;
7945 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7946 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7948 /* Check access permissions */
7949 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7954 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7955 /* Emit code to perform further access permissions checks at
7956 * runtime; this may result in an exception.
7957 * Note that on XScale all cp0..c13 registers do an access check
7958 * call in order to handle c15_cpar.
7961 TCGv_i32 tcg_syn
, tcg_isread
;
7964 /* Note that since we are an implementation which takes an
7965 * exception on a trapped conditional instruction only if the
7966 * instruction passes its condition code check, we can take
7967 * advantage of the clause in the ARM ARM that allows us to set
7968 * the COND field in the instruction to 0xE in all cases.
7969 * We could fish the actual condition out of the insn (ARM)
7970 * or the condexec bits (Thumb) but it isn't necessary.
7975 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7978 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7984 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7987 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7992 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7993 * so this can only happen if this is an ARMv7 or earlier CPU,
7994 * in which case the syndrome information won't actually be
7997 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7998 syndrome
= syn_uncategorized();
8002 gen_set_condexec(s
);
8003 gen_set_pc_im(s
, s
->pc
- 4);
8004 tmpptr
= tcg_const_ptr(ri
);
8005 tcg_syn
= tcg_const_i32(syndrome
);
8006 tcg_isread
= tcg_const_i32(isread
);
8007 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
8009 tcg_temp_free_ptr(tmpptr
);
8010 tcg_temp_free_i32(tcg_syn
);
8011 tcg_temp_free_i32(tcg_isread
);
8014 /* Handle special cases first */
8015 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
8022 gen_set_pc_im(s
, s
->pc
);
8023 s
->base
.is_jmp
= DISAS_WFI
;
8029 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
8038 if (ri
->type
& ARM_CP_CONST
) {
8039 tmp64
= tcg_const_i64(ri
->resetvalue
);
8040 } else if (ri
->readfn
) {
8042 tmp64
= tcg_temp_new_i64();
8043 tmpptr
= tcg_const_ptr(ri
);
8044 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
8045 tcg_temp_free_ptr(tmpptr
);
8047 tmp64
= tcg_temp_new_i64();
8048 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
8050 tmp
= tcg_temp_new_i32();
8051 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8052 store_reg(s
, rt
, tmp
);
8053 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8054 tmp
= tcg_temp_new_i32();
8055 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8056 tcg_temp_free_i64(tmp64
);
8057 store_reg(s
, rt2
, tmp
);
8060 if (ri
->type
& ARM_CP_CONST
) {
8061 tmp
= tcg_const_i32(ri
->resetvalue
);
8062 } else if (ri
->readfn
) {
8064 tmp
= tcg_temp_new_i32();
8065 tmpptr
= tcg_const_ptr(ri
);
8066 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
8067 tcg_temp_free_ptr(tmpptr
);
8069 tmp
= load_cpu_offset(ri
->fieldoffset
);
8072 /* Destination register of r15 for 32 bit loads sets
8073 * the condition codes from the high 4 bits of the value
8076 tcg_temp_free_i32(tmp
);
8078 store_reg(s
, rt
, tmp
);
8083 if (ri
->type
& ARM_CP_CONST
) {
8084 /* If not forbidden by access permissions, treat as WI */
8089 TCGv_i32 tmplo
, tmphi
;
8090 TCGv_i64 tmp64
= tcg_temp_new_i64();
8091 tmplo
= load_reg(s
, rt
);
8092 tmphi
= load_reg(s
, rt2
);
8093 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
8094 tcg_temp_free_i32(tmplo
);
8095 tcg_temp_free_i32(tmphi
);
8097 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
8098 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
8099 tcg_temp_free_ptr(tmpptr
);
8101 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
8103 tcg_temp_free_i64(tmp64
);
8108 tmp
= load_reg(s
, rt
);
8109 tmpptr
= tcg_const_ptr(ri
);
8110 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
8111 tcg_temp_free_ptr(tmpptr
);
8112 tcg_temp_free_i32(tmp
);
8114 TCGv_i32 tmp
= load_reg(s
, rt
);
8115 store_cpu_offset(tmp
, ri
->fieldoffset
);
8120 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
8121 /* I/O operations must end the TB here (whether read or write) */
8124 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
8125 /* We default to ending the TB on a coprocessor register write,
8126 * but allow this to be suppressed by the register definition
8127 * (usually only necessary to work around guest bugs).
8135 /* Unknown register; this might be a guest error or a QEMU
8136 * unimplemented feature.
8139 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8140 "64 bit system register cp:%d opc1: %d crm:%d "
8142 isread
? "read" : "write", cpnum
, opc1
, crm
,
8143 s
->ns
? "non-secure" : "secure");
8145 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8146 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8148 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
8149 s
->ns
? "non-secure" : "secure");
8156 /* Store a 64-bit value to a register pair. Clobbers val. */
8157 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
8160 tmp
= tcg_temp_new_i32();
8161 tcg_gen_extrl_i64_i32(tmp
, val
);
8162 store_reg(s
, rlow
, tmp
);
8163 tmp
= tcg_temp_new_i32();
8164 tcg_gen_shri_i64(val
, val
, 32);
8165 tcg_gen_extrl_i64_i32(tmp
, val
);
8166 store_reg(s
, rhigh
, tmp
);
8169 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8170 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
8175 /* Load value and extend to 64 bits. */
8176 tmp
= tcg_temp_new_i64();
8177 tmp2
= load_reg(s
, rlow
);
8178 tcg_gen_extu_i32_i64(tmp
, tmp2
);
8179 tcg_temp_free_i32(tmp2
);
8180 tcg_gen_add_i64(val
, val
, tmp
);
8181 tcg_temp_free_i64(tmp
);
8184 /* load and add a 64-bit value from a register pair. */
8185 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
8191 /* Load 64-bit value rd:rn. */
8192 tmpl
= load_reg(s
, rlow
);
8193 tmph
= load_reg(s
, rhigh
);
8194 tmp
= tcg_temp_new_i64();
8195 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
8196 tcg_temp_free_i32(tmpl
);
8197 tcg_temp_free_i32(tmph
);
8198 tcg_gen_add_i64(val
, val
, tmp
);
8199 tcg_temp_free_i64(tmp
);
8202 /* Set N and Z flags from hi|lo. */
8203 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
8205 tcg_gen_mov_i32(cpu_NF
, hi
);
8206 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
8209 /* Load/Store exclusive instructions are implemented by remembering
8210 the value/address loaded, and seeing if these are the same
8211 when the store is performed. This should be sufficient to implement
8212 the architecturally mandated semantics, and avoids having to monitor
8213 regular stores. The compare vs the remembered value is done during
8214 the cmpxchg operation, but we must compare the addresses manually. */
8215 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
8216 TCGv_i32 addr
, int size
)
8218 TCGv_i32 tmp
= tcg_temp_new_i32();
8219 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8224 TCGv_i32 tmp2
= tcg_temp_new_i32();
8225 TCGv_i64 t64
= tcg_temp_new_i64();
8227 /* For AArch32, architecturally the 32-bit word at the lowest
8228 * address is always Rt and the one at addr+4 is Rt2, even if
8229 * the CPU is big-endian. That means we don't want to do a
8230 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8231 * for an architecturally 64-bit access, but instead do a
8232 * 64-bit access using MO_BE if appropriate and then split
8234 * This only makes a difference for BE32 user-mode, where
8235 * frob64() must not flip the two halves of the 64-bit data
8236 * but this code must treat BE32 user-mode like BE32 system.
8238 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
8240 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
8241 tcg_temp_free(taddr
);
8242 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
8243 if (s
->be_data
== MO_BE
) {
8244 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
8246 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
8248 tcg_temp_free_i64(t64
);
8250 store_reg(s
, rt2
, tmp2
);
8252 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
8253 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
8256 store_reg(s
, rt
, tmp
);
8257 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
8260 static void gen_clrex(DisasContext
*s
)
8262 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8265 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
8266 TCGv_i32 addr
, int size
)
8268 TCGv_i32 t0
, t1
, t2
;
8271 TCGLabel
*done_label
;
8272 TCGLabel
*fail_label
;
8273 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8275 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8281 fail_label
= gen_new_label();
8282 done_label
= gen_new_label();
8283 extaddr
= tcg_temp_new_i64();
8284 tcg_gen_extu_i32_i64(extaddr
, addr
);
8285 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
8286 tcg_temp_free_i64(extaddr
);
8288 taddr
= gen_aa32_addr(s
, addr
, opc
);
8289 t0
= tcg_temp_new_i32();
8290 t1
= load_reg(s
, rt
);
8292 TCGv_i64 o64
= tcg_temp_new_i64();
8293 TCGv_i64 n64
= tcg_temp_new_i64();
8295 t2
= load_reg(s
, rt2
);
8296 /* For AArch32, architecturally the 32-bit word at the lowest
8297 * address is always Rt and the one at addr+4 is Rt2, even if
8298 * the CPU is big-endian. Since we're going to treat this as a
8299 * single 64-bit BE store, we need to put the two halves in the
8300 * opposite order for BE to LE, so that they end up in the right
8302 * We don't want gen_aa32_frob64() because that does the wrong
8303 * thing for BE32 usermode.
8305 if (s
->be_data
== MO_BE
) {
8306 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
8308 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
8310 tcg_temp_free_i32(t2
);
8312 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
8313 get_mem_index(s
), opc
);
8314 tcg_temp_free_i64(n64
);
8316 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
8317 tcg_gen_extrl_i64_i32(t0
, o64
);
8319 tcg_temp_free_i64(o64
);
8321 t2
= tcg_temp_new_i32();
8322 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
8323 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
8324 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
8325 tcg_temp_free_i32(t2
);
8327 tcg_temp_free_i32(t1
);
8328 tcg_temp_free(taddr
);
8329 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
8330 tcg_temp_free_i32(t0
);
8331 tcg_gen_br(done_label
);
8333 gen_set_label(fail_label
);
8334 tcg_gen_movi_i32(cpu_R
[rd
], 1);
8335 gen_set_label(done_label
);
8336 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8342 * @mode: mode field from insn (which stack to store to)
8343 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8344 * @writeback: true if writeback bit set
8346 * Generate code for the SRS (Store Return State) insn.
8348 static void gen_srs(DisasContext
*s
,
8349 uint32_t mode
, uint32_t amode
, bool writeback
)
8356 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8357 * and specified mode is monitor mode
8358 * - UNDEFINED in Hyp mode
8359 * - UNPREDICTABLE in User or System mode
8360 * - UNPREDICTABLE if the specified mode is:
8361 * -- not implemented
8362 * -- not a valid mode number
8363 * -- a mode that's at a higher exception level
8364 * -- Monitor, if we are Non-secure
8365 * For the UNPREDICTABLE cases we choose to UNDEF.
8367 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
8368 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
8372 if (s
->current_el
== 0 || s
->current_el
== 2) {
8377 case ARM_CPU_MODE_USR
:
8378 case ARM_CPU_MODE_FIQ
:
8379 case ARM_CPU_MODE_IRQ
:
8380 case ARM_CPU_MODE_SVC
:
8381 case ARM_CPU_MODE_ABT
:
8382 case ARM_CPU_MODE_UND
:
8383 case ARM_CPU_MODE_SYS
:
8385 case ARM_CPU_MODE_HYP
:
8386 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
8390 case ARM_CPU_MODE_MON
:
8391 /* No need to check specifically for "are we non-secure" because
8392 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8393 * so if this isn't EL3 then we must be non-secure.
8395 if (s
->current_el
!= 3) {
8404 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8405 default_exception_el(s
));
8409 addr
= tcg_temp_new_i32();
8410 tmp
= tcg_const_i32(mode
);
8411 /* get_r13_banked() will raise an exception if called from System mode */
8412 gen_set_condexec(s
);
8413 gen_set_pc_im(s
, s
->pc
- 4);
8414 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8415 tcg_temp_free_i32(tmp
);
8432 tcg_gen_addi_i32(addr
, addr
, offset
);
8433 tmp
= load_reg(s
, 14);
8434 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8435 tcg_temp_free_i32(tmp
);
8436 tmp
= load_cpu_field(spsr
);
8437 tcg_gen_addi_i32(addr
, addr
, 4);
8438 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8439 tcg_temp_free_i32(tmp
);
8457 tcg_gen_addi_i32(addr
, addr
, offset
);
8458 tmp
= tcg_const_i32(mode
);
8459 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8460 tcg_temp_free_i32(tmp
);
8462 tcg_temp_free_i32(addr
);
8463 s
->base
.is_jmp
= DISAS_UPDATE
;
8466 /* Generate a label used for skipping this instruction */
8467 static void arm_gen_condlabel(DisasContext
*s
)
8470 s
->condlabel
= gen_new_label();
8475 /* Skip this instruction if the ARM condition is false */
8476 static void arm_skip_unless(DisasContext
*s
, uint32_t cond
)
8478 arm_gen_condlabel(s
);
8479 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8482 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8484 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8491 /* M variants do not implement ARM mode; this must raise the INVSTATE
8492 * UsageFault exception.
8494 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8495 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8496 default_exception_el(s
));
8501 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8502 * choose to UNDEF. In ARMv5 and above the space is used
8503 * for miscellaneous unconditional instructions.
8507 /* Unconditional instructions. */
8508 if (((insn
>> 25) & 7) == 1) {
8509 /* NEON Data processing. */
8510 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8514 if (disas_neon_data_insn(s
, insn
)) {
8519 if ((insn
& 0x0f100000) == 0x04000000) {
8520 /* NEON load/store. */
8521 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8525 if (disas_neon_ls_insn(s
, insn
)) {
8530 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8532 if (disas_vfp_insn(s
, insn
)) {
8537 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8538 ((insn
& 0x0f30f010) == 0x0710f000)) {
8539 if ((insn
& (1 << 22)) == 0) {
8541 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8545 /* Otherwise PLD; v5TE+ */
8549 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8550 ((insn
& 0x0f70f010) == 0x0650f000)) {
8552 return; /* PLI; V7 */
8554 if (((insn
& 0x0f700000) == 0x04100000) ||
8555 ((insn
& 0x0f700010) == 0x06100000)) {
8556 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8559 return; /* v7MP: Unallocated memory hint: must NOP */
8562 if ((insn
& 0x0ffffdff) == 0x01010000) {
8565 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8566 gen_helper_setend(cpu_env
);
8567 s
->base
.is_jmp
= DISAS_UPDATE
;
8570 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8571 switch ((insn
>> 4) & 0xf) {
8579 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8582 /* We need to break the TB after this insn to execute
8583 * self-modifying code correctly and also to take
8584 * any pending interrupts immediately.
8586 gen_goto_tb(s
, 0, s
->pc
& ~1);
8589 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
8593 * TODO: There is no speculation barrier opcode
8594 * for TCG; MB and end the TB instead.
8596 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8597 gen_goto_tb(s
, 0, s
->pc
& ~1);
8602 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8605 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8607 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8613 rn
= (insn
>> 16) & 0xf;
8614 addr
= load_reg(s
, rn
);
8615 i
= (insn
>> 23) & 3;
8617 case 0: offset
= -4; break; /* DA */
8618 case 1: offset
= 0; break; /* IA */
8619 case 2: offset
= -8; break; /* DB */
8620 case 3: offset
= 4; break; /* IB */
8624 tcg_gen_addi_i32(addr
, addr
, offset
);
8625 /* Load PC into tmp and CPSR into tmp2. */
8626 tmp
= tcg_temp_new_i32();
8627 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8628 tcg_gen_addi_i32(addr
, addr
, 4);
8629 tmp2
= tcg_temp_new_i32();
8630 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8631 if (insn
& (1 << 21)) {
8632 /* Base writeback. */
8634 case 0: offset
= -8; break;
8635 case 1: offset
= 4; break;
8636 case 2: offset
= -4; break;
8637 case 3: offset
= 0; break;
8641 tcg_gen_addi_i32(addr
, addr
, offset
);
8642 store_reg(s
, rn
, addr
);
8644 tcg_temp_free_i32(addr
);
8646 gen_rfe(s
, tmp
, tmp2
);
8648 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8649 /* branch link and change to thumb (blx <offset>) */
8652 val
= (uint32_t)s
->pc
;
8653 tmp
= tcg_temp_new_i32();
8654 tcg_gen_movi_i32(tmp
, val
);
8655 store_reg(s
, 14, tmp
);
8656 /* Sign-extend the 24-bit offset */
8657 offset
= (((int32_t)insn
) << 8) >> 8;
8658 /* offset * 4 + bit24 * 2 + (thumb bit) */
8659 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8660 /* pipeline offset */
8662 /* protected by ARCH(5); above, near the start of uncond block */
8665 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8666 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8667 /* iWMMXt register transfer. */
8668 if (extract32(s
->c15_cpar
, 1, 1)) {
8669 if (!disas_iwmmxt_insn(s
, insn
)) {
8674 } else if ((insn
& 0x0e000a00) == 0x0c000800
8675 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8676 if (disas_neon_insn_3same_ext(s
, insn
)) {
8680 } else if ((insn
& 0x0f000a00) == 0x0e000800
8681 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8682 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
8686 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8687 /* Coprocessor double register transfer. */
8689 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8690 /* Additional coprocessor register transfer. */
8691 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8694 /* cps (privileged) */
8698 if (insn
& (1 << 19)) {
8699 if (insn
& (1 << 8))
8701 if (insn
& (1 << 7))
8703 if (insn
& (1 << 6))
8705 if (insn
& (1 << 18))
8708 if (insn
& (1 << 17)) {
8710 val
|= (insn
& 0x1f);
8713 gen_set_psr_im(s
, mask
, 0, val
);
8720 /* if not always execute, we generate a conditional jump to
8722 arm_skip_unless(s
, cond
);
8724 if ((insn
& 0x0f900000) == 0x03000000) {
8725 if ((insn
& (1 << 21)) == 0) {
8727 rd
= (insn
>> 12) & 0xf;
8728 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8729 if ((insn
& (1 << 22)) == 0) {
8731 tmp
= tcg_temp_new_i32();
8732 tcg_gen_movi_i32(tmp
, val
);
8735 tmp
= load_reg(s
, rd
);
8736 tcg_gen_ext16u_i32(tmp
, tmp
);
8737 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8739 store_reg(s
, rd
, tmp
);
8741 if (((insn
>> 12) & 0xf) != 0xf)
8743 if (((insn
>> 16) & 0xf) == 0) {
8744 gen_nop_hint(s
, insn
& 0xff);
8746 /* CPSR = immediate */
8748 shift
= ((insn
>> 8) & 0xf) * 2;
8750 val
= (val
>> shift
) | (val
<< (32 - shift
));
8751 i
= ((insn
& (1 << 22)) != 0);
8752 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8758 } else if ((insn
& 0x0f900000) == 0x01000000
8759 && (insn
& 0x00000090) != 0x00000090) {
8760 /* miscellaneous instructions */
8761 op1
= (insn
>> 21) & 3;
8762 sh
= (insn
>> 4) & 0xf;
8765 case 0x0: /* MSR, MRS */
8766 if (insn
& (1 << 9)) {
8767 /* MSR (banked) and MRS (banked) */
8768 int sysm
= extract32(insn
, 16, 4) |
8769 (extract32(insn
, 8, 1) << 4);
8770 int r
= extract32(insn
, 22, 1);
8774 gen_msr_banked(s
, r
, sysm
, rm
);
8777 int rd
= extract32(insn
, 12, 4);
8779 gen_mrs_banked(s
, r
, sysm
, rd
);
8784 /* MSR, MRS (for PSRs) */
8787 tmp
= load_reg(s
, rm
);
8788 i
= ((op1
& 2) != 0);
8789 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8793 rd
= (insn
>> 12) & 0xf;
8797 tmp
= load_cpu_field(spsr
);
8799 tmp
= tcg_temp_new_i32();
8800 gen_helper_cpsr_read(tmp
, cpu_env
);
8802 store_reg(s
, rd
, tmp
);
8807 /* branch/exchange thumb (bx). */
8809 tmp
= load_reg(s
, rm
);
8811 } else if (op1
== 3) {
8814 rd
= (insn
>> 12) & 0xf;
8815 tmp
= load_reg(s
, rm
);
8816 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8817 store_reg(s
, rd
, tmp
);
8825 /* Trivial implementation equivalent to bx. */
8826 tmp
= load_reg(s
, rm
);
8837 /* branch link/exchange thumb (blx) */
8838 tmp
= load_reg(s
, rm
);
8839 tmp2
= tcg_temp_new_i32();
8840 tcg_gen_movi_i32(tmp2
, s
->pc
);
8841 store_reg(s
, 14, tmp2
);
8847 uint32_t c
= extract32(insn
, 8, 4);
8849 /* Check this CPU supports ARMv8 CRC instructions.
8850 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8851 * Bits 8, 10 and 11 should be zero.
8853 if (!dc_isar_feature(aa32_crc32
, s
) || op1
== 0x3 || (c
& 0xd) != 0) {
8857 rn
= extract32(insn
, 16, 4);
8858 rd
= extract32(insn
, 12, 4);
8860 tmp
= load_reg(s
, rn
);
8861 tmp2
= load_reg(s
, rm
);
8863 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8864 } else if (op1
== 1) {
8865 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8867 tmp3
= tcg_const_i32(1 << op1
);
8869 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8871 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8873 tcg_temp_free_i32(tmp2
);
8874 tcg_temp_free_i32(tmp3
);
8875 store_reg(s
, rd
, tmp
);
8878 case 0x5: /* saturating add/subtract */
8880 rd
= (insn
>> 12) & 0xf;
8881 rn
= (insn
>> 16) & 0xf;
8882 tmp
= load_reg(s
, rm
);
8883 tmp2
= load_reg(s
, rn
);
8885 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8887 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8889 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8890 tcg_temp_free_i32(tmp2
);
8891 store_reg(s
, rd
, tmp
);
8893 case 0x6: /* ERET */
8897 if (!arm_dc_feature(s
, ARM_FEATURE_V7VE
)) {
8900 if ((insn
& 0x000fff0f) != 0x0000000e) {
8901 /* UNPREDICTABLE; we choose to UNDEF */
8905 if (s
->current_el
== 2) {
8906 tmp
= load_cpu_field(elr_el
[2]);
8908 tmp
= load_reg(s
, 14);
8910 gen_exception_return(s
, tmp
);
8914 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8923 gen_exception_bkpt_insn(s
, 4, syn_aa32_bkpt(imm16
, false));
8926 /* Hypervisor call (v7) */
8934 /* Secure monitor call (v6+) */
8942 g_assert_not_reached();
8946 case 0x8: /* signed multiply */
8951 rs
= (insn
>> 8) & 0xf;
8952 rn
= (insn
>> 12) & 0xf;
8953 rd
= (insn
>> 16) & 0xf;
8955 /* (32 * 16) >> 16 */
8956 tmp
= load_reg(s
, rm
);
8957 tmp2
= load_reg(s
, rs
);
8959 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8962 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8963 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8964 tmp
= tcg_temp_new_i32();
8965 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8966 tcg_temp_free_i64(tmp64
);
8967 if ((sh
& 2) == 0) {
8968 tmp2
= load_reg(s
, rn
);
8969 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8970 tcg_temp_free_i32(tmp2
);
8972 store_reg(s
, rd
, tmp
);
8975 tmp
= load_reg(s
, rm
);
8976 tmp2
= load_reg(s
, rs
);
8977 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8978 tcg_temp_free_i32(tmp2
);
8980 tmp64
= tcg_temp_new_i64();
8981 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8982 tcg_temp_free_i32(tmp
);
8983 gen_addq(s
, tmp64
, rn
, rd
);
8984 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8985 tcg_temp_free_i64(tmp64
);
8988 tmp2
= load_reg(s
, rn
);
8989 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8990 tcg_temp_free_i32(tmp2
);
8992 store_reg(s
, rd
, tmp
);
8999 } else if (((insn
& 0x0e000000) == 0 &&
9000 (insn
& 0x00000090) != 0x90) ||
9001 ((insn
& 0x0e000000) == (1 << 25))) {
9002 int set_cc
, logic_cc
, shiftop
;
9004 op1
= (insn
>> 21) & 0xf;
9005 set_cc
= (insn
>> 20) & 1;
9006 logic_cc
= table_logic_cc
[op1
] & set_cc
;
9008 /* data processing instruction */
9009 if (insn
& (1 << 25)) {
9010 /* immediate operand */
9012 shift
= ((insn
>> 8) & 0xf) * 2;
9014 val
= (val
>> shift
) | (val
<< (32 - shift
));
9016 tmp2
= tcg_temp_new_i32();
9017 tcg_gen_movi_i32(tmp2
, val
);
9018 if (logic_cc
&& shift
) {
9019 gen_set_CF_bit31(tmp2
);
9024 tmp2
= load_reg(s
, rm
);
9025 shiftop
= (insn
>> 5) & 3;
9026 if (!(insn
& (1 << 4))) {
9027 shift
= (insn
>> 7) & 0x1f;
9028 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9030 rs
= (insn
>> 8) & 0xf;
9031 tmp
= load_reg(s
, rs
);
9032 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
9035 if (op1
!= 0x0f && op1
!= 0x0d) {
9036 rn
= (insn
>> 16) & 0xf;
9037 tmp
= load_reg(s
, rn
);
9041 rd
= (insn
>> 12) & 0xf;
9044 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9048 store_reg_bx(s
, rd
, tmp
);
9051 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9055 store_reg_bx(s
, rd
, tmp
);
9058 if (set_cc
&& rd
== 15) {
9059 /* SUBS r15, ... is used for exception return. */
9063 gen_sub_CC(tmp
, tmp
, tmp2
);
9064 gen_exception_return(s
, tmp
);
9067 gen_sub_CC(tmp
, tmp
, tmp2
);
9069 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9071 store_reg_bx(s
, rd
, tmp
);
9076 gen_sub_CC(tmp
, tmp2
, tmp
);
9078 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9080 store_reg_bx(s
, rd
, tmp
);
9084 gen_add_CC(tmp
, tmp
, tmp2
);
9086 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9088 store_reg_bx(s
, rd
, tmp
);
9092 gen_adc_CC(tmp
, tmp
, tmp2
);
9094 gen_add_carry(tmp
, tmp
, tmp2
);
9096 store_reg_bx(s
, rd
, tmp
);
9100 gen_sbc_CC(tmp
, tmp
, tmp2
);
9102 gen_sub_carry(tmp
, tmp
, tmp2
);
9104 store_reg_bx(s
, rd
, tmp
);
9108 gen_sbc_CC(tmp
, tmp2
, tmp
);
9110 gen_sub_carry(tmp
, tmp2
, tmp
);
9112 store_reg_bx(s
, rd
, tmp
);
9116 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9119 tcg_temp_free_i32(tmp
);
9123 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9126 tcg_temp_free_i32(tmp
);
9130 gen_sub_CC(tmp
, tmp
, tmp2
);
9132 tcg_temp_free_i32(tmp
);
9136 gen_add_CC(tmp
, tmp
, tmp2
);
9138 tcg_temp_free_i32(tmp
);
9141 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9145 store_reg_bx(s
, rd
, tmp
);
9148 if (logic_cc
&& rd
== 15) {
9149 /* MOVS r15, ... is used for exception return. */
9153 gen_exception_return(s
, tmp2
);
9158 store_reg_bx(s
, rd
, tmp2
);
9162 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9166 store_reg_bx(s
, rd
, tmp
);
9170 tcg_gen_not_i32(tmp2
, tmp2
);
9174 store_reg_bx(s
, rd
, tmp2
);
9177 if (op1
!= 0x0f && op1
!= 0x0d) {
9178 tcg_temp_free_i32(tmp2
);
9181 /* other instructions */
9182 op1
= (insn
>> 24) & 0xf;
9186 /* multiplies, extra load/stores */
9187 sh
= (insn
>> 5) & 3;
9190 rd
= (insn
>> 16) & 0xf;
9191 rn
= (insn
>> 12) & 0xf;
9192 rs
= (insn
>> 8) & 0xf;
9194 op1
= (insn
>> 20) & 0xf;
9196 case 0: case 1: case 2: case 3: case 6:
9198 tmp
= load_reg(s
, rs
);
9199 tmp2
= load_reg(s
, rm
);
9200 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9201 tcg_temp_free_i32(tmp2
);
9202 if (insn
& (1 << 22)) {
9203 /* Subtract (mls) */
9205 tmp2
= load_reg(s
, rn
);
9206 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9207 tcg_temp_free_i32(tmp2
);
9208 } else if (insn
& (1 << 21)) {
9210 tmp2
= load_reg(s
, rn
);
9211 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9212 tcg_temp_free_i32(tmp2
);
9214 if (insn
& (1 << 20))
9216 store_reg(s
, rd
, tmp
);
9219 /* 64 bit mul double accumulate (UMAAL) */
9221 tmp
= load_reg(s
, rs
);
9222 tmp2
= load_reg(s
, rm
);
9223 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9224 gen_addq_lo(s
, tmp64
, rn
);
9225 gen_addq_lo(s
, tmp64
, rd
);
9226 gen_storeq_reg(s
, rn
, rd
, tmp64
);
9227 tcg_temp_free_i64(tmp64
);
9229 case 8: case 9: case 10: case 11:
9230 case 12: case 13: case 14: case 15:
9231 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9232 tmp
= load_reg(s
, rs
);
9233 tmp2
= load_reg(s
, rm
);
9234 if (insn
& (1 << 22)) {
9235 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
9237 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
9239 if (insn
& (1 << 21)) { /* mult accumulate */
9240 TCGv_i32 al
= load_reg(s
, rn
);
9241 TCGv_i32 ah
= load_reg(s
, rd
);
9242 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
9243 tcg_temp_free_i32(al
);
9244 tcg_temp_free_i32(ah
);
9246 if (insn
& (1 << 20)) {
9247 gen_logicq_cc(tmp
, tmp2
);
9249 store_reg(s
, rn
, tmp
);
9250 store_reg(s
, rd
, tmp2
);
9256 rn
= (insn
>> 16) & 0xf;
9257 rd
= (insn
>> 12) & 0xf;
9258 if (insn
& (1 << 23)) {
9259 /* load/store exclusive */
9260 bool is_ld
= extract32(insn
, 20, 1);
9261 bool is_lasr
= !extract32(insn
, 8, 1);
9262 int op2
= (insn
>> 8) & 3;
9263 op1
= (insn
>> 21) & 0x3;
9266 case 0: /* lda/stl */
9272 case 1: /* reserved */
9274 case 2: /* ldaex/stlex */
9277 case 3: /* ldrex/strex */
9286 addr
= tcg_temp_local_new_i32();
9287 load_reg_var(s
, addr
, rn
);
9289 if (is_lasr
&& !is_ld
) {
9290 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
9295 tmp
= tcg_temp_new_i32();
9298 gen_aa32_ld32u_iss(s
, tmp
, addr
,
9303 gen_aa32_ld8u_iss(s
, tmp
, addr
,
9308 gen_aa32_ld16u_iss(s
, tmp
, addr
,
9315 store_reg(s
, rd
, tmp
);
9318 tmp
= load_reg(s
, rm
);
9321 gen_aa32_st32_iss(s
, tmp
, addr
,
9326 gen_aa32_st8_iss(s
, tmp
, addr
,
9331 gen_aa32_st16_iss(s
, tmp
, addr
,
9338 tcg_temp_free_i32(tmp
);
9343 gen_load_exclusive(s
, rd
, 15, addr
, 2);
9345 case 1: /* ldrexd */
9346 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
9348 case 2: /* ldrexb */
9349 gen_load_exclusive(s
, rd
, 15, addr
, 0);
9351 case 3: /* ldrexh */
9352 gen_load_exclusive(s
, rd
, 15, addr
, 1);
9361 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
9363 case 1: /* strexd */
9364 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
9366 case 2: /* strexb */
9367 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
9369 case 3: /* strexh */
9370 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
9376 tcg_temp_free_i32(addr
);
9378 if (is_lasr
&& is_ld
) {
9379 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
9381 } else if ((insn
& 0x00300f00) == 0) {
9382 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9387 TCGMemOp opc
= s
->be_data
;
9391 if (insn
& (1 << 22)) {
9394 opc
|= MO_UL
| MO_ALIGN
;
9397 addr
= load_reg(s
, rn
);
9398 taddr
= gen_aa32_addr(s
, addr
, opc
);
9399 tcg_temp_free_i32(addr
);
9401 tmp
= load_reg(s
, rm
);
9402 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
9403 get_mem_index(s
), opc
);
9404 tcg_temp_free(taddr
);
9405 store_reg(s
, rd
, tmp
);
9412 bool load
= insn
& (1 << 20);
9413 bool wbit
= insn
& (1 << 21);
9414 bool pbit
= insn
& (1 << 24);
9415 bool doubleword
= false;
9418 /* Misc load/store */
9419 rn
= (insn
>> 16) & 0xf;
9420 rd
= (insn
>> 12) & 0xf;
9422 /* ISS not valid if writeback */
9423 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
9425 if (!load
&& (sh
& 2)) {
9429 /* UNPREDICTABLE; we choose to UNDEF */
9432 load
= (sh
& 1) == 0;
9436 addr
= load_reg(s
, rn
);
9438 gen_add_datah_offset(s
, insn
, 0, addr
);
9445 tmp
= load_reg(s
, rd
);
9446 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9447 tcg_temp_free_i32(tmp
);
9448 tcg_gen_addi_i32(addr
, addr
, 4);
9449 tmp
= load_reg(s
, rd
+ 1);
9450 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9451 tcg_temp_free_i32(tmp
);
9454 tmp
= tcg_temp_new_i32();
9455 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9456 store_reg(s
, rd
, tmp
);
9457 tcg_gen_addi_i32(addr
, addr
, 4);
9458 tmp
= tcg_temp_new_i32();
9459 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9462 address_offset
= -4;
9465 tmp
= tcg_temp_new_i32();
9468 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9472 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9477 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9483 tmp
= load_reg(s
, rd
);
9484 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9485 tcg_temp_free_i32(tmp
);
9487 /* Perform base writeback before the loaded value to
9488 ensure correct behavior with overlapping index registers.
9489 ldrd with base writeback is undefined if the
9490 destination and index registers overlap. */
9492 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9493 store_reg(s
, rn
, addr
);
9496 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9497 store_reg(s
, rn
, addr
);
9499 tcg_temp_free_i32(addr
);
9502 /* Complete the load. */
9503 store_reg(s
, rd
, tmp
);
9512 if (insn
& (1 << 4)) {
9514 /* Armv6 Media instructions. */
9516 rn
= (insn
>> 16) & 0xf;
9517 rd
= (insn
>> 12) & 0xf;
9518 rs
= (insn
>> 8) & 0xf;
9519 switch ((insn
>> 23) & 3) {
9520 case 0: /* Parallel add/subtract. */
9521 op1
= (insn
>> 20) & 7;
9522 tmp
= load_reg(s
, rn
);
9523 tmp2
= load_reg(s
, rm
);
9524 sh
= (insn
>> 5) & 7;
9525 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9527 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9528 tcg_temp_free_i32(tmp2
);
9529 store_reg(s
, rd
, tmp
);
9532 if ((insn
& 0x00700020) == 0) {
9533 /* Halfword pack. */
9534 tmp
= load_reg(s
, rn
);
9535 tmp2
= load_reg(s
, rm
);
9536 shift
= (insn
>> 7) & 0x1f;
9537 if (insn
& (1 << 6)) {
9541 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9542 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9543 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9547 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9548 tcg_gen_ext16u_i32(tmp
, tmp
);
9549 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9551 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9552 tcg_temp_free_i32(tmp2
);
9553 store_reg(s
, rd
, tmp
);
9554 } else if ((insn
& 0x00200020) == 0x00200000) {
9556 tmp
= load_reg(s
, rm
);
9557 shift
= (insn
>> 7) & 0x1f;
9558 if (insn
& (1 << 6)) {
9561 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9563 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9565 sh
= (insn
>> 16) & 0x1f;
9566 tmp2
= tcg_const_i32(sh
);
9567 if (insn
& (1 << 22))
9568 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9570 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9571 tcg_temp_free_i32(tmp2
);
9572 store_reg(s
, rd
, tmp
);
9573 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9575 tmp
= load_reg(s
, rm
);
9576 sh
= (insn
>> 16) & 0x1f;
9577 tmp2
= tcg_const_i32(sh
);
9578 if (insn
& (1 << 22))
9579 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9581 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9582 tcg_temp_free_i32(tmp2
);
9583 store_reg(s
, rd
, tmp
);
9584 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9586 tmp
= load_reg(s
, rn
);
9587 tmp2
= load_reg(s
, rm
);
9588 tmp3
= tcg_temp_new_i32();
9589 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9590 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9591 tcg_temp_free_i32(tmp3
);
9592 tcg_temp_free_i32(tmp2
);
9593 store_reg(s
, rd
, tmp
);
9594 } else if ((insn
& 0x000003e0) == 0x00000060) {
9595 tmp
= load_reg(s
, rm
);
9596 shift
= (insn
>> 10) & 3;
9597 /* ??? In many cases it's not necessary to do a
9598 rotate, a shift is sufficient. */
9600 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9601 op1
= (insn
>> 20) & 7;
9603 case 0: gen_sxtb16(tmp
); break;
9604 case 2: gen_sxtb(tmp
); break;
9605 case 3: gen_sxth(tmp
); break;
9606 case 4: gen_uxtb16(tmp
); break;
9607 case 6: gen_uxtb(tmp
); break;
9608 case 7: gen_uxth(tmp
); break;
9609 default: goto illegal_op
;
9612 tmp2
= load_reg(s
, rn
);
9613 if ((op1
& 3) == 0) {
9614 gen_add16(tmp
, tmp2
);
9616 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9617 tcg_temp_free_i32(tmp2
);
9620 store_reg(s
, rd
, tmp
);
9621 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9623 tmp
= load_reg(s
, rm
);
9624 if (insn
& (1 << 22)) {
9625 if (insn
& (1 << 7)) {
9629 gen_helper_rbit(tmp
, tmp
);
9632 if (insn
& (1 << 7))
9635 tcg_gen_bswap32_i32(tmp
, tmp
);
9637 store_reg(s
, rd
, tmp
);
9642 case 2: /* Multiplies (Type 3). */
9643 switch ((insn
>> 20) & 0x7) {
9645 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9646 /* op2 not 00x or 11x : UNDEF */
9649 /* Signed multiply most significant [accumulate].
9650 (SMMUL, SMMLA, SMMLS) */
9651 tmp
= load_reg(s
, rm
);
9652 tmp2
= load_reg(s
, rs
);
9653 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9656 tmp
= load_reg(s
, rd
);
9657 if (insn
& (1 << 6)) {
9658 tmp64
= gen_subq_msw(tmp64
, tmp
);
9660 tmp64
= gen_addq_msw(tmp64
, tmp
);
9663 if (insn
& (1 << 5)) {
9664 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9666 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9667 tmp
= tcg_temp_new_i32();
9668 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9669 tcg_temp_free_i64(tmp64
);
9670 store_reg(s
, rn
, tmp
);
9674 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9675 if (insn
& (1 << 7)) {
9678 tmp
= load_reg(s
, rm
);
9679 tmp2
= load_reg(s
, rs
);
9680 if (insn
& (1 << 5))
9681 gen_swap_half(tmp2
);
9682 gen_smul_dual(tmp
, tmp2
);
9683 if (insn
& (1 << 22)) {
9684 /* smlald, smlsld */
9687 tmp64
= tcg_temp_new_i64();
9688 tmp64_2
= tcg_temp_new_i64();
9689 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9690 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9691 tcg_temp_free_i32(tmp
);
9692 tcg_temp_free_i32(tmp2
);
9693 if (insn
& (1 << 6)) {
9694 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9696 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9698 tcg_temp_free_i64(tmp64_2
);
9699 gen_addq(s
, tmp64
, rd
, rn
);
9700 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9701 tcg_temp_free_i64(tmp64
);
9703 /* smuad, smusd, smlad, smlsd */
9704 if (insn
& (1 << 6)) {
9705 /* This subtraction cannot overflow. */
9706 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9708 /* This addition cannot overflow 32 bits;
9709 * however it may overflow considered as a
9710 * signed operation, in which case we must set
9713 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9715 tcg_temp_free_i32(tmp2
);
9718 tmp2
= load_reg(s
, rd
);
9719 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9720 tcg_temp_free_i32(tmp2
);
9722 store_reg(s
, rn
, tmp
);
9728 if (!dc_isar_feature(arm_div
, s
)) {
9731 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9734 tmp
= load_reg(s
, rm
);
9735 tmp2
= load_reg(s
, rs
);
9736 if (insn
& (1 << 21)) {
9737 gen_helper_udiv(tmp
, tmp
, tmp2
);
9739 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9741 tcg_temp_free_i32(tmp2
);
9742 store_reg(s
, rn
, tmp
);
9749 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9751 case 0: /* Unsigned sum of absolute differences. */
9753 tmp
= load_reg(s
, rm
);
9754 tmp2
= load_reg(s
, rs
);
9755 gen_helper_usad8(tmp
, tmp
, tmp2
);
9756 tcg_temp_free_i32(tmp2
);
9758 tmp2
= load_reg(s
, rd
);
9759 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9760 tcg_temp_free_i32(tmp2
);
9762 store_reg(s
, rn
, tmp
);
9764 case 0x20: case 0x24: case 0x28: case 0x2c:
9765 /* Bitfield insert/clear. */
9767 shift
= (insn
>> 7) & 0x1f;
9768 i
= (insn
>> 16) & 0x1f;
9770 /* UNPREDICTABLE; we choose to UNDEF */
9775 tmp
= tcg_temp_new_i32();
9776 tcg_gen_movi_i32(tmp
, 0);
9778 tmp
= load_reg(s
, rm
);
9781 tmp2
= load_reg(s
, rd
);
9782 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9783 tcg_temp_free_i32(tmp2
);
9785 store_reg(s
, rd
, tmp
);
9787 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9788 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9790 tmp
= load_reg(s
, rm
);
9791 shift
= (insn
>> 7) & 0x1f;
9792 i
= ((insn
>> 16) & 0x1f) + 1;
9797 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9799 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9802 store_reg(s
, rd
, tmp
);
9812 /* Check for undefined extension instructions
9813 * per the ARM Bible IE:
9814 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9816 sh
= (0xf << 20) | (0xf << 4);
9817 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9821 /* load/store byte/word */
9822 rn
= (insn
>> 16) & 0xf;
9823 rd
= (insn
>> 12) & 0xf;
9824 tmp2
= load_reg(s
, rn
);
9825 if ((insn
& 0x01200000) == 0x00200000) {
9827 i
= get_a32_user_mem_index(s
);
9829 i
= get_mem_index(s
);
9831 if (insn
& (1 << 24))
9832 gen_add_data_offset(s
, insn
, tmp2
);
9833 if (insn
& (1 << 20)) {
9835 tmp
= tcg_temp_new_i32();
9836 if (insn
& (1 << 22)) {
9837 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9839 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9843 tmp
= load_reg(s
, rd
);
9844 if (insn
& (1 << 22)) {
9845 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9847 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9849 tcg_temp_free_i32(tmp
);
9851 if (!(insn
& (1 << 24))) {
9852 gen_add_data_offset(s
, insn
, tmp2
);
9853 store_reg(s
, rn
, tmp2
);
9854 } else if (insn
& (1 << 21)) {
9855 store_reg(s
, rn
, tmp2
);
9857 tcg_temp_free_i32(tmp2
);
9859 if (insn
& (1 << 20)) {
9860 /* Complete the load. */
9861 store_reg_from_load(s
, rd
, tmp
);
9867 int j
, n
, loaded_base
;
9868 bool exc_return
= false;
9869 bool is_load
= extract32(insn
, 20, 1);
9871 TCGv_i32 loaded_var
;
9872 /* load/store multiple words */
9873 /* XXX: store correct base if write back */
9874 if (insn
& (1 << 22)) {
9875 /* LDM (user), LDM (exception return) and STM (user) */
9877 goto illegal_op
; /* only usable in supervisor mode */
9879 if (is_load
&& extract32(insn
, 15, 1)) {
9885 rn
= (insn
>> 16) & 0xf;
9886 addr
= load_reg(s
, rn
);
9888 /* compute total size */
9893 if (insn
& (1 << i
))
9896 /* XXX: test invalid n == 0 case ? */
9897 if (insn
& (1 << 23)) {
9898 if (insn
& (1 << 24)) {
9900 tcg_gen_addi_i32(addr
, addr
, 4);
9902 /* post increment */
9905 if (insn
& (1 << 24)) {
9907 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9909 /* post decrement */
9911 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9916 if (insn
& (1 << i
)) {
9919 tmp
= tcg_temp_new_i32();
9920 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9922 tmp2
= tcg_const_i32(i
);
9923 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9924 tcg_temp_free_i32(tmp2
);
9925 tcg_temp_free_i32(tmp
);
9926 } else if (i
== rn
) {
9929 } else if (i
== 15 && exc_return
) {
9930 store_pc_exc_ret(s
, tmp
);
9932 store_reg_from_load(s
, i
, tmp
);
9937 /* special case: r15 = PC + 8 */
9938 val
= (long)s
->pc
+ 4;
9939 tmp
= tcg_temp_new_i32();
9940 tcg_gen_movi_i32(tmp
, val
);
9942 tmp
= tcg_temp_new_i32();
9943 tmp2
= tcg_const_i32(i
);
9944 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9945 tcg_temp_free_i32(tmp2
);
9947 tmp
= load_reg(s
, i
);
9949 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9950 tcg_temp_free_i32(tmp
);
9953 /* no need to add after the last transfer */
9955 tcg_gen_addi_i32(addr
, addr
, 4);
9958 if (insn
& (1 << 21)) {
9960 if (insn
& (1 << 23)) {
9961 if (insn
& (1 << 24)) {
9964 /* post increment */
9965 tcg_gen_addi_i32(addr
, addr
, 4);
9968 if (insn
& (1 << 24)) {
9971 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9973 /* post decrement */
9974 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9977 store_reg(s
, rn
, addr
);
9979 tcg_temp_free_i32(addr
);
9982 store_reg(s
, rn
, loaded_var
);
9985 /* Restore CPSR from SPSR. */
9986 tmp
= load_cpu_field(spsr
);
9987 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
9990 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9991 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
9994 tcg_temp_free_i32(tmp
);
9995 /* Must exit loop to check un-masked IRQs */
9996 s
->base
.is_jmp
= DISAS_EXIT
;
10005 /* branch (and link) */
10006 val
= (int32_t)s
->pc
;
10007 if (insn
& (1 << 24)) {
10008 tmp
= tcg_temp_new_i32();
10009 tcg_gen_movi_i32(tmp
, val
);
10010 store_reg(s
, 14, tmp
);
10012 offset
= sextract32(insn
<< 2, 0, 26);
10020 if (((insn
>> 8) & 0xe) == 10) {
10022 if (disas_vfp_insn(s
, insn
)) {
10025 } else if (disas_coproc_insn(s
, insn
)) {
10032 gen_set_pc_im(s
, s
->pc
);
10033 s
->svc_imm
= extract32(insn
, 0, 24);
10034 s
->base
.is_jmp
= DISAS_SWI
;
10038 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
10039 default_exception_el(s
));
10045 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t insn
)
10047 /* Return true if this is a 16 bit instruction. We must be precise
10048 * about this (matching the decode). We assume that s->pc still
10049 * points to the first 16 bits of the insn.
10051 if ((insn
>> 11) < 0x1d) {
10052 /* Definitely a 16-bit instruction */
10056 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10057 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10058 * end up actually treating this as two 16-bit insns, though,
10059 * if it's half of a bl/blx pair that might span a page boundary.
10061 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
) ||
10062 arm_dc_feature(s
, ARM_FEATURE_M
)) {
10063 /* Thumb2 cores (including all M profile ones) always treat
10064 * 32-bit insns as 32-bit.
10069 if ((insn
>> 11) == 0x1e && s
->pc
- s
->page_start
< TARGET_PAGE_SIZE
- 3) {
10070 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10071 * is not on the next page; we merge this into a 32-bit
10076 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10077 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10078 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10079 * -- handle as single 16 bit insn
10084 /* Return true if this is a Thumb-2 logical op. */
10086 thumb2_logic_op(int op
)
10091 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10092 then set condition code flags based on the result of the operation.
10093 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10094 to the high bit of T1.
10095 Returns zero if the opcode is valid. */
10098 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
10099 TCGv_i32 t0
, TCGv_i32 t1
)
10106 tcg_gen_and_i32(t0
, t0
, t1
);
10110 tcg_gen_andc_i32(t0
, t0
, t1
);
10114 tcg_gen_or_i32(t0
, t0
, t1
);
10118 tcg_gen_orc_i32(t0
, t0
, t1
);
10122 tcg_gen_xor_i32(t0
, t0
, t1
);
10127 gen_add_CC(t0
, t0
, t1
);
10129 tcg_gen_add_i32(t0
, t0
, t1
);
10133 gen_adc_CC(t0
, t0
, t1
);
10139 gen_sbc_CC(t0
, t0
, t1
);
10141 gen_sub_carry(t0
, t0
, t1
);
10146 gen_sub_CC(t0
, t0
, t1
);
10148 tcg_gen_sub_i32(t0
, t0
, t1
);
10152 gen_sub_CC(t0
, t1
, t0
);
10154 tcg_gen_sub_i32(t0
, t1
, t0
);
10156 default: /* 5, 6, 7, 9, 12, 15. */
10162 gen_set_CF_bit31(t1
);
10167 /* Translate a 32-bit thumb instruction. */
10168 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
10170 uint32_t imm
, shift
, offset
;
10171 uint32_t rd
, rn
, rm
, rs
;
10183 * ARMv6-M supports a limited subset of Thumb2 instructions.
10184 * Other Thumb1 architectures allow only 32-bit
10185 * combined BL/BLX prefix and suffix.
10187 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
10188 !arm_dc_feature(s
, ARM_FEATURE_V7
)) {
10190 bool found
= false;
10191 static const uint32_t armv6m_insn
[] = {0xf3808000 /* msr */,
10192 0xf3b08040 /* dsb */,
10193 0xf3b08050 /* dmb */,
10194 0xf3b08060 /* isb */,
10195 0xf3e08000 /* mrs */,
10196 0xf000d000 /* bl */};
10197 static const uint32_t armv6m_mask
[] = {0xffe0d000,
10204 for (i
= 0; i
< ARRAY_SIZE(armv6m_insn
); i
++) {
10205 if ((insn
& armv6m_mask
[i
]) == armv6m_insn
[i
]) {
10213 } else if ((insn
& 0xf800e800) != 0xf000e800) {
10217 rn
= (insn
>> 16) & 0xf;
10218 rs
= (insn
>> 12) & 0xf;
10219 rd
= (insn
>> 8) & 0xf;
10221 switch ((insn
>> 25) & 0xf) {
10222 case 0: case 1: case 2: case 3:
10223 /* 16-bit instructions. Should never happen. */
10226 if (insn
& (1 << 22)) {
10227 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10228 * - load/store doubleword, load/store exclusive, ldacq/strel,
10229 * table branch, TT.
10231 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_M
) &&
10232 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10233 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10235 * The bulk of the behaviour for this instruction is implemented
10236 * in v7m_handle_execute_nsc(), which deals with the insn when
10237 * it is executed by a CPU in non-secure state from memory
10238 * which is Secure & NonSecure-Callable.
10239 * Here we only need to handle the remaining cases:
10240 * * in NS memory (including the "security extension not
10241 * implemented" case) : NOP
10242 * * in S memory but CPU already secure (clear IT bits)
10243 * We know that the attribute for the memory this insn is
10244 * in must match the current CPU state, because otherwise
10245 * get_phys_addr_pmsav8 would have generated an exception.
10247 if (s
->v8m_secure
) {
10248 /* Like the IT insn, we don't need to generate any code */
10249 s
->condexec_cond
= 0;
10250 s
->condexec_mask
= 0;
10252 } else if (insn
& 0x01200000) {
10253 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10254 * - load/store dual (post-indexed)
10255 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10256 * - load/store dual (literal and immediate)
10257 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10258 * - load/store dual (pre-indexed)
10260 bool wback
= extract32(insn
, 21, 1);
10263 if (insn
& (1 << 21)) {
10264 /* UNPREDICTABLE */
10267 addr
= tcg_temp_new_i32();
10268 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
10270 addr
= load_reg(s
, rn
);
10272 offset
= (insn
& 0xff) * 4;
10273 if ((insn
& (1 << 23)) == 0) {
10277 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
10279 * Here 'addr' is the current SP; if offset is +ve we're
10280 * moving SP up, else down. It is UNKNOWN whether the limit
10281 * check triggers when SP starts below the limit and ends
10282 * up above it; check whichever of the current and final
10283 * SP is lower, so QEMU will trigger in that situation.
10285 if ((int32_t)offset
< 0) {
10286 TCGv_i32 newsp
= tcg_temp_new_i32();
10288 tcg_gen_addi_i32(newsp
, addr
, offset
);
10289 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
10290 tcg_temp_free_i32(newsp
);
10292 gen_helper_v8m_stackcheck(cpu_env
, addr
);
10296 if (insn
& (1 << 24)) {
10297 tcg_gen_addi_i32(addr
, addr
, offset
);
10300 if (insn
& (1 << 20)) {
10302 tmp
= tcg_temp_new_i32();
10303 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10304 store_reg(s
, rs
, tmp
);
10305 tcg_gen_addi_i32(addr
, addr
, 4);
10306 tmp
= tcg_temp_new_i32();
10307 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10308 store_reg(s
, rd
, tmp
);
10311 tmp
= load_reg(s
, rs
);
10312 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10313 tcg_temp_free_i32(tmp
);
10314 tcg_gen_addi_i32(addr
, addr
, 4);
10315 tmp
= load_reg(s
, rd
);
10316 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10317 tcg_temp_free_i32(tmp
);
10320 /* Base writeback. */
10321 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
10322 store_reg(s
, rn
, addr
);
10324 tcg_temp_free_i32(addr
);
10326 } else if ((insn
& (1 << 23)) == 0) {
10327 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10328 * - load/store exclusive word
10332 if (!(insn
& (1 << 20)) &&
10333 arm_dc_feature(s
, ARM_FEATURE_M
) &&
10334 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10335 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10338 bool alt
= insn
& (1 << 7);
10339 TCGv_i32 addr
, op
, ttresp
;
10341 if ((insn
& 0x3f) || rd
== 13 || rd
== 15 || rn
== 15) {
10342 /* we UNDEF for these UNPREDICTABLE cases */
10346 if (alt
&& !s
->v8m_secure
) {
10350 addr
= load_reg(s
, rn
);
10351 op
= tcg_const_i32(extract32(insn
, 6, 2));
10352 ttresp
= tcg_temp_new_i32();
10353 gen_helper_v7m_tt(ttresp
, cpu_env
, addr
, op
);
10354 tcg_temp_free_i32(addr
);
10355 tcg_temp_free_i32(op
);
10356 store_reg(s
, rd
, ttresp
);
10361 addr
= tcg_temp_local_new_i32();
10362 load_reg_var(s
, addr
, rn
);
10363 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
10364 if (insn
& (1 << 20)) {
10365 gen_load_exclusive(s
, rs
, 15, addr
, 2);
10367 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
10369 tcg_temp_free_i32(addr
);
10370 } else if ((insn
& (7 << 5)) == 0) {
10371 /* Table Branch. */
10373 addr
= tcg_temp_new_i32();
10374 tcg_gen_movi_i32(addr
, s
->pc
);
10376 addr
= load_reg(s
, rn
);
10378 tmp
= load_reg(s
, rm
);
10379 tcg_gen_add_i32(addr
, addr
, tmp
);
10380 if (insn
& (1 << 4)) {
10382 tcg_gen_add_i32(addr
, addr
, tmp
);
10383 tcg_temp_free_i32(tmp
);
10384 tmp
= tcg_temp_new_i32();
10385 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
10387 tcg_temp_free_i32(tmp
);
10388 tmp
= tcg_temp_new_i32();
10389 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
10391 tcg_temp_free_i32(addr
);
10392 tcg_gen_shli_i32(tmp
, tmp
, 1);
10393 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
10394 store_reg(s
, 15, tmp
);
10396 bool is_lasr
= false;
10397 bool is_ld
= extract32(insn
, 20, 1);
10398 int op2
= (insn
>> 6) & 0x3;
10399 op
= (insn
>> 4) & 0x3;
10404 /* Load/store exclusive byte/halfword/doubleword */
10411 /* Load-acquire/store-release */
10417 /* Load-acquire/store-release exclusive */
10423 if (is_lasr
&& !is_ld
) {
10424 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
10427 addr
= tcg_temp_local_new_i32();
10428 load_reg_var(s
, addr
, rn
);
10431 tmp
= tcg_temp_new_i32();
10434 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
10438 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
10442 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
10448 store_reg(s
, rs
, tmp
);
10450 tmp
= load_reg(s
, rs
);
10453 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
10457 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
10461 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
10467 tcg_temp_free_i32(tmp
);
10469 } else if (is_ld
) {
10470 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
10472 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
10474 tcg_temp_free_i32(addr
);
10476 if (is_lasr
&& is_ld
) {
10477 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
10481 /* Load/store multiple, RFE, SRS. */
10482 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
10483 /* RFE, SRS: not available in user mode or on M profile */
10484 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10487 if (insn
& (1 << 20)) {
10489 addr
= load_reg(s
, rn
);
10490 if ((insn
& (1 << 24)) == 0)
10491 tcg_gen_addi_i32(addr
, addr
, -8);
10492 /* Load PC into tmp and CPSR into tmp2. */
10493 tmp
= tcg_temp_new_i32();
10494 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10495 tcg_gen_addi_i32(addr
, addr
, 4);
10496 tmp2
= tcg_temp_new_i32();
10497 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
10498 if (insn
& (1 << 21)) {
10499 /* Base writeback. */
10500 if (insn
& (1 << 24)) {
10501 tcg_gen_addi_i32(addr
, addr
, 4);
10503 tcg_gen_addi_i32(addr
, addr
, -4);
10505 store_reg(s
, rn
, addr
);
10507 tcg_temp_free_i32(addr
);
10509 gen_rfe(s
, tmp
, tmp2
);
10512 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
10516 int i
, loaded_base
= 0;
10517 TCGv_i32 loaded_var
;
10518 bool wback
= extract32(insn
, 21, 1);
10519 /* Load/store multiple. */
10520 addr
= load_reg(s
, rn
);
10522 for (i
= 0; i
< 16; i
++) {
10523 if (insn
& (1 << i
))
10527 if (insn
& (1 << 24)) {
10528 tcg_gen_addi_i32(addr
, addr
, -offset
);
10531 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
10533 * If the writeback is incrementing SP rather than
10534 * decrementing it, and the initial SP is below the
10535 * stack limit but the final written-back SP would
10536 * be above, then then we must not perform any memory
10537 * accesses, but it is IMPDEF whether we generate
10538 * an exception. We choose to do so in this case.
10539 * At this point 'addr' is the lowest address, so
10540 * either the original SP (if incrementing) or our
10541 * final SP (if decrementing), so that's what we check.
10543 gen_helper_v8m_stackcheck(cpu_env
, addr
);
10547 for (i
= 0; i
< 16; i
++) {
10548 if ((insn
& (1 << i
)) == 0)
10550 if (insn
& (1 << 20)) {
10552 tmp
= tcg_temp_new_i32();
10553 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10555 gen_bx_excret(s
, tmp
);
10556 } else if (i
== rn
) {
10560 store_reg(s
, i
, tmp
);
10564 tmp
= load_reg(s
, i
);
10565 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10566 tcg_temp_free_i32(tmp
);
10568 tcg_gen_addi_i32(addr
, addr
, 4);
10571 store_reg(s
, rn
, loaded_var
);
10574 /* Base register writeback. */
10575 if (insn
& (1 << 24)) {
10576 tcg_gen_addi_i32(addr
, addr
, -offset
);
10578 /* Fault if writeback register is in register list. */
10579 if (insn
& (1 << rn
))
10581 store_reg(s
, rn
, addr
);
10583 tcg_temp_free_i32(addr
);
10590 op
= (insn
>> 21) & 0xf;
10592 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10595 /* Halfword pack. */
10596 tmp
= load_reg(s
, rn
);
10597 tmp2
= load_reg(s
, rm
);
10598 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
10599 if (insn
& (1 << 5)) {
10603 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
10604 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
10605 tcg_gen_ext16u_i32(tmp2
, tmp2
);
10609 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10610 tcg_gen_ext16u_i32(tmp
, tmp
);
10611 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10613 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10614 tcg_temp_free_i32(tmp2
);
10615 store_reg(s
, rd
, tmp
);
10617 /* Data processing register constant shift. */
10619 tmp
= tcg_temp_new_i32();
10620 tcg_gen_movi_i32(tmp
, 0);
10622 tmp
= load_reg(s
, rn
);
10624 tmp2
= load_reg(s
, rm
);
10626 shiftop
= (insn
>> 4) & 3;
10627 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10628 conds
= (insn
& (1 << 20)) != 0;
10629 logic_cc
= (conds
&& thumb2_logic_op(op
));
10630 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10631 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10633 tcg_temp_free_i32(tmp2
);
10635 ((op
== 2 && rn
== 15) ||
10636 (op
== 8 && rn
== 13) ||
10637 (op
== 13 && rn
== 13))) {
10638 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
10639 store_sp_checked(s
, tmp
);
10640 } else if (rd
!= 15) {
10641 store_reg(s
, rd
, tmp
);
10643 tcg_temp_free_i32(tmp
);
10647 case 13: /* Misc data processing. */
10648 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10649 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10652 case 0: /* Register controlled shift. */
10653 tmp
= load_reg(s
, rn
);
10654 tmp2
= load_reg(s
, rm
);
10655 if ((insn
& 0x70) != 0)
10658 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
10659 * - MOV, MOVS (register-shifted register), flagsetting
10661 op
= (insn
>> 21) & 3;
10662 logic_cc
= (insn
& (1 << 20)) != 0;
10663 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10666 store_reg(s
, rd
, tmp
);
10668 case 1: /* Sign/zero extend. */
10669 op
= (insn
>> 20) & 7;
10671 case 0: /* SXTAH, SXTH */
10672 case 1: /* UXTAH, UXTH */
10673 case 4: /* SXTAB, SXTB */
10674 case 5: /* UXTAB, UXTB */
10676 case 2: /* SXTAB16, SXTB16 */
10677 case 3: /* UXTAB16, UXTB16 */
10678 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10686 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10690 tmp
= load_reg(s
, rm
);
10691 shift
= (insn
>> 4) & 3;
10692 /* ??? In many cases it's not necessary to do a
10693 rotate, a shift is sufficient. */
10695 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10696 op
= (insn
>> 20) & 7;
10698 case 0: gen_sxth(tmp
); break;
10699 case 1: gen_uxth(tmp
); break;
10700 case 2: gen_sxtb16(tmp
); break;
10701 case 3: gen_uxtb16(tmp
); break;
10702 case 4: gen_sxtb(tmp
); break;
10703 case 5: gen_uxtb(tmp
); break;
10705 g_assert_not_reached();
10708 tmp2
= load_reg(s
, rn
);
10709 if ((op
>> 1) == 1) {
10710 gen_add16(tmp
, tmp2
);
10712 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10713 tcg_temp_free_i32(tmp2
);
10716 store_reg(s
, rd
, tmp
);
10718 case 2: /* SIMD add/subtract. */
10719 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10722 op
= (insn
>> 20) & 7;
10723 shift
= (insn
>> 4) & 7;
10724 if ((op
& 3) == 3 || (shift
& 3) == 3)
10726 tmp
= load_reg(s
, rn
);
10727 tmp2
= load_reg(s
, rm
);
10728 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10729 tcg_temp_free_i32(tmp2
);
10730 store_reg(s
, rd
, tmp
);
10732 case 3: /* Other data processing. */
10733 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10735 /* Saturating add/subtract. */
10736 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10739 tmp
= load_reg(s
, rn
);
10740 tmp2
= load_reg(s
, rm
);
10742 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10744 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10746 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10747 tcg_temp_free_i32(tmp2
);
10750 case 0x0a: /* rbit */
10751 case 0x08: /* rev */
10752 case 0x09: /* rev16 */
10753 case 0x0b: /* revsh */
10754 case 0x18: /* clz */
10756 case 0x10: /* sel */
10757 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10761 case 0x20: /* crc32/crc32c */
10767 if (!dc_isar_feature(aa32_crc32
, s
)) {
10774 tmp
= load_reg(s
, rn
);
10776 case 0x0a: /* rbit */
10777 gen_helper_rbit(tmp
, tmp
);
10779 case 0x08: /* rev */
10780 tcg_gen_bswap32_i32(tmp
, tmp
);
10782 case 0x09: /* rev16 */
10785 case 0x0b: /* revsh */
10788 case 0x10: /* sel */
10789 tmp2
= load_reg(s
, rm
);
10790 tmp3
= tcg_temp_new_i32();
10791 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10792 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10793 tcg_temp_free_i32(tmp3
);
10794 tcg_temp_free_i32(tmp2
);
10796 case 0x18: /* clz */
10797 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10807 uint32_t sz
= op
& 0x3;
10808 uint32_t c
= op
& 0x8;
10810 tmp2
= load_reg(s
, rm
);
10812 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10813 } else if (sz
== 1) {
10814 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10816 tmp3
= tcg_const_i32(1 << sz
);
10818 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10820 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10822 tcg_temp_free_i32(tmp2
);
10823 tcg_temp_free_i32(tmp3
);
10827 g_assert_not_reached();
10830 store_reg(s
, rd
, tmp
);
10832 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10833 switch ((insn
>> 20) & 7) {
10834 case 0: /* 32 x 32 -> 32 */
10835 case 7: /* Unsigned sum of absolute differences. */
10837 case 1: /* 16 x 16 -> 32 */
10838 case 2: /* Dual multiply add. */
10839 case 3: /* 32 * 16 -> 32msb */
10840 case 4: /* Dual multiply subtract. */
10841 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10842 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10847 op
= (insn
>> 4) & 0xf;
10848 tmp
= load_reg(s
, rn
);
10849 tmp2
= load_reg(s
, rm
);
10850 switch ((insn
>> 20) & 7) {
10851 case 0: /* 32 x 32 -> 32 */
10852 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10853 tcg_temp_free_i32(tmp2
);
10855 tmp2
= load_reg(s
, rs
);
10857 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10859 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10860 tcg_temp_free_i32(tmp2
);
10863 case 1: /* 16 x 16 -> 32 */
10864 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10865 tcg_temp_free_i32(tmp2
);
10867 tmp2
= load_reg(s
, rs
);
10868 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10869 tcg_temp_free_i32(tmp2
);
10872 case 2: /* Dual multiply add. */
10873 case 4: /* Dual multiply subtract. */
10875 gen_swap_half(tmp2
);
10876 gen_smul_dual(tmp
, tmp2
);
10877 if (insn
& (1 << 22)) {
10878 /* This subtraction cannot overflow. */
10879 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10881 /* This addition cannot overflow 32 bits;
10882 * however it may overflow considered as a signed
10883 * operation, in which case we must set the Q flag.
10885 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10887 tcg_temp_free_i32(tmp2
);
10890 tmp2
= load_reg(s
, rs
);
10891 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10892 tcg_temp_free_i32(tmp2
);
10895 case 3: /* 32 * 16 -> 32msb */
10897 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10900 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10901 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10902 tmp
= tcg_temp_new_i32();
10903 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10904 tcg_temp_free_i64(tmp64
);
10907 tmp2
= load_reg(s
, rs
);
10908 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10909 tcg_temp_free_i32(tmp2
);
10912 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10913 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10915 tmp
= load_reg(s
, rs
);
10916 if (insn
& (1 << 20)) {
10917 tmp64
= gen_addq_msw(tmp64
, tmp
);
10919 tmp64
= gen_subq_msw(tmp64
, tmp
);
10922 if (insn
& (1 << 4)) {
10923 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10925 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10926 tmp
= tcg_temp_new_i32();
10927 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10928 tcg_temp_free_i64(tmp64
);
10930 case 7: /* Unsigned sum of absolute differences. */
10931 gen_helper_usad8(tmp
, tmp
, tmp2
);
10932 tcg_temp_free_i32(tmp2
);
10934 tmp2
= load_reg(s
, rs
);
10935 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10936 tcg_temp_free_i32(tmp2
);
10940 store_reg(s
, rd
, tmp
);
10942 case 6: case 7: /* 64-bit multiply, Divide. */
10943 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10944 tmp
= load_reg(s
, rn
);
10945 tmp2
= load_reg(s
, rm
);
10946 if ((op
& 0x50) == 0x10) {
10948 if (!dc_isar_feature(thumb_div
, s
)) {
10952 gen_helper_udiv(tmp
, tmp
, tmp2
);
10954 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10955 tcg_temp_free_i32(tmp2
);
10956 store_reg(s
, rd
, tmp
);
10957 } else if ((op
& 0xe) == 0xc) {
10958 /* Dual multiply accumulate long. */
10959 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10960 tcg_temp_free_i32(tmp
);
10961 tcg_temp_free_i32(tmp2
);
10965 gen_swap_half(tmp2
);
10966 gen_smul_dual(tmp
, tmp2
);
10968 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10970 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10972 tcg_temp_free_i32(tmp2
);
10974 tmp64
= tcg_temp_new_i64();
10975 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10976 tcg_temp_free_i32(tmp
);
10977 gen_addq(s
, tmp64
, rs
, rd
);
10978 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10979 tcg_temp_free_i64(tmp64
);
10982 /* Unsigned 64-bit multiply */
10983 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10987 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10988 tcg_temp_free_i32(tmp2
);
10989 tcg_temp_free_i32(tmp
);
10992 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10993 tcg_temp_free_i32(tmp2
);
10994 tmp64
= tcg_temp_new_i64();
10995 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10996 tcg_temp_free_i32(tmp
);
10998 /* Signed 64-bit multiply */
10999 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
11004 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11005 tcg_temp_free_i64(tmp64
);
11008 gen_addq_lo(s
, tmp64
, rs
);
11009 gen_addq_lo(s
, tmp64
, rd
);
11010 } else if (op
& 0x40) {
11011 /* 64-bit accumulate. */
11012 gen_addq(s
, tmp64
, rs
, rd
);
11014 gen_storeq_reg(s
, rs
, rd
, tmp64
);
11015 tcg_temp_free_i64(tmp64
);
11020 case 6: case 7: case 14: case 15:
11022 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11023 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
11024 if (extract32(insn
, 24, 2) == 3) {
11025 goto illegal_op
; /* op0 = 0b11 : unallocated */
11029 * Decode VLLDM and VLSTM first: these are nonstandard because:
11030 * * if there is no FPU then these insns must NOP in
11031 * Secure state and UNDEF in Nonsecure state
11032 * * if there is an FPU then these insns do not have
11033 * the usual behaviour that disas_vfp_insn() provides of
11034 * being controlled by CPACR/NSACR enable bits or the
11035 * lazy-stacking logic.
11037 if (arm_dc_feature(s
, ARM_FEATURE_V8
) &&
11038 (insn
& 0xffa00f00) == 0xec200a00) {
11039 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
11041 * We choose to UNDEF if the RAZ bits are non-zero.
11043 if (!s
->v8m_secure
|| (insn
& 0x0040f0ff)) {
11047 if (arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
11048 TCGv_i32 fptr
= load_reg(s
, rn
);
11050 if (extract32(insn
, 20, 1)) {
11051 gen_helper_v7m_vlldm(cpu_env
, fptr
);
11053 gen_helper_v7m_vlstm(cpu_env
, fptr
);
11055 tcg_temp_free_i32(fptr
);
11057 /* End the TB, because we have updated FP control bits */
11058 s
->base
.is_jmp
= DISAS_UPDATE
;
11062 if (arm_dc_feature(s
, ARM_FEATURE_VFP
) &&
11063 ((insn
>> 8) & 0xe) == 10) {
11064 /* FP, and the CPU supports it */
11065 if (disas_vfp_insn(s
, insn
)) {
11071 /* All other insns: NOCP */
11072 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
11073 default_exception_el(s
));
11076 if ((insn
& 0xfe000a00) == 0xfc000800
11077 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
11078 /* The Thumb2 and ARM encodings are identical. */
11079 if (disas_neon_insn_3same_ext(s
, insn
)) {
11082 } else if ((insn
& 0xff000a00) == 0xfe000800
11083 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
11084 /* The Thumb2 and ARM encodings are identical. */
11085 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
11088 } else if (((insn
>> 24) & 3) == 3) {
11089 /* Translate into the equivalent ARM encoding. */
11090 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
11091 if (disas_neon_data_insn(s
, insn
)) {
11094 } else if (((insn
>> 8) & 0xe) == 10) {
11095 if (disas_vfp_insn(s
, insn
)) {
11099 if (insn
& (1 << 28))
11101 if (disas_coproc_insn(s
, insn
)) {
11106 case 8: case 9: case 10: case 11:
11107 if (insn
& (1 << 15)) {
11108 /* Branches, misc control. */
11109 if (insn
& 0x5000) {
11110 /* Unconditional branch. */
11111 /* signextend(hw1[10:0]) -> offset[:12]. */
11112 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
11113 /* hw1[10:0] -> offset[11:1]. */
11114 offset
|= (insn
& 0x7ff) << 1;
11115 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11116 offset[24:22] already have the same value because of the
11117 sign extension above. */
11118 offset
^= ((~insn
) & (1 << 13)) << 10;
11119 offset
^= ((~insn
) & (1 << 11)) << 11;
11121 if (insn
& (1 << 14)) {
11122 /* Branch and link. */
11123 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
11127 if (insn
& (1 << 12)) {
11129 gen_jmp(s
, offset
);
11132 offset
&= ~(uint32_t)2;
11133 /* thumb2 bx, no need to check */
11134 gen_bx_im(s
, offset
);
11136 } else if (((insn
>> 23) & 7) == 7) {
11138 if (insn
& (1 << 13))
11141 if (insn
& (1 << 26)) {
11142 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11145 if (!(insn
& (1 << 20))) {
11146 /* Hypervisor call (v7) */
11147 int imm16
= extract32(insn
, 16, 4) << 12
11148 | extract32(insn
, 0, 12);
11155 /* Secure monitor call (v6+) */
11163 op
= (insn
>> 20) & 7;
11165 case 0: /* msr cpsr. */
11166 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11167 tmp
= load_reg(s
, rn
);
11168 /* the constant is the mask and SYSm fields */
11169 addr
= tcg_const_i32(insn
& 0xfff);
11170 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11171 tcg_temp_free_i32(addr
);
11172 tcg_temp_free_i32(tmp
);
11177 case 1: /* msr spsr. */
11178 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11182 if (extract32(insn
, 5, 1)) {
11184 int sysm
= extract32(insn
, 8, 4) |
11185 (extract32(insn
, 4, 1) << 4);
11188 gen_msr_banked(s
, r
, sysm
, rm
);
11192 /* MSR (for PSRs) */
11193 tmp
= load_reg(s
, rn
);
11195 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
11199 case 2: /* cps, nop-hint. */
11200 if (((insn
>> 8) & 7) == 0) {
11201 gen_nop_hint(s
, insn
& 0xff);
11203 /* Implemented as NOP in user mode. */
11208 if (insn
& (1 << 10)) {
11209 if (insn
& (1 << 7))
11211 if (insn
& (1 << 6))
11213 if (insn
& (1 << 5))
11215 if (insn
& (1 << 9))
11216 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
11218 if (insn
& (1 << 8)) {
11220 imm
|= (insn
& 0x1f);
11223 gen_set_psr_im(s
, offset
, 0, imm
);
11226 case 3: /* Special control operations. */
11227 if (!arm_dc_feature(s
, ARM_FEATURE_V7
) &&
11228 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11231 op
= (insn
>> 4) & 0xf;
11233 case 2: /* clrex */
11238 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
11241 /* We need to break the TB after this insn
11242 * to execute self-modifying code correctly
11243 * and also to take any pending interrupts
11246 gen_goto_tb(s
, 0, s
->pc
& ~1);
11249 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
11253 * TODO: There is no speculation barrier opcode
11254 * for TCG; MB and end the TB instead.
11256 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
11257 gen_goto_tb(s
, 0, s
->pc
& ~1);
11264 /* Trivial implementation equivalent to bx.
11265 * This instruction doesn't exist at all for M-profile.
11267 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11270 tmp
= load_reg(s
, rn
);
11273 case 5: /* Exception return. */
11277 if (rn
!= 14 || rd
!= 15) {
11280 if (s
->current_el
== 2) {
11281 /* ERET from Hyp uses ELR_Hyp, not LR */
11285 tmp
= load_cpu_field(elr_el
[2]);
11287 tmp
= load_reg(s
, rn
);
11288 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
11290 gen_exception_return(s
, tmp
);
11293 if (extract32(insn
, 5, 1) &&
11294 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11296 int sysm
= extract32(insn
, 16, 4) |
11297 (extract32(insn
, 4, 1) << 4);
11299 gen_mrs_banked(s
, 0, sysm
, rd
);
11303 if (extract32(insn
, 16, 4) != 0xf) {
11306 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
11307 extract32(insn
, 0, 8) != 0) {
11312 tmp
= tcg_temp_new_i32();
11313 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11314 addr
= tcg_const_i32(insn
& 0xff);
11315 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
11316 tcg_temp_free_i32(addr
);
11318 gen_helper_cpsr_read(tmp
, cpu_env
);
11320 store_reg(s
, rd
, tmp
);
11323 if (extract32(insn
, 5, 1) &&
11324 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11326 int sysm
= extract32(insn
, 16, 4) |
11327 (extract32(insn
, 4, 1) << 4);
11329 gen_mrs_banked(s
, 1, sysm
, rd
);
11334 /* Not accessible in user mode. */
11335 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
11339 if (extract32(insn
, 16, 4) != 0xf ||
11340 extract32(insn
, 0, 8) != 0) {
11344 tmp
= load_cpu_field(spsr
);
11345 store_reg(s
, rd
, tmp
);
11350 /* Conditional branch. */
11351 op
= (insn
>> 22) & 0xf;
11352 /* Generate a conditional jump to next instruction. */
11353 arm_skip_unless(s
, op
);
11355 /* offset[11:1] = insn[10:0] */
11356 offset
= (insn
& 0x7ff) << 1;
11357 /* offset[17:12] = insn[21:16]. */
11358 offset
|= (insn
& 0x003f0000) >> 4;
11359 /* offset[31:20] = insn[26]. */
11360 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
11361 /* offset[18] = insn[13]. */
11362 offset
|= (insn
& (1 << 13)) << 5;
11363 /* offset[19] = insn[11]. */
11364 offset
|= (insn
& (1 << 11)) << 8;
11366 /* jump to the offset */
11367 gen_jmp(s
, s
->pc
+ offset
);
11371 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11372 * - Data-processing (modified immediate, plain binary immediate)
11374 if (insn
& (1 << 25)) {
11376 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11377 * - Data-processing (plain binary immediate)
11379 if (insn
& (1 << 24)) {
11380 if (insn
& (1 << 20))
11382 /* Bitfield/Saturate. */
11383 op
= (insn
>> 21) & 7;
11385 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
11387 tmp
= tcg_temp_new_i32();
11388 tcg_gen_movi_i32(tmp
, 0);
11390 tmp
= load_reg(s
, rn
);
11393 case 2: /* Signed bitfield extract. */
11395 if (shift
+ imm
> 32)
11398 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
11401 case 6: /* Unsigned bitfield extract. */
11403 if (shift
+ imm
> 32)
11406 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
11409 case 3: /* Bitfield insert/clear. */
11412 imm
= imm
+ 1 - shift
;
11414 tmp2
= load_reg(s
, rd
);
11415 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
11416 tcg_temp_free_i32(tmp2
);
11421 default: /* Saturate. */
11424 tcg_gen_sari_i32(tmp
, tmp
, shift
);
11426 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11428 tmp2
= tcg_const_i32(imm
);
11431 if ((op
& 1) && shift
== 0) {
11432 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11433 tcg_temp_free_i32(tmp
);
11434 tcg_temp_free_i32(tmp2
);
11437 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
11439 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
11443 if ((op
& 1) && shift
== 0) {
11444 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11445 tcg_temp_free_i32(tmp
);
11446 tcg_temp_free_i32(tmp2
);
11449 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
11451 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
11454 tcg_temp_free_i32(tmp2
);
11457 store_reg(s
, rd
, tmp
);
11459 imm
= ((insn
& 0x04000000) >> 15)
11460 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
11461 if (insn
& (1 << 22)) {
11462 /* 16-bit immediate. */
11463 imm
|= (insn
>> 4) & 0xf000;
11464 if (insn
& (1 << 23)) {
11466 tmp
= load_reg(s
, rd
);
11467 tcg_gen_ext16u_i32(tmp
, tmp
);
11468 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
11471 tmp
= tcg_temp_new_i32();
11472 tcg_gen_movi_i32(tmp
, imm
);
11474 store_reg(s
, rd
, tmp
);
11476 /* Add/sub 12-bit immediate. */
11478 offset
= s
->pc
& ~(uint32_t)3;
11479 if (insn
& (1 << 23))
11483 tmp
= tcg_temp_new_i32();
11484 tcg_gen_movi_i32(tmp
, offset
);
11485 store_reg(s
, rd
, tmp
);
11487 tmp
= load_reg(s
, rn
);
11488 if (insn
& (1 << 23))
11489 tcg_gen_subi_i32(tmp
, tmp
, imm
);
11491 tcg_gen_addi_i32(tmp
, tmp
, imm
);
11492 if (rn
== 13 && rd
== 13) {
11493 /* ADD SP, SP, imm or SUB SP, SP, imm */
11494 store_sp_checked(s
, tmp
);
11496 store_reg(s
, rd
, tmp
);
11503 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11504 * - Data-processing (modified immediate)
11506 int shifter_out
= 0;
11507 /* modified 12-bit immediate. */
11508 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
11509 imm
= (insn
& 0xff);
11512 /* Nothing to do. */
11514 case 1: /* 00XY00XY */
11517 case 2: /* XY00XY00 */
11521 case 3: /* XYXYXYXY */
11525 default: /* Rotated constant. */
11526 shift
= (shift
<< 1) | (imm
>> 7);
11528 imm
= imm
<< (32 - shift
);
11532 tmp2
= tcg_temp_new_i32();
11533 tcg_gen_movi_i32(tmp2
, imm
);
11534 rn
= (insn
>> 16) & 0xf;
11536 tmp
= tcg_temp_new_i32();
11537 tcg_gen_movi_i32(tmp
, 0);
11539 tmp
= load_reg(s
, rn
);
11541 op
= (insn
>> 21) & 0xf;
11542 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
11543 shifter_out
, tmp
, tmp2
))
11545 tcg_temp_free_i32(tmp2
);
11546 rd
= (insn
>> 8) & 0xf;
11547 if (rd
== 13 && rn
== 13
11548 && (op
== 8 || op
== 13)) {
11549 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11550 store_sp_checked(s
, tmp
);
11551 } else if (rd
!= 15) {
11552 store_reg(s
, rd
, tmp
);
11554 tcg_temp_free_i32(tmp
);
11559 case 12: /* Load/store single data item. */
11566 if ((insn
& 0x01100000) == 0x01000000) {
11567 if (disas_neon_ls_insn(s
, insn
)) {
11572 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
11574 if (!(insn
& (1 << 20))) {
11578 /* Byte or halfword load space with dest == r15 : memory hints.
11579 * Catch them early so we don't emit pointless addressing code.
11580 * This space is a mix of:
11581 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11582 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11584 * unallocated hints, which must be treated as NOPs
11585 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11586 * which is easiest for the decoding logic
11587 * Some space which must UNDEF
11589 int op1
= (insn
>> 23) & 3;
11590 int op2
= (insn
>> 6) & 0x3f;
11595 /* UNPREDICTABLE, unallocated hint or
11596 * PLD/PLDW/PLI (literal)
11601 return; /* PLD/PLDW/PLI or unallocated hint */
11603 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
11604 return; /* PLD/PLDW/PLI or unallocated hint */
11606 /* UNDEF space, or an UNPREDICTABLE */
11610 memidx
= get_mem_index(s
);
11612 addr
= tcg_temp_new_i32();
11614 /* s->pc has already been incremented by 4. */
11615 imm
= s
->pc
& 0xfffffffc;
11616 if (insn
& (1 << 23))
11617 imm
+= insn
& 0xfff;
11619 imm
-= insn
& 0xfff;
11620 tcg_gen_movi_i32(addr
, imm
);
11622 addr
= load_reg(s
, rn
);
11623 if (insn
& (1 << 23)) {
11624 /* Positive offset. */
11625 imm
= insn
& 0xfff;
11626 tcg_gen_addi_i32(addr
, addr
, imm
);
11629 switch ((insn
>> 8) & 0xf) {
11630 case 0x0: /* Shifted Register. */
11631 shift
= (insn
>> 4) & 0xf;
11633 tcg_temp_free_i32(addr
);
11636 tmp
= load_reg(s
, rm
);
11638 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11639 tcg_gen_add_i32(addr
, addr
, tmp
);
11640 tcg_temp_free_i32(tmp
);
11642 case 0xc: /* Negative offset. */
11643 tcg_gen_addi_i32(addr
, addr
, -imm
);
11645 case 0xe: /* User privilege. */
11646 tcg_gen_addi_i32(addr
, addr
, imm
);
11647 memidx
= get_a32_user_mem_index(s
);
11649 case 0x9: /* Post-decrement. */
11651 /* Fall through. */
11652 case 0xb: /* Post-increment. */
11656 case 0xd: /* Pre-decrement. */
11658 /* Fall through. */
11659 case 0xf: /* Pre-increment. */
11663 tcg_temp_free_i32(addr
);
11669 issinfo
= writeback
? ISSInvalid
: rs
;
11671 if (s
->v8m_stackcheck
&& rn
== 13 && writeback
) {
11673 * Stackcheck. Here we know 'addr' is the current SP;
11674 * if imm is +ve we're moving SP up, else down. It is
11675 * UNKNOWN whether the limit check triggers when SP starts
11676 * below the limit and ends up above it; we chose to do so.
11678 if ((int32_t)imm
< 0) {
11679 TCGv_i32 newsp
= tcg_temp_new_i32();
11681 tcg_gen_addi_i32(newsp
, addr
, imm
);
11682 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
11683 tcg_temp_free_i32(newsp
);
11685 gen_helper_v8m_stackcheck(cpu_env
, addr
);
11689 if (writeback
&& !postinc
) {
11690 tcg_gen_addi_i32(addr
, addr
, imm
);
11693 if (insn
& (1 << 20)) {
11695 tmp
= tcg_temp_new_i32();
11698 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11701 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11704 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11707 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11710 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11713 tcg_temp_free_i32(tmp
);
11714 tcg_temp_free_i32(addr
);
11718 gen_bx_excret(s
, tmp
);
11720 store_reg(s
, rs
, tmp
);
11724 tmp
= load_reg(s
, rs
);
11727 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
11730 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
11733 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
11736 tcg_temp_free_i32(tmp
);
11737 tcg_temp_free_i32(addr
);
11740 tcg_temp_free_i32(tmp
);
11743 tcg_gen_addi_i32(addr
, addr
, imm
);
11745 store_reg(s
, rn
, addr
);
11747 tcg_temp_free_i32(addr
);
11756 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11757 default_exception_el(s
));
11760 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
11762 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
11769 switch (insn
>> 12) {
11773 op
= (insn
>> 11) & 3;
11776 * 0b0001_1xxx_xxxx_xxxx
11777 * - Add, subtract (three low registers)
11778 * - Add, subtract (two low registers and immediate)
11780 rn
= (insn
>> 3) & 7;
11781 tmp
= load_reg(s
, rn
);
11782 if (insn
& (1 << 10)) {
11784 tmp2
= tcg_temp_new_i32();
11785 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11788 rm
= (insn
>> 6) & 7;
11789 tmp2
= load_reg(s
, rm
);
11791 if (insn
& (1 << 9)) {
11792 if (s
->condexec_mask
)
11793 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11795 gen_sub_CC(tmp
, tmp
, tmp2
);
11797 if (s
->condexec_mask
)
11798 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11800 gen_add_CC(tmp
, tmp
, tmp2
);
11802 tcg_temp_free_i32(tmp2
);
11803 store_reg(s
, rd
, tmp
);
11805 /* shift immediate */
11806 rm
= (insn
>> 3) & 7;
11807 shift
= (insn
>> 6) & 0x1f;
11808 tmp
= load_reg(s
, rm
);
11809 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11810 if (!s
->condexec_mask
)
11812 store_reg(s
, rd
, tmp
);
11817 * 0b001x_xxxx_xxxx_xxxx
11818 * - Add, subtract, compare, move (one low register and immediate)
11820 op
= (insn
>> 11) & 3;
11821 rd
= (insn
>> 8) & 0x7;
11822 if (op
== 0) { /* mov */
11823 tmp
= tcg_temp_new_i32();
11824 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11825 if (!s
->condexec_mask
)
11827 store_reg(s
, rd
, tmp
);
11829 tmp
= load_reg(s
, rd
);
11830 tmp2
= tcg_temp_new_i32();
11831 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11834 gen_sub_CC(tmp
, tmp
, tmp2
);
11835 tcg_temp_free_i32(tmp
);
11836 tcg_temp_free_i32(tmp2
);
11839 if (s
->condexec_mask
)
11840 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11842 gen_add_CC(tmp
, tmp
, tmp2
);
11843 tcg_temp_free_i32(tmp2
);
11844 store_reg(s
, rd
, tmp
);
11847 if (s
->condexec_mask
)
11848 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11850 gen_sub_CC(tmp
, tmp
, tmp2
);
11851 tcg_temp_free_i32(tmp2
);
11852 store_reg(s
, rd
, tmp
);
11858 if (insn
& (1 << 11)) {
11859 rd
= (insn
>> 8) & 7;
11860 /* load pc-relative. Bit 1 of PC is ignored. */
11861 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11862 val
&= ~(uint32_t)2;
11863 addr
= tcg_temp_new_i32();
11864 tcg_gen_movi_i32(addr
, val
);
11865 tmp
= tcg_temp_new_i32();
11866 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11868 tcg_temp_free_i32(addr
);
11869 store_reg(s
, rd
, tmp
);
11872 if (insn
& (1 << 10)) {
11873 /* 0b0100_01xx_xxxx_xxxx
11874 * - data processing extended, branch and exchange
11876 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11877 rm
= (insn
>> 3) & 0xf;
11878 op
= (insn
>> 8) & 3;
11881 tmp
= load_reg(s
, rd
);
11882 tmp2
= load_reg(s
, rm
);
11883 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11884 tcg_temp_free_i32(tmp2
);
11886 /* ADD SP, SP, reg */
11887 store_sp_checked(s
, tmp
);
11889 store_reg(s
, rd
, tmp
);
11893 tmp
= load_reg(s
, rd
);
11894 tmp2
= load_reg(s
, rm
);
11895 gen_sub_CC(tmp
, tmp
, tmp2
);
11896 tcg_temp_free_i32(tmp2
);
11897 tcg_temp_free_i32(tmp
);
11899 case 2: /* mov/cpy */
11900 tmp
= load_reg(s
, rm
);
11903 store_sp_checked(s
, tmp
);
11905 store_reg(s
, rd
, tmp
);
11910 /* 0b0100_0111_xxxx_xxxx
11911 * - branch [and link] exchange thumb register
11913 bool link
= insn
& (1 << 7);
11922 /* BXNS/BLXNS: only exists for v8M with the
11923 * security extensions, and always UNDEF if NonSecure.
11924 * We don't implement these in the user-only mode
11925 * either (in theory you can use them from Secure User
11926 * mode but they are too tied in to system emulation.)
11928 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
11939 tmp
= load_reg(s
, rm
);
11941 val
= (uint32_t)s
->pc
| 1;
11942 tmp2
= tcg_temp_new_i32();
11943 tcg_gen_movi_i32(tmp2
, val
);
11944 store_reg(s
, 14, tmp2
);
11947 /* Only BX works as exception-return, not BLX */
11948 gen_bx_excret(s
, tmp
);
11957 * 0b0100_00xx_xxxx_xxxx
11958 * - Data-processing (two low registers)
11961 rm
= (insn
>> 3) & 7;
11962 op
= (insn
>> 6) & 0xf;
11963 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11964 /* the shift/rotate ops want the operands backwards */
11973 if (op
== 9) { /* neg */
11974 tmp
= tcg_temp_new_i32();
11975 tcg_gen_movi_i32(tmp
, 0);
11976 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11977 tmp
= load_reg(s
, rd
);
11982 tmp2
= load_reg(s
, rm
);
11984 case 0x0: /* and */
11985 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11986 if (!s
->condexec_mask
)
11989 case 0x1: /* eor */
11990 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11991 if (!s
->condexec_mask
)
11994 case 0x2: /* lsl */
11995 if (s
->condexec_mask
) {
11996 gen_shl(tmp2
, tmp2
, tmp
);
11998 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11999 gen_logic_CC(tmp2
);
12002 case 0x3: /* lsr */
12003 if (s
->condexec_mask
) {
12004 gen_shr(tmp2
, tmp2
, tmp
);
12006 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
12007 gen_logic_CC(tmp2
);
12010 case 0x4: /* asr */
12011 if (s
->condexec_mask
) {
12012 gen_sar(tmp2
, tmp2
, tmp
);
12014 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
12015 gen_logic_CC(tmp2
);
12018 case 0x5: /* adc */
12019 if (s
->condexec_mask
) {
12020 gen_adc(tmp
, tmp2
);
12022 gen_adc_CC(tmp
, tmp
, tmp2
);
12025 case 0x6: /* sbc */
12026 if (s
->condexec_mask
) {
12027 gen_sub_carry(tmp
, tmp
, tmp2
);
12029 gen_sbc_CC(tmp
, tmp
, tmp2
);
12032 case 0x7: /* ror */
12033 if (s
->condexec_mask
) {
12034 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
12035 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
12037 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
12038 gen_logic_CC(tmp2
);
12041 case 0x8: /* tst */
12042 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
12046 case 0x9: /* neg */
12047 if (s
->condexec_mask
)
12048 tcg_gen_neg_i32(tmp
, tmp2
);
12050 gen_sub_CC(tmp
, tmp
, tmp2
);
12052 case 0xa: /* cmp */
12053 gen_sub_CC(tmp
, tmp
, tmp2
);
12056 case 0xb: /* cmn */
12057 gen_add_CC(tmp
, tmp
, tmp2
);
12060 case 0xc: /* orr */
12061 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
12062 if (!s
->condexec_mask
)
12065 case 0xd: /* mul */
12066 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
12067 if (!s
->condexec_mask
)
12070 case 0xe: /* bic */
12071 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
12072 if (!s
->condexec_mask
)
12075 case 0xf: /* mvn */
12076 tcg_gen_not_i32(tmp2
, tmp2
);
12077 if (!s
->condexec_mask
)
12078 gen_logic_CC(tmp2
);
12085 store_reg(s
, rm
, tmp2
);
12087 tcg_temp_free_i32(tmp
);
12089 store_reg(s
, rd
, tmp
);
12090 tcg_temp_free_i32(tmp2
);
12093 tcg_temp_free_i32(tmp
);
12094 tcg_temp_free_i32(tmp2
);
12099 /* load/store register offset. */
12101 rn
= (insn
>> 3) & 7;
12102 rm
= (insn
>> 6) & 7;
12103 op
= (insn
>> 9) & 7;
12104 addr
= load_reg(s
, rn
);
12105 tmp
= load_reg(s
, rm
);
12106 tcg_gen_add_i32(addr
, addr
, tmp
);
12107 tcg_temp_free_i32(tmp
);
12109 if (op
< 3) { /* store */
12110 tmp
= load_reg(s
, rd
);
12112 tmp
= tcg_temp_new_i32();
12117 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12120 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12123 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12125 case 3: /* ldrsb */
12126 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12129 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12132 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12135 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12137 case 7: /* ldrsh */
12138 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12141 if (op
>= 3) { /* load */
12142 store_reg(s
, rd
, tmp
);
12144 tcg_temp_free_i32(tmp
);
12146 tcg_temp_free_i32(addr
);
12150 /* load/store word immediate offset */
12152 rn
= (insn
>> 3) & 7;
12153 addr
= load_reg(s
, rn
);
12154 val
= (insn
>> 4) & 0x7c;
12155 tcg_gen_addi_i32(addr
, addr
, val
);
12157 if (insn
& (1 << 11)) {
12159 tmp
= tcg_temp_new_i32();
12160 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12161 store_reg(s
, rd
, tmp
);
12164 tmp
= load_reg(s
, rd
);
12165 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12166 tcg_temp_free_i32(tmp
);
12168 tcg_temp_free_i32(addr
);
12172 /* load/store byte immediate offset */
12174 rn
= (insn
>> 3) & 7;
12175 addr
= load_reg(s
, rn
);
12176 val
= (insn
>> 6) & 0x1f;
12177 tcg_gen_addi_i32(addr
, addr
, val
);
12179 if (insn
& (1 << 11)) {
12181 tmp
= tcg_temp_new_i32();
12182 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12183 store_reg(s
, rd
, tmp
);
12186 tmp
= load_reg(s
, rd
);
12187 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12188 tcg_temp_free_i32(tmp
);
12190 tcg_temp_free_i32(addr
);
12194 /* load/store halfword immediate offset */
12196 rn
= (insn
>> 3) & 7;
12197 addr
= load_reg(s
, rn
);
12198 val
= (insn
>> 5) & 0x3e;
12199 tcg_gen_addi_i32(addr
, addr
, val
);
12201 if (insn
& (1 << 11)) {
12203 tmp
= tcg_temp_new_i32();
12204 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12205 store_reg(s
, rd
, tmp
);
12208 tmp
= load_reg(s
, rd
);
12209 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12210 tcg_temp_free_i32(tmp
);
12212 tcg_temp_free_i32(addr
);
12216 /* load/store from stack */
12217 rd
= (insn
>> 8) & 7;
12218 addr
= load_reg(s
, 13);
12219 val
= (insn
& 0xff) * 4;
12220 tcg_gen_addi_i32(addr
, addr
, val
);
12222 if (insn
& (1 << 11)) {
12224 tmp
= tcg_temp_new_i32();
12225 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12226 store_reg(s
, rd
, tmp
);
12229 tmp
= load_reg(s
, rd
);
12230 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12231 tcg_temp_free_i32(tmp
);
12233 tcg_temp_free_i32(addr
);
12238 * 0b1010_xxxx_xxxx_xxxx
12239 * - Add PC/SP (immediate)
12241 rd
= (insn
>> 8) & 7;
12242 if (insn
& (1 << 11)) {
12244 tmp
= load_reg(s
, 13);
12246 /* PC. bit 1 is ignored. */
12247 tmp
= tcg_temp_new_i32();
12248 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
12250 val
= (insn
& 0xff) * 4;
12251 tcg_gen_addi_i32(tmp
, tmp
, val
);
12252 store_reg(s
, rd
, tmp
);
12257 op
= (insn
>> 8) & 0xf;
12261 * 0b1011_0000_xxxx_xxxx
12262 * - ADD (SP plus immediate)
12263 * - SUB (SP minus immediate)
12265 tmp
= load_reg(s
, 13);
12266 val
= (insn
& 0x7f) * 4;
12267 if (insn
& (1 << 7))
12268 val
= -(int32_t)val
;
12269 tcg_gen_addi_i32(tmp
, tmp
, val
);
12270 store_sp_checked(s
, tmp
);
12273 case 2: /* sign/zero extend. */
12276 rm
= (insn
>> 3) & 7;
12277 tmp
= load_reg(s
, rm
);
12278 switch ((insn
>> 6) & 3) {
12279 case 0: gen_sxth(tmp
); break;
12280 case 1: gen_sxtb(tmp
); break;
12281 case 2: gen_uxth(tmp
); break;
12282 case 3: gen_uxtb(tmp
); break;
12284 store_reg(s
, rd
, tmp
);
12286 case 4: case 5: case 0xc: case 0xd:
12288 * 0b1011_x10x_xxxx_xxxx
12291 addr
= load_reg(s
, 13);
12292 if (insn
& (1 << 8))
12296 for (i
= 0; i
< 8; i
++) {
12297 if (insn
& (1 << i
))
12300 if ((insn
& (1 << 11)) == 0) {
12301 tcg_gen_addi_i32(addr
, addr
, -offset
);
12304 if (s
->v8m_stackcheck
) {
12306 * Here 'addr' is the lower of "old SP" and "new SP";
12307 * if this is a pop that starts below the limit and ends
12308 * above it, it is UNKNOWN whether the limit check triggers;
12309 * we choose to trigger.
12311 gen_helper_v8m_stackcheck(cpu_env
, addr
);
12314 for (i
= 0; i
< 8; i
++) {
12315 if (insn
& (1 << i
)) {
12316 if (insn
& (1 << 11)) {
12318 tmp
= tcg_temp_new_i32();
12319 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12320 store_reg(s
, i
, tmp
);
12323 tmp
= load_reg(s
, i
);
12324 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12325 tcg_temp_free_i32(tmp
);
12327 /* advance to the next address. */
12328 tcg_gen_addi_i32(addr
, addr
, 4);
12332 if (insn
& (1 << 8)) {
12333 if (insn
& (1 << 11)) {
12335 tmp
= tcg_temp_new_i32();
12336 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12337 /* don't set the pc until the rest of the instruction
12341 tmp
= load_reg(s
, 14);
12342 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12343 tcg_temp_free_i32(tmp
);
12345 tcg_gen_addi_i32(addr
, addr
, 4);
12347 if ((insn
& (1 << 11)) == 0) {
12348 tcg_gen_addi_i32(addr
, addr
, -offset
);
12350 /* write back the new stack pointer */
12351 store_reg(s
, 13, addr
);
12352 /* set the new PC value */
12353 if ((insn
& 0x0900) == 0x0900) {
12354 store_reg_from_load(s
, 15, tmp
);
12358 case 1: case 3: case 9: case 11: /* czb */
12360 tmp
= load_reg(s
, rm
);
12361 arm_gen_condlabel(s
);
12362 if (insn
& (1 << 11))
12363 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
12365 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
12366 tcg_temp_free_i32(tmp
);
12367 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
12368 val
= (uint32_t)s
->pc
+ 2;
12373 case 15: /* IT, nop-hint. */
12374 if ((insn
& 0xf) == 0) {
12375 gen_nop_hint(s
, (insn
>> 4) & 0xf);
12379 s
->condexec_cond
= (insn
>> 4) & 0xe;
12380 s
->condexec_mask
= insn
& 0x1f;
12381 /* No actual code generated for this insn, just setup state. */
12384 case 0xe: /* bkpt */
12386 int imm8
= extract32(insn
, 0, 8);
12388 gen_exception_bkpt_insn(s
, 2, syn_aa32_bkpt(imm8
, true));
12392 case 0xa: /* rev, and hlt */
12394 int op1
= extract32(insn
, 6, 2);
12398 int imm6
= extract32(insn
, 0, 6);
12404 /* Otherwise this is rev */
12406 rn
= (insn
>> 3) & 0x7;
12408 tmp
= load_reg(s
, rn
);
12410 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
12411 case 1: gen_rev16(tmp
); break;
12412 case 3: gen_revsh(tmp
); break;
12414 g_assert_not_reached();
12416 store_reg(s
, rd
, tmp
);
12421 switch ((insn
>> 5) & 7) {
12425 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
12426 gen_helper_setend(cpu_env
);
12427 s
->base
.is_jmp
= DISAS_UPDATE
;
12436 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
12437 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
12440 addr
= tcg_const_i32(19);
12441 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12442 tcg_temp_free_i32(addr
);
12446 addr
= tcg_const_i32(16);
12447 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12448 tcg_temp_free_i32(addr
);
12450 tcg_temp_free_i32(tmp
);
12453 if (insn
& (1 << 4)) {
12454 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
12458 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
12473 /* load/store multiple */
12474 TCGv_i32 loaded_var
= NULL
;
12475 rn
= (insn
>> 8) & 0x7;
12476 addr
= load_reg(s
, rn
);
12477 for (i
= 0; i
< 8; i
++) {
12478 if (insn
& (1 << i
)) {
12479 if (insn
& (1 << 11)) {
12481 tmp
= tcg_temp_new_i32();
12482 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12486 store_reg(s
, i
, tmp
);
12490 tmp
= load_reg(s
, i
);
12491 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12492 tcg_temp_free_i32(tmp
);
12494 /* advance to the next address */
12495 tcg_gen_addi_i32(addr
, addr
, 4);
12498 if ((insn
& (1 << rn
)) == 0) {
12499 /* base reg not in list: base register writeback */
12500 store_reg(s
, rn
, addr
);
12502 /* base reg in list: if load, complete it now */
12503 if (insn
& (1 << 11)) {
12504 store_reg(s
, rn
, loaded_var
);
12506 tcg_temp_free_i32(addr
);
12511 /* conditional branch or swi */
12512 cond
= (insn
>> 8) & 0xf;
12518 gen_set_pc_im(s
, s
->pc
);
12519 s
->svc_imm
= extract32(insn
, 0, 8);
12520 s
->base
.is_jmp
= DISAS_SWI
;
12523 /* generate a conditional jump to next instruction */
12524 arm_skip_unless(s
, cond
);
12526 /* jump to the offset */
12527 val
= (uint32_t)s
->pc
+ 2;
12528 offset
= ((int32_t)insn
<< 24) >> 24;
12529 val
+= offset
<< 1;
12534 if (insn
& (1 << 11)) {
12535 /* thumb_insn_is_16bit() ensures we can't get here for
12536 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12537 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12539 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12541 offset
= ((insn
& 0x7ff) << 1);
12542 tmp
= load_reg(s
, 14);
12543 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12544 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
12546 tmp2
= tcg_temp_new_i32();
12547 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12548 store_reg(s
, 14, tmp2
);
12552 /* unconditional branch */
12553 val
= (uint32_t)s
->pc
;
12554 offset
= ((int32_t)insn
<< 21) >> 21;
12555 val
+= (offset
<< 1) + 2;
12560 /* thumb_insn_is_16bit() ensures we can't get here for
12561 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12563 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12565 if (insn
& (1 << 11)) {
12566 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12567 offset
= ((insn
& 0x7ff) << 1) | 1;
12568 tmp
= load_reg(s
, 14);
12569 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12571 tmp2
= tcg_temp_new_i32();
12572 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12573 store_reg(s
, 14, tmp2
);
12576 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12577 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
12579 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
12586 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
12587 default_exception_el(s
));
12590 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
12592 /* Return true if the insn at dc->pc might cross a page boundary.
12593 * (False positives are OK, false negatives are not.)
12594 * We know this is a Thumb insn, and our caller ensures we are
12595 * only called if dc->pc is less than 4 bytes from the page
12596 * boundary, so we cross the page if the first 16 bits indicate
12597 * that this is a 32 bit insn.
12599 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
12601 return !thumb_insn_is_16bit(s
, insn
);
12604 static void arm_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
12606 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12607 CPUARMState
*env
= cs
->env_ptr
;
12608 ARMCPU
*cpu
= env_archcpu(env
);
12609 uint32_t tb_flags
= dc
->base
.tb
->flags
;
12610 uint32_t condexec
, core_mmu_idx
;
12612 dc
->isar
= &cpu
->isar
;
12613 dc
->pc
= dc
->base
.pc_first
;
12617 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12618 * there is no secure EL1, so we route exceptions to EL3.
12620 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
12621 !arm_el_is_aa64(env
, 3);
12622 dc
->thumb
= FIELD_EX32(tb_flags
, TBFLAG_A32
, THUMB
);
12623 dc
->sctlr_b
= FIELD_EX32(tb_flags
, TBFLAG_A32
, SCTLR_B
);
12624 dc
->be_data
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, BE_DATA
) ? MO_BE
: MO_LE
;
12625 condexec
= FIELD_EX32(tb_flags
, TBFLAG_A32
, CONDEXEC
);
12626 dc
->condexec_mask
= (condexec
& 0xf) << 1;
12627 dc
->condexec_cond
= condexec
>> 4;
12628 core_mmu_idx
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, MMUIDX
);
12629 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, core_mmu_idx
);
12630 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
12631 #if !defined(CONFIG_USER_ONLY)
12632 dc
->user
= (dc
->current_el
== 0);
12634 dc
->ns
= FIELD_EX32(tb_flags
, TBFLAG_A32
, NS
);
12635 dc
->fp_excp_el
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, FPEXC_EL
);
12636 dc
->vfp_enabled
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VFPEN
);
12637 dc
->vec_len
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECLEN
);
12638 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
12639 dc
->c15_cpar
= FIELD_EX32(tb_flags
, TBFLAG_A32
, XSCALE_CPAR
);
12640 dc
->vec_stride
= 0;
12642 dc
->vec_stride
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECSTRIDE
);
12645 dc
->v7m_handler_mode
= FIELD_EX32(tb_flags
, TBFLAG_A32
, HANDLER
);
12646 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
12647 regime_is_secure(env
, dc
->mmu_idx
);
12648 dc
->v8m_stackcheck
= FIELD_EX32(tb_flags
, TBFLAG_A32
, STACKCHECK
);
12649 dc
->v8m_fpccr_s_wrong
= FIELD_EX32(tb_flags
, TBFLAG_A32
, FPCCR_S_WRONG
);
12650 dc
->v7m_new_fp_ctxt_needed
=
12651 FIELD_EX32(tb_flags
, TBFLAG_A32
, NEW_FP_CTXT_NEEDED
);
12652 dc
->v7m_lspact
= FIELD_EX32(tb_flags
, TBFLAG_A32
, LSPACT
);
12653 dc
->cp_regs
= cpu
->cp_regs
;
12654 dc
->features
= env
->features
;
12656 /* Single step state. The code-generation logic here is:
12658 * generate code with no special handling for single-stepping (except
12659 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12660 * this happens anyway because those changes are all system register or
12662 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12663 * emit code for one insn
12664 * emit code to clear PSTATE.SS
12665 * emit code to generate software step exception for completed step
12666 * end TB (as usual for having generated an exception)
12667 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12668 * emit code to generate a software step exception
12671 dc
->ss_active
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, SS_ACTIVE
);
12672 dc
->pstate_ss
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, PSTATE_SS
);
12673 dc
->is_ldex
= false;
12674 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
12676 dc
->page_start
= dc
->base
.pc_first
& TARGET_PAGE_MASK
;
12678 /* If architectural single step active, limit to 1. */
12679 if (is_singlestepping(dc
)) {
12680 dc
->base
.max_insns
= 1;
12683 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12684 to those left on the page. */
12686 int bound
= -(dc
->base
.pc_first
| TARGET_PAGE_MASK
) / 4;
12687 dc
->base
.max_insns
= MIN(dc
->base
.max_insns
, bound
);
12690 cpu_F0s
= tcg_temp_new_i32();
12691 cpu_F1s
= tcg_temp_new_i32();
12692 cpu_F0d
= tcg_temp_new_i64();
12693 cpu_F1d
= tcg_temp_new_i64();
12696 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12697 cpu_M0
= tcg_temp_new_i64();
12700 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12702 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12704 /* A note on handling of the condexec (IT) bits:
12706 * We want to avoid the overhead of having to write the updated condexec
12707 * bits back to the CPUARMState for every instruction in an IT block. So:
12708 * (1) if the condexec bits are not already zero then we write
12709 * zero back into the CPUARMState now. This avoids complications trying
12710 * to do it at the end of the block. (For example if we don't do this
12711 * it's hard to identify whether we can safely skip writing condexec
12712 * at the end of the TB, which we definitely want to do for the case
12713 * where a TB doesn't do anything with the IT state at all.)
12714 * (2) if we are going to leave the TB then we call gen_set_condexec()
12715 * which will write the correct value into CPUARMState if zero is wrong.
12716 * This is done both for leaving the TB at the end, and for leaving
12717 * it because of an exception we know will happen, which is done in
12718 * gen_exception_insn(). The latter is necessary because we need to
12719 * leave the TB with the PC/IT state just prior to execution of the
12720 * instruction which caused the exception.
12721 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12722 * then the CPUARMState will be wrong and we need to reset it.
12723 * This is handled in the same way as restoration of the
12724 * PC in these situations; we save the value of the condexec bits
12725 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12726 * then uses this to restore them after an exception.
12728 * Note that there are no instructions which can read the condexec
12729 * bits, and none which can write non-static values to them, so
12730 * we don't need to care about whether CPUARMState is correct in the
12734 /* Reset the conditional execution bits immediately. This avoids
12735 complications trying to do it at the end of the block. */
12736 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
12737 TCGv_i32 tmp
= tcg_temp_new_i32();
12738 tcg_gen_movi_i32(tmp
, 0);
12739 store_cpu_field(tmp
, condexec_bits
);
12743 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12745 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12747 tcg_gen_insn_start(dc
->pc
,
12748 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
12750 dc
->insn_start
= tcg_last_op();
12753 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
12754 const CPUBreakpoint
*bp
)
12756 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12758 if (bp
->flags
& BP_CPU
) {
12759 gen_set_condexec(dc
);
12760 gen_set_pc_im(dc
, dc
->pc
);
12761 gen_helper_check_breakpoints(cpu_env
);
12762 /* End the TB early; it's likely not going to be executed */
12763 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12765 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
12766 /* The address covered by the breakpoint must be
12767 included in [tb->pc, tb->pc + tb->size) in order
12768 to for it to be properly cleared -- thus we
12769 increment the PC here so that the logic setting
12770 tb->size below does the right thing. */
12771 /* TODO: Advance PC by correct instruction length to
12772 * avoid disassembler error messages */
12774 dc
->base
.is_jmp
= DISAS_NORETURN
;
12780 static bool arm_pre_translate_insn(DisasContext
*dc
)
12782 #ifdef CONFIG_USER_ONLY
12783 /* Intercept jump to the magic kernel page. */
12784 if (dc
->pc
>= 0xffff0000) {
12785 /* We always get here via a jump, so know we are not in a
12786 conditional execution block. */
12787 gen_exception_internal(EXCP_KERNEL_TRAP
);
12788 dc
->base
.is_jmp
= DISAS_NORETURN
;
12793 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12794 /* Singlestep state is Active-pending.
12795 * If we're in this state at the start of a TB then either
12796 * a) we just took an exception to an EL which is being debugged
12797 * and this is the first insn in the exception handler
12798 * b) debug exceptions were masked and we just unmasked them
12799 * without changing EL (eg by clearing PSTATE.D)
12800 * In either case we're going to take a swstep exception in the
12801 * "did not step an insn" case, and so the syndrome ISV and EX
12802 * bits should be zero.
12804 assert(dc
->base
.num_insns
== 1);
12805 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
12806 default_exception_el(dc
));
12807 dc
->base
.is_jmp
= DISAS_NORETURN
;
12814 static void arm_post_translate_insn(DisasContext
*dc
)
12816 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12817 gen_set_label(dc
->condlabel
);
12820 dc
->base
.pc_next
= dc
->pc
;
12821 translator_loop_temp_check(&dc
->base
);
12824 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12826 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12827 CPUARMState
*env
= cpu
->env_ptr
;
12830 if (arm_pre_translate_insn(dc
)) {
12834 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12837 disas_arm_insn(dc
, insn
);
12839 arm_post_translate_insn(dc
);
12841 /* ARM is a fixed-length ISA. We performed the cross-page check
12842 in init_disas_context by adjusting max_insns. */
12845 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
12847 /* Return true if this Thumb insn is always unconditional,
12848 * even inside an IT block. This is true of only a very few
12849 * instructions: BKPT, HLT, and SG.
12851 * A larger class of instructions are UNPREDICTABLE if used
12852 * inside an IT block; we do not need to detect those here, because
12853 * what we do by default (perform the cc check and update the IT
12854 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12855 * choice for those situations.
12857 * insn is either a 16-bit or a 32-bit instruction; the two are
12858 * distinguishable because for the 16-bit case the top 16 bits
12859 * are zeroes, and that isn't a valid 32-bit encoding.
12861 if ((insn
& 0xffffff00) == 0xbe00) {
12866 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12867 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
12868 /* HLT: v8A only. This is unconditional even when it is going to
12869 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12870 * For v7 cores this was a plain old undefined encoding and so
12871 * honours its cc check. (We might be using the encoding as
12872 * a semihosting trap, but we don't change the cc check behaviour
12873 * on that account, because a debugger connected to a real v7A
12874 * core and emulating semihosting traps by catching the UNDEF
12875 * exception would also only see cases where the cc check passed.
12876 * No guest code should be trying to do a HLT semihosting trap
12877 * in an IT block anyway.
12882 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12883 arm_dc_feature(s
, ARM_FEATURE_M
)) {
12891 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12893 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12894 CPUARMState
*env
= cpu
->env_ptr
;
12898 if (arm_pre_translate_insn(dc
)) {
12902 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12903 is_16bit
= thumb_insn_is_16bit(dc
, insn
);
12906 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12908 insn
= insn
<< 16 | insn2
;
12913 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
12914 uint32_t cond
= dc
->condexec_cond
;
12916 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
12917 arm_skip_unless(dc
, cond
);
12922 disas_thumb_insn(dc
, insn
);
12924 disas_thumb2_insn(dc
, insn
);
12927 /* Advance the Thumb condexec condition. */
12928 if (dc
->condexec_mask
) {
12929 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
12930 ((dc
->condexec_mask
>> 4) & 1));
12931 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12932 if (dc
->condexec_mask
== 0) {
12933 dc
->condexec_cond
= 0;
12937 arm_post_translate_insn(dc
);
12939 /* Thumb is a variable-length ISA. Stop translation when the next insn
12940 * will touch a new page. This ensures that prefetch aborts occur at
12943 * We want to stop the TB if the next insn starts in a new page,
12944 * or if it spans between this page and the next. This means that
12945 * if we're looking at the last halfword in the page we need to
12946 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12947 * or a 32-bit Thumb insn (which won't).
12948 * This is to avoid generating a silly TB with a single 16-bit insn
12949 * in it at the end of this page (which would execute correctly
12950 * but isn't very efficient).
12952 if (dc
->base
.is_jmp
== DISAS_NEXT
12953 && (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
12954 || (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
- 3
12955 && insn_crosses_page(env
, dc
)))) {
12956 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12960 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
12962 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12964 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
12965 /* FIXME: This can theoretically happen with self-modifying code. */
12966 cpu_abort(cpu
, "IO on conditional branch instruction");
12969 /* At this stage dc->condjmp will only be set when the skipped
12970 instruction was a conditional branch or trap, and the PC has
12971 already been written. */
12972 gen_set_condexec(dc
);
12973 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12974 /* Exception return branches need some special case code at the
12975 * end of the TB, which is complex enough that it has to
12976 * handle the single-step vs not and the condition-failed
12977 * insn codepath itself.
12979 gen_bx_excret_final_code(dc
);
12980 } else if (unlikely(is_singlestepping(dc
))) {
12981 /* Unconditional and "condition passed" instruction codepath. */
12982 switch (dc
->base
.is_jmp
) {
12984 gen_ss_advance(dc
);
12985 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12986 default_exception_el(dc
));
12989 gen_ss_advance(dc
);
12990 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12993 gen_ss_advance(dc
);
12994 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12997 case DISAS_TOO_MANY
:
12999 gen_set_pc_im(dc
, dc
->pc
);
13002 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
13003 gen_singlestep_exception(dc
);
13005 case DISAS_NORETURN
:
13009 /* While branches must always occur at the end of an IT block,
13010 there are a few other things that can cause us to terminate
13011 the TB in the middle of an IT block:
13012 - Exception generating instructions (bkpt, swi, undefined).
13014 - Hardware watchpoints.
13015 Hardware breakpoints have already been handled and skip this code.
13017 switch(dc
->base
.is_jmp
) {
13019 case DISAS_TOO_MANY
:
13020 gen_goto_tb(dc
, 1, dc
->pc
);
13026 gen_set_pc_im(dc
, dc
->pc
);
13029 /* indicate that the hash table must be used to find the next TB */
13030 tcg_gen_exit_tb(NULL
, 0);
13032 case DISAS_NORETURN
:
13033 /* nothing more to generate */
13037 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
13038 !(dc
->insn
& (1U << 31))) ? 2 : 4);
13040 gen_helper_wfi(cpu_env
, tmp
);
13041 tcg_temp_free_i32(tmp
);
13042 /* The helper doesn't necessarily throw an exception, but we
13043 * must go back to the main loop to check for interrupts anyway.
13045 tcg_gen_exit_tb(NULL
, 0);
13049 gen_helper_wfe(cpu_env
);
13052 gen_helper_yield(cpu_env
);
13055 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
13056 default_exception_el(dc
));
13059 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
13062 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
13068 /* "Condition failed" instruction codepath for the branch/trap insn */
13069 gen_set_label(dc
->condlabel
);
13070 gen_set_condexec(dc
);
13071 if (unlikely(is_singlestepping(dc
))) {
13072 gen_set_pc_im(dc
, dc
->pc
);
13073 gen_singlestep_exception(dc
);
13075 gen_goto_tb(dc
, 1, dc
->pc
);
13079 /* Functions above can change dc->pc, so re-align db->pc_next */
13080 dc
->base
.pc_next
= dc
->pc
;
13083 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
13085 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
13087 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
13088 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
13091 static const TranslatorOps arm_translator_ops
= {
13092 .init_disas_context
= arm_tr_init_disas_context
,
13093 .tb_start
= arm_tr_tb_start
,
13094 .insn_start
= arm_tr_insn_start
,
13095 .breakpoint_check
= arm_tr_breakpoint_check
,
13096 .translate_insn
= arm_tr_translate_insn
,
13097 .tb_stop
= arm_tr_tb_stop
,
13098 .disas_log
= arm_tr_disas_log
,
13101 static const TranslatorOps thumb_translator_ops
= {
13102 .init_disas_context
= arm_tr_init_disas_context
,
13103 .tb_start
= arm_tr_tb_start
,
13104 .insn_start
= arm_tr_insn_start
,
13105 .breakpoint_check
= arm_tr_breakpoint_check
,
13106 .translate_insn
= thumb_tr_translate_insn
,
13107 .tb_stop
= arm_tr_tb_stop
,
13108 .disas_log
= arm_tr_disas_log
,
13111 /* generate intermediate code for basic block 'tb'. */
13112 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
13115 const TranslatorOps
*ops
= &arm_translator_ops
;
13117 if (FIELD_EX32(tb
->flags
, TBFLAG_A32
, THUMB
)) {
13118 ops
= &thumb_translator_ops
;
13120 #ifdef TARGET_AARCH64
13121 if (FIELD_EX32(tb
->flags
, TBFLAG_ANY
, AARCH64_STATE
)) {
13122 ops
= &aarch64_translator_ops
;
13126 translator_loop(ops
, &dc
.base
, cpu
, tb
, max_insns
);
13129 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
13131 ARMCPU
*cpu
= ARM_CPU(cs
);
13132 CPUARMState
*env
= &cpu
->env
;
13136 aarch64_cpu_dump_state(cs
, f
, flags
);
13140 for(i
=0;i
<16;i
++) {
13141 qemu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
13143 qemu_fprintf(f
, "\n");
13145 qemu_fprintf(f
, " ");
13148 if (arm_feature(env
, ARM_FEATURE_M
)) {
13149 uint32_t xpsr
= xpsr_read(env
);
13151 const char *ns_status
= "";
13153 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
13154 ns_status
= env
->v7m
.secure
? "S " : "NS ";
13157 if (xpsr
& XPSR_EXCP
) {
13160 if (env
->v7m
.control
[env
->v7m
.secure
] & R_V7M_CONTROL_NPRIV_MASK
) {
13161 mode
= "unpriv-thread";
13163 mode
= "priv-thread";
13167 qemu_fprintf(f
, "XPSR=%08x %c%c%c%c %c %s%s\n",
13169 xpsr
& XPSR_N
? 'N' : '-',
13170 xpsr
& XPSR_Z
? 'Z' : '-',
13171 xpsr
& XPSR_C
? 'C' : '-',
13172 xpsr
& XPSR_V
? 'V' : '-',
13173 xpsr
& XPSR_T
? 'T' : 'A',
13177 uint32_t psr
= cpsr_read(env
);
13178 const char *ns_status
= "";
13180 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
13181 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
13182 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
13185 qemu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13187 psr
& CPSR_N
? 'N' : '-',
13188 psr
& CPSR_Z
? 'Z' : '-',
13189 psr
& CPSR_C
? 'C' : '-',
13190 psr
& CPSR_V
? 'V' : '-',
13191 psr
& CPSR_T
? 'T' : 'A',
13193 aarch32_mode_name(psr
), (psr
& 0x10) ? 32 : 26);
13196 if (flags
& CPU_DUMP_FPU
) {
13197 int numvfpregs
= 0;
13198 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
13201 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
13204 for (i
= 0; i
< numvfpregs
; i
++) {
13205 uint64_t v
= *aa32_vfp_dreg(env
, i
);
13206 qemu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
13207 i
* 2, (uint32_t)v
,
13208 i
* 2 + 1, (uint32_t)(v
>> 32),
13211 qemu_fprintf(f
, "FPSCR: %08x\n", vfp_get_fpscr(env
));
13215 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
13216 target_ulong
*data
)
13220 env
->condexec_bits
= 0;
13221 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
13223 env
->regs
[15] = data
[0];
13224 env
->condexec_bits
= data
[1];
13225 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;