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); \
1394 static inline void gen_vfp_abs(int dp
)
1397 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1399 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1402 static inline void gen_vfp_neg(int dp
)
1405 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1407 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1410 static inline void gen_vfp_sqrt(int dp
)
1413 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1415 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1418 static inline void gen_vfp_cmp(int dp
)
1421 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1423 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1426 static inline void gen_vfp_cmpe(int dp
)
1429 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1431 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1434 static inline void gen_vfp_F1_ld0(int dp
)
1437 tcg_gen_movi_i64(cpu_F1d
, 0);
1439 tcg_gen_movi_i32(cpu_F1s
, 0);
1442 #define VFP_GEN_ITOF(name) \
1443 static inline void gen_vfp_##name(int dp, int neon) \
1445 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1447 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1449 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1451 tcg_temp_free_ptr(statusptr); \
1458 #define VFP_GEN_FTOI(name) \
1459 static inline void gen_vfp_##name(int dp, int neon) \
1461 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1463 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1465 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1467 tcg_temp_free_ptr(statusptr); \
1476 #define VFP_GEN_FIX(name, round) \
1477 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1479 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1480 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1482 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1485 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1488 tcg_temp_free_i32(tmp_shift); \
1489 tcg_temp_free_ptr(statusptr); \
1491 VFP_GEN_FIX(tosh
, _round_to_zero
)
1492 VFP_GEN_FIX(tosl
, _round_to_zero
)
1493 VFP_GEN_FIX(touh
, _round_to_zero
)
1494 VFP_GEN_FIX(toul
, _round_to_zero
)
1501 static inline long vfp_reg_offset(bool dp
, unsigned reg
)
1504 return offsetof(CPUARMState
, vfp
.zregs
[reg
>> 1].d
[reg
& 1]);
1506 long ofs
= offsetof(CPUARMState
, vfp
.zregs
[reg
>> 2].d
[(reg
>> 1) & 1]);
1508 ofs
+= offsetof(CPU_DoubleU
, l
.upper
);
1510 ofs
+= offsetof(CPU_DoubleU
, l
.lower
);
1516 /* Return the offset of a 32-bit piece of a NEON register.
1517 zero is the least significant end of the register. */
1519 neon_reg_offset (int reg
, int n
)
1523 return vfp_reg_offset(0, sreg
);
1526 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1527 * where 0 is the least significant end of the register.
1530 neon_element_offset(int reg
, int element
, TCGMemOp size
)
1532 int element_size
= 1 << size
;
1533 int ofs
= element
* element_size
;
1534 #ifdef HOST_WORDS_BIGENDIAN
1535 /* Calculate the offset assuming fully little-endian,
1536 * then XOR to account for the order of the 8-byte units.
1538 if (element_size
< 8) {
1539 ofs
^= 8 - element_size
;
1542 return neon_reg_offset(reg
, 0) + ofs
;
1545 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1547 TCGv_i32 tmp
= tcg_temp_new_i32();
1548 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1552 static void neon_load_element(TCGv_i32 var
, int reg
, int ele
, TCGMemOp mop
)
1554 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1558 tcg_gen_ld8u_i32(var
, cpu_env
, offset
);
1561 tcg_gen_ld16u_i32(var
, cpu_env
, offset
);
1564 tcg_gen_ld_i32(var
, cpu_env
, offset
);
1567 g_assert_not_reached();
1571 static void neon_load_element64(TCGv_i64 var
, int reg
, int ele
, TCGMemOp mop
)
1573 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1577 tcg_gen_ld8u_i64(var
, cpu_env
, offset
);
1580 tcg_gen_ld16u_i64(var
, cpu_env
, offset
);
1583 tcg_gen_ld32u_i64(var
, cpu_env
, offset
);
1586 tcg_gen_ld_i64(var
, cpu_env
, offset
);
1589 g_assert_not_reached();
1593 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1595 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1596 tcg_temp_free_i32(var
);
1599 static void neon_store_element(int reg
, int ele
, TCGMemOp size
, TCGv_i32 var
)
1601 long offset
= neon_element_offset(reg
, ele
, size
);
1605 tcg_gen_st8_i32(var
, cpu_env
, offset
);
1608 tcg_gen_st16_i32(var
, cpu_env
, offset
);
1611 tcg_gen_st_i32(var
, cpu_env
, offset
);
1614 g_assert_not_reached();
1618 static void neon_store_element64(int reg
, int ele
, TCGMemOp size
, TCGv_i64 var
)
1620 long offset
= neon_element_offset(reg
, ele
, size
);
1624 tcg_gen_st8_i64(var
, cpu_env
, offset
);
1627 tcg_gen_st16_i64(var
, cpu_env
, offset
);
1630 tcg_gen_st32_i64(var
, cpu_env
, offset
);
1633 tcg_gen_st_i64(var
, cpu_env
, offset
);
1636 g_assert_not_reached();
1640 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1642 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1645 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1647 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1650 static inline void neon_load_reg32(TCGv_i32 var
, int reg
)
1652 tcg_gen_ld_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1655 static inline void neon_store_reg32(TCGv_i32 var
, int reg
)
1657 tcg_gen_st_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1660 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1662 TCGv_ptr ret
= tcg_temp_new_ptr();
1663 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1667 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1668 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1669 #define tcg_gen_st_f32 tcg_gen_st_i32
1670 #define tcg_gen_st_f64 tcg_gen_st_i64
1672 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1675 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1677 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1680 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1683 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1685 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1688 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1691 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1693 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1696 #define ARM_CP_RW_BIT (1 << 20)
1698 /* Include the VFP decoder */
1699 #include "translate-vfp.inc.c"
1701 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1703 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1706 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1708 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1711 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1713 TCGv_i32 var
= tcg_temp_new_i32();
1714 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1718 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1720 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1721 tcg_temp_free_i32(var
);
1724 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1726 iwmmxt_store_reg(cpu_M0
, rn
);
1729 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1731 iwmmxt_load_reg(cpu_M0
, rn
);
1734 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1736 iwmmxt_load_reg(cpu_V1
, rn
);
1737 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1740 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1742 iwmmxt_load_reg(cpu_V1
, rn
);
1743 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1746 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1748 iwmmxt_load_reg(cpu_V1
, rn
);
1749 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1752 #define IWMMXT_OP(name) \
1753 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1755 iwmmxt_load_reg(cpu_V1, rn); \
1756 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1759 #define IWMMXT_OP_ENV(name) \
1760 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1762 iwmmxt_load_reg(cpu_V1, rn); \
1763 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1766 #define IWMMXT_OP_ENV_SIZE(name) \
1767 IWMMXT_OP_ENV(name##b) \
1768 IWMMXT_OP_ENV(name##w) \
1769 IWMMXT_OP_ENV(name##l)
1771 #define IWMMXT_OP_ENV1(name) \
1772 static inline void gen_op_iwmmxt_##name##_M0(void) \
1774 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1788 IWMMXT_OP_ENV_SIZE(unpackl
)
1789 IWMMXT_OP_ENV_SIZE(unpackh
)
1791 IWMMXT_OP_ENV1(unpacklub
)
1792 IWMMXT_OP_ENV1(unpackluw
)
1793 IWMMXT_OP_ENV1(unpacklul
)
1794 IWMMXT_OP_ENV1(unpackhub
)
1795 IWMMXT_OP_ENV1(unpackhuw
)
1796 IWMMXT_OP_ENV1(unpackhul
)
1797 IWMMXT_OP_ENV1(unpacklsb
)
1798 IWMMXT_OP_ENV1(unpacklsw
)
1799 IWMMXT_OP_ENV1(unpacklsl
)
1800 IWMMXT_OP_ENV1(unpackhsb
)
1801 IWMMXT_OP_ENV1(unpackhsw
)
1802 IWMMXT_OP_ENV1(unpackhsl
)
1804 IWMMXT_OP_ENV_SIZE(cmpeq
)
1805 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1806 IWMMXT_OP_ENV_SIZE(cmpgts
)
1808 IWMMXT_OP_ENV_SIZE(mins
)
1809 IWMMXT_OP_ENV_SIZE(minu
)
1810 IWMMXT_OP_ENV_SIZE(maxs
)
1811 IWMMXT_OP_ENV_SIZE(maxu
)
1813 IWMMXT_OP_ENV_SIZE(subn
)
1814 IWMMXT_OP_ENV_SIZE(addn
)
1815 IWMMXT_OP_ENV_SIZE(subu
)
1816 IWMMXT_OP_ENV_SIZE(addu
)
1817 IWMMXT_OP_ENV_SIZE(subs
)
1818 IWMMXT_OP_ENV_SIZE(adds
)
1820 IWMMXT_OP_ENV(avgb0
)
1821 IWMMXT_OP_ENV(avgb1
)
1822 IWMMXT_OP_ENV(avgw0
)
1823 IWMMXT_OP_ENV(avgw1
)
1825 IWMMXT_OP_ENV(packuw
)
1826 IWMMXT_OP_ENV(packul
)
1827 IWMMXT_OP_ENV(packuq
)
1828 IWMMXT_OP_ENV(packsw
)
1829 IWMMXT_OP_ENV(packsl
)
1830 IWMMXT_OP_ENV(packsq
)
1832 static void gen_op_iwmmxt_set_mup(void)
1835 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1836 tcg_gen_ori_i32(tmp
, tmp
, 2);
1837 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1840 static void gen_op_iwmmxt_set_cup(void)
1843 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1844 tcg_gen_ori_i32(tmp
, tmp
, 1);
1845 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1848 static void gen_op_iwmmxt_setpsr_nz(void)
1850 TCGv_i32 tmp
= tcg_temp_new_i32();
1851 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1852 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1855 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1857 iwmmxt_load_reg(cpu_V1
, rn
);
1858 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1859 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1862 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1869 rd
= (insn
>> 16) & 0xf;
1870 tmp
= load_reg(s
, rd
);
1872 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1873 if (insn
& (1 << 24)) {
1875 if (insn
& (1 << 23))
1876 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1878 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1879 tcg_gen_mov_i32(dest
, tmp
);
1880 if (insn
& (1 << 21))
1881 store_reg(s
, rd
, tmp
);
1883 tcg_temp_free_i32(tmp
);
1884 } else if (insn
& (1 << 21)) {
1886 tcg_gen_mov_i32(dest
, tmp
);
1887 if (insn
& (1 << 23))
1888 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1890 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1891 store_reg(s
, rd
, tmp
);
1892 } else if (!(insn
& (1 << 23)))
1897 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1899 int rd
= (insn
>> 0) & 0xf;
1902 if (insn
& (1 << 8)) {
1903 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1906 tmp
= iwmmxt_load_creg(rd
);
1909 tmp
= tcg_temp_new_i32();
1910 iwmmxt_load_reg(cpu_V0
, rd
);
1911 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1913 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1914 tcg_gen_mov_i32(dest
, tmp
);
1915 tcg_temp_free_i32(tmp
);
1919 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1920 (ie. an undefined instruction). */
1921 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1924 int rdhi
, rdlo
, rd0
, rd1
, i
;
1926 TCGv_i32 tmp
, tmp2
, tmp3
;
1928 if ((insn
& 0x0e000e00) == 0x0c000000) {
1929 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1931 rdlo
= (insn
>> 12) & 0xf;
1932 rdhi
= (insn
>> 16) & 0xf;
1933 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1934 iwmmxt_load_reg(cpu_V0
, wrd
);
1935 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1936 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1937 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1938 } else { /* TMCRR */
1939 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1940 iwmmxt_store_reg(cpu_V0
, wrd
);
1941 gen_op_iwmmxt_set_mup();
1946 wrd
= (insn
>> 12) & 0xf;
1947 addr
= tcg_temp_new_i32();
1948 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1949 tcg_temp_free_i32(addr
);
1952 if (insn
& ARM_CP_RW_BIT
) {
1953 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1954 tmp
= tcg_temp_new_i32();
1955 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1956 iwmmxt_store_creg(wrd
, tmp
);
1959 if (insn
& (1 << 8)) {
1960 if (insn
& (1 << 22)) { /* WLDRD */
1961 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1963 } else { /* WLDRW wRd */
1964 tmp
= tcg_temp_new_i32();
1965 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1968 tmp
= tcg_temp_new_i32();
1969 if (insn
& (1 << 22)) { /* WLDRH */
1970 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1971 } else { /* WLDRB */
1972 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1976 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1977 tcg_temp_free_i32(tmp
);
1979 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1982 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1983 tmp
= iwmmxt_load_creg(wrd
);
1984 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1986 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1987 tmp
= tcg_temp_new_i32();
1988 if (insn
& (1 << 8)) {
1989 if (insn
& (1 << 22)) { /* WSTRD */
1990 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1991 } else { /* WSTRW wRd */
1992 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1993 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1996 if (insn
& (1 << 22)) { /* WSTRH */
1997 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1998 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1999 } else { /* WSTRB */
2000 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2001 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
2005 tcg_temp_free_i32(tmp
);
2007 tcg_temp_free_i32(addr
);
2011 if ((insn
& 0x0f000000) != 0x0e000000)
2014 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
2015 case 0x000: /* WOR */
2016 wrd
= (insn
>> 12) & 0xf;
2017 rd0
= (insn
>> 0) & 0xf;
2018 rd1
= (insn
>> 16) & 0xf;
2019 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2020 gen_op_iwmmxt_orq_M0_wRn(rd1
);
2021 gen_op_iwmmxt_setpsr_nz();
2022 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2023 gen_op_iwmmxt_set_mup();
2024 gen_op_iwmmxt_set_cup();
2026 case 0x011: /* TMCR */
2029 rd
= (insn
>> 12) & 0xf;
2030 wrd
= (insn
>> 16) & 0xf;
2032 case ARM_IWMMXT_wCID
:
2033 case ARM_IWMMXT_wCASF
:
2035 case ARM_IWMMXT_wCon
:
2036 gen_op_iwmmxt_set_cup();
2038 case ARM_IWMMXT_wCSSF
:
2039 tmp
= iwmmxt_load_creg(wrd
);
2040 tmp2
= load_reg(s
, rd
);
2041 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
2042 tcg_temp_free_i32(tmp2
);
2043 iwmmxt_store_creg(wrd
, tmp
);
2045 case ARM_IWMMXT_wCGR0
:
2046 case ARM_IWMMXT_wCGR1
:
2047 case ARM_IWMMXT_wCGR2
:
2048 case ARM_IWMMXT_wCGR3
:
2049 gen_op_iwmmxt_set_cup();
2050 tmp
= load_reg(s
, rd
);
2051 iwmmxt_store_creg(wrd
, tmp
);
2057 case 0x100: /* WXOR */
2058 wrd
= (insn
>> 12) & 0xf;
2059 rd0
= (insn
>> 0) & 0xf;
2060 rd1
= (insn
>> 16) & 0xf;
2061 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2062 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
2063 gen_op_iwmmxt_setpsr_nz();
2064 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2065 gen_op_iwmmxt_set_mup();
2066 gen_op_iwmmxt_set_cup();
2068 case 0x111: /* TMRC */
2071 rd
= (insn
>> 12) & 0xf;
2072 wrd
= (insn
>> 16) & 0xf;
2073 tmp
= iwmmxt_load_creg(wrd
);
2074 store_reg(s
, rd
, tmp
);
2076 case 0x300: /* WANDN */
2077 wrd
= (insn
>> 12) & 0xf;
2078 rd0
= (insn
>> 0) & 0xf;
2079 rd1
= (insn
>> 16) & 0xf;
2080 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2081 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
2082 gen_op_iwmmxt_andq_M0_wRn(rd1
);
2083 gen_op_iwmmxt_setpsr_nz();
2084 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2085 gen_op_iwmmxt_set_mup();
2086 gen_op_iwmmxt_set_cup();
2088 case 0x200: /* WAND */
2089 wrd
= (insn
>> 12) & 0xf;
2090 rd0
= (insn
>> 0) & 0xf;
2091 rd1
= (insn
>> 16) & 0xf;
2092 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2093 gen_op_iwmmxt_andq_M0_wRn(rd1
);
2094 gen_op_iwmmxt_setpsr_nz();
2095 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2096 gen_op_iwmmxt_set_mup();
2097 gen_op_iwmmxt_set_cup();
2099 case 0x810: case 0xa10: /* WMADD */
2100 wrd
= (insn
>> 12) & 0xf;
2101 rd0
= (insn
>> 0) & 0xf;
2102 rd1
= (insn
>> 16) & 0xf;
2103 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2104 if (insn
& (1 << 21))
2105 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
2107 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
2108 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2109 gen_op_iwmmxt_set_mup();
2111 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2112 wrd
= (insn
>> 12) & 0xf;
2113 rd0
= (insn
>> 16) & 0xf;
2114 rd1
= (insn
>> 0) & 0xf;
2115 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2116 switch ((insn
>> 22) & 3) {
2118 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
2121 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
2124 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
2129 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2130 gen_op_iwmmxt_set_mup();
2131 gen_op_iwmmxt_set_cup();
2133 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2134 wrd
= (insn
>> 12) & 0xf;
2135 rd0
= (insn
>> 16) & 0xf;
2136 rd1
= (insn
>> 0) & 0xf;
2137 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2138 switch ((insn
>> 22) & 3) {
2140 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
2143 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
2146 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
2151 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2152 gen_op_iwmmxt_set_mup();
2153 gen_op_iwmmxt_set_cup();
2155 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2156 wrd
= (insn
>> 12) & 0xf;
2157 rd0
= (insn
>> 16) & 0xf;
2158 rd1
= (insn
>> 0) & 0xf;
2159 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2160 if (insn
& (1 << 22))
2161 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2163 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2164 if (!(insn
& (1 << 20)))
2165 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2166 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2167 gen_op_iwmmxt_set_mup();
2169 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2170 wrd
= (insn
>> 12) & 0xf;
2171 rd0
= (insn
>> 16) & 0xf;
2172 rd1
= (insn
>> 0) & 0xf;
2173 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2174 if (insn
& (1 << 21)) {
2175 if (insn
& (1 << 20))
2176 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2178 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2180 if (insn
& (1 << 20))
2181 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2183 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2185 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2186 gen_op_iwmmxt_set_mup();
2188 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2189 wrd
= (insn
>> 12) & 0xf;
2190 rd0
= (insn
>> 16) & 0xf;
2191 rd1
= (insn
>> 0) & 0xf;
2192 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2193 if (insn
& (1 << 21))
2194 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2196 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2197 if (!(insn
& (1 << 20))) {
2198 iwmmxt_load_reg(cpu_V1
, wrd
);
2199 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2201 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2202 gen_op_iwmmxt_set_mup();
2204 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2205 wrd
= (insn
>> 12) & 0xf;
2206 rd0
= (insn
>> 16) & 0xf;
2207 rd1
= (insn
>> 0) & 0xf;
2208 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2209 switch ((insn
>> 22) & 3) {
2211 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2214 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2217 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2222 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2223 gen_op_iwmmxt_set_mup();
2224 gen_op_iwmmxt_set_cup();
2226 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2227 wrd
= (insn
>> 12) & 0xf;
2228 rd0
= (insn
>> 16) & 0xf;
2229 rd1
= (insn
>> 0) & 0xf;
2230 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2231 if (insn
& (1 << 22)) {
2232 if (insn
& (1 << 20))
2233 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2235 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2237 if (insn
& (1 << 20))
2238 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2240 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2242 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2243 gen_op_iwmmxt_set_mup();
2244 gen_op_iwmmxt_set_cup();
2246 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2247 wrd
= (insn
>> 12) & 0xf;
2248 rd0
= (insn
>> 16) & 0xf;
2249 rd1
= (insn
>> 0) & 0xf;
2250 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2251 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2252 tcg_gen_andi_i32(tmp
, tmp
, 7);
2253 iwmmxt_load_reg(cpu_V1
, rd1
);
2254 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2255 tcg_temp_free_i32(tmp
);
2256 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2257 gen_op_iwmmxt_set_mup();
2259 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2260 if (((insn
>> 6) & 3) == 3)
2262 rd
= (insn
>> 12) & 0xf;
2263 wrd
= (insn
>> 16) & 0xf;
2264 tmp
= load_reg(s
, rd
);
2265 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2266 switch ((insn
>> 6) & 3) {
2268 tmp2
= tcg_const_i32(0xff);
2269 tmp3
= tcg_const_i32((insn
& 7) << 3);
2272 tmp2
= tcg_const_i32(0xffff);
2273 tmp3
= tcg_const_i32((insn
& 3) << 4);
2276 tmp2
= tcg_const_i32(0xffffffff);
2277 tmp3
= tcg_const_i32((insn
& 1) << 5);
2283 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2284 tcg_temp_free_i32(tmp3
);
2285 tcg_temp_free_i32(tmp2
);
2286 tcg_temp_free_i32(tmp
);
2287 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2288 gen_op_iwmmxt_set_mup();
2290 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2291 rd
= (insn
>> 12) & 0xf;
2292 wrd
= (insn
>> 16) & 0xf;
2293 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2295 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2296 tmp
= tcg_temp_new_i32();
2297 switch ((insn
>> 22) & 3) {
2299 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2300 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2302 tcg_gen_ext8s_i32(tmp
, tmp
);
2304 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2308 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2309 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2311 tcg_gen_ext16s_i32(tmp
, tmp
);
2313 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2317 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2318 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2321 store_reg(s
, rd
, tmp
);
2323 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2324 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2326 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2327 switch ((insn
>> 22) & 3) {
2329 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2332 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2335 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2338 tcg_gen_shli_i32(tmp
, tmp
, 28);
2340 tcg_temp_free_i32(tmp
);
2342 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2343 if (((insn
>> 6) & 3) == 3)
2345 rd
= (insn
>> 12) & 0xf;
2346 wrd
= (insn
>> 16) & 0xf;
2347 tmp
= load_reg(s
, rd
);
2348 switch ((insn
>> 6) & 3) {
2350 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2353 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2356 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2359 tcg_temp_free_i32(tmp
);
2360 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2361 gen_op_iwmmxt_set_mup();
2363 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2364 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2366 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2367 tmp2
= tcg_temp_new_i32();
2368 tcg_gen_mov_i32(tmp2
, tmp
);
2369 switch ((insn
>> 22) & 3) {
2371 for (i
= 0; i
< 7; i
++) {
2372 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2373 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2377 for (i
= 0; i
< 3; i
++) {
2378 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2379 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2383 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2384 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2388 tcg_temp_free_i32(tmp2
);
2389 tcg_temp_free_i32(tmp
);
2391 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2392 wrd
= (insn
>> 12) & 0xf;
2393 rd0
= (insn
>> 16) & 0xf;
2394 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2395 switch ((insn
>> 22) & 3) {
2397 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2400 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2403 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2408 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2409 gen_op_iwmmxt_set_mup();
2411 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2412 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2414 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2415 tmp2
= tcg_temp_new_i32();
2416 tcg_gen_mov_i32(tmp2
, tmp
);
2417 switch ((insn
>> 22) & 3) {
2419 for (i
= 0; i
< 7; i
++) {
2420 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2421 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2425 for (i
= 0; i
< 3; i
++) {
2426 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2427 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2431 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2432 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2436 tcg_temp_free_i32(tmp2
);
2437 tcg_temp_free_i32(tmp
);
2439 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2440 rd
= (insn
>> 12) & 0xf;
2441 rd0
= (insn
>> 16) & 0xf;
2442 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2444 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2445 tmp
= tcg_temp_new_i32();
2446 switch ((insn
>> 22) & 3) {
2448 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2451 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2454 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2457 store_reg(s
, rd
, tmp
);
2459 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2460 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2461 wrd
= (insn
>> 12) & 0xf;
2462 rd0
= (insn
>> 16) & 0xf;
2463 rd1
= (insn
>> 0) & 0xf;
2464 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2465 switch ((insn
>> 22) & 3) {
2467 if (insn
& (1 << 21))
2468 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2470 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2473 if (insn
& (1 << 21))
2474 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2476 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2479 if (insn
& (1 << 21))
2480 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2482 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2487 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2488 gen_op_iwmmxt_set_mup();
2489 gen_op_iwmmxt_set_cup();
2491 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2492 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2493 wrd
= (insn
>> 12) & 0xf;
2494 rd0
= (insn
>> 16) & 0xf;
2495 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2496 switch ((insn
>> 22) & 3) {
2498 if (insn
& (1 << 21))
2499 gen_op_iwmmxt_unpacklsb_M0();
2501 gen_op_iwmmxt_unpacklub_M0();
2504 if (insn
& (1 << 21))
2505 gen_op_iwmmxt_unpacklsw_M0();
2507 gen_op_iwmmxt_unpackluw_M0();
2510 if (insn
& (1 << 21))
2511 gen_op_iwmmxt_unpacklsl_M0();
2513 gen_op_iwmmxt_unpacklul_M0();
2518 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2519 gen_op_iwmmxt_set_mup();
2520 gen_op_iwmmxt_set_cup();
2522 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2523 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2524 wrd
= (insn
>> 12) & 0xf;
2525 rd0
= (insn
>> 16) & 0xf;
2526 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2527 switch ((insn
>> 22) & 3) {
2529 if (insn
& (1 << 21))
2530 gen_op_iwmmxt_unpackhsb_M0();
2532 gen_op_iwmmxt_unpackhub_M0();
2535 if (insn
& (1 << 21))
2536 gen_op_iwmmxt_unpackhsw_M0();
2538 gen_op_iwmmxt_unpackhuw_M0();
2541 if (insn
& (1 << 21))
2542 gen_op_iwmmxt_unpackhsl_M0();
2544 gen_op_iwmmxt_unpackhul_M0();
2549 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2550 gen_op_iwmmxt_set_mup();
2551 gen_op_iwmmxt_set_cup();
2553 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2554 case 0x214: case 0x614: case 0xa14: case 0xe14:
2555 if (((insn
>> 22) & 3) == 0)
2557 wrd
= (insn
>> 12) & 0xf;
2558 rd0
= (insn
>> 16) & 0xf;
2559 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2560 tmp
= tcg_temp_new_i32();
2561 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2562 tcg_temp_free_i32(tmp
);
2565 switch ((insn
>> 22) & 3) {
2567 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2570 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2573 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2576 tcg_temp_free_i32(tmp
);
2577 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2578 gen_op_iwmmxt_set_mup();
2579 gen_op_iwmmxt_set_cup();
2581 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2582 case 0x014: case 0x414: case 0x814: case 0xc14:
2583 if (((insn
>> 22) & 3) == 0)
2585 wrd
= (insn
>> 12) & 0xf;
2586 rd0
= (insn
>> 16) & 0xf;
2587 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2588 tmp
= tcg_temp_new_i32();
2589 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2590 tcg_temp_free_i32(tmp
);
2593 switch ((insn
>> 22) & 3) {
2595 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2598 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2601 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2604 tcg_temp_free_i32(tmp
);
2605 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2606 gen_op_iwmmxt_set_mup();
2607 gen_op_iwmmxt_set_cup();
2609 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2610 case 0x114: case 0x514: case 0x914: case 0xd14:
2611 if (((insn
>> 22) & 3) == 0)
2613 wrd
= (insn
>> 12) & 0xf;
2614 rd0
= (insn
>> 16) & 0xf;
2615 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2616 tmp
= tcg_temp_new_i32();
2617 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2618 tcg_temp_free_i32(tmp
);
2621 switch ((insn
>> 22) & 3) {
2623 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2626 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2629 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2632 tcg_temp_free_i32(tmp
);
2633 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2634 gen_op_iwmmxt_set_mup();
2635 gen_op_iwmmxt_set_cup();
2637 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2638 case 0x314: case 0x714: case 0xb14: case 0xf14:
2639 if (((insn
>> 22) & 3) == 0)
2641 wrd
= (insn
>> 12) & 0xf;
2642 rd0
= (insn
>> 16) & 0xf;
2643 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2644 tmp
= tcg_temp_new_i32();
2645 switch ((insn
>> 22) & 3) {
2647 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2648 tcg_temp_free_i32(tmp
);
2651 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2654 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2655 tcg_temp_free_i32(tmp
);
2658 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2661 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2662 tcg_temp_free_i32(tmp
);
2665 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2668 tcg_temp_free_i32(tmp
);
2669 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2670 gen_op_iwmmxt_set_mup();
2671 gen_op_iwmmxt_set_cup();
2673 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2674 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2675 wrd
= (insn
>> 12) & 0xf;
2676 rd0
= (insn
>> 16) & 0xf;
2677 rd1
= (insn
>> 0) & 0xf;
2678 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2679 switch ((insn
>> 22) & 3) {
2681 if (insn
& (1 << 21))
2682 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2684 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2687 if (insn
& (1 << 21))
2688 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2690 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2693 if (insn
& (1 << 21))
2694 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2696 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2701 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2702 gen_op_iwmmxt_set_mup();
2704 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2705 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2706 wrd
= (insn
>> 12) & 0xf;
2707 rd0
= (insn
>> 16) & 0xf;
2708 rd1
= (insn
>> 0) & 0xf;
2709 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2710 switch ((insn
>> 22) & 3) {
2712 if (insn
& (1 << 21))
2713 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2715 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2718 if (insn
& (1 << 21))
2719 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2721 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2724 if (insn
& (1 << 21))
2725 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2727 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2732 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2733 gen_op_iwmmxt_set_mup();
2735 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2736 case 0x402: case 0x502: case 0x602: case 0x702:
2737 wrd
= (insn
>> 12) & 0xf;
2738 rd0
= (insn
>> 16) & 0xf;
2739 rd1
= (insn
>> 0) & 0xf;
2740 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2741 tmp
= tcg_const_i32((insn
>> 20) & 3);
2742 iwmmxt_load_reg(cpu_V1
, rd1
);
2743 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2744 tcg_temp_free_i32(tmp
);
2745 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2746 gen_op_iwmmxt_set_mup();
2748 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2749 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2750 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2751 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2752 wrd
= (insn
>> 12) & 0xf;
2753 rd0
= (insn
>> 16) & 0xf;
2754 rd1
= (insn
>> 0) & 0xf;
2755 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2756 switch ((insn
>> 20) & 0xf) {
2758 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2761 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2764 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2767 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2770 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2773 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2776 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2779 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2782 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2787 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2788 gen_op_iwmmxt_set_mup();
2789 gen_op_iwmmxt_set_cup();
2791 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2792 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2793 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2794 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2795 wrd
= (insn
>> 12) & 0xf;
2796 rd0
= (insn
>> 16) & 0xf;
2797 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2798 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2799 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2800 tcg_temp_free_i32(tmp
);
2801 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2802 gen_op_iwmmxt_set_mup();
2803 gen_op_iwmmxt_set_cup();
2805 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2806 case 0x418: case 0x518: case 0x618: case 0x718:
2807 case 0x818: case 0x918: case 0xa18: case 0xb18:
2808 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2809 wrd
= (insn
>> 12) & 0xf;
2810 rd0
= (insn
>> 16) & 0xf;
2811 rd1
= (insn
>> 0) & 0xf;
2812 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2813 switch ((insn
>> 20) & 0xf) {
2815 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2818 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2821 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2824 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2827 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2830 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2833 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2836 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2839 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2844 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2845 gen_op_iwmmxt_set_mup();
2846 gen_op_iwmmxt_set_cup();
2848 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2849 case 0x408: case 0x508: case 0x608: case 0x708:
2850 case 0x808: case 0x908: case 0xa08: case 0xb08:
2851 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2852 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2854 wrd
= (insn
>> 12) & 0xf;
2855 rd0
= (insn
>> 16) & 0xf;
2856 rd1
= (insn
>> 0) & 0xf;
2857 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2858 switch ((insn
>> 22) & 3) {
2860 if (insn
& (1 << 21))
2861 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2863 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2866 if (insn
& (1 << 21))
2867 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2869 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2872 if (insn
& (1 << 21))
2873 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2875 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2878 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2879 gen_op_iwmmxt_set_mup();
2880 gen_op_iwmmxt_set_cup();
2882 case 0x201: case 0x203: case 0x205: case 0x207:
2883 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2884 case 0x211: case 0x213: case 0x215: case 0x217:
2885 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2886 wrd
= (insn
>> 5) & 0xf;
2887 rd0
= (insn
>> 12) & 0xf;
2888 rd1
= (insn
>> 0) & 0xf;
2889 if (rd0
== 0xf || rd1
== 0xf)
2891 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2892 tmp
= load_reg(s
, rd0
);
2893 tmp2
= load_reg(s
, rd1
);
2894 switch ((insn
>> 16) & 0xf) {
2895 case 0x0: /* TMIA */
2896 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2898 case 0x8: /* TMIAPH */
2899 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2901 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2902 if (insn
& (1 << 16))
2903 tcg_gen_shri_i32(tmp
, tmp
, 16);
2904 if (insn
& (1 << 17))
2905 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2906 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2909 tcg_temp_free_i32(tmp2
);
2910 tcg_temp_free_i32(tmp
);
2913 tcg_temp_free_i32(tmp2
);
2914 tcg_temp_free_i32(tmp
);
2915 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2916 gen_op_iwmmxt_set_mup();
2925 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2926 (ie. an undefined instruction). */
2927 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2929 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2932 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2933 /* Multiply with Internal Accumulate Format */
2934 rd0
= (insn
>> 12) & 0xf;
2936 acc
= (insn
>> 5) & 7;
2941 tmp
= load_reg(s
, rd0
);
2942 tmp2
= load_reg(s
, rd1
);
2943 switch ((insn
>> 16) & 0xf) {
2945 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2947 case 0x8: /* MIAPH */
2948 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2950 case 0xc: /* MIABB */
2951 case 0xd: /* MIABT */
2952 case 0xe: /* MIATB */
2953 case 0xf: /* MIATT */
2954 if (insn
& (1 << 16))
2955 tcg_gen_shri_i32(tmp
, tmp
, 16);
2956 if (insn
& (1 << 17))
2957 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2958 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2963 tcg_temp_free_i32(tmp2
);
2964 tcg_temp_free_i32(tmp
);
2966 gen_op_iwmmxt_movq_wRn_M0(acc
);
2970 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2971 /* Internal Accumulator Access Format */
2972 rdhi
= (insn
>> 16) & 0xf;
2973 rdlo
= (insn
>> 12) & 0xf;
2979 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2980 iwmmxt_load_reg(cpu_V0
, acc
);
2981 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2982 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2983 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2984 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2986 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2987 iwmmxt_store_reg(cpu_V0
, acc
);
2995 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2996 #define VFP_SREG(insn, bigbit, smallbit) \
2997 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2998 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2999 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
3000 reg = (((insn) >> (bigbit)) & 0x0f) \
3001 | (((insn) >> ((smallbit) - 4)) & 0x10); \
3003 if (insn & (1 << (smallbit))) \
3005 reg = ((insn) >> (bigbit)) & 0x0f; \
3008 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
3009 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
3010 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
3011 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
3012 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
3013 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
3015 /* Move between integer and VFP cores. */
3016 static TCGv_i32
gen_vfp_mrs(void)
3018 TCGv_i32 tmp
= tcg_temp_new_i32();
3019 tcg_gen_mov_i32(tmp
, cpu_F0s
);
3023 static void gen_vfp_msr(TCGv_i32 tmp
)
3025 tcg_gen_mov_i32(cpu_F0s
, tmp
);
3026 tcg_temp_free_i32(tmp
);
3029 static void gen_neon_dup_low16(TCGv_i32 var
)
3031 TCGv_i32 tmp
= tcg_temp_new_i32();
3032 tcg_gen_ext16u_i32(var
, var
);
3033 tcg_gen_shli_i32(tmp
, var
, 16);
3034 tcg_gen_or_i32(var
, var
, tmp
);
3035 tcg_temp_free_i32(tmp
);
3038 static void gen_neon_dup_high16(TCGv_i32 var
)
3040 TCGv_i32 tmp
= tcg_temp_new_i32();
3041 tcg_gen_andi_i32(var
, var
, 0xffff0000);
3042 tcg_gen_shri_i32(tmp
, var
, 16);
3043 tcg_gen_or_i32(var
, var
, tmp
);
3044 tcg_temp_free_i32(tmp
);
3048 * Disassemble a VFP instruction. Returns nonzero if an error occurred
3049 * (ie. an undefined instruction).
3051 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3053 uint32_t rd
, rn
, rm
, op
, i
, n
, delta_d
, delta_m
, bank_mask
;
3058 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3063 * If the decodetree decoder handles this insn it will always
3064 * emit code to either execute the insn or generate an appropriate
3065 * exception; so we don't need to ever return non-zero to tell
3066 * the calling code to emit an UNDEF exception.
3068 if (extract32(insn
, 28, 4) == 0xf) {
3069 if (disas_vfp_uncond(s
, insn
)) {
3073 if (disas_vfp(s
, insn
)) {
3078 if (extract32(insn
, 28, 4) == 0xf) {
3080 * Encodings with T=1 (Thumb) or unconditional (ARM): these
3081 * were all handled by the decodetree decoder, so any insn
3082 * patterns which get here must be UNDEF.
3088 * FIXME: this access check should not take precedence over UNDEF
3089 * for invalid encodings; we will generate incorrect syndrome information
3090 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3092 if (!vfp_access_check(s
)) {
3096 dp
= ((insn
& 0xf00) == 0xb00);
3097 switch ((insn
>> 24) & 0xf) {
3099 if (insn
& (1 << 4)) {
3100 /* already handled by decodetree */
3103 /* data processing */
3106 bool no_output
= false;
3108 /* The opcode is in bits 23, 21, 20 and 6. */
3109 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3110 rn
= VFP_SREG_N(insn
);
3114 /* Already handled by decodetree */
3121 /* rn is opcode, encoded as per VFP_SREG_N. */
3123 case 0x00: /* vmov */
3124 case 0x01: /* vabs */
3125 case 0x02: /* vneg */
3126 case 0x03: /* vsqrt */
3129 case 0x04: /* vcvtb.f64.f16, vcvtb.f32.f16 */
3130 case 0x05: /* vcvtt.f64.f16, vcvtt.f32.f16 */
3132 * VCVTB, VCVTT: only present with the halfprec extension
3133 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3134 * (we choose to UNDEF)
3137 if (!dc_isar_feature(aa32_fp16_dpconv
, s
)) {
3141 if (!dc_isar_feature(aa32_fp16_spconv
, s
)) {
3147 case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3148 case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3150 if (!dc_isar_feature(aa32_fp16_dpconv
, s
)) {
3154 if (!dc_isar_feature(aa32_fp16_spconv
, s
)) {
3161 case 0x08: case 0x0a: /* vcmp, vcmpz */
3162 case 0x09: case 0x0b: /* vcmpe, vcmpez */
3166 case 0x0c: /* vrintr */
3167 case 0x0d: /* vrintz */
3168 case 0x0e: /* vrintx */
3171 case 0x0f: /* vcvt double<->single */
3175 case 0x10: /* vcvt.fxx.u32 */
3176 case 0x11: /* vcvt.fxx.s32 */
3179 case 0x18: /* vcvtr.u32.fxx */
3180 case 0x19: /* vcvtz.u32.fxx */
3181 case 0x1a: /* vcvtr.s32.fxx */
3182 case 0x1b: /* vcvtz.s32.fxx */
3186 case 0x14: /* vcvt fp <-> fixed */
3194 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3197 /* Immediate frac_bits has same format as SREG_M. */
3201 case 0x13: /* vjcvt */
3202 if (!dp
|| !dc_isar_feature(aa32_jscvt
, s
)) {
3212 /* rn is register number */
3213 VFP_DREG_N(rn
, insn
);
3217 VFP_DREG_D(rd
, insn
);
3219 rd
= VFP_SREG_D(insn
);
3222 VFP_DREG_M(rm
, insn
);
3224 rm
= VFP_SREG_M(insn
);
3227 veclen
= s
->vec_len
;
3228 if (op
== 15 && rn
> 3) {
3232 /* Shut up compiler warnings. */
3243 /* Figure out what type of vector operation this is. */
3244 if ((rd
& bank_mask
) == 0) {
3249 delta_d
= (s
->vec_stride
>> 1) + 1;
3251 delta_d
= s
->vec_stride
+ 1;
3253 if ((rm
& bank_mask
) == 0) {
3254 /* mixed scalar/vector */
3263 /* Load the initial operands. */
3266 case 0x08: case 0x09: /* Compare */
3267 gen_mov_F0_vreg(dp
, rd
);
3268 gen_mov_F1_vreg(dp
, rm
);
3270 case 0x0a: case 0x0b: /* Compare with zero */
3271 gen_mov_F0_vreg(dp
, rd
);
3274 case 0x14: /* vcvt fp <-> fixed */
3282 /* Source and destination the same. */
3283 gen_mov_F0_vreg(dp
, rd
);
3286 /* One source operand. */
3287 gen_mov_F0_vreg(rm_is_dp
, rm
);
3291 /* Two source operands. */
3292 gen_mov_F0_vreg(dp
, rn
);
3293 gen_mov_F1_vreg(dp
, rm
);
3297 /* Perform the calculation. */
3299 case 7: /* sub: fn - fm */
3302 case 8: /* div: fn / fm */
3305 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3306 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3307 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3308 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3309 /* These are fused multiply-add, and must be done as one
3310 * floating point operation with no rounding between the
3311 * multiplication and addition steps.
3312 * NB that doing the negations here as separate steps is
3313 * correct : an input NaN should come out with its sign bit
3314 * flipped if it is a negated-input.
3316 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3324 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3326 frd
= tcg_temp_new_i64();
3327 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3330 gen_helper_vfp_negd(frd
, frd
);
3332 fpst
= get_fpstatus_ptr(0);
3333 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3334 cpu_F1d
, frd
, fpst
);
3335 tcg_temp_free_ptr(fpst
);
3336 tcg_temp_free_i64(frd
);
3342 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3344 frd
= tcg_temp_new_i32();
3345 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3347 gen_helper_vfp_negs(frd
, frd
);
3349 fpst
= get_fpstatus_ptr(0);
3350 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3351 cpu_F1s
, frd
, fpst
);
3352 tcg_temp_free_ptr(fpst
);
3353 tcg_temp_free_i32(frd
);
3356 case 14: /* fconst */
3357 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3361 n
= (insn
<< 12) & 0x80000000;
3362 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3369 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3376 tcg_gen_movi_i32(cpu_F0s
, n
);
3379 case 15: /* extension space */
3393 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3395 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3396 TCGv_i32 ahp_mode
= get_ahp_flag();
3397 tmp
= gen_vfp_mrs();
3398 tcg_gen_ext16u_i32(tmp
, tmp
);
3400 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3403 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3406 tcg_temp_free_i32(ahp_mode
);
3407 tcg_temp_free_ptr(fpst
);
3408 tcg_temp_free_i32(tmp
);
3411 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3413 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3414 TCGv_i32 ahp
= get_ahp_flag();
3415 tmp
= gen_vfp_mrs();
3416 tcg_gen_shri_i32(tmp
, tmp
, 16);
3418 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3421 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3424 tcg_temp_free_i32(tmp
);
3425 tcg_temp_free_i32(ahp
);
3426 tcg_temp_free_ptr(fpst
);
3429 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3431 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3432 TCGv_i32 ahp
= get_ahp_flag();
3433 tmp
= tcg_temp_new_i32();
3436 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3439 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3442 tcg_temp_free_i32(ahp
);
3443 tcg_temp_free_ptr(fpst
);
3444 gen_mov_F0_vreg(0, rd
);
3445 tmp2
= gen_vfp_mrs();
3446 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3447 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3448 tcg_temp_free_i32(tmp2
);
3452 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3454 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3455 TCGv_i32 ahp
= get_ahp_flag();
3456 tmp
= tcg_temp_new_i32();
3458 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3461 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3464 tcg_temp_free_i32(ahp
);
3465 tcg_temp_free_ptr(fpst
);
3466 tcg_gen_shli_i32(tmp
, tmp
, 16);
3467 gen_mov_F0_vreg(0, rd
);
3468 tmp2
= gen_vfp_mrs();
3469 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3470 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3471 tcg_temp_free_i32(tmp2
);
3484 case 11: /* cmpez */
3488 case 12: /* vrintr */
3490 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3492 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3494 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3496 tcg_temp_free_ptr(fpst
);
3499 case 13: /* vrintz */
3501 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3503 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3504 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3506 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3508 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3510 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3511 tcg_temp_free_i32(tcg_rmode
);
3512 tcg_temp_free_ptr(fpst
);
3515 case 14: /* vrintx */
3517 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3519 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3521 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3523 tcg_temp_free_ptr(fpst
);
3526 case 15: /* single<->double conversion */
3528 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3530 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3533 case 16: /* fuito */
3534 gen_vfp_uito(dp
, 0);
3536 case 17: /* fsito */
3537 gen_vfp_sito(dp
, 0);
3539 case 19: /* vjcvt */
3540 gen_helper_vjcvt(cpu_F0s
, cpu_F0d
, cpu_env
);
3542 case 20: /* fshto */
3543 gen_vfp_shto(dp
, 16 - rm
, 0);
3545 case 21: /* fslto */
3546 gen_vfp_slto(dp
, 32 - rm
, 0);
3548 case 22: /* fuhto */
3549 gen_vfp_uhto(dp
, 16 - rm
, 0);
3551 case 23: /* fulto */
3552 gen_vfp_ulto(dp
, 32 - rm
, 0);
3554 case 24: /* ftoui */
3555 gen_vfp_toui(dp
, 0);
3557 case 25: /* ftouiz */
3558 gen_vfp_touiz(dp
, 0);
3560 case 26: /* ftosi */
3561 gen_vfp_tosi(dp
, 0);
3563 case 27: /* ftosiz */
3564 gen_vfp_tosiz(dp
, 0);
3566 case 28: /* ftosh */
3567 gen_vfp_tosh(dp
, 16 - rm
, 0);
3569 case 29: /* ftosl */
3570 gen_vfp_tosl(dp
, 32 - rm
, 0);
3572 case 30: /* ftouh */
3573 gen_vfp_touh(dp
, 16 - rm
, 0);
3575 case 31: /* ftoul */
3576 gen_vfp_toul(dp
, 32 - rm
, 0);
3578 default: /* undefined */
3579 g_assert_not_reached();
3582 default: /* undefined */
3586 /* Write back the result, if any. */
3588 gen_mov_vreg_F0(rd_is_dp
, rd
);
3591 /* break out of the loop if we have finished */
3596 if (op
== 15 && delta_m
== 0) {
3597 /* single source one-many */
3599 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3601 gen_mov_vreg_F0(dp
, rd
);
3605 /* Setup the next operands. */
3607 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3611 /* One source operand. */
3612 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3614 gen_mov_F0_vreg(dp
, rm
);
3616 /* Two source operands. */
3617 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3619 gen_mov_F0_vreg(dp
, rn
);
3621 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3623 gen_mov_F1_vreg(dp
, rm
);
3631 /* Already handled by decodetree */
3634 /* Should never happen. */
3640 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
3642 #ifndef CONFIG_USER_ONLY
3643 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
3644 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
3650 static void gen_goto_ptr(void)
3652 tcg_gen_lookup_and_goto_ptr();
3655 /* This will end the TB but doesn't guarantee we'll return to
3656 * cpu_loop_exec. Any live exit_requests will be processed as we
3657 * enter the next TB.
3659 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3661 if (use_goto_tb(s
, dest
)) {
3663 gen_set_pc_im(s
, dest
);
3664 tcg_gen_exit_tb(s
->base
.tb
, n
);
3666 gen_set_pc_im(s
, dest
);
3669 s
->base
.is_jmp
= DISAS_NORETURN
;
3672 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3674 if (unlikely(is_singlestepping(s
))) {
3675 /* An indirect jump so that we still trigger the debug exception. */
3680 gen_goto_tb(s
, 0, dest
);
3684 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3687 tcg_gen_sari_i32(t0
, t0
, 16);
3691 tcg_gen_sari_i32(t1
, t1
, 16);
3694 tcg_gen_mul_i32(t0
, t0
, t1
);
3697 /* Return the mask of PSR bits set by a MSR instruction. */
3698 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
3703 if (flags
& (1 << 0))
3705 if (flags
& (1 << 1))
3707 if (flags
& (1 << 2))
3709 if (flags
& (1 << 3))
3712 /* Mask out undefined bits. */
3713 mask
&= ~CPSR_RESERVED
;
3714 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
3717 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
3718 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3720 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
3721 mask
&= ~(CPSR_E
| CPSR_GE
);
3723 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
3726 /* Mask out execution state and reserved bits. */
3728 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
3730 /* Mask out privileged bits. */
3736 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3737 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3741 /* ??? This is also undefined in system mode. */
3745 tmp
= load_cpu_field(spsr
);
3746 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3747 tcg_gen_andi_i32(t0
, t0
, mask
);
3748 tcg_gen_or_i32(tmp
, tmp
, t0
);
3749 store_cpu_field(tmp
, spsr
);
3751 gen_set_cpsr(t0
, mask
);
3753 tcg_temp_free_i32(t0
);
3758 /* Returns nonzero if access to the PSR is not permitted. */
3759 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3762 tmp
= tcg_temp_new_i32();
3763 tcg_gen_movi_i32(tmp
, val
);
3764 return gen_set_psr(s
, mask
, spsr
, tmp
);
3767 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
3768 int *tgtmode
, int *regno
)
3770 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3771 * the target mode and register number, and identify the various
3772 * unpredictable cases.
3773 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3774 * + executed in user mode
3775 * + using R15 as the src/dest register
3776 * + accessing an unimplemented register
3777 * + accessing a register that's inaccessible at current PL/security state*
3778 * + accessing a register that you could access with a different insn
3779 * We choose to UNDEF in all these cases.
3780 * Since we don't know which of the various AArch32 modes we are in
3781 * we have to defer some checks to runtime.
3782 * Accesses to Monitor mode registers from Secure EL1 (which implies
3783 * that EL3 is AArch64) must trap to EL3.
3785 * If the access checks fail this function will emit code to take
3786 * an exception and return false. Otherwise it will return true,
3787 * and set *tgtmode and *regno appropriately.
3789 int exc_target
= default_exception_el(s
);
3791 /* These instructions are present only in ARMv8, or in ARMv7 with the
3792 * Virtualization Extensions.
3794 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
3795 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
3799 if (IS_USER(s
) || rn
== 15) {
3803 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3804 * of registers into (r, sysm).
3807 /* SPSRs for other modes */
3809 case 0xe: /* SPSR_fiq */
3810 *tgtmode
= ARM_CPU_MODE_FIQ
;
3812 case 0x10: /* SPSR_irq */
3813 *tgtmode
= ARM_CPU_MODE_IRQ
;
3815 case 0x12: /* SPSR_svc */
3816 *tgtmode
= ARM_CPU_MODE_SVC
;
3818 case 0x14: /* SPSR_abt */
3819 *tgtmode
= ARM_CPU_MODE_ABT
;
3821 case 0x16: /* SPSR_und */
3822 *tgtmode
= ARM_CPU_MODE_UND
;
3824 case 0x1c: /* SPSR_mon */
3825 *tgtmode
= ARM_CPU_MODE_MON
;
3827 case 0x1e: /* SPSR_hyp */
3828 *tgtmode
= ARM_CPU_MODE_HYP
;
3830 default: /* unallocated */
3833 /* We arbitrarily assign SPSR a register number of 16. */
3836 /* general purpose registers for other modes */
3838 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3839 *tgtmode
= ARM_CPU_MODE_USR
;
3842 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3843 *tgtmode
= ARM_CPU_MODE_FIQ
;
3846 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3847 *tgtmode
= ARM_CPU_MODE_IRQ
;
3848 *regno
= sysm
& 1 ? 13 : 14;
3850 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3851 *tgtmode
= ARM_CPU_MODE_SVC
;
3852 *regno
= sysm
& 1 ? 13 : 14;
3854 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3855 *tgtmode
= ARM_CPU_MODE_ABT
;
3856 *regno
= sysm
& 1 ? 13 : 14;
3858 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3859 *tgtmode
= ARM_CPU_MODE_UND
;
3860 *regno
= sysm
& 1 ? 13 : 14;
3862 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3863 *tgtmode
= ARM_CPU_MODE_MON
;
3864 *regno
= sysm
& 1 ? 13 : 14;
3866 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3867 *tgtmode
= ARM_CPU_MODE_HYP
;
3868 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3869 *regno
= sysm
& 1 ? 13 : 17;
3871 default: /* unallocated */
3876 /* Catch the 'accessing inaccessible register' cases we can detect
3877 * at translate time.
3880 case ARM_CPU_MODE_MON
:
3881 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
3884 if (s
->current_el
== 1) {
3885 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3886 * then accesses to Mon registers trap to EL3
3892 case ARM_CPU_MODE_HYP
:
3894 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3895 * (and so we can forbid accesses from EL2 or below). elr_hyp
3896 * can be accessed also from Hyp mode, so forbid accesses from
3899 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 2 ||
3900 (s
->current_el
< 3 && *regno
!= 17)) {
3911 /* If we get here then some access check did not pass */
3912 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
3916 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
3918 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
3919 int tgtmode
= 0, regno
= 0;
3921 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
3925 /* Sync state because msr_banked() can raise exceptions */
3926 gen_set_condexec(s
);
3927 gen_set_pc_im(s
, s
->pc
- 4);
3928 tcg_reg
= load_reg(s
, rn
);
3929 tcg_tgtmode
= tcg_const_i32(tgtmode
);
3930 tcg_regno
= tcg_const_i32(regno
);
3931 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
3932 tcg_temp_free_i32(tcg_tgtmode
);
3933 tcg_temp_free_i32(tcg_regno
);
3934 tcg_temp_free_i32(tcg_reg
);
3935 s
->base
.is_jmp
= DISAS_UPDATE
;
3938 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
3940 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
3941 int tgtmode
= 0, regno
= 0;
3943 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
3947 /* Sync state because mrs_banked() can raise exceptions */
3948 gen_set_condexec(s
);
3949 gen_set_pc_im(s
, s
->pc
- 4);
3950 tcg_reg
= tcg_temp_new_i32();
3951 tcg_tgtmode
= tcg_const_i32(tgtmode
);
3952 tcg_regno
= tcg_const_i32(regno
);
3953 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
3954 tcg_temp_free_i32(tcg_tgtmode
);
3955 tcg_temp_free_i32(tcg_regno
);
3956 store_reg(s
, rn
, tcg_reg
);
3957 s
->base
.is_jmp
= DISAS_UPDATE
;
3960 /* Store value to PC as for an exception return (ie don't
3961 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3962 * will do the masking based on the new value of the Thumb bit.
3964 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
3966 tcg_gen_mov_i32(cpu_R
[15], pc
);
3967 tcg_temp_free_i32(pc
);
3970 /* Generate a v6 exception return. Marks both values as dead. */
3971 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3973 store_pc_exc_ret(s
, pc
);
3974 /* The cpsr_write_eret helper will mask the low bits of PC
3975 * appropriately depending on the new Thumb bit, so it must
3976 * be called after storing the new PC.
3978 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
3981 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
3982 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
3985 tcg_temp_free_i32(cpsr
);
3986 /* Must exit loop to check un-masked IRQs */
3987 s
->base
.is_jmp
= DISAS_EXIT
;
3990 /* Generate an old-style exception return. Marks pc as dead. */
3991 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3993 gen_rfe(s
, pc
, load_cpu_field(spsr
));
3997 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3998 * only call the helper when running single threaded TCG code to ensure
3999 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4000 * just skip this instruction. Currently the SEV/SEVL instructions
4001 * which are *one* of many ways to wake the CPU from WFE are not
4002 * implemented so we can't sleep like WFI does.
4004 static void gen_nop_hint(DisasContext
*s
, int val
)
4007 /* When running in MTTCG we don't generate jumps to the yield and
4008 * WFE helpers as it won't affect the scheduling of other vCPUs.
4009 * If we wanted to more completely model WFE/SEV so we don't busy
4010 * spin unnecessarily we would need to do something more involved.
4013 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4014 gen_set_pc_im(s
, s
->pc
);
4015 s
->base
.is_jmp
= DISAS_YIELD
;
4019 gen_set_pc_im(s
, s
->pc
);
4020 s
->base
.is_jmp
= DISAS_WFI
;
4023 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4024 gen_set_pc_im(s
, s
->pc
);
4025 s
->base
.is_jmp
= DISAS_WFE
;
4030 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4036 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4038 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4041 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4042 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4043 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4048 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4051 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4052 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4053 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4058 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4059 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
4060 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
4061 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
4062 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
4064 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4065 switch ((size << 1) | u) { \
4067 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4070 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4073 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4076 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4079 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4082 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4084 default: return 1; \
4087 #define GEN_NEON_INTEGER_OP(name) do { \
4088 switch ((size << 1) | u) { \
4090 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4093 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4096 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4099 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4102 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4105 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4107 default: return 1; \
4110 static TCGv_i32
neon_load_scratch(int scratch
)
4112 TCGv_i32 tmp
= tcg_temp_new_i32();
4113 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4117 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4119 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4120 tcg_temp_free_i32(var
);
4123 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4127 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4129 gen_neon_dup_high16(tmp
);
4131 gen_neon_dup_low16(tmp
);
4134 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4139 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4143 if (!q
&& size
== 2) {
4146 pd
= vfp_reg_ptr(true, rd
);
4147 pm
= vfp_reg_ptr(true, rm
);
4151 gen_helper_neon_qunzip8(pd
, pm
);
4154 gen_helper_neon_qunzip16(pd
, pm
);
4157 gen_helper_neon_qunzip32(pd
, pm
);
4165 gen_helper_neon_unzip8(pd
, pm
);
4168 gen_helper_neon_unzip16(pd
, pm
);
4174 tcg_temp_free_ptr(pd
);
4175 tcg_temp_free_ptr(pm
);
4179 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4183 if (!q
&& size
== 2) {
4186 pd
= vfp_reg_ptr(true, rd
);
4187 pm
= vfp_reg_ptr(true, rm
);
4191 gen_helper_neon_qzip8(pd
, pm
);
4194 gen_helper_neon_qzip16(pd
, pm
);
4197 gen_helper_neon_qzip32(pd
, pm
);
4205 gen_helper_neon_zip8(pd
, pm
);
4208 gen_helper_neon_zip16(pd
, pm
);
4214 tcg_temp_free_ptr(pd
);
4215 tcg_temp_free_ptr(pm
);
4219 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4223 rd
= tcg_temp_new_i32();
4224 tmp
= tcg_temp_new_i32();
4226 tcg_gen_shli_i32(rd
, t0
, 8);
4227 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4228 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4229 tcg_gen_or_i32(rd
, rd
, tmp
);
4231 tcg_gen_shri_i32(t1
, t1
, 8);
4232 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4233 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4234 tcg_gen_or_i32(t1
, t1
, tmp
);
4235 tcg_gen_mov_i32(t0
, rd
);
4237 tcg_temp_free_i32(tmp
);
4238 tcg_temp_free_i32(rd
);
4241 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4245 rd
= tcg_temp_new_i32();
4246 tmp
= tcg_temp_new_i32();
4248 tcg_gen_shli_i32(rd
, t0
, 16);
4249 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4250 tcg_gen_or_i32(rd
, rd
, tmp
);
4251 tcg_gen_shri_i32(t1
, t1
, 16);
4252 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4253 tcg_gen_or_i32(t1
, t1
, tmp
);
4254 tcg_gen_mov_i32(t0
, rd
);
4256 tcg_temp_free_i32(tmp
);
4257 tcg_temp_free_i32(rd
);
4265 } const neon_ls_element_type
[11] = {
4279 /* Translate a NEON load/store element instruction. Return nonzero if the
4280 instruction is invalid. */
4281 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4301 /* FIXME: this access check should not take precedence over UNDEF
4302 * for invalid encodings; we will generate incorrect syndrome information
4303 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4305 if (s
->fp_excp_el
) {
4306 gen_exception_insn(s
, 4, EXCP_UDEF
,
4307 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
4311 if (!s
->vfp_enabled
)
4313 VFP_DREG_D(rd
, insn
);
4314 rn
= (insn
>> 16) & 0xf;
4316 load
= (insn
& (1 << 21)) != 0;
4317 endian
= s
->be_data
;
4318 mmu_idx
= get_mem_index(s
);
4319 if ((insn
& (1 << 23)) == 0) {
4320 /* Load store all elements. */
4321 op
= (insn
>> 8) & 0xf;
4322 size
= (insn
>> 6) & 3;
4325 /* Catch UNDEF cases for bad values of align field */
4328 if (((insn
>> 5) & 1) == 1) {
4333 if (((insn
>> 4) & 3) == 3) {
4340 nregs
= neon_ls_element_type
[op
].nregs
;
4341 interleave
= neon_ls_element_type
[op
].interleave
;
4342 spacing
= neon_ls_element_type
[op
].spacing
;
4343 if (size
== 3 && (interleave
| spacing
) != 1) {
4346 /* For our purposes, bytes are always little-endian. */
4350 /* Consecutive little-endian elements from a single register
4351 * can be promoted to a larger little-endian operation.
4353 if (interleave
== 1 && endian
== MO_LE
) {
4356 tmp64
= tcg_temp_new_i64();
4357 addr
= tcg_temp_new_i32();
4358 tmp2
= tcg_const_i32(1 << size
);
4359 load_reg_var(s
, addr
, rn
);
4360 for (reg
= 0; reg
< nregs
; reg
++) {
4361 for (n
= 0; n
< 8 >> size
; n
++) {
4363 for (xs
= 0; xs
< interleave
; xs
++) {
4364 int tt
= rd
+ reg
+ spacing
* xs
;
4367 gen_aa32_ld_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
4368 neon_store_element64(tt
, n
, size
, tmp64
);
4370 neon_load_element64(tmp64
, tt
, n
, size
);
4371 gen_aa32_st_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
4373 tcg_gen_add_i32(addr
, addr
, tmp2
);
4377 tcg_temp_free_i32(addr
);
4378 tcg_temp_free_i32(tmp2
);
4379 tcg_temp_free_i64(tmp64
);
4380 stride
= nregs
* interleave
* 8;
4382 size
= (insn
>> 10) & 3;
4384 /* Load single element to all lanes. */
4385 int a
= (insn
>> 4) & 1;
4389 size
= (insn
>> 6) & 3;
4390 nregs
= ((insn
>> 8) & 3) + 1;
4393 if (nregs
!= 4 || a
== 0) {
4396 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4399 if (nregs
== 1 && a
== 1 && size
== 0) {
4402 if (nregs
== 3 && a
== 1) {
4405 addr
= tcg_temp_new_i32();
4406 load_reg_var(s
, addr
, rn
);
4408 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
4409 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
4411 stride
= (insn
& (1 << 5)) ? 2 : 1;
4412 vec_size
= nregs
== 1 ? stride
* 8 : 8;
4414 tmp
= tcg_temp_new_i32();
4415 for (reg
= 0; reg
< nregs
; reg
++) {
4416 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
4418 if ((rd
& 1) && vec_size
== 16) {
4419 /* We cannot write 16 bytes at once because the
4420 * destination is unaligned.
4422 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
4424 tcg_gen_gvec_mov(0, neon_reg_offset(rd
+ 1, 0),
4425 neon_reg_offset(rd
, 0), 8, 8);
4427 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
4428 vec_size
, vec_size
, tmp
);
4430 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4433 tcg_temp_free_i32(tmp
);
4434 tcg_temp_free_i32(addr
);
4435 stride
= (1 << size
) * nregs
;
4437 /* Single element. */
4438 int idx
= (insn
>> 4) & 0xf;
4442 reg_idx
= (insn
>> 5) & 7;
4446 reg_idx
= (insn
>> 6) & 3;
4447 stride
= (insn
& (1 << 5)) ? 2 : 1;
4450 reg_idx
= (insn
>> 7) & 1;
4451 stride
= (insn
& (1 << 6)) ? 2 : 1;
4456 nregs
= ((insn
>> 8) & 3) + 1;
4457 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4460 if (((idx
& (1 << size
)) != 0) ||
4461 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4466 if ((idx
& 1) != 0) {
4471 if (size
== 2 && (idx
& 2) != 0) {
4476 if ((size
== 2) && ((idx
& 3) == 3)) {
4483 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4484 /* Attempts to write off the end of the register file
4485 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4486 * the neon_load_reg() would write off the end of the array.
4490 tmp
= tcg_temp_new_i32();
4491 addr
= tcg_temp_new_i32();
4492 load_reg_var(s
, addr
, rn
);
4493 for (reg
= 0; reg
< nregs
; reg
++) {
4495 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
4497 neon_store_element(rd
, reg_idx
, size
, tmp
);
4498 } else { /* Store */
4499 neon_load_element(tmp
, rd
, reg_idx
, size
);
4500 gen_aa32_st_i32(s
, tmp
, addr
, get_mem_index(s
),
4504 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4506 tcg_temp_free_i32(addr
);
4507 tcg_temp_free_i32(tmp
);
4508 stride
= nregs
* (1 << size
);
4514 base
= load_reg(s
, rn
);
4516 tcg_gen_addi_i32(base
, base
, stride
);
4519 index
= load_reg(s
, rm
);
4520 tcg_gen_add_i32(base
, base
, index
);
4521 tcg_temp_free_i32(index
);
4523 store_reg(s
, rn
, base
);
4528 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4531 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4532 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4533 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4538 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4541 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4542 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4543 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4548 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4551 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4552 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4553 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4558 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4561 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4562 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4563 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4568 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4574 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4575 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4580 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4581 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4588 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4589 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4594 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4595 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4602 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4606 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4607 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4608 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4613 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4614 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4615 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4619 tcg_temp_free_i32(src
);
4622 static inline void gen_neon_addl(int size
)
4625 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4626 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4627 case 2: tcg_gen_add_i64(CPU_V001
); break;
4632 static inline void gen_neon_subl(int size
)
4635 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4636 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4637 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4642 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4645 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4646 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4648 tcg_gen_neg_i64(var
, var
);
4654 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4657 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4658 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4663 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4668 switch ((size
<< 1) | u
) {
4669 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4670 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4671 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4672 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4674 tmp
= gen_muls_i64_i32(a
, b
);
4675 tcg_gen_mov_i64(dest
, tmp
);
4676 tcg_temp_free_i64(tmp
);
4679 tmp
= gen_mulu_i64_i32(a
, b
);
4680 tcg_gen_mov_i64(dest
, tmp
);
4681 tcg_temp_free_i64(tmp
);
4686 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4687 Don't forget to clean them now. */
4689 tcg_temp_free_i32(a
);
4690 tcg_temp_free_i32(b
);
4694 static void gen_neon_narrow_op(int op
, int u
, int size
,
4695 TCGv_i32 dest
, TCGv_i64 src
)
4699 gen_neon_unarrow_sats(size
, dest
, src
);
4701 gen_neon_narrow(size
, dest
, src
);
4705 gen_neon_narrow_satu(size
, dest
, src
);
4707 gen_neon_narrow_sats(size
, dest
, src
);
4712 /* Symbolic constants for op fields for Neon 3-register same-length.
4713 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4716 #define NEON_3R_VHADD 0
4717 #define NEON_3R_VQADD 1
4718 #define NEON_3R_VRHADD 2
4719 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4720 #define NEON_3R_VHSUB 4
4721 #define NEON_3R_VQSUB 5
4722 #define NEON_3R_VCGT 6
4723 #define NEON_3R_VCGE 7
4724 #define NEON_3R_VSHL 8
4725 #define NEON_3R_VQSHL 9
4726 #define NEON_3R_VRSHL 10
4727 #define NEON_3R_VQRSHL 11
4728 #define NEON_3R_VMAX 12
4729 #define NEON_3R_VMIN 13
4730 #define NEON_3R_VABD 14
4731 #define NEON_3R_VABA 15
4732 #define NEON_3R_VADD_VSUB 16
4733 #define NEON_3R_VTST_VCEQ 17
4734 #define NEON_3R_VML 18 /* VMLA, VMLS */
4735 #define NEON_3R_VMUL 19
4736 #define NEON_3R_VPMAX 20
4737 #define NEON_3R_VPMIN 21
4738 #define NEON_3R_VQDMULH_VQRDMULH 22
4739 #define NEON_3R_VPADD_VQRDMLAH 23
4740 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4741 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
4742 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4743 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4744 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4745 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4746 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4747 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4749 static const uint8_t neon_3r_sizes
[] = {
4750 [NEON_3R_VHADD
] = 0x7,
4751 [NEON_3R_VQADD
] = 0xf,
4752 [NEON_3R_VRHADD
] = 0x7,
4753 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4754 [NEON_3R_VHSUB
] = 0x7,
4755 [NEON_3R_VQSUB
] = 0xf,
4756 [NEON_3R_VCGT
] = 0x7,
4757 [NEON_3R_VCGE
] = 0x7,
4758 [NEON_3R_VSHL
] = 0xf,
4759 [NEON_3R_VQSHL
] = 0xf,
4760 [NEON_3R_VRSHL
] = 0xf,
4761 [NEON_3R_VQRSHL
] = 0xf,
4762 [NEON_3R_VMAX
] = 0x7,
4763 [NEON_3R_VMIN
] = 0x7,
4764 [NEON_3R_VABD
] = 0x7,
4765 [NEON_3R_VABA
] = 0x7,
4766 [NEON_3R_VADD_VSUB
] = 0xf,
4767 [NEON_3R_VTST_VCEQ
] = 0x7,
4768 [NEON_3R_VML
] = 0x7,
4769 [NEON_3R_VMUL
] = 0x7,
4770 [NEON_3R_VPMAX
] = 0x7,
4771 [NEON_3R_VPMIN
] = 0x7,
4772 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4773 [NEON_3R_VPADD_VQRDMLAH
] = 0x7,
4774 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4775 [NEON_3R_VFM_VQRDMLSH
] = 0x7, /* For VFM, size bit 1 encodes op */
4776 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4777 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4778 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4779 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4780 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4781 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4784 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4785 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4788 #define NEON_2RM_VREV64 0
4789 #define NEON_2RM_VREV32 1
4790 #define NEON_2RM_VREV16 2
4791 #define NEON_2RM_VPADDL 4
4792 #define NEON_2RM_VPADDL_U 5
4793 #define NEON_2RM_AESE 6 /* Includes AESD */
4794 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4795 #define NEON_2RM_VCLS 8
4796 #define NEON_2RM_VCLZ 9
4797 #define NEON_2RM_VCNT 10
4798 #define NEON_2RM_VMVN 11
4799 #define NEON_2RM_VPADAL 12
4800 #define NEON_2RM_VPADAL_U 13
4801 #define NEON_2RM_VQABS 14
4802 #define NEON_2RM_VQNEG 15
4803 #define NEON_2RM_VCGT0 16
4804 #define NEON_2RM_VCGE0 17
4805 #define NEON_2RM_VCEQ0 18
4806 #define NEON_2RM_VCLE0 19
4807 #define NEON_2RM_VCLT0 20
4808 #define NEON_2RM_SHA1H 21
4809 #define NEON_2RM_VABS 22
4810 #define NEON_2RM_VNEG 23
4811 #define NEON_2RM_VCGT0_F 24
4812 #define NEON_2RM_VCGE0_F 25
4813 #define NEON_2RM_VCEQ0_F 26
4814 #define NEON_2RM_VCLE0_F 27
4815 #define NEON_2RM_VCLT0_F 28
4816 #define NEON_2RM_VABS_F 30
4817 #define NEON_2RM_VNEG_F 31
4818 #define NEON_2RM_VSWP 32
4819 #define NEON_2RM_VTRN 33
4820 #define NEON_2RM_VUZP 34
4821 #define NEON_2RM_VZIP 35
4822 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4823 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4824 #define NEON_2RM_VSHLL 38
4825 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4826 #define NEON_2RM_VRINTN 40
4827 #define NEON_2RM_VRINTX 41
4828 #define NEON_2RM_VRINTA 42
4829 #define NEON_2RM_VRINTZ 43
4830 #define NEON_2RM_VCVT_F16_F32 44
4831 #define NEON_2RM_VRINTM 45
4832 #define NEON_2RM_VCVT_F32_F16 46
4833 #define NEON_2RM_VRINTP 47
4834 #define NEON_2RM_VCVTAU 48
4835 #define NEON_2RM_VCVTAS 49
4836 #define NEON_2RM_VCVTNU 50
4837 #define NEON_2RM_VCVTNS 51
4838 #define NEON_2RM_VCVTPU 52
4839 #define NEON_2RM_VCVTPS 53
4840 #define NEON_2RM_VCVTMU 54
4841 #define NEON_2RM_VCVTMS 55
4842 #define NEON_2RM_VRECPE 56
4843 #define NEON_2RM_VRSQRTE 57
4844 #define NEON_2RM_VRECPE_F 58
4845 #define NEON_2RM_VRSQRTE_F 59
4846 #define NEON_2RM_VCVT_FS 60
4847 #define NEON_2RM_VCVT_FU 61
4848 #define NEON_2RM_VCVT_SF 62
4849 #define NEON_2RM_VCVT_UF 63
4851 static int neon_2rm_is_float_op(int op
)
4853 /* Return true if this neon 2reg-misc op is float-to-float */
4854 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4855 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4856 op
== NEON_2RM_VRINTM
||
4857 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4858 op
>= NEON_2RM_VRECPE_F
);
4861 static bool neon_2rm_is_v8_op(int op
)
4863 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4865 case NEON_2RM_VRINTN
:
4866 case NEON_2RM_VRINTA
:
4867 case NEON_2RM_VRINTM
:
4868 case NEON_2RM_VRINTP
:
4869 case NEON_2RM_VRINTZ
:
4870 case NEON_2RM_VRINTX
:
4871 case NEON_2RM_VCVTAU
:
4872 case NEON_2RM_VCVTAS
:
4873 case NEON_2RM_VCVTNU
:
4874 case NEON_2RM_VCVTNS
:
4875 case NEON_2RM_VCVTPU
:
4876 case NEON_2RM_VCVTPS
:
4877 case NEON_2RM_VCVTMU
:
4878 case NEON_2RM_VCVTMS
:
4885 /* Each entry in this array has bit n set if the insn allows
4886 * size value n (otherwise it will UNDEF). Since unallocated
4887 * op values will have no bits set they always UNDEF.
4889 static const uint8_t neon_2rm_sizes
[] = {
4890 [NEON_2RM_VREV64
] = 0x7,
4891 [NEON_2RM_VREV32
] = 0x3,
4892 [NEON_2RM_VREV16
] = 0x1,
4893 [NEON_2RM_VPADDL
] = 0x7,
4894 [NEON_2RM_VPADDL_U
] = 0x7,
4895 [NEON_2RM_AESE
] = 0x1,
4896 [NEON_2RM_AESMC
] = 0x1,
4897 [NEON_2RM_VCLS
] = 0x7,
4898 [NEON_2RM_VCLZ
] = 0x7,
4899 [NEON_2RM_VCNT
] = 0x1,
4900 [NEON_2RM_VMVN
] = 0x1,
4901 [NEON_2RM_VPADAL
] = 0x7,
4902 [NEON_2RM_VPADAL_U
] = 0x7,
4903 [NEON_2RM_VQABS
] = 0x7,
4904 [NEON_2RM_VQNEG
] = 0x7,
4905 [NEON_2RM_VCGT0
] = 0x7,
4906 [NEON_2RM_VCGE0
] = 0x7,
4907 [NEON_2RM_VCEQ0
] = 0x7,
4908 [NEON_2RM_VCLE0
] = 0x7,
4909 [NEON_2RM_VCLT0
] = 0x7,
4910 [NEON_2RM_SHA1H
] = 0x4,
4911 [NEON_2RM_VABS
] = 0x7,
4912 [NEON_2RM_VNEG
] = 0x7,
4913 [NEON_2RM_VCGT0_F
] = 0x4,
4914 [NEON_2RM_VCGE0_F
] = 0x4,
4915 [NEON_2RM_VCEQ0_F
] = 0x4,
4916 [NEON_2RM_VCLE0_F
] = 0x4,
4917 [NEON_2RM_VCLT0_F
] = 0x4,
4918 [NEON_2RM_VABS_F
] = 0x4,
4919 [NEON_2RM_VNEG_F
] = 0x4,
4920 [NEON_2RM_VSWP
] = 0x1,
4921 [NEON_2RM_VTRN
] = 0x7,
4922 [NEON_2RM_VUZP
] = 0x7,
4923 [NEON_2RM_VZIP
] = 0x7,
4924 [NEON_2RM_VMOVN
] = 0x7,
4925 [NEON_2RM_VQMOVN
] = 0x7,
4926 [NEON_2RM_VSHLL
] = 0x7,
4927 [NEON_2RM_SHA1SU1
] = 0x4,
4928 [NEON_2RM_VRINTN
] = 0x4,
4929 [NEON_2RM_VRINTX
] = 0x4,
4930 [NEON_2RM_VRINTA
] = 0x4,
4931 [NEON_2RM_VRINTZ
] = 0x4,
4932 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4933 [NEON_2RM_VRINTM
] = 0x4,
4934 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4935 [NEON_2RM_VRINTP
] = 0x4,
4936 [NEON_2RM_VCVTAU
] = 0x4,
4937 [NEON_2RM_VCVTAS
] = 0x4,
4938 [NEON_2RM_VCVTNU
] = 0x4,
4939 [NEON_2RM_VCVTNS
] = 0x4,
4940 [NEON_2RM_VCVTPU
] = 0x4,
4941 [NEON_2RM_VCVTPS
] = 0x4,
4942 [NEON_2RM_VCVTMU
] = 0x4,
4943 [NEON_2RM_VCVTMS
] = 0x4,
4944 [NEON_2RM_VRECPE
] = 0x4,
4945 [NEON_2RM_VRSQRTE
] = 0x4,
4946 [NEON_2RM_VRECPE_F
] = 0x4,
4947 [NEON_2RM_VRSQRTE_F
] = 0x4,
4948 [NEON_2RM_VCVT_FS
] = 0x4,
4949 [NEON_2RM_VCVT_FU
] = 0x4,
4950 [NEON_2RM_VCVT_SF
] = 0x4,
4951 [NEON_2RM_VCVT_UF
] = 0x4,
4955 /* Expand v8.1 simd helper. */
4956 static int do_v81_helper(DisasContext
*s
, gen_helper_gvec_3_ptr
*fn
,
4957 int q
, int rd
, int rn
, int rm
)
4959 if (dc_isar_feature(aa32_rdm
, s
)) {
4960 int opr_sz
= (1 + q
) * 8;
4961 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
4962 vfp_reg_offset(1, rn
),
4963 vfp_reg_offset(1, rm
), cpu_env
,
4964 opr_sz
, opr_sz
, 0, fn
);
4970 static void gen_ssra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4972 tcg_gen_vec_sar8i_i64(a
, a
, shift
);
4973 tcg_gen_vec_add8_i64(d
, d
, a
);
4976 static void gen_ssra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4978 tcg_gen_vec_sar16i_i64(a
, a
, shift
);
4979 tcg_gen_vec_add16_i64(d
, d
, a
);
4982 static void gen_ssra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4984 tcg_gen_sari_i32(a
, a
, shift
);
4985 tcg_gen_add_i32(d
, d
, a
);
4988 static void gen_ssra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4990 tcg_gen_sari_i64(a
, a
, shift
);
4991 tcg_gen_add_i64(d
, d
, a
);
4994 static void gen_ssra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4996 tcg_gen_sari_vec(vece
, a
, a
, sh
);
4997 tcg_gen_add_vec(vece
, d
, d
, a
);
5000 static const TCGOpcode vecop_list_ssra
[] = {
5001 INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
5004 const GVecGen2i ssra_op
[4] = {
5005 { .fni8
= gen_ssra8_i64
,
5006 .fniv
= gen_ssra_vec
,
5008 .opt_opc
= vecop_list_ssra
,
5010 { .fni8
= gen_ssra16_i64
,
5011 .fniv
= gen_ssra_vec
,
5013 .opt_opc
= vecop_list_ssra
,
5015 { .fni4
= gen_ssra32_i32
,
5016 .fniv
= gen_ssra_vec
,
5018 .opt_opc
= vecop_list_ssra
,
5020 { .fni8
= gen_ssra64_i64
,
5021 .fniv
= gen_ssra_vec
,
5022 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5023 .opt_opc
= vecop_list_ssra
,
5028 static void gen_usra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5030 tcg_gen_vec_shr8i_i64(a
, a
, shift
);
5031 tcg_gen_vec_add8_i64(d
, d
, a
);
5034 static void gen_usra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5036 tcg_gen_vec_shr16i_i64(a
, a
, shift
);
5037 tcg_gen_vec_add16_i64(d
, d
, a
);
5040 static void gen_usra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5042 tcg_gen_shri_i32(a
, a
, shift
);
5043 tcg_gen_add_i32(d
, d
, a
);
5046 static void gen_usra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5048 tcg_gen_shri_i64(a
, a
, shift
);
5049 tcg_gen_add_i64(d
, d
, a
);
5052 static void gen_usra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5054 tcg_gen_shri_vec(vece
, a
, a
, sh
);
5055 tcg_gen_add_vec(vece
, d
, d
, a
);
5058 static const TCGOpcode vecop_list_usra
[] = {
5059 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
5062 const GVecGen2i usra_op
[4] = {
5063 { .fni8
= gen_usra8_i64
,
5064 .fniv
= gen_usra_vec
,
5066 .opt_opc
= vecop_list_usra
,
5068 { .fni8
= gen_usra16_i64
,
5069 .fniv
= gen_usra_vec
,
5071 .opt_opc
= vecop_list_usra
,
5073 { .fni4
= gen_usra32_i32
,
5074 .fniv
= gen_usra_vec
,
5076 .opt_opc
= vecop_list_usra
,
5078 { .fni8
= gen_usra64_i64
,
5079 .fniv
= gen_usra_vec
,
5080 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5082 .opt_opc
= vecop_list_usra
,
5086 static void gen_shr8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5088 uint64_t mask
= dup_const(MO_8
, 0xff >> shift
);
5089 TCGv_i64 t
= tcg_temp_new_i64();
5091 tcg_gen_shri_i64(t
, a
, shift
);
5092 tcg_gen_andi_i64(t
, t
, mask
);
5093 tcg_gen_andi_i64(d
, d
, ~mask
);
5094 tcg_gen_or_i64(d
, d
, t
);
5095 tcg_temp_free_i64(t
);
5098 static void gen_shr16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5100 uint64_t mask
= dup_const(MO_16
, 0xffff >> shift
);
5101 TCGv_i64 t
= tcg_temp_new_i64();
5103 tcg_gen_shri_i64(t
, a
, shift
);
5104 tcg_gen_andi_i64(t
, t
, mask
);
5105 tcg_gen_andi_i64(d
, d
, ~mask
);
5106 tcg_gen_or_i64(d
, d
, t
);
5107 tcg_temp_free_i64(t
);
5110 static void gen_shr32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5112 tcg_gen_shri_i32(a
, a
, shift
);
5113 tcg_gen_deposit_i32(d
, d
, a
, 0, 32 - shift
);
5116 static void gen_shr64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5118 tcg_gen_shri_i64(a
, a
, shift
);
5119 tcg_gen_deposit_i64(d
, d
, a
, 0, 64 - shift
);
5122 static void gen_shr_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5125 tcg_gen_mov_vec(d
, a
);
5127 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
5128 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
5130 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK((8 << vece
) - sh
, sh
));
5131 tcg_gen_shri_vec(vece
, t
, a
, sh
);
5132 tcg_gen_and_vec(vece
, d
, d
, m
);
5133 tcg_gen_or_vec(vece
, d
, d
, t
);
5135 tcg_temp_free_vec(t
);
5136 tcg_temp_free_vec(m
);
5140 static const TCGOpcode vecop_list_sri
[] = { INDEX_op_shri_vec
, 0 };
5142 const GVecGen2i sri_op
[4] = {
5143 { .fni8
= gen_shr8_ins_i64
,
5144 .fniv
= gen_shr_ins_vec
,
5146 .opt_opc
= vecop_list_sri
,
5148 { .fni8
= gen_shr16_ins_i64
,
5149 .fniv
= gen_shr_ins_vec
,
5151 .opt_opc
= vecop_list_sri
,
5153 { .fni4
= gen_shr32_ins_i32
,
5154 .fniv
= gen_shr_ins_vec
,
5156 .opt_opc
= vecop_list_sri
,
5158 { .fni8
= gen_shr64_ins_i64
,
5159 .fniv
= gen_shr_ins_vec
,
5160 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5162 .opt_opc
= vecop_list_sri
,
5166 static void gen_shl8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5168 uint64_t mask
= dup_const(MO_8
, 0xff << shift
);
5169 TCGv_i64 t
= tcg_temp_new_i64();
5171 tcg_gen_shli_i64(t
, a
, shift
);
5172 tcg_gen_andi_i64(t
, t
, mask
);
5173 tcg_gen_andi_i64(d
, d
, ~mask
);
5174 tcg_gen_or_i64(d
, d
, t
);
5175 tcg_temp_free_i64(t
);
5178 static void gen_shl16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5180 uint64_t mask
= dup_const(MO_16
, 0xffff << shift
);
5181 TCGv_i64 t
= tcg_temp_new_i64();
5183 tcg_gen_shli_i64(t
, a
, shift
);
5184 tcg_gen_andi_i64(t
, t
, mask
);
5185 tcg_gen_andi_i64(d
, d
, ~mask
);
5186 tcg_gen_or_i64(d
, d
, t
);
5187 tcg_temp_free_i64(t
);
5190 static void gen_shl32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5192 tcg_gen_deposit_i32(d
, d
, a
, shift
, 32 - shift
);
5195 static void gen_shl64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5197 tcg_gen_deposit_i64(d
, d
, a
, shift
, 64 - shift
);
5200 static void gen_shl_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5203 tcg_gen_mov_vec(d
, a
);
5205 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
5206 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
5208 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK(0, sh
));
5209 tcg_gen_shli_vec(vece
, t
, a
, sh
);
5210 tcg_gen_and_vec(vece
, d
, d
, m
);
5211 tcg_gen_or_vec(vece
, d
, d
, t
);
5213 tcg_temp_free_vec(t
);
5214 tcg_temp_free_vec(m
);
5218 static const TCGOpcode vecop_list_sli
[] = { INDEX_op_shli_vec
, 0 };
5220 const GVecGen2i sli_op
[4] = {
5221 { .fni8
= gen_shl8_ins_i64
,
5222 .fniv
= gen_shl_ins_vec
,
5224 .opt_opc
= vecop_list_sli
,
5226 { .fni8
= gen_shl16_ins_i64
,
5227 .fniv
= gen_shl_ins_vec
,
5229 .opt_opc
= vecop_list_sli
,
5231 { .fni4
= gen_shl32_ins_i32
,
5232 .fniv
= gen_shl_ins_vec
,
5234 .opt_opc
= vecop_list_sli
,
5236 { .fni8
= gen_shl64_ins_i64
,
5237 .fniv
= gen_shl_ins_vec
,
5238 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5240 .opt_opc
= vecop_list_sli
,
5244 static void gen_mla8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5246 gen_helper_neon_mul_u8(a
, a
, b
);
5247 gen_helper_neon_add_u8(d
, d
, a
);
5250 static void gen_mls8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5252 gen_helper_neon_mul_u8(a
, a
, b
);
5253 gen_helper_neon_sub_u8(d
, d
, a
);
5256 static void gen_mla16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5258 gen_helper_neon_mul_u16(a
, a
, b
);
5259 gen_helper_neon_add_u16(d
, d
, a
);
5262 static void gen_mls16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5264 gen_helper_neon_mul_u16(a
, a
, b
);
5265 gen_helper_neon_sub_u16(d
, d
, a
);
5268 static void gen_mla32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5270 tcg_gen_mul_i32(a
, a
, b
);
5271 tcg_gen_add_i32(d
, d
, a
);
5274 static void gen_mls32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5276 tcg_gen_mul_i32(a
, a
, b
);
5277 tcg_gen_sub_i32(d
, d
, a
);
5280 static void gen_mla64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5282 tcg_gen_mul_i64(a
, a
, b
);
5283 tcg_gen_add_i64(d
, d
, a
);
5286 static void gen_mls64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5288 tcg_gen_mul_i64(a
, a
, b
);
5289 tcg_gen_sub_i64(d
, d
, a
);
5292 static void gen_mla_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5294 tcg_gen_mul_vec(vece
, a
, a
, b
);
5295 tcg_gen_add_vec(vece
, d
, d
, a
);
5298 static void gen_mls_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5300 tcg_gen_mul_vec(vece
, a
, a
, b
);
5301 tcg_gen_sub_vec(vece
, d
, d
, a
);
5304 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
5305 * these tables are shared with AArch64 which does support them.
5308 static const TCGOpcode vecop_list_mla
[] = {
5309 INDEX_op_mul_vec
, INDEX_op_add_vec
, 0
5312 static const TCGOpcode vecop_list_mls
[] = {
5313 INDEX_op_mul_vec
, INDEX_op_sub_vec
, 0
5316 const GVecGen3 mla_op
[4] = {
5317 { .fni4
= gen_mla8_i32
,
5318 .fniv
= gen_mla_vec
,
5320 .opt_opc
= vecop_list_mla
,
5322 { .fni4
= gen_mla16_i32
,
5323 .fniv
= gen_mla_vec
,
5325 .opt_opc
= vecop_list_mla
,
5327 { .fni4
= gen_mla32_i32
,
5328 .fniv
= gen_mla_vec
,
5330 .opt_opc
= vecop_list_mla
,
5332 { .fni8
= gen_mla64_i64
,
5333 .fniv
= gen_mla_vec
,
5334 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5336 .opt_opc
= vecop_list_mla
,
5340 const GVecGen3 mls_op
[4] = {
5341 { .fni4
= gen_mls8_i32
,
5342 .fniv
= gen_mls_vec
,
5344 .opt_opc
= vecop_list_mls
,
5346 { .fni4
= gen_mls16_i32
,
5347 .fniv
= gen_mls_vec
,
5349 .opt_opc
= vecop_list_mls
,
5351 { .fni4
= gen_mls32_i32
,
5352 .fniv
= gen_mls_vec
,
5354 .opt_opc
= vecop_list_mls
,
5356 { .fni8
= gen_mls64_i64
,
5357 .fniv
= gen_mls_vec
,
5358 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5360 .opt_opc
= vecop_list_mls
,
5364 /* CMTST : test is "if (X & Y != 0)". */
5365 static void gen_cmtst_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5367 tcg_gen_and_i32(d
, a
, b
);
5368 tcg_gen_setcondi_i32(TCG_COND_NE
, d
, d
, 0);
5369 tcg_gen_neg_i32(d
, d
);
5372 void gen_cmtst_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5374 tcg_gen_and_i64(d
, a
, b
);
5375 tcg_gen_setcondi_i64(TCG_COND_NE
, d
, d
, 0);
5376 tcg_gen_neg_i64(d
, d
);
5379 static void gen_cmtst_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5381 tcg_gen_and_vec(vece
, d
, a
, b
);
5382 tcg_gen_dupi_vec(vece
, a
, 0);
5383 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, d
, d
, a
);
5386 static const TCGOpcode vecop_list_cmtst
[] = { INDEX_op_cmp_vec
, 0 };
5388 const GVecGen3 cmtst_op
[4] = {
5389 { .fni4
= gen_helper_neon_tst_u8
,
5390 .fniv
= gen_cmtst_vec
,
5391 .opt_opc
= vecop_list_cmtst
,
5393 { .fni4
= gen_helper_neon_tst_u16
,
5394 .fniv
= gen_cmtst_vec
,
5395 .opt_opc
= vecop_list_cmtst
,
5397 { .fni4
= gen_cmtst_i32
,
5398 .fniv
= gen_cmtst_vec
,
5399 .opt_opc
= vecop_list_cmtst
,
5401 { .fni8
= gen_cmtst_i64
,
5402 .fniv
= gen_cmtst_vec
,
5403 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5404 .opt_opc
= vecop_list_cmtst
,
5408 static void gen_uqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5409 TCGv_vec a
, TCGv_vec b
)
5411 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5412 tcg_gen_add_vec(vece
, x
, a
, b
);
5413 tcg_gen_usadd_vec(vece
, t
, a
, b
);
5414 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5415 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5416 tcg_temp_free_vec(x
);
5419 static const TCGOpcode vecop_list_uqadd
[] = {
5420 INDEX_op_usadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
5423 const GVecGen4 uqadd_op
[4] = {
5424 { .fniv
= gen_uqadd_vec
,
5425 .fno
= gen_helper_gvec_uqadd_b
,
5427 .opt_opc
= vecop_list_uqadd
,
5429 { .fniv
= gen_uqadd_vec
,
5430 .fno
= gen_helper_gvec_uqadd_h
,
5432 .opt_opc
= vecop_list_uqadd
,
5434 { .fniv
= gen_uqadd_vec
,
5435 .fno
= gen_helper_gvec_uqadd_s
,
5437 .opt_opc
= vecop_list_uqadd
,
5439 { .fniv
= gen_uqadd_vec
,
5440 .fno
= gen_helper_gvec_uqadd_d
,
5442 .opt_opc
= vecop_list_uqadd
,
5446 static void gen_sqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5447 TCGv_vec a
, TCGv_vec b
)
5449 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5450 tcg_gen_add_vec(vece
, x
, a
, b
);
5451 tcg_gen_ssadd_vec(vece
, t
, a
, b
);
5452 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5453 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5454 tcg_temp_free_vec(x
);
5457 static const TCGOpcode vecop_list_sqadd
[] = {
5458 INDEX_op_ssadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
5461 const GVecGen4 sqadd_op
[4] = {
5462 { .fniv
= gen_sqadd_vec
,
5463 .fno
= gen_helper_gvec_sqadd_b
,
5464 .opt_opc
= vecop_list_sqadd
,
5467 { .fniv
= gen_sqadd_vec
,
5468 .fno
= gen_helper_gvec_sqadd_h
,
5469 .opt_opc
= vecop_list_sqadd
,
5472 { .fniv
= gen_sqadd_vec
,
5473 .fno
= gen_helper_gvec_sqadd_s
,
5474 .opt_opc
= vecop_list_sqadd
,
5477 { .fniv
= gen_sqadd_vec
,
5478 .fno
= gen_helper_gvec_sqadd_d
,
5479 .opt_opc
= vecop_list_sqadd
,
5484 static void gen_uqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5485 TCGv_vec a
, TCGv_vec b
)
5487 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5488 tcg_gen_sub_vec(vece
, x
, a
, b
);
5489 tcg_gen_ussub_vec(vece
, t
, a
, b
);
5490 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5491 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5492 tcg_temp_free_vec(x
);
5495 static const TCGOpcode vecop_list_uqsub
[] = {
5496 INDEX_op_ussub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
5499 const GVecGen4 uqsub_op
[4] = {
5500 { .fniv
= gen_uqsub_vec
,
5501 .fno
= gen_helper_gvec_uqsub_b
,
5502 .opt_opc
= vecop_list_uqsub
,
5505 { .fniv
= gen_uqsub_vec
,
5506 .fno
= gen_helper_gvec_uqsub_h
,
5507 .opt_opc
= vecop_list_uqsub
,
5510 { .fniv
= gen_uqsub_vec
,
5511 .fno
= gen_helper_gvec_uqsub_s
,
5512 .opt_opc
= vecop_list_uqsub
,
5515 { .fniv
= gen_uqsub_vec
,
5516 .fno
= gen_helper_gvec_uqsub_d
,
5517 .opt_opc
= vecop_list_uqsub
,
5522 static void gen_sqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5523 TCGv_vec a
, TCGv_vec b
)
5525 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5526 tcg_gen_sub_vec(vece
, x
, a
, b
);
5527 tcg_gen_sssub_vec(vece
, t
, a
, b
);
5528 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5529 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5530 tcg_temp_free_vec(x
);
5533 static const TCGOpcode vecop_list_sqsub
[] = {
5534 INDEX_op_sssub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
5537 const GVecGen4 sqsub_op
[4] = {
5538 { .fniv
= gen_sqsub_vec
,
5539 .fno
= gen_helper_gvec_sqsub_b
,
5540 .opt_opc
= vecop_list_sqsub
,
5543 { .fniv
= gen_sqsub_vec
,
5544 .fno
= gen_helper_gvec_sqsub_h
,
5545 .opt_opc
= vecop_list_sqsub
,
5548 { .fniv
= gen_sqsub_vec
,
5549 .fno
= gen_helper_gvec_sqsub_s
,
5550 .opt_opc
= vecop_list_sqsub
,
5553 { .fniv
= gen_sqsub_vec
,
5554 .fno
= gen_helper_gvec_sqsub_d
,
5555 .opt_opc
= vecop_list_sqsub
,
5560 /* Translate a NEON data processing instruction. Return nonzero if the
5561 instruction is invalid.
5562 We process data in a mixture of 32-bit and 64-bit chunks.
5563 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5565 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5569 int rd
, rn
, rm
, rd_ofs
, rn_ofs
, rm_ofs
;
5578 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5579 TCGv_ptr ptr1
, ptr2
, ptr3
;
5582 /* FIXME: this access check should not take precedence over UNDEF
5583 * for invalid encodings; we will generate incorrect syndrome information
5584 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5586 if (s
->fp_excp_el
) {
5587 gen_exception_insn(s
, 4, EXCP_UDEF
,
5588 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
5592 if (!s
->vfp_enabled
)
5594 q
= (insn
& (1 << 6)) != 0;
5595 u
= (insn
>> 24) & 1;
5596 VFP_DREG_D(rd
, insn
);
5597 VFP_DREG_N(rn
, insn
);
5598 VFP_DREG_M(rm
, insn
);
5599 size
= (insn
>> 20) & 3;
5600 vec_size
= q
? 16 : 8;
5601 rd_ofs
= neon_reg_offset(rd
, 0);
5602 rn_ofs
= neon_reg_offset(rn
, 0);
5603 rm_ofs
= neon_reg_offset(rm
, 0);
5605 if ((insn
& (1 << 23)) == 0) {
5606 /* Three register same length. */
5607 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5608 /* Catch invalid op and bad size combinations: UNDEF */
5609 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5612 /* All insns of this form UNDEF for either this condition or the
5613 * superset of cases "Q==1"; we catch the latter later.
5615 if (q
&& ((rd
| rn
| rm
) & 1)) {
5620 /* The SHA-1/SHA-256 3-register instructions require special
5621 * treatment here, as their size field is overloaded as an
5622 * op type selector, and they all consume their input in a
5628 if (!u
) { /* SHA-1 */
5629 if (!dc_isar_feature(aa32_sha1
, s
)) {
5632 ptr1
= vfp_reg_ptr(true, rd
);
5633 ptr2
= vfp_reg_ptr(true, rn
);
5634 ptr3
= vfp_reg_ptr(true, rm
);
5635 tmp4
= tcg_const_i32(size
);
5636 gen_helper_crypto_sha1_3reg(ptr1
, ptr2
, ptr3
, tmp4
);
5637 tcg_temp_free_i32(tmp4
);
5638 } else { /* SHA-256 */
5639 if (!dc_isar_feature(aa32_sha2
, s
) || size
== 3) {
5642 ptr1
= vfp_reg_ptr(true, rd
);
5643 ptr2
= vfp_reg_ptr(true, rn
);
5644 ptr3
= vfp_reg_ptr(true, rm
);
5647 gen_helper_crypto_sha256h(ptr1
, ptr2
, ptr3
);
5650 gen_helper_crypto_sha256h2(ptr1
, ptr2
, ptr3
);
5653 gen_helper_crypto_sha256su1(ptr1
, ptr2
, ptr3
);
5657 tcg_temp_free_ptr(ptr1
);
5658 tcg_temp_free_ptr(ptr2
);
5659 tcg_temp_free_ptr(ptr3
);
5662 case NEON_3R_VPADD_VQRDMLAH
:
5669 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s16
,
5672 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s32
,
5677 case NEON_3R_VFM_VQRDMLSH
:
5688 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s16
,
5691 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s32
,
5696 case NEON_3R_LOGIC
: /* Logic ops. */
5697 switch ((u
<< 2) | size
) {
5699 tcg_gen_gvec_and(0, rd_ofs
, rn_ofs
, rm_ofs
,
5700 vec_size
, vec_size
);
5703 tcg_gen_gvec_andc(0, rd_ofs
, rn_ofs
, rm_ofs
,
5704 vec_size
, vec_size
);
5707 tcg_gen_gvec_or(0, rd_ofs
, rn_ofs
, rm_ofs
,
5708 vec_size
, vec_size
);
5711 tcg_gen_gvec_orc(0, rd_ofs
, rn_ofs
, rm_ofs
,
5712 vec_size
, vec_size
);
5715 tcg_gen_gvec_xor(0, rd_ofs
, rn_ofs
, rm_ofs
,
5716 vec_size
, vec_size
);
5719 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rd_ofs
, rn_ofs
, rm_ofs
,
5720 vec_size
, vec_size
);
5723 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rn_ofs
, rd_ofs
,
5724 vec_size
, vec_size
);
5727 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rd_ofs
, rn_ofs
,
5728 vec_size
, vec_size
);
5733 case NEON_3R_VADD_VSUB
:
5735 tcg_gen_gvec_sub(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5736 vec_size
, vec_size
);
5738 tcg_gen_gvec_add(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5739 vec_size
, vec_size
);
5744 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
5745 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5746 (u
? uqadd_op
: sqadd_op
) + size
);
5750 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
5751 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5752 (u
? uqsub_op
: sqsub_op
) + size
);
5755 case NEON_3R_VMUL
: /* VMUL */
5757 /* Polynomial case allows only P8 and is handled below. */
5762 tcg_gen_gvec_mul(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5763 vec_size
, vec_size
);
5768 case NEON_3R_VML
: /* VMLA, VMLS */
5769 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5770 u
? &mls_op
[size
] : &mla_op
[size
]);
5773 case NEON_3R_VTST_VCEQ
:
5775 tcg_gen_gvec_cmp(TCG_COND_EQ
, size
, rd_ofs
, rn_ofs
, rm_ofs
,
5776 vec_size
, vec_size
);
5778 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
,
5779 vec_size
, vec_size
, &cmtst_op
[size
]);
5784 tcg_gen_gvec_cmp(u
? TCG_COND_GTU
: TCG_COND_GT
, size
,
5785 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
5789 tcg_gen_gvec_cmp(u
? TCG_COND_GEU
: TCG_COND_GE
, size
,
5790 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
5795 tcg_gen_gvec_umax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5796 vec_size
, vec_size
);
5798 tcg_gen_gvec_smax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5799 vec_size
, vec_size
);
5804 tcg_gen_gvec_umin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5805 vec_size
, vec_size
);
5807 tcg_gen_gvec_smin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5808 vec_size
, vec_size
);
5814 /* 64-bit element instructions. */
5815 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5816 neon_load_reg64(cpu_V0
, rn
+ pass
);
5817 neon_load_reg64(cpu_V1
, rm
+ pass
);
5821 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5823 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5828 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5831 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5837 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5839 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5842 case NEON_3R_VQRSHL
:
5844 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5847 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5854 neon_store_reg64(cpu_V0
, rd
+ pass
);
5863 case NEON_3R_VQRSHL
:
5866 /* Shift instruction operands are reversed. */
5872 case NEON_3R_VPADD_VQRDMLAH
:
5877 case NEON_3R_FLOAT_ARITH
:
5878 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5880 case NEON_3R_FLOAT_MINMAX
:
5881 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5883 case NEON_3R_FLOAT_CMP
:
5885 /* no encoding for U=0 C=1x */
5889 case NEON_3R_FLOAT_ACMP
:
5894 case NEON_3R_FLOAT_MISC
:
5895 /* VMAXNM/VMINNM in ARMv8 */
5896 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5900 case NEON_3R_VFM_VQRDMLSH
:
5901 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
5909 if (pairwise
&& q
) {
5910 /* All the pairwise insns UNDEF if Q is set */
5914 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5919 tmp
= neon_load_reg(rn
, 0);
5920 tmp2
= neon_load_reg(rn
, 1);
5922 tmp
= neon_load_reg(rm
, 0);
5923 tmp2
= neon_load_reg(rm
, 1);
5927 tmp
= neon_load_reg(rn
, pass
);
5928 tmp2
= neon_load_reg(rm
, pass
);
5932 GEN_NEON_INTEGER_OP(hadd
);
5934 case NEON_3R_VRHADD
:
5935 GEN_NEON_INTEGER_OP(rhadd
);
5938 GEN_NEON_INTEGER_OP(hsub
);
5941 GEN_NEON_INTEGER_OP(shl
);
5944 GEN_NEON_INTEGER_OP_ENV(qshl
);
5947 GEN_NEON_INTEGER_OP(rshl
);
5949 case NEON_3R_VQRSHL
:
5950 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5953 GEN_NEON_INTEGER_OP(abd
);
5956 GEN_NEON_INTEGER_OP(abd
);
5957 tcg_temp_free_i32(tmp2
);
5958 tmp2
= neon_load_reg(rd
, pass
);
5959 gen_neon_add(size
, tmp
, tmp2
);
5962 /* VMUL.P8; other cases already eliminated. */
5963 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5966 GEN_NEON_INTEGER_OP(pmax
);
5969 GEN_NEON_INTEGER_OP(pmin
);
5971 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5972 if (!u
) { /* VQDMULH */
5975 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5978 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5982 } else { /* VQRDMULH */
5985 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5988 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5994 case NEON_3R_VPADD_VQRDMLAH
:
5996 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5997 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5998 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
6002 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
6004 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6005 switch ((u
<< 2) | size
) {
6008 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6011 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
6014 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
6019 tcg_temp_free_ptr(fpstatus
);
6022 case NEON_3R_FLOAT_MULTIPLY
:
6024 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6025 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6027 tcg_temp_free_i32(tmp2
);
6028 tmp2
= neon_load_reg(rd
, pass
);
6030 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6032 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6035 tcg_temp_free_ptr(fpstatus
);
6038 case NEON_3R_FLOAT_CMP
:
6040 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6042 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6045 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6047 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6050 tcg_temp_free_ptr(fpstatus
);
6053 case NEON_3R_FLOAT_ACMP
:
6055 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6057 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6059 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6061 tcg_temp_free_ptr(fpstatus
);
6064 case NEON_3R_FLOAT_MINMAX
:
6066 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6068 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6070 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6072 tcg_temp_free_ptr(fpstatus
);
6075 case NEON_3R_FLOAT_MISC
:
6078 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6080 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6082 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6084 tcg_temp_free_ptr(fpstatus
);
6087 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6089 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6093 case NEON_3R_VFM_VQRDMLSH
:
6095 /* VFMA, VFMS: fused multiply-add */
6096 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6097 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6100 gen_helper_vfp_negs(tmp
, tmp
);
6102 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6103 tcg_temp_free_i32(tmp3
);
6104 tcg_temp_free_ptr(fpstatus
);
6110 tcg_temp_free_i32(tmp2
);
6112 /* Save the result. For elementwise operations we can put it
6113 straight into the destination register. For pairwise operations
6114 we have to be careful to avoid clobbering the source operands. */
6115 if (pairwise
&& rd
== rm
) {
6116 neon_store_scratch(pass
, tmp
);
6118 neon_store_reg(rd
, pass
, tmp
);
6122 if (pairwise
&& rd
== rm
) {
6123 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6124 tmp
= neon_load_scratch(pass
);
6125 neon_store_reg(rd
, pass
, tmp
);
6128 /* End of 3 register same size operations. */
6129 } else if (insn
& (1 << 4)) {
6130 if ((insn
& 0x00380080) != 0) {
6131 /* Two registers and shift. */
6132 op
= (insn
>> 8) & 0xf;
6133 if (insn
& (1 << 7)) {
6141 while ((insn
& (1 << (size
+ 19))) == 0)
6144 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6146 /* Shift by immediate:
6147 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6148 if (q
&& ((rd
| rm
) & 1)) {
6151 if (!u
&& (op
== 4 || op
== 6)) {
6154 /* Right shifts are encoded as N - shift, where N is the
6155 element size in bits. */
6157 shift
= shift
- (1 << (size
+ 3));
6162 /* Right shift comes here negative. */
6164 /* Shifts larger than the element size are architecturally
6165 * valid. Unsigned results in all zeros; signed results
6169 tcg_gen_gvec_sari(size
, rd_ofs
, rm_ofs
,
6170 MIN(shift
, (8 << size
) - 1),
6171 vec_size
, vec_size
);
6172 } else if (shift
>= 8 << size
) {
6173 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
6175 tcg_gen_gvec_shri(size
, rd_ofs
, rm_ofs
, shift
,
6176 vec_size
, vec_size
);
6181 /* Right shift comes here negative. */
6183 /* Shifts larger than the element size are architecturally
6184 * valid. Unsigned results in all zeros; signed results
6188 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6189 MIN(shift
, (8 << size
) - 1),
6191 } else if (shift
>= 8 << size
) {
6194 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6195 shift
, &usra_op
[size
]);
6203 /* Right shift comes here negative. */
6205 /* Shift out of range leaves destination unchanged. */
6206 if (shift
< 8 << size
) {
6207 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6208 shift
, &sri_op
[size
]);
6212 case 5: /* VSHL, VSLI */
6214 /* Shift out of range leaves destination unchanged. */
6215 if (shift
< 8 << size
) {
6216 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
,
6217 vec_size
, shift
, &sli_op
[size
]);
6220 /* Shifts larger than the element size are
6221 * architecturally valid and results in zero.
6223 if (shift
>= 8 << size
) {
6224 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
6226 tcg_gen_gvec_shli(size
, rd_ofs
, rm_ofs
, shift
,
6227 vec_size
, vec_size
);
6239 /* To avoid excessive duplication of ops we implement shift
6240 * by immediate using the variable shift operations.
6242 imm
= dup_const(size
, shift
);
6244 for (pass
= 0; pass
< count
; pass
++) {
6246 neon_load_reg64(cpu_V0
, rm
+ pass
);
6247 tcg_gen_movi_i64(cpu_V1
, imm
);
6252 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6254 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6256 case 6: /* VQSHLU */
6257 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6262 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6265 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6270 g_assert_not_reached();
6274 neon_load_reg64(cpu_V1
, rd
+ pass
);
6275 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6277 neon_store_reg64(cpu_V0
, rd
+ pass
);
6278 } else { /* size < 3 */
6279 /* Operands in T0 and T1. */
6280 tmp
= neon_load_reg(rm
, pass
);
6281 tmp2
= tcg_temp_new_i32();
6282 tcg_gen_movi_i32(tmp2
, imm
);
6286 GEN_NEON_INTEGER_OP(rshl
);
6288 case 6: /* VQSHLU */
6291 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6295 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6299 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6307 GEN_NEON_INTEGER_OP_ENV(qshl
);
6310 g_assert_not_reached();
6312 tcg_temp_free_i32(tmp2
);
6316 tmp2
= neon_load_reg(rd
, pass
);
6317 gen_neon_add(size
, tmp
, tmp2
);
6318 tcg_temp_free_i32(tmp2
);
6320 neon_store_reg(rd
, pass
, tmp
);
6323 } else if (op
< 10) {
6324 /* Shift by immediate and narrow:
6325 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6326 int input_unsigned
= (op
== 8) ? !u
: u
;
6330 shift
= shift
- (1 << (size
+ 3));
6333 tmp64
= tcg_const_i64(shift
);
6334 neon_load_reg64(cpu_V0
, rm
);
6335 neon_load_reg64(cpu_V1
, rm
+ 1);
6336 for (pass
= 0; pass
< 2; pass
++) {
6344 if (input_unsigned
) {
6345 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6347 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6350 if (input_unsigned
) {
6351 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6353 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6356 tmp
= tcg_temp_new_i32();
6357 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6358 neon_store_reg(rd
, pass
, tmp
);
6360 tcg_temp_free_i64(tmp64
);
6363 imm
= (uint16_t)shift
;
6367 imm
= (uint32_t)shift
;
6369 tmp2
= tcg_const_i32(imm
);
6370 tmp4
= neon_load_reg(rm
+ 1, 0);
6371 tmp5
= neon_load_reg(rm
+ 1, 1);
6372 for (pass
= 0; pass
< 2; pass
++) {
6374 tmp
= neon_load_reg(rm
, 0);
6378 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6381 tmp3
= neon_load_reg(rm
, 1);
6385 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6387 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6388 tcg_temp_free_i32(tmp
);
6389 tcg_temp_free_i32(tmp3
);
6390 tmp
= tcg_temp_new_i32();
6391 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6392 neon_store_reg(rd
, pass
, tmp
);
6394 tcg_temp_free_i32(tmp2
);
6396 } else if (op
== 10) {
6398 if (q
|| (rd
& 1)) {
6401 tmp
= neon_load_reg(rm
, 0);
6402 tmp2
= neon_load_reg(rm
, 1);
6403 for (pass
= 0; pass
< 2; pass
++) {
6407 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6410 /* The shift is less than the width of the source
6411 type, so we can just shift the whole register. */
6412 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6413 /* Widen the result of shift: we need to clear
6414 * the potential overflow bits resulting from
6415 * left bits of the narrow input appearing as
6416 * right bits of left the neighbour narrow
6418 if (size
< 2 || !u
) {
6421 imm
= (0xffu
>> (8 - shift
));
6423 } else if (size
== 1) {
6424 imm
= 0xffff >> (16 - shift
);
6427 imm
= 0xffffffff >> (32 - shift
);
6430 imm64
= imm
| (((uint64_t)imm
) << 32);
6434 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6437 neon_store_reg64(cpu_V0
, rd
+ pass
);
6439 } else if (op
>= 14) {
6440 /* VCVT fixed-point. */
6441 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6444 /* We have already masked out the must-be-1 top bit of imm6,
6445 * hence this 32-shift where the ARM ARM has 64-imm6.
6448 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6449 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6452 gen_vfp_ulto(0, shift
, 1);
6454 gen_vfp_slto(0, shift
, 1);
6457 gen_vfp_toul(0, shift
, 1);
6459 gen_vfp_tosl(0, shift
, 1);
6461 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6466 } else { /* (insn & 0x00380080) == 0 */
6467 int invert
, reg_ofs
, vec_size
;
6469 if (q
&& (rd
& 1)) {
6473 op
= (insn
>> 8) & 0xf;
6474 /* One register and immediate. */
6475 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6476 invert
= (insn
& (1 << 5)) != 0;
6477 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6478 * We choose to not special-case this and will behave as if a
6479 * valid constant encoding of 0 had been given.
6498 imm
= (imm
<< 8) | (imm
<< 24);
6501 imm
= (imm
<< 8) | 0xff;
6504 imm
= (imm
<< 16) | 0xffff;
6507 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6516 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6517 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6524 reg_ofs
= neon_reg_offset(rd
, 0);
6525 vec_size
= q
? 16 : 8;
6527 if (op
& 1 && op
< 12) {
6529 /* The immediate value has already been inverted,
6530 * so BIC becomes AND.
6532 tcg_gen_gvec_andi(MO_32
, reg_ofs
, reg_ofs
, imm
,
6533 vec_size
, vec_size
);
6535 tcg_gen_gvec_ori(MO_32
, reg_ofs
, reg_ofs
, imm
,
6536 vec_size
, vec_size
);
6540 if (op
== 14 && invert
) {
6541 TCGv_i64 t64
= tcg_temp_new_i64();
6543 for (pass
= 0; pass
<= q
; ++pass
) {
6547 for (n
= 0; n
< 8; n
++) {
6548 if (imm
& (1 << (n
+ pass
* 8))) {
6549 val
|= 0xffull
<< (n
* 8);
6552 tcg_gen_movi_i64(t64
, val
);
6553 neon_store_reg64(t64
, rd
+ pass
);
6555 tcg_temp_free_i64(t64
);
6557 tcg_gen_gvec_dup32i(reg_ofs
, vec_size
, vec_size
, imm
);
6561 } else { /* (insn & 0x00800010 == 0x00800000) */
6563 op
= (insn
>> 8) & 0xf;
6564 if ((insn
& (1 << 6)) == 0) {
6565 /* Three registers of different lengths. */
6569 /* undefreq: bit 0 : UNDEF if size == 0
6570 * bit 1 : UNDEF if size == 1
6571 * bit 2 : UNDEF if size == 2
6572 * bit 3 : UNDEF if U == 1
6573 * Note that [2:0] set implies 'always UNDEF'
6576 /* prewiden, src1_wide, src2_wide, undefreq */
6577 static const int neon_3reg_wide
[16][4] = {
6578 {1, 0, 0, 0}, /* VADDL */
6579 {1, 1, 0, 0}, /* VADDW */
6580 {1, 0, 0, 0}, /* VSUBL */
6581 {1, 1, 0, 0}, /* VSUBW */
6582 {0, 1, 1, 0}, /* VADDHN */
6583 {0, 0, 0, 0}, /* VABAL */
6584 {0, 1, 1, 0}, /* VSUBHN */
6585 {0, 0, 0, 0}, /* VABDL */
6586 {0, 0, 0, 0}, /* VMLAL */
6587 {0, 0, 0, 9}, /* VQDMLAL */
6588 {0, 0, 0, 0}, /* VMLSL */
6589 {0, 0, 0, 9}, /* VQDMLSL */
6590 {0, 0, 0, 0}, /* Integer VMULL */
6591 {0, 0, 0, 1}, /* VQDMULL */
6592 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6593 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6596 prewiden
= neon_3reg_wide
[op
][0];
6597 src1_wide
= neon_3reg_wide
[op
][1];
6598 src2_wide
= neon_3reg_wide
[op
][2];
6599 undefreq
= neon_3reg_wide
[op
][3];
6601 if ((undefreq
& (1 << size
)) ||
6602 ((undefreq
& 8) && u
)) {
6605 if ((src1_wide
&& (rn
& 1)) ||
6606 (src2_wide
&& (rm
& 1)) ||
6607 (!src2_wide
&& (rd
& 1))) {
6611 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6612 * outside the loop below as it only performs a single pass.
6614 if (op
== 14 && size
== 2) {
6615 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6617 if (!dc_isar_feature(aa32_pmull
, s
)) {
6620 tcg_rn
= tcg_temp_new_i64();
6621 tcg_rm
= tcg_temp_new_i64();
6622 tcg_rd
= tcg_temp_new_i64();
6623 neon_load_reg64(tcg_rn
, rn
);
6624 neon_load_reg64(tcg_rm
, rm
);
6625 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6626 neon_store_reg64(tcg_rd
, rd
);
6627 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6628 neon_store_reg64(tcg_rd
, rd
+ 1);
6629 tcg_temp_free_i64(tcg_rn
);
6630 tcg_temp_free_i64(tcg_rm
);
6631 tcg_temp_free_i64(tcg_rd
);
6635 /* Avoid overlapping operands. Wide source operands are
6636 always aligned so will never overlap with wide
6637 destinations in problematic ways. */
6638 if (rd
== rm
&& !src2_wide
) {
6639 tmp
= neon_load_reg(rm
, 1);
6640 neon_store_scratch(2, tmp
);
6641 } else if (rd
== rn
&& !src1_wide
) {
6642 tmp
= neon_load_reg(rn
, 1);
6643 neon_store_scratch(2, tmp
);
6646 for (pass
= 0; pass
< 2; pass
++) {
6648 neon_load_reg64(cpu_V0
, rn
+ pass
);
6651 if (pass
== 1 && rd
== rn
) {
6652 tmp
= neon_load_scratch(2);
6654 tmp
= neon_load_reg(rn
, pass
);
6657 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6661 neon_load_reg64(cpu_V1
, rm
+ pass
);
6664 if (pass
== 1 && rd
== rm
) {
6665 tmp2
= neon_load_scratch(2);
6667 tmp2
= neon_load_reg(rm
, pass
);
6670 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6674 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6675 gen_neon_addl(size
);
6677 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6678 gen_neon_subl(size
);
6680 case 5: case 7: /* VABAL, VABDL */
6681 switch ((size
<< 1) | u
) {
6683 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6686 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6689 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6692 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6695 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6698 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6702 tcg_temp_free_i32(tmp2
);
6703 tcg_temp_free_i32(tmp
);
6705 case 8: case 9: case 10: case 11: case 12: case 13:
6706 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6707 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6709 case 14: /* Polynomial VMULL */
6710 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6711 tcg_temp_free_i32(tmp2
);
6712 tcg_temp_free_i32(tmp
);
6714 default: /* 15 is RESERVED: caught earlier */
6719 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6720 neon_store_reg64(cpu_V0
, rd
+ pass
);
6721 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6723 neon_load_reg64(cpu_V1
, rd
+ pass
);
6725 case 10: /* VMLSL */
6726 gen_neon_negl(cpu_V0
, size
);
6728 case 5: case 8: /* VABAL, VMLAL */
6729 gen_neon_addl(size
);
6731 case 9: case 11: /* VQDMLAL, VQDMLSL */
6732 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6734 gen_neon_negl(cpu_V0
, size
);
6736 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6741 neon_store_reg64(cpu_V0
, rd
+ pass
);
6742 } else if (op
== 4 || op
== 6) {
6743 /* Narrowing operation. */
6744 tmp
= tcg_temp_new_i32();
6748 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6751 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6754 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6755 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6762 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6765 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6768 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6769 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6770 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6778 neon_store_reg(rd
, 0, tmp3
);
6779 neon_store_reg(rd
, 1, tmp
);
6782 /* Write back the result. */
6783 neon_store_reg64(cpu_V0
, rd
+ pass
);
6787 /* Two registers and a scalar. NB that for ops of this form
6788 * the ARM ARM labels bit 24 as Q, but it is in our variable
6795 case 1: /* Float VMLA scalar */
6796 case 5: /* Floating point VMLS scalar */
6797 case 9: /* Floating point VMUL scalar */
6802 case 0: /* Integer VMLA scalar */
6803 case 4: /* Integer VMLS scalar */
6804 case 8: /* Integer VMUL scalar */
6805 case 12: /* VQDMULH scalar */
6806 case 13: /* VQRDMULH scalar */
6807 if (u
&& ((rd
| rn
) & 1)) {
6810 tmp
= neon_get_scalar(size
, rm
);
6811 neon_store_scratch(0, tmp
);
6812 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6813 tmp
= neon_load_scratch(0);
6814 tmp2
= neon_load_reg(rn
, pass
);
6817 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6819 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6821 } else if (op
== 13) {
6823 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6825 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6827 } else if (op
& 1) {
6828 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6829 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6830 tcg_temp_free_ptr(fpstatus
);
6833 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6834 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6835 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6839 tcg_temp_free_i32(tmp2
);
6842 tmp2
= neon_load_reg(rd
, pass
);
6845 gen_neon_add(size
, tmp
, tmp2
);
6849 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6850 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6851 tcg_temp_free_ptr(fpstatus
);
6855 gen_neon_rsb(size
, tmp
, tmp2
);
6859 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6860 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6861 tcg_temp_free_ptr(fpstatus
);
6867 tcg_temp_free_i32(tmp2
);
6869 neon_store_reg(rd
, pass
, tmp
);
6872 case 3: /* VQDMLAL scalar */
6873 case 7: /* VQDMLSL scalar */
6874 case 11: /* VQDMULL scalar */
6879 case 2: /* VMLAL sclar */
6880 case 6: /* VMLSL scalar */
6881 case 10: /* VMULL scalar */
6885 tmp2
= neon_get_scalar(size
, rm
);
6886 /* We need a copy of tmp2 because gen_neon_mull
6887 * deletes it during pass 0. */
6888 tmp4
= tcg_temp_new_i32();
6889 tcg_gen_mov_i32(tmp4
, tmp2
);
6890 tmp3
= neon_load_reg(rn
, 1);
6892 for (pass
= 0; pass
< 2; pass
++) {
6894 tmp
= neon_load_reg(rn
, 0);
6899 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6901 neon_load_reg64(cpu_V1
, rd
+ pass
);
6905 gen_neon_negl(cpu_V0
, size
);
6908 gen_neon_addl(size
);
6911 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6913 gen_neon_negl(cpu_V0
, size
);
6915 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6921 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6926 neon_store_reg64(cpu_V0
, rd
+ pass
);
6929 case 14: /* VQRDMLAH scalar */
6930 case 15: /* VQRDMLSH scalar */
6932 NeonGenThreeOpEnvFn
*fn
;
6934 if (!dc_isar_feature(aa32_rdm
, s
)) {
6937 if (u
&& ((rd
| rn
) & 1)) {
6942 fn
= gen_helper_neon_qrdmlah_s16
;
6944 fn
= gen_helper_neon_qrdmlah_s32
;
6948 fn
= gen_helper_neon_qrdmlsh_s16
;
6950 fn
= gen_helper_neon_qrdmlsh_s32
;
6954 tmp2
= neon_get_scalar(size
, rm
);
6955 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6956 tmp
= neon_load_reg(rn
, pass
);
6957 tmp3
= neon_load_reg(rd
, pass
);
6958 fn(tmp
, cpu_env
, tmp
, tmp2
, tmp3
);
6959 tcg_temp_free_i32(tmp3
);
6960 neon_store_reg(rd
, pass
, tmp
);
6962 tcg_temp_free_i32(tmp2
);
6966 g_assert_not_reached();
6969 } else { /* size == 3 */
6972 imm
= (insn
>> 8) & 0xf;
6977 if (q
&& ((rd
| rn
| rm
) & 1)) {
6982 neon_load_reg64(cpu_V0
, rn
);
6984 neon_load_reg64(cpu_V1
, rn
+ 1);
6986 } else if (imm
== 8) {
6987 neon_load_reg64(cpu_V0
, rn
+ 1);
6989 neon_load_reg64(cpu_V1
, rm
);
6992 tmp64
= tcg_temp_new_i64();
6994 neon_load_reg64(cpu_V0
, rn
);
6995 neon_load_reg64(tmp64
, rn
+ 1);
6997 neon_load_reg64(cpu_V0
, rn
+ 1);
6998 neon_load_reg64(tmp64
, rm
);
7000 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
7001 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
7002 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7004 neon_load_reg64(cpu_V1
, rm
);
7006 neon_load_reg64(cpu_V1
, rm
+ 1);
7009 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7010 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
7011 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
7012 tcg_temp_free_i64(tmp64
);
7015 neon_load_reg64(cpu_V0
, rn
);
7016 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
7017 neon_load_reg64(cpu_V1
, rm
);
7018 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7019 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7021 neon_store_reg64(cpu_V0
, rd
);
7023 neon_store_reg64(cpu_V1
, rd
+ 1);
7025 } else if ((insn
& (1 << 11)) == 0) {
7026 /* Two register misc. */
7027 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
7028 size
= (insn
>> 18) & 3;
7029 /* UNDEF for unknown op values and bad op-size combinations */
7030 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
7033 if (neon_2rm_is_v8_op(op
) &&
7034 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7037 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
7038 q
&& ((rm
| rd
) & 1)) {
7042 case NEON_2RM_VREV64
:
7043 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
7044 tmp
= neon_load_reg(rm
, pass
* 2);
7045 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
7047 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7048 case 1: gen_swap_half(tmp
); break;
7049 case 2: /* no-op */ break;
7052 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
7054 neon_store_reg(rd
, pass
* 2, tmp2
);
7057 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
7058 case 1: gen_swap_half(tmp2
); break;
7061 neon_store_reg(rd
, pass
* 2, tmp2
);
7065 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
7066 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
7067 for (pass
= 0; pass
< q
+ 1; pass
++) {
7068 tmp
= neon_load_reg(rm
, pass
* 2);
7069 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
7070 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
7071 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
7073 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
7074 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
7075 case 2: tcg_gen_add_i64(CPU_V001
); break;
7078 if (op
>= NEON_2RM_VPADAL
) {
7080 neon_load_reg64(cpu_V1
, rd
+ pass
);
7081 gen_neon_addl(size
);
7083 neon_store_reg64(cpu_V0
, rd
+ pass
);
7089 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7090 tmp
= neon_load_reg(rm
, n
);
7091 tmp2
= neon_load_reg(rd
, n
+ 1);
7092 neon_store_reg(rm
, n
, tmp2
);
7093 neon_store_reg(rd
, n
+ 1, tmp
);
7100 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7105 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7109 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7110 /* also VQMOVUN; op field and mnemonics don't line up */
7115 for (pass
= 0; pass
< 2; pass
++) {
7116 neon_load_reg64(cpu_V0
, rm
+ pass
);
7117 tmp
= tcg_temp_new_i32();
7118 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7123 neon_store_reg(rd
, 0, tmp2
);
7124 neon_store_reg(rd
, 1, tmp
);
7128 case NEON_2RM_VSHLL
:
7129 if (q
|| (rd
& 1)) {
7132 tmp
= neon_load_reg(rm
, 0);
7133 tmp2
= neon_load_reg(rm
, 1);
7134 for (pass
= 0; pass
< 2; pass
++) {
7137 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7138 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7139 neon_store_reg64(cpu_V0
, rd
+ pass
);
7142 case NEON_2RM_VCVT_F16_F32
:
7147 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
7151 tmp
= tcg_temp_new_i32();
7152 tmp2
= tcg_temp_new_i32();
7153 fpst
= get_fpstatus_ptr(true);
7154 ahp
= get_ahp_flag();
7155 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7156 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, fpst
, ahp
);
7157 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7158 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, cpu_F0s
, fpst
, ahp
);
7159 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7160 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7161 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7162 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, fpst
, ahp
);
7163 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7164 neon_store_reg(rd
, 0, tmp2
);
7165 tmp2
= tcg_temp_new_i32();
7166 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, cpu_F0s
, fpst
, ahp
);
7167 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7168 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7169 neon_store_reg(rd
, 1, tmp2
);
7170 tcg_temp_free_i32(tmp
);
7171 tcg_temp_free_i32(ahp
);
7172 tcg_temp_free_ptr(fpst
);
7175 case NEON_2RM_VCVT_F32_F16
:
7179 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
7183 fpst
= get_fpstatus_ptr(true);
7184 ahp
= get_ahp_flag();
7185 tmp3
= tcg_temp_new_i32();
7186 tmp
= neon_load_reg(rm
, 0);
7187 tmp2
= neon_load_reg(rm
, 1);
7188 tcg_gen_ext16u_i32(tmp3
, tmp
);
7189 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7190 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7191 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7192 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7193 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7194 tcg_temp_free_i32(tmp
);
7195 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7196 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7197 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7198 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7199 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7200 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7201 tcg_temp_free_i32(tmp2
);
7202 tcg_temp_free_i32(tmp3
);
7203 tcg_temp_free_i32(ahp
);
7204 tcg_temp_free_ptr(fpst
);
7207 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7208 if (!dc_isar_feature(aa32_aes
, s
) || ((rm
| rd
) & 1)) {
7211 ptr1
= vfp_reg_ptr(true, rd
);
7212 ptr2
= vfp_reg_ptr(true, rm
);
7214 /* Bit 6 is the lowest opcode bit; it distinguishes between
7215 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7217 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7219 if (op
== NEON_2RM_AESE
) {
7220 gen_helper_crypto_aese(ptr1
, ptr2
, tmp3
);
7222 gen_helper_crypto_aesmc(ptr1
, ptr2
, tmp3
);
7224 tcg_temp_free_ptr(ptr1
);
7225 tcg_temp_free_ptr(ptr2
);
7226 tcg_temp_free_i32(tmp3
);
7228 case NEON_2RM_SHA1H
:
7229 if (!dc_isar_feature(aa32_sha1
, s
) || ((rm
| rd
) & 1)) {
7232 ptr1
= vfp_reg_ptr(true, rd
);
7233 ptr2
= vfp_reg_ptr(true, rm
);
7235 gen_helper_crypto_sha1h(ptr1
, ptr2
);
7237 tcg_temp_free_ptr(ptr1
);
7238 tcg_temp_free_ptr(ptr2
);
7240 case NEON_2RM_SHA1SU1
:
7241 if ((rm
| rd
) & 1) {
7244 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7246 if (!dc_isar_feature(aa32_sha2
, s
)) {
7249 } else if (!dc_isar_feature(aa32_sha1
, s
)) {
7252 ptr1
= vfp_reg_ptr(true, rd
);
7253 ptr2
= vfp_reg_ptr(true, rm
);
7255 gen_helper_crypto_sha256su0(ptr1
, ptr2
);
7257 gen_helper_crypto_sha1su1(ptr1
, ptr2
);
7259 tcg_temp_free_ptr(ptr1
);
7260 tcg_temp_free_ptr(ptr2
);
7264 tcg_gen_gvec_not(0, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7267 tcg_gen_gvec_neg(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7270 tcg_gen_gvec_abs(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7275 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7276 if (neon_2rm_is_float_op(op
)) {
7277 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7278 neon_reg_offset(rm
, pass
));
7281 tmp
= neon_load_reg(rm
, pass
);
7284 case NEON_2RM_VREV32
:
7286 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7287 case 1: gen_swap_half(tmp
); break;
7291 case NEON_2RM_VREV16
:
7296 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7297 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7298 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7304 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7305 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7306 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7311 gen_helper_neon_cnt_u8(tmp
, tmp
);
7313 case NEON_2RM_VQABS
:
7316 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7319 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7322 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7327 case NEON_2RM_VQNEG
:
7330 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7333 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7336 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7341 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7342 tmp2
= tcg_const_i32(0);
7344 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7345 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7346 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7349 tcg_temp_free_i32(tmp2
);
7350 if (op
== NEON_2RM_VCLE0
) {
7351 tcg_gen_not_i32(tmp
, tmp
);
7354 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7355 tmp2
= tcg_const_i32(0);
7357 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7358 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7359 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7362 tcg_temp_free_i32(tmp2
);
7363 if (op
== NEON_2RM_VCLT0
) {
7364 tcg_gen_not_i32(tmp
, tmp
);
7367 case NEON_2RM_VCEQ0
:
7368 tmp2
= tcg_const_i32(0);
7370 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7371 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7372 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7375 tcg_temp_free_i32(tmp2
);
7377 case NEON_2RM_VCGT0_F
:
7379 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7380 tmp2
= tcg_const_i32(0);
7381 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7382 tcg_temp_free_i32(tmp2
);
7383 tcg_temp_free_ptr(fpstatus
);
7386 case NEON_2RM_VCGE0_F
:
7388 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7389 tmp2
= tcg_const_i32(0);
7390 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7391 tcg_temp_free_i32(tmp2
);
7392 tcg_temp_free_ptr(fpstatus
);
7395 case NEON_2RM_VCEQ0_F
:
7397 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7398 tmp2
= tcg_const_i32(0);
7399 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7400 tcg_temp_free_i32(tmp2
);
7401 tcg_temp_free_ptr(fpstatus
);
7404 case NEON_2RM_VCLE0_F
:
7406 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7407 tmp2
= tcg_const_i32(0);
7408 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7409 tcg_temp_free_i32(tmp2
);
7410 tcg_temp_free_ptr(fpstatus
);
7413 case NEON_2RM_VCLT0_F
:
7415 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7416 tmp2
= tcg_const_i32(0);
7417 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7418 tcg_temp_free_i32(tmp2
);
7419 tcg_temp_free_ptr(fpstatus
);
7422 case NEON_2RM_VABS_F
:
7425 case NEON_2RM_VNEG_F
:
7429 tmp2
= neon_load_reg(rd
, pass
);
7430 neon_store_reg(rm
, pass
, tmp2
);
7433 tmp2
= neon_load_reg(rd
, pass
);
7435 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7436 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7439 neon_store_reg(rm
, pass
, tmp2
);
7441 case NEON_2RM_VRINTN
:
7442 case NEON_2RM_VRINTA
:
7443 case NEON_2RM_VRINTM
:
7444 case NEON_2RM_VRINTP
:
7445 case NEON_2RM_VRINTZ
:
7448 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7451 if (op
== NEON_2RM_VRINTZ
) {
7452 rmode
= FPROUNDING_ZERO
;
7454 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7457 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7458 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7460 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7461 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7463 tcg_temp_free_ptr(fpstatus
);
7464 tcg_temp_free_i32(tcg_rmode
);
7467 case NEON_2RM_VRINTX
:
7469 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7470 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7471 tcg_temp_free_ptr(fpstatus
);
7474 case NEON_2RM_VCVTAU
:
7475 case NEON_2RM_VCVTAS
:
7476 case NEON_2RM_VCVTNU
:
7477 case NEON_2RM_VCVTNS
:
7478 case NEON_2RM_VCVTPU
:
7479 case NEON_2RM_VCVTPS
:
7480 case NEON_2RM_VCVTMU
:
7481 case NEON_2RM_VCVTMS
:
7483 bool is_signed
= !extract32(insn
, 7, 1);
7484 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7485 TCGv_i32 tcg_rmode
, tcg_shift
;
7486 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7488 tcg_shift
= tcg_const_i32(0);
7489 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7490 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7494 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7497 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7501 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7503 tcg_temp_free_i32(tcg_rmode
);
7504 tcg_temp_free_i32(tcg_shift
);
7505 tcg_temp_free_ptr(fpst
);
7508 case NEON_2RM_VRECPE
:
7510 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7511 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7512 tcg_temp_free_ptr(fpstatus
);
7515 case NEON_2RM_VRSQRTE
:
7517 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7518 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7519 tcg_temp_free_ptr(fpstatus
);
7522 case NEON_2RM_VRECPE_F
:
7524 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7525 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7526 tcg_temp_free_ptr(fpstatus
);
7529 case NEON_2RM_VRSQRTE_F
:
7531 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7532 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7533 tcg_temp_free_ptr(fpstatus
);
7536 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7539 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7542 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7543 gen_vfp_tosiz(0, 1);
7545 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7546 gen_vfp_touiz(0, 1);
7549 /* Reserved op values were caught by the
7550 * neon_2rm_sizes[] check earlier.
7554 if (neon_2rm_is_float_op(op
)) {
7555 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7556 neon_reg_offset(rd
, pass
));
7558 neon_store_reg(rd
, pass
, tmp
);
7563 } else if ((insn
& (1 << 10)) == 0) {
7565 int n
= ((insn
>> 8) & 3) + 1;
7566 if ((rn
+ n
) > 32) {
7567 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7568 * helper function running off the end of the register file.
7573 if (insn
& (1 << 6)) {
7574 tmp
= neon_load_reg(rd
, 0);
7576 tmp
= tcg_temp_new_i32();
7577 tcg_gen_movi_i32(tmp
, 0);
7579 tmp2
= neon_load_reg(rm
, 0);
7580 ptr1
= vfp_reg_ptr(true, rn
);
7581 tmp5
= tcg_const_i32(n
);
7582 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, ptr1
, tmp5
);
7583 tcg_temp_free_i32(tmp
);
7584 if (insn
& (1 << 6)) {
7585 tmp
= neon_load_reg(rd
, 1);
7587 tmp
= tcg_temp_new_i32();
7588 tcg_gen_movi_i32(tmp
, 0);
7590 tmp3
= neon_load_reg(rm
, 1);
7591 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, ptr1
, tmp5
);
7592 tcg_temp_free_i32(tmp5
);
7593 tcg_temp_free_ptr(ptr1
);
7594 neon_store_reg(rd
, 0, tmp2
);
7595 neon_store_reg(rd
, 1, tmp3
);
7596 tcg_temp_free_i32(tmp
);
7597 } else if ((insn
& 0x380) == 0) {
7602 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7605 if (insn
& (1 << 16)) {
7607 element
= (insn
>> 17) & 7;
7608 } else if (insn
& (1 << 17)) {
7610 element
= (insn
>> 18) & 3;
7613 element
= (insn
>> 19) & 1;
7615 tcg_gen_gvec_dup_mem(size
, neon_reg_offset(rd
, 0),
7616 neon_element_offset(rm
, element
, size
),
7617 q
? 16 : 8, q
? 16 : 8);
7626 /* Advanced SIMD three registers of the same length extension.
7627 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7628 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7629 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7630 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7632 static int disas_neon_insn_3same_ext(DisasContext
*s
, uint32_t insn
)
7634 gen_helper_gvec_3
*fn_gvec
= NULL
;
7635 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
7636 int rd
, rn
, rm
, opr_sz
;
7639 bool is_long
= false, q
= extract32(insn
, 6, 1);
7640 bool ptr_is_env
= false;
7642 if ((insn
& 0xfe200f10) == 0xfc200800) {
7643 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7644 int size
= extract32(insn
, 20, 1);
7645 data
= extract32(insn
, 23, 2); /* rot */
7646 if (!dc_isar_feature(aa32_vcma
, s
)
7647 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
7650 fn_gvec_ptr
= size
? gen_helper_gvec_fcmlas
: gen_helper_gvec_fcmlah
;
7651 } else if ((insn
& 0xfea00f10) == 0xfc800800) {
7652 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7653 int size
= extract32(insn
, 20, 1);
7654 data
= extract32(insn
, 24, 1); /* rot */
7655 if (!dc_isar_feature(aa32_vcma
, s
)
7656 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
7659 fn_gvec_ptr
= size
? gen_helper_gvec_fcadds
: gen_helper_gvec_fcaddh
;
7660 } else if ((insn
& 0xfeb00f00) == 0xfc200d00) {
7661 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
7662 bool u
= extract32(insn
, 4, 1);
7663 if (!dc_isar_feature(aa32_dp
, s
)) {
7666 fn_gvec
= u
? gen_helper_gvec_udot_b
: gen_helper_gvec_sdot_b
;
7667 } else if ((insn
& 0xff300f10) == 0xfc200810) {
7668 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
7669 int is_s
= extract32(insn
, 23, 1);
7670 if (!dc_isar_feature(aa32_fhm
, s
)) {
7674 data
= is_s
; /* is_2 == 0 */
7675 fn_gvec_ptr
= gen_helper_gvec_fmlal_a32
;
7681 VFP_DREG_D(rd
, insn
);
7685 if (q
|| !is_long
) {
7686 VFP_DREG_N(rn
, insn
);
7687 VFP_DREG_M(rm
, insn
);
7688 if ((rn
| rm
) & q
& !is_long
) {
7691 off_rn
= vfp_reg_offset(1, rn
);
7692 off_rm
= vfp_reg_offset(1, rm
);
7694 rn
= VFP_SREG_N(insn
);
7695 rm
= VFP_SREG_M(insn
);
7696 off_rn
= vfp_reg_offset(0, rn
);
7697 off_rm
= vfp_reg_offset(0, rm
);
7700 if (s
->fp_excp_el
) {
7701 gen_exception_insn(s
, 4, EXCP_UDEF
,
7702 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
7705 if (!s
->vfp_enabled
) {
7709 opr_sz
= (1 + q
) * 8;
7715 ptr
= get_fpstatus_ptr(1);
7717 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
7718 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
7720 tcg_temp_free_ptr(ptr
);
7723 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
7724 opr_sz
, opr_sz
, data
, fn_gvec
);
7729 /* Advanced SIMD two registers and a scalar extension.
7730 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7731 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7732 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7733 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7737 static int disas_neon_insn_2reg_scalar_ext(DisasContext
*s
, uint32_t insn
)
7739 gen_helper_gvec_3
*fn_gvec
= NULL
;
7740 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
7741 int rd
, rn
, rm
, opr_sz
, data
;
7743 bool is_long
= false, q
= extract32(insn
, 6, 1);
7744 bool ptr_is_env
= false;
7746 if ((insn
& 0xff000f10) == 0xfe000800) {
7747 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7748 int rot
= extract32(insn
, 20, 2);
7749 int size
= extract32(insn
, 23, 1);
7752 if (!dc_isar_feature(aa32_vcma
, s
)) {
7756 if (!dc_isar_feature(aa32_fp16_arith
, s
)) {
7759 /* For fp16, rm is just Vm, and index is M. */
7760 rm
= extract32(insn
, 0, 4);
7761 index
= extract32(insn
, 5, 1);
7763 /* For fp32, rm is the usual M:Vm, and index is 0. */
7764 VFP_DREG_M(rm
, insn
);
7767 data
= (index
<< 2) | rot
;
7768 fn_gvec_ptr
= (size
? gen_helper_gvec_fcmlas_idx
7769 : gen_helper_gvec_fcmlah_idx
);
7770 } else if ((insn
& 0xffb00f00) == 0xfe200d00) {
7771 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7772 int u
= extract32(insn
, 4, 1);
7774 if (!dc_isar_feature(aa32_dp
, s
)) {
7777 fn_gvec
= u
? gen_helper_gvec_udot_idx_b
: gen_helper_gvec_sdot_idx_b
;
7778 /* rm is just Vm, and index is M. */
7779 data
= extract32(insn
, 5, 1); /* index */
7780 rm
= extract32(insn
, 0, 4);
7781 } else if ((insn
& 0xffa00f10) == 0xfe000810) {
7782 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7783 int is_s
= extract32(insn
, 20, 1);
7784 int vm20
= extract32(insn
, 0, 3);
7785 int vm3
= extract32(insn
, 3, 1);
7786 int m
= extract32(insn
, 5, 1);
7789 if (!dc_isar_feature(aa32_fhm
, s
)) {
7794 index
= m
* 2 + vm3
;
7800 data
= (index
<< 2) | is_s
; /* is_2 == 0 */
7801 fn_gvec_ptr
= gen_helper_gvec_fmlal_idx_a32
;
7807 VFP_DREG_D(rd
, insn
);
7811 if (q
|| !is_long
) {
7812 VFP_DREG_N(rn
, insn
);
7813 if (rn
& q
& !is_long
) {
7816 off_rn
= vfp_reg_offset(1, rn
);
7817 off_rm
= vfp_reg_offset(1, rm
);
7819 rn
= VFP_SREG_N(insn
);
7820 off_rn
= vfp_reg_offset(0, rn
);
7821 off_rm
= vfp_reg_offset(0, rm
);
7823 if (s
->fp_excp_el
) {
7824 gen_exception_insn(s
, 4, EXCP_UDEF
,
7825 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
7828 if (!s
->vfp_enabled
) {
7832 opr_sz
= (1 + q
) * 8;
7838 ptr
= get_fpstatus_ptr(1);
7840 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
7841 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
7843 tcg_temp_free_ptr(ptr
);
7846 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
7847 opr_sz
, opr_sz
, data
, fn_gvec
);
7852 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7854 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7855 const ARMCPRegInfo
*ri
;
7857 cpnum
= (insn
>> 8) & 0xf;
7859 /* First check for coprocessor space used for XScale/iwMMXt insns */
7860 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7861 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7864 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7865 return disas_iwmmxt_insn(s
, insn
);
7866 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7867 return disas_dsp_insn(s
, insn
);
7872 /* Otherwise treat as a generic register access */
7873 is64
= (insn
& (1 << 25)) == 0;
7874 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7882 opc1
= (insn
>> 4) & 0xf;
7884 rt2
= (insn
>> 16) & 0xf;
7886 crn
= (insn
>> 16) & 0xf;
7887 opc1
= (insn
>> 21) & 7;
7888 opc2
= (insn
>> 5) & 7;
7891 isread
= (insn
>> 20) & 1;
7892 rt
= (insn
>> 12) & 0xf;
7894 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7895 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7897 /* Check access permissions */
7898 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7903 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7904 /* Emit code to perform further access permissions checks at
7905 * runtime; this may result in an exception.
7906 * Note that on XScale all cp0..c13 registers do an access check
7907 * call in order to handle c15_cpar.
7910 TCGv_i32 tcg_syn
, tcg_isread
;
7913 /* Note that since we are an implementation which takes an
7914 * exception on a trapped conditional instruction only if the
7915 * instruction passes its condition code check, we can take
7916 * advantage of the clause in the ARM ARM that allows us to set
7917 * the COND field in the instruction to 0xE in all cases.
7918 * We could fish the actual condition out of the insn (ARM)
7919 * or the condexec bits (Thumb) but it isn't necessary.
7924 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7927 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7933 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7936 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7941 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7942 * so this can only happen if this is an ARMv7 or earlier CPU,
7943 * in which case the syndrome information won't actually be
7946 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7947 syndrome
= syn_uncategorized();
7951 gen_set_condexec(s
);
7952 gen_set_pc_im(s
, s
->pc
- 4);
7953 tmpptr
= tcg_const_ptr(ri
);
7954 tcg_syn
= tcg_const_i32(syndrome
);
7955 tcg_isread
= tcg_const_i32(isread
);
7956 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7958 tcg_temp_free_ptr(tmpptr
);
7959 tcg_temp_free_i32(tcg_syn
);
7960 tcg_temp_free_i32(tcg_isread
);
7963 /* Handle special cases first */
7964 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7971 gen_set_pc_im(s
, s
->pc
);
7972 s
->base
.is_jmp
= DISAS_WFI
;
7978 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7987 if (ri
->type
& ARM_CP_CONST
) {
7988 tmp64
= tcg_const_i64(ri
->resetvalue
);
7989 } else if (ri
->readfn
) {
7991 tmp64
= tcg_temp_new_i64();
7992 tmpptr
= tcg_const_ptr(ri
);
7993 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7994 tcg_temp_free_ptr(tmpptr
);
7996 tmp64
= tcg_temp_new_i64();
7997 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7999 tmp
= tcg_temp_new_i32();
8000 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8001 store_reg(s
, rt
, tmp
);
8002 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8003 tmp
= tcg_temp_new_i32();
8004 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8005 tcg_temp_free_i64(tmp64
);
8006 store_reg(s
, rt2
, tmp
);
8009 if (ri
->type
& ARM_CP_CONST
) {
8010 tmp
= tcg_const_i32(ri
->resetvalue
);
8011 } else if (ri
->readfn
) {
8013 tmp
= tcg_temp_new_i32();
8014 tmpptr
= tcg_const_ptr(ri
);
8015 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
8016 tcg_temp_free_ptr(tmpptr
);
8018 tmp
= load_cpu_offset(ri
->fieldoffset
);
8021 /* Destination register of r15 for 32 bit loads sets
8022 * the condition codes from the high 4 bits of the value
8025 tcg_temp_free_i32(tmp
);
8027 store_reg(s
, rt
, tmp
);
8032 if (ri
->type
& ARM_CP_CONST
) {
8033 /* If not forbidden by access permissions, treat as WI */
8038 TCGv_i32 tmplo
, tmphi
;
8039 TCGv_i64 tmp64
= tcg_temp_new_i64();
8040 tmplo
= load_reg(s
, rt
);
8041 tmphi
= load_reg(s
, rt2
);
8042 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
8043 tcg_temp_free_i32(tmplo
);
8044 tcg_temp_free_i32(tmphi
);
8046 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
8047 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
8048 tcg_temp_free_ptr(tmpptr
);
8050 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
8052 tcg_temp_free_i64(tmp64
);
8057 tmp
= load_reg(s
, rt
);
8058 tmpptr
= tcg_const_ptr(ri
);
8059 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
8060 tcg_temp_free_ptr(tmpptr
);
8061 tcg_temp_free_i32(tmp
);
8063 TCGv_i32 tmp
= load_reg(s
, rt
);
8064 store_cpu_offset(tmp
, ri
->fieldoffset
);
8069 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
8070 /* I/O operations must end the TB here (whether read or write) */
8073 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
8074 /* We default to ending the TB on a coprocessor register write,
8075 * but allow this to be suppressed by the register definition
8076 * (usually only necessary to work around guest bugs).
8084 /* Unknown register; this might be a guest error or a QEMU
8085 * unimplemented feature.
8088 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8089 "64 bit system register cp:%d opc1: %d crm:%d "
8091 isread
? "read" : "write", cpnum
, opc1
, crm
,
8092 s
->ns
? "non-secure" : "secure");
8094 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8095 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8097 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
8098 s
->ns
? "non-secure" : "secure");
8105 /* Store a 64-bit value to a register pair. Clobbers val. */
8106 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
8109 tmp
= tcg_temp_new_i32();
8110 tcg_gen_extrl_i64_i32(tmp
, val
);
8111 store_reg(s
, rlow
, tmp
);
8112 tmp
= tcg_temp_new_i32();
8113 tcg_gen_shri_i64(val
, val
, 32);
8114 tcg_gen_extrl_i64_i32(tmp
, val
);
8115 store_reg(s
, rhigh
, tmp
);
8118 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8119 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
8124 /* Load value and extend to 64 bits. */
8125 tmp
= tcg_temp_new_i64();
8126 tmp2
= load_reg(s
, rlow
);
8127 tcg_gen_extu_i32_i64(tmp
, tmp2
);
8128 tcg_temp_free_i32(tmp2
);
8129 tcg_gen_add_i64(val
, val
, tmp
);
8130 tcg_temp_free_i64(tmp
);
8133 /* load and add a 64-bit value from a register pair. */
8134 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
8140 /* Load 64-bit value rd:rn. */
8141 tmpl
= load_reg(s
, rlow
);
8142 tmph
= load_reg(s
, rhigh
);
8143 tmp
= tcg_temp_new_i64();
8144 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
8145 tcg_temp_free_i32(tmpl
);
8146 tcg_temp_free_i32(tmph
);
8147 tcg_gen_add_i64(val
, val
, tmp
);
8148 tcg_temp_free_i64(tmp
);
8151 /* Set N and Z flags from hi|lo. */
8152 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
8154 tcg_gen_mov_i32(cpu_NF
, hi
);
8155 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
8158 /* Load/Store exclusive instructions are implemented by remembering
8159 the value/address loaded, and seeing if these are the same
8160 when the store is performed. This should be sufficient to implement
8161 the architecturally mandated semantics, and avoids having to monitor
8162 regular stores. The compare vs the remembered value is done during
8163 the cmpxchg operation, but we must compare the addresses manually. */
8164 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
8165 TCGv_i32 addr
, int size
)
8167 TCGv_i32 tmp
= tcg_temp_new_i32();
8168 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8173 TCGv_i32 tmp2
= tcg_temp_new_i32();
8174 TCGv_i64 t64
= tcg_temp_new_i64();
8176 /* For AArch32, architecturally the 32-bit word at the lowest
8177 * address is always Rt and the one at addr+4 is Rt2, even if
8178 * the CPU is big-endian. That means we don't want to do a
8179 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8180 * for an architecturally 64-bit access, but instead do a
8181 * 64-bit access using MO_BE if appropriate and then split
8183 * This only makes a difference for BE32 user-mode, where
8184 * frob64() must not flip the two halves of the 64-bit data
8185 * but this code must treat BE32 user-mode like BE32 system.
8187 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
8189 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
8190 tcg_temp_free(taddr
);
8191 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
8192 if (s
->be_data
== MO_BE
) {
8193 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
8195 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
8197 tcg_temp_free_i64(t64
);
8199 store_reg(s
, rt2
, tmp2
);
8201 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
8202 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
8205 store_reg(s
, rt
, tmp
);
8206 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
8209 static void gen_clrex(DisasContext
*s
)
8211 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8214 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
8215 TCGv_i32 addr
, int size
)
8217 TCGv_i32 t0
, t1
, t2
;
8220 TCGLabel
*done_label
;
8221 TCGLabel
*fail_label
;
8222 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8224 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8230 fail_label
= gen_new_label();
8231 done_label
= gen_new_label();
8232 extaddr
= tcg_temp_new_i64();
8233 tcg_gen_extu_i32_i64(extaddr
, addr
);
8234 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
8235 tcg_temp_free_i64(extaddr
);
8237 taddr
= gen_aa32_addr(s
, addr
, opc
);
8238 t0
= tcg_temp_new_i32();
8239 t1
= load_reg(s
, rt
);
8241 TCGv_i64 o64
= tcg_temp_new_i64();
8242 TCGv_i64 n64
= tcg_temp_new_i64();
8244 t2
= load_reg(s
, rt2
);
8245 /* For AArch32, architecturally the 32-bit word at the lowest
8246 * address is always Rt and the one at addr+4 is Rt2, even if
8247 * the CPU is big-endian. Since we're going to treat this as a
8248 * single 64-bit BE store, we need to put the two halves in the
8249 * opposite order for BE to LE, so that they end up in the right
8251 * We don't want gen_aa32_frob64() because that does the wrong
8252 * thing for BE32 usermode.
8254 if (s
->be_data
== MO_BE
) {
8255 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
8257 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
8259 tcg_temp_free_i32(t2
);
8261 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
8262 get_mem_index(s
), opc
);
8263 tcg_temp_free_i64(n64
);
8265 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
8266 tcg_gen_extrl_i64_i32(t0
, o64
);
8268 tcg_temp_free_i64(o64
);
8270 t2
= tcg_temp_new_i32();
8271 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
8272 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
8273 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
8274 tcg_temp_free_i32(t2
);
8276 tcg_temp_free_i32(t1
);
8277 tcg_temp_free(taddr
);
8278 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
8279 tcg_temp_free_i32(t0
);
8280 tcg_gen_br(done_label
);
8282 gen_set_label(fail_label
);
8283 tcg_gen_movi_i32(cpu_R
[rd
], 1);
8284 gen_set_label(done_label
);
8285 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8291 * @mode: mode field from insn (which stack to store to)
8292 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8293 * @writeback: true if writeback bit set
8295 * Generate code for the SRS (Store Return State) insn.
8297 static void gen_srs(DisasContext
*s
,
8298 uint32_t mode
, uint32_t amode
, bool writeback
)
8305 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8306 * and specified mode is monitor mode
8307 * - UNDEFINED in Hyp mode
8308 * - UNPREDICTABLE in User or System mode
8309 * - UNPREDICTABLE if the specified mode is:
8310 * -- not implemented
8311 * -- not a valid mode number
8312 * -- a mode that's at a higher exception level
8313 * -- Monitor, if we are Non-secure
8314 * For the UNPREDICTABLE cases we choose to UNDEF.
8316 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
8317 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
8321 if (s
->current_el
== 0 || s
->current_el
== 2) {
8326 case ARM_CPU_MODE_USR
:
8327 case ARM_CPU_MODE_FIQ
:
8328 case ARM_CPU_MODE_IRQ
:
8329 case ARM_CPU_MODE_SVC
:
8330 case ARM_CPU_MODE_ABT
:
8331 case ARM_CPU_MODE_UND
:
8332 case ARM_CPU_MODE_SYS
:
8334 case ARM_CPU_MODE_HYP
:
8335 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
8339 case ARM_CPU_MODE_MON
:
8340 /* No need to check specifically for "are we non-secure" because
8341 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8342 * so if this isn't EL3 then we must be non-secure.
8344 if (s
->current_el
!= 3) {
8353 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8354 default_exception_el(s
));
8358 addr
= tcg_temp_new_i32();
8359 tmp
= tcg_const_i32(mode
);
8360 /* get_r13_banked() will raise an exception if called from System mode */
8361 gen_set_condexec(s
);
8362 gen_set_pc_im(s
, s
->pc
- 4);
8363 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8364 tcg_temp_free_i32(tmp
);
8381 tcg_gen_addi_i32(addr
, addr
, offset
);
8382 tmp
= load_reg(s
, 14);
8383 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8384 tcg_temp_free_i32(tmp
);
8385 tmp
= load_cpu_field(spsr
);
8386 tcg_gen_addi_i32(addr
, addr
, 4);
8387 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8388 tcg_temp_free_i32(tmp
);
8406 tcg_gen_addi_i32(addr
, addr
, offset
);
8407 tmp
= tcg_const_i32(mode
);
8408 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8409 tcg_temp_free_i32(tmp
);
8411 tcg_temp_free_i32(addr
);
8412 s
->base
.is_jmp
= DISAS_UPDATE
;
8415 /* Generate a label used for skipping this instruction */
8416 static void arm_gen_condlabel(DisasContext
*s
)
8419 s
->condlabel
= gen_new_label();
8424 /* Skip this instruction if the ARM condition is false */
8425 static void arm_skip_unless(DisasContext
*s
, uint32_t cond
)
8427 arm_gen_condlabel(s
);
8428 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8431 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8433 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8440 /* M variants do not implement ARM mode; this must raise the INVSTATE
8441 * UsageFault exception.
8443 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8444 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8445 default_exception_el(s
));
8450 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8451 * choose to UNDEF. In ARMv5 and above the space is used
8452 * for miscellaneous unconditional instructions.
8456 /* Unconditional instructions. */
8457 if (((insn
>> 25) & 7) == 1) {
8458 /* NEON Data processing. */
8459 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8463 if (disas_neon_data_insn(s
, insn
)) {
8468 if ((insn
& 0x0f100000) == 0x04000000) {
8469 /* NEON load/store. */
8470 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8474 if (disas_neon_ls_insn(s
, insn
)) {
8479 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8481 if (disas_vfp_insn(s
, insn
)) {
8486 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8487 ((insn
& 0x0f30f010) == 0x0710f000)) {
8488 if ((insn
& (1 << 22)) == 0) {
8490 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8494 /* Otherwise PLD; v5TE+ */
8498 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8499 ((insn
& 0x0f70f010) == 0x0650f000)) {
8501 return; /* PLI; V7 */
8503 if (((insn
& 0x0f700000) == 0x04100000) ||
8504 ((insn
& 0x0f700010) == 0x06100000)) {
8505 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8508 return; /* v7MP: Unallocated memory hint: must NOP */
8511 if ((insn
& 0x0ffffdff) == 0x01010000) {
8514 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8515 gen_helper_setend(cpu_env
);
8516 s
->base
.is_jmp
= DISAS_UPDATE
;
8519 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8520 switch ((insn
>> 4) & 0xf) {
8528 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8531 /* We need to break the TB after this insn to execute
8532 * self-modifying code correctly and also to take
8533 * any pending interrupts immediately.
8535 gen_goto_tb(s
, 0, s
->pc
& ~1);
8538 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
8542 * TODO: There is no speculation barrier opcode
8543 * for TCG; MB and end the TB instead.
8545 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8546 gen_goto_tb(s
, 0, s
->pc
& ~1);
8551 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8554 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8556 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8562 rn
= (insn
>> 16) & 0xf;
8563 addr
= load_reg(s
, rn
);
8564 i
= (insn
>> 23) & 3;
8566 case 0: offset
= -4; break; /* DA */
8567 case 1: offset
= 0; break; /* IA */
8568 case 2: offset
= -8; break; /* DB */
8569 case 3: offset
= 4; break; /* IB */
8573 tcg_gen_addi_i32(addr
, addr
, offset
);
8574 /* Load PC into tmp and CPSR into tmp2. */
8575 tmp
= tcg_temp_new_i32();
8576 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8577 tcg_gen_addi_i32(addr
, addr
, 4);
8578 tmp2
= tcg_temp_new_i32();
8579 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8580 if (insn
& (1 << 21)) {
8581 /* Base writeback. */
8583 case 0: offset
= -8; break;
8584 case 1: offset
= 4; break;
8585 case 2: offset
= -4; break;
8586 case 3: offset
= 0; break;
8590 tcg_gen_addi_i32(addr
, addr
, offset
);
8591 store_reg(s
, rn
, addr
);
8593 tcg_temp_free_i32(addr
);
8595 gen_rfe(s
, tmp
, tmp2
);
8597 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8598 /* branch link and change to thumb (blx <offset>) */
8601 val
= (uint32_t)s
->pc
;
8602 tmp
= tcg_temp_new_i32();
8603 tcg_gen_movi_i32(tmp
, val
);
8604 store_reg(s
, 14, tmp
);
8605 /* Sign-extend the 24-bit offset */
8606 offset
= (((int32_t)insn
) << 8) >> 8;
8607 /* offset * 4 + bit24 * 2 + (thumb bit) */
8608 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8609 /* pipeline offset */
8611 /* protected by ARCH(5); above, near the start of uncond block */
8614 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8615 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8616 /* iWMMXt register transfer. */
8617 if (extract32(s
->c15_cpar
, 1, 1)) {
8618 if (!disas_iwmmxt_insn(s
, insn
)) {
8623 } else if ((insn
& 0x0e000a00) == 0x0c000800
8624 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8625 if (disas_neon_insn_3same_ext(s
, insn
)) {
8629 } else if ((insn
& 0x0f000a00) == 0x0e000800
8630 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8631 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
8635 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8636 /* Coprocessor double register transfer. */
8638 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8639 /* Additional coprocessor register transfer. */
8640 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8643 /* cps (privileged) */
8647 if (insn
& (1 << 19)) {
8648 if (insn
& (1 << 8))
8650 if (insn
& (1 << 7))
8652 if (insn
& (1 << 6))
8654 if (insn
& (1 << 18))
8657 if (insn
& (1 << 17)) {
8659 val
|= (insn
& 0x1f);
8662 gen_set_psr_im(s
, mask
, 0, val
);
8669 /* if not always execute, we generate a conditional jump to
8671 arm_skip_unless(s
, cond
);
8673 if ((insn
& 0x0f900000) == 0x03000000) {
8674 if ((insn
& (1 << 21)) == 0) {
8676 rd
= (insn
>> 12) & 0xf;
8677 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8678 if ((insn
& (1 << 22)) == 0) {
8680 tmp
= tcg_temp_new_i32();
8681 tcg_gen_movi_i32(tmp
, val
);
8684 tmp
= load_reg(s
, rd
);
8685 tcg_gen_ext16u_i32(tmp
, tmp
);
8686 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8688 store_reg(s
, rd
, tmp
);
8690 if (((insn
>> 12) & 0xf) != 0xf)
8692 if (((insn
>> 16) & 0xf) == 0) {
8693 gen_nop_hint(s
, insn
& 0xff);
8695 /* CPSR = immediate */
8697 shift
= ((insn
>> 8) & 0xf) * 2;
8699 val
= (val
>> shift
) | (val
<< (32 - shift
));
8700 i
= ((insn
& (1 << 22)) != 0);
8701 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8707 } else if ((insn
& 0x0f900000) == 0x01000000
8708 && (insn
& 0x00000090) != 0x00000090) {
8709 /* miscellaneous instructions */
8710 op1
= (insn
>> 21) & 3;
8711 sh
= (insn
>> 4) & 0xf;
8714 case 0x0: /* MSR, MRS */
8715 if (insn
& (1 << 9)) {
8716 /* MSR (banked) and MRS (banked) */
8717 int sysm
= extract32(insn
, 16, 4) |
8718 (extract32(insn
, 8, 1) << 4);
8719 int r
= extract32(insn
, 22, 1);
8723 gen_msr_banked(s
, r
, sysm
, rm
);
8726 int rd
= extract32(insn
, 12, 4);
8728 gen_mrs_banked(s
, r
, sysm
, rd
);
8733 /* MSR, MRS (for PSRs) */
8736 tmp
= load_reg(s
, rm
);
8737 i
= ((op1
& 2) != 0);
8738 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8742 rd
= (insn
>> 12) & 0xf;
8746 tmp
= load_cpu_field(spsr
);
8748 tmp
= tcg_temp_new_i32();
8749 gen_helper_cpsr_read(tmp
, cpu_env
);
8751 store_reg(s
, rd
, tmp
);
8756 /* branch/exchange thumb (bx). */
8758 tmp
= load_reg(s
, rm
);
8760 } else if (op1
== 3) {
8763 rd
= (insn
>> 12) & 0xf;
8764 tmp
= load_reg(s
, rm
);
8765 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8766 store_reg(s
, rd
, tmp
);
8774 /* Trivial implementation equivalent to bx. */
8775 tmp
= load_reg(s
, rm
);
8786 /* branch link/exchange thumb (blx) */
8787 tmp
= load_reg(s
, rm
);
8788 tmp2
= tcg_temp_new_i32();
8789 tcg_gen_movi_i32(tmp2
, s
->pc
);
8790 store_reg(s
, 14, tmp2
);
8796 uint32_t c
= extract32(insn
, 8, 4);
8798 /* Check this CPU supports ARMv8 CRC instructions.
8799 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8800 * Bits 8, 10 and 11 should be zero.
8802 if (!dc_isar_feature(aa32_crc32
, s
) || op1
== 0x3 || (c
& 0xd) != 0) {
8806 rn
= extract32(insn
, 16, 4);
8807 rd
= extract32(insn
, 12, 4);
8809 tmp
= load_reg(s
, rn
);
8810 tmp2
= load_reg(s
, rm
);
8812 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8813 } else if (op1
== 1) {
8814 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8816 tmp3
= tcg_const_i32(1 << op1
);
8818 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8820 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8822 tcg_temp_free_i32(tmp2
);
8823 tcg_temp_free_i32(tmp3
);
8824 store_reg(s
, rd
, tmp
);
8827 case 0x5: /* saturating add/subtract */
8829 rd
= (insn
>> 12) & 0xf;
8830 rn
= (insn
>> 16) & 0xf;
8831 tmp
= load_reg(s
, rm
);
8832 tmp2
= load_reg(s
, rn
);
8834 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8836 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8838 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8839 tcg_temp_free_i32(tmp2
);
8840 store_reg(s
, rd
, tmp
);
8842 case 0x6: /* ERET */
8846 if (!arm_dc_feature(s
, ARM_FEATURE_V7VE
)) {
8849 if ((insn
& 0x000fff0f) != 0x0000000e) {
8850 /* UNPREDICTABLE; we choose to UNDEF */
8854 if (s
->current_el
== 2) {
8855 tmp
= load_cpu_field(elr_el
[2]);
8857 tmp
= load_reg(s
, 14);
8859 gen_exception_return(s
, tmp
);
8863 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8872 gen_exception_bkpt_insn(s
, 4, syn_aa32_bkpt(imm16
, false));
8875 /* Hypervisor call (v7) */
8883 /* Secure monitor call (v6+) */
8891 g_assert_not_reached();
8895 case 0x8: /* signed multiply */
8900 rs
= (insn
>> 8) & 0xf;
8901 rn
= (insn
>> 12) & 0xf;
8902 rd
= (insn
>> 16) & 0xf;
8904 /* (32 * 16) >> 16 */
8905 tmp
= load_reg(s
, rm
);
8906 tmp2
= load_reg(s
, rs
);
8908 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8911 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8912 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8913 tmp
= tcg_temp_new_i32();
8914 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8915 tcg_temp_free_i64(tmp64
);
8916 if ((sh
& 2) == 0) {
8917 tmp2
= load_reg(s
, rn
);
8918 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8919 tcg_temp_free_i32(tmp2
);
8921 store_reg(s
, rd
, tmp
);
8924 tmp
= load_reg(s
, rm
);
8925 tmp2
= load_reg(s
, rs
);
8926 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8927 tcg_temp_free_i32(tmp2
);
8929 tmp64
= tcg_temp_new_i64();
8930 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8931 tcg_temp_free_i32(tmp
);
8932 gen_addq(s
, tmp64
, rn
, rd
);
8933 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8934 tcg_temp_free_i64(tmp64
);
8937 tmp2
= load_reg(s
, rn
);
8938 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8939 tcg_temp_free_i32(tmp2
);
8941 store_reg(s
, rd
, tmp
);
8948 } else if (((insn
& 0x0e000000) == 0 &&
8949 (insn
& 0x00000090) != 0x90) ||
8950 ((insn
& 0x0e000000) == (1 << 25))) {
8951 int set_cc
, logic_cc
, shiftop
;
8953 op1
= (insn
>> 21) & 0xf;
8954 set_cc
= (insn
>> 20) & 1;
8955 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8957 /* data processing instruction */
8958 if (insn
& (1 << 25)) {
8959 /* immediate operand */
8961 shift
= ((insn
>> 8) & 0xf) * 2;
8963 val
= (val
>> shift
) | (val
<< (32 - shift
));
8965 tmp2
= tcg_temp_new_i32();
8966 tcg_gen_movi_i32(tmp2
, val
);
8967 if (logic_cc
&& shift
) {
8968 gen_set_CF_bit31(tmp2
);
8973 tmp2
= load_reg(s
, rm
);
8974 shiftop
= (insn
>> 5) & 3;
8975 if (!(insn
& (1 << 4))) {
8976 shift
= (insn
>> 7) & 0x1f;
8977 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8979 rs
= (insn
>> 8) & 0xf;
8980 tmp
= load_reg(s
, rs
);
8981 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8984 if (op1
!= 0x0f && op1
!= 0x0d) {
8985 rn
= (insn
>> 16) & 0xf;
8986 tmp
= load_reg(s
, rn
);
8990 rd
= (insn
>> 12) & 0xf;
8993 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8997 store_reg_bx(s
, rd
, tmp
);
9000 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9004 store_reg_bx(s
, rd
, tmp
);
9007 if (set_cc
&& rd
== 15) {
9008 /* SUBS r15, ... is used for exception return. */
9012 gen_sub_CC(tmp
, tmp
, tmp2
);
9013 gen_exception_return(s
, tmp
);
9016 gen_sub_CC(tmp
, tmp
, tmp2
);
9018 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9020 store_reg_bx(s
, rd
, tmp
);
9025 gen_sub_CC(tmp
, tmp2
, tmp
);
9027 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9029 store_reg_bx(s
, rd
, tmp
);
9033 gen_add_CC(tmp
, tmp
, tmp2
);
9035 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9037 store_reg_bx(s
, rd
, tmp
);
9041 gen_adc_CC(tmp
, tmp
, tmp2
);
9043 gen_add_carry(tmp
, tmp
, tmp2
);
9045 store_reg_bx(s
, rd
, tmp
);
9049 gen_sbc_CC(tmp
, tmp
, tmp2
);
9051 gen_sub_carry(tmp
, tmp
, tmp2
);
9053 store_reg_bx(s
, rd
, tmp
);
9057 gen_sbc_CC(tmp
, tmp2
, tmp
);
9059 gen_sub_carry(tmp
, tmp2
, tmp
);
9061 store_reg_bx(s
, rd
, tmp
);
9065 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9068 tcg_temp_free_i32(tmp
);
9072 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9075 tcg_temp_free_i32(tmp
);
9079 gen_sub_CC(tmp
, tmp
, tmp2
);
9081 tcg_temp_free_i32(tmp
);
9085 gen_add_CC(tmp
, tmp
, tmp2
);
9087 tcg_temp_free_i32(tmp
);
9090 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9094 store_reg_bx(s
, rd
, tmp
);
9097 if (logic_cc
&& rd
== 15) {
9098 /* MOVS r15, ... is used for exception return. */
9102 gen_exception_return(s
, tmp2
);
9107 store_reg_bx(s
, rd
, tmp2
);
9111 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9115 store_reg_bx(s
, rd
, tmp
);
9119 tcg_gen_not_i32(tmp2
, tmp2
);
9123 store_reg_bx(s
, rd
, tmp2
);
9126 if (op1
!= 0x0f && op1
!= 0x0d) {
9127 tcg_temp_free_i32(tmp2
);
9130 /* other instructions */
9131 op1
= (insn
>> 24) & 0xf;
9135 /* multiplies, extra load/stores */
9136 sh
= (insn
>> 5) & 3;
9139 rd
= (insn
>> 16) & 0xf;
9140 rn
= (insn
>> 12) & 0xf;
9141 rs
= (insn
>> 8) & 0xf;
9143 op1
= (insn
>> 20) & 0xf;
9145 case 0: case 1: case 2: case 3: case 6:
9147 tmp
= load_reg(s
, rs
);
9148 tmp2
= load_reg(s
, rm
);
9149 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9150 tcg_temp_free_i32(tmp2
);
9151 if (insn
& (1 << 22)) {
9152 /* Subtract (mls) */
9154 tmp2
= load_reg(s
, rn
);
9155 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9156 tcg_temp_free_i32(tmp2
);
9157 } else if (insn
& (1 << 21)) {
9159 tmp2
= load_reg(s
, rn
);
9160 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9161 tcg_temp_free_i32(tmp2
);
9163 if (insn
& (1 << 20))
9165 store_reg(s
, rd
, tmp
);
9168 /* 64 bit mul double accumulate (UMAAL) */
9170 tmp
= load_reg(s
, rs
);
9171 tmp2
= load_reg(s
, rm
);
9172 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9173 gen_addq_lo(s
, tmp64
, rn
);
9174 gen_addq_lo(s
, tmp64
, rd
);
9175 gen_storeq_reg(s
, rn
, rd
, tmp64
);
9176 tcg_temp_free_i64(tmp64
);
9178 case 8: case 9: case 10: case 11:
9179 case 12: case 13: case 14: case 15:
9180 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9181 tmp
= load_reg(s
, rs
);
9182 tmp2
= load_reg(s
, rm
);
9183 if (insn
& (1 << 22)) {
9184 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
9186 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
9188 if (insn
& (1 << 21)) { /* mult accumulate */
9189 TCGv_i32 al
= load_reg(s
, rn
);
9190 TCGv_i32 ah
= load_reg(s
, rd
);
9191 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
9192 tcg_temp_free_i32(al
);
9193 tcg_temp_free_i32(ah
);
9195 if (insn
& (1 << 20)) {
9196 gen_logicq_cc(tmp
, tmp2
);
9198 store_reg(s
, rn
, tmp
);
9199 store_reg(s
, rd
, tmp2
);
9205 rn
= (insn
>> 16) & 0xf;
9206 rd
= (insn
>> 12) & 0xf;
9207 if (insn
& (1 << 23)) {
9208 /* load/store exclusive */
9209 bool is_ld
= extract32(insn
, 20, 1);
9210 bool is_lasr
= !extract32(insn
, 8, 1);
9211 int op2
= (insn
>> 8) & 3;
9212 op1
= (insn
>> 21) & 0x3;
9215 case 0: /* lda/stl */
9221 case 1: /* reserved */
9223 case 2: /* ldaex/stlex */
9226 case 3: /* ldrex/strex */
9235 addr
= tcg_temp_local_new_i32();
9236 load_reg_var(s
, addr
, rn
);
9238 if (is_lasr
&& !is_ld
) {
9239 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
9244 tmp
= tcg_temp_new_i32();
9247 gen_aa32_ld32u_iss(s
, tmp
, addr
,
9252 gen_aa32_ld8u_iss(s
, tmp
, addr
,
9257 gen_aa32_ld16u_iss(s
, tmp
, addr
,
9264 store_reg(s
, rd
, tmp
);
9267 tmp
= load_reg(s
, rm
);
9270 gen_aa32_st32_iss(s
, tmp
, addr
,
9275 gen_aa32_st8_iss(s
, tmp
, addr
,
9280 gen_aa32_st16_iss(s
, tmp
, addr
,
9287 tcg_temp_free_i32(tmp
);
9292 gen_load_exclusive(s
, rd
, 15, addr
, 2);
9294 case 1: /* ldrexd */
9295 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
9297 case 2: /* ldrexb */
9298 gen_load_exclusive(s
, rd
, 15, addr
, 0);
9300 case 3: /* ldrexh */
9301 gen_load_exclusive(s
, rd
, 15, addr
, 1);
9310 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
9312 case 1: /* strexd */
9313 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
9315 case 2: /* strexb */
9316 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
9318 case 3: /* strexh */
9319 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
9325 tcg_temp_free_i32(addr
);
9327 if (is_lasr
&& is_ld
) {
9328 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
9330 } else if ((insn
& 0x00300f00) == 0) {
9331 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9336 TCGMemOp opc
= s
->be_data
;
9340 if (insn
& (1 << 22)) {
9343 opc
|= MO_UL
| MO_ALIGN
;
9346 addr
= load_reg(s
, rn
);
9347 taddr
= gen_aa32_addr(s
, addr
, opc
);
9348 tcg_temp_free_i32(addr
);
9350 tmp
= load_reg(s
, rm
);
9351 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
9352 get_mem_index(s
), opc
);
9353 tcg_temp_free(taddr
);
9354 store_reg(s
, rd
, tmp
);
9361 bool load
= insn
& (1 << 20);
9362 bool wbit
= insn
& (1 << 21);
9363 bool pbit
= insn
& (1 << 24);
9364 bool doubleword
= false;
9367 /* Misc load/store */
9368 rn
= (insn
>> 16) & 0xf;
9369 rd
= (insn
>> 12) & 0xf;
9371 /* ISS not valid if writeback */
9372 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
9374 if (!load
&& (sh
& 2)) {
9378 /* UNPREDICTABLE; we choose to UNDEF */
9381 load
= (sh
& 1) == 0;
9385 addr
= load_reg(s
, rn
);
9387 gen_add_datah_offset(s
, insn
, 0, addr
);
9394 tmp
= load_reg(s
, rd
);
9395 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9396 tcg_temp_free_i32(tmp
);
9397 tcg_gen_addi_i32(addr
, addr
, 4);
9398 tmp
= load_reg(s
, rd
+ 1);
9399 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9400 tcg_temp_free_i32(tmp
);
9403 tmp
= tcg_temp_new_i32();
9404 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9405 store_reg(s
, rd
, tmp
);
9406 tcg_gen_addi_i32(addr
, addr
, 4);
9407 tmp
= tcg_temp_new_i32();
9408 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9411 address_offset
= -4;
9414 tmp
= tcg_temp_new_i32();
9417 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9421 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9426 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9432 tmp
= load_reg(s
, rd
);
9433 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9434 tcg_temp_free_i32(tmp
);
9436 /* Perform base writeback before the loaded value to
9437 ensure correct behavior with overlapping index registers.
9438 ldrd with base writeback is undefined if the
9439 destination and index registers overlap. */
9441 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9442 store_reg(s
, rn
, addr
);
9445 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9446 store_reg(s
, rn
, addr
);
9448 tcg_temp_free_i32(addr
);
9451 /* Complete the load. */
9452 store_reg(s
, rd
, tmp
);
9461 if (insn
& (1 << 4)) {
9463 /* Armv6 Media instructions. */
9465 rn
= (insn
>> 16) & 0xf;
9466 rd
= (insn
>> 12) & 0xf;
9467 rs
= (insn
>> 8) & 0xf;
9468 switch ((insn
>> 23) & 3) {
9469 case 0: /* Parallel add/subtract. */
9470 op1
= (insn
>> 20) & 7;
9471 tmp
= load_reg(s
, rn
);
9472 tmp2
= load_reg(s
, rm
);
9473 sh
= (insn
>> 5) & 7;
9474 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9476 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9477 tcg_temp_free_i32(tmp2
);
9478 store_reg(s
, rd
, tmp
);
9481 if ((insn
& 0x00700020) == 0) {
9482 /* Halfword pack. */
9483 tmp
= load_reg(s
, rn
);
9484 tmp2
= load_reg(s
, rm
);
9485 shift
= (insn
>> 7) & 0x1f;
9486 if (insn
& (1 << 6)) {
9490 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9491 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9492 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9496 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9497 tcg_gen_ext16u_i32(tmp
, tmp
);
9498 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9500 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9501 tcg_temp_free_i32(tmp2
);
9502 store_reg(s
, rd
, tmp
);
9503 } else if ((insn
& 0x00200020) == 0x00200000) {
9505 tmp
= load_reg(s
, rm
);
9506 shift
= (insn
>> 7) & 0x1f;
9507 if (insn
& (1 << 6)) {
9510 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9512 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9514 sh
= (insn
>> 16) & 0x1f;
9515 tmp2
= tcg_const_i32(sh
);
9516 if (insn
& (1 << 22))
9517 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9519 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9520 tcg_temp_free_i32(tmp2
);
9521 store_reg(s
, rd
, tmp
);
9522 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9524 tmp
= load_reg(s
, rm
);
9525 sh
= (insn
>> 16) & 0x1f;
9526 tmp2
= tcg_const_i32(sh
);
9527 if (insn
& (1 << 22))
9528 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9530 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9531 tcg_temp_free_i32(tmp2
);
9532 store_reg(s
, rd
, tmp
);
9533 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9535 tmp
= load_reg(s
, rn
);
9536 tmp2
= load_reg(s
, rm
);
9537 tmp3
= tcg_temp_new_i32();
9538 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9539 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9540 tcg_temp_free_i32(tmp3
);
9541 tcg_temp_free_i32(tmp2
);
9542 store_reg(s
, rd
, tmp
);
9543 } else if ((insn
& 0x000003e0) == 0x00000060) {
9544 tmp
= load_reg(s
, rm
);
9545 shift
= (insn
>> 10) & 3;
9546 /* ??? In many cases it's not necessary to do a
9547 rotate, a shift is sufficient. */
9549 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9550 op1
= (insn
>> 20) & 7;
9552 case 0: gen_sxtb16(tmp
); break;
9553 case 2: gen_sxtb(tmp
); break;
9554 case 3: gen_sxth(tmp
); break;
9555 case 4: gen_uxtb16(tmp
); break;
9556 case 6: gen_uxtb(tmp
); break;
9557 case 7: gen_uxth(tmp
); break;
9558 default: goto illegal_op
;
9561 tmp2
= load_reg(s
, rn
);
9562 if ((op1
& 3) == 0) {
9563 gen_add16(tmp
, tmp2
);
9565 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9566 tcg_temp_free_i32(tmp2
);
9569 store_reg(s
, rd
, tmp
);
9570 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9572 tmp
= load_reg(s
, rm
);
9573 if (insn
& (1 << 22)) {
9574 if (insn
& (1 << 7)) {
9578 gen_helper_rbit(tmp
, tmp
);
9581 if (insn
& (1 << 7))
9584 tcg_gen_bswap32_i32(tmp
, tmp
);
9586 store_reg(s
, rd
, tmp
);
9591 case 2: /* Multiplies (Type 3). */
9592 switch ((insn
>> 20) & 0x7) {
9594 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9595 /* op2 not 00x or 11x : UNDEF */
9598 /* Signed multiply most significant [accumulate].
9599 (SMMUL, SMMLA, SMMLS) */
9600 tmp
= load_reg(s
, rm
);
9601 tmp2
= load_reg(s
, rs
);
9602 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9605 tmp
= load_reg(s
, rd
);
9606 if (insn
& (1 << 6)) {
9607 tmp64
= gen_subq_msw(tmp64
, tmp
);
9609 tmp64
= gen_addq_msw(tmp64
, tmp
);
9612 if (insn
& (1 << 5)) {
9613 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9615 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9616 tmp
= tcg_temp_new_i32();
9617 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9618 tcg_temp_free_i64(tmp64
);
9619 store_reg(s
, rn
, tmp
);
9623 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9624 if (insn
& (1 << 7)) {
9627 tmp
= load_reg(s
, rm
);
9628 tmp2
= load_reg(s
, rs
);
9629 if (insn
& (1 << 5))
9630 gen_swap_half(tmp2
);
9631 gen_smul_dual(tmp
, tmp2
);
9632 if (insn
& (1 << 22)) {
9633 /* smlald, smlsld */
9636 tmp64
= tcg_temp_new_i64();
9637 tmp64_2
= tcg_temp_new_i64();
9638 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9639 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9640 tcg_temp_free_i32(tmp
);
9641 tcg_temp_free_i32(tmp2
);
9642 if (insn
& (1 << 6)) {
9643 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9645 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9647 tcg_temp_free_i64(tmp64_2
);
9648 gen_addq(s
, tmp64
, rd
, rn
);
9649 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9650 tcg_temp_free_i64(tmp64
);
9652 /* smuad, smusd, smlad, smlsd */
9653 if (insn
& (1 << 6)) {
9654 /* This subtraction cannot overflow. */
9655 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9657 /* This addition cannot overflow 32 bits;
9658 * however it may overflow considered as a
9659 * signed operation, in which case we must set
9662 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9664 tcg_temp_free_i32(tmp2
);
9667 tmp2
= load_reg(s
, rd
);
9668 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9669 tcg_temp_free_i32(tmp2
);
9671 store_reg(s
, rn
, tmp
);
9677 if (!dc_isar_feature(arm_div
, s
)) {
9680 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9683 tmp
= load_reg(s
, rm
);
9684 tmp2
= load_reg(s
, rs
);
9685 if (insn
& (1 << 21)) {
9686 gen_helper_udiv(tmp
, tmp
, tmp2
);
9688 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9690 tcg_temp_free_i32(tmp2
);
9691 store_reg(s
, rn
, tmp
);
9698 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9700 case 0: /* Unsigned sum of absolute differences. */
9702 tmp
= load_reg(s
, rm
);
9703 tmp2
= load_reg(s
, rs
);
9704 gen_helper_usad8(tmp
, tmp
, tmp2
);
9705 tcg_temp_free_i32(tmp2
);
9707 tmp2
= load_reg(s
, rd
);
9708 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9709 tcg_temp_free_i32(tmp2
);
9711 store_reg(s
, rn
, tmp
);
9713 case 0x20: case 0x24: case 0x28: case 0x2c:
9714 /* Bitfield insert/clear. */
9716 shift
= (insn
>> 7) & 0x1f;
9717 i
= (insn
>> 16) & 0x1f;
9719 /* UNPREDICTABLE; we choose to UNDEF */
9724 tmp
= tcg_temp_new_i32();
9725 tcg_gen_movi_i32(tmp
, 0);
9727 tmp
= load_reg(s
, rm
);
9730 tmp2
= load_reg(s
, rd
);
9731 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9732 tcg_temp_free_i32(tmp2
);
9734 store_reg(s
, rd
, tmp
);
9736 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9737 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9739 tmp
= load_reg(s
, rm
);
9740 shift
= (insn
>> 7) & 0x1f;
9741 i
= ((insn
>> 16) & 0x1f) + 1;
9746 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9748 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9751 store_reg(s
, rd
, tmp
);
9761 /* Check for undefined extension instructions
9762 * per the ARM Bible IE:
9763 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9765 sh
= (0xf << 20) | (0xf << 4);
9766 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9770 /* load/store byte/word */
9771 rn
= (insn
>> 16) & 0xf;
9772 rd
= (insn
>> 12) & 0xf;
9773 tmp2
= load_reg(s
, rn
);
9774 if ((insn
& 0x01200000) == 0x00200000) {
9776 i
= get_a32_user_mem_index(s
);
9778 i
= get_mem_index(s
);
9780 if (insn
& (1 << 24))
9781 gen_add_data_offset(s
, insn
, tmp2
);
9782 if (insn
& (1 << 20)) {
9784 tmp
= tcg_temp_new_i32();
9785 if (insn
& (1 << 22)) {
9786 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9788 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9792 tmp
= load_reg(s
, rd
);
9793 if (insn
& (1 << 22)) {
9794 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9796 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9798 tcg_temp_free_i32(tmp
);
9800 if (!(insn
& (1 << 24))) {
9801 gen_add_data_offset(s
, insn
, tmp2
);
9802 store_reg(s
, rn
, tmp2
);
9803 } else if (insn
& (1 << 21)) {
9804 store_reg(s
, rn
, tmp2
);
9806 tcg_temp_free_i32(tmp2
);
9808 if (insn
& (1 << 20)) {
9809 /* Complete the load. */
9810 store_reg_from_load(s
, rd
, tmp
);
9816 int j
, n
, loaded_base
;
9817 bool exc_return
= false;
9818 bool is_load
= extract32(insn
, 20, 1);
9820 TCGv_i32 loaded_var
;
9821 /* load/store multiple words */
9822 /* XXX: store correct base if write back */
9823 if (insn
& (1 << 22)) {
9824 /* LDM (user), LDM (exception return) and STM (user) */
9826 goto illegal_op
; /* only usable in supervisor mode */
9828 if (is_load
&& extract32(insn
, 15, 1)) {
9834 rn
= (insn
>> 16) & 0xf;
9835 addr
= load_reg(s
, rn
);
9837 /* compute total size */
9842 if (insn
& (1 << i
))
9845 /* XXX: test invalid n == 0 case ? */
9846 if (insn
& (1 << 23)) {
9847 if (insn
& (1 << 24)) {
9849 tcg_gen_addi_i32(addr
, addr
, 4);
9851 /* post increment */
9854 if (insn
& (1 << 24)) {
9856 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9858 /* post decrement */
9860 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9865 if (insn
& (1 << i
)) {
9868 tmp
= tcg_temp_new_i32();
9869 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9871 tmp2
= tcg_const_i32(i
);
9872 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9873 tcg_temp_free_i32(tmp2
);
9874 tcg_temp_free_i32(tmp
);
9875 } else if (i
== rn
) {
9878 } else if (i
== 15 && exc_return
) {
9879 store_pc_exc_ret(s
, tmp
);
9881 store_reg_from_load(s
, i
, tmp
);
9886 /* special case: r15 = PC + 8 */
9887 val
= (long)s
->pc
+ 4;
9888 tmp
= tcg_temp_new_i32();
9889 tcg_gen_movi_i32(tmp
, val
);
9891 tmp
= tcg_temp_new_i32();
9892 tmp2
= tcg_const_i32(i
);
9893 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9894 tcg_temp_free_i32(tmp2
);
9896 tmp
= load_reg(s
, i
);
9898 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9899 tcg_temp_free_i32(tmp
);
9902 /* no need to add after the last transfer */
9904 tcg_gen_addi_i32(addr
, addr
, 4);
9907 if (insn
& (1 << 21)) {
9909 if (insn
& (1 << 23)) {
9910 if (insn
& (1 << 24)) {
9913 /* post increment */
9914 tcg_gen_addi_i32(addr
, addr
, 4);
9917 if (insn
& (1 << 24)) {
9920 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9922 /* post decrement */
9923 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9926 store_reg(s
, rn
, addr
);
9928 tcg_temp_free_i32(addr
);
9931 store_reg(s
, rn
, loaded_var
);
9934 /* Restore CPSR from SPSR. */
9935 tmp
= load_cpu_field(spsr
);
9936 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
9939 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9940 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
9943 tcg_temp_free_i32(tmp
);
9944 /* Must exit loop to check un-masked IRQs */
9945 s
->base
.is_jmp
= DISAS_EXIT
;
9954 /* branch (and link) */
9955 val
= (int32_t)s
->pc
;
9956 if (insn
& (1 << 24)) {
9957 tmp
= tcg_temp_new_i32();
9958 tcg_gen_movi_i32(tmp
, val
);
9959 store_reg(s
, 14, tmp
);
9961 offset
= sextract32(insn
<< 2, 0, 26);
9969 if (((insn
>> 8) & 0xe) == 10) {
9971 if (disas_vfp_insn(s
, insn
)) {
9974 } else if (disas_coproc_insn(s
, insn
)) {
9981 gen_set_pc_im(s
, s
->pc
);
9982 s
->svc_imm
= extract32(insn
, 0, 24);
9983 s
->base
.is_jmp
= DISAS_SWI
;
9987 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9988 default_exception_el(s
));
9994 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t insn
)
9996 /* Return true if this is a 16 bit instruction. We must be precise
9997 * about this (matching the decode). We assume that s->pc still
9998 * points to the first 16 bits of the insn.
10000 if ((insn
>> 11) < 0x1d) {
10001 /* Definitely a 16-bit instruction */
10005 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10006 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10007 * end up actually treating this as two 16-bit insns, though,
10008 * if it's half of a bl/blx pair that might span a page boundary.
10010 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
) ||
10011 arm_dc_feature(s
, ARM_FEATURE_M
)) {
10012 /* Thumb2 cores (including all M profile ones) always treat
10013 * 32-bit insns as 32-bit.
10018 if ((insn
>> 11) == 0x1e && s
->pc
- s
->page_start
< TARGET_PAGE_SIZE
- 3) {
10019 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10020 * is not on the next page; we merge this into a 32-bit
10025 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10026 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10027 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10028 * -- handle as single 16 bit insn
10033 /* Return true if this is a Thumb-2 logical op. */
10035 thumb2_logic_op(int op
)
10040 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10041 then set condition code flags based on the result of the operation.
10042 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10043 to the high bit of T1.
10044 Returns zero if the opcode is valid. */
10047 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
10048 TCGv_i32 t0
, TCGv_i32 t1
)
10055 tcg_gen_and_i32(t0
, t0
, t1
);
10059 tcg_gen_andc_i32(t0
, t0
, t1
);
10063 tcg_gen_or_i32(t0
, t0
, t1
);
10067 tcg_gen_orc_i32(t0
, t0
, t1
);
10071 tcg_gen_xor_i32(t0
, t0
, t1
);
10076 gen_add_CC(t0
, t0
, t1
);
10078 tcg_gen_add_i32(t0
, t0
, t1
);
10082 gen_adc_CC(t0
, t0
, t1
);
10088 gen_sbc_CC(t0
, t0
, t1
);
10090 gen_sub_carry(t0
, t0
, t1
);
10095 gen_sub_CC(t0
, t0
, t1
);
10097 tcg_gen_sub_i32(t0
, t0
, t1
);
10101 gen_sub_CC(t0
, t1
, t0
);
10103 tcg_gen_sub_i32(t0
, t1
, t0
);
10105 default: /* 5, 6, 7, 9, 12, 15. */
10111 gen_set_CF_bit31(t1
);
10116 /* Translate a 32-bit thumb instruction. */
10117 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
10119 uint32_t imm
, shift
, offset
;
10120 uint32_t rd
, rn
, rm
, rs
;
10132 * ARMv6-M supports a limited subset of Thumb2 instructions.
10133 * Other Thumb1 architectures allow only 32-bit
10134 * combined BL/BLX prefix and suffix.
10136 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
10137 !arm_dc_feature(s
, ARM_FEATURE_V7
)) {
10139 bool found
= false;
10140 static const uint32_t armv6m_insn
[] = {0xf3808000 /* msr */,
10141 0xf3b08040 /* dsb */,
10142 0xf3b08050 /* dmb */,
10143 0xf3b08060 /* isb */,
10144 0xf3e08000 /* mrs */,
10145 0xf000d000 /* bl */};
10146 static const uint32_t armv6m_mask
[] = {0xffe0d000,
10153 for (i
= 0; i
< ARRAY_SIZE(armv6m_insn
); i
++) {
10154 if ((insn
& armv6m_mask
[i
]) == armv6m_insn
[i
]) {
10162 } else if ((insn
& 0xf800e800) != 0xf000e800) {
10166 rn
= (insn
>> 16) & 0xf;
10167 rs
= (insn
>> 12) & 0xf;
10168 rd
= (insn
>> 8) & 0xf;
10170 switch ((insn
>> 25) & 0xf) {
10171 case 0: case 1: case 2: case 3:
10172 /* 16-bit instructions. Should never happen. */
10175 if (insn
& (1 << 22)) {
10176 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10177 * - load/store doubleword, load/store exclusive, ldacq/strel,
10178 * table branch, TT.
10180 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_M
) &&
10181 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10182 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10184 * The bulk of the behaviour for this instruction is implemented
10185 * in v7m_handle_execute_nsc(), which deals with the insn when
10186 * it is executed by a CPU in non-secure state from memory
10187 * which is Secure & NonSecure-Callable.
10188 * Here we only need to handle the remaining cases:
10189 * * in NS memory (including the "security extension not
10190 * implemented" case) : NOP
10191 * * in S memory but CPU already secure (clear IT bits)
10192 * We know that the attribute for the memory this insn is
10193 * in must match the current CPU state, because otherwise
10194 * get_phys_addr_pmsav8 would have generated an exception.
10196 if (s
->v8m_secure
) {
10197 /* Like the IT insn, we don't need to generate any code */
10198 s
->condexec_cond
= 0;
10199 s
->condexec_mask
= 0;
10201 } else if (insn
& 0x01200000) {
10202 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10203 * - load/store dual (post-indexed)
10204 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10205 * - load/store dual (literal and immediate)
10206 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10207 * - load/store dual (pre-indexed)
10209 bool wback
= extract32(insn
, 21, 1);
10212 if (insn
& (1 << 21)) {
10213 /* UNPREDICTABLE */
10216 addr
= tcg_temp_new_i32();
10217 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
10219 addr
= load_reg(s
, rn
);
10221 offset
= (insn
& 0xff) * 4;
10222 if ((insn
& (1 << 23)) == 0) {
10226 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
10228 * Here 'addr' is the current SP; if offset is +ve we're
10229 * moving SP up, else down. It is UNKNOWN whether the limit
10230 * check triggers when SP starts below the limit and ends
10231 * up above it; check whichever of the current and final
10232 * SP is lower, so QEMU will trigger in that situation.
10234 if ((int32_t)offset
< 0) {
10235 TCGv_i32 newsp
= tcg_temp_new_i32();
10237 tcg_gen_addi_i32(newsp
, addr
, offset
);
10238 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
10239 tcg_temp_free_i32(newsp
);
10241 gen_helper_v8m_stackcheck(cpu_env
, addr
);
10245 if (insn
& (1 << 24)) {
10246 tcg_gen_addi_i32(addr
, addr
, offset
);
10249 if (insn
& (1 << 20)) {
10251 tmp
= tcg_temp_new_i32();
10252 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10253 store_reg(s
, rs
, tmp
);
10254 tcg_gen_addi_i32(addr
, addr
, 4);
10255 tmp
= tcg_temp_new_i32();
10256 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10257 store_reg(s
, rd
, tmp
);
10260 tmp
= load_reg(s
, rs
);
10261 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10262 tcg_temp_free_i32(tmp
);
10263 tcg_gen_addi_i32(addr
, addr
, 4);
10264 tmp
= load_reg(s
, rd
);
10265 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10266 tcg_temp_free_i32(tmp
);
10269 /* Base writeback. */
10270 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
10271 store_reg(s
, rn
, addr
);
10273 tcg_temp_free_i32(addr
);
10275 } else if ((insn
& (1 << 23)) == 0) {
10276 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10277 * - load/store exclusive word
10281 if (!(insn
& (1 << 20)) &&
10282 arm_dc_feature(s
, ARM_FEATURE_M
) &&
10283 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10284 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10287 bool alt
= insn
& (1 << 7);
10288 TCGv_i32 addr
, op
, ttresp
;
10290 if ((insn
& 0x3f) || rd
== 13 || rd
== 15 || rn
== 15) {
10291 /* we UNDEF for these UNPREDICTABLE cases */
10295 if (alt
&& !s
->v8m_secure
) {
10299 addr
= load_reg(s
, rn
);
10300 op
= tcg_const_i32(extract32(insn
, 6, 2));
10301 ttresp
= tcg_temp_new_i32();
10302 gen_helper_v7m_tt(ttresp
, cpu_env
, addr
, op
);
10303 tcg_temp_free_i32(addr
);
10304 tcg_temp_free_i32(op
);
10305 store_reg(s
, rd
, ttresp
);
10310 addr
= tcg_temp_local_new_i32();
10311 load_reg_var(s
, addr
, rn
);
10312 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
10313 if (insn
& (1 << 20)) {
10314 gen_load_exclusive(s
, rs
, 15, addr
, 2);
10316 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
10318 tcg_temp_free_i32(addr
);
10319 } else if ((insn
& (7 << 5)) == 0) {
10320 /* Table Branch. */
10322 addr
= tcg_temp_new_i32();
10323 tcg_gen_movi_i32(addr
, s
->pc
);
10325 addr
= load_reg(s
, rn
);
10327 tmp
= load_reg(s
, rm
);
10328 tcg_gen_add_i32(addr
, addr
, tmp
);
10329 if (insn
& (1 << 4)) {
10331 tcg_gen_add_i32(addr
, addr
, tmp
);
10332 tcg_temp_free_i32(tmp
);
10333 tmp
= tcg_temp_new_i32();
10334 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
10336 tcg_temp_free_i32(tmp
);
10337 tmp
= tcg_temp_new_i32();
10338 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
10340 tcg_temp_free_i32(addr
);
10341 tcg_gen_shli_i32(tmp
, tmp
, 1);
10342 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
10343 store_reg(s
, 15, tmp
);
10345 bool is_lasr
= false;
10346 bool is_ld
= extract32(insn
, 20, 1);
10347 int op2
= (insn
>> 6) & 0x3;
10348 op
= (insn
>> 4) & 0x3;
10353 /* Load/store exclusive byte/halfword/doubleword */
10360 /* Load-acquire/store-release */
10366 /* Load-acquire/store-release exclusive */
10372 if (is_lasr
&& !is_ld
) {
10373 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
10376 addr
= tcg_temp_local_new_i32();
10377 load_reg_var(s
, addr
, rn
);
10380 tmp
= tcg_temp_new_i32();
10383 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
10387 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
10391 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
10397 store_reg(s
, rs
, tmp
);
10399 tmp
= load_reg(s
, rs
);
10402 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
10406 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
10410 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
10416 tcg_temp_free_i32(tmp
);
10418 } else if (is_ld
) {
10419 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
10421 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
10423 tcg_temp_free_i32(addr
);
10425 if (is_lasr
&& is_ld
) {
10426 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
10430 /* Load/store multiple, RFE, SRS. */
10431 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
10432 /* RFE, SRS: not available in user mode or on M profile */
10433 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10436 if (insn
& (1 << 20)) {
10438 addr
= load_reg(s
, rn
);
10439 if ((insn
& (1 << 24)) == 0)
10440 tcg_gen_addi_i32(addr
, addr
, -8);
10441 /* Load PC into tmp and CPSR into tmp2. */
10442 tmp
= tcg_temp_new_i32();
10443 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10444 tcg_gen_addi_i32(addr
, addr
, 4);
10445 tmp2
= tcg_temp_new_i32();
10446 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
10447 if (insn
& (1 << 21)) {
10448 /* Base writeback. */
10449 if (insn
& (1 << 24)) {
10450 tcg_gen_addi_i32(addr
, addr
, 4);
10452 tcg_gen_addi_i32(addr
, addr
, -4);
10454 store_reg(s
, rn
, addr
);
10456 tcg_temp_free_i32(addr
);
10458 gen_rfe(s
, tmp
, tmp2
);
10461 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
10465 int i
, loaded_base
= 0;
10466 TCGv_i32 loaded_var
;
10467 bool wback
= extract32(insn
, 21, 1);
10468 /* Load/store multiple. */
10469 addr
= load_reg(s
, rn
);
10471 for (i
= 0; i
< 16; i
++) {
10472 if (insn
& (1 << i
))
10476 if (insn
& (1 << 24)) {
10477 tcg_gen_addi_i32(addr
, addr
, -offset
);
10480 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
10482 * If the writeback is incrementing SP rather than
10483 * decrementing it, and the initial SP is below the
10484 * stack limit but the final written-back SP would
10485 * be above, then then we must not perform any memory
10486 * accesses, but it is IMPDEF whether we generate
10487 * an exception. We choose to do so in this case.
10488 * At this point 'addr' is the lowest address, so
10489 * either the original SP (if incrementing) or our
10490 * final SP (if decrementing), so that's what we check.
10492 gen_helper_v8m_stackcheck(cpu_env
, addr
);
10496 for (i
= 0; i
< 16; i
++) {
10497 if ((insn
& (1 << i
)) == 0)
10499 if (insn
& (1 << 20)) {
10501 tmp
= tcg_temp_new_i32();
10502 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10504 gen_bx_excret(s
, tmp
);
10505 } else if (i
== rn
) {
10509 store_reg(s
, i
, tmp
);
10513 tmp
= load_reg(s
, i
);
10514 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10515 tcg_temp_free_i32(tmp
);
10517 tcg_gen_addi_i32(addr
, addr
, 4);
10520 store_reg(s
, rn
, loaded_var
);
10523 /* Base register writeback. */
10524 if (insn
& (1 << 24)) {
10525 tcg_gen_addi_i32(addr
, addr
, -offset
);
10527 /* Fault if writeback register is in register list. */
10528 if (insn
& (1 << rn
))
10530 store_reg(s
, rn
, addr
);
10532 tcg_temp_free_i32(addr
);
10539 op
= (insn
>> 21) & 0xf;
10541 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10544 /* Halfword pack. */
10545 tmp
= load_reg(s
, rn
);
10546 tmp2
= load_reg(s
, rm
);
10547 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
10548 if (insn
& (1 << 5)) {
10552 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
10553 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
10554 tcg_gen_ext16u_i32(tmp2
, tmp2
);
10558 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10559 tcg_gen_ext16u_i32(tmp
, tmp
);
10560 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10562 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10563 tcg_temp_free_i32(tmp2
);
10564 store_reg(s
, rd
, tmp
);
10566 /* Data processing register constant shift. */
10568 tmp
= tcg_temp_new_i32();
10569 tcg_gen_movi_i32(tmp
, 0);
10571 tmp
= load_reg(s
, rn
);
10573 tmp2
= load_reg(s
, rm
);
10575 shiftop
= (insn
>> 4) & 3;
10576 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10577 conds
= (insn
& (1 << 20)) != 0;
10578 logic_cc
= (conds
&& thumb2_logic_op(op
));
10579 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10580 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10582 tcg_temp_free_i32(tmp2
);
10584 ((op
== 2 && rn
== 15) ||
10585 (op
== 8 && rn
== 13) ||
10586 (op
== 13 && rn
== 13))) {
10587 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
10588 store_sp_checked(s
, tmp
);
10589 } else if (rd
!= 15) {
10590 store_reg(s
, rd
, tmp
);
10592 tcg_temp_free_i32(tmp
);
10596 case 13: /* Misc data processing. */
10597 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10598 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10601 case 0: /* Register controlled shift. */
10602 tmp
= load_reg(s
, rn
);
10603 tmp2
= load_reg(s
, rm
);
10604 if ((insn
& 0x70) != 0)
10607 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
10608 * - MOV, MOVS (register-shifted register), flagsetting
10610 op
= (insn
>> 21) & 3;
10611 logic_cc
= (insn
& (1 << 20)) != 0;
10612 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10615 store_reg(s
, rd
, tmp
);
10617 case 1: /* Sign/zero extend. */
10618 op
= (insn
>> 20) & 7;
10620 case 0: /* SXTAH, SXTH */
10621 case 1: /* UXTAH, UXTH */
10622 case 4: /* SXTAB, SXTB */
10623 case 5: /* UXTAB, UXTB */
10625 case 2: /* SXTAB16, SXTB16 */
10626 case 3: /* UXTAB16, UXTB16 */
10627 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10635 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10639 tmp
= load_reg(s
, rm
);
10640 shift
= (insn
>> 4) & 3;
10641 /* ??? In many cases it's not necessary to do a
10642 rotate, a shift is sufficient. */
10644 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10645 op
= (insn
>> 20) & 7;
10647 case 0: gen_sxth(tmp
); break;
10648 case 1: gen_uxth(tmp
); break;
10649 case 2: gen_sxtb16(tmp
); break;
10650 case 3: gen_uxtb16(tmp
); break;
10651 case 4: gen_sxtb(tmp
); break;
10652 case 5: gen_uxtb(tmp
); break;
10654 g_assert_not_reached();
10657 tmp2
= load_reg(s
, rn
);
10658 if ((op
>> 1) == 1) {
10659 gen_add16(tmp
, tmp2
);
10661 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10662 tcg_temp_free_i32(tmp2
);
10665 store_reg(s
, rd
, tmp
);
10667 case 2: /* SIMD add/subtract. */
10668 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10671 op
= (insn
>> 20) & 7;
10672 shift
= (insn
>> 4) & 7;
10673 if ((op
& 3) == 3 || (shift
& 3) == 3)
10675 tmp
= load_reg(s
, rn
);
10676 tmp2
= load_reg(s
, rm
);
10677 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10678 tcg_temp_free_i32(tmp2
);
10679 store_reg(s
, rd
, tmp
);
10681 case 3: /* Other data processing. */
10682 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10684 /* Saturating add/subtract. */
10685 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10688 tmp
= load_reg(s
, rn
);
10689 tmp2
= load_reg(s
, rm
);
10691 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10693 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10695 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10696 tcg_temp_free_i32(tmp2
);
10699 case 0x0a: /* rbit */
10700 case 0x08: /* rev */
10701 case 0x09: /* rev16 */
10702 case 0x0b: /* revsh */
10703 case 0x18: /* clz */
10705 case 0x10: /* sel */
10706 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10710 case 0x20: /* crc32/crc32c */
10716 if (!dc_isar_feature(aa32_crc32
, s
)) {
10723 tmp
= load_reg(s
, rn
);
10725 case 0x0a: /* rbit */
10726 gen_helper_rbit(tmp
, tmp
);
10728 case 0x08: /* rev */
10729 tcg_gen_bswap32_i32(tmp
, tmp
);
10731 case 0x09: /* rev16 */
10734 case 0x0b: /* revsh */
10737 case 0x10: /* sel */
10738 tmp2
= load_reg(s
, rm
);
10739 tmp3
= tcg_temp_new_i32();
10740 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10741 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10742 tcg_temp_free_i32(tmp3
);
10743 tcg_temp_free_i32(tmp2
);
10745 case 0x18: /* clz */
10746 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10756 uint32_t sz
= op
& 0x3;
10757 uint32_t c
= op
& 0x8;
10759 tmp2
= load_reg(s
, rm
);
10761 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10762 } else if (sz
== 1) {
10763 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10765 tmp3
= tcg_const_i32(1 << sz
);
10767 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10769 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10771 tcg_temp_free_i32(tmp2
);
10772 tcg_temp_free_i32(tmp3
);
10776 g_assert_not_reached();
10779 store_reg(s
, rd
, tmp
);
10781 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10782 switch ((insn
>> 20) & 7) {
10783 case 0: /* 32 x 32 -> 32 */
10784 case 7: /* Unsigned sum of absolute differences. */
10786 case 1: /* 16 x 16 -> 32 */
10787 case 2: /* Dual multiply add. */
10788 case 3: /* 32 * 16 -> 32msb */
10789 case 4: /* Dual multiply subtract. */
10790 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10791 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10796 op
= (insn
>> 4) & 0xf;
10797 tmp
= load_reg(s
, rn
);
10798 tmp2
= load_reg(s
, rm
);
10799 switch ((insn
>> 20) & 7) {
10800 case 0: /* 32 x 32 -> 32 */
10801 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10802 tcg_temp_free_i32(tmp2
);
10804 tmp2
= load_reg(s
, rs
);
10806 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10808 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10809 tcg_temp_free_i32(tmp2
);
10812 case 1: /* 16 x 16 -> 32 */
10813 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10814 tcg_temp_free_i32(tmp2
);
10816 tmp2
= load_reg(s
, rs
);
10817 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10818 tcg_temp_free_i32(tmp2
);
10821 case 2: /* Dual multiply add. */
10822 case 4: /* Dual multiply subtract. */
10824 gen_swap_half(tmp2
);
10825 gen_smul_dual(tmp
, tmp2
);
10826 if (insn
& (1 << 22)) {
10827 /* This subtraction cannot overflow. */
10828 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10830 /* This addition cannot overflow 32 bits;
10831 * however it may overflow considered as a signed
10832 * operation, in which case we must set the Q flag.
10834 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10836 tcg_temp_free_i32(tmp2
);
10839 tmp2
= load_reg(s
, rs
);
10840 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10841 tcg_temp_free_i32(tmp2
);
10844 case 3: /* 32 * 16 -> 32msb */
10846 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10849 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10850 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10851 tmp
= tcg_temp_new_i32();
10852 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10853 tcg_temp_free_i64(tmp64
);
10856 tmp2
= load_reg(s
, rs
);
10857 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10858 tcg_temp_free_i32(tmp2
);
10861 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10862 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10864 tmp
= load_reg(s
, rs
);
10865 if (insn
& (1 << 20)) {
10866 tmp64
= gen_addq_msw(tmp64
, tmp
);
10868 tmp64
= gen_subq_msw(tmp64
, tmp
);
10871 if (insn
& (1 << 4)) {
10872 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10874 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10875 tmp
= tcg_temp_new_i32();
10876 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10877 tcg_temp_free_i64(tmp64
);
10879 case 7: /* Unsigned sum of absolute differences. */
10880 gen_helper_usad8(tmp
, tmp
, tmp2
);
10881 tcg_temp_free_i32(tmp2
);
10883 tmp2
= load_reg(s
, rs
);
10884 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10885 tcg_temp_free_i32(tmp2
);
10889 store_reg(s
, rd
, tmp
);
10891 case 6: case 7: /* 64-bit multiply, Divide. */
10892 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10893 tmp
= load_reg(s
, rn
);
10894 tmp2
= load_reg(s
, rm
);
10895 if ((op
& 0x50) == 0x10) {
10897 if (!dc_isar_feature(thumb_div
, s
)) {
10901 gen_helper_udiv(tmp
, tmp
, tmp2
);
10903 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10904 tcg_temp_free_i32(tmp2
);
10905 store_reg(s
, rd
, tmp
);
10906 } else if ((op
& 0xe) == 0xc) {
10907 /* Dual multiply accumulate long. */
10908 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10909 tcg_temp_free_i32(tmp
);
10910 tcg_temp_free_i32(tmp2
);
10914 gen_swap_half(tmp2
);
10915 gen_smul_dual(tmp
, tmp2
);
10917 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10919 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10921 tcg_temp_free_i32(tmp2
);
10923 tmp64
= tcg_temp_new_i64();
10924 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10925 tcg_temp_free_i32(tmp
);
10926 gen_addq(s
, tmp64
, rs
, rd
);
10927 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10928 tcg_temp_free_i64(tmp64
);
10931 /* Unsigned 64-bit multiply */
10932 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10936 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10937 tcg_temp_free_i32(tmp2
);
10938 tcg_temp_free_i32(tmp
);
10941 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10942 tcg_temp_free_i32(tmp2
);
10943 tmp64
= tcg_temp_new_i64();
10944 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10945 tcg_temp_free_i32(tmp
);
10947 /* Signed 64-bit multiply */
10948 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10953 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10954 tcg_temp_free_i64(tmp64
);
10957 gen_addq_lo(s
, tmp64
, rs
);
10958 gen_addq_lo(s
, tmp64
, rd
);
10959 } else if (op
& 0x40) {
10960 /* 64-bit accumulate. */
10961 gen_addq(s
, tmp64
, rs
, rd
);
10963 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10964 tcg_temp_free_i64(tmp64
);
10969 case 6: case 7: case 14: case 15:
10971 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10972 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10973 if (extract32(insn
, 24, 2) == 3) {
10974 goto illegal_op
; /* op0 = 0b11 : unallocated */
10978 * Decode VLLDM and VLSTM first: these are nonstandard because:
10979 * * if there is no FPU then these insns must NOP in
10980 * Secure state and UNDEF in Nonsecure state
10981 * * if there is an FPU then these insns do not have
10982 * the usual behaviour that disas_vfp_insn() provides of
10983 * being controlled by CPACR/NSACR enable bits or the
10984 * lazy-stacking logic.
10986 if (arm_dc_feature(s
, ARM_FEATURE_V8
) &&
10987 (insn
& 0xffa00f00) == 0xec200a00) {
10988 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10990 * We choose to UNDEF if the RAZ bits are non-zero.
10992 if (!s
->v8m_secure
|| (insn
& 0x0040f0ff)) {
10996 if (arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
10997 TCGv_i32 fptr
= load_reg(s
, rn
);
10999 if (extract32(insn
, 20, 1)) {
11000 gen_helper_v7m_vlldm(cpu_env
, fptr
);
11002 gen_helper_v7m_vlstm(cpu_env
, fptr
);
11004 tcg_temp_free_i32(fptr
);
11006 /* End the TB, because we have updated FP control bits */
11007 s
->base
.is_jmp
= DISAS_UPDATE
;
11011 if (arm_dc_feature(s
, ARM_FEATURE_VFP
) &&
11012 ((insn
>> 8) & 0xe) == 10) {
11013 /* FP, and the CPU supports it */
11014 if (disas_vfp_insn(s
, insn
)) {
11020 /* All other insns: NOCP */
11021 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
11022 default_exception_el(s
));
11025 if ((insn
& 0xfe000a00) == 0xfc000800
11026 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
11027 /* The Thumb2 and ARM encodings are identical. */
11028 if (disas_neon_insn_3same_ext(s
, insn
)) {
11031 } else if ((insn
& 0xff000a00) == 0xfe000800
11032 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
11033 /* The Thumb2 and ARM encodings are identical. */
11034 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
11037 } else if (((insn
>> 24) & 3) == 3) {
11038 /* Translate into the equivalent ARM encoding. */
11039 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
11040 if (disas_neon_data_insn(s
, insn
)) {
11043 } else if (((insn
>> 8) & 0xe) == 10) {
11044 if (disas_vfp_insn(s
, insn
)) {
11048 if (insn
& (1 << 28))
11050 if (disas_coproc_insn(s
, insn
)) {
11055 case 8: case 9: case 10: case 11:
11056 if (insn
& (1 << 15)) {
11057 /* Branches, misc control. */
11058 if (insn
& 0x5000) {
11059 /* Unconditional branch. */
11060 /* signextend(hw1[10:0]) -> offset[:12]. */
11061 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
11062 /* hw1[10:0] -> offset[11:1]. */
11063 offset
|= (insn
& 0x7ff) << 1;
11064 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11065 offset[24:22] already have the same value because of the
11066 sign extension above. */
11067 offset
^= ((~insn
) & (1 << 13)) << 10;
11068 offset
^= ((~insn
) & (1 << 11)) << 11;
11070 if (insn
& (1 << 14)) {
11071 /* Branch and link. */
11072 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
11076 if (insn
& (1 << 12)) {
11078 gen_jmp(s
, offset
);
11081 offset
&= ~(uint32_t)2;
11082 /* thumb2 bx, no need to check */
11083 gen_bx_im(s
, offset
);
11085 } else if (((insn
>> 23) & 7) == 7) {
11087 if (insn
& (1 << 13))
11090 if (insn
& (1 << 26)) {
11091 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11094 if (!(insn
& (1 << 20))) {
11095 /* Hypervisor call (v7) */
11096 int imm16
= extract32(insn
, 16, 4) << 12
11097 | extract32(insn
, 0, 12);
11104 /* Secure monitor call (v6+) */
11112 op
= (insn
>> 20) & 7;
11114 case 0: /* msr cpsr. */
11115 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11116 tmp
= load_reg(s
, rn
);
11117 /* the constant is the mask and SYSm fields */
11118 addr
= tcg_const_i32(insn
& 0xfff);
11119 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11120 tcg_temp_free_i32(addr
);
11121 tcg_temp_free_i32(tmp
);
11126 case 1: /* msr spsr. */
11127 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11131 if (extract32(insn
, 5, 1)) {
11133 int sysm
= extract32(insn
, 8, 4) |
11134 (extract32(insn
, 4, 1) << 4);
11137 gen_msr_banked(s
, r
, sysm
, rm
);
11141 /* MSR (for PSRs) */
11142 tmp
= load_reg(s
, rn
);
11144 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
11148 case 2: /* cps, nop-hint. */
11149 if (((insn
>> 8) & 7) == 0) {
11150 gen_nop_hint(s
, insn
& 0xff);
11152 /* Implemented as NOP in user mode. */
11157 if (insn
& (1 << 10)) {
11158 if (insn
& (1 << 7))
11160 if (insn
& (1 << 6))
11162 if (insn
& (1 << 5))
11164 if (insn
& (1 << 9))
11165 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
11167 if (insn
& (1 << 8)) {
11169 imm
|= (insn
& 0x1f);
11172 gen_set_psr_im(s
, offset
, 0, imm
);
11175 case 3: /* Special control operations. */
11176 if (!arm_dc_feature(s
, ARM_FEATURE_V7
) &&
11177 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11180 op
= (insn
>> 4) & 0xf;
11182 case 2: /* clrex */
11187 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
11190 /* We need to break the TB after this insn
11191 * to execute self-modifying code correctly
11192 * and also to take any pending interrupts
11195 gen_goto_tb(s
, 0, s
->pc
& ~1);
11198 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
11202 * TODO: There is no speculation barrier opcode
11203 * for TCG; MB and end the TB instead.
11205 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
11206 gen_goto_tb(s
, 0, s
->pc
& ~1);
11213 /* Trivial implementation equivalent to bx.
11214 * This instruction doesn't exist at all for M-profile.
11216 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11219 tmp
= load_reg(s
, rn
);
11222 case 5: /* Exception return. */
11226 if (rn
!= 14 || rd
!= 15) {
11229 if (s
->current_el
== 2) {
11230 /* ERET from Hyp uses ELR_Hyp, not LR */
11234 tmp
= load_cpu_field(elr_el
[2]);
11236 tmp
= load_reg(s
, rn
);
11237 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
11239 gen_exception_return(s
, tmp
);
11242 if (extract32(insn
, 5, 1) &&
11243 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11245 int sysm
= extract32(insn
, 16, 4) |
11246 (extract32(insn
, 4, 1) << 4);
11248 gen_mrs_banked(s
, 0, sysm
, rd
);
11252 if (extract32(insn
, 16, 4) != 0xf) {
11255 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
11256 extract32(insn
, 0, 8) != 0) {
11261 tmp
= tcg_temp_new_i32();
11262 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11263 addr
= tcg_const_i32(insn
& 0xff);
11264 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
11265 tcg_temp_free_i32(addr
);
11267 gen_helper_cpsr_read(tmp
, cpu_env
);
11269 store_reg(s
, rd
, tmp
);
11272 if (extract32(insn
, 5, 1) &&
11273 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11275 int sysm
= extract32(insn
, 16, 4) |
11276 (extract32(insn
, 4, 1) << 4);
11278 gen_mrs_banked(s
, 1, sysm
, rd
);
11283 /* Not accessible in user mode. */
11284 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
11288 if (extract32(insn
, 16, 4) != 0xf ||
11289 extract32(insn
, 0, 8) != 0) {
11293 tmp
= load_cpu_field(spsr
);
11294 store_reg(s
, rd
, tmp
);
11299 /* Conditional branch. */
11300 op
= (insn
>> 22) & 0xf;
11301 /* Generate a conditional jump to next instruction. */
11302 arm_skip_unless(s
, op
);
11304 /* offset[11:1] = insn[10:0] */
11305 offset
= (insn
& 0x7ff) << 1;
11306 /* offset[17:12] = insn[21:16]. */
11307 offset
|= (insn
& 0x003f0000) >> 4;
11308 /* offset[31:20] = insn[26]. */
11309 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
11310 /* offset[18] = insn[13]. */
11311 offset
|= (insn
& (1 << 13)) << 5;
11312 /* offset[19] = insn[11]. */
11313 offset
|= (insn
& (1 << 11)) << 8;
11315 /* jump to the offset */
11316 gen_jmp(s
, s
->pc
+ offset
);
11320 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11321 * - Data-processing (modified immediate, plain binary immediate)
11323 if (insn
& (1 << 25)) {
11325 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11326 * - Data-processing (plain binary immediate)
11328 if (insn
& (1 << 24)) {
11329 if (insn
& (1 << 20))
11331 /* Bitfield/Saturate. */
11332 op
= (insn
>> 21) & 7;
11334 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
11336 tmp
= tcg_temp_new_i32();
11337 tcg_gen_movi_i32(tmp
, 0);
11339 tmp
= load_reg(s
, rn
);
11342 case 2: /* Signed bitfield extract. */
11344 if (shift
+ imm
> 32)
11347 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
11350 case 6: /* Unsigned bitfield extract. */
11352 if (shift
+ imm
> 32)
11355 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
11358 case 3: /* Bitfield insert/clear. */
11361 imm
= imm
+ 1 - shift
;
11363 tmp2
= load_reg(s
, rd
);
11364 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
11365 tcg_temp_free_i32(tmp2
);
11370 default: /* Saturate. */
11373 tcg_gen_sari_i32(tmp
, tmp
, shift
);
11375 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11377 tmp2
= tcg_const_i32(imm
);
11380 if ((op
& 1) && shift
== 0) {
11381 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11382 tcg_temp_free_i32(tmp
);
11383 tcg_temp_free_i32(tmp2
);
11386 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
11388 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
11392 if ((op
& 1) && shift
== 0) {
11393 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11394 tcg_temp_free_i32(tmp
);
11395 tcg_temp_free_i32(tmp2
);
11398 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
11400 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
11403 tcg_temp_free_i32(tmp2
);
11406 store_reg(s
, rd
, tmp
);
11408 imm
= ((insn
& 0x04000000) >> 15)
11409 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
11410 if (insn
& (1 << 22)) {
11411 /* 16-bit immediate. */
11412 imm
|= (insn
>> 4) & 0xf000;
11413 if (insn
& (1 << 23)) {
11415 tmp
= load_reg(s
, rd
);
11416 tcg_gen_ext16u_i32(tmp
, tmp
);
11417 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
11420 tmp
= tcg_temp_new_i32();
11421 tcg_gen_movi_i32(tmp
, imm
);
11423 store_reg(s
, rd
, tmp
);
11425 /* Add/sub 12-bit immediate. */
11427 offset
= s
->pc
& ~(uint32_t)3;
11428 if (insn
& (1 << 23))
11432 tmp
= tcg_temp_new_i32();
11433 tcg_gen_movi_i32(tmp
, offset
);
11434 store_reg(s
, rd
, tmp
);
11436 tmp
= load_reg(s
, rn
);
11437 if (insn
& (1 << 23))
11438 tcg_gen_subi_i32(tmp
, tmp
, imm
);
11440 tcg_gen_addi_i32(tmp
, tmp
, imm
);
11441 if (rn
== 13 && rd
== 13) {
11442 /* ADD SP, SP, imm or SUB SP, SP, imm */
11443 store_sp_checked(s
, tmp
);
11445 store_reg(s
, rd
, tmp
);
11452 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11453 * - Data-processing (modified immediate)
11455 int shifter_out
= 0;
11456 /* modified 12-bit immediate. */
11457 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
11458 imm
= (insn
& 0xff);
11461 /* Nothing to do. */
11463 case 1: /* 00XY00XY */
11466 case 2: /* XY00XY00 */
11470 case 3: /* XYXYXYXY */
11474 default: /* Rotated constant. */
11475 shift
= (shift
<< 1) | (imm
>> 7);
11477 imm
= imm
<< (32 - shift
);
11481 tmp2
= tcg_temp_new_i32();
11482 tcg_gen_movi_i32(tmp2
, imm
);
11483 rn
= (insn
>> 16) & 0xf;
11485 tmp
= tcg_temp_new_i32();
11486 tcg_gen_movi_i32(tmp
, 0);
11488 tmp
= load_reg(s
, rn
);
11490 op
= (insn
>> 21) & 0xf;
11491 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
11492 shifter_out
, tmp
, tmp2
))
11494 tcg_temp_free_i32(tmp2
);
11495 rd
= (insn
>> 8) & 0xf;
11496 if (rd
== 13 && rn
== 13
11497 && (op
== 8 || op
== 13)) {
11498 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11499 store_sp_checked(s
, tmp
);
11500 } else if (rd
!= 15) {
11501 store_reg(s
, rd
, tmp
);
11503 tcg_temp_free_i32(tmp
);
11508 case 12: /* Load/store single data item. */
11515 if ((insn
& 0x01100000) == 0x01000000) {
11516 if (disas_neon_ls_insn(s
, insn
)) {
11521 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
11523 if (!(insn
& (1 << 20))) {
11527 /* Byte or halfword load space with dest == r15 : memory hints.
11528 * Catch them early so we don't emit pointless addressing code.
11529 * This space is a mix of:
11530 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11531 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11533 * unallocated hints, which must be treated as NOPs
11534 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11535 * which is easiest for the decoding logic
11536 * Some space which must UNDEF
11538 int op1
= (insn
>> 23) & 3;
11539 int op2
= (insn
>> 6) & 0x3f;
11544 /* UNPREDICTABLE, unallocated hint or
11545 * PLD/PLDW/PLI (literal)
11550 return; /* PLD/PLDW/PLI or unallocated hint */
11552 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
11553 return; /* PLD/PLDW/PLI or unallocated hint */
11555 /* UNDEF space, or an UNPREDICTABLE */
11559 memidx
= get_mem_index(s
);
11561 addr
= tcg_temp_new_i32();
11563 /* s->pc has already been incremented by 4. */
11564 imm
= s
->pc
& 0xfffffffc;
11565 if (insn
& (1 << 23))
11566 imm
+= insn
& 0xfff;
11568 imm
-= insn
& 0xfff;
11569 tcg_gen_movi_i32(addr
, imm
);
11571 addr
= load_reg(s
, rn
);
11572 if (insn
& (1 << 23)) {
11573 /* Positive offset. */
11574 imm
= insn
& 0xfff;
11575 tcg_gen_addi_i32(addr
, addr
, imm
);
11578 switch ((insn
>> 8) & 0xf) {
11579 case 0x0: /* Shifted Register. */
11580 shift
= (insn
>> 4) & 0xf;
11582 tcg_temp_free_i32(addr
);
11585 tmp
= load_reg(s
, rm
);
11587 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11588 tcg_gen_add_i32(addr
, addr
, tmp
);
11589 tcg_temp_free_i32(tmp
);
11591 case 0xc: /* Negative offset. */
11592 tcg_gen_addi_i32(addr
, addr
, -imm
);
11594 case 0xe: /* User privilege. */
11595 tcg_gen_addi_i32(addr
, addr
, imm
);
11596 memidx
= get_a32_user_mem_index(s
);
11598 case 0x9: /* Post-decrement. */
11600 /* Fall through. */
11601 case 0xb: /* Post-increment. */
11605 case 0xd: /* Pre-decrement. */
11607 /* Fall through. */
11608 case 0xf: /* Pre-increment. */
11612 tcg_temp_free_i32(addr
);
11618 issinfo
= writeback
? ISSInvalid
: rs
;
11620 if (s
->v8m_stackcheck
&& rn
== 13 && writeback
) {
11622 * Stackcheck. Here we know 'addr' is the current SP;
11623 * if imm is +ve we're moving SP up, else down. It is
11624 * UNKNOWN whether the limit check triggers when SP starts
11625 * below the limit and ends up above it; we chose to do so.
11627 if ((int32_t)imm
< 0) {
11628 TCGv_i32 newsp
= tcg_temp_new_i32();
11630 tcg_gen_addi_i32(newsp
, addr
, imm
);
11631 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
11632 tcg_temp_free_i32(newsp
);
11634 gen_helper_v8m_stackcheck(cpu_env
, addr
);
11638 if (writeback
&& !postinc
) {
11639 tcg_gen_addi_i32(addr
, addr
, imm
);
11642 if (insn
& (1 << 20)) {
11644 tmp
= tcg_temp_new_i32();
11647 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11650 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11653 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11656 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11659 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11662 tcg_temp_free_i32(tmp
);
11663 tcg_temp_free_i32(addr
);
11667 gen_bx_excret(s
, tmp
);
11669 store_reg(s
, rs
, tmp
);
11673 tmp
= load_reg(s
, rs
);
11676 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
11679 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
11682 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
11685 tcg_temp_free_i32(tmp
);
11686 tcg_temp_free_i32(addr
);
11689 tcg_temp_free_i32(tmp
);
11692 tcg_gen_addi_i32(addr
, addr
, imm
);
11694 store_reg(s
, rn
, addr
);
11696 tcg_temp_free_i32(addr
);
11705 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11706 default_exception_el(s
));
11709 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
11711 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
11718 switch (insn
>> 12) {
11722 op
= (insn
>> 11) & 3;
11725 * 0b0001_1xxx_xxxx_xxxx
11726 * - Add, subtract (three low registers)
11727 * - Add, subtract (two low registers and immediate)
11729 rn
= (insn
>> 3) & 7;
11730 tmp
= load_reg(s
, rn
);
11731 if (insn
& (1 << 10)) {
11733 tmp2
= tcg_temp_new_i32();
11734 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11737 rm
= (insn
>> 6) & 7;
11738 tmp2
= load_reg(s
, rm
);
11740 if (insn
& (1 << 9)) {
11741 if (s
->condexec_mask
)
11742 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11744 gen_sub_CC(tmp
, tmp
, tmp2
);
11746 if (s
->condexec_mask
)
11747 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11749 gen_add_CC(tmp
, tmp
, tmp2
);
11751 tcg_temp_free_i32(tmp2
);
11752 store_reg(s
, rd
, tmp
);
11754 /* shift immediate */
11755 rm
= (insn
>> 3) & 7;
11756 shift
= (insn
>> 6) & 0x1f;
11757 tmp
= load_reg(s
, rm
);
11758 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11759 if (!s
->condexec_mask
)
11761 store_reg(s
, rd
, tmp
);
11766 * 0b001x_xxxx_xxxx_xxxx
11767 * - Add, subtract, compare, move (one low register and immediate)
11769 op
= (insn
>> 11) & 3;
11770 rd
= (insn
>> 8) & 0x7;
11771 if (op
== 0) { /* mov */
11772 tmp
= tcg_temp_new_i32();
11773 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11774 if (!s
->condexec_mask
)
11776 store_reg(s
, rd
, tmp
);
11778 tmp
= load_reg(s
, rd
);
11779 tmp2
= tcg_temp_new_i32();
11780 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11783 gen_sub_CC(tmp
, tmp
, tmp2
);
11784 tcg_temp_free_i32(tmp
);
11785 tcg_temp_free_i32(tmp2
);
11788 if (s
->condexec_mask
)
11789 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11791 gen_add_CC(tmp
, tmp
, tmp2
);
11792 tcg_temp_free_i32(tmp2
);
11793 store_reg(s
, rd
, tmp
);
11796 if (s
->condexec_mask
)
11797 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11799 gen_sub_CC(tmp
, tmp
, tmp2
);
11800 tcg_temp_free_i32(tmp2
);
11801 store_reg(s
, rd
, tmp
);
11807 if (insn
& (1 << 11)) {
11808 rd
= (insn
>> 8) & 7;
11809 /* load pc-relative. Bit 1 of PC is ignored. */
11810 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11811 val
&= ~(uint32_t)2;
11812 addr
= tcg_temp_new_i32();
11813 tcg_gen_movi_i32(addr
, val
);
11814 tmp
= tcg_temp_new_i32();
11815 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11817 tcg_temp_free_i32(addr
);
11818 store_reg(s
, rd
, tmp
);
11821 if (insn
& (1 << 10)) {
11822 /* 0b0100_01xx_xxxx_xxxx
11823 * - data processing extended, branch and exchange
11825 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11826 rm
= (insn
>> 3) & 0xf;
11827 op
= (insn
>> 8) & 3;
11830 tmp
= load_reg(s
, rd
);
11831 tmp2
= load_reg(s
, rm
);
11832 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11833 tcg_temp_free_i32(tmp2
);
11835 /* ADD SP, SP, reg */
11836 store_sp_checked(s
, tmp
);
11838 store_reg(s
, rd
, tmp
);
11842 tmp
= load_reg(s
, rd
);
11843 tmp2
= load_reg(s
, rm
);
11844 gen_sub_CC(tmp
, tmp
, tmp2
);
11845 tcg_temp_free_i32(tmp2
);
11846 tcg_temp_free_i32(tmp
);
11848 case 2: /* mov/cpy */
11849 tmp
= load_reg(s
, rm
);
11852 store_sp_checked(s
, tmp
);
11854 store_reg(s
, rd
, tmp
);
11859 /* 0b0100_0111_xxxx_xxxx
11860 * - branch [and link] exchange thumb register
11862 bool link
= insn
& (1 << 7);
11871 /* BXNS/BLXNS: only exists for v8M with the
11872 * security extensions, and always UNDEF if NonSecure.
11873 * We don't implement these in the user-only mode
11874 * either (in theory you can use them from Secure User
11875 * mode but they are too tied in to system emulation.)
11877 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
11888 tmp
= load_reg(s
, rm
);
11890 val
= (uint32_t)s
->pc
| 1;
11891 tmp2
= tcg_temp_new_i32();
11892 tcg_gen_movi_i32(tmp2
, val
);
11893 store_reg(s
, 14, tmp2
);
11896 /* Only BX works as exception-return, not BLX */
11897 gen_bx_excret(s
, tmp
);
11906 * 0b0100_00xx_xxxx_xxxx
11907 * - Data-processing (two low registers)
11910 rm
= (insn
>> 3) & 7;
11911 op
= (insn
>> 6) & 0xf;
11912 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11913 /* the shift/rotate ops want the operands backwards */
11922 if (op
== 9) { /* neg */
11923 tmp
= tcg_temp_new_i32();
11924 tcg_gen_movi_i32(tmp
, 0);
11925 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11926 tmp
= load_reg(s
, rd
);
11931 tmp2
= load_reg(s
, rm
);
11933 case 0x0: /* and */
11934 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11935 if (!s
->condexec_mask
)
11938 case 0x1: /* eor */
11939 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11940 if (!s
->condexec_mask
)
11943 case 0x2: /* lsl */
11944 if (s
->condexec_mask
) {
11945 gen_shl(tmp2
, tmp2
, tmp
);
11947 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11948 gen_logic_CC(tmp2
);
11951 case 0x3: /* lsr */
11952 if (s
->condexec_mask
) {
11953 gen_shr(tmp2
, tmp2
, tmp
);
11955 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11956 gen_logic_CC(tmp2
);
11959 case 0x4: /* asr */
11960 if (s
->condexec_mask
) {
11961 gen_sar(tmp2
, tmp2
, tmp
);
11963 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11964 gen_logic_CC(tmp2
);
11967 case 0x5: /* adc */
11968 if (s
->condexec_mask
) {
11969 gen_adc(tmp
, tmp2
);
11971 gen_adc_CC(tmp
, tmp
, tmp2
);
11974 case 0x6: /* sbc */
11975 if (s
->condexec_mask
) {
11976 gen_sub_carry(tmp
, tmp
, tmp2
);
11978 gen_sbc_CC(tmp
, tmp
, tmp2
);
11981 case 0x7: /* ror */
11982 if (s
->condexec_mask
) {
11983 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11984 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11986 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11987 gen_logic_CC(tmp2
);
11990 case 0x8: /* tst */
11991 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11995 case 0x9: /* neg */
11996 if (s
->condexec_mask
)
11997 tcg_gen_neg_i32(tmp
, tmp2
);
11999 gen_sub_CC(tmp
, tmp
, tmp2
);
12001 case 0xa: /* cmp */
12002 gen_sub_CC(tmp
, tmp
, tmp2
);
12005 case 0xb: /* cmn */
12006 gen_add_CC(tmp
, tmp
, tmp2
);
12009 case 0xc: /* orr */
12010 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
12011 if (!s
->condexec_mask
)
12014 case 0xd: /* mul */
12015 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
12016 if (!s
->condexec_mask
)
12019 case 0xe: /* bic */
12020 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
12021 if (!s
->condexec_mask
)
12024 case 0xf: /* mvn */
12025 tcg_gen_not_i32(tmp2
, tmp2
);
12026 if (!s
->condexec_mask
)
12027 gen_logic_CC(tmp2
);
12034 store_reg(s
, rm
, tmp2
);
12036 tcg_temp_free_i32(tmp
);
12038 store_reg(s
, rd
, tmp
);
12039 tcg_temp_free_i32(tmp2
);
12042 tcg_temp_free_i32(tmp
);
12043 tcg_temp_free_i32(tmp2
);
12048 /* load/store register offset. */
12050 rn
= (insn
>> 3) & 7;
12051 rm
= (insn
>> 6) & 7;
12052 op
= (insn
>> 9) & 7;
12053 addr
= load_reg(s
, rn
);
12054 tmp
= load_reg(s
, rm
);
12055 tcg_gen_add_i32(addr
, addr
, tmp
);
12056 tcg_temp_free_i32(tmp
);
12058 if (op
< 3) { /* store */
12059 tmp
= load_reg(s
, rd
);
12061 tmp
= tcg_temp_new_i32();
12066 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12069 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12072 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12074 case 3: /* ldrsb */
12075 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12078 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12081 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12084 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12086 case 7: /* ldrsh */
12087 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12090 if (op
>= 3) { /* load */
12091 store_reg(s
, rd
, tmp
);
12093 tcg_temp_free_i32(tmp
);
12095 tcg_temp_free_i32(addr
);
12099 /* load/store word immediate offset */
12101 rn
= (insn
>> 3) & 7;
12102 addr
= load_reg(s
, rn
);
12103 val
= (insn
>> 4) & 0x7c;
12104 tcg_gen_addi_i32(addr
, addr
, val
);
12106 if (insn
& (1 << 11)) {
12108 tmp
= tcg_temp_new_i32();
12109 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12110 store_reg(s
, rd
, tmp
);
12113 tmp
= load_reg(s
, rd
);
12114 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12115 tcg_temp_free_i32(tmp
);
12117 tcg_temp_free_i32(addr
);
12121 /* load/store byte immediate offset */
12123 rn
= (insn
>> 3) & 7;
12124 addr
= load_reg(s
, rn
);
12125 val
= (insn
>> 6) & 0x1f;
12126 tcg_gen_addi_i32(addr
, addr
, val
);
12128 if (insn
& (1 << 11)) {
12130 tmp
= tcg_temp_new_i32();
12131 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12132 store_reg(s
, rd
, tmp
);
12135 tmp
= load_reg(s
, rd
);
12136 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12137 tcg_temp_free_i32(tmp
);
12139 tcg_temp_free_i32(addr
);
12143 /* load/store halfword immediate offset */
12145 rn
= (insn
>> 3) & 7;
12146 addr
= load_reg(s
, rn
);
12147 val
= (insn
>> 5) & 0x3e;
12148 tcg_gen_addi_i32(addr
, addr
, val
);
12150 if (insn
& (1 << 11)) {
12152 tmp
= tcg_temp_new_i32();
12153 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12154 store_reg(s
, rd
, tmp
);
12157 tmp
= load_reg(s
, rd
);
12158 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12159 tcg_temp_free_i32(tmp
);
12161 tcg_temp_free_i32(addr
);
12165 /* load/store from stack */
12166 rd
= (insn
>> 8) & 7;
12167 addr
= load_reg(s
, 13);
12168 val
= (insn
& 0xff) * 4;
12169 tcg_gen_addi_i32(addr
, addr
, val
);
12171 if (insn
& (1 << 11)) {
12173 tmp
= tcg_temp_new_i32();
12174 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12175 store_reg(s
, rd
, tmp
);
12178 tmp
= load_reg(s
, rd
);
12179 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12180 tcg_temp_free_i32(tmp
);
12182 tcg_temp_free_i32(addr
);
12187 * 0b1010_xxxx_xxxx_xxxx
12188 * - Add PC/SP (immediate)
12190 rd
= (insn
>> 8) & 7;
12191 if (insn
& (1 << 11)) {
12193 tmp
= load_reg(s
, 13);
12195 /* PC. bit 1 is ignored. */
12196 tmp
= tcg_temp_new_i32();
12197 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
12199 val
= (insn
& 0xff) * 4;
12200 tcg_gen_addi_i32(tmp
, tmp
, val
);
12201 store_reg(s
, rd
, tmp
);
12206 op
= (insn
>> 8) & 0xf;
12210 * 0b1011_0000_xxxx_xxxx
12211 * - ADD (SP plus immediate)
12212 * - SUB (SP minus immediate)
12214 tmp
= load_reg(s
, 13);
12215 val
= (insn
& 0x7f) * 4;
12216 if (insn
& (1 << 7))
12217 val
= -(int32_t)val
;
12218 tcg_gen_addi_i32(tmp
, tmp
, val
);
12219 store_sp_checked(s
, tmp
);
12222 case 2: /* sign/zero extend. */
12225 rm
= (insn
>> 3) & 7;
12226 tmp
= load_reg(s
, rm
);
12227 switch ((insn
>> 6) & 3) {
12228 case 0: gen_sxth(tmp
); break;
12229 case 1: gen_sxtb(tmp
); break;
12230 case 2: gen_uxth(tmp
); break;
12231 case 3: gen_uxtb(tmp
); break;
12233 store_reg(s
, rd
, tmp
);
12235 case 4: case 5: case 0xc: case 0xd:
12237 * 0b1011_x10x_xxxx_xxxx
12240 addr
= load_reg(s
, 13);
12241 if (insn
& (1 << 8))
12245 for (i
= 0; i
< 8; i
++) {
12246 if (insn
& (1 << i
))
12249 if ((insn
& (1 << 11)) == 0) {
12250 tcg_gen_addi_i32(addr
, addr
, -offset
);
12253 if (s
->v8m_stackcheck
) {
12255 * Here 'addr' is the lower of "old SP" and "new SP";
12256 * if this is a pop that starts below the limit and ends
12257 * above it, it is UNKNOWN whether the limit check triggers;
12258 * we choose to trigger.
12260 gen_helper_v8m_stackcheck(cpu_env
, addr
);
12263 for (i
= 0; i
< 8; i
++) {
12264 if (insn
& (1 << i
)) {
12265 if (insn
& (1 << 11)) {
12267 tmp
= tcg_temp_new_i32();
12268 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12269 store_reg(s
, i
, tmp
);
12272 tmp
= load_reg(s
, i
);
12273 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12274 tcg_temp_free_i32(tmp
);
12276 /* advance to the next address. */
12277 tcg_gen_addi_i32(addr
, addr
, 4);
12281 if (insn
& (1 << 8)) {
12282 if (insn
& (1 << 11)) {
12284 tmp
= tcg_temp_new_i32();
12285 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12286 /* don't set the pc until the rest of the instruction
12290 tmp
= load_reg(s
, 14);
12291 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12292 tcg_temp_free_i32(tmp
);
12294 tcg_gen_addi_i32(addr
, addr
, 4);
12296 if ((insn
& (1 << 11)) == 0) {
12297 tcg_gen_addi_i32(addr
, addr
, -offset
);
12299 /* write back the new stack pointer */
12300 store_reg(s
, 13, addr
);
12301 /* set the new PC value */
12302 if ((insn
& 0x0900) == 0x0900) {
12303 store_reg_from_load(s
, 15, tmp
);
12307 case 1: case 3: case 9: case 11: /* czb */
12309 tmp
= load_reg(s
, rm
);
12310 arm_gen_condlabel(s
);
12311 if (insn
& (1 << 11))
12312 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
12314 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
12315 tcg_temp_free_i32(tmp
);
12316 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
12317 val
= (uint32_t)s
->pc
+ 2;
12322 case 15: /* IT, nop-hint. */
12323 if ((insn
& 0xf) == 0) {
12324 gen_nop_hint(s
, (insn
>> 4) & 0xf);
12328 s
->condexec_cond
= (insn
>> 4) & 0xe;
12329 s
->condexec_mask
= insn
& 0x1f;
12330 /* No actual code generated for this insn, just setup state. */
12333 case 0xe: /* bkpt */
12335 int imm8
= extract32(insn
, 0, 8);
12337 gen_exception_bkpt_insn(s
, 2, syn_aa32_bkpt(imm8
, true));
12341 case 0xa: /* rev, and hlt */
12343 int op1
= extract32(insn
, 6, 2);
12347 int imm6
= extract32(insn
, 0, 6);
12353 /* Otherwise this is rev */
12355 rn
= (insn
>> 3) & 0x7;
12357 tmp
= load_reg(s
, rn
);
12359 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
12360 case 1: gen_rev16(tmp
); break;
12361 case 3: gen_revsh(tmp
); break;
12363 g_assert_not_reached();
12365 store_reg(s
, rd
, tmp
);
12370 switch ((insn
>> 5) & 7) {
12374 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
12375 gen_helper_setend(cpu_env
);
12376 s
->base
.is_jmp
= DISAS_UPDATE
;
12385 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
12386 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
12389 addr
= tcg_const_i32(19);
12390 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12391 tcg_temp_free_i32(addr
);
12395 addr
= tcg_const_i32(16);
12396 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12397 tcg_temp_free_i32(addr
);
12399 tcg_temp_free_i32(tmp
);
12402 if (insn
& (1 << 4)) {
12403 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
12407 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
12422 /* load/store multiple */
12423 TCGv_i32 loaded_var
= NULL
;
12424 rn
= (insn
>> 8) & 0x7;
12425 addr
= load_reg(s
, rn
);
12426 for (i
= 0; i
< 8; i
++) {
12427 if (insn
& (1 << i
)) {
12428 if (insn
& (1 << 11)) {
12430 tmp
= tcg_temp_new_i32();
12431 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12435 store_reg(s
, i
, tmp
);
12439 tmp
= load_reg(s
, i
);
12440 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12441 tcg_temp_free_i32(tmp
);
12443 /* advance to the next address */
12444 tcg_gen_addi_i32(addr
, addr
, 4);
12447 if ((insn
& (1 << rn
)) == 0) {
12448 /* base reg not in list: base register writeback */
12449 store_reg(s
, rn
, addr
);
12451 /* base reg in list: if load, complete it now */
12452 if (insn
& (1 << 11)) {
12453 store_reg(s
, rn
, loaded_var
);
12455 tcg_temp_free_i32(addr
);
12460 /* conditional branch or swi */
12461 cond
= (insn
>> 8) & 0xf;
12467 gen_set_pc_im(s
, s
->pc
);
12468 s
->svc_imm
= extract32(insn
, 0, 8);
12469 s
->base
.is_jmp
= DISAS_SWI
;
12472 /* generate a conditional jump to next instruction */
12473 arm_skip_unless(s
, cond
);
12475 /* jump to the offset */
12476 val
= (uint32_t)s
->pc
+ 2;
12477 offset
= ((int32_t)insn
<< 24) >> 24;
12478 val
+= offset
<< 1;
12483 if (insn
& (1 << 11)) {
12484 /* thumb_insn_is_16bit() ensures we can't get here for
12485 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12486 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12488 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12490 offset
= ((insn
& 0x7ff) << 1);
12491 tmp
= load_reg(s
, 14);
12492 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12493 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
12495 tmp2
= tcg_temp_new_i32();
12496 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12497 store_reg(s
, 14, tmp2
);
12501 /* unconditional branch */
12502 val
= (uint32_t)s
->pc
;
12503 offset
= ((int32_t)insn
<< 21) >> 21;
12504 val
+= (offset
<< 1) + 2;
12509 /* thumb_insn_is_16bit() ensures we can't get here for
12510 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12512 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12514 if (insn
& (1 << 11)) {
12515 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12516 offset
= ((insn
& 0x7ff) << 1) | 1;
12517 tmp
= load_reg(s
, 14);
12518 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12520 tmp2
= tcg_temp_new_i32();
12521 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12522 store_reg(s
, 14, tmp2
);
12525 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12526 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
12528 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
12535 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
12536 default_exception_el(s
));
12539 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
12541 /* Return true if the insn at dc->pc might cross a page boundary.
12542 * (False positives are OK, false negatives are not.)
12543 * We know this is a Thumb insn, and our caller ensures we are
12544 * only called if dc->pc is less than 4 bytes from the page
12545 * boundary, so we cross the page if the first 16 bits indicate
12546 * that this is a 32 bit insn.
12548 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
12550 return !thumb_insn_is_16bit(s
, insn
);
12553 static void arm_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
12555 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12556 CPUARMState
*env
= cs
->env_ptr
;
12557 ARMCPU
*cpu
= env_archcpu(env
);
12558 uint32_t tb_flags
= dc
->base
.tb
->flags
;
12559 uint32_t condexec
, core_mmu_idx
;
12561 dc
->isar
= &cpu
->isar
;
12562 dc
->pc
= dc
->base
.pc_first
;
12566 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12567 * there is no secure EL1, so we route exceptions to EL3.
12569 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
12570 !arm_el_is_aa64(env
, 3);
12571 dc
->thumb
= FIELD_EX32(tb_flags
, TBFLAG_A32
, THUMB
);
12572 dc
->sctlr_b
= FIELD_EX32(tb_flags
, TBFLAG_A32
, SCTLR_B
);
12573 dc
->be_data
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, BE_DATA
) ? MO_BE
: MO_LE
;
12574 condexec
= FIELD_EX32(tb_flags
, TBFLAG_A32
, CONDEXEC
);
12575 dc
->condexec_mask
= (condexec
& 0xf) << 1;
12576 dc
->condexec_cond
= condexec
>> 4;
12577 core_mmu_idx
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, MMUIDX
);
12578 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, core_mmu_idx
);
12579 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
12580 #if !defined(CONFIG_USER_ONLY)
12581 dc
->user
= (dc
->current_el
== 0);
12583 dc
->ns
= FIELD_EX32(tb_flags
, TBFLAG_A32
, NS
);
12584 dc
->fp_excp_el
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, FPEXC_EL
);
12585 dc
->vfp_enabled
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VFPEN
);
12586 dc
->vec_len
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECLEN
);
12587 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
12588 dc
->c15_cpar
= FIELD_EX32(tb_flags
, TBFLAG_A32
, XSCALE_CPAR
);
12589 dc
->vec_stride
= 0;
12591 dc
->vec_stride
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECSTRIDE
);
12594 dc
->v7m_handler_mode
= FIELD_EX32(tb_flags
, TBFLAG_A32
, HANDLER
);
12595 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
12596 regime_is_secure(env
, dc
->mmu_idx
);
12597 dc
->v8m_stackcheck
= FIELD_EX32(tb_flags
, TBFLAG_A32
, STACKCHECK
);
12598 dc
->v8m_fpccr_s_wrong
= FIELD_EX32(tb_flags
, TBFLAG_A32
, FPCCR_S_WRONG
);
12599 dc
->v7m_new_fp_ctxt_needed
=
12600 FIELD_EX32(tb_flags
, TBFLAG_A32
, NEW_FP_CTXT_NEEDED
);
12601 dc
->v7m_lspact
= FIELD_EX32(tb_flags
, TBFLAG_A32
, LSPACT
);
12602 dc
->cp_regs
= cpu
->cp_regs
;
12603 dc
->features
= env
->features
;
12605 /* Single step state. The code-generation logic here is:
12607 * generate code with no special handling for single-stepping (except
12608 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12609 * this happens anyway because those changes are all system register or
12611 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12612 * emit code for one insn
12613 * emit code to clear PSTATE.SS
12614 * emit code to generate software step exception for completed step
12615 * end TB (as usual for having generated an exception)
12616 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12617 * emit code to generate a software step exception
12620 dc
->ss_active
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, SS_ACTIVE
);
12621 dc
->pstate_ss
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, PSTATE_SS
);
12622 dc
->is_ldex
= false;
12623 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
12625 dc
->page_start
= dc
->base
.pc_first
& TARGET_PAGE_MASK
;
12627 /* If architectural single step active, limit to 1. */
12628 if (is_singlestepping(dc
)) {
12629 dc
->base
.max_insns
= 1;
12632 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12633 to those left on the page. */
12635 int bound
= -(dc
->base
.pc_first
| TARGET_PAGE_MASK
) / 4;
12636 dc
->base
.max_insns
= MIN(dc
->base
.max_insns
, bound
);
12639 cpu_F0s
= tcg_temp_new_i32();
12640 cpu_F1s
= tcg_temp_new_i32();
12641 cpu_F0d
= tcg_temp_new_i64();
12642 cpu_F1d
= tcg_temp_new_i64();
12645 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12646 cpu_M0
= tcg_temp_new_i64();
12649 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12651 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12653 /* A note on handling of the condexec (IT) bits:
12655 * We want to avoid the overhead of having to write the updated condexec
12656 * bits back to the CPUARMState for every instruction in an IT block. So:
12657 * (1) if the condexec bits are not already zero then we write
12658 * zero back into the CPUARMState now. This avoids complications trying
12659 * to do it at the end of the block. (For example if we don't do this
12660 * it's hard to identify whether we can safely skip writing condexec
12661 * at the end of the TB, which we definitely want to do for the case
12662 * where a TB doesn't do anything with the IT state at all.)
12663 * (2) if we are going to leave the TB then we call gen_set_condexec()
12664 * which will write the correct value into CPUARMState if zero is wrong.
12665 * This is done both for leaving the TB at the end, and for leaving
12666 * it because of an exception we know will happen, which is done in
12667 * gen_exception_insn(). The latter is necessary because we need to
12668 * leave the TB with the PC/IT state just prior to execution of the
12669 * instruction which caused the exception.
12670 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12671 * then the CPUARMState will be wrong and we need to reset it.
12672 * This is handled in the same way as restoration of the
12673 * PC in these situations; we save the value of the condexec bits
12674 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12675 * then uses this to restore them after an exception.
12677 * Note that there are no instructions which can read the condexec
12678 * bits, and none which can write non-static values to them, so
12679 * we don't need to care about whether CPUARMState is correct in the
12683 /* Reset the conditional execution bits immediately. This avoids
12684 complications trying to do it at the end of the block. */
12685 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
12686 TCGv_i32 tmp
= tcg_temp_new_i32();
12687 tcg_gen_movi_i32(tmp
, 0);
12688 store_cpu_field(tmp
, condexec_bits
);
12692 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12694 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12696 tcg_gen_insn_start(dc
->pc
,
12697 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
12699 dc
->insn_start
= tcg_last_op();
12702 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
12703 const CPUBreakpoint
*bp
)
12705 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12707 if (bp
->flags
& BP_CPU
) {
12708 gen_set_condexec(dc
);
12709 gen_set_pc_im(dc
, dc
->pc
);
12710 gen_helper_check_breakpoints(cpu_env
);
12711 /* End the TB early; it's likely not going to be executed */
12712 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12714 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
12715 /* The address covered by the breakpoint must be
12716 included in [tb->pc, tb->pc + tb->size) in order
12717 to for it to be properly cleared -- thus we
12718 increment the PC here so that the logic setting
12719 tb->size below does the right thing. */
12720 /* TODO: Advance PC by correct instruction length to
12721 * avoid disassembler error messages */
12723 dc
->base
.is_jmp
= DISAS_NORETURN
;
12729 static bool arm_pre_translate_insn(DisasContext
*dc
)
12731 #ifdef CONFIG_USER_ONLY
12732 /* Intercept jump to the magic kernel page. */
12733 if (dc
->pc
>= 0xffff0000) {
12734 /* We always get here via a jump, so know we are not in a
12735 conditional execution block. */
12736 gen_exception_internal(EXCP_KERNEL_TRAP
);
12737 dc
->base
.is_jmp
= DISAS_NORETURN
;
12742 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12743 /* Singlestep state is Active-pending.
12744 * If we're in this state at the start of a TB then either
12745 * a) we just took an exception to an EL which is being debugged
12746 * and this is the first insn in the exception handler
12747 * b) debug exceptions were masked and we just unmasked them
12748 * without changing EL (eg by clearing PSTATE.D)
12749 * In either case we're going to take a swstep exception in the
12750 * "did not step an insn" case, and so the syndrome ISV and EX
12751 * bits should be zero.
12753 assert(dc
->base
.num_insns
== 1);
12754 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
12755 default_exception_el(dc
));
12756 dc
->base
.is_jmp
= DISAS_NORETURN
;
12763 static void arm_post_translate_insn(DisasContext
*dc
)
12765 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12766 gen_set_label(dc
->condlabel
);
12769 dc
->base
.pc_next
= dc
->pc
;
12770 translator_loop_temp_check(&dc
->base
);
12773 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12775 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12776 CPUARMState
*env
= cpu
->env_ptr
;
12779 if (arm_pre_translate_insn(dc
)) {
12783 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12786 disas_arm_insn(dc
, insn
);
12788 arm_post_translate_insn(dc
);
12790 /* ARM is a fixed-length ISA. We performed the cross-page check
12791 in init_disas_context by adjusting max_insns. */
12794 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
12796 /* Return true if this Thumb insn is always unconditional,
12797 * even inside an IT block. This is true of only a very few
12798 * instructions: BKPT, HLT, and SG.
12800 * A larger class of instructions are UNPREDICTABLE if used
12801 * inside an IT block; we do not need to detect those here, because
12802 * what we do by default (perform the cc check and update the IT
12803 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12804 * choice for those situations.
12806 * insn is either a 16-bit or a 32-bit instruction; the two are
12807 * distinguishable because for the 16-bit case the top 16 bits
12808 * are zeroes, and that isn't a valid 32-bit encoding.
12810 if ((insn
& 0xffffff00) == 0xbe00) {
12815 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12816 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
12817 /* HLT: v8A only. This is unconditional even when it is going to
12818 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12819 * For v7 cores this was a plain old undefined encoding and so
12820 * honours its cc check. (We might be using the encoding as
12821 * a semihosting trap, but we don't change the cc check behaviour
12822 * on that account, because a debugger connected to a real v7A
12823 * core and emulating semihosting traps by catching the UNDEF
12824 * exception would also only see cases where the cc check passed.
12825 * No guest code should be trying to do a HLT semihosting trap
12826 * in an IT block anyway.
12831 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12832 arm_dc_feature(s
, ARM_FEATURE_M
)) {
12840 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12842 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12843 CPUARMState
*env
= cpu
->env_ptr
;
12847 if (arm_pre_translate_insn(dc
)) {
12851 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12852 is_16bit
= thumb_insn_is_16bit(dc
, insn
);
12855 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12857 insn
= insn
<< 16 | insn2
;
12862 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
12863 uint32_t cond
= dc
->condexec_cond
;
12865 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
12866 arm_skip_unless(dc
, cond
);
12871 disas_thumb_insn(dc
, insn
);
12873 disas_thumb2_insn(dc
, insn
);
12876 /* Advance the Thumb condexec condition. */
12877 if (dc
->condexec_mask
) {
12878 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
12879 ((dc
->condexec_mask
>> 4) & 1));
12880 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12881 if (dc
->condexec_mask
== 0) {
12882 dc
->condexec_cond
= 0;
12886 arm_post_translate_insn(dc
);
12888 /* Thumb is a variable-length ISA. Stop translation when the next insn
12889 * will touch a new page. This ensures that prefetch aborts occur at
12892 * We want to stop the TB if the next insn starts in a new page,
12893 * or if it spans between this page and the next. This means that
12894 * if we're looking at the last halfword in the page we need to
12895 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12896 * or a 32-bit Thumb insn (which won't).
12897 * This is to avoid generating a silly TB with a single 16-bit insn
12898 * in it at the end of this page (which would execute correctly
12899 * but isn't very efficient).
12901 if (dc
->base
.is_jmp
== DISAS_NEXT
12902 && (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
12903 || (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
- 3
12904 && insn_crosses_page(env
, dc
)))) {
12905 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12909 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
12911 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12913 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
12914 /* FIXME: This can theoretically happen with self-modifying code. */
12915 cpu_abort(cpu
, "IO on conditional branch instruction");
12918 /* At this stage dc->condjmp will only be set when the skipped
12919 instruction was a conditional branch or trap, and the PC has
12920 already been written. */
12921 gen_set_condexec(dc
);
12922 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12923 /* Exception return branches need some special case code at the
12924 * end of the TB, which is complex enough that it has to
12925 * handle the single-step vs not and the condition-failed
12926 * insn codepath itself.
12928 gen_bx_excret_final_code(dc
);
12929 } else if (unlikely(is_singlestepping(dc
))) {
12930 /* Unconditional and "condition passed" instruction codepath. */
12931 switch (dc
->base
.is_jmp
) {
12933 gen_ss_advance(dc
);
12934 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12935 default_exception_el(dc
));
12938 gen_ss_advance(dc
);
12939 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12942 gen_ss_advance(dc
);
12943 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12946 case DISAS_TOO_MANY
:
12948 gen_set_pc_im(dc
, dc
->pc
);
12951 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12952 gen_singlestep_exception(dc
);
12954 case DISAS_NORETURN
:
12958 /* While branches must always occur at the end of an IT block,
12959 there are a few other things that can cause us to terminate
12960 the TB in the middle of an IT block:
12961 - Exception generating instructions (bkpt, swi, undefined).
12963 - Hardware watchpoints.
12964 Hardware breakpoints have already been handled and skip this code.
12966 switch(dc
->base
.is_jmp
) {
12968 case DISAS_TOO_MANY
:
12969 gen_goto_tb(dc
, 1, dc
->pc
);
12975 gen_set_pc_im(dc
, dc
->pc
);
12978 /* indicate that the hash table must be used to find the next TB */
12979 tcg_gen_exit_tb(NULL
, 0);
12981 case DISAS_NORETURN
:
12982 /* nothing more to generate */
12986 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
12987 !(dc
->insn
& (1U << 31))) ? 2 : 4);
12989 gen_helper_wfi(cpu_env
, tmp
);
12990 tcg_temp_free_i32(tmp
);
12991 /* The helper doesn't necessarily throw an exception, but we
12992 * must go back to the main loop to check for interrupts anyway.
12994 tcg_gen_exit_tb(NULL
, 0);
12998 gen_helper_wfe(cpu_env
);
13001 gen_helper_yield(cpu_env
);
13004 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
13005 default_exception_el(dc
));
13008 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
13011 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
13017 /* "Condition failed" instruction codepath for the branch/trap insn */
13018 gen_set_label(dc
->condlabel
);
13019 gen_set_condexec(dc
);
13020 if (unlikely(is_singlestepping(dc
))) {
13021 gen_set_pc_im(dc
, dc
->pc
);
13022 gen_singlestep_exception(dc
);
13024 gen_goto_tb(dc
, 1, dc
->pc
);
13028 /* Functions above can change dc->pc, so re-align db->pc_next */
13029 dc
->base
.pc_next
= dc
->pc
;
13032 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
13034 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
13036 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
13037 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
13040 static const TranslatorOps arm_translator_ops
= {
13041 .init_disas_context
= arm_tr_init_disas_context
,
13042 .tb_start
= arm_tr_tb_start
,
13043 .insn_start
= arm_tr_insn_start
,
13044 .breakpoint_check
= arm_tr_breakpoint_check
,
13045 .translate_insn
= arm_tr_translate_insn
,
13046 .tb_stop
= arm_tr_tb_stop
,
13047 .disas_log
= arm_tr_disas_log
,
13050 static const TranslatorOps thumb_translator_ops
= {
13051 .init_disas_context
= arm_tr_init_disas_context
,
13052 .tb_start
= arm_tr_tb_start
,
13053 .insn_start
= arm_tr_insn_start
,
13054 .breakpoint_check
= arm_tr_breakpoint_check
,
13055 .translate_insn
= thumb_tr_translate_insn
,
13056 .tb_stop
= arm_tr_tb_stop
,
13057 .disas_log
= arm_tr_disas_log
,
13060 /* generate intermediate code for basic block 'tb'. */
13061 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
13064 const TranslatorOps
*ops
= &arm_translator_ops
;
13066 if (FIELD_EX32(tb
->flags
, TBFLAG_A32
, THUMB
)) {
13067 ops
= &thumb_translator_ops
;
13069 #ifdef TARGET_AARCH64
13070 if (FIELD_EX32(tb
->flags
, TBFLAG_ANY
, AARCH64_STATE
)) {
13071 ops
= &aarch64_translator_ops
;
13075 translator_loop(ops
, &dc
.base
, cpu
, tb
, max_insns
);
13078 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
13080 ARMCPU
*cpu
= ARM_CPU(cs
);
13081 CPUARMState
*env
= &cpu
->env
;
13085 aarch64_cpu_dump_state(cs
, f
, flags
);
13089 for(i
=0;i
<16;i
++) {
13090 qemu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
13092 qemu_fprintf(f
, "\n");
13094 qemu_fprintf(f
, " ");
13097 if (arm_feature(env
, ARM_FEATURE_M
)) {
13098 uint32_t xpsr
= xpsr_read(env
);
13100 const char *ns_status
= "";
13102 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
13103 ns_status
= env
->v7m
.secure
? "S " : "NS ";
13106 if (xpsr
& XPSR_EXCP
) {
13109 if (env
->v7m
.control
[env
->v7m
.secure
] & R_V7M_CONTROL_NPRIV_MASK
) {
13110 mode
= "unpriv-thread";
13112 mode
= "priv-thread";
13116 qemu_fprintf(f
, "XPSR=%08x %c%c%c%c %c %s%s\n",
13118 xpsr
& XPSR_N
? 'N' : '-',
13119 xpsr
& XPSR_Z
? 'Z' : '-',
13120 xpsr
& XPSR_C
? 'C' : '-',
13121 xpsr
& XPSR_V
? 'V' : '-',
13122 xpsr
& XPSR_T
? 'T' : 'A',
13126 uint32_t psr
= cpsr_read(env
);
13127 const char *ns_status
= "";
13129 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
13130 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
13131 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
13134 qemu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13136 psr
& CPSR_N
? 'N' : '-',
13137 psr
& CPSR_Z
? 'Z' : '-',
13138 psr
& CPSR_C
? 'C' : '-',
13139 psr
& CPSR_V
? 'V' : '-',
13140 psr
& CPSR_T
? 'T' : 'A',
13142 aarch32_mode_name(psr
), (psr
& 0x10) ? 32 : 26);
13145 if (flags
& CPU_DUMP_FPU
) {
13146 int numvfpregs
= 0;
13147 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
13150 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
13153 for (i
= 0; i
< numvfpregs
; i
++) {
13154 uint64_t v
= *aa32_vfp_dreg(env
, i
);
13155 qemu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
13156 i
* 2, (uint32_t)v
,
13157 i
* 2 + 1, (uint32_t)(v
>> 32),
13160 qemu_fprintf(f
, "FPSCR: %08x\n", vfp_get_fpscr(env
));
13164 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
13165 target_ulong
*data
)
13169 env
->condexec_bits
= 0;
13170 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
13172 env
->regs
[15] = data
[0];
13173 env
->condexec_bits
= data
[1];
13174 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;