4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
28 #include "tcg-op-gvec.h"
30 #include "qemu/bitops.h"
31 #include "qemu/qemu-print.h"
33 #include "hw/semihosting/semihost.h"
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
38 #include "trace-tcg.h"
42 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
43 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
44 /* currently all emulated v5 cores are also v5TE, so don't bother */
45 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
46 #define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
47 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
48 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
49 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
50 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
51 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
53 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
55 #include "translate.h"
57 #if defined(CONFIG_USER_ONLY)
60 #define IS_USER(s) (s->user)
63 /* We reuse the same 64-bit temporaries for efficiency. */
64 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
65 static TCGv_i32 cpu_R
[16];
66 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
67 TCGv_i64 cpu_exclusive_addr
;
68 TCGv_i64 cpu_exclusive_val
;
70 /* FIXME: These should be removed. */
71 static TCGv_i32 cpu_F0s
, cpu_F1s
;
72 static TCGv_i64 cpu_F0d
, cpu_F1d
;
74 #include "exec/gen-icount.h"
76 static const char * const regnames
[] =
77 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
78 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
80 /* Function prototypes for gen_ functions calling Neon helpers. */
81 typedef void NeonGenThreeOpEnvFn(TCGv_i32
, TCGv_env
, TCGv_i32
,
84 /* initialize TCG globals. */
85 void arm_translate_init(void)
89 for (i
= 0; i
< 16; i
++) {
90 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
91 offsetof(CPUARMState
, regs
[i
]),
94 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
95 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
96 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
97 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
99 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
100 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
101 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
102 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
104 a64_translate_init();
107 /* Flags for the disas_set_da_iss info argument:
108 * lower bits hold the Rt register number, higher bits are flags.
110 typedef enum ISSInfo
{
113 ISSInvalid
= (1 << 5),
114 ISSIsAcqRel
= (1 << 6),
115 ISSIsWrite
= (1 << 7),
116 ISSIs16Bit
= (1 << 8),
119 /* Save the syndrome information for a Data Abort */
120 static void disas_set_da_iss(DisasContext
*s
, TCGMemOp memop
, ISSInfo issinfo
)
123 int sas
= memop
& MO_SIZE
;
124 bool sse
= memop
& MO_SIGN
;
125 bool is_acqrel
= issinfo
& ISSIsAcqRel
;
126 bool is_write
= issinfo
& ISSIsWrite
;
127 bool is_16bit
= issinfo
& ISSIs16Bit
;
128 int srt
= issinfo
& ISSRegMask
;
130 if (issinfo
& ISSInvalid
) {
131 /* Some callsites want to conditionally provide ISS info,
132 * eg "only if this was not a writeback"
138 /* For AArch32, insns where the src/dest is R15 never generate
139 * ISS information. Catching that here saves checking at all
145 syn
= syn_data_abort_with_iss(0, sas
, sse
, srt
, 0, is_acqrel
,
146 0, 0, 0, is_write
, 0, is_16bit
);
147 disas_set_insn_syndrome(s
, syn
);
150 static inline int get_a32_user_mem_index(DisasContext
*s
)
152 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
154 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
155 * otherwise, access as if at PL0.
157 switch (s
->mmu_idx
) {
158 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
159 case ARMMMUIdx_S12NSE0
:
160 case ARMMMUIdx_S12NSE1
:
161 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0
);
163 case ARMMMUIdx_S1SE0
:
164 case ARMMMUIdx_S1SE1
:
165 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0
);
166 case ARMMMUIdx_MUser
:
167 case ARMMMUIdx_MPriv
:
168 return arm_to_core_mmu_idx(ARMMMUIdx_MUser
);
169 case ARMMMUIdx_MUserNegPri
:
170 case ARMMMUIdx_MPrivNegPri
:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri
);
172 case ARMMMUIdx_MSUser
:
173 case ARMMMUIdx_MSPriv
:
174 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser
);
175 case ARMMMUIdx_MSUserNegPri
:
176 case ARMMMUIdx_MSPrivNegPri
:
177 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri
);
180 g_assert_not_reached();
184 static inline TCGv_i32
load_cpu_offset(int offset
)
186 TCGv_i32 tmp
= tcg_temp_new_i32();
187 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
191 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
193 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
195 tcg_gen_st_i32(var
, cpu_env
, offset
);
196 tcg_temp_free_i32(var
);
199 #define store_cpu_field(var, name) \
200 store_cpu_offset(var, offsetof(CPUARMState, name))
202 /* Set a variable to the value of a CPU register. */
203 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
207 /* normally, since we updated PC, we need only to add one insn */
209 addr
= (long)s
->pc
+ 2;
211 addr
= (long)s
->pc
+ 4;
212 tcg_gen_movi_i32(var
, addr
);
214 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
218 /* Create a new temporary and set it to the value of a CPU register. */
219 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
221 TCGv_i32 tmp
= tcg_temp_new_i32();
222 load_reg_var(s
, tmp
, reg
);
226 /* Set a CPU register. The source must be a temporary and will be
228 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
231 /* In Thumb mode, we must ignore bit 0.
232 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
233 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
234 * We choose to ignore [1:0] in ARM mode for all architecture versions.
236 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
237 s
->base
.is_jmp
= DISAS_JUMP
;
239 tcg_gen_mov_i32(cpu_R
[reg
], var
);
240 tcg_temp_free_i32(var
);
244 * Variant of store_reg which applies v8M stack-limit checks before updating
245 * SP. If the check fails this will result in an exception being taken.
246 * We disable the stack checks for CONFIG_USER_ONLY because we have
247 * no idea what the stack limits should be in that case.
248 * If stack checking is not being done this just acts like store_reg().
250 static void store_sp_checked(DisasContext
*s
, TCGv_i32 var
)
252 #ifndef CONFIG_USER_ONLY
253 if (s
->v8m_stackcheck
) {
254 gen_helper_v8m_stackcheck(cpu_env
, var
);
257 store_reg(s
, 13, var
);
260 /* Value extensions. */
261 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
262 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
263 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
264 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
266 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
267 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
270 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
272 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
273 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
274 tcg_temp_free_i32(tmp_mask
);
276 /* Set NZCV flags from the high 4 bits of var. */
277 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
279 static void gen_exception_internal(int excp
)
281 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
283 assert(excp_is_internal(excp
));
284 gen_helper_exception_internal(cpu_env
, tcg_excp
);
285 tcg_temp_free_i32(tcg_excp
);
288 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
290 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
291 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
292 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
294 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
297 tcg_temp_free_i32(tcg_el
);
298 tcg_temp_free_i32(tcg_syn
);
299 tcg_temp_free_i32(tcg_excp
);
302 static void gen_step_complete_exception(DisasContext
*s
)
304 /* We just completed step of an insn. Move from Active-not-pending
305 * to Active-pending, and then also take the swstep exception.
306 * This corresponds to making the (IMPDEF) choice to prioritize
307 * swstep exceptions over asynchronous exceptions taken to an exception
308 * level where debug is disabled. This choice has the advantage that
309 * we do not need to maintain internal state corresponding to the
310 * ISV/EX syndrome bits between completion of the step and generation
311 * of the exception, and our syndrome information is always correct.
314 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
315 default_exception_el(s
));
316 s
->base
.is_jmp
= DISAS_NORETURN
;
319 static void gen_singlestep_exception(DisasContext
*s
)
321 /* Generate the right kind of exception for singlestep, which is
322 * either the architectural singlestep or EXCP_DEBUG for QEMU's
323 * gdb singlestepping.
326 gen_step_complete_exception(s
);
328 gen_exception_internal(EXCP_DEBUG
);
332 static inline bool is_singlestepping(DisasContext
*s
)
334 /* Return true if we are singlestepping either because of
335 * architectural singlestep or QEMU gdbstub singlestep. This does
336 * not include the command line '-singlestep' mode which is rather
337 * misnamed as it only means "one instruction per TB" and doesn't
338 * affect the code we generate.
340 return s
->base
.singlestep_enabled
|| s
->ss_active
;
343 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
345 TCGv_i32 tmp1
= tcg_temp_new_i32();
346 TCGv_i32 tmp2
= tcg_temp_new_i32();
347 tcg_gen_ext16s_i32(tmp1
, a
);
348 tcg_gen_ext16s_i32(tmp2
, b
);
349 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
350 tcg_temp_free_i32(tmp2
);
351 tcg_gen_sari_i32(a
, a
, 16);
352 tcg_gen_sari_i32(b
, b
, 16);
353 tcg_gen_mul_i32(b
, b
, a
);
354 tcg_gen_mov_i32(a
, tmp1
);
355 tcg_temp_free_i32(tmp1
);
358 /* Byteswap each halfword. */
359 static void gen_rev16(TCGv_i32 var
)
361 TCGv_i32 tmp
= tcg_temp_new_i32();
362 TCGv_i32 mask
= tcg_const_i32(0x00ff00ff);
363 tcg_gen_shri_i32(tmp
, var
, 8);
364 tcg_gen_and_i32(tmp
, tmp
, mask
);
365 tcg_gen_and_i32(var
, var
, mask
);
366 tcg_gen_shli_i32(var
, var
, 8);
367 tcg_gen_or_i32(var
, var
, tmp
);
368 tcg_temp_free_i32(mask
);
369 tcg_temp_free_i32(tmp
);
372 /* Byteswap low halfword and sign extend. */
373 static void gen_revsh(TCGv_i32 var
)
375 tcg_gen_ext16u_i32(var
, var
);
376 tcg_gen_bswap16_i32(var
, var
);
377 tcg_gen_ext16s_i32(var
, var
);
380 /* Return (b << 32) + a. Mark inputs as dead */
381 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
383 TCGv_i64 tmp64
= tcg_temp_new_i64();
385 tcg_gen_extu_i32_i64(tmp64
, b
);
386 tcg_temp_free_i32(b
);
387 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
388 tcg_gen_add_i64(a
, tmp64
, a
);
390 tcg_temp_free_i64(tmp64
);
394 /* Return (b << 32) - a. Mark inputs as dead. */
395 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
397 TCGv_i64 tmp64
= tcg_temp_new_i64();
399 tcg_gen_extu_i32_i64(tmp64
, b
);
400 tcg_temp_free_i32(b
);
401 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
402 tcg_gen_sub_i64(a
, tmp64
, a
);
404 tcg_temp_free_i64(tmp64
);
408 /* 32x32->64 multiply. Marks inputs as dead. */
409 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
411 TCGv_i32 lo
= tcg_temp_new_i32();
412 TCGv_i32 hi
= tcg_temp_new_i32();
415 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
416 tcg_temp_free_i32(a
);
417 tcg_temp_free_i32(b
);
419 ret
= tcg_temp_new_i64();
420 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
421 tcg_temp_free_i32(lo
);
422 tcg_temp_free_i32(hi
);
427 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
429 TCGv_i32 lo
= tcg_temp_new_i32();
430 TCGv_i32 hi
= tcg_temp_new_i32();
433 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
434 tcg_temp_free_i32(a
);
435 tcg_temp_free_i32(b
);
437 ret
= tcg_temp_new_i64();
438 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
439 tcg_temp_free_i32(lo
);
440 tcg_temp_free_i32(hi
);
445 /* Swap low and high halfwords. */
446 static void gen_swap_half(TCGv_i32 var
)
448 TCGv_i32 tmp
= tcg_temp_new_i32();
449 tcg_gen_shri_i32(tmp
, var
, 16);
450 tcg_gen_shli_i32(var
, var
, 16);
451 tcg_gen_or_i32(var
, var
, tmp
);
452 tcg_temp_free_i32(tmp
);
455 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
456 tmp = (t0 ^ t1) & 0x8000;
459 t0 = (t0 + t1) ^ tmp;
462 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
464 TCGv_i32 tmp
= tcg_temp_new_i32();
465 tcg_gen_xor_i32(tmp
, t0
, t1
);
466 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
467 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
468 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
469 tcg_gen_add_i32(t0
, t0
, t1
);
470 tcg_gen_xor_i32(t0
, t0
, tmp
);
471 tcg_temp_free_i32(tmp
);
472 tcg_temp_free_i32(t1
);
475 /* Set CF to the top bit of var. */
476 static void gen_set_CF_bit31(TCGv_i32 var
)
478 tcg_gen_shri_i32(cpu_CF
, var
, 31);
481 /* Set N and Z flags from var. */
482 static inline void gen_logic_CC(TCGv_i32 var
)
484 tcg_gen_mov_i32(cpu_NF
, var
);
485 tcg_gen_mov_i32(cpu_ZF
, var
);
489 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
491 tcg_gen_add_i32(t0
, t0
, t1
);
492 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
495 /* dest = T0 + T1 + CF. */
496 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
498 tcg_gen_add_i32(dest
, t0
, t1
);
499 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
502 /* dest = T0 - T1 + CF - 1. */
503 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
505 tcg_gen_sub_i32(dest
, t0
, t1
);
506 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
507 tcg_gen_subi_i32(dest
, dest
, 1);
510 /* dest = T0 + T1. Compute C, N, V and Z flags */
511 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
513 TCGv_i32 tmp
= tcg_temp_new_i32();
514 tcg_gen_movi_i32(tmp
, 0);
515 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
516 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
517 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
518 tcg_gen_xor_i32(tmp
, t0
, t1
);
519 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
520 tcg_temp_free_i32(tmp
);
521 tcg_gen_mov_i32(dest
, cpu_NF
);
524 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
525 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
527 TCGv_i32 tmp
= tcg_temp_new_i32();
528 if (TCG_TARGET_HAS_add2_i32
) {
529 tcg_gen_movi_i32(tmp
, 0);
530 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
531 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
533 TCGv_i64 q0
= tcg_temp_new_i64();
534 TCGv_i64 q1
= tcg_temp_new_i64();
535 tcg_gen_extu_i32_i64(q0
, t0
);
536 tcg_gen_extu_i32_i64(q1
, t1
);
537 tcg_gen_add_i64(q0
, q0
, q1
);
538 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
539 tcg_gen_add_i64(q0
, q0
, q1
);
540 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
541 tcg_temp_free_i64(q0
);
542 tcg_temp_free_i64(q1
);
544 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
545 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
546 tcg_gen_xor_i32(tmp
, t0
, t1
);
547 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
548 tcg_temp_free_i32(tmp
);
549 tcg_gen_mov_i32(dest
, cpu_NF
);
552 /* dest = T0 - T1. Compute C, N, V and Z flags */
553 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
556 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
557 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
558 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
559 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
560 tmp
= tcg_temp_new_i32();
561 tcg_gen_xor_i32(tmp
, t0
, t1
);
562 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
563 tcg_temp_free_i32(tmp
);
564 tcg_gen_mov_i32(dest
, cpu_NF
);
567 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
568 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
570 TCGv_i32 tmp
= tcg_temp_new_i32();
571 tcg_gen_not_i32(tmp
, t1
);
572 gen_adc_CC(dest
, t0
, tmp
);
573 tcg_temp_free_i32(tmp
);
576 #define GEN_SHIFT(name) \
577 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
579 TCGv_i32 tmp1, tmp2, tmp3; \
580 tmp1 = tcg_temp_new_i32(); \
581 tcg_gen_andi_i32(tmp1, t1, 0xff); \
582 tmp2 = tcg_const_i32(0); \
583 tmp3 = tcg_const_i32(0x1f); \
584 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
585 tcg_temp_free_i32(tmp3); \
586 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
587 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
588 tcg_temp_free_i32(tmp2); \
589 tcg_temp_free_i32(tmp1); \
595 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
598 tmp1
= tcg_temp_new_i32();
599 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
600 tmp2
= tcg_const_i32(0x1f);
601 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
602 tcg_temp_free_i32(tmp2
);
603 tcg_gen_sar_i32(dest
, t0
, tmp1
);
604 tcg_temp_free_i32(tmp1
);
607 static void shifter_out_im(TCGv_i32 var
, int shift
)
610 tcg_gen_andi_i32(cpu_CF
, var
, 1);
612 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
614 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
619 /* Shift by immediate. Includes special handling for shift == 0. */
620 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
621 int shift
, int flags
)
627 shifter_out_im(var
, 32 - shift
);
628 tcg_gen_shli_i32(var
, var
, shift
);
634 tcg_gen_shri_i32(cpu_CF
, var
, 31);
636 tcg_gen_movi_i32(var
, 0);
639 shifter_out_im(var
, shift
- 1);
640 tcg_gen_shri_i32(var
, var
, shift
);
647 shifter_out_im(var
, shift
- 1);
650 tcg_gen_sari_i32(var
, var
, shift
);
652 case 3: /* ROR/RRX */
655 shifter_out_im(var
, shift
- 1);
656 tcg_gen_rotri_i32(var
, var
, shift
); break;
658 TCGv_i32 tmp
= tcg_temp_new_i32();
659 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
661 shifter_out_im(var
, 0);
662 tcg_gen_shri_i32(var
, var
, 1);
663 tcg_gen_or_i32(var
, var
, tmp
);
664 tcg_temp_free_i32(tmp
);
669 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
670 TCGv_i32 shift
, int flags
)
674 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
675 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
676 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
677 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
682 gen_shl(var
, var
, shift
);
685 gen_shr(var
, var
, shift
);
688 gen_sar(var
, var
, shift
);
690 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
691 tcg_gen_rotr_i32(var
, var
, shift
); break;
694 tcg_temp_free_i32(shift
);
697 #define PAS_OP(pfx) \
699 case 0: gen_pas_helper(glue(pfx,add16)); break; \
700 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
701 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
702 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
703 case 4: gen_pas_helper(glue(pfx,add8)); break; \
704 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
706 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
711 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
713 tmp
= tcg_temp_new_ptr();
714 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
716 tcg_temp_free_ptr(tmp
);
719 tmp
= tcg_temp_new_ptr();
720 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
722 tcg_temp_free_ptr(tmp
);
724 #undef gen_pas_helper
725 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
738 #undef gen_pas_helper
743 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
744 #define PAS_OP(pfx) \
746 case 0: gen_pas_helper(glue(pfx,add8)); break; \
747 case 1: gen_pas_helper(glue(pfx,add16)); break; \
748 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
749 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
750 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
751 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
753 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
758 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
760 tmp
= tcg_temp_new_ptr();
761 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
763 tcg_temp_free_ptr(tmp
);
766 tmp
= tcg_temp_new_ptr();
767 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
769 tcg_temp_free_ptr(tmp
);
771 #undef gen_pas_helper
772 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
785 #undef gen_pas_helper
791 * Generate a conditional based on ARM condition code cc.
792 * This is common between ARM and Aarch64 targets.
794 void arm_test_cc(DisasCompare
*cmp
, int cc
)
825 case 8: /* hi: C && !Z */
826 case 9: /* ls: !C || Z -> !(C && !Z) */
828 value
= tcg_temp_new_i32();
830 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
831 ZF is non-zero for !Z; so AND the two subexpressions. */
832 tcg_gen_neg_i32(value
, cpu_CF
);
833 tcg_gen_and_i32(value
, value
, cpu_ZF
);
836 case 10: /* ge: N == V -> N ^ V == 0 */
837 case 11: /* lt: N != V -> N ^ V != 0 */
838 /* Since we're only interested in the sign bit, == 0 is >= 0. */
840 value
= tcg_temp_new_i32();
842 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
845 case 12: /* gt: !Z && N == V */
846 case 13: /* le: Z || N != V */
848 value
= tcg_temp_new_i32();
850 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
851 * the sign bit then AND with ZF to yield the result. */
852 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
853 tcg_gen_sari_i32(value
, value
, 31);
854 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
857 case 14: /* always */
858 case 15: /* always */
859 /* Use the ALWAYS condition, which will fold early.
860 * It doesn't matter what we use for the value. */
861 cond
= TCG_COND_ALWAYS
;
866 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
871 cond
= tcg_invert_cond(cond
);
877 cmp
->value_global
= global
;
880 void arm_free_cc(DisasCompare
*cmp
)
882 if (!cmp
->value_global
) {
883 tcg_temp_free_i32(cmp
->value
);
887 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
889 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
892 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
895 arm_test_cc(&cmp
, cc
);
896 arm_jump_cc(&cmp
, label
);
900 static const uint8_t table_logic_cc
[16] = {
919 static inline void gen_set_condexec(DisasContext
*s
)
921 if (s
->condexec_mask
) {
922 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
923 TCGv_i32 tmp
= tcg_temp_new_i32();
924 tcg_gen_movi_i32(tmp
, val
);
925 store_cpu_field(tmp
, condexec_bits
);
929 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
931 tcg_gen_movi_i32(cpu_R
[15], val
);
934 /* Set PC and Thumb state from an immediate address. */
935 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
939 s
->base
.is_jmp
= DISAS_JUMP
;
940 if (s
->thumb
!= (addr
& 1)) {
941 tmp
= tcg_temp_new_i32();
942 tcg_gen_movi_i32(tmp
, addr
& 1);
943 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
944 tcg_temp_free_i32(tmp
);
946 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
949 /* Set PC and Thumb state from var. var is marked as dead. */
950 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
952 s
->base
.is_jmp
= DISAS_JUMP
;
953 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
954 tcg_gen_andi_i32(var
, var
, 1);
955 store_cpu_field(var
, thumb
);
958 /* Set PC and Thumb state from var. var is marked as dead.
959 * For M-profile CPUs, include logic to detect exception-return
960 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
961 * and BX reg, and no others, and happens only for code in Handler mode.
963 static inline void gen_bx_excret(DisasContext
*s
, TCGv_i32 var
)
965 /* Generate the same code here as for a simple bx, but flag via
966 * s->base.is_jmp that we need to do the rest of the work later.
969 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
) ||
970 (s
->v7m_handler_mode
&& arm_dc_feature(s
, ARM_FEATURE_M
))) {
971 s
->base
.is_jmp
= DISAS_BX_EXCRET
;
975 static inline void gen_bx_excret_final_code(DisasContext
*s
)
977 /* Generate the code to finish possible exception return and end the TB */
978 TCGLabel
*excret_label
= gen_new_label();
981 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
)) {
982 /* Covers FNC_RETURN and EXC_RETURN magic */
983 min_magic
= FNC_RETURN_MIN_MAGIC
;
985 /* EXC_RETURN magic only */
986 min_magic
= EXC_RETURN_MIN_MAGIC
;
989 /* Is the new PC value in the magic range indicating exception return? */
990 tcg_gen_brcondi_i32(TCG_COND_GEU
, cpu_R
[15], min_magic
, excret_label
);
991 /* No: end the TB as we would for a DISAS_JMP */
992 if (is_singlestepping(s
)) {
993 gen_singlestep_exception(s
);
995 tcg_gen_exit_tb(NULL
, 0);
997 gen_set_label(excret_label
);
998 /* Yes: this is an exception return.
999 * At this point in runtime env->regs[15] and env->thumb will hold
1000 * the exception-return magic number, which do_v7m_exception_exit()
1001 * will read. Nothing else will be able to see those values because
1002 * the cpu-exec main loop guarantees that we will always go straight
1003 * from raising the exception to the exception-handling code.
1005 * gen_ss_advance(s) does nothing on M profile currently but
1006 * calling it is conceptually the right thing as we have executed
1007 * this instruction (compare SWI, HVC, SMC handling).
1010 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
1013 static inline void gen_bxns(DisasContext
*s
, int rm
)
1015 TCGv_i32 var
= load_reg(s
, rm
);
1017 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1018 * we need to sync state before calling it, but:
1019 * - we don't need to do gen_set_pc_im() because the bxns helper will
1020 * always set the PC itself
1021 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1022 * unless it's outside an IT block or the last insn in an IT block,
1023 * so we know that condexec == 0 (already set at the top of the TB)
1024 * is correct in the non-UNPREDICTABLE cases, and we can choose
1025 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1027 gen_helper_v7m_bxns(cpu_env
, var
);
1028 tcg_temp_free_i32(var
);
1029 s
->base
.is_jmp
= DISAS_EXIT
;
1032 static inline void gen_blxns(DisasContext
*s
, int rm
)
1034 TCGv_i32 var
= load_reg(s
, rm
);
1036 /* We don't need to sync condexec state, for the same reason as bxns.
1037 * We do however need to set the PC, because the blxns helper reads it.
1038 * The blxns helper may throw an exception.
1040 gen_set_pc_im(s
, s
->pc
);
1041 gen_helper_v7m_blxns(cpu_env
, var
);
1042 tcg_temp_free_i32(var
);
1043 s
->base
.is_jmp
= DISAS_EXIT
;
1046 /* Variant of store_reg which uses branch&exchange logic when storing
1047 to r15 in ARM architecture v7 and above. The source must be a temporary
1048 and will be marked as dead. */
1049 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
1051 if (reg
== 15 && ENABLE_ARCH_7
) {
1054 store_reg(s
, reg
, var
);
1058 /* Variant of store_reg which uses branch&exchange logic when storing
1059 * to r15 in ARM architecture v5T and above. This is used for storing
1060 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1061 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1062 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
1064 if (reg
== 15 && ENABLE_ARCH_5
) {
1065 gen_bx_excret(s
, var
);
1067 store_reg(s
, reg
, var
);
1071 #ifdef CONFIG_USER_ONLY
1072 #define IS_USER_ONLY 1
1074 #define IS_USER_ONLY 0
1077 /* Abstractions of "generate code to do a guest load/store for
1078 * AArch32", where a vaddr is always 32 bits (and is zero
1079 * extended if we're a 64 bit core) and data is also
1080 * 32 bits unless specifically doing a 64 bit access.
1081 * These functions work like tcg_gen_qemu_{ld,st}* except
1082 * that the address argument is TCGv_i32 rather than TCGv.
1085 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, TCGMemOp op
)
1087 TCGv addr
= tcg_temp_new();
1088 tcg_gen_extu_i32_tl(addr
, a32
);
1090 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1091 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
1092 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
1097 static void gen_aa32_ld_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1098 int index
, TCGMemOp opc
)
1102 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
1103 !arm_dc_feature(s
, ARM_FEATURE_M_MAIN
)) {
1107 addr
= gen_aa32_addr(s
, a32
, opc
);
1108 tcg_gen_qemu_ld_i32(val
, addr
, index
, opc
);
1109 tcg_temp_free(addr
);
1112 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1113 int index
, TCGMemOp opc
)
1117 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
1118 !arm_dc_feature(s
, ARM_FEATURE_M_MAIN
)) {
1122 addr
= gen_aa32_addr(s
, a32
, opc
);
1123 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
1124 tcg_temp_free(addr
);
1127 #define DO_GEN_LD(SUFF, OPC) \
1128 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1129 TCGv_i32 a32, int index) \
1131 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1133 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1135 TCGv_i32 a32, int index, \
1138 gen_aa32_ld##SUFF(s, val, a32, index); \
1139 disas_set_da_iss(s, OPC, issinfo); \
1142 #define DO_GEN_ST(SUFF, OPC) \
1143 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1144 TCGv_i32 a32, int index) \
1146 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1148 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1150 TCGv_i32 a32, int index, \
1153 gen_aa32_st##SUFF(s, val, a32, index); \
1154 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1157 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
1159 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1160 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1161 tcg_gen_rotri_i64(val
, val
, 32);
1165 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1166 int index
, TCGMemOp opc
)
1168 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1169 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
1170 gen_aa32_frob64(s
, val
);
1171 tcg_temp_free(addr
);
1174 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1175 TCGv_i32 a32
, int index
)
1177 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1180 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1181 int index
, TCGMemOp opc
)
1183 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1185 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1186 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1187 TCGv_i64 tmp
= tcg_temp_new_i64();
1188 tcg_gen_rotri_i64(tmp
, val
, 32);
1189 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
1190 tcg_temp_free_i64(tmp
);
1192 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
1194 tcg_temp_free(addr
);
1197 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1198 TCGv_i32 a32
, int index
)
1200 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1203 DO_GEN_LD(8s
, MO_SB
)
1204 DO_GEN_LD(8u, MO_UB
)
1205 DO_GEN_LD(16s
, MO_SW
)
1206 DO_GEN_LD(16u, MO_UW
)
1207 DO_GEN_LD(32u, MO_UL
)
1209 DO_GEN_ST(16, MO_UW
)
1210 DO_GEN_ST(32, MO_UL
)
1212 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1214 /* The pre HVC helper handles cases when HVC gets trapped
1215 * as an undefined insn by runtime configuration (ie before
1216 * the insn really executes).
1218 gen_set_pc_im(s
, s
->pc
- 4);
1219 gen_helper_pre_hvc(cpu_env
);
1220 /* Otherwise we will treat this as a real exception which
1221 * happens after execution of the insn. (The distinction matters
1222 * for the PC value reported to the exception handler and also
1223 * for single stepping.)
1226 gen_set_pc_im(s
, s
->pc
);
1227 s
->base
.is_jmp
= DISAS_HVC
;
1230 static inline void gen_smc(DisasContext
*s
)
1232 /* As with HVC, we may take an exception either before or after
1233 * the insn executes.
1237 gen_set_pc_im(s
, s
->pc
- 4);
1238 tmp
= tcg_const_i32(syn_aa32_smc());
1239 gen_helper_pre_smc(cpu_env
, tmp
);
1240 tcg_temp_free_i32(tmp
);
1241 gen_set_pc_im(s
, s
->pc
);
1242 s
->base
.is_jmp
= DISAS_SMC
;
1245 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1247 gen_set_condexec(s
);
1248 gen_set_pc_im(s
, s
->pc
- offset
);
1249 gen_exception_internal(excp
);
1250 s
->base
.is_jmp
= DISAS_NORETURN
;
1253 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1254 int syn
, uint32_t target_el
)
1256 gen_set_condexec(s
);
1257 gen_set_pc_im(s
, s
->pc
- offset
);
1258 gen_exception(excp
, syn
, target_el
);
1259 s
->base
.is_jmp
= DISAS_NORETURN
;
1262 static void gen_exception_bkpt_insn(DisasContext
*s
, int offset
, uint32_t syn
)
1266 gen_set_condexec(s
);
1267 gen_set_pc_im(s
, s
->pc
- offset
);
1268 tcg_syn
= tcg_const_i32(syn
);
1269 gen_helper_exception_bkpt_insn(cpu_env
, tcg_syn
);
1270 tcg_temp_free_i32(tcg_syn
);
1271 s
->base
.is_jmp
= DISAS_NORETURN
;
1274 /* Force a TB lookup after an instruction that changes the CPU state. */
1275 static inline void gen_lookup_tb(DisasContext
*s
)
1277 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1278 s
->base
.is_jmp
= DISAS_EXIT
;
1281 static inline void gen_hlt(DisasContext
*s
, int imm
)
1283 /* HLT. This has two purposes.
1284 * Architecturally, it is an external halting debug instruction.
1285 * Since QEMU doesn't implement external debug, we treat this as
1286 * it is required for halting debug disabled: it will UNDEF.
1287 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1288 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1289 * must trigger semihosting even for ARMv7 and earlier, where
1290 * HLT was an undefined encoding.
1291 * In system mode, we don't allow userspace access to
1292 * semihosting, to provide some semblance of security
1293 * (and for consistency with our 32-bit semihosting).
1295 if (semihosting_enabled() &&
1296 #ifndef CONFIG_USER_ONLY
1297 s
->current_el
!= 0 &&
1299 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1300 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1304 gen_exception_insn(s
, s
->thumb
? 2 : 4, EXCP_UDEF
, syn_uncategorized(),
1305 default_exception_el(s
));
1308 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1311 int val
, rm
, shift
, shiftop
;
1314 if (!(insn
& (1 << 25))) {
1317 if (!(insn
& (1 << 23)))
1320 tcg_gen_addi_i32(var
, var
, val
);
1322 /* shift/register */
1324 shift
= (insn
>> 7) & 0x1f;
1325 shiftop
= (insn
>> 5) & 3;
1326 offset
= load_reg(s
, rm
);
1327 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1328 if (!(insn
& (1 << 23)))
1329 tcg_gen_sub_i32(var
, var
, offset
);
1331 tcg_gen_add_i32(var
, var
, offset
);
1332 tcg_temp_free_i32(offset
);
1336 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1337 int extra
, TCGv_i32 var
)
1342 if (insn
& (1 << 22)) {
1344 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1345 if (!(insn
& (1 << 23)))
1349 tcg_gen_addi_i32(var
, var
, val
);
1353 tcg_gen_addi_i32(var
, var
, extra
);
1355 offset
= load_reg(s
, rm
);
1356 if (!(insn
& (1 << 23)))
1357 tcg_gen_sub_i32(var
, var
, offset
);
1359 tcg_gen_add_i32(var
, var
, offset
);
1360 tcg_temp_free_i32(offset
);
1364 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1366 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1369 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1371 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1373 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1377 #define VFP_OP2(name) \
1378 static inline void gen_vfp_##name(int dp) \
1380 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1382 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1384 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1386 tcg_temp_free_ptr(fpst); \
1396 static inline void gen_vfp_F1_mul(int dp
)
1398 /* Like gen_vfp_mul() but put result in F1 */
1399 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1401 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1403 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1405 tcg_temp_free_ptr(fpst
);
1408 static inline void gen_vfp_F1_neg(int dp
)
1410 /* Like gen_vfp_neg() but put result in F1 */
1412 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1414 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1418 static inline void gen_vfp_abs(int dp
)
1421 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1423 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1426 static inline void gen_vfp_neg(int dp
)
1429 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1431 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1434 static inline void gen_vfp_sqrt(int dp
)
1437 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1439 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1442 static inline void gen_vfp_cmp(int dp
)
1445 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1447 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1450 static inline void gen_vfp_cmpe(int dp
)
1453 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1455 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1458 static inline void gen_vfp_F1_ld0(int dp
)
1461 tcg_gen_movi_i64(cpu_F1d
, 0);
1463 tcg_gen_movi_i32(cpu_F1s
, 0);
1466 #define VFP_GEN_ITOF(name) \
1467 static inline void gen_vfp_##name(int dp, int neon) \
1469 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1471 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1473 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1475 tcg_temp_free_ptr(statusptr); \
1482 #define VFP_GEN_FTOI(name) \
1483 static inline void gen_vfp_##name(int dp, int neon) \
1485 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1487 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1489 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1491 tcg_temp_free_ptr(statusptr); \
1500 #define VFP_GEN_FIX(name, round) \
1501 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1503 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1504 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1506 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1509 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1512 tcg_temp_free_i32(tmp_shift); \
1513 tcg_temp_free_ptr(statusptr); \
1515 VFP_GEN_FIX(tosh
, _round_to_zero
)
1516 VFP_GEN_FIX(tosl
, _round_to_zero
)
1517 VFP_GEN_FIX(touh
, _round_to_zero
)
1518 VFP_GEN_FIX(toul
, _round_to_zero
)
1525 static inline long vfp_reg_offset(bool dp
, unsigned reg
)
1528 return offsetof(CPUARMState
, vfp
.zregs
[reg
>> 1].d
[reg
& 1]);
1530 long ofs
= offsetof(CPUARMState
, vfp
.zregs
[reg
>> 2].d
[(reg
>> 1) & 1]);
1532 ofs
+= offsetof(CPU_DoubleU
, l
.upper
);
1534 ofs
+= offsetof(CPU_DoubleU
, l
.lower
);
1540 /* Return the offset of a 32-bit piece of a NEON register.
1541 zero is the least significant end of the register. */
1543 neon_reg_offset (int reg
, int n
)
1547 return vfp_reg_offset(0, sreg
);
1550 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1551 * where 0 is the least significant end of the register.
1554 neon_element_offset(int reg
, int element
, TCGMemOp size
)
1556 int element_size
= 1 << size
;
1557 int ofs
= element
* element_size
;
1558 #ifdef HOST_WORDS_BIGENDIAN
1559 /* Calculate the offset assuming fully little-endian,
1560 * then XOR to account for the order of the 8-byte units.
1562 if (element_size
< 8) {
1563 ofs
^= 8 - element_size
;
1566 return neon_reg_offset(reg
, 0) + ofs
;
1569 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1571 TCGv_i32 tmp
= tcg_temp_new_i32();
1572 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1576 static void neon_load_element(TCGv_i32 var
, int reg
, int ele
, TCGMemOp mop
)
1578 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1582 tcg_gen_ld8u_i32(var
, cpu_env
, offset
);
1585 tcg_gen_ld16u_i32(var
, cpu_env
, offset
);
1588 tcg_gen_ld_i32(var
, cpu_env
, offset
);
1591 g_assert_not_reached();
1595 static void neon_load_element64(TCGv_i64 var
, int reg
, int ele
, TCGMemOp mop
)
1597 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1601 tcg_gen_ld8u_i64(var
, cpu_env
, offset
);
1604 tcg_gen_ld16u_i64(var
, cpu_env
, offset
);
1607 tcg_gen_ld32u_i64(var
, cpu_env
, offset
);
1610 tcg_gen_ld_i64(var
, cpu_env
, offset
);
1613 g_assert_not_reached();
1617 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1619 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1620 tcg_temp_free_i32(var
);
1623 static void neon_store_element(int reg
, int ele
, TCGMemOp size
, TCGv_i32 var
)
1625 long offset
= neon_element_offset(reg
, ele
, size
);
1629 tcg_gen_st8_i32(var
, cpu_env
, offset
);
1632 tcg_gen_st16_i32(var
, cpu_env
, offset
);
1635 tcg_gen_st_i32(var
, cpu_env
, offset
);
1638 g_assert_not_reached();
1642 static void neon_store_element64(int reg
, int ele
, TCGMemOp size
, TCGv_i64 var
)
1644 long offset
= neon_element_offset(reg
, ele
, size
);
1648 tcg_gen_st8_i64(var
, cpu_env
, offset
);
1651 tcg_gen_st16_i64(var
, cpu_env
, offset
);
1654 tcg_gen_st32_i64(var
, cpu_env
, offset
);
1657 tcg_gen_st_i64(var
, cpu_env
, offset
);
1660 g_assert_not_reached();
1664 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1666 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1669 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1671 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1674 static inline void neon_load_reg32(TCGv_i32 var
, int reg
)
1676 tcg_gen_ld_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1679 static inline void neon_store_reg32(TCGv_i32 var
, int reg
)
1681 tcg_gen_st_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1684 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1686 TCGv_ptr ret
= tcg_temp_new_ptr();
1687 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1691 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1692 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1693 #define tcg_gen_st_f32 tcg_gen_st_i32
1694 #define tcg_gen_st_f64 tcg_gen_st_i64
1696 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1699 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1701 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1704 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1707 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1709 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1712 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1715 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1717 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1720 #define ARM_CP_RW_BIT (1 << 20)
1722 /* Include the VFP decoder */
1723 #include "translate-vfp.inc.c"
1725 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1727 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1730 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1732 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1735 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1737 TCGv_i32 var
= tcg_temp_new_i32();
1738 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1742 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1744 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1745 tcg_temp_free_i32(var
);
1748 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1750 iwmmxt_store_reg(cpu_M0
, rn
);
1753 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1755 iwmmxt_load_reg(cpu_M0
, rn
);
1758 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1760 iwmmxt_load_reg(cpu_V1
, rn
);
1761 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1764 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1766 iwmmxt_load_reg(cpu_V1
, rn
);
1767 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1770 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1772 iwmmxt_load_reg(cpu_V1
, rn
);
1773 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1776 #define IWMMXT_OP(name) \
1777 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1779 iwmmxt_load_reg(cpu_V1, rn); \
1780 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1783 #define IWMMXT_OP_ENV(name) \
1784 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1786 iwmmxt_load_reg(cpu_V1, rn); \
1787 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1790 #define IWMMXT_OP_ENV_SIZE(name) \
1791 IWMMXT_OP_ENV(name##b) \
1792 IWMMXT_OP_ENV(name##w) \
1793 IWMMXT_OP_ENV(name##l)
1795 #define IWMMXT_OP_ENV1(name) \
1796 static inline void gen_op_iwmmxt_##name##_M0(void) \
1798 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1812 IWMMXT_OP_ENV_SIZE(unpackl
)
1813 IWMMXT_OP_ENV_SIZE(unpackh
)
1815 IWMMXT_OP_ENV1(unpacklub
)
1816 IWMMXT_OP_ENV1(unpackluw
)
1817 IWMMXT_OP_ENV1(unpacklul
)
1818 IWMMXT_OP_ENV1(unpackhub
)
1819 IWMMXT_OP_ENV1(unpackhuw
)
1820 IWMMXT_OP_ENV1(unpackhul
)
1821 IWMMXT_OP_ENV1(unpacklsb
)
1822 IWMMXT_OP_ENV1(unpacklsw
)
1823 IWMMXT_OP_ENV1(unpacklsl
)
1824 IWMMXT_OP_ENV1(unpackhsb
)
1825 IWMMXT_OP_ENV1(unpackhsw
)
1826 IWMMXT_OP_ENV1(unpackhsl
)
1828 IWMMXT_OP_ENV_SIZE(cmpeq
)
1829 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1830 IWMMXT_OP_ENV_SIZE(cmpgts
)
1832 IWMMXT_OP_ENV_SIZE(mins
)
1833 IWMMXT_OP_ENV_SIZE(minu
)
1834 IWMMXT_OP_ENV_SIZE(maxs
)
1835 IWMMXT_OP_ENV_SIZE(maxu
)
1837 IWMMXT_OP_ENV_SIZE(subn
)
1838 IWMMXT_OP_ENV_SIZE(addn
)
1839 IWMMXT_OP_ENV_SIZE(subu
)
1840 IWMMXT_OP_ENV_SIZE(addu
)
1841 IWMMXT_OP_ENV_SIZE(subs
)
1842 IWMMXT_OP_ENV_SIZE(adds
)
1844 IWMMXT_OP_ENV(avgb0
)
1845 IWMMXT_OP_ENV(avgb1
)
1846 IWMMXT_OP_ENV(avgw0
)
1847 IWMMXT_OP_ENV(avgw1
)
1849 IWMMXT_OP_ENV(packuw
)
1850 IWMMXT_OP_ENV(packul
)
1851 IWMMXT_OP_ENV(packuq
)
1852 IWMMXT_OP_ENV(packsw
)
1853 IWMMXT_OP_ENV(packsl
)
1854 IWMMXT_OP_ENV(packsq
)
1856 static void gen_op_iwmmxt_set_mup(void)
1859 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1860 tcg_gen_ori_i32(tmp
, tmp
, 2);
1861 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1864 static void gen_op_iwmmxt_set_cup(void)
1867 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1868 tcg_gen_ori_i32(tmp
, tmp
, 1);
1869 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1872 static void gen_op_iwmmxt_setpsr_nz(void)
1874 TCGv_i32 tmp
= tcg_temp_new_i32();
1875 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1876 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1879 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1881 iwmmxt_load_reg(cpu_V1
, rn
);
1882 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1883 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1886 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1893 rd
= (insn
>> 16) & 0xf;
1894 tmp
= load_reg(s
, rd
);
1896 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1897 if (insn
& (1 << 24)) {
1899 if (insn
& (1 << 23))
1900 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1902 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1903 tcg_gen_mov_i32(dest
, tmp
);
1904 if (insn
& (1 << 21))
1905 store_reg(s
, rd
, tmp
);
1907 tcg_temp_free_i32(tmp
);
1908 } else if (insn
& (1 << 21)) {
1910 tcg_gen_mov_i32(dest
, tmp
);
1911 if (insn
& (1 << 23))
1912 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1914 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1915 store_reg(s
, rd
, tmp
);
1916 } else if (!(insn
& (1 << 23)))
1921 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1923 int rd
= (insn
>> 0) & 0xf;
1926 if (insn
& (1 << 8)) {
1927 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1930 tmp
= iwmmxt_load_creg(rd
);
1933 tmp
= tcg_temp_new_i32();
1934 iwmmxt_load_reg(cpu_V0
, rd
);
1935 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1937 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1938 tcg_gen_mov_i32(dest
, tmp
);
1939 tcg_temp_free_i32(tmp
);
1943 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1944 (ie. an undefined instruction). */
1945 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1948 int rdhi
, rdlo
, rd0
, rd1
, i
;
1950 TCGv_i32 tmp
, tmp2
, tmp3
;
1952 if ((insn
& 0x0e000e00) == 0x0c000000) {
1953 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1955 rdlo
= (insn
>> 12) & 0xf;
1956 rdhi
= (insn
>> 16) & 0xf;
1957 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1958 iwmmxt_load_reg(cpu_V0
, wrd
);
1959 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1960 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1961 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1962 } else { /* TMCRR */
1963 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1964 iwmmxt_store_reg(cpu_V0
, wrd
);
1965 gen_op_iwmmxt_set_mup();
1970 wrd
= (insn
>> 12) & 0xf;
1971 addr
= tcg_temp_new_i32();
1972 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1973 tcg_temp_free_i32(addr
);
1976 if (insn
& ARM_CP_RW_BIT
) {
1977 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1978 tmp
= tcg_temp_new_i32();
1979 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1980 iwmmxt_store_creg(wrd
, tmp
);
1983 if (insn
& (1 << 8)) {
1984 if (insn
& (1 << 22)) { /* WLDRD */
1985 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1987 } else { /* WLDRW wRd */
1988 tmp
= tcg_temp_new_i32();
1989 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1992 tmp
= tcg_temp_new_i32();
1993 if (insn
& (1 << 22)) { /* WLDRH */
1994 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1995 } else { /* WLDRB */
1996 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2000 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
2001 tcg_temp_free_i32(tmp
);
2003 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2006 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
2007 tmp
= iwmmxt_load_creg(wrd
);
2008 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
2010 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2011 tmp
= tcg_temp_new_i32();
2012 if (insn
& (1 << 8)) {
2013 if (insn
& (1 << 22)) { /* WSTRD */
2014 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
2015 } else { /* WSTRW wRd */
2016 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2017 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
2020 if (insn
& (1 << 22)) { /* WSTRH */
2021 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2022 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
2023 } else { /* WSTRB */
2024 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2025 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
2029 tcg_temp_free_i32(tmp
);
2031 tcg_temp_free_i32(addr
);
2035 if ((insn
& 0x0f000000) != 0x0e000000)
2038 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
2039 case 0x000: /* WOR */
2040 wrd
= (insn
>> 12) & 0xf;
2041 rd0
= (insn
>> 0) & 0xf;
2042 rd1
= (insn
>> 16) & 0xf;
2043 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2044 gen_op_iwmmxt_orq_M0_wRn(rd1
);
2045 gen_op_iwmmxt_setpsr_nz();
2046 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2047 gen_op_iwmmxt_set_mup();
2048 gen_op_iwmmxt_set_cup();
2050 case 0x011: /* TMCR */
2053 rd
= (insn
>> 12) & 0xf;
2054 wrd
= (insn
>> 16) & 0xf;
2056 case ARM_IWMMXT_wCID
:
2057 case ARM_IWMMXT_wCASF
:
2059 case ARM_IWMMXT_wCon
:
2060 gen_op_iwmmxt_set_cup();
2062 case ARM_IWMMXT_wCSSF
:
2063 tmp
= iwmmxt_load_creg(wrd
);
2064 tmp2
= load_reg(s
, rd
);
2065 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
2066 tcg_temp_free_i32(tmp2
);
2067 iwmmxt_store_creg(wrd
, tmp
);
2069 case ARM_IWMMXT_wCGR0
:
2070 case ARM_IWMMXT_wCGR1
:
2071 case ARM_IWMMXT_wCGR2
:
2072 case ARM_IWMMXT_wCGR3
:
2073 gen_op_iwmmxt_set_cup();
2074 tmp
= load_reg(s
, rd
);
2075 iwmmxt_store_creg(wrd
, tmp
);
2081 case 0x100: /* WXOR */
2082 wrd
= (insn
>> 12) & 0xf;
2083 rd0
= (insn
>> 0) & 0xf;
2084 rd1
= (insn
>> 16) & 0xf;
2085 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2086 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
2087 gen_op_iwmmxt_setpsr_nz();
2088 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2089 gen_op_iwmmxt_set_mup();
2090 gen_op_iwmmxt_set_cup();
2092 case 0x111: /* TMRC */
2095 rd
= (insn
>> 12) & 0xf;
2096 wrd
= (insn
>> 16) & 0xf;
2097 tmp
= iwmmxt_load_creg(wrd
);
2098 store_reg(s
, rd
, tmp
);
2100 case 0x300: /* WANDN */
2101 wrd
= (insn
>> 12) & 0xf;
2102 rd0
= (insn
>> 0) & 0xf;
2103 rd1
= (insn
>> 16) & 0xf;
2104 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2105 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
2106 gen_op_iwmmxt_andq_M0_wRn(rd1
);
2107 gen_op_iwmmxt_setpsr_nz();
2108 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2109 gen_op_iwmmxt_set_mup();
2110 gen_op_iwmmxt_set_cup();
2112 case 0x200: /* WAND */
2113 wrd
= (insn
>> 12) & 0xf;
2114 rd0
= (insn
>> 0) & 0xf;
2115 rd1
= (insn
>> 16) & 0xf;
2116 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2117 gen_op_iwmmxt_andq_M0_wRn(rd1
);
2118 gen_op_iwmmxt_setpsr_nz();
2119 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2120 gen_op_iwmmxt_set_mup();
2121 gen_op_iwmmxt_set_cup();
2123 case 0x810: case 0xa10: /* WMADD */
2124 wrd
= (insn
>> 12) & 0xf;
2125 rd0
= (insn
>> 0) & 0xf;
2126 rd1
= (insn
>> 16) & 0xf;
2127 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2128 if (insn
& (1 << 21))
2129 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
2131 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
2132 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2133 gen_op_iwmmxt_set_mup();
2135 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2136 wrd
= (insn
>> 12) & 0xf;
2137 rd0
= (insn
>> 16) & 0xf;
2138 rd1
= (insn
>> 0) & 0xf;
2139 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2140 switch ((insn
>> 22) & 3) {
2142 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
2145 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
2148 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
2153 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2154 gen_op_iwmmxt_set_mup();
2155 gen_op_iwmmxt_set_cup();
2157 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2158 wrd
= (insn
>> 12) & 0xf;
2159 rd0
= (insn
>> 16) & 0xf;
2160 rd1
= (insn
>> 0) & 0xf;
2161 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2162 switch ((insn
>> 22) & 3) {
2164 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
2167 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
2170 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
2175 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2176 gen_op_iwmmxt_set_mup();
2177 gen_op_iwmmxt_set_cup();
2179 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2180 wrd
= (insn
>> 12) & 0xf;
2181 rd0
= (insn
>> 16) & 0xf;
2182 rd1
= (insn
>> 0) & 0xf;
2183 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2184 if (insn
& (1 << 22))
2185 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2187 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2188 if (!(insn
& (1 << 20)))
2189 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2190 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2191 gen_op_iwmmxt_set_mup();
2193 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2194 wrd
= (insn
>> 12) & 0xf;
2195 rd0
= (insn
>> 16) & 0xf;
2196 rd1
= (insn
>> 0) & 0xf;
2197 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2198 if (insn
& (1 << 21)) {
2199 if (insn
& (1 << 20))
2200 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2202 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2204 if (insn
& (1 << 20))
2205 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2207 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2209 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2210 gen_op_iwmmxt_set_mup();
2212 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2213 wrd
= (insn
>> 12) & 0xf;
2214 rd0
= (insn
>> 16) & 0xf;
2215 rd1
= (insn
>> 0) & 0xf;
2216 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2217 if (insn
& (1 << 21))
2218 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2220 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2221 if (!(insn
& (1 << 20))) {
2222 iwmmxt_load_reg(cpu_V1
, wrd
);
2223 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2225 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2226 gen_op_iwmmxt_set_mup();
2228 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2229 wrd
= (insn
>> 12) & 0xf;
2230 rd0
= (insn
>> 16) & 0xf;
2231 rd1
= (insn
>> 0) & 0xf;
2232 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2233 switch ((insn
>> 22) & 3) {
2235 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2238 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2241 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2246 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2247 gen_op_iwmmxt_set_mup();
2248 gen_op_iwmmxt_set_cup();
2250 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2251 wrd
= (insn
>> 12) & 0xf;
2252 rd0
= (insn
>> 16) & 0xf;
2253 rd1
= (insn
>> 0) & 0xf;
2254 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2255 if (insn
& (1 << 22)) {
2256 if (insn
& (1 << 20))
2257 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2259 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2261 if (insn
& (1 << 20))
2262 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2264 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2266 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2267 gen_op_iwmmxt_set_mup();
2268 gen_op_iwmmxt_set_cup();
2270 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2271 wrd
= (insn
>> 12) & 0xf;
2272 rd0
= (insn
>> 16) & 0xf;
2273 rd1
= (insn
>> 0) & 0xf;
2274 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2275 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2276 tcg_gen_andi_i32(tmp
, tmp
, 7);
2277 iwmmxt_load_reg(cpu_V1
, rd1
);
2278 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2279 tcg_temp_free_i32(tmp
);
2280 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2281 gen_op_iwmmxt_set_mup();
2283 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2284 if (((insn
>> 6) & 3) == 3)
2286 rd
= (insn
>> 12) & 0xf;
2287 wrd
= (insn
>> 16) & 0xf;
2288 tmp
= load_reg(s
, rd
);
2289 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2290 switch ((insn
>> 6) & 3) {
2292 tmp2
= tcg_const_i32(0xff);
2293 tmp3
= tcg_const_i32((insn
& 7) << 3);
2296 tmp2
= tcg_const_i32(0xffff);
2297 tmp3
= tcg_const_i32((insn
& 3) << 4);
2300 tmp2
= tcg_const_i32(0xffffffff);
2301 tmp3
= tcg_const_i32((insn
& 1) << 5);
2307 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2308 tcg_temp_free_i32(tmp3
);
2309 tcg_temp_free_i32(tmp2
);
2310 tcg_temp_free_i32(tmp
);
2311 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2312 gen_op_iwmmxt_set_mup();
2314 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2315 rd
= (insn
>> 12) & 0xf;
2316 wrd
= (insn
>> 16) & 0xf;
2317 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2319 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2320 tmp
= tcg_temp_new_i32();
2321 switch ((insn
>> 22) & 3) {
2323 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2324 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2326 tcg_gen_ext8s_i32(tmp
, tmp
);
2328 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2332 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2333 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2335 tcg_gen_ext16s_i32(tmp
, tmp
);
2337 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2341 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2342 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2345 store_reg(s
, rd
, tmp
);
2347 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2348 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2350 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2351 switch ((insn
>> 22) & 3) {
2353 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2356 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2359 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2362 tcg_gen_shli_i32(tmp
, tmp
, 28);
2364 tcg_temp_free_i32(tmp
);
2366 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2367 if (((insn
>> 6) & 3) == 3)
2369 rd
= (insn
>> 12) & 0xf;
2370 wrd
= (insn
>> 16) & 0xf;
2371 tmp
= load_reg(s
, rd
);
2372 switch ((insn
>> 6) & 3) {
2374 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2377 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2380 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2383 tcg_temp_free_i32(tmp
);
2384 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2385 gen_op_iwmmxt_set_mup();
2387 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2388 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2390 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2391 tmp2
= tcg_temp_new_i32();
2392 tcg_gen_mov_i32(tmp2
, tmp
);
2393 switch ((insn
>> 22) & 3) {
2395 for (i
= 0; i
< 7; i
++) {
2396 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2397 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2401 for (i
= 0; i
< 3; i
++) {
2402 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2403 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2407 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2408 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2412 tcg_temp_free_i32(tmp2
);
2413 tcg_temp_free_i32(tmp
);
2415 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2416 wrd
= (insn
>> 12) & 0xf;
2417 rd0
= (insn
>> 16) & 0xf;
2418 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2419 switch ((insn
>> 22) & 3) {
2421 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2424 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2427 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2432 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2433 gen_op_iwmmxt_set_mup();
2435 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2436 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2438 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2439 tmp2
= tcg_temp_new_i32();
2440 tcg_gen_mov_i32(tmp2
, tmp
);
2441 switch ((insn
>> 22) & 3) {
2443 for (i
= 0; i
< 7; i
++) {
2444 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2445 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2449 for (i
= 0; i
< 3; i
++) {
2450 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2451 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2455 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2456 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2460 tcg_temp_free_i32(tmp2
);
2461 tcg_temp_free_i32(tmp
);
2463 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2464 rd
= (insn
>> 12) & 0xf;
2465 rd0
= (insn
>> 16) & 0xf;
2466 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2468 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2469 tmp
= tcg_temp_new_i32();
2470 switch ((insn
>> 22) & 3) {
2472 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2475 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2478 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2481 store_reg(s
, rd
, tmp
);
2483 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2484 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2485 wrd
= (insn
>> 12) & 0xf;
2486 rd0
= (insn
>> 16) & 0xf;
2487 rd1
= (insn
>> 0) & 0xf;
2488 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2489 switch ((insn
>> 22) & 3) {
2491 if (insn
& (1 << 21))
2492 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2494 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2497 if (insn
& (1 << 21))
2498 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2500 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2503 if (insn
& (1 << 21))
2504 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2506 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2511 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2512 gen_op_iwmmxt_set_mup();
2513 gen_op_iwmmxt_set_cup();
2515 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2516 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2517 wrd
= (insn
>> 12) & 0xf;
2518 rd0
= (insn
>> 16) & 0xf;
2519 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2520 switch ((insn
>> 22) & 3) {
2522 if (insn
& (1 << 21))
2523 gen_op_iwmmxt_unpacklsb_M0();
2525 gen_op_iwmmxt_unpacklub_M0();
2528 if (insn
& (1 << 21))
2529 gen_op_iwmmxt_unpacklsw_M0();
2531 gen_op_iwmmxt_unpackluw_M0();
2534 if (insn
& (1 << 21))
2535 gen_op_iwmmxt_unpacklsl_M0();
2537 gen_op_iwmmxt_unpacklul_M0();
2542 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2543 gen_op_iwmmxt_set_mup();
2544 gen_op_iwmmxt_set_cup();
2546 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2547 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2548 wrd
= (insn
>> 12) & 0xf;
2549 rd0
= (insn
>> 16) & 0xf;
2550 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2551 switch ((insn
>> 22) & 3) {
2553 if (insn
& (1 << 21))
2554 gen_op_iwmmxt_unpackhsb_M0();
2556 gen_op_iwmmxt_unpackhub_M0();
2559 if (insn
& (1 << 21))
2560 gen_op_iwmmxt_unpackhsw_M0();
2562 gen_op_iwmmxt_unpackhuw_M0();
2565 if (insn
& (1 << 21))
2566 gen_op_iwmmxt_unpackhsl_M0();
2568 gen_op_iwmmxt_unpackhul_M0();
2573 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2574 gen_op_iwmmxt_set_mup();
2575 gen_op_iwmmxt_set_cup();
2577 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2578 case 0x214: case 0x614: case 0xa14: case 0xe14:
2579 if (((insn
>> 22) & 3) == 0)
2581 wrd
= (insn
>> 12) & 0xf;
2582 rd0
= (insn
>> 16) & 0xf;
2583 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2584 tmp
= tcg_temp_new_i32();
2585 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2586 tcg_temp_free_i32(tmp
);
2589 switch ((insn
>> 22) & 3) {
2591 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2594 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2597 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2600 tcg_temp_free_i32(tmp
);
2601 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2602 gen_op_iwmmxt_set_mup();
2603 gen_op_iwmmxt_set_cup();
2605 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2606 case 0x014: case 0x414: case 0x814: case 0xc14:
2607 if (((insn
>> 22) & 3) == 0)
2609 wrd
= (insn
>> 12) & 0xf;
2610 rd0
= (insn
>> 16) & 0xf;
2611 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2612 tmp
= tcg_temp_new_i32();
2613 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2614 tcg_temp_free_i32(tmp
);
2617 switch ((insn
>> 22) & 3) {
2619 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2622 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2625 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2628 tcg_temp_free_i32(tmp
);
2629 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2630 gen_op_iwmmxt_set_mup();
2631 gen_op_iwmmxt_set_cup();
2633 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2634 case 0x114: case 0x514: case 0x914: case 0xd14:
2635 if (((insn
>> 22) & 3) == 0)
2637 wrd
= (insn
>> 12) & 0xf;
2638 rd0
= (insn
>> 16) & 0xf;
2639 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2640 tmp
= tcg_temp_new_i32();
2641 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2642 tcg_temp_free_i32(tmp
);
2645 switch ((insn
>> 22) & 3) {
2647 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2650 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2653 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2656 tcg_temp_free_i32(tmp
);
2657 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2658 gen_op_iwmmxt_set_mup();
2659 gen_op_iwmmxt_set_cup();
2661 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2662 case 0x314: case 0x714: case 0xb14: case 0xf14:
2663 if (((insn
>> 22) & 3) == 0)
2665 wrd
= (insn
>> 12) & 0xf;
2666 rd0
= (insn
>> 16) & 0xf;
2667 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2668 tmp
= tcg_temp_new_i32();
2669 switch ((insn
>> 22) & 3) {
2671 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2672 tcg_temp_free_i32(tmp
);
2675 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2678 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2679 tcg_temp_free_i32(tmp
);
2682 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2685 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2686 tcg_temp_free_i32(tmp
);
2689 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2692 tcg_temp_free_i32(tmp
);
2693 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2694 gen_op_iwmmxt_set_mup();
2695 gen_op_iwmmxt_set_cup();
2697 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2698 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2699 wrd
= (insn
>> 12) & 0xf;
2700 rd0
= (insn
>> 16) & 0xf;
2701 rd1
= (insn
>> 0) & 0xf;
2702 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2703 switch ((insn
>> 22) & 3) {
2705 if (insn
& (1 << 21))
2706 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2708 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2711 if (insn
& (1 << 21))
2712 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2714 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2717 if (insn
& (1 << 21))
2718 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2720 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2725 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2726 gen_op_iwmmxt_set_mup();
2728 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2729 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2730 wrd
= (insn
>> 12) & 0xf;
2731 rd0
= (insn
>> 16) & 0xf;
2732 rd1
= (insn
>> 0) & 0xf;
2733 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2734 switch ((insn
>> 22) & 3) {
2736 if (insn
& (1 << 21))
2737 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2739 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2742 if (insn
& (1 << 21))
2743 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2745 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2748 if (insn
& (1 << 21))
2749 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2751 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2756 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2757 gen_op_iwmmxt_set_mup();
2759 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2760 case 0x402: case 0x502: case 0x602: case 0x702:
2761 wrd
= (insn
>> 12) & 0xf;
2762 rd0
= (insn
>> 16) & 0xf;
2763 rd1
= (insn
>> 0) & 0xf;
2764 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2765 tmp
= tcg_const_i32((insn
>> 20) & 3);
2766 iwmmxt_load_reg(cpu_V1
, rd1
);
2767 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2768 tcg_temp_free_i32(tmp
);
2769 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2770 gen_op_iwmmxt_set_mup();
2772 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2773 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2774 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2775 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2776 wrd
= (insn
>> 12) & 0xf;
2777 rd0
= (insn
>> 16) & 0xf;
2778 rd1
= (insn
>> 0) & 0xf;
2779 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2780 switch ((insn
>> 20) & 0xf) {
2782 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2785 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2788 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2791 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2794 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2797 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2800 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2803 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2806 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2811 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2812 gen_op_iwmmxt_set_mup();
2813 gen_op_iwmmxt_set_cup();
2815 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2816 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2817 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2818 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2819 wrd
= (insn
>> 12) & 0xf;
2820 rd0
= (insn
>> 16) & 0xf;
2821 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2822 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2823 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2824 tcg_temp_free_i32(tmp
);
2825 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2826 gen_op_iwmmxt_set_mup();
2827 gen_op_iwmmxt_set_cup();
2829 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2830 case 0x418: case 0x518: case 0x618: case 0x718:
2831 case 0x818: case 0x918: case 0xa18: case 0xb18:
2832 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2833 wrd
= (insn
>> 12) & 0xf;
2834 rd0
= (insn
>> 16) & 0xf;
2835 rd1
= (insn
>> 0) & 0xf;
2836 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2837 switch ((insn
>> 20) & 0xf) {
2839 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2842 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2845 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2848 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2851 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2854 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2857 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2860 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2863 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2868 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2869 gen_op_iwmmxt_set_mup();
2870 gen_op_iwmmxt_set_cup();
2872 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2873 case 0x408: case 0x508: case 0x608: case 0x708:
2874 case 0x808: case 0x908: case 0xa08: case 0xb08:
2875 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2876 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2878 wrd
= (insn
>> 12) & 0xf;
2879 rd0
= (insn
>> 16) & 0xf;
2880 rd1
= (insn
>> 0) & 0xf;
2881 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2882 switch ((insn
>> 22) & 3) {
2884 if (insn
& (1 << 21))
2885 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2887 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2890 if (insn
& (1 << 21))
2891 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2893 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2896 if (insn
& (1 << 21))
2897 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2899 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2902 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2903 gen_op_iwmmxt_set_mup();
2904 gen_op_iwmmxt_set_cup();
2906 case 0x201: case 0x203: case 0x205: case 0x207:
2907 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2908 case 0x211: case 0x213: case 0x215: case 0x217:
2909 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2910 wrd
= (insn
>> 5) & 0xf;
2911 rd0
= (insn
>> 12) & 0xf;
2912 rd1
= (insn
>> 0) & 0xf;
2913 if (rd0
== 0xf || rd1
== 0xf)
2915 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2916 tmp
= load_reg(s
, rd0
);
2917 tmp2
= load_reg(s
, rd1
);
2918 switch ((insn
>> 16) & 0xf) {
2919 case 0x0: /* TMIA */
2920 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2922 case 0x8: /* TMIAPH */
2923 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2925 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2926 if (insn
& (1 << 16))
2927 tcg_gen_shri_i32(tmp
, tmp
, 16);
2928 if (insn
& (1 << 17))
2929 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2930 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2933 tcg_temp_free_i32(tmp2
);
2934 tcg_temp_free_i32(tmp
);
2937 tcg_temp_free_i32(tmp2
);
2938 tcg_temp_free_i32(tmp
);
2939 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2940 gen_op_iwmmxt_set_mup();
2949 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2950 (ie. an undefined instruction). */
2951 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2953 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2956 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2957 /* Multiply with Internal Accumulate Format */
2958 rd0
= (insn
>> 12) & 0xf;
2960 acc
= (insn
>> 5) & 7;
2965 tmp
= load_reg(s
, rd0
);
2966 tmp2
= load_reg(s
, rd1
);
2967 switch ((insn
>> 16) & 0xf) {
2969 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2971 case 0x8: /* MIAPH */
2972 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2974 case 0xc: /* MIABB */
2975 case 0xd: /* MIABT */
2976 case 0xe: /* MIATB */
2977 case 0xf: /* MIATT */
2978 if (insn
& (1 << 16))
2979 tcg_gen_shri_i32(tmp
, tmp
, 16);
2980 if (insn
& (1 << 17))
2981 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2982 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2987 tcg_temp_free_i32(tmp2
);
2988 tcg_temp_free_i32(tmp
);
2990 gen_op_iwmmxt_movq_wRn_M0(acc
);
2994 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2995 /* Internal Accumulator Access Format */
2996 rdhi
= (insn
>> 16) & 0xf;
2997 rdlo
= (insn
>> 12) & 0xf;
3003 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
3004 iwmmxt_load_reg(cpu_V0
, acc
);
3005 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
3006 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
3007 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
3008 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
3010 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
3011 iwmmxt_store_reg(cpu_V0
, acc
);
3019 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
3020 #define VFP_SREG(insn, bigbit, smallbit) \
3021 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
3022 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
3023 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
3024 reg = (((insn) >> (bigbit)) & 0x0f) \
3025 | (((insn) >> ((smallbit) - 4)) & 0x10); \
3027 if (insn & (1 << (smallbit))) \
3029 reg = ((insn) >> (bigbit)) & 0x0f; \
3032 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
3033 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
3034 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
3035 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
3036 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
3037 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
3039 /* Move between integer and VFP cores. */
3040 static TCGv_i32
gen_vfp_mrs(void)
3042 TCGv_i32 tmp
= tcg_temp_new_i32();
3043 tcg_gen_mov_i32(tmp
, cpu_F0s
);
3047 static void gen_vfp_msr(TCGv_i32 tmp
)
3049 tcg_gen_mov_i32(cpu_F0s
, tmp
);
3050 tcg_temp_free_i32(tmp
);
3053 static void gen_neon_dup_low16(TCGv_i32 var
)
3055 TCGv_i32 tmp
= tcg_temp_new_i32();
3056 tcg_gen_ext16u_i32(var
, var
);
3057 tcg_gen_shli_i32(tmp
, var
, 16);
3058 tcg_gen_or_i32(var
, var
, tmp
);
3059 tcg_temp_free_i32(tmp
);
3062 static void gen_neon_dup_high16(TCGv_i32 var
)
3064 TCGv_i32 tmp
= tcg_temp_new_i32();
3065 tcg_gen_andi_i32(var
, var
, 0xffff0000);
3066 tcg_gen_shri_i32(tmp
, var
, 16);
3067 tcg_gen_or_i32(var
, var
, tmp
);
3068 tcg_temp_free_i32(tmp
);
3072 * Disassemble a VFP instruction. Returns nonzero if an error occurred
3073 * (ie. an undefined instruction).
3075 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3077 uint32_t rd
, rn
, rm
, op
, i
, n
, delta_d
, delta_m
, bank_mask
;
3082 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3087 * If the decodetree decoder handles this insn it will always
3088 * emit code to either execute the insn or generate an appropriate
3089 * exception; so we don't need to ever return non-zero to tell
3090 * the calling code to emit an UNDEF exception.
3092 if (extract32(insn
, 28, 4) == 0xf) {
3093 if (disas_vfp_uncond(s
, insn
)) {
3097 if (disas_vfp(s
, insn
)) {
3102 if (extract32(insn
, 28, 4) == 0xf) {
3104 * Encodings with T=1 (Thumb) or unconditional (ARM): these
3105 * were all handled by the decodetree decoder, so any insn
3106 * patterns which get here must be UNDEF.
3112 * FIXME: this access check should not take precedence over UNDEF
3113 * for invalid encodings; we will generate incorrect syndrome information
3114 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3116 if (!vfp_access_check(s
)) {
3120 dp
= ((insn
& 0xf00) == 0xb00);
3121 switch ((insn
>> 24) & 0xf) {
3123 if (insn
& (1 << 4)) {
3124 /* already handled by decodetree */
3127 /* data processing */
3130 bool no_output
= false;
3132 /* The opcode is in bits 23, 21, 20 and 6. */
3133 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3134 rn
= VFP_SREG_N(insn
);
3137 /* rn is opcode, encoded as per VFP_SREG_N. */
3139 case 0x00: /* vmov */
3140 case 0x01: /* vabs */
3141 case 0x02: /* vneg */
3142 case 0x03: /* vsqrt */
3145 case 0x04: /* vcvtb.f64.f16, vcvtb.f32.f16 */
3146 case 0x05: /* vcvtt.f64.f16, vcvtt.f32.f16 */
3148 * VCVTB, VCVTT: only present with the halfprec extension
3149 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3150 * (we choose to UNDEF)
3153 if (!dc_isar_feature(aa32_fp16_dpconv
, s
)) {
3157 if (!dc_isar_feature(aa32_fp16_spconv
, s
)) {
3163 case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3164 case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3166 if (!dc_isar_feature(aa32_fp16_dpconv
, s
)) {
3170 if (!dc_isar_feature(aa32_fp16_spconv
, s
)) {
3177 case 0x08: case 0x0a: /* vcmp, vcmpz */
3178 case 0x09: case 0x0b: /* vcmpe, vcmpez */
3182 case 0x0c: /* vrintr */
3183 case 0x0d: /* vrintz */
3184 case 0x0e: /* vrintx */
3187 case 0x0f: /* vcvt double<->single */
3191 case 0x10: /* vcvt.fxx.u32 */
3192 case 0x11: /* vcvt.fxx.s32 */
3195 case 0x18: /* vcvtr.u32.fxx */
3196 case 0x19: /* vcvtz.u32.fxx */
3197 case 0x1a: /* vcvtr.s32.fxx */
3198 case 0x1b: /* vcvtz.s32.fxx */
3202 case 0x14: /* vcvt fp <-> fixed */
3210 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3213 /* Immediate frac_bits has same format as SREG_M. */
3217 case 0x13: /* vjcvt */
3218 if (!dp
|| !dc_isar_feature(aa32_jscvt
, s
)) {
3228 /* rn is register number */
3229 VFP_DREG_N(rn
, insn
);
3233 VFP_DREG_D(rd
, insn
);
3235 rd
= VFP_SREG_D(insn
);
3238 VFP_DREG_M(rm
, insn
);
3240 rm
= VFP_SREG_M(insn
);
3243 veclen
= s
->vec_len
;
3244 if (op
== 15 && rn
> 3) {
3248 /* Shut up compiler warnings. */
3259 /* Figure out what type of vector operation this is. */
3260 if ((rd
& bank_mask
) == 0) {
3265 delta_d
= (s
->vec_stride
>> 1) + 1;
3267 delta_d
= s
->vec_stride
+ 1;
3269 if ((rm
& bank_mask
) == 0) {
3270 /* mixed scalar/vector */
3279 /* Load the initial operands. */
3282 case 0x08: case 0x09: /* Compare */
3283 gen_mov_F0_vreg(dp
, rd
);
3284 gen_mov_F1_vreg(dp
, rm
);
3286 case 0x0a: case 0x0b: /* Compare with zero */
3287 gen_mov_F0_vreg(dp
, rd
);
3290 case 0x14: /* vcvt fp <-> fixed */
3298 /* Source and destination the same. */
3299 gen_mov_F0_vreg(dp
, rd
);
3302 /* One source operand. */
3303 gen_mov_F0_vreg(rm_is_dp
, rm
);
3307 /* Two source operands. */
3308 gen_mov_F0_vreg(dp
, rn
);
3309 gen_mov_F1_vreg(dp
, rm
);
3313 /* Perform the calculation. */
3315 case 0: /* VMLA: fd + (fn * fm) */
3316 /* Note that order of inputs to the add matters for NaNs */
3318 gen_mov_F0_vreg(dp
, rd
);
3321 case 1: /* VMLS: fd + -(fn * fm) */
3324 gen_mov_F0_vreg(dp
, rd
);
3327 case 2: /* VNMLS: -fd + (fn * fm) */
3328 /* Note that it isn't valid to replace (-A + B) with (B - A)
3329 * or similar plausible looking simplifications
3330 * because this will give wrong results for NaNs.
3333 gen_mov_F0_vreg(dp
, rd
);
3337 case 3: /* VNMLA: -fd + -(fn * fm) */
3340 gen_mov_F0_vreg(dp
, rd
);
3344 case 4: /* mul: fn * fm */
3347 case 5: /* nmul: -(fn * fm) */
3351 case 6: /* add: fn + fm */
3354 case 7: /* sub: fn - fm */
3357 case 8: /* div: fn / fm */
3360 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3361 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3362 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3363 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3364 /* These are fused multiply-add, and must be done as one
3365 * floating point operation with no rounding between the
3366 * multiplication and addition steps.
3367 * NB that doing the negations here as separate steps is
3368 * correct : an input NaN should come out with its sign bit
3369 * flipped if it is a negated-input.
3371 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3379 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3381 frd
= tcg_temp_new_i64();
3382 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3385 gen_helper_vfp_negd(frd
, frd
);
3387 fpst
= get_fpstatus_ptr(0);
3388 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3389 cpu_F1d
, frd
, fpst
);
3390 tcg_temp_free_ptr(fpst
);
3391 tcg_temp_free_i64(frd
);
3397 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3399 frd
= tcg_temp_new_i32();
3400 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3402 gen_helper_vfp_negs(frd
, frd
);
3404 fpst
= get_fpstatus_ptr(0);
3405 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3406 cpu_F1s
, frd
, fpst
);
3407 tcg_temp_free_ptr(fpst
);
3408 tcg_temp_free_i32(frd
);
3411 case 14: /* fconst */
3412 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3416 n
= (insn
<< 12) & 0x80000000;
3417 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3424 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3431 tcg_gen_movi_i32(cpu_F0s
, n
);
3434 case 15: /* extension space */
3448 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3450 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3451 TCGv_i32 ahp_mode
= get_ahp_flag();
3452 tmp
= gen_vfp_mrs();
3453 tcg_gen_ext16u_i32(tmp
, tmp
);
3455 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3458 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3461 tcg_temp_free_i32(ahp_mode
);
3462 tcg_temp_free_ptr(fpst
);
3463 tcg_temp_free_i32(tmp
);
3466 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3468 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3469 TCGv_i32 ahp
= get_ahp_flag();
3470 tmp
= gen_vfp_mrs();
3471 tcg_gen_shri_i32(tmp
, tmp
, 16);
3473 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3476 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3479 tcg_temp_free_i32(tmp
);
3480 tcg_temp_free_i32(ahp
);
3481 tcg_temp_free_ptr(fpst
);
3484 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3486 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3487 TCGv_i32 ahp
= get_ahp_flag();
3488 tmp
= tcg_temp_new_i32();
3491 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3494 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3497 tcg_temp_free_i32(ahp
);
3498 tcg_temp_free_ptr(fpst
);
3499 gen_mov_F0_vreg(0, rd
);
3500 tmp2
= gen_vfp_mrs();
3501 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3502 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3503 tcg_temp_free_i32(tmp2
);
3507 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3509 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3510 TCGv_i32 ahp
= get_ahp_flag();
3511 tmp
= tcg_temp_new_i32();
3513 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3516 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3519 tcg_temp_free_i32(ahp
);
3520 tcg_temp_free_ptr(fpst
);
3521 tcg_gen_shli_i32(tmp
, tmp
, 16);
3522 gen_mov_F0_vreg(0, rd
);
3523 tmp2
= gen_vfp_mrs();
3524 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3525 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3526 tcg_temp_free_i32(tmp2
);
3539 case 11: /* cmpez */
3543 case 12: /* vrintr */
3545 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3547 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3549 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3551 tcg_temp_free_ptr(fpst
);
3554 case 13: /* vrintz */
3556 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3558 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3559 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3561 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3563 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3565 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3566 tcg_temp_free_i32(tcg_rmode
);
3567 tcg_temp_free_ptr(fpst
);
3570 case 14: /* vrintx */
3572 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3574 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3576 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3578 tcg_temp_free_ptr(fpst
);
3581 case 15: /* single<->double conversion */
3583 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3585 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3588 case 16: /* fuito */
3589 gen_vfp_uito(dp
, 0);
3591 case 17: /* fsito */
3592 gen_vfp_sito(dp
, 0);
3594 case 19: /* vjcvt */
3595 gen_helper_vjcvt(cpu_F0s
, cpu_F0d
, cpu_env
);
3597 case 20: /* fshto */
3598 gen_vfp_shto(dp
, 16 - rm
, 0);
3600 case 21: /* fslto */
3601 gen_vfp_slto(dp
, 32 - rm
, 0);
3603 case 22: /* fuhto */
3604 gen_vfp_uhto(dp
, 16 - rm
, 0);
3606 case 23: /* fulto */
3607 gen_vfp_ulto(dp
, 32 - rm
, 0);
3609 case 24: /* ftoui */
3610 gen_vfp_toui(dp
, 0);
3612 case 25: /* ftouiz */
3613 gen_vfp_touiz(dp
, 0);
3615 case 26: /* ftosi */
3616 gen_vfp_tosi(dp
, 0);
3618 case 27: /* ftosiz */
3619 gen_vfp_tosiz(dp
, 0);
3621 case 28: /* ftosh */
3622 gen_vfp_tosh(dp
, 16 - rm
, 0);
3624 case 29: /* ftosl */
3625 gen_vfp_tosl(dp
, 32 - rm
, 0);
3627 case 30: /* ftouh */
3628 gen_vfp_touh(dp
, 16 - rm
, 0);
3630 case 31: /* ftoul */
3631 gen_vfp_toul(dp
, 32 - rm
, 0);
3633 default: /* undefined */
3634 g_assert_not_reached();
3637 default: /* undefined */
3641 /* Write back the result, if any. */
3643 gen_mov_vreg_F0(rd_is_dp
, rd
);
3646 /* break out of the loop if we have finished */
3651 if (op
== 15 && delta_m
== 0) {
3652 /* single source one-many */
3654 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3656 gen_mov_vreg_F0(dp
, rd
);
3660 /* Setup the next operands. */
3662 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3666 /* One source operand. */
3667 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3669 gen_mov_F0_vreg(dp
, rm
);
3671 /* Two source operands. */
3672 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3674 gen_mov_F0_vreg(dp
, rn
);
3676 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3678 gen_mov_F1_vreg(dp
, rm
);
3686 /* Already handled by decodetree */
3689 /* Should never happen. */
3695 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
3697 #ifndef CONFIG_USER_ONLY
3698 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
3699 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
3705 static void gen_goto_ptr(void)
3707 tcg_gen_lookup_and_goto_ptr();
3710 /* This will end the TB but doesn't guarantee we'll return to
3711 * cpu_loop_exec. Any live exit_requests will be processed as we
3712 * enter the next TB.
3714 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3716 if (use_goto_tb(s
, dest
)) {
3718 gen_set_pc_im(s
, dest
);
3719 tcg_gen_exit_tb(s
->base
.tb
, n
);
3721 gen_set_pc_im(s
, dest
);
3724 s
->base
.is_jmp
= DISAS_NORETURN
;
3727 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3729 if (unlikely(is_singlestepping(s
))) {
3730 /* An indirect jump so that we still trigger the debug exception. */
3735 gen_goto_tb(s
, 0, dest
);
3739 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3742 tcg_gen_sari_i32(t0
, t0
, 16);
3746 tcg_gen_sari_i32(t1
, t1
, 16);
3749 tcg_gen_mul_i32(t0
, t0
, t1
);
3752 /* Return the mask of PSR bits set by a MSR instruction. */
3753 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
3758 if (flags
& (1 << 0))
3760 if (flags
& (1 << 1))
3762 if (flags
& (1 << 2))
3764 if (flags
& (1 << 3))
3767 /* Mask out undefined bits. */
3768 mask
&= ~CPSR_RESERVED
;
3769 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
3772 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
3773 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3775 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
3776 mask
&= ~(CPSR_E
| CPSR_GE
);
3778 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
3781 /* Mask out execution state and reserved bits. */
3783 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
3785 /* Mask out privileged bits. */
3791 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3792 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3796 /* ??? This is also undefined in system mode. */
3800 tmp
= load_cpu_field(spsr
);
3801 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3802 tcg_gen_andi_i32(t0
, t0
, mask
);
3803 tcg_gen_or_i32(tmp
, tmp
, t0
);
3804 store_cpu_field(tmp
, spsr
);
3806 gen_set_cpsr(t0
, mask
);
3808 tcg_temp_free_i32(t0
);
3813 /* Returns nonzero if access to the PSR is not permitted. */
3814 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3817 tmp
= tcg_temp_new_i32();
3818 tcg_gen_movi_i32(tmp
, val
);
3819 return gen_set_psr(s
, mask
, spsr
, tmp
);
3822 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
3823 int *tgtmode
, int *regno
)
3825 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3826 * the target mode and register number, and identify the various
3827 * unpredictable cases.
3828 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3829 * + executed in user mode
3830 * + using R15 as the src/dest register
3831 * + accessing an unimplemented register
3832 * + accessing a register that's inaccessible at current PL/security state*
3833 * + accessing a register that you could access with a different insn
3834 * We choose to UNDEF in all these cases.
3835 * Since we don't know which of the various AArch32 modes we are in
3836 * we have to defer some checks to runtime.
3837 * Accesses to Monitor mode registers from Secure EL1 (which implies
3838 * that EL3 is AArch64) must trap to EL3.
3840 * If the access checks fail this function will emit code to take
3841 * an exception and return false. Otherwise it will return true,
3842 * and set *tgtmode and *regno appropriately.
3844 int exc_target
= default_exception_el(s
);
3846 /* These instructions are present only in ARMv8, or in ARMv7 with the
3847 * Virtualization Extensions.
3849 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
3850 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
3854 if (IS_USER(s
) || rn
== 15) {
3858 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3859 * of registers into (r, sysm).
3862 /* SPSRs for other modes */
3864 case 0xe: /* SPSR_fiq */
3865 *tgtmode
= ARM_CPU_MODE_FIQ
;
3867 case 0x10: /* SPSR_irq */
3868 *tgtmode
= ARM_CPU_MODE_IRQ
;
3870 case 0x12: /* SPSR_svc */
3871 *tgtmode
= ARM_CPU_MODE_SVC
;
3873 case 0x14: /* SPSR_abt */
3874 *tgtmode
= ARM_CPU_MODE_ABT
;
3876 case 0x16: /* SPSR_und */
3877 *tgtmode
= ARM_CPU_MODE_UND
;
3879 case 0x1c: /* SPSR_mon */
3880 *tgtmode
= ARM_CPU_MODE_MON
;
3882 case 0x1e: /* SPSR_hyp */
3883 *tgtmode
= ARM_CPU_MODE_HYP
;
3885 default: /* unallocated */
3888 /* We arbitrarily assign SPSR a register number of 16. */
3891 /* general purpose registers for other modes */
3893 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3894 *tgtmode
= ARM_CPU_MODE_USR
;
3897 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3898 *tgtmode
= ARM_CPU_MODE_FIQ
;
3901 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3902 *tgtmode
= ARM_CPU_MODE_IRQ
;
3903 *regno
= sysm
& 1 ? 13 : 14;
3905 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3906 *tgtmode
= ARM_CPU_MODE_SVC
;
3907 *regno
= sysm
& 1 ? 13 : 14;
3909 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3910 *tgtmode
= ARM_CPU_MODE_ABT
;
3911 *regno
= sysm
& 1 ? 13 : 14;
3913 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3914 *tgtmode
= ARM_CPU_MODE_UND
;
3915 *regno
= sysm
& 1 ? 13 : 14;
3917 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3918 *tgtmode
= ARM_CPU_MODE_MON
;
3919 *regno
= sysm
& 1 ? 13 : 14;
3921 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3922 *tgtmode
= ARM_CPU_MODE_HYP
;
3923 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3924 *regno
= sysm
& 1 ? 13 : 17;
3926 default: /* unallocated */
3931 /* Catch the 'accessing inaccessible register' cases we can detect
3932 * at translate time.
3935 case ARM_CPU_MODE_MON
:
3936 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
3939 if (s
->current_el
== 1) {
3940 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3941 * then accesses to Mon registers trap to EL3
3947 case ARM_CPU_MODE_HYP
:
3949 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3950 * (and so we can forbid accesses from EL2 or below). elr_hyp
3951 * can be accessed also from Hyp mode, so forbid accesses from
3954 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 2 ||
3955 (s
->current_el
< 3 && *regno
!= 17)) {
3966 /* If we get here then some access check did not pass */
3967 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
3971 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
3973 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
3974 int tgtmode
= 0, regno
= 0;
3976 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
3980 /* Sync state because msr_banked() can raise exceptions */
3981 gen_set_condexec(s
);
3982 gen_set_pc_im(s
, s
->pc
- 4);
3983 tcg_reg
= load_reg(s
, rn
);
3984 tcg_tgtmode
= tcg_const_i32(tgtmode
);
3985 tcg_regno
= tcg_const_i32(regno
);
3986 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
3987 tcg_temp_free_i32(tcg_tgtmode
);
3988 tcg_temp_free_i32(tcg_regno
);
3989 tcg_temp_free_i32(tcg_reg
);
3990 s
->base
.is_jmp
= DISAS_UPDATE
;
3993 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
3995 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
3996 int tgtmode
= 0, regno
= 0;
3998 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4002 /* Sync state because mrs_banked() can raise exceptions */
4003 gen_set_condexec(s
);
4004 gen_set_pc_im(s
, s
->pc
- 4);
4005 tcg_reg
= tcg_temp_new_i32();
4006 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4007 tcg_regno
= tcg_const_i32(regno
);
4008 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4009 tcg_temp_free_i32(tcg_tgtmode
);
4010 tcg_temp_free_i32(tcg_regno
);
4011 store_reg(s
, rn
, tcg_reg
);
4012 s
->base
.is_jmp
= DISAS_UPDATE
;
4015 /* Store value to PC as for an exception return (ie don't
4016 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4017 * will do the masking based on the new value of the Thumb bit.
4019 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4021 tcg_gen_mov_i32(cpu_R
[15], pc
);
4022 tcg_temp_free_i32(pc
);
4025 /* Generate a v6 exception return. Marks both values as dead. */
4026 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4028 store_pc_exc_ret(s
, pc
);
4029 /* The cpsr_write_eret helper will mask the low bits of PC
4030 * appropriately depending on the new Thumb bit, so it must
4031 * be called after storing the new PC.
4033 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
4036 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4037 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
4040 tcg_temp_free_i32(cpsr
);
4041 /* Must exit loop to check un-masked IRQs */
4042 s
->base
.is_jmp
= DISAS_EXIT
;
4045 /* Generate an old-style exception return. Marks pc as dead. */
4046 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4048 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4052 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4053 * only call the helper when running single threaded TCG code to ensure
4054 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4055 * just skip this instruction. Currently the SEV/SEVL instructions
4056 * which are *one* of many ways to wake the CPU from WFE are not
4057 * implemented so we can't sleep like WFI does.
4059 static void gen_nop_hint(DisasContext
*s
, int val
)
4062 /* When running in MTTCG we don't generate jumps to the yield and
4063 * WFE helpers as it won't affect the scheduling of other vCPUs.
4064 * If we wanted to more completely model WFE/SEV so we don't busy
4065 * spin unnecessarily we would need to do something more involved.
4068 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4069 gen_set_pc_im(s
, s
->pc
);
4070 s
->base
.is_jmp
= DISAS_YIELD
;
4074 gen_set_pc_im(s
, s
->pc
);
4075 s
->base
.is_jmp
= DISAS_WFI
;
4078 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4079 gen_set_pc_im(s
, s
->pc
);
4080 s
->base
.is_jmp
= DISAS_WFE
;
4085 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4091 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4093 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4096 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4097 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4098 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4103 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4106 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4107 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4108 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4113 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4114 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
4115 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
4116 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
4117 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
4119 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4120 switch ((size << 1) | u) { \
4122 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4125 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4128 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4131 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4134 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4137 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4139 default: return 1; \
4142 #define GEN_NEON_INTEGER_OP(name) do { \
4143 switch ((size << 1) | u) { \
4145 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4148 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4151 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4154 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4157 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4160 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4162 default: return 1; \
4165 static TCGv_i32
neon_load_scratch(int scratch
)
4167 TCGv_i32 tmp
= tcg_temp_new_i32();
4168 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4172 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4174 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4175 tcg_temp_free_i32(var
);
4178 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4182 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4184 gen_neon_dup_high16(tmp
);
4186 gen_neon_dup_low16(tmp
);
4189 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4194 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4198 if (!q
&& size
== 2) {
4201 pd
= vfp_reg_ptr(true, rd
);
4202 pm
= vfp_reg_ptr(true, rm
);
4206 gen_helper_neon_qunzip8(pd
, pm
);
4209 gen_helper_neon_qunzip16(pd
, pm
);
4212 gen_helper_neon_qunzip32(pd
, pm
);
4220 gen_helper_neon_unzip8(pd
, pm
);
4223 gen_helper_neon_unzip16(pd
, pm
);
4229 tcg_temp_free_ptr(pd
);
4230 tcg_temp_free_ptr(pm
);
4234 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4238 if (!q
&& size
== 2) {
4241 pd
= vfp_reg_ptr(true, rd
);
4242 pm
= vfp_reg_ptr(true, rm
);
4246 gen_helper_neon_qzip8(pd
, pm
);
4249 gen_helper_neon_qzip16(pd
, pm
);
4252 gen_helper_neon_qzip32(pd
, pm
);
4260 gen_helper_neon_zip8(pd
, pm
);
4263 gen_helper_neon_zip16(pd
, pm
);
4269 tcg_temp_free_ptr(pd
);
4270 tcg_temp_free_ptr(pm
);
4274 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4278 rd
= tcg_temp_new_i32();
4279 tmp
= tcg_temp_new_i32();
4281 tcg_gen_shli_i32(rd
, t0
, 8);
4282 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4283 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4284 tcg_gen_or_i32(rd
, rd
, tmp
);
4286 tcg_gen_shri_i32(t1
, t1
, 8);
4287 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4288 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4289 tcg_gen_or_i32(t1
, t1
, tmp
);
4290 tcg_gen_mov_i32(t0
, rd
);
4292 tcg_temp_free_i32(tmp
);
4293 tcg_temp_free_i32(rd
);
4296 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4300 rd
= tcg_temp_new_i32();
4301 tmp
= tcg_temp_new_i32();
4303 tcg_gen_shli_i32(rd
, t0
, 16);
4304 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4305 tcg_gen_or_i32(rd
, rd
, tmp
);
4306 tcg_gen_shri_i32(t1
, t1
, 16);
4307 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4308 tcg_gen_or_i32(t1
, t1
, tmp
);
4309 tcg_gen_mov_i32(t0
, rd
);
4311 tcg_temp_free_i32(tmp
);
4312 tcg_temp_free_i32(rd
);
4320 } const neon_ls_element_type
[11] = {
4334 /* Translate a NEON load/store element instruction. Return nonzero if the
4335 instruction is invalid. */
4336 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4356 /* FIXME: this access check should not take precedence over UNDEF
4357 * for invalid encodings; we will generate incorrect syndrome information
4358 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4360 if (s
->fp_excp_el
) {
4361 gen_exception_insn(s
, 4, EXCP_UDEF
,
4362 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
4366 if (!s
->vfp_enabled
)
4368 VFP_DREG_D(rd
, insn
);
4369 rn
= (insn
>> 16) & 0xf;
4371 load
= (insn
& (1 << 21)) != 0;
4372 endian
= s
->be_data
;
4373 mmu_idx
= get_mem_index(s
);
4374 if ((insn
& (1 << 23)) == 0) {
4375 /* Load store all elements. */
4376 op
= (insn
>> 8) & 0xf;
4377 size
= (insn
>> 6) & 3;
4380 /* Catch UNDEF cases for bad values of align field */
4383 if (((insn
>> 5) & 1) == 1) {
4388 if (((insn
>> 4) & 3) == 3) {
4395 nregs
= neon_ls_element_type
[op
].nregs
;
4396 interleave
= neon_ls_element_type
[op
].interleave
;
4397 spacing
= neon_ls_element_type
[op
].spacing
;
4398 if (size
== 3 && (interleave
| spacing
) != 1) {
4401 /* For our purposes, bytes are always little-endian. */
4405 /* Consecutive little-endian elements from a single register
4406 * can be promoted to a larger little-endian operation.
4408 if (interleave
== 1 && endian
== MO_LE
) {
4411 tmp64
= tcg_temp_new_i64();
4412 addr
= tcg_temp_new_i32();
4413 tmp2
= tcg_const_i32(1 << size
);
4414 load_reg_var(s
, addr
, rn
);
4415 for (reg
= 0; reg
< nregs
; reg
++) {
4416 for (n
= 0; n
< 8 >> size
; n
++) {
4418 for (xs
= 0; xs
< interleave
; xs
++) {
4419 int tt
= rd
+ reg
+ spacing
* xs
;
4422 gen_aa32_ld_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
4423 neon_store_element64(tt
, n
, size
, tmp64
);
4425 neon_load_element64(tmp64
, tt
, n
, size
);
4426 gen_aa32_st_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
4428 tcg_gen_add_i32(addr
, addr
, tmp2
);
4432 tcg_temp_free_i32(addr
);
4433 tcg_temp_free_i32(tmp2
);
4434 tcg_temp_free_i64(tmp64
);
4435 stride
= nregs
* interleave
* 8;
4437 size
= (insn
>> 10) & 3;
4439 /* Load single element to all lanes. */
4440 int a
= (insn
>> 4) & 1;
4444 size
= (insn
>> 6) & 3;
4445 nregs
= ((insn
>> 8) & 3) + 1;
4448 if (nregs
!= 4 || a
== 0) {
4451 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4454 if (nregs
== 1 && a
== 1 && size
== 0) {
4457 if (nregs
== 3 && a
== 1) {
4460 addr
= tcg_temp_new_i32();
4461 load_reg_var(s
, addr
, rn
);
4463 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
4464 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
4466 stride
= (insn
& (1 << 5)) ? 2 : 1;
4467 vec_size
= nregs
== 1 ? stride
* 8 : 8;
4469 tmp
= tcg_temp_new_i32();
4470 for (reg
= 0; reg
< nregs
; reg
++) {
4471 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
4473 if ((rd
& 1) && vec_size
== 16) {
4474 /* We cannot write 16 bytes at once because the
4475 * destination is unaligned.
4477 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
4479 tcg_gen_gvec_mov(0, neon_reg_offset(rd
+ 1, 0),
4480 neon_reg_offset(rd
, 0), 8, 8);
4482 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
4483 vec_size
, vec_size
, tmp
);
4485 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4488 tcg_temp_free_i32(tmp
);
4489 tcg_temp_free_i32(addr
);
4490 stride
= (1 << size
) * nregs
;
4492 /* Single element. */
4493 int idx
= (insn
>> 4) & 0xf;
4497 reg_idx
= (insn
>> 5) & 7;
4501 reg_idx
= (insn
>> 6) & 3;
4502 stride
= (insn
& (1 << 5)) ? 2 : 1;
4505 reg_idx
= (insn
>> 7) & 1;
4506 stride
= (insn
& (1 << 6)) ? 2 : 1;
4511 nregs
= ((insn
>> 8) & 3) + 1;
4512 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4515 if (((idx
& (1 << size
)) != 0) ||
4516 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4521 if ((idx
& 1) != 0) {
4526 if (size
== 2 && (idx
& 2) != 0) {
4531 if ((size
== 2) && ((idx
& 3) == 3)) {
4538 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4539 /* Attempts to write off the end of the register file
4540 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4541 * the neon_load_reg() would write off the end of the array.
4545 tmp
= tcg_temp_new_i32();
4546 addr
= tcg_temp_new_i32();
4547 load_reg_var(s
, addr
, rn
);
4548 for (reg
= 0; reg
< nregs
; reg
++) {
4550 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
4552 neon_store_element(rd
, reg_idx
, size
, tmp
);
4553 } else { /* Store */
4554 neon_load_element(tmp
, rd
, reg_idx
, size
);
4555 gen_aa32_st_i32(s
, tmp
, addr
, get_mem_index(s
),
4559 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4561 tcg_temp_free_i32(addr
);
4562 tcg_temp_free_i32(tmp
);
4563 stride
= nregs
* (1 << size
);
4569 base
= load_reg(s
, rn
);
4571 tcg_gen_addi_i32(base
, base
, stride
);
4574 index
= load_reg(s
, rm
);
4575 tcg_gen_add_i32(base
, base
, index
);
4576 tcg_temp_free_i32(index
);
4578 store_reg(s
, rn
, base
);
4583 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4586 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4587 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4588 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4593 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4596 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4597 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4598 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4603 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4606 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4607 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4608 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4613 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4616 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4617 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4618 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4623 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4629 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4630 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4635 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4636 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4643 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4644 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4649 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4650 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4657 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4661 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4662 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4663 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4668 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4669 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4670 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4674 tcg_temp_free_i32(src
);
4677 static inline void gen_neon_addl(int size
)
4680 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4681 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4682 case 2: tcg_gen_add_i64(CPU_V001
); break;
4687 static inline void gen_neon_subl(int size
)
4690 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4691 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4692 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4697 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4700 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4701 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4703 tcg_gen_neg_i64(var
, var
);
4709 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4712 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4713 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4718 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4723 switch ((size
<< 1) | u
) {
4724 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4725 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4726 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4727 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4729 tmp
= gen_muls_i64_i32(a
, b
);
4730 tcg_gen_mov_i64(dest
, tmp
);
4731 tcg_temp_free_i64(tmp
);
4734 tmp
= gen_mulu_i64_i32(a
, b
);
4735 tcg_gen_mov_i64(dest
, tmp
);
4736 tcg_temp_free_i64(tmp
);
4741 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4742 Don't forget to clean them now. */
4744 tcg_temp_free_i32(a
);
4745 tcg_temp_free_i32(b
);
4749 static void gen_neon_narrow_op(int op
, int u
, int size
,
4750 TCGv_i32 dest
, TCGv_i64 src
)
4754 gen_neon_unarrow_sats(size
, dest
, src
);
4756 gen_neon_narrow(size
, dest
, src
);
4760 gen_neon_narrow_satu(size
, dest
, src
);
4762 gen_neon_narrow_sats(size
, dest
, src
);
4767 /* Symbolic constants for op fields for Neon 3-register same-length.
4768 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4771 #define NEON_3R_VHADD 0
4772 #define NEON_3R_VQADD 1
4773 #define NEON_3R_VRHADD 2
4774 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4775 #define NEON_3R_VHSUB 4
4776 #define NEON_3R_VQSUB 5
4777 #define NEON_3R_VCGT 6
4778 #define NEON_3R_VCGE 7
4779 #define NEON_3R_VSHL 8
4780 #define NEON_3R_VQSHL 9
4781 #define NEON_3R_VRSHL 10
4782 #define NEON_3R_VQRSHL 11
4783 #define NEON_3R_VMAX 12
4784 #define NEON_3R_VMIN 13
4785 #define NEON_3R_VABD 14
4786 #define NEON_3R_VABA 15
4787 #define NEON_3R_VADD_VSUB 16
4788 #define NEON_3R_VTST_VCEQ 17
4789 #define NEON_3R_VML 18 /* VMLA, VMLS */
4790 #define NEON_3R_VMUL 19
4791 #define NEON_3R_VPMAX 20
4792 #define NEON_3R_VPMIN 21
4793 #define NEON_3R_VQDMULH_VQRDMULH 22
4794 #define NEON_3R_VPADD_VQRDMLAH 23
4795 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4796 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
4797 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4798 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4799 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4800 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4801 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4802 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4804 static const uint8_t neon_3r_sizes
[] = {
4805 [NEON_3R_VHADD
] = 0x7,
4806 [NEON_3R_VQADD
] = 0xf,
4807 [NEON_3R_VRHADD
] = 0x7,
4808 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4809 [NEON_3R_VHSUB
] = 0x7,
4810 [NEON_3R_VQSUB
] = 0xf,
4811 [NEON_3R_VCGT
] = 0x7,
4812 [NEON_3R_VCGE
] = 0x7,
4813 [NEON_3R_VSHL
] = 0xf,
4814 [NEON_3R_VQSHL
] = 0xf,
4815 [NEON_3R_VRSHL
] = 0xf,
4816 [NEON_3R_VQRSHL
] = 0xf,
4817 [NEON_3R_VMAX
] = 0x7,
4818 [NEON_3R_VMIN
] = 0x7,
4819 [NEON_3R_VABD
] = 0x7,
4820 [NEON_3R_VABA
] = 0x7,
4821 [NEON_3R_VADD_VSUB
] = 0xf,
4822 [NEON_3R_VTST_VCEQ
] = 0x7,
4823 [NEON_3R_VML
] = 0x7,
4824 [NEON_3R_VMUL
] = 0x7,
4825 [NEON_3R_VPMAX
] = 0x7,
4826 [NEON_3R_VPMIN
] = 0x7,
4827 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4828 [NEON_3R_VPADD_VQRDMLAH
] = 0x7,
4829 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4830 [NEON_3R_VFM_VQRDMLSH
] = 0x7, /* For VFM, size bit 1 encodes op */
4831 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4832 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4833 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4834 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4835 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4836 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4839 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4840 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4843 #define NEON_2RM_VREV64 0
4844 #define NEON_2RM_VREV32 1
4845 #define NEON_2RM_VREV16 2
4846 #define NEON_2RM_VPADDL 4
4847 #define NEON_2RM_VPADDL_U 5
4848 #define NEON_2RM_AESE 6 /* Includes AESD */
4849 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4850 #define NEON_2RM_VCLS 8
4851 #define NEON_2RM_VCLZ 9
4852 #define NEON_2RM_VCNT 10
4853 #define NEON_2RM_VMVN 11
4854 #define NEON_2RM_VPADAL 12
4855 #define NEON_2RM_VPADAL_U 13
4856 #define NEON_2RM_VQABS 14
4857 #define NEON_2RM_VQNEG 15
4858 #define NEON_2RM_VCGT0 16
4859 #define NEON_2RM_VCGE0 17
4860 #define NEON_2RM_VCEQ0 18
4861 #define NEON_2RM_VCLE0 19
4862 #define NEON_2RM_VCLT0 20
4863 #define NEON_2RM_SHA1H 21
4864 #define NEON_2RM_VABS 22
4865 #define NEON_2RM_VNEG 23
4866 #define NEON_2RM_VCGT0_F 24
4867 #define NEON_2RM_VCGE0_F 25
4868 #define NEON_2RM_VCEQ0_F 26
4869 #define NEON_2RM_VCLE0_F 27
4870 #define NEON_2RM_VCLT0_F 28
4871 #define NEON_2RM_VABS_F 30
4872 #define NEON_2RM_VNEG_F 31
4873 #define NEON_2RM_VSWP 32
4874 #define NEON_2RM_VTRN 33
4875 #define NEON_2RM_VUZP 34
4876 #define NEON_2RM_VZIP 35
4877 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4878 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4879 #define NEON_2RM_VSHLL 38
4880 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4881 #define NEON_2RM_VRINTN 40
4882 #define NEON_2RM_VRINTX 41
4883 #define NEON_2RM_VRINTA 42
4884 #define NEON_2RM_VRINTZ 43
4885 #define NEON_2RM_VCVT_F16_F32 44
4886 #define NEON_2RM_VRINTM 45
4887 #define NEON_2RM_VCVT_F32_F16 46
4888 #define NEON_2RM_VRINTP 47
4889 #define NEON_2RM_VCVTAU 48
4890 #define NEON_2RM_VCVTAS 49
4891 #define NEON_2RM_VCVTNU 50
4892 #define NEON_2RM_VCVTNS 51
4893 #define NEON_2RM_VCVTPU 52
4894 #define NEON_2RM_VCVTPS 53
4895 #define NEON_2RM_VCVTMU 54
4896 #define NEON_2RM_VCVTMS 55
4897 #define NEON_2RM_VRECPE 56
4898 #define NEON_2RM_VRSQRTE 57
4899 #define NEON_2RM_VRECPE_F 58
4900 #define NEON_2RM_VRSQRTE_F 59
4901 #define NEON_2RM_VCVT_FS 60
4902 #define NEON_2RM_VCVT_FU 61
4903 #define NEON_2RM_VCVT_SF 62
4904 #define NEON_2RM_VCVT_UF 63
4906 static int neon_2rm_is_float_op(int op
)
4908 /* Return true if this neon 2reg-misc op is float-to-float */
4909 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4910 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4911 op
== NEON_2RM_VRINTM
||
4912 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4913 op
>= NEON_2RM_VRECPE_F
);
4916 static bool neon_2rm_is_v8_op(int op
)
4918 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4920 case NEON_2RM_VRINTN
:
4921 case NEON_2RM_VRINTA
:
4922 case NEON_2RM_VRINTM
:
4923 case NEON_2RM_VRINTP
:
4924 case NEON_2RM_VRINTZ
:
4925 case NEON_2RM_VRINTX
:
4926 case NEON_2RM_VCVTAU
:
4927 case NEON_2RM_VCVTAS
:
4928 case NEON_2RM_VCVTNU
:
4929 case NEON_2RM_VCVTNS
:
4930 case NEON_2RM_VCVTPU
:
4931 case NEON_2RM_VCVTPS
:
4932 case NEON_2RM_VCVTMU
:
4933 case NEON_2RM_VCVTMS
:
4940 /* Each entry in this array has bit n set if the insn allows
4941 * size value n (otherwise it will UNDEF). Since unallocated
4942 * op values will have no bits set they always UNDEF.
4944 static const uint8_t neon_2rm_sizes
[] = {
4945 [NEON_2RM_VREV64
] = 0x7,
4946 [NEON_2RM_VREV32
] = 0x3,
4947 [NEON_2RM_VREV16
] = 0x1,
4948 [NEON_2RM_VPADDL
] = 0x7,
4949 [NEON_2RM_VPADDL_U
] = 0x7,
4950 [NEON_2RM_AESE
] = 0x1,
4951 [NEON_2RM_AESMC
] = 0x1,
4952 [NEON_2RM_VCLS
] = 0x7,
4953 [NEON_2RM_VCLZ
] = 0x7,
4954 [NEON_2RM_VCNT
] = 0x1,
4955 [NEON_2RM_VMVN
] = 0x1,
4956 [NEON_2RM_VPADAL
] = 0x7,
4957 [NEON_2RM_VPADAL_U
] = 0x7,
4958 [NEON_2RM_VQABS
] = 0x7,
4959 [NEON_2RM_VQNEG
] = 0x7,
4960 [NEON_2RM_VCGT0
] = 0x7,
4961 [NEON_2RM_VCGE0
] = 0x7,
4962 [NEON_2RM_VCEQ0
] = 0x7,
4963 [NEON_2RM_VCLE0
] = 0x7,
4964 [NEON_2RM_VCLT0
] = 0x7,
4965 [NEON_2RM_SHA1H
] = 0x4,
4966 [NEON_2RM_VABS
] = 0x7,
4967 [NEON_2RM_VNEG
] = 0x7,
4968 [NEON_2RM_VCGT0_F
] = 0x4,
4969 [NEON_2RM_VCGE0_F
] = 0x4,
4970 [NEON_2RM_VCEQ0_F
] = 0x4,
4971 [NEON_2RM_VCLE0_F
] = 0x4,
4972 [NEON_2RM_VCLT0_F
] = 0x4,
4973 [NEON_2RM_VABS_F
] = 0x4,
4974 [NEON_2RM_VNEG_F
] = 0x4,
4975 [NEON_2RM_VSWP
] = 0x1,
4976 [NEON_2RM_VTRN
] = 0x7,
4977 [NEON_2RM_VUZP
] = 0x7,
4978 [NEON_2RM_VZIP
] = 0x7,
4979 [NEON_2RM_VMOVN
] = 0x7,
4980 [NEON_2RM_VQMOVN
] = 0x7,
4981 [NEON_2RM_VSHLL
] = 0x7,
4982 [NEON_2RM_SHA1SU1
] = 0x4,
4983 [NEON_2RM_VRINTN
] = 0x4,
4984 [NEON_2RM_VRINTX
] = 0x4,
4985 [NEON_2RM_VRINTA
] = 0x4,
4986 [NEON_2RM_VRINTZ
] = 0x4,
4987 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4988 [NEON_2RM_VRINTM
] = 0x4,
4989 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4990 [NEON_2RM_VRINTP
] = 0x4,
4991 [NEON_2RM_VCVTAU
] = 0x4,
4992 [NEON_2RM_VCVTAS
] = 0x4,
4993 [NEON_2RM_VCVTNU
] = 0x4,
4994 [NEON_2RM_VCVTNS
] = 0x4,
4995 [NEON_2RM_VCVTPU
] = 0x4,
4996 [NEON_2RM_VCVTPS
] = 0x4,
4997 [NEON_2RM_VCVTMU
] = 0x4,
4998 [NEON_2RM_VCVTMS
] = 0x4,
4999 [NEON_2RM_VRECPE
] = 0x4,
5000 [NEON_2RM_VRSQRTE
] = 0x4,
5001 [NEON_2RM_VRECPE_F
] = 0x4,
5002 [NEON_2RM_VRSQRTE_F
] = 0x4,
5003 [NEON_2RM_VCVT_FS
] = 0x4,
5004 [NEON_2RM_VCVT_FU
] = 0x4,
5005 [NEON_2RM_VCVT_SF
] = 0x4,
5006 [NEON_2RM_VCVT_UF
] = 0x4,
5010 /* Expand v8.1 simd helper. */
5011 static int do_v81_helper(DisasContext
*s
, gen_helper_gvec_3_ptr
*fn
,
5012 int q
, int rd
, int rn
, int rm
)
5014 if (dc_isar_feature(aa32_rdm
, s
)) {
5015 int opr_sz
= (1 + q
) * 8;
5016 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
5017 vfp_reg_offset(1, rn
),
5018 vfp_reg_offset(1, rm
), cpu_env
,
5019 opr_sz
, opr_sz
, 0, fn
);
5025 static void gen_ssra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5027 tcg_gen_vec_sar8i_i64(a
, a
, shift
);
5028 tcg_gen_vec_add8_i64(d
, d
, a
);
5031 static void gen_ssra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5033 tcg_gen_vec_sar16i_i64(a
, a
, shift
);
5034 tcg_gen_vec_add16_i64(d
, d
, a
);
5037 static void gen_ssra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5039 tcg_gen_sari_i32(a
, a
, shift
);
5040 tcg_gen_add_i32(d
, d
, a
);
5043 static void gen_ssra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5045 tcg_gen_sari_i64(a
, a
, shift
);
5046 tcg_gen_add_i64(d
, d
, a
);
5049 static void gen_ssra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5051 tcg_gen_sari_vec(vece
, a
, a
, sh
);
5052 tcg_gen_add_vec(vece
, d
, d
, a
);
5055 static const TCGOpcode vecop_list_ssra
[] = {
5056 INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
5059 const GVecGen2i ssra_op
[4] = {
5060 { .fni8
= gen_ssra8_i64
,
5061 .fniv
= gen_ssra_vec
,
5063 .opt_opc
= vecop_list_ssra
,
5065 { .fni8
= gen_ssra16_i64
,
5066 .fniv
= gen_ssra_vec
,
5068 .opt_opc
= vecop_list_ssra
,
5070 { .fni4
= gen_ssra32_i32
,
5071 .fniv
= gen_ssra_vec
,
5073 .opt_opc
= vecop_list_ssra
,
5075 { .fni8
= gen_ssra64_i64
,
5076 .fniv
= gen_ssra_vec
,
5077 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5078 .opt_opc
= vecop_list_ssra
,
5083 static void gen_usra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5085 tcg_gen_vec_shr8i_i64(a
, a
, shift
);
5086 tcg_gen_vec_add8_i64(d
, d
, a
);
5089 static void gen_usra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5091 tcg_gen_vec_shr16i_i64(a
, a
, shift
);
5092 tcg_gen_vec_add16_i64(d
, d
, a
);
5095 static void gen_usra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5097 tcg_gen_shri_i32(a
, a
, shift
);
5098 tcg_gen_add_i32(d
, d
, a
);
5101 static void gen_usra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5103 tcg_gen_shri_i64(a
, a
, shift
);
5104 tcg_gen_add_i64(d
, d
, a
);
5107 static void gen_usra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5109 tcg_gen_shri_vec(vece
, a
, a
, sh
);
5110 tcg_gen_add_vec(vece
, d
, d
, a
);
5113 static const TCGOpcode vecop_list_usra
[] = {
5114 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
5117 const GVecGen2i usra_op
[4] = {
5118 { .fni8
= gen_usra8_i64
,
5119 .fniv
= gen_usra_vec
,
5121 .opt_opc
= vecop_list_usra
,
5123 { .fni8
= gen_usra16_i64
,
5124 .fniv
= gen_usra_vec
,
5126 .opt_opc
= vecop_list_usra
,
5128 { .fni4
= gen_usra32_i32
,
5129 .fniv
= gen_usra_vec
,
5131 .opt_opc
= vecop_list_usra
,
5133 { .fni8
= gen_usra64_i64
,
5134 .fniv
= gen_usra_vec
,
5135 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5137 .opt_opc
= vecop_list_usra
,
5141 static void gen_shr8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5143 uint64_t mask
= dup_const(MO_8
, 0xff >> shift
);
5144 TCGv_i64 t
= tcg_temp_new_i64();
5146 tcg_gen_shri_i64(t
, a
, shift
);
5147 tcg_gen_andi_i64(t
, t
, mask
);
5148 tcg_gen_andi_i64(d
, d
, ~mask
);
5149 tcg_gen_or_i64(d
, d
, t
);
5150 tcg_temp_free_i64(t
);
5153 static void gen_shr16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5155 uint64_t mask
= dup_const(MO_16
, 0xffff >> shift
);
5156 TCGv_i64 t
= tcg_temp_new_i64();
5158 tcg_gen_shri_i64(t
, a
, shift
);
5159 tcg_gen_andi_i64(t
, t
, mask
);
5160 tcg_gen_andi_i64(d
, d
, ~mask
);
5161 tcg_gen_or_i64(d
, d
, t
);
5162 tcg_temp_free_i64(t
);
5165 static void gen_shr32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5167 tcg_gen_shri_i32(a
, a
, shift
);
5168 tcg_gen_deposit_i32(d
, d
, a
, 0, 32 - shift
);
5171 static void gen_shr64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5173 tcg_gen_shri_i64(a
, a
, shift
);
5174 tcg_gen_deposit_i64(d
, d
, a
, 0, 64 - shift
);
5177 static void gen_shr_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5180 tcg_gen_mov_vec(d
, a
);
5182 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
5183 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
5185 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK((8 << vece
) - sh
, sh
));
5186 tcg_gen_shri_vec(vece
, t
, a
, sh
);
5187 tcg_gen_and_vec(vece
, d
, d
, m
);
5188 tcg_gen_or_vec(vece
, d
, d
, t
);
5190 tcg_temp_free_vec(t
);
5191 tcg_temp_free_vec(m
);
5195 static const TCGOpcode vecop_list_sri
[] = { INDEX_op_shri_vec
, 0 };
5197 const GVecGen2i sri_op
[4] = {
5198 { .fni8
= gen_shr8_ins_i64
,
5199 .fniv
= gen_shr_ins_vec
,
5201 .opt_opc
= vecop_list_sri
,
5203 { .fni8
= gen_shr16_ins_i64
,
5204 .fniv
= gen_shr_ins_vec
,
5206 .opt_opc
= vecop_list_sri
,
5208 { .fni4
= gen_shr32_ins_i32
,
5209 .fniv
= gen_shr_ins_vec
,
5211 .opt_opc
= vecop_list_sri
,
5213 { .fni8
= gen_shr64_ins_i64
,
5214 .fniv
= gen_shr_ins_vec
,
5215 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5217 .opt_opc
= vecop_list_sri
,
5221 static void gen_shl8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5223 uint64_t mask
= dup_const(MO_8
, 0xff << shift
);
5224 TCGv_i64 t
= tcg_temp_new_i64();
5226 tcg_gen_shli_i64(t
, a
, shift
);
5227 tcg_gen_andi_i64(t
, t
, mask
);
5228 tcg_gen_andi_i64(d
, d
, ~mask
);
5229 tcg_gen_or_i64(d
, d
, t
);
5230 tcg_temp_free_i64(t
);
5233 static void gen_shl16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5235 uint64_t mask
= dup_const(MO_16
, 0xffff << shift
);
5236 TCGv_i64 t
= tcg_temp_new_i64();
5238 tcg_gen_shli_i64(t
, a
, shift
);
5239 tcg_gen_andi_i64(t
, t
, mask
);
5240 tcg_gen_andi_i64(d
, d
, ~mask
);
5241 tcg_gen_or_i64(d
, d
, t
);
5242 tcg_temp_free_i64(t
);
5245 static void gen_shl32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5247 tcg_gen_deposit_i32(d
, d
, a
, shift
, 32 - shift
);
5250 static void gen_shl64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5252 tcg_gen_deposit_i64(d
, d
, a
, shift
, 64 - shift
);
5255 static void gen_shl_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5258 tcg_gen_mov_vec(d
, a
);
5260 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
5261 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
5263 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK(0, sh
));
5264 tcg_gen_shli_vec(vece
, t
, a
, sh
);
5265 tcg_gen_and_vec(vece
, d
, d
, m
);
5266 tcg_gen_or_vec(vece
, d
, d
, t
);
5268 tcg_temp_free_vec(t
);
5269 tcg_temp_free_vec(m
);
5273 static const TCGOpcode vecop_list_sli
[] = { INDEX_op_shli_vec
, 0 };
5275 const GVecGen2i sli_op
[4] = {
5276 { .fni8
= gen_shl8_ins_i64
,
5277 .fniv
= gen_shl_ins_vec
,
5279 .opt_opc
= vecop_list_sli
,
5281 { .fni8
= gen_shl16_ins_i64
,
5282 .fniv
= gen_shl_ins_vec
,
5284 .opt_opc
= vecop_list_sli
,
5286 { .fni4
= gen_shl32_ins_i32
,
5287 .fniv
= gen_shl_ins_vec
,
5289 .opt_opc
= vecop_list_sli
,
5291 { .fni8
= gen_shl64_ins_i64
,
5292 .fniv
= gen_shl_ins_vec
,
5293 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5295 .opt_opc
= vecop_list_sli
,
5299 static void gen_mla8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5301 gen_helper_neon_mul_u8(a
, a
, b
);
5302 gen_helper_neon_add_u8(d
, d
, a
);
5305 static void gen_mls8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5307 gen_helper_neon_mul_u8(a
, a
, b
);
5308 gen_helper_neon_sub_u8(d
, d
, a
);
5311 static void gen_mla16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5313 gen_helper_neon_mul_u16(a
, a
, b
);
5314 gen_helper_neon_add_u16(d
, d
, a
);
5317 static void gen_mls16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5319 gen_helper_neon_mul_u16(a
, a
, b
);
5320 gen_helper_neon_sub_u16(d
, d
, a
);
5323 static void gen_mla32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5325 tcg_gen_mul_i32(a
, a
, b
);
5326 tcg_gen_add_i32(d
, d
, a
);
5329 static void gen_mls32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5331 tcg_gen_mul_i32(a
, a
, b
);
5332 tcg_gen_sub_i32(d
, d
, a
);
5335 static void gen_mla64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5337 tcg_gen_mul_i64(a
, a
, b
);
5338 tcg_gen_add_i64(d
, d
, a
);
5341 static void gen_mls64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5343 tcg_gen_mul_i64(a
, a
, b
);
5344 tcg_gen_sub_i64(d
, d
, a
);
5347 static void gen_mla_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5349 tcg_gen_mul_vec(vece
, a
, a
, b
);
5350 tcg_gen_add_vec(vece
, d
, d
, a
);
5353 static void gen_mls_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5355 tcg_gen_mul_vec(vece
, a
, a
, b
);
5356 tcg_gen_sub_vec(vece
, d
, d
, a
);
5359 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
5360 * these tables are shared with AArch64 which does support them.
5363 static const TCGOpcode vecop_list_mla
[] = {
5364 INDEX_op_mul_vec
, INDEX_op_add_vec
, 0
5367 static const TCGOpcode vecop_list_mls
[] = {
5368 INDEX_op_mul_vec
, INDEX_op_sub_vec
, 0
5371 const GVecGen3 mla_op
[4] = {
5372 { .fni4
= gen_mla8_i32
,
5373 .fniv
= gen_mla_vec
,
5375 .opt_opc
= vecop_list_mla
,
5377 { .fni4
= gen_mla16_i32
,
5378 .fniv
= gen_mla_vec
,
5380 .opt_opc
= vecop_list_mla
,
5382 { .fni4
= gen_mla32_i32
,
5383 .fniv
= gen_mla_vec
,
5385 .opt_opc
= vecop_list_mla
,
5387 { .fni8
= gen_mla64_i64
,
5388 .fniv
= gen_mla_vec
,
5389 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5391 .opt_opc
= vecop_list_mla
,
5395 const GVecGen3 mls_op
[4] = {
5396 { .fni4
= gen_mls8_i32
,
5397 .fniv
= gen_mls_vec
,
5399 .opt_opc
= vecop_list_mls
,
5401 { .fni4
= gen_mls16_i32
,
5402 .fniv
= gen_mls_vec
,
5404 .opt_opc
= vecop_list_mls
,
5406 { .fni4
= gen_mls32_i32
,
5407 .fniv
= gen_mls_vec
,
5409 .opt_opc
= vecop_list_mls
,
5411 { .fni8
= gen_mls64_i64
,
5412 .fniv
= gen_mls_vec
,
5413 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5415 .opt_opc
= vecop_list_mls
,
5419 /* CMTST : test is "if (X & Y != 0)". */
5420 static void gen_cmtst_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5422 tcg_gen_and_i32(d
, a
, b
);
5423 tcg_gen_setcondi_i32(TCG_COND_NE
, d
, d
, 0);
5424 tcg_gen_neg_i32(d
, d
);
5427 void gen_cmtst_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5429 tcg_gen_and_i64(d
, a
, b
);
5430 tcg_gen_setcondi_i64(TCG_COND_NE
, d
, d
, 0);
5431 tcg_gen_neg_i64(d
, d
);
5434 static void gen_cmtst_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5436 tcg_gen_and_vec(vece
, d
, a
, b
);
5437 tcg_gen_dupi_vec(vece
, a
, 0);
5438 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, d
, d
, a
);
5441 static const TCGOpcode vecop_list_cmtst
[] = { INDEX_op_cmp_vec
, 0 };
5443 const GVecGen3 cmtst_op
[4] = {
5444 { .fni4
= gen_helper_neon_tst_u8
,
5445 .fniv
= gen_cmtst_vec
,
5446 .opt_opc
= vecop_list_cmtst
,
5448 { .fni4
= gen_helper_neon_tst_u16
,
5449 .fniv
= gen_cmtst_vec
,
5450 .opt_opc
= vecop_list_cmtst
,
5452 { .fni4
= gen_cmtst_i32
,
5453 .fniv
= gen_cmtst_vec
,
5454 .opt_opc
= vecop_list_cmtst
,
5456 { .fni8
= gen_cmtst_i64
,
5457 .fniv
= gen_cmtst_vec
,
5458 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5459 .opt_opc
= vecop_list_cmtst
,
5463 static void gen_uqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5464 TCGv_vec a
, TCGv_vec b
)
5466 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5467 tcg_gen_add_vec(vece
, x
, a
, b
);
5468 tcg_gen_usadd_vec(vece
, t
, a
, b
);
5469 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5470 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5471 tcg_temp_free_vec(x
);
5474 static const TCGOpcode vecop_list_uqadd
[] = {
5475 INDEX_op_usadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
5478 const GVecGen4 uqadd_op
[4] = {
5479 { .fniv
= gen_uqadd_vec
,
5480 .fno
= gen_helper_gvec_uqadd_b
,
5482 .opt_opc
= vecop_list_uqadd
,
5484 { .fniv
= gen_uqadd_vec
,
5485 .fno
= gen_helper_gvec_uqadd_h
,
5487 .opt_opc
= vecop_list_uqadd
,
5489 { .fniv
= gen_uqadd_vec
,
5490 .fno
= gen_helper_gvec_uqadd_s
,
5492 .opt_opc
= vecop_list_uqadd
,
5494 { .fniv
= gen_uqadd_vec
,
5495 .fno
= gen_helper_gvec_uqadd_d
,
5497 .opt_opc
= vecop_list_uqadd
,
5501 static void gen_sqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5502 TCGv_vec a
, TCGv_vec b
)
5504 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5505 tcg_gen_add_vec(vece
, x
, a
, b
);
5506 tcg_gen_ssadd_vec(vece
, t
, a
, b
);
5507 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5508 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5509 tcg_temp_free_vec(x
);
5512 static const TCGOpcode vecop_list_sqadd
[] = {
5513 INDEX_op_ssadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
5516 const GVecGen4 sqadd_op
[4] = {
5517 { .fniv
= gen_sqadd_vec
,
5518 .fno
= gen_helper_gvec_sqadd_b
,
5519 .opt_opc
= vecop_list_sqadd
,
5522 { .fniv
= gen_sqadd_vec
,
5523 .fno
= gen_helper_gvec_sqadd_h
,
5524 .opt_opc
= vecop_list_sqadd
,
5527 { .fniv
= gen_sqadd_vec
,
5528 .fno
= gen_helper_gvec_sqadd_s
,
5529 .opt_opc
= vecop_list_sqadd
,
5532 { .fniv
= gen_sqadd_vec
,
5533 .fno
= gen_helper_gvec_sqadd_d
,
5534 .opt_opc
= vecop_list_sqadd
,
5539 static void gen_uqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5540 TCGv_vec a
, TCGv_vec b
)
5542 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5543 tcg_gen_sub_vec(vece
, x
, a
, b
);
5544 tcg_gen_ussub_vec(vece
, t
, a
, b
);
5545 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5546 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5547 tcg_temp_free_vec(x
);
5550 static const TCGOpcode vecop_list_uqsub
[] = {
5551 INDEX_op_ussub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
5554 const GVecGen4 uqsub_op
[4] = {
5555 { .fniv
= gen_uqsub_vec
,
5556 .fno
= gen_helper_gvec_uqsub_b
,
5557 .opt_opc
= vecop_list_uqsub
,
5560 { .fniv
= gen_uqsub_vec
,
5561 .fno
= gen_helper_gvec_uqsub_h
,
5562 .opt_opc
= vecop_list_uqsub
,
5565 { .fniv
= gen_uqsub_vec
,
5566 .fno
= gen_helper_gvec_uqsub_s
,
5567 .opt_opc
= vecop_list_uqsub
,
5570 { .fniv
= gen_uqsub_vec
,
5571 .fno
= gen_helper_gvec_uqsub_d
,
5572 .opt_opc
= vecop_list_uqsub
,
5577 static void gen_sqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5578 TCGv_vec a
, TCGv_vec b
)
5580 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5581 tcg_gen_sub_vec(vece
, x
, a
, b
);
5582 tcg_gen_sssub_vec(vece
, t
, a
, b
);
5583 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5584 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5585 tcg_temp_free_vec(x
);
5588 static const TCGOpcode vecop_list_sqsub
[] = {
5589 INDEX_op_sssub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
5592 const GVecGen4 sqsub_op
[4] = {
5593 { .fniv
= gen_sqsub_vec
,
5594 .fno
= gen_helper_gvec_sqsub_b
,
5595 .opt_opc
= vecop_list_sqsub
,
5598 { .fniv
= gen_sqsub_vec
,
5599 .fno
= gen_helper_gvec_sqsub_h
,
5600 .opt_opc
= vecop_list_sqsub
,
5603 { .fniv
= gen_sqsub_vec
,
5604 .fno
= gen_helper_gvec_sqsub_s
,
5605 .opt_opc
= vecop_list_sqsub
,
5608 { .fniv
= gen_sqsub_vec
,
5609 .fno
= gen_helper_gvec_sqsub_d
,
5610 .opt_opc
= vecop_list_sqsub
,
5615 /* Translate a NEON data processing instruction. Return nonzero if the
5616 instruction is invalid.
5617 We process data in a mixture of 32-bit and 64-bit chunks.
5618 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5620 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5624 int rd
, rn
, rm
, rd_ofs
, rn_ofs
, rm_ofs
;
5633 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5634 TCGv_ptr ptr1
, ptr2
, ptr3
;
5637 /* FIXME: this access check should not take precedence over UNDEF
5638 * for invalid encodings; we will generate incorrect syndrome information
5639 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5641 if (s
->fp_excp_el
) {
5642 gen_exception_insn(s
, 4, EXCP_UDEF
,
5643 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
5647 if (!s
->vfp_enabled
)
5649 q
= (insn
& (1 << 6)) != 0;
5650 u
= (insn
>> 24) & 1;
5651 VFP_DREG_D(rd
, insn
);
5652 VFP_DREG_N(rn
, insn
);
5653 VFP_DREG_M(rm
, insn
);
5654 size
= (insn
>> 20) & 3;
5655 vec_size
= q
? 16 : 8;
5656 rd_ofs
= neon_reg_offset(rd
, 0);
5657 rn_ofs
= neon_reg_offset(rn
, 0);
5658 rm_ofs
= neon_reg_offset(rm
, 0);
5660 if ((insn
& (1 << 23)) == 0) {
5661 /* Three register same length. */
5662 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5663 /* Catch invalid op and bad size combinations: UNDEF */
5664 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5667 /* All insns of this form UNDEF for either this condition or the
5668 * superset of cases "Q==1"; we catch the latter later.
5670 if (q
&& ((rd
| rn
| rm
) & 1)) {
5675 /* The SHA-1/SHA-256 3-register instructions require special
5676 * treatment here, as their size field is overloaded as an
5677 * op type selector, and they all consume their input in a
5683 if (!u
) { /* SHA-1 */
5684 if (!dc_isar_feature(aa32_sha1
, s
)) {
5687 ptr1
= vfp_reg_ptr(true, rd
);
5688 ptr2
= vfp_reg_ptr(true, rn
);
5689 ptr3
= vfp_reg_ptr(true, rm
);
5690 tmp4
= tcg_const_i32(size
);
5691 gen_helper_crypto_sha1_3reg(ptr1
, ptr2
, ptr3
, tmp4
);
5692 tcg_temp_free_i32(tmp4
);
5693 } else { /* SHA-256 */
5694 if (!dc_isar_feature(aa32_sha2
, s
) || size
== 3) {
5697 ptr1
= vfp_reg_ptr(true, rd
);
5698 ptr2
= vfp_reg_ptr(true, rn
);
5699 ptr3
= vfp_reg_ptr(true, rm
);
5702 gen_helper_crypto_sha256h(ptr1
, ptr2
, ptr3
);
5705 gen_helper_crypto_sha256h2(ptr1
, ptr2
, ptr3
);
5708 gen_helper_crypto_sha256su1(ptr1
, ptr2
, ptr3
);
5712 tcg_temp_free_ptr(ptr1
);
5713 tcg_temp_free_ptr(ptr2
);
5714 tcg_temp_free_ptr(ptr3
);
5717 case NEON_3R_VPADD_VQRDMLAH
:
5724 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s16
,
5727 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s32
,
5732 case NEON_3R_VFM_VQRDMLSH
:
5743 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s16
,
5746 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s32
,
5751 case NEON_3R_LOGIC
: /* Logic ops. */
5752 switch ((u
<< 2) | size
) {
5754 tcg_gen_gvec_and(0, rd_ofs
, rn_ofs
, rm_ofs
,
5755 vec_size
, vec_size
);
5758 tcg_gen_gvec_andc(0, rd_ofs
, rn_ofs
, rm_ofs
,
5759 vec_size
, vec_size
);
5762 tcg_gen_gvec_or(0, rd_ofs
, rn_ofs
, rm_ofs
,
5763 vec_size
, vec_size
);
5766 tcg_gen_gvec_orc(0, rd_ofs
, rn_ofs
, rm_ofs
,
5767 vec_size
, vec_size
);
5770 tcg_gen_gvec_xor(0, rd_ofs
, rn_ofs
, rm_ofs
,
5771 vec_size
, vec_size
);
5774 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rd_ofs
, rn_ofs
, rm_ofs
,
5775 vec_size
, vec_size
);
5778 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rn_ofs
, rd_ofs
,
5779 vec_size
, vec_size
);
5782 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rd_ofs
, rn_ofs
,
5783 vec_size
, vec_size
);
5788 case NEON_3R_VADD_VSUB
:
5790 tcg_gen_gvec_sub(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5791 vec_size
, vec_size
);
5793 tcg_gen_gvec_add(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5794 vec_size
, vec_size
);
5799 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
5800 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5801 (u
? uqadd_op
: sqadd_op
) + size
);
5805 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
5806 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5807 (u
? uqsub_op
: sqsub_op
) + size
);
5810 case NEON_3R_VMUL
: /* VMUL */
5812 /* Polynomial case allows only P8 and is handled below. */
5817 tcg_gen_gvec_mul(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5818 vec_size
, vec_size
);
5823 case NEON_3R_VML
: /* VMLA, VMLS */
5824 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5825 u
? &mls_op
[size
] : &mla_op
[size
]);
5828 case NEON_3R_VTST_VCEQ
:
5830 tcg_gen_gvec_cmp(TCG_COND_EQ
, size
, rd_ofs
, rn_ofs
, rm_ofs
,
5831 vec_size
, vec_size
);
5833 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
,
5834 vec_size
, vec_size
, &cmtst_op
[size
]);
5839 tcg_gen_gvec_cmp(u
? TCG_COND_GTU
: TCG_COND_GT
, size
,
5840 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
5844 tcg_gen_gvec_cmp(u
? TCG_COND_GEU
: TCG_COND_GE
, size
,
5845 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
5850 tcg_gen_gvec_umax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5851 vec_size
, vec_size
);
5853 tcg_gen_gvec_smax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5854 vec_size
, vec_size
);
5859 tcg_gen_gvec_umin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5860 vec_size
, vec_size
);
5862 tcg_gen_gvec_smin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5863 vec_size
, vec_size
);
5869 /* 64-bit element instructions. */
5870 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5871 neon_load_reg64(cpu_V0
, rn
+ pass
);
5872 neon_load_reg64(cpu_V1
, rm
+ pass
);
5876 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5878 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5883 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5886 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5892 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5894 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5897 case NEON_3R_VQRSHL
:
5899 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5902 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5909 neon_store_reg64(cpu_V0
, rd
+ pass
);
5918 case NEON_3R_VQRSHL
:
5921 /* Shift instruction operands are reversed. */
5927 case NEON_3R_VPADD_VQRDMLAH
:
5932 case NEON_3R_FLOAT_ARITH
:
5933 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5935 case NEON_3R_FLOAT_MINMAX
:
5936 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5938 case NEON_3R_FLOAT_CMP
:
5940 /* no encoding for U=0 C=1x */
5944 case NEON_3R_FLOAT_ACMP
:
5949 case NEON_3R_FLOAT_MISC
:
5950 /* VMAXNM/VMINNM in ARMv8 */
5951 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5955 case NEON_3R_VFM_VQRDMLSH
:
5956 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
5964 if (pairwise
&& q
) {
5965 /* All the pairwise insns UNDEF if Q is set */
5969 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5974 tmp
= neon_load_reg(rn
, 0);
5975 tmp2
= neon_load_reg(rn
, 1);
5977 tmp
= neon_load_reg(rm
, 0);
5978 tmp2
= neon_load_reg(rm
, 1);
5982 tmp
= neon_load_reg(rn
, pass
);
5983 tmp2
= neon_load_reg(rm
, pass
);
5987 GEN_NEON_INTEGER_OP(hadd
);
5989 case NEON_3R_VRHADD
:
5990 GEN_NEON_INTEGER_OP(rhadd
);
5993 GEN_NEON_INTEGER_OP(hsub
);
5996 GEN_NEON_INTEGER_OP(shl
);
5999 GEN_NEON_INTEGER_OP_ENV(qshl
);
6002 GEN_NEON_INTEGER_OP(rshl
);
6004 case NEON_3R_VQRSHL
:
6005 GEN_NEON_INTEGER_OP_ENV(qrshl
);
6008 GEN_NEON_INTEGER_OP(abd
);
6011 GEN_NEON_INTEGER_OP(abd
);
6012 tcg_temp_free_i32(tmp2
);
6013 tmp2
= neon_load_reg(rd
, pass
);
6014 gen_neon_add(size
, tmp
, tmp2
);
6017 /* VMUL.P8; other cases already eliminated. */
6018 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
6021 GEN_NEON_INTEGER_OP(pmax
);
6024 GEN_NEON_INTEGER_OP(pmin
);
6026 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
6027 if (!u
) { /* VQDMULH */
6030 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6033 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6037 } else { /* VQRDMULH */
6040 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6043 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6049 case NEON_3R_VPADD_VQRDMLAH
:
6051 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
6052 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
6053 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
6057 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
6059 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6060 switch ((u
<< 2) | size
) {
6063 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6066 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
6069 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
6074 tcg_temp_free_ptr(fpstatus
);
6077 case NEON_3R_FLOAT_MULTIPLY
:
6079 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6080 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6082 tcg_temp_free_i32(tmp2
);
6083 tmp2
= neon_load_reg(rd
, pass
);
6085 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6087 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6090 tcg_temp_free_ptr(fpstatus
);
6093 case NEON_3R_FLOAT_CMP
:
6095 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6097 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6100 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6102 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6105 tcg_temp_free_ptr(fpstatus
);
6108 case NEON_3R_FLOAT_ACMP
:
6110 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6112 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6114 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6116 tcg_temp_free_ptr(fpstatus
);
6119 case NEON_3R_FLOAT_MINMAX
:
6121 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6123 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6125 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6127 tcg_temp_free_ptr(fpstatus
);
6130 case NEON_3R_FLOAT_MISC
:
6133 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6135 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6137 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6139 tcg_temp_free_ptr(fpstatus
);
6142 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6144 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6148 case NEON_3R_VFM_VQRDMLSH
:
6150 /* VFMA, VFMS: fused multiply-add */
6151 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6152 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6155 gen_helper_vfp_negs(tmp
, tmp
);
6157 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6158 tcg_temp_free_i32(tmp3
);
6159 tcg_temp_free_ptr(fpstatus
);
6165 tcg_temp_free_i32(tmp2
);
6167 /* Save the result. For elementwise operations we can put it
6168 straight into the destination register. For pairwise operations
6169 we have to be careful to avoid clobbering the source operands. */
6170 if (pairwise
&& rd
== rm
) {
6171 neon_store_scratch(pass
, tmp
);
6173 neon_store_reg(rd
, pass
, tmp
);
6177 if (pairwise
&& rd
== rm
) {
6178 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6179 tmp
= neon_load_scratch(pass
);
6180 neon_store_reg(rd
, pass
, tmp
);
6183 /* End of 3 register same size operations. */
6184 } else if (insn
& (1 << 4)) {
6185 if ((insn
& 0x00380080) != 0) {
6186 /* Two registers and shift. */
6187 op
= (insn
>> 8) & 0xf;
6188 if (insn
& (1 << 7)) {
6196 while ((insn
& (1 << (size
+ 19))) == 0)
6199 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6201 /* Shift by immediate:
6202 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6203 if (q
&& ((rd
| rm
) & 1)) {
6206 if (!u
&& (op
== 4 || op
== 6)) {
6209 /* Right shifts are encoded as N - shift, where N is the
6210 element size in bits. */
6212 shift
= shift
- (1 << (size
+ 3));
6217 /* Right shift comes here negative. */
6219 /* Shifts larger than the element size are architecturally
6220 * valid. Unsigned results in all zeros; signed results
6224 tcg_gen_gvec_sari(size
, rd_ofs
, rm_ofs
,
6225 MIN(shift
, (8 << size
) - 1),
6226 vec_size
, vec_size
);
6227 } else if (shift
>= 8 << size
) {
6228 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
6230 tcg_gen_gvec_shri(size
, rd_ofs
, rm_ofs
, shift
,
6231 vec_size
, vec_size
);
6236 /* Right shift comes here negative. */
6238 /* Shifts larger than the element size are architecturally
6239 * valid. Unsigned results in all zeros; signed results
6243 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6244 MIN(shift
, (8 << size
) - 1),
6246 } else if (shift
>= 8 << size
) {
6249 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6250 shift
, &usra_op
[size
]);
6258 /* Right shift comes here negative. */
6260 /* Shift out of range leaves destination unchanged. */
6261 if (shift
< 8 << size
) {
6262 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6263 shift
, &sri_op
[size
]);
6267 case 5: /* VSHL, VSLI */
6269 /* Shift out of range leaves destination unchanged. */
6270 if (shift
< 8 << size
) {
6271 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
,
6272 vec_size
, shift
, &sli_op
[size
]);
6275 /* Shifts larger than the element size are
6276 * architecturally valid and results in zero.
6278 if (shift
>= 8 << size
) {
6279 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
6281 tcg_gen_gvec_shli(size
, rd_ofs
, rm_ofs
, shift
,
6282 vec_size
, vec_size
);
6294 /* To avoid excessive duplication of ops we implement shift
6295 * by immediate using the variable shift operations.
6297 imm
= dup_const(size
, shift
);
6299 for (pass
= 0; pass
< count
; pass
++) {
6301 neon_load_reg64(cpu_V0
, rm
+ pass
);
6302 tcg_gen_movi_i64(cpu_V1
, imm
);
6307 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6309 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6311 case 6: /* VQSHLU */
6312 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6317 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6320 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6325 g_assert_not_reached();
6329 neon_load_reg64(cpu_V1
, rd
+ pass
);
6330 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6332 neon_store_reg64(cpu_V0
, rd
+ pass
);
6333 } else { /* size < 3 */
6334 /* Operands in T0 and T1. */
6335 tmp
= neon_load_reg(rm
, pass
);
6336 tmp2
= tcg_temp_new_i32();
6337 tcg_gen_movi_i32(tmp2
, imm
);
6341 GEN_NEON_INTEGER_OP(rshl
);
6343 case 6: /* VQSHLU */
6346 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6350 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6354 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6362 GEN_NEON_INTEGER_OP_ENV(qshl
);
6365 g_assert_not_reached();
6367 tcg_temp_free_i32(tmp2
);
6371 tmp2
= neon_load_reg(rd
, pass
);
6372 gen_neon_add(size
, tmp
, tmp2
);
6373 tcg_temp_free_i32(tmp2
);
6375 neon_store_reg(rd
, pass
, tmp
);
6378 } else if (op
< 10) {
6379 /* Shift by immediate and narrow:
6380 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6381 int input_unsigned
= (op
== 8) ? !u
: u
;
6385 shift
= shift
- (1 << (size
+ 3));
6388 tmp64
= tcg_const_i64(shift
);
6389 neon_load_reg64(cpu_V0
, rm
);
6390 neon_load_reg64(cpu_V1
, rm
+ 1);
6391 for (pass
= 0; pass
< 2; pass
++) {
6399 if (input_unsigned
) {
6400 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6402 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6405 if (input_unsigned
) {
6406 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6408 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6411 tmp
= tcg_temp_new_i32();
6412 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6413 neon_store_reg(rd
, pass
, tmp
);
6415 tcg_temp_free_i64(tmp64
);
6418 imm
= (uint16_t)shift
;
6422 imm
= (uint32_t)shift
;
6424 tmp2
= tcg_const_i32(imm
);
6425 tmp4
= neon_load_reg(rm
+ 1, 0);
6426 tmp5
= neon_load_reg(rm
+ 1, 1);
6427 for (pass
= 0; pass
< 2; pass
++) {
6429 tmp
= neon_load_reg(rm
, 0);
6433 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6436 tmp3
= neon_load_reg(rm
, 1);
6440 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6442 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6443 tcg_temp_free_i32(tmp
);
6444 tcg_temp_free_i32(tmp3
);
6445 tmp
= tcg_temp_new_i32();
6446 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6447 neon_store_reg(rd
, pass
, tmp
);
6449 tcg_temp_free_i32(tmp2
);
6451 } else if (op
== 10) {
6453 if (q
|| (rd
& 1)) {
6456 tmp
= neon_load_reg(rm
, 0);
6457 tmp2
= neon_load_reg(rm
, 1);
6458 for (pass
= 0; pass
< 2; pass
++) {
6462 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6465 /* The shift is less than the width of the source
6466 type, so we can just shift the whole register. */
6467 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6468 /* Widen the result of shift: we need to clear
6469 * the potential overflow bits resulting from
6470 * left bits of the narrow input appearing as
6471 * right bits of left the neighbour narrow
6473 if (size
< 2 || !u
) {
6476 imm
= (0xffu
>> (8 - shift
));
6478 } else if (size
== 1) {
6479 imm
= 0xffff >> (16 - shift
);
6482 imm
= 0xffffffff >> (32 - shift
);
6485 imm64
= imm
| (((uint64_t)imm
) << 32);
6489 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6492 neon_store_reg64(cpu_V0
, rd
+ pass
);
6494 } else if (op
>= 14) {
6495 /* VCVT fixed-point. */
6496 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6499 /* We have already masked out the must-be-1 top bit of imm6,
6500 * hence this 32-shift where the ARM ARM has 64-imm6.
6503 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6504 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6507 gen_vfp_ulto(0, shift
, 1);
6509 gen_vfp_slto(0, shift
, 1);
6512 gen_vfp_toul(0, shift
, 1);
6514 gen_vfp_tosl(0, shift
, 1);
6516 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6521 } else { /* (insn & 0x00380080) == 0 */
6522 int invert
, reg_ofs
, vec_size
;
6524 if (q
&& (rd
& 1)) {
6528 op
= (insn
>> 8) & 0xf;
6529 /* One register and immediate. */
6530 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6531 invert
= (insn
& (1 << 5)) != 0;
6532 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6533 * We choose to not special-case this and will behave as if a
6534 * valid constant encoding of 0 had been given.
6553 imm
= (imm
<< 8) | (imm
<< 24);
6556 imm
= (imm
<< 8) | 0xff;
6559 imm
= (imm
<< 16) | 0xffff;
6562 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6571 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6572 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6579 reg_ofs
= neon_reg_offset(rd
, 0);
6580 vec_size
= q
? 16 : 8;
6582 if (op
& 1 && op
< 12) {
6584 /* The immediate value has already been inverted,
6585 * so BIC becomes AND.
6587 tcg_gen_gvec_andi(MO_32
, reg_ofs
, reg_ofs
, imm
,
6588 vec_size
, vec_size
);
6590 tcg_gen_gvec_ori(MO_32
, reg_ofs
, reg_ofs
, imm
,
6591 vec_size
, vec_size
);
6595 if (op
== 14 && invert
) {
6596 TCGv_i64 t64
= tcg_temp_new_i64();
6598 for (pass
= 0; pass
<= q
; ++pass
) {
6602 for (n
= 0; n
< 8; n
++) {
6603 if (imm
& (1 << (n
+ pass
* 8))) {
6604 val
|= 0xffull
<< (n
* 8);
6607 tcg_gen_movi_i64(t64
, val
);
6608 neon_store_reg64(t64
, rd
+ pass
);
6610 tcg_temp_free_i64(t64
);
6612 tcg_gen_gvec_dup32i(reg_ofs
, vec_size
, vec_size
, imm
);
6616 } else { /* (insn & 0x00800010 == 0x00800000) */
6618 op
= (insn
>> 8) & 0xf;
6619 if ((insn
& (1 << 6)) == 0) {
6620 /* Three registers of different lengths. */
6624 /* undefreq: bit 0 : UNDEF if size == 0
6625 * bit 1 : UNDEF if size == 1
6626 * bit 2 : UNDEF if size == 2
6627 * bit 3 : UNDEF if U == 1
6628 * Note that [2:0] set implies 'always UNDEF'
6631 /* prewiden, src1_wide, src2_wide, undefreq */
6632 static const int neon_3reg_wide
[16][4] = {
6633 {1, 0, 0, 0}, /* VADDL */
6634 {1, 1, 0, 0}, /* VADDW */
6635 {1, 0, 0, 0}, /* VSUBL */
6636 {1, 1, 0, 0}, /* VSUBW */
6637 {0, 1, 1, 0}, /* VADDHN */
6638 {0, 0, 0, 0}, /* VABAL */
6639 {0, 1, 1, 0}, /* VSUBHN */
6640 {0, 0, 0, 0}, /* VABDL */
6641 {0, 0, 0, 0}, /* VMLAL */
6642 {0, 0, 0, 9}, /* VQDMLAL */
6643 {0, 0, 0, 0}, /* VMLSL */
6644 {0, 0, 0, 9}, /* VQDMLSL */
6645 {0, 0, 0, 0}, /* Integer VMULL */
6646 {0, 0, 0, 1}, /* VQDMULL */
6647 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6648 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6651 prewiden
= neon_3reg_wide
[op
][0];
6652 src1_wide
= neon_3reg_wide
[op
][1];
6653 src2_wide
= neon_3reg_wide
[op
][2];
6654 undefreq
= neon_3reg_wide
[op
][3];
6656 if ((undefreq
& (1 << size
)) ||
6657 ((undefreq
& 8) && u
)) {
6660 if ((src1_wide
&& (rn
& 1)) ||
6661 (src2_wide
&& (rm
& 1)) ||
6662 (!src2_wide
&& (rd
& 1))) {
6666 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6667 * outside the loop below as it only performs a single pass.
6669 if (op
== 14 && size
== 2) {
6670 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6672 if (!dc_isar_feature(aa32_pmull
, s
)) {
6675 tcg_rn
= tcg_temp_new_i64();
6676 tcg_rm
= tcg_temp_new_i64();
6677 tcg_rd
= tcg_temp_new_i64();
6678 neon_load_reg64(tcg_rn
, rn
);
6679 neon_load_reg64(tcg_rm
, rm
);
6680 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6681 neon_store_reg64(tcg_rd
, rd
);
6682 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6683 neon_store_reg64(tcg_rd
, rd
+ 1);
6684 tcg_temp_free_i64(tcg_rn
);
6685 tcg_temp_free_i64(tcg_rm
);
6686 tcg_temp_free_i64(tcg_rd
);
6690 /* Avoid overlapping operands. Wide source operands are
6691 always aligned so will never overlap with wide
6692 destinations in problematic ways. */
6693 if (rd
== rm
&& !src2_wide
) {
6694 tmp
= neon_load_reg(rm
, 1);
6695 neon_store_scratch(2, tmp
);
6696 } else if (rd
== rn
&& !src1_wide
) {
6697 tmp
= neon_load_reg(rn
, 1);
6698 neon_store_scratch(2, tmp
);
6701 for (pass
= 0; pass
< 2; pass
++) {
6703 neon_load_reg64(cpu_V0
, rn
+ pass
);
6706 if (pass
== 1 && rd
== rn
) {
6707 tmp
= neon_load_scratch(2);
6709 tmp
= neon_load_reg(rn
, pass
);
6712 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6716 neon_load_reg64(cpu_V1
, rm
+ pass
);
6719 if (pass
== 1 && rd
== rm
) {
6720 tmp2
= neon_load_scratch(2);
6722 tmp2
= neon_load_reg(rm
, pass
);
6725 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6729 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6730 gen_neon_addl(size
);
6732 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6733 gen_neon_subl(size
);
6735 case 5: case 7: /* VABAL, VABDL */
6736 switch ((size
<< 1) | u
) {
6738 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6741 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6744 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6747 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6750 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6753 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6757 tcg_temp_free_i32(tmp2
);
6758 tcg_temp_free_i32(tmp
);
6760 case 8: case 9: case 10: case 11: case 12: case 13:
6761 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6762 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6764 case 14: /* Polynomial VMULL */
6765 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6766 tcg_temp_free_i32(tmp2
);
6767 tcg_temp_free_i32(tmp
);
6769 default: /* 15 is RESERVED: caught earlier */
6774 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6775 neon_store_reg64(cpu_V0
, rd
+ pass
);
6776 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6778 neon_load_reg64(cpu_V1
, rd
+ pass
);
6780 case 10: /* VMLSL */
6781 gen_neon_negl(cpu_V0
, size
);
6783 case 5: case 8: /* VABAL, VMLAL */
6784 gen_neon_addl(size
);
6786 case 9: case 11: /* VQDMLAL, VQDMLSL */
6787 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6789 gen_neon_negl(cpu_V0
, size
);
6791 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6796 neon_store_reg64(cpu_V0
, rd
+ pass
);
6797 } else if (op
== 4 || op
== 6) {
6798 /* Narrowing operation. */
6799 tmp
= tcg_temp_new_i32();
6803 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6806 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6809 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6810 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6817 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6820 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6823 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6824 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6825 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6833 neon_store_reg(rd
, 0, tmp3
);
6834 neon_store_reg(rd
, 1, tmp
);
6837 /* Write back the result. */
6838 neon_store_reg64(cpu_V0
, rd
+ pass
);
6842 /* Two registers and a scalar. NB that for ops of this form
6843 * the ARM ARM labels bit 24 as Q, but it is in our variable
6850 case 1: /* Float VMLA scalar */
6851 case 5: /* Floating point VMLS scalar */
6852 case 9: /* Floating point VMUL scalar */
6857 case 0: /* Integer VMLA scalar */
6858 case 4: /* Integer VMLS scalar */
6859 case 8: /* Integer VMUL scalar */
6860 case 12: /* VQDMULH scalar */
6861 case 13: /* VQRDMULH scalar */
6862 if (u
&& ((rd
| rn
) & 1)) {
6865 tmp
= neon_get_scalar(size
, rm
);
6866 neon_store_scratch(0, tmp
);
6867 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6868 tmp
= neon_load_scratch(0);
6869 tmp2
= neon_load_reg(rn
, pass
);
6872 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6874 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6876 } else if (op
== 13) {
6878 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6880 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6882 } else if (op
& 1) {
6883 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6884 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6885 tcg_temp_free_ptr(fpstatus
);
6888 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6889 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6890 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6894 tcg_temp_free_i32(tmp2
);
6897 tmp2
= neon_load_reg(rd
, pass
);
6900 gen_neon_add(size
, tmp
, tmp2
);
6904 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6905 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6906 tcg_temp_free_ptr(fpstatus
);
6910 gen_neon_rsb(size
, tmp
, tmp2
);
6914 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6915 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6916 tcg_temp_free_ptr(fpstatus
);
6922 tcg_temp_free_i32(tmp2
);
6924 neon_store_reg(rd
, pass
, tmp
);
6927 case 3: /* VQDMLAL scalar */
6928 case 7: /* VQDMLSL scalar */
6929 case 11: /* VQDMULL scalar */
6934 case 2: /* VMLAL sclar */
6935 case 6: /* VMLSL scalar */
6936 case 10: /* VMULL scalar */
6940 tmp2
= neon_get_scalar(size
, rm
);
6941 /* We need a copy of tmp2 because gen_neon_mull
6942 * deletes it during pass 0. */
6943 tmp4
= tcg_temp_new_i32();
6944 tcg_gen_mov_i32(tmp4
, tmp2
);
6945 tmp3
= neon_load_reg(rn
, 1);
6947 for (pass
= 0; pass
< 2; pass
++) {
6949 tmp
= neon_load_reg(rn
, 0);
6954 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6956 neon_load_reg64(cpu_V1
, rd
+ pass
);
6960 gen_neon_negl(cpu_V0
, size
);
6963 gen_neon_addl(size
);
6966 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6968 gen_neon_negl(cpu_V0
, size
);
6970 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6976 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6981 neon_store_reg64(cpu_V0
, rd
+ pass
);
6984 case 14: /* VQRDMLAH scalar */
6985 case 15: /* VQRDMLSH scalar */
6987 NeonGenThreeOpEnvFn
*fn
;
6989 if (!dc_isar_feature(aa32_rdm
, s
)) {
6992 if (u
&& ((rd
| rn
) & 1)) {
6997 fn
= gen_helper_neon_qrdmlah_s16
;
6999 fn
= gen_helper_neon_qrdmlah_s32
;
7003 fn
= gen_helper_neon_qrdmlsh_s16
;
7005 fn
= gen_helper_neon_qrdmlsh_s32
;
7009 tmp2
= neon_get_scalar(size
, rm
);
7010 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
7011 tmp
= neon_load_reg(rn
, pass
);
7012 tmp3
= neon_load_reg(rd
, pass
);
7013 fn(tmp
, cpu_env
, tmp
, tmp2
, tmp3
);
7014 tcg_temp_free_i32(tmp3
);
7015 neon_store_reg(rd
, pass
, tmp
);
7017 tcg_temp_free_i32(tmp2
);
7021 g_assert_not_reached();
7024 } else { /* size == 3 */
7027 imm
= (insn
>> 8) & 0xf;
7032 if (q
&& ((rd
| rn
| rm
) & 1)) {
7037 neon_load_reg64(cpu_V0
, rn
);
7039 neon_load_reg64(cpu_V1
, rn
+ 1);
7041 } else if (imm
== 8) {
7042 neon_load_reg64(cpu_V0
, rn
+ 1);
7044 neon_load_reg64(cpu_V1
, rm
);
7047 tmp64
= tcg_temp_new_i64();
7049 neon_load_reg64(cpu_V0
, rn
);
7050 neon_load_reg64(tmp64
, rn
+ 1);
7052 neon_load_reg64(cpu_V0
, rn
+ 1);
7053 neon_load_reg64(tmp64
, rm
);
7055 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
7056 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
7057 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7059 neon_load_reg64(cpu_V1
, rm
);
7061 neon_load_reg64(cpu_V1
, rm
+ 1);
7064 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7065 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
7066 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
7067 tcg_temp_free_i64(tmp64
);
7070 neon_load_reg64(cpu_V0
, rn
);
7071 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
7072 neon_load_reg64(cpu_V1
, rm
);
7073 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7074 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7076 neon_store_reg64(cpu_V0
, rd
);
7078 neon_store_reg64(cpu_V1
, rd
+ 1);
7080 } else if ((insn
& (1 << 11)) == 0) {
7081 /* Two register misc. */
7082 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
7083 size
= (insn
>> 18) & 3;
7084 /* UNDEF for unknown op values and bad op-size combinations */
7085 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
7088 if (neon_2rm_is_v8_op(op
) &&
7089 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7092 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
7093 q
&& ((rm
| rd
) & 1)) {
7097 case NEON_2RM_VREV64
:
7098 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
7099 tmp
= neon_load_reg(rm
, pass
* 2);
7100 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
7102 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7103 case 1: gen_swap_half(tmp
); break;
7104 case 2: /* no-op */ break;
7107 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
7109 neon_store_reg(rd
, pass
* 2, tmp2
);
7112 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
7113 case 1: gen_swap_half(tmp2
); break;
7116 neon_store_reg(rd
, pass
* 2, tmp2
);
7120 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
7121 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
7122 for (pass
= 0; pass
< q
+ 1; pass
++) {
7123 tmp
= neon_load_reg(rm
, pass
* 2);
7124 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
7125 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
7126 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
7128 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
7129 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
7130 case 2: tcg_gen_add_i64(CPU_V001
); break;
7133 if (op
>= NEON_2RM_VPADAL
) {
7135 neon_load_reg64(cpu_V1
, rd
+ pass
);
7136 gen_neon_addl(size
);
7138 neon_store_reg64(cpu_V0
, rd
+ pass
);
7144 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7145 tmp
= neon_load_reg(rm
, n
);
7146 tmp2
= neon_load_reg(rd
, n
+ 1);
7147 neon_store_reg(rm
, n
, tmp2
);
7148 neon_store_reg(rd
, n
+ 1, tmp
);
7155 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7160 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7164 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7165 /* also VQMOVUN; op field and mnemonics don't line up */
7170 for (pass
= 0; pass
< 2; pass
++) {
7171 neon_load_reg64(cpu_V0
, rm
+ pass
);
7172 tmp
= tcg_temp_new_i32();
7173 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7178 neon_store_reg(rd
, 0, tmp2
);
7179 neon_store_reg(rd
, 1, tmp
);
7183 case NEON_2RM_VSHLL
:
7184 if (q
|| (rd
& 1)) {
7187 tmp
= neon_load_reg(rm
, 0);
7188 tmp2
= neon_load_reg(rm
, 1);
7189 for (pass
= 0; pass
< 2; pass
++) {
7192 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7193 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7194 neon_store_reg64(cpu_V0
, rd
+ pass
);
7197 case NEON_2RM_VCVT_F16_F32
:
7202 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
7206 tmp
= tcg_temp_new_i32();
7207 tmp2
= tcg_temp_new_i32();
7208 fpst
= get_fpstatus_ptr(true);
7209 ahp
= get_ahp_flag();
7210 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7211 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, fpst
, ahp
);
7212 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7213 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, cpu_F0s
, fpst
, ahp
);
7214 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7215 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7216 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7217 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, fpst
, ahp
);
7218 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7219 neon_store_reg(rd
, 0, tmp2
);
7220 tmp2
= tcg_temp_new_i32();
7221 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, cpu_F0s
, fpst
, ahp
);
7222 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7223 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7224 neon_store_reg(rd
, 1, tmp2
);
7225 tcg_temp_free_i32(tmp
);
7226 tcg_temp_free_i32(ahp
);
7227 tcg_temp_free_ptr(fpst
);
7230 case NEON_2RM_VCVT_F32_F16
:
7234 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
7238 fpst
= get_fpstatus_ptr(true);
7239 ahp
= get_ahp_flag();
7240 tmp3
= tcg_temp_new_i32();
7241 tmp
= neon_load_reg(rm
, 0);
7242 tmp2
= neon_load_reg(rm
, 1);
7243 tcg_gen_ext16u_i32(tmp3
, tmp
);
7244 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7245 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7246 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7247 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7248 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7249 tcg_temp_free_i32(tmp
);
7250 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7251 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7252 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7253 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7254 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7255 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7256 tcg_temp_free_i32(tmp2
);
7257 tcg_temp_free_i32(tmp3
);
7258 tcg_temp_free_i32(ahp
);
7259 tcg_temp_free_ptr(fpst
);
7262 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7263 if (!dc_isar_feature(aa32_aes
, s
) || ((rm
| rd
) & 1)) {
7266 ptr1
= vfp_reg_ptr(true, rd
);
7267 ptr2
= vfp_reg_ptr(true, rm
);
7269 /* Bit 6 is the lowest opcode bit; it distinguishes between
7270 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7272 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7274 if (op
== NEON_2RM_AESE
) {
7275 gen_helper_crypto_aese(ptr1
, ptr2
, tmp3
);
7277 gen_helper_crypto_aesmc(ptr1
, ptr2
, tmp3
);
7279 tcg_temp_free_ptr(ptr1
);
7280 tcg_temp_free_ptr(ptr2
);
7281 tcg_temp_free_i32(tmp3
);
7283 case NEON_2RM_SHA1H
:
7284 if (!dc_isar_feature(aa32_sha1
, s
) || ((rm
| rd
) & 1)) {
7287 ptr1
= vfp_reg_ptr(true, rd
);
7288 ptr2
= vfp_reg_ptr(true, rm
);
7290 gen_helper_crypto_sha1h(ptr1
, ptr2
);
7292 tcg_temp_free_ptr(ptr1
);
7293 tcg_temp_free_ptr(ptr2
);
7295 case NEON_2RM_SHA1SU1
:
7296 if ((rm
| rd
) & 1) {
7299 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7301 if (!dc_isar_feature(aa32_sha2
, s
)) {
7304 } else if (!dc_isar_feature(aa32_sha1
, s
)) {
7307 ptr1
= vfp_reg_ptr(true, rd
);
7308 ptr2
= vfp_reg_ptr(true, rm
);
7310 gen_helper_crypto_sha256su0(ptr1
, ptr2
);
7312 gen_helper_crypto_sha1su1(ptr1
, ptr2
);
7314 tcg_temp_free_ptr(ptr1
);
7315 tcg_temp_free_ptr(ptr2
);
7319 tcg_gen_gvec_not(0, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7322 tcg_gen_gvec_neg(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7325 tcg_gen_gvec_abs(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7330 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7331 if (neon_2rm_is_float_op(op
)) {
7332 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7333 neon_reg_offset(rm
, pass
));
7336 tmp
= neon_load_reg(rm
, pass
);
7339 case NEON_2RM_VREV32
:
7341 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7342 case 1: gen_swap_half(tmp
); break;
7346 case NEON_2RM_VREV16
:
7351 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7352 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7353 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7359 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7360 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7361 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7366 gen_helper_neon_cnt_u8(tmp
, tmp
);
7368 case NEON_2RM_VQABS
:
7371 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7374 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7377 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7382 case NEON_2RM_VQNEG
:
7385 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7388 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7391 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7396 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7397 tmp2
= tcg_const_i32(0);
7399 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7400 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7401 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7404 tcg_temp_free_i32(tmp2
);
7405 if (op
== NEON_2RM_VCLE0
) {
7406 tcg_gen_not_i32(tmp
, tmp
);
7409 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7410 tmp2
= tcg_const_i32(0);
7412 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7413 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7414 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7417 tcg_temp_free_i32(tmp2
);
7418 if (op
== NEON_2RM_VCLT0
) {
7419 tcg_gen_not_i32(tmp
, tmp
);
7422 case NEON_2RM_VCEQ0
:
7423 tmp2
= tcg_const_i32(0);
7425 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7426 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7427 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7430 tcg_temp_free_i32(tmp2
);
7432 case NEON_2RM_VCGT0_F
:
7434 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7435 tmp2
= tcg_const_i32(0);
7436 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7437 tcg_temp_free_i32(tmp2
);
7438 tcg_temp_free_ptr(fpstatus
);
7441 case NEON_2RM_VCGE0_F
:
7443 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7444 tmp2
= tcg_const_i32(0);
7445 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7446 tcg_temp_free_i32(tmp2
);
7447 tcg_temp_free_ptr(fpstatus
);
7450 case NEON_2RM_VCEQ0_F
:
7452 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7453 tmp2
= tcg_const_i32(0);
7454 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7455 tcg_temp_free_i32(tmp2
);
7456 tcg_temp_free_ptr(fpstatus
);
7459 case NEON_2RM_VCLE0_F
:
7461 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7462 tmp2
= tcg_const_i32(0);
7463 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7464 tcg_temp_free_i32(tmp2
);
7465 tcg_temp_free_ptr(fpstatus
);
7468 case NEON_2RM_VCLT0_F
:
7470 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7471 tmp2
= tcg_const_i32(0);
7472 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7473 tcg_temp_free_i32(tmp2
);
7474 tcg_temp_free_ptr(fpstatus
);
7477 case NEON_2RM_VABS_F
:
7480 case NEON_2RM_VNEG_F
:
7484 tmp2
= neon_load_reg(rd
, pass
);
7485 neon_store_reg(rm
, pass
, tmp2
);
7488 tmp2
= neon_load_reg(rd
, pass
);
7490 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7491 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7494 neon_store_reg(rm
, pass
, tmp2
);
7496 case NEON_2RM_VRINTN
:
7497 case NEON_2RM_VRINTA
:
7498 case NEON_2RM_VRINTM
:
7499 case NEON_2RM_VRINTP
:
7500 case NEON_2RM_VRINTZ
:
7503 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7506 if (op
== NEON_2RM_VRINTZ
) {
7507 rmode
= FPROUNDING_ZERO
;
7509 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7512 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7513 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7515 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7516 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7518 tcg_temp_free_ptr(fpstatus
);
7519 tcg_temp_free_i32(tcg_rmode
);
7522 case NEON_2RM_VRINTX
:
7524 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7525 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7526 tcg_temp_free_ptr(fpstatus
);
7529 case NEON_2RM_VCVTAU
:
7530 case NEON_2RM_VCVTAS
:
7531 case NEON_2RM_VCVTNU
:
7532 case NEON_2RM_VCVTNS
:
7533 case NEON_2RM_VCVTPU
:
7534 case NEON_2RM_VCVTPS
:
7535 case NEON_2RM_VCVTMU
:
7536 case NEON_2RM_VCVTMS
:
7538 bool is_signed
= !extract32(insn
, 7, 1);
7539 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7540 TCGv_i32 tcg_rmode
, tcg_shift
;
7541 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7543 tcg_shift
= tcg_const_i32(0);
7544 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7545 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7549 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7552 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7556 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7558 tcg_temp_free_i32(tcg_rmode
);
7559 tcg_temp_free_i32(tcg_shift
);
7560 tcg_temp_free_ptr(fpst
);
7563 case NEON_2RM_VRECPE
:
7565 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7566 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7567 tcg_temp_free_ptr(fpstatus
);
7570 case NEON_2RM_VRSQRTE
:
7572 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7573 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7574 tcg_temp_free_ptr(fpstatus
);
7577 case NEON_2RM_VRECPE_F
:
7579 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7580 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7581 tcg_temp_free_ptr(fpstatus
);
7584 case NEON_2RM_VRSQRTE_F
:
7586 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7587 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7588 tcg_temp_free_ptr(fpstatus
);
7591 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7594 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7597 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7598 gen_vfp_tosiz(0, 1);
7600 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7601 gen_vfp_touiz(0, 1);
7604 /* Reserved op values were caught by the
7605 * neon_2rm_sizes[] check earlier.
7609 if (neon_2rm_is_float_op(op
)) {
7610 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7611 neon_reg_offset(rd
, pass
));
7613 neon_store_reg(rd
, pass
, tmp
);
7618 } else if ((insn
& (1 << 10)) == 0) {
7620 int n
= ((insn
>> 8) & 3) + 1;
7621 if ((rn
+ n
) > 32) {
7622 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7623 * helper function running off the end of the register file.
7628 if (insn
& (1 << 6)) {
7629 tmp
= neon_load_reg(rd
, 0);
7631 tmp
= tcg_temp_new_i32();
7632 tcg_gen_movi_i32(tmp
, 0);
7634 tmp2
= neon_load_reg(rm
, 0);
7635 ptr1
= vfp_reg_ptr(true, rn
);
7636 tmp5
= tcg_const_i32(n
);
7637 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, ptr1
, tmp5
);
7638 tcg_temp_free_i32(tmp
);
7639 if (insn
& (1 << 6)) {
7640 tmp
= neon_load_reg(rd
, 1);
7642 tmp
= tcg_temp_new_i32();
7643 tcg_gen_movi_i32(tmp
, 0);
7645 tmp3
= neon_load_reg(rm
, 1);
7646 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, ptr1
, tmp5
);
7647 tcg_temp_free_i32(tmp5
);
7648 tcg_temp_free_ptr(ptr1
);
7649 neon_store_reg(rd
, 0, tmp2
);
7650 neon_store_reg(rd
, 1, tmp3
);
7651 tcg_temp_free_i32(tmp
);
7652 } else if ((insn
& 0x380) == 0) {
7657 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7660 if (insn
& (1 << 16)) {
7662 element
= (insn
>> 17) & 7;
7663 } else if (insn
& (1 << 17)) {
7665 element
= (insn
>> 18) & 3;
7668 element
= (insn
>> 19) & 1;
7670 tcg_gen_gvec_dup_mem(size
, neon_reg_offset(rd
, 0),
7671 neon_element_offset(rm
, element
, size
),
7672 q
? 16 : 8, q
? 16 : 8);
7681 /* Advanced SIMD three registers of the same length extension.
7682 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7683 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7684 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7685 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7687 static int disas_neon_insn_3same_ext(DisasContext
*s
, uint32_t insn
)
7689 gen_helper_gvec_3
*fn_gvec
= NULL
;
7690 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
7691 int rd
, rn
, rm
, opr_sz
;
7694 bool is_long
= false, q
= extract32(insn
, 6, 1);
7695 bool ptr_is_env
= false;
7697 if ((insn
& 0xfe200f10) == 0xfc200800) {
7698 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7699 int size
= extract32(insn
, 20, 1);
7700 data
= extract32(insn
, 23, 2); /* rot */
7701 if (!dc_isar_feature(aa32_vcma
, s
)
7702 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
7705 fn_gvec_ptr
= size
? gen_helper_gvec_fcmlas
: gen_helper_gvec_fcmlah
;
7706 } else if ((insn
& 0xfea00f10) == 0xfc800800) {
7707 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7708 int size
= extract32(insn
, 20, 1);
7709 data
= extract32(insn
, 24, 1); /* rot */
7710 if (!dc_isar_feature(aa32_vcma
, s
)
7711 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
7714 fn_gvec_ptr
= size
? gen_helper_gvec_fcadds
: gen_helper_gvec_fcaddh
;
7715 } else if ((insn
& 0xfeb00f00) == 0xfc200d00) {
7716 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
7717 bool u
= extract32(insn
, 4, 1);
7718 if (!dc_isar_feature(aa32_dp
, s
)) {
7721 fn_gvec
= u
? gen_helper_gvec_udot_b
: gen_helper_gvec_sdot_b
;
7722 } else if ((insn
& 0xff300f10) == 0xfc200810) {
7723 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
7724 int is_s
= extract32(insn
, 23, 1);
7725 if (!dc_isar_feature(aa32_fhm
, s
)) {
7729 data
= is_s
; /* is_2 == 0 */
7730 fn_gvec_ptr
= gen_helper_gvec_fmlal_a32
;
7736 VFP_DREG_D(rd
, insn
);
7740 if (q
|| !is_long
) {
7741 VFP_DREG_N(rn
, insn
);
7742 VFP_DREG_M(rm
, insn
);
7743 if ((rn
| rm
) & q
& !is_long
) {
7746 off_rn
= vfp_reg_offset(1, rn
);
7747 off_rm
= vfp_reg_offset(1, rm
);
7749 rn
= VFP_SREG_N(insn
);
7750 rm
= VFP_SREG_M(insn
);
7751 off_rn
= vfp_reg_offset(0, rn
);
7752 off_rm
= vfp_reg_offset(0, rm
);
7755 if (s
->fp_excp_el
) {
7756 gen_exception_insn(s
, 4, EXCP_UDEF
,
7757 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
7760 if (!s
->vfp_enabled
) {
7764 opr_sz
= (1 + q
) * 8;
7770 ptr
= get_fpstatus_ptr(1);
7772 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
7773 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
7775 tcg_temp_free_ptr(ptr
);
7778 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
7779 opr_sz
, opr_sz
, data
, fn_gvec
);
7784 /* Advanced SIMD two registers and a scalar extension.
7785 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7786 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7787 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7788 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7792 static int disas_neon_insn_2reg_scalar_ext(DisasContext
*s
, uint32_t insn
)
7794 gen_helper_gvec_3
*fn_gvec
= NULL
;
7795 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
7796 int rd
, rn
, rm
, opr_sz
, data
;
7798 bool is_long
= false, q
= extract32(insn
, 6, 1);
7799 bool ptr_is_env
= false;
7801 if ((insn
& 0xff000f10) == 0xfe000800) {
7802 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7803 int rot
= extract32(insn
, 20, 2);
7804 int size
= extract32(insn
, 23, 1);
7807 if (!dc_isar_feature(aa32_vcma
, s
)) {
7811 if (!dc_isar_feature(aa32_fp16_arith
, s
)) {
7814 /* For fp16, rm is just Vm, and index is M. */
7815 rm
= extract32(insn
, 0, 4);
7816 index
= extract32(insn
, 5, 1);
7818 /* For fp32, rm is the usual M:Vm, and index is 0. */
7819 VFP_DREG_M(rm
, insn
);
7822 data
= (index
<< 2) | rot
;
7823 fn_gvec_ptr
= (size
? gen_helper_gvec_fcmlas_idx
7824 : gen_helper_gvec_fcmlah_idx
);
7825 } else if ((insn
& 0xffb00f00) == 0xfe200d00) {
7826 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7827 int u
= extract32(insn
, 4, 1);
7829 if (!dc_isar_feature(aa32_dp
, s
)) {
7832 fn_gvec
= u
? gen_helper_gvec_udot_idx_b
: gen_helper_gvec_sdot_idx_b
;
7833 /* rm is just Vm, and index is M. */
7834 data
= extract32(insn
, 5, 1); /* index */
7835 rm
= extract32(insn
, 0, 4);
7836 } else if ((insn
& 0xffa00f10) == 0xfe000810) {
7837 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7838 int is_s
= extract32(insn
, 20, 1);
7839 int vm20
= extract32(insn
, 0, 3);
7840 int vm3
= extract32(insn
, 3, 1);
7841 int m
= extract32(insn
, 5, 1);
7844 if (!dc_isar_feature(aa32_fhm
, s
)) {
7849 index
= m
* 2 + vm3
;
7855 data
= (index
<< 2) | is_s
; /* is_2 == 0 */
7856 fn_gvec_ptr
= gen_helper_gvec_fmlal_idx_a32
;
7862 VFP_DREG_D(rd
, insn
);
7866 if (q
|| !is_long
) {
7867 VFP_DREG_N(rn
, insn
);
7868 if (rn
& q
& !is_long
) {
7871 off_rn
= vfp_reg_offset(1, rn
);
7872 off_rm
= vfp_reg_offset(1, rm
);
7874 rn
= VFP_SREG_N(insn
);
7875 off_rn
= vfp_reg_offset(0, rn
);
7876 off_rm
= vfp_reg_offset(0, rm
);
7878 if (s
->fp_excp_el
) {
7879 gen_exception_insn(s
, 4, EXCP_UDEF
,
7880 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
7883 if (!s
->vfp_enabled
) {
7887 opr_sz
= (1 + q
) * 8;
7893 ptr
= get_fpstatus_ptr(1);
7895 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
7896 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
7898 tcg_temp_free_ptr(ptr
);
7901 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
7902 opr_sz
, opr_sz
, data
, fn_gvec
);
7907 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7909 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7910 const ARMCPRegInfo
*ri
;
7912 cpnum
= (insn
>> 8) & 0xf;
7914 /* First check for coprocessor space used for XScale/iwMMXt insns */
7915 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7916 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7919 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7920 return disas_iwmmxt_insn(s
, insn
);
7921 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7922 return disas_dsp_insn(s
, insn
);
7927 /* Otherwise treat as a generic register access */
7928 is64
= (insn
& (1 << 25)) == 0;
7929 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7937 opc1
= (insn
>> 4) & 0xf;
7939 rt2
= (insn
>> 16) & 0xf;
7941 crn
= (insn
>> 16) & 0xf;
7942 opc1
= (insn
>> 21) & 7;
7943 opc2
= (insn
>> 5) & 7;
7946 isread
= (insn
>> 20) & 1;
7947 rt
= (insn
>> 12) & 0xf;
7949 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7950 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7952 /* Check access permissions */
7953 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7958 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7959 /* Emit code to perform further access permissions checks at
7960 * runtime; this may result in an exception.
7961 * Note that on XScale all cp0..c13 registers do an access check
7962 * call in order to handle c15_cpar.
7965 TCGv_i32 tcg_syn
, tcg_isread
;
7968 /* Note that since we are an implementation which takes an
7969 * exception on a trapped conditional instruction only if the
7970 * instruction passes its condition code check, we can take
7971 * advantage of the clause in the ARM ARM that allows us to set
7972 * the COND field in the instruction to 0xE in all cases.
7973 * We could fish the actual condition out of the insn (ARM)
7974 * or the condexec bits (Thumb) but it isn't necessary.
7979 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7982 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7988 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7991 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7996 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7997 * so this can only happen if this is an ARMv7 or earlier CPU,
7998 * in which case the syndrome information won't actually be
8001 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
8002 syndrome
= syn_uncategorized();
8006 gen_set_condexec(s
);
8007 gen_set_pc_im(s
, s
->pc
- 4);
8008 tmpptr
= tcg_const_ptr(ri
);
8009 tcg_syn
= tcg_const_i32(syndrome
);
8010 tcg_isread
= tcg_const_i32(isread
);
8011 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
8013 tcg_temp_free_ptr(tmpptr
);
8014 tcg_temp_free_i32(tcg_syn
);
8015 tcg_temp_free_i32(tcg_isread
);
8018 /* Handle special cases first */
8019 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
8026 gen_set_pc_im(s
, s
->pc
);
8027 s
->base
.is_jmp
= DISAS_WFI
;
8033 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
8042 if (ri
->type
& ARM_CP_CONST
) {
8043 tmp64
= tcg_const_i64(ri
->resetvalue
);
8044 } else if (ri
->readfn
) {
8046 tmp64
= tcg_temp_new_i64();
8047 tmpptr
= tcg_const_ptr(ri
);
8048 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
8049 tcg_temp_free_ptr(tmpptr
);
8051 tmp64
= tcg_temp_new_i64();
8052 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
8054 tmp
= tcg_temp_new_i32();
8055 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8056 store_reg(s
, rt
, tmp
);
8057 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8058 tmp
= tcg_temp_new_i32();
8059 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8060 tcg_temp_free_i64(tmp64
);
8061 store_reg(s
, rt2
, tmp
);
8064 if (ri
->type
& ARM_CP_CONST
) {
8065 tmp
= tcg_const_i32(ri
->resetvalue
);
8066 } else if (ri
->readfn
) {
8068 tmp
= tcg_temp_new_i32();
8069 tmpptr
= tcg_const_ptr(ri
);
8070 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
8071 tcg_temp_free_ptr(tmpptr
);
8073 tmp
= load_cpu_offset(ri
->fieldoffset
);
8076 /* Destination register of r15 for 32 bit loads sets
8077 * the condition codes from the high 4 bits of the value
8080 tcg_temp_free_i32(tmp
);
8082 store_reg(s
, rt
, tmp
);
8087 if (ri
->type
& ARM_CP_CONST
) {
8088 /* If not forbidden by access permissions, treat as WI */
8093 TCGv_i32 tmplo
, tmphi
;
8094 TCGv_i64 tmp64
= tcg_temp_new_i64();
8095 tmplo
= load_reg(s
, rt
);
8096 tmphi
= load_reg(s
, rt2
);
8097 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
8098 tcg_temp_free_i32(tmplo
);
8099 tcg_temp_free_i32(tmphi
);
8101 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
8102 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
8103 tcg_temp_free_ptr(tmpptr
);
8105 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
8107 tcg_temp_free_i64(tmp64
);
8112 tmp
= load_reg(s
, rt
);
8113 tmpptr
= tcg_const_ptr(ri
);
8114 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
8115 tcg_temp_free_ptr(tmpptr
);
8116 tcg_temp_free_i32(tmp
);
8118 TCGv_i32 tmp
= load_reg(s
, rt
);
8119 store_cpu_offset(tmp
, ri
->fieldoffset
);
8124 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
8125 /* I/O operations must end the TB here (whether read or write) */
8128 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
8129 /* We default to ending the TB on a coprocessor register write,
8130 * but allow this to be suppressed by the register definition
8131 * (usually only necessary to work around guest bugs).
8139 /* Unknown register; this might be a guest error or a QEMU
8140 * unimplemented feature.
8143 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8144 "64 bit system register cp:%d opc1: %d crm:%d "
8146 isread
? "read" : "write", cpnum
, opc1
, crm
,
8147 s
->ns
? "non-secure" : "secure");
8149 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8150 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8152 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
8153 s
->ns
? "non-secure" : "secure");
8160 /* Store a 64-bit value to a register pair. Clobbers val. */
8161 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
8164 tmp
= tcg_temp_new_i32();
8165 tcg_gen_extrl_i64_i32(tmp
, val
);
8166 store_reg(s
, rlow
, tmp
);
8167 tmp
= tcg_temp_new_i32();
8168 tcg_gen_shri_i64(val
, val
, 32);
8169 tcg_gen_extrl_i64_i32(tmp
, val
);
8170 store_reg(s
, rhigh
, tmp
);
8173 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8174 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
8179 /* Load value and extend to 64 bits. */
8180 tmp
= tcg_temp_new_i64();
8181 tmp2
= load_reg(s
, rlow
);
8182 tcg_gen_extu_i32_i64(tmp
, tmp2
);
8183 tcg_temp_free_i32(tmp2
);
8184 tcg_gen_add_i64(val
, val
, tmp
);
8185 tcg_temp_free_i64(tmp
);
8188 /* load and add a 64-bit value from a register pair. */
8189 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
8195 /* Load 64-bit value rd:rn. */
8196 tmpl
= load_reg(s
, rlow
);
8197 tmph
= load_reg(s
, rhigh
);
8198 tmp
= tcg_temp_new_i64();
8199 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
8200 tcg_temp_free_i32(tmpl
);
8201 tcg_temp_free_i32(tmph
);
8202 tcg_gen_add_i64(val
, val
, tmp
);
8203 tcg_temp_free_i64(tmp
);
8206 /* Set N and Z flags from hi|lo. */
8207 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
8209 tcg_gen_mov_i32(cpu_NF
, hi
);
8210 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
8213 /* Load/Store exclusive instructions are implemented by remembering
8214 the value/address loaded, and seeing if these are the same
8215 when the store is performed. This should be sufficient to implement
8216 the architecturally mandated semantics, and avoids having to monitor
8217 regular stores. The compare vs the remembered value is done during
8218 the cmpxchg operation, but we must compare the addresses manually. */
8219 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
8220 TCGv_i32 addr
, int size
)
8222 TCGv_i32 tmp
= tcg_temp_new_i32();
8223 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8228 TCGv_i32 tmp2
= tcg_temp_new_i32();
8229 TCGv_i64 t64
= tcg_temp_new_i64();
8231 /* For AArch32, architecturally the 32-bit word at the lowest
8232 * address is always Rt and the one at addr+4 is Rt2, even if
8233 * the CPU is big-endian. That means we don't want to do a
8234 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8235 * for an architecturally 64-bit access, but instead do a
8236 * 64-bit access using MO_BE if appropriate and then split
8238 * This only makes a difference for BE32 user-mode, where
8239 * frob64() must not flip the two halves of the 64-bit data
8240 * but this code must treat BE32 user-mode like BE32 system.
8242 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
8244 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
8245 tcg_temp_free(taddr
);
8246 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
8247 if (s
->be_data
== MO_BE
) {
8248 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
8250 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
8252 tcg_temp_free_i64(t64
);
8254 store_reg(s
, rt2
, tmp2
);
8256 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
8257 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
8260 store_reg(s
, rt
, tmp
);
8261 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
8264 static void gen_clrex(DisasContext
*s
)
8266 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8269 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
8270 TCGv_i32 addr
, int size
)
8272 TCGv_i32 t0
, t1
, t2
;
8275 TCGLabel
*done_label
;
8276 TCGLabel
*fail_label
;
8277 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8279 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8285 fail_label
= gen_new_label();
8286 done_label
= gen_new_label();
8287 extaddr
= tcg_temp_new_i64();
8288 tcg_gen_extu_i32_i64(extaddr
, addr
);
8289 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
8290 tcg_temp_free_i64(extaddr
);
8292 taddr
= gen_aa32_addr(s
, addr
, opc
);
8293 t0
= tcg_temp_new_i32();
8294 t1
= load_reg(s
, rt
);
8296 TCGv_i64 o64
= tcg_temp_new_i64();
8297 TCGv_i64 n64
= tcg_temp_new_i64();
8299 t2
= load_reg(s
, rt2
);
8300 /* For AArch32, architecturally the 32-bit word at the lowest
8301 * address is always Rt and the one at addr+4 is Rt2, even if
8302 * the CPU is big-endian. Since we're going to treat this as a
8303 * single 64-bit BE store, we need to put the two halves in the
8304 * opposite order for BE to LE, so that they end up in the right
8306 * We don't want gen_aa32_frob64() because that does the wrong
8307 * thing for BE32 usermode.
8309 if (s
->be_data
== MO_BE
) {
8310 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
8312 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
8314 tcg_temp_free_i32(t2
);
8316 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
8317 get_mem_index(s
), opc
);
8318 tcg_temp_free_i64(n64
);
8320 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
8321 tcg_gen_extrl_i64_i32(t0
, o64
);
8323 tcg_temp_free_i64(o64
);
8325 t2
= tcg_temp_new_i32();
8326 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
8327 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
8328 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
8329 tcg_temp_free_i32(t2
);
8331 tcg_temp_free_i32(t1
);
8332 tcg_temp_free(taddr
);
8333 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
8334 tcg_temp_free_i32(t0
);
8335 tcg_gen_br(done_label
);
8337 gen_set_label(fail_label
);
8338 tcg_gen_movi_i32(cpu_R
[rd
], 1);
8339 gen_set_label(done_label
);
8340 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8346 * @mode: mode field from insn (which stack to store to)
8347 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8348 * @writeback: true if writeback bit set
8350 * Generate code for the SRS (Store Return State) insn.
8352 static void gen_srs(DisasContext
*s
,
8353 uint32_t mode
, uint32_t amode
, bool writeback
)
8360 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8361 * and specified mode is monitor mode
8362 * - UNDEFINED in Hyp mode
8363 * - UNPREDICTABLE in User or System mode
8364 * - UNPREDICTABLE if the specified mode is:
8365 * -- not implemented
8366 * -- not a valid mode number
8367 * -- a mode that's at a higher exception level
8368 * -- Monitor, if we are Non-secure
8369 * For the UNPREDICTABLE cases we choose to UNDEF.
8371 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
8372 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
8376 if (s
->current_el
== 0 || s
->current_el
== 2) {
8381 case ARM_CPU_MODE_USR
:
8382 case ARM_CPU_MODE_FIQ
:
8383 case ARM_CPU_MODE_IRQ
:
8384 case ARM_CPU_MODE_SVC
:
8385 case ARM_CPU_MODE_ABT
:
8386 case ARM_CPU_MODE_UND
:
8387 case ARM_CPU_MODE_SYS
:
8389 case ARM_CPU_MODE_HYP
:
8390 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
8394 case ARM_CPU_MODE_MON
:
8395 /* No need to check specifically for "are we non-secure" because
8396 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8397 * so if this isn't EL3 then we must be non-secure.
8399 if (s
->current_el
!= 3) {
8408 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8409 default_exception_el(s
));
8413 addr
= tcg_temp_new_i32();
8414 tmp
= tcg_const_i32(mode
);
8415 /* get_r13_banked() will raise an exception if called from System mode */
8416 gen_set_condexec(s
);
8417 gen_set_pc_im(s
, s
->pc
- 4);
8418 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8419 tcg_temp_free_i32(tmp
);
8436 tcg_gen_addi_i32(addr
, addr
, offset
);
8437 tmp
= load_reg(s
, 14);
8438 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8439 tcg_temp_free_i32(tmp
);
8440 tmp
= load_cpu_field(spsr
);
8441 tcg_gen_addi_i32(addr
, addr
, 4);
8442 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8443 tcg_temp_free_i32(tmp
);
8461 tcg_gen_addi_i32(addr
, addr
, offset
);
8462 tmp
= tcg_const_i32(mode
);
8463 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8464 tcg_temp_free_i32(tmp
);
8466 tcg_temp_free_i32(addr
);
8467 s
->base
.is_jmp
= DISAS_UPDATE
;
8470 /* Generate a label used for skipping this instruction */
8471 static void arm_gen_condlabel(DisasContext
*s
)
8474 s
->condlabel
= gen_new_label();
8479 /* Skip this instruction if the ARM condition is false */
8480 static void arm_skip_unless(DisasContext
*s
, uint32_t cond
)
8482 arm_gen_condlabel(s
);
8483 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8486 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8488 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8495 /* M variants do not implement ARM mode; this must raise the INVSTATE
8496 * UsageFault exception.
8498 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8499 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8500 default_exception_el(s
));
8505 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8506 * choose to UNDEF. In ARMv5 and above the space is used
8507 * for miscellaneous unconditional instructions.
8511 /* Unconditional instructions. */
8512 if (((insn
>> 25) & 7) == 1) {
8513 /* NEON Data processing. */
8514 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8518 if (disas_neon_data_insn(s
, insn
)) {
8523 if ((insn
& 0x0f100000) == 0x04000000) {
8524 /* NEON load/store. */
8525 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8529 if (disas_neon_ls_insn(s
, insn
)) {
8534 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8536 if (disas_vfp_insn(s
, insn
)) {
8541 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8542 ((insn
& 0x0f30f010) == 0x0710f000)) {
8543 if ((insn
& (1 << 22)) == 0) {
8545 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8549 /* Otherwise PLD; v5TE+ */
8553 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8554 ((insn
& 0x0f70f010) == 0x0650f000)) {
8556 return; /* PLI; V7 */
8558 if (((insn
& 0x0f700000) == 0x04100000) ||
8559 ((insn
& 0x0f700010) == 0x06100000)) {
8560 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8563 return; /* v7MP: Unallocated memory hint: must NOP */
8566 if ((insn
& 0x0ffffdff) == 0x01010000) {
8569 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8570 gen_helper_setend(cpu_env
);
8571 s
->base
.is_jmp
= DISAS_UPDATE
;
8574 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8575 switch ((insn
>> 4) & 0xf) {
8583 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8586 /* We need to break the TB after this insn to execute
8587 * self-modifying code correctly and also to take
8588 * any pending interrupts immediately.
8590 gen_goto_tb(s
, 0, s
->pc
& ~1);
8593 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
8597 * TODO: There is no speculation barrier opcode
8598 * for TCG; MB and end the TB instead.
8600 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8601 gen_goto_tb(s
, 0, s
->pc
& ~1);
8606 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8609 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8611 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8617 rn
= (insn
>> 16) & 0xf;
8618 addr
= load_reg(s
, rn
);
8619 i
= (insn
>> 23) & 3;
8621 case 0: offset
= -4; break; /* DA */
8622 case 1: offset
= 0; break; /* IA */
8623 case 2: offset
= -8; break; /* DB */
8624 case 3: offset
= 4; break; /* IB */
8628 tcg_gen_addi_i32(addr
, addr
, offset
);
8629 /* Load PC into tmp and CPSR into tmp2. */
8630 tmp
= tcg_temp_new_i32();
8631 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8632 tcg_gen_addi_i32(addr
, addr
, 4);
8633 tmp2
= tcg_temp_new_i32();
8634 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8635 if (insn
& (1 << 21)) {
8636 /* Base writeback. */
8638 case 0: offset
= -8; break;
8639 case 1: offset
= 4; break;
8640 case 2: offset
= -4; break;
8641 case 3: offset
= 0; break;
8645 tcg_gen_addi_i32(addr
, addr
, offset
);
8646 store_reg(s
, rn
, addr
);
8648 tcg_temp_free_i32(addr
);
8650 gen_rfe(s
, tmp
, tmp2
);
8652 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8653 /* branch link and change to thumb (blx <offset>) */
8656 val
= (uint32_t)s
->pc
;
8657 tmp
= tcg_temp_new_i32();
8658 tcg_gen_movi_i32(tmp
, val
);
8659 store_reg(s
, 14, tmp
);
8660 /* Sign-extend the 24-bit offset */
8661 offset
= (((int32_t)insn
) << 8) >> 8;
8662 /* offset * 4 + bit24 * 2 + (thumb bit) */
8663 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8664 /* pipeline offset */
8666 /* protected by ARCH(5); above, near the start of uncond block */
8669 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8670 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8671 /* iWMMXt register transfer. */
8672 if (extract32(s
->c15_cpar
, 1, 1)) {
8673 if (!disas_iwmmxt_insn(s
, insn
)) {
8678 } else if ((insn
& 0x0e000a00) == 0x0c000800
8679 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8680 if (disas_neon_insn_3same_ext(s
, insn
)) {
8684 } else if ((insn
& 0x0f000a00) == 0x0e000800
8685 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8686 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
8690 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8691 /* Coprocessor double register transfer. */
8693 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8694 /* Additional coprocessor register transfer. */
8695 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8698 /* cps (privileged) */
8702 if (insn
& (1 << 19)) {
8703 if (insn
& (1 << 8))
8705 if (insn
& (1 << 7))
8707 if (insn
& (1 << 6))
8709 if (insn
& (1 << 18))
8712 if (insn
& (1 << 17)) {
8714 val
|= (insn
& 0x1f);
8717 gen_set_psr_im(s
, mask
, 0, val
);
8724 /* if not always execute, we generate a conditional jump to
8726 arm_skip_unless(s
, cond
);
8728 if ((insn
& 0x0f900000) == 0x03000000) {
8729 if ((insn
& (1 << 21)) == 0) {
8731 rd
= (insn
>> 12) & 0xf;
8732 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8733 if ((insn
& (1 << 22)) == 0) {
8735 tmp
= tcg_temp_new_i32();
8736 tcg_gen_movi_i32(tmp
, val
);
8739 tmp
= load_reg(s
, rd
);
8740 tcg_gen_ext16u_i32(tmp
, tmp
);
8741 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8743 store_reg(s
, rd
, tmp
);
8745 if (((insn
>> 12) & 0xf) != 0xf)
8747 if (((insn
>> 16) & 0xf) == 0) {
8748 gen_nop_hint(s
, insn
& 0xff);
8750 /* CPSR = immediate */
8752 shift
= ((insn
>> 8) & 0xf) * 2;
8754 val
= (val
>> shift
) | (val
<< (32 - shift
));
8755 i
= ((insn
& (1 << 22)) != 0);
8756 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8762 } else if ((insn
& 0x0f900000) == 0x01000000
8763 && (insn
& 0x00000090) != 0x00000090) {
8764 /* miscellaneous instructions */
8765 op1
= (insn
>> 21) & 3;
8766 sh
= (insn
>> 4) & 0xf;
8769 case 0x0: /* MSR, MRS */
8770 if (insn
& (1 << 9)) {
8771 /* MSR (banked) and MRS (banked) */
8772 int sysm
= extract32(insn
, 16, 4) |
8773 (extract32(insn
, 8, 1) << 4);
8774 int r
= extract32(insn
, 22, 1);
8778 gen_msr_banked(s
, r
, sysm
, rm
);
8781 int rd
= extract32(insn
, 12, 4);
8783 gen_mrs_banked(s
, r
, sysm
, rd
);
8788 /* MSR, MRS (for PSRs) */
8791 tmp
= load_reg(s
, rm
);
8792 i
= ((op1
& 2) != 0);
8793 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8797 rd
= (insn
>> 12) & 0xf;
8801 tmp
= load_cpu_field(spsr
);
8803 tmp
= tcg_temp_new_i32();
8804 gen_helper_cpsr_read(tmp
, cpu_env
);
8806 store_reg(s
, rd
, tmp
);
8811 /* branch/exchange thumb (bx). */
8813 tmp
= load_reg(s
, rm
);
8815 } else if (op1
== 3) {
8818 rd
= (insn
>> 12) & 0xf;
8819 tmp
= load_reg(s
, rm
);
8820 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8821 store_reg(s
, rd
, tmp
);
8829 /* Trivial implementation equivalent to bx. */
8830 tmp
= load_reg(s
, rm
);
8841 /* branch link/exchange thumb (blx) */
8842 tmp
= load_reg(s
, rm
);
8843 tmp2
= tcg_temp_new_i32();
8844 tcg_gen_movi_i32(tmp2
, s
->pc
);
8845 store_reg(s
, 14, tmp2
);
8851 uint32_t c
= extract32(insn
, 8, 4);
8853 /* Check this CPU supports ARMv8 CRC instructions.
8854 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8855 * Bits 8, 10 and 11 should be zero.
8857 if (!dc_isar_feature(aa32_crc32
, s
) || op1
== 0x3 || (c
& 0xd) != 0) {
8861 rn
= extract32(insn
, 16, 4);
8862 rd
= extract32(insn
, 12, 4);
8864 tmp
= load_reg(s
, rn
);
8865 tmp2
= load_reg(s
, rm
);
8867 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8868 } else if (op1
== 1) {
8869 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8871 tmp3
= tcg_const_i32(1 << op1
);
8873 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8875 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8877 tcg_temp_free_i32(tmp2
);
8878 tcg_temp_free_i32(tmp3
);
8879 store_reg(s
, rd
, tmp
);
8882 case 0x5: /* saturating add/subtract */
8884 rd
= (insn
>> 12) & 0xf;
8885 rn
= (insn
>> 16) & 0xf;
8886 tmp
= load_reg(s
, rm
);
8887 tmp2
= load_reg(s
, rn
);
8889 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8891 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8893 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8894 tcg_temp_free_i32(tmp2
);
8895 store_reg(s
, rd
, tmp
);
8897 case 0x6: /* ERET */
8901 if (!arm_dc_feature(s
, ARM_FEATURE_V7VE
)) {
8904 if ((insn
& 0x000fff0f) != 0x0000000e) {
8905 /* UNPREDICTABLE; we choose to UNDEF */
8909 if (s
->current_el
== 2) {
8910 tmp
= load_cpu_field(elr_el
[2]);
8912 tmp
= load_reg(s
, 14);
8914 gen_exception_return(s
, tmp
);
8918 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8927 gen_exception_bkpt_insn(s
, 4, syn_aa32_bkpt(imm16
, false));
8930 /* Hypervisor call (v7) */
8938 /* Secure monitor call (v6+) */
8946 g_assert_not_reached();
8950 case 0x8: /* signed multiply */
8955 rs
= (insn
>> 8) & 0xf;
8956 rn
= (insn
>> 12) & 0xf;
8957 rd
= (insn
>> 16) & 0xf;
8959 /* (32 * 16) >> 16 */
8960 tmp
= load_reg(s
, rm
);
8961 tmp2
= load_reg(s
, rs
);
8963 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8966 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8967 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8968 tmp
= tcg_temp_new_i32();
8969 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8970 tcg_temp_free_i64(tmp64
);
8971 if ((sh
& 2) == 0) {
8972 tmp2
= load_reg(s
, rn
);
8973 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8974 tcg_temp_free_i32(tmp2
);
8976 store_reg(s
, rd
, tmp
);
8979 tmp
= load_reg(s
, rm
);
8980 tmp2
= load_reg(s
, rs
);
8981 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8982 tcg_temp_free_i32(tmp2
);
8984 tmp64
= tcg_temp_new_i64();
8985 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8986 tcg_temp_free_i32(tmp
);
8987 gen_addq(s
, tmp64
, rn
, rd
);
8988 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8989 tcg_temp_free_i64(tmp64
);
8992 tmp2
= load_reg(s
, rn
);
8993 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8994 tcg_temp_free_i32(tmp2
);
8996 store_reg(s
, rd
, tmp
);
9003 } else if (((insn
& 0x0e000000) == 0 &&
9004 (insn
& 0x00000090) != 0x90) ||
9005 ((insn
& 0x0e000000) == (1 << 25))) {
9006 int set_cc
, logic_cc
, shiftop
;
9008 op1
= (insn
>> 21) & 0xf;
9009 set_cc
= (insn
>> 20) & 1;
9010 logic_cc
= table_logic_cc
[op1
] & set_cc
;
9012 /* data processing instruction */
9013 if (insn
& (1 << 25)) {
9014 /* immediate operand */
9016 shift
= ((insn
>> 8) & 0xf) * 2;
9018 val
= (val
>> shift
) | (val
<< (32 - shift
));
9020 tmp2
= tcg_temp_new_i32();
9021 tcg_gen_movi_i32(tmp2
, val
);
9022 if (logic_cc
&& shift
) {
9023 gen_set_CF_bit31(tmp2
);
9028 tmp2
= load_reg(s
, rm
);
9029 shiftop
= (insn
>> 5) & 3;
9030 if (!(insn
& (1 << 4))) {
9031 shift
= (insn
>> 7) & 0x1f;
9032 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9034 rs
= (insn
>> 8) & 0xf;
9035 tmp
= load_reg(s
, rs
);
9036 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
9039 if (op1
!= 0x0f && op1
!= 0x0d) {
9040 rn
= (insn
>> 16) & 0xf;
9041 tmp
= load_reg(s
, rn
);
9045 rd
= (insn
>> 12) & 0xf;
9048 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9052 store_reg_bx(s
, rd
, tmp
);
9055 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9059 store_reg_bx(s
, rd
, tmp
);
9062 if (set_cc
&& rd
== 15) {
9063 /* SUBS r15, ... is used for exception return. */
9067 gen_sub_CC(tmp
, tmp
, tmp2
);
9068 gen_exception_return(s
, tmp
);
9071 gen_sub_CC(tmp
, tmp
, tmp2
);
9073 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9075 store_reg_bx(s
, rd
, tmp
);
9080 gen_sub_CC(tmp
, tmp2
, tmp
);
9082 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9084 store_reg_bx(s
, rd
, tmp
);
9088 gen_add_CC(tmp
, tmp
, tmp2
);
9090 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9092 store_reg_bx(s
, rd
, tmp
);
9096 gen_adc_CC(tmp
, tmp
, tmp2
);
9098 gen_add_carry(tmp
, tmp
, tmp2
);
9100 store_reg_bx(s
, rd
, tmp
);
9104 gen_sbc_CC(tmp
, tmp
, tmp2
);
9106 gen_sub_carry(tmp
, tmp
, tmp2
);
9108 store_reg_bx(s
, rd
, tmp
);
9112 gen_sbc_CC(tmp
, tmp2
, tmp
);
9114 gen_sub_carry(tmp
, tmp2
, tmp
);
9116 store_reg_bx(s
, rd
, tmp
);
9120 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9123 tcg_temp_free_i32(tmp
);
9127 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9130 tcg_temp_free_i32(tmp
);
9134 gen_sub_CC(tmp
, tmp
, tmp2
);
9136 tcg_temp_free_i32(tmp
);
9140 gen_add_CC(tmp
, tmp
, tmp2
);
9142 tcg_temp_free_i32(tmp
);
9145 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9149 store_reg_bx(s
, rd
, tmp
);
9152 if (logic_cc
&& rd
== 15) {
9153 /* MOVS r15, ... is used for exception return. */
9157 gen_exception_return(s
, tmp2
);
9162 store_reg_bx(s
, rd
, tmp2
);
9166 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9170 store_reg_bx(s
, rd
, tmp
);
9174 tcg_gen_not_i32(tmp2
, tmp2
);
9178 store_reg_bx(s
, rd
, tmp2
);
9181 if (op1
!= 0x0f && op1
!= 0x0d) {
9182 tcg_temp_free_i32(tmp2
);
9185 /* other instructions */
9186 op1
= (insn
>> 24) & 0xf;
9190 /* multiplies, extra load/stores */
9191 sh
= (insn
>> 5) & 3;
9194 rd
= (insn
>> 16) & 0xf;
9195 rn
= (insn
>> 12) & 0xf;
9196 rs
= (insn
>> 8) & 0xf;
9198 op1
= (insn
>> 20) & 0xf;
9200 case 0: case 1: case 2: case 3: case 6:
9202 tmp
= load_reg(s
, rs
);
9203 tmp2
= load_reg(s
, rm
);
9204 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9205 tcg_temp_free_i32(tmp2
);
9206 if (insn
& (1 << 22)) {
9207 /* Subtract (mls) */
9209 tmp2
= load_reg(s
, rn
);
9210 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9211 tcg_temp_free_i32(tmp2
);
9212 } else if (insn
& (1 << 21)) {
9214 tmp2
= load_reg(s
, rn
);
9215 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9216 tcg_temp_free_i32(tmp2
);
9218 if (insn
& (1 << 20))
9220 store_reg(s
, rd
, tmp
);
9223 /* 64 bit mul double accumulate (UMAAL) */
9225 tmp
= load_reg(s
, rs
);
9226 tmp2
= load_reg(s
, rm
);
9227 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9228 gen_addq_lo(s
, tmp64
, rn
);
9229 gen_addq_lo(s
, tmp64
, rd
);
9230 gen_storeq_reg(s
, rn
, rd
, tmp64
);
9231 tcg_temp_free_i64(tmp64
);
9233 case 8: case 9: case 10: case 11:
9234 case 12: case 13: case 14: case 15:
9235 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9236 tmp
= load_reg(s
, rs
);
9237 tmp2
= load_reg(s
, rm
);
9238 if (insn
& (1 << 22)) {
9239 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
9241 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
9243 if (insn
& (1 << 21)) { /* mult accumulate */
9244 TCGv_i32 al
= load_reg(s
, rn
);
9245 TCGv_i32 ah
= load_reg(s
, rd
);
9246 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
9247 tcg_temp_free_i32(al
);
9248 tcg_temp_free_i32(ah
);
9250 if (insn
& (1 << 20)) {
9251 gen_logicq_cc(tmp
, tmp2
);
9253 store_reg(s
, rn
, tmp
);
9254 store_reg(s
, rd
, tmp2
);
9260 rn
= (insn
>> 16) & 0xf;
9261 rd
= (insn
>> 12) & 0xf;
9262 if (insn
& (1 << 23)) {
9263 /* load/store exclusive */
9264 bool is_ld
= extract32(insn
, 20, 1);
9265 bool is_lasr
= !extract32(insn
, 8, 1);
9266 int op2
= (insn
>> 8) & 3;
9267 op1
= (insn
>> 21) & 0x3;
9270 case 0: /* lda/stl */
9276 case 1: /* reserved */
9278 case 2: /* ldaex/stlex */
9281 case 3: /* ldrex/strex */
9290 addr
= tcg_temp_local_new_i32();
9291 load_reg_var(s
, addr
, rn
);
9293 if (is_lasr
&& !is_ld
) {
9294 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
9299 tmp
= tcg_temp_new_i32();
9302 gen_aa32_ld32u_iss(s
, tmp
, addr
,
9307 gen_aa32_ld8u_iss(s
, tmp
, addr
,
9312 gen_aa32_ld16u_iss(s
, tmp
, addr
,
9319 store_reg(s
, rd
, tmp
);
9322 tmp
= load_reg(s
, rm
);
9325 gen_aa32_st32_iss(s
, tmp
, addr
,
9330 gen_aa32_st8_iss(s
, tmp
, addr
,
9335 gen_aa32_st16_iss(s
, tmp
, addr
,
9342 tcg_temp_free_i32(tmp
);
9347 gen_load_exclusive(s
, rd
, 15, addr
, 2);
9349 case 1: /* ldrexd */
9350 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
9352 case 2: /* ldrexb */
9353 gen_load_exclusive(s
, rd
, 15, addr
, 0);
9355 case 3: /* ldrexh */
9356 gen_load_exclusive(s
, rd
, 15, addr
, 1);
9365 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
9367 case 1: /* strexd */
9368 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
9370 case 2: /* strexb */
9371 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
9373 case 3: /* strexh */
9374 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
9380 tcg_temp_free_i32(addr
);
9382 if (is_lasr
&& is_ld
) {
9383 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
9385 } else if ((insn
& 0x00300f00) == 0) {
9386 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9391 TCGMemOp opc
= s
->be_data
;
9395 if (insn
& (1 << 22)) {
9398 opc
|= MO_UL
| MO_ALIGN
;
9401 addr
= load_reg(s
, rn
);
9402 taddr
= gen_aa32_addr(s
, addr
, opc
);
9403 tcg_temp_free_i32(addr
);
9405 tmp
= load_reg(s
, rm
);
9406 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
9407 get_mem_index(s
), opc
);
9408 tcg_temp_free(taddr
);
9409 store_reg(s
, rd
, tmp
);
9416 bool load
= insn
& (1 << 20);
9417 bool wbit
= insn
& (1 << 21);
9418 bool pbit
= insn
& (1 << 24);
9419 bool doubleword
= false;
9422 /* Misc load/store */
9423 rn
= (insn
>> 16) & 0xf;
9424 rd
= (insn
>> 12) & 0xf;
9426 /* ISS not valid if writeback */
9427 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
9429 if (!load
&& (sh
& 2)) {
9433 /* UNPREDICTABLE; we choose to UNDEF */
9436 load
= (sh
& 1) == 0;
9440 addr
= load_reg(s
, rn
);
9442 gen_add_datah_offset(s
, insn
, 0, addr
);
9449 tmp
= load_reg(s
, rd
);
9450 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9451 tcg_temp_free_i32(tmp
);
9452 tcg_gen_addi_i32(addr
, addr
, 4);
9453 tmp
= load_reg(s
, rd
+ 1);
9454 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9455 tcg_temp_free_i32(tmp
);
9458 tmp
= tcg_temp_new_i32();
9459 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9460 store_reg(s
, rd
, tmp
);
9461 tcg_gen_addi_i32(addr
, addr
, 4);
9462 tmp
= tcg_temp_new_i32();
9463 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9466 address_offset
= -4;
9469 tmp
= tcg_temp_new_i32();
9472 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9476 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9481 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9487 tmp
= load_reg(s
, rd
);
9488 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9489 tcg_temp_free_i32(tmp
);
9491 /* Perform base writeback before the loaded value to
9492 ensure correct behavior with overlapping index registers.
9493 ldrd with base writeback is undefined if the
9494 destination and index registers overlap. */
9496 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9497 store_reg(s
, rn
, addr
);
9500 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9501 store_reg(s
, rn
, addr
);
9503 tcg_temp_free_i32(addr
);
9506 /* Complete the load. */
9507 store_reg(s
, rd
, tmp
);
9516 if (insn
& (1 << 4)) {
9518 /* Armv6 Media instructions. */
9520 rn
= (insn
>> 16) & 0xf;
9521 rd
= (insn
>> 12) & 0xf;
9522 rs
= (insn
>> 8) & 0xf;
9523 switch ((insn
>> 23) & 3) {
9524 case 0: /* Parallel add/subtract. */
9525 op1
= (insn
>> 20) & 7;
9526 tmp
= load_reg(s
, rn
);
9527 tmp2
= load_reg(s
, rm
);
9528 sh
= (insn
>> 5) & 7;
9529 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9531 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9532 tcg_temp_free_i32(tmp2
);
9533 store_reg(s
, rd
, tmp
);
9536 if ((insn
& 0x00700020) == 0) {
9537 /* Halfword pack. */
9538 tmp
= load_reg(s
, rn
);
9539 tmp2
= load_reg(s
, rm
);
9540 shift
= (insn
>> 7) & 0x1f;
9541 if (insn
& (1 << 6)) {
9545 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9546 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9547 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9551 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9552 tcg_gen_ext16u_i32(tmp
, tmp
);
9553 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9555 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9556 tcg_temp_free_i32(tmp2
);
9557 store_reg(s
, rd
, tmp
);
9558 } else if ((insn
& 0x00200020) == 0x00200000) {
9560 tmp
= load_reg(s
, rm
);
9561 shift
= (insn
>> 7) & 0x1f;
9562 if (insn
& (1 << 6)) {
9565 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9567 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9569 sh
= (insn
>> 16) & 0x1f;
9570 tmp2
= tcg_const_i32(sh
);
9571 if (insn
& (1 << 22))
9572 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9574 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9575 tcg_temp_free_i32(tmp2
);
9576 store_reg(s
, rd
, tmp
);
9577 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9579 tmp
= load_reg(s
, rm
);
9580 sh
= (insn
>> 16) & 0x1f;
9581 tmp2
= tcg_const_i32(sh
);
9582 if (insn
& (1 << 22))
9583 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9585 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9586 tcg_temp_free_i32(tmp2
);
9587 store_reg(s
, rd
, tmp
);
9588 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9590 tmp
= load_reg(s
, rn
);
9591 tmp2
= load_reg(s
, rm
);
9592 tmp3
= tcg_temp_new_i32();
9593 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9594 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9595 tcg_temp_free_i32(tmp3
);
9596 tcg_temp_free_i32(tmp2
);
9597 store_reg(s
, rd
, tmp
);
9598 } else if ((insn
& 0x000003e0) == 0x00000060) {
9599 tmp
= load_reg(s
, rm
);
9600 shift
= (insn
>> 10) & 3;
9601 /* ??? In many cases it's not necessary to do a
9602 rotate, a shift is sufficient. */
9604 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9605 op1
= (insn
>> 20) & 7;
9607 case 0: gen_sxtb16(tmp
); break;
9608 case 2: gen_sxtb(tmp
); break;
9609 case 3: gen_sxth(tmp
); break;
9610 case 4: gen_uxtb16(tmp
); break;
9611 case 6: gen_uxtb(tmp
); break;
9612 case 7: gen_uxth(tmp
); break;
9613 default: goto illegal_op
;
9616 tmp2
= load_reg(s
, rn
);
9617 if ((op1
& 3) == 0) {
9618 gen_add16(tmp
, tmp2
);
9620 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9621 tcg_temp_free_i32(tmp2
);
9624 store_reg(s
, rd
, tmp
);
9625 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9627 tmp
= load_reg(s
, rm
);
9628 if (insn
& (1 << 22)) {
9629 if (insn
& (1 << 7)) {
9633 gen_helper_rbit(tmp
, tmp
);
9636 if (insn
& (1 << 7))
9639 tcg_gen_bswap32_i32(tmp
, tmp
);
9641 store_reg(s
, rd
, tmp
);
9646 case 2: /* Multiplies (Type 3). */
9647 switch ((insn
>> 20) & 0x7) {
9649 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9650 /* op2 not 00x or 11x : UNDEF */
9653 /* Signed multiply most significant [accumulate].
9654 (SMMUL, SMMLA, SMMLS) */
9655 tmp
= load_reg(s
, rm
);
9656 tmp2
= load_reg(s
, rs
);
9657 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9660 tmp
= load_reg(s
, rd
);
9661 if (insn
& (1 << 6)) {
9662 tmp64
= gen_subq_msw(tmp64
, tmp
);
9664 tmp64
= gen_addq_msw(tmp64
, tmp
);
9667 if (insn
& (1 << 5)) {
9668 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9670 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9671 tmp
= tcg_temp_new_i32();
9672 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9673 tcg_temp_free_i64(tmp64
);
9674 store_reg(s
, rn
, tmp
);
9678 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9679 if (insn
& (1 << 7)) {
9682 tmp
= load_reg(s
, rm
);
9683 tmp2
= load_reg(s
, rs
);
9684 if (insn
& (1 << 5))
9685 gen_swap_half(tmp2
);
9686 gen_smul_dual(tmp
, tmp2
);
9687 if (insn
& (1 << 22)) {
9688 /* smlald, smlsld */
9691 tmp64
= tcg_temp_new_i64();
9692 tmp64_2
= tcg_temp_new_i64();
9693 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9694 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9695 tcg_temp_free_i32(tmp
);
9696 tcg_temp_free_i32(tmp2
);
9697 if (insn
& (1 << 6)) {
9698 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9700 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9702 tcg_temp_free_i64(tmp64_2
);
9703 gen_addq(s
, tmp64
, rd
, rn
);
9704 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9705 tcg_temp_free_i64(tmp64
);
9707 /* smuad, smusd, smlad, smlsd */
9708 if (insn
& (1 << 6)) {
9709 /* This subtraction cannot overflow. */
9710 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9712 /* This addition cannot overflow 32 bits;
9713 * however it may overflow considered as a
9714 * signed operation, in which case we must set
9717 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9719 tcg_temp_free_i32(tmp2
);
9722 tmp2
= load_reg(s
, rd
);
9723 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9724 tcg_temp_free_i32(tmp2
);
9726 store_reg(s
, rn
, tmp
);
9732 if (!dc_isar_feature(arm_div
, s
)) {
9735 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9738 tmp
= load_reg(s
, rm
);
9739 tmp2
= load_reg(s
, rs
);
9740 if (insn
& (1 << 21)) {
9741 gen_helper_udiv(tmp
, tmp
, tmp2
);
9743 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9745 tcg_temp_free_i32(tmp2
);
9746 store_reg(s
, rn
, tmp
);
9753 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9755 case 0: /* Unsigned sum of absolute differences. */
9757 tmp
= load_reg(s
, rm
);
9758 tmp2
= load_reg(s
, rs
);
9759 gen_helper_usad8(tmp
, tmp
, tmp2
);
9760 tcg_temp_free_i32(tmp2
);
9762 tmp2
= load_reg(s
, rd
);
9763 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9764 tcg_temp_free_i32(tmp2
);
9766 store_reg(s
, rn
, tmp
);
9768 case 0x20: case 0x24: case 0x28: case 0x2c:
9769 /* Bitfield insert/clear. */
9771 shift
= (insn
>> 7) & 0x1f;
9772 i
= (insn
>> 16) & 0x1f;
9774 /* UNPREDICTABLE; we choose to UNDEF */
9779 tmp
= tcg_temp_new_i32();
9780 tcg_gen_movi_i32(tmp
, 0);
9782 tmp
= load_reg(s
, rm
);
9785 tmp2
= load_reg(s
, rd
);
9786 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9787 tcg_temp_free_i32(tmp2
);
9789 store_reg(s
, rd
, tmp
);
9791 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9792 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9794 tmp
= load_reg(s
, rm
);
9795 shift
= (insn
>> 7) & 0x1f;
9796 i
= ((insn
>> 16) & 0x1f) + 1;
9801 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9803 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9806 store_reg(s
, rd
, tmp
);
9816 /* Check for undefined extension instructions
9817 * per the ARM Bible IE:
9818 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9820 sh
= (0xf << 20) | (0xf << 4);
9821 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9825 /* load/store byte/word */
9826 rn
= (insn
>> 16) & 0xf;
9827 rd
= (insn
>> 12) & 0xf;
9828 tmp2
= load_reg(s
, rn
);
9829 if ((insn
& 0x01200000) == 0x00200000) {
9831 i
= get_a32_user_mem_index(s
);
9833 i
= get_mem_index(s
);
9835 if (insn
& (1 << 24))
9836 gen_add_data_offset(s
, insn
, tmp2
);
9837 if (insn
& (1 << 20)) {
9839 tmp
= tcg_temp_new_i32();
9840 if (insn
& (1 << 22)) {
9841 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9843 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9847 tmp
= load_reg(s
, rd
);
9848 if (insn
& (1 << 22)) {
9849 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9851 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9853 tcg_temp_free_i32(tmp
);
9855 if (!(insn
& (1 << 24))) {
9856 gen_add_data_offset(s
, insn
, tmp2
);
9857 store_reg(s
, rn
, tmp2
);
9858 } else if (insn
& (1 << 21)) {
9859 store_reg(s
, rn
, tmp2
);
9861 tcg_temp_free_i32(tmp2
);
9863 if (insn
& (1 << 20)) {
9864 /* Complete the load. */
9865 store_reg_from_load(s
, rd
, tmp
);
9871 int j
, n
, loaded_base
;
9872 bool exc_return
= false;
9873 bool is_load
= extract32(insn
, 20, 1);
9875 TCGv_i32 loaded_var
;
9876 /* load/store multiple words */
9877 /* XXX: store correct base if write back */
9878 if (insn
& (1 << 22)) {
9879 /* LDM (user), LDM (exception return) and STM (user) */
9881 goto illegal_op
; /* only usable in supervisor mode */
9883 if (is_load
&& extract32(insn
, 15, 1)) {
9889 rn
= (insn
>> 16) & 0xf;
9890 addr
= load_reg(s
, rn
);
9892 /* compute total size */
9897 if (insn
& (1 << i
))
9900 /* XXX: test invalid n == 0 case ? */
9901 if (insn
& (1 << 23)) {
9902 if (insn
& (1 << 24)) {
9904 tcg_gen_addi_i32(addr
, addr
, 4);
9906 /* post increment */
9909 if (insn
& (1 << 24)) {
9911 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9913 /* post decrement */
9915 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9920 if (insn
& (1 << i
)) {
9923 tmp
= tcg_temp_new_i32();
9924 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9926 tmp2
= tcg_const_i32(i
);
9927 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9928 tcg_temp_free_i32(tmp2
);
9929 tcg_temp_free_i32(tmp
);
9930 } else if (i
== rn
) {
9933 } else if (i
== 15 && exc_return
) {
9934 store_pc_exc_ret(s
, tmp
);
9936 store_reg_from_load(s
, i
, tmp
);
9941 /* special case: r15 = PC + 8 */
9942 val
= (long)s
->pc
+ 4;
9943 tmp
= tcg_temp_new_i32();
9944 tcg_gen_movi_i32(tmp
, val
);
9946 tmp
= tcg_temp_new_i32();
9947 tmp2
= tcg_const_i32(i
);
9948 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9949 tcg_temp_free_i32(tmp2
);
9951 tmp
= load_reg(s
, i
);
9953 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9954 tcg_temp_free_i32(tmp
);
9957 /* no need to add after the last transfer */
9959 tcg_gen_addi_i32(addr
, addr
, 4);
9962 if (insn
& (1 << 21)) {
9964 if (insn
& (1 << 23)) {
9965 if (insn
& (1 << 24)) {
9968 /* post increment */
9969 tcg_gen_addi_i32(addr
, addr
, 4);
9972 if (insn
& (1 << 24)) {
9975 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9977 /* post decrement */
9978 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9981 store_reg(s
, rn
, addr
);
9983 tcg_temp_free_i32(addr
);
9986 store_reg(s
, rn
, loaded_var
);
9989 /* Restore CPSR from SPSR. */
9990 tmp
= load_cpu_field(spsr
);
9991 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
9994 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9995 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
9998 tcg_temp_free_i32(tmp
);
9999 /* Must exit loop to check un-masked IRQs */
10000 s
->base
.is_jmp
= DISAS_EXIT
;
10009 /* branch (and link) */
10010 val
= (int32_t)s
->pc
;
10011 if (insn
& (1 << 24)) {
10012 tmp
= tcg_temp_new_i32();
10013 tcg_gen_movi_i32(tmp
, val
);
10014 store_reg(s
, 14, tmp
);
10016 offset
= sextract32(insn
<< 2, 0, 26);
10024 if (((insn
>> 8) & 0xe) == 10) {
10026 if (disas_vfp_insn(s
, insn
)) {
10029 } else if (disas_coproc_insn(s
, insn
)) {
10036 gen_set_pc_im(s
, s
->pc
);
10037 s
->svc_imm
= extract32(insn
, 0, 24);
10038 s
->base
.is_jmp
= DISAS_SWI
;
10042 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
10043 default_exception_el(s
));
10049 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t insn
)
10051 /* Return true if this is a 16 bit instruction. We must be precise
10052 * about this (matching the decode). We assume that s->pc still
10053 * points to the first 16 bits of the insn.
10055 if ((insn
>> 11) < 0x1d) {
10056 /* Definitely a 16-bit instruction */
10060 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10061 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10062 * end up actually treating this as two 16-bit insns, though,
10063 * if it's half of a bl/blx pair that might span a page boundary.
10065 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
) ||
10066 arm_dc_feature(s
, ARM_FEATURE_M
)) {
10067 /* Thumb2 cores (including all M profile ones) always treat
10068 * 32-bit insns as 32-bit.
10073 if ((insn
>> 11) == 0x1e && s
->pc
- s
->page_start
< TARGET_PAGE_SIZE
- 3) {
10074 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10075 * is not on the next page; we merge this into a 32-bit
10080 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10081 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10082 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10083 * -- handle as single 16 bit insn
10088 /* Return true if this is a Thumb-2 logical op. */
10090 thumb2_logic_op(int op
)
10095 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10096 then set condition code flags based on the result of the operation.
10097 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10098 to the high bit of T1.
10099 Returns zero if the opcode is valid. */
10102 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
10103 TCGv_i32 t0
, TCGv_i32 t1
)
10110 tcg_gen_and_i32(t0
, t0
, t1
);
10114 tcg_gen_andc_i32(t0
, t0
, t1
);
10118 tcg_gen_or_i32(t0
, t0
, t1
);
10122 tcg_gen_orc_i32(t0
, t0
, t1
);
10126 tcg_gen_xor_i32(t0
, t0
, t1
);
10131 gen_add_CC(t0
, t0
, t1
);
10133 tcg_gen_add_i32(t0
, t0
, t1
);
10137 gen_adc_CC(t0
, t0
, t1
);
10143 gen_sbc_CC(t0
, t0
, t1
);
10145 gen_sub_carry(t0
, t0
, t1
);
10150 gen_sub_CC(t0
, t0
, t1
);
10152 tcg_gen_sub_i32(t0
, t0
, t1
);
10156 gen_sub_CC(t0
, t1
, t0
);
10158 tcg_gen_sub_i32(t0
, t1
, t0
);
10160 default: /* 5, 6, 7, 9, 12, 15. */
10166 gen_set_CF_bit31(t1
);
10171 /* Translate a 32-bit thumb instruction. */
10172 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
10174 uint32_t imm
, shift
, offset
;
10175 uint32_t rd
, rn
, rm
, rs
;
10187 * ARMv6-M supports a limited subset of Thumb2 instructions.
10188 * Other Thumb1 architectures allow only 32-bit
10189 * combined BL/BLX prefix and suffix.
10191 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
10192 !arm_dc_feature(s
, ARM_FEATURE_V7
)) {
10194 bool found
= false;
10195 static const uint32_t armv6m_insn
[] = {0xf3808000 /* msr */,
10196 0xf3b08040 /* dsb */,
10197 0xf3b08050 /* dmb */,
10198 0xf3b08060 /* isb */,
10199 0xf3e08000 /* mrs */,
10200 0xf000d000 /* bl */};
10201 static const uint32_t armv6m_mask
[] = {0xffe0d000,
10208 for (i
= 0; i
< ARRAY_SIZE(armv6m_insn
); i
++) {
10209 if ((insn
& armv6m_mask
[i
]) == armv6m_insn
[i
]) {
10217 } else if ((insn
& 0xf800e800) != 0xf000e800) {
10221 rn
= (insn
>> 16) & 0xf;
10222 rs
= (insn
>> 12) & 0xf;
10223 rd
= (insn
>> 8) & 0xf;
10225 switch ((insn
>> 25) & 0xf) {
10226 case 0: case 1: case 2: case 3:
10227 /* 16-bit instructions. Should never happen. */
10230 if (insn
& (1 << 22)) {
10231 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10232 * - load/store doubleword, load/store exclusive, ldacq/strel,
10233 * table branch, TT.
10235 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_M
) &&
10236 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10237 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10239 * The bulk of the behaviour for this instruction is implemented
10240 * in v7m_handle_execute_nsc(), which deals with the insn when
10241 * it is executed by a CPU in non-secure state from memory
10242 * which is Secure & NonSecure-Callable.
10243 * Here we only need to handle the remaining cases:
10244 * * in NS memory (including the "security extension not
10245 * implemented" case) : NOP
10246 * * in S memory but CPU already secure (clear IT bits)
10247 * We know that the attribute for the memory this insn is
10248 * in must match the current CPU state, because otherwise
10249 * get_phys_addr_pmsav8 would have generated an exception.
10251 if (s
->v8m_secure
) {
10252 /* Like the IT insn, we don't need to generate any code */
10253 s
->condexec_cond
= 0;
10254 s
->condexec_mask
= 0;
10256 } else if (insn
& 0x01200000) {
10257 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10258 * - load/store dual (post-indexed)
10259 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10260 * - load/store dual (literal and immediate)
10261 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10262 * - load/store dual (pre-indexed)
10264 bool wback
= extract32(insn
, 21, 1);
10267 if (insn
& (1 << 21)) {
10268 /* UNPREDICTABLE */
10271 addr
= tcg_temp_new_i32();
10272 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
10274 addr
= load_reg(s
, rn
);
10276 offset
= (insn
& 0xff) * 4;
10277 if ((insn
& (1 << 23)) == 0) {
10281 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
10283 * Here 'addr' is the current SP; if offset is +ve we're
10284 * moving SP up, else down. It is UNKNOWN whether the limit
10285 * check triggers when SP starts below the limit and ends
10286 * up above it; check whichever of the current and final
10287 * SP is lower, so QEMU will trigger in that situation.
10289 if ((int32_t)offset
< 0) {
10290 TCGv_i32 newsp
= tcg_temp_new_i32();
10292 tcg_gen_addi_i32(newsp
, addr
, offset
);
10293 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
10294 tcg_temp_free_i32(newsp
);
10296 gen_helper_v8m_stackcheck(cpu_env
, addr
);
10300 if (insn
& (1 << 24)) {
10301 tcg_gen_addi_i32(addr
, addr
, offset
);
10304 if (insn
& (1 << 20)) {
10306 tmp
= tcg_temp_new_i32();
10307 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10308 store_reg(s
, rs
, tmp
);
10309 tcg_gen_addi_i32(addr
, addr
, 4);
10310 tmp
= tcg_temp_new_i32();
10311 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10312 store_reg(s
, rd
, tmp
);
10315 tmp
= load_reg(s
, rs
);
10316 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10317 tcg_temp_free_i32(tmp
);
10318 tcg_gen_addi_i32(addr
, addr
, 4);
10319 tmp
= load_reg(s
, rd
);
10320 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10321 tcg_temp_free_i32(tmp
);
10324 /* Base writeback. */
10325 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
10326 store_reg(s
, rn
, addr
);
10328 tcg_temp_free_i32(addr
);
10330 } else if ((insn
& (1 << 23)) == 0) {
10331 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10332 * - load/store exclusive word
10336 if (!(insn
& (1 << 20)) &&
10337 arm_dc_feature(s
, ARM_FEATURE_M
) &&
10338 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10339 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10342 bool alt
= insn
& (1 << 7);
10343 TCGv_i32 addr
, op
, ttresp
;
10345 if ((insn
& 0x3f) || rd
== 13 || rd
== 15 || rn
== 15) {
10346 /* we UNDEF for these UNPREDICTABLE cases */
10350 if (alt
&& !s
->v8m_secure
) {
10354 addr
= load_reg(s
, rn
);
10355 op
= tcg_const_i32(extract32(insn
, 6, 2));
10356 ttresp
= tcg_temp_new_i32();
10357 gen_helper_v7m_tt(ttresp
, cpu_env
, addr
, op
);
10358 tcg_temp_free_i32(addr
);
10359 tcg_temp_free_i32(op
);
10360 store_reg(s
, rd
, ttresp
);
10365 addr
= tcg_temp_local_new_i32();
10366 load_reg_var(s
, addr
, rn
);
10367 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
10368 if (insn
& (1 << 20)) {
10369 gen_load_exclusive(s
, rs
, 15, addr
, 2);
10371 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
10373 tcg_temp_free_i32(addr
);
10374 } else if ((insn
& (7 << 5)) == 0) {
10375 /* Table Branch. */
10377 addr
= tcg_temp_new_i32();
10378 tcg_gen_movi_i32(addr
, s
->pc
);
10380 addr
= load_reg(s
, rn
);
10382 tmp
= load_reg(s
, rm
);
10383 tcg_gen_add_i32(addr
, addr
, tmp
);
10384 if (insn
& (1 << 4)) {
10386 tcg_gen_add_i32(addr
, addr
, tmp
);
10387 tcg_temp_free_i32(tmp
);
10388 tmp
= tcg_temp_new_i32();
10389 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
10391 tcg_temp_free_i32(tmp
);
10392 tmp
= tcg_temp_new_i32();
10393 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
10395 tcg_temp_free_i32(addr
);
10396 tcg_gen_shli_i32(tmp
, tmp
, 1);
10397 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
10398 store_reg(s
, 15, tmp
);
10400 bool is_lasr
= false;
10401 bool is_ld
= extract32(insn
, 20, 1);
10402 int op2
= (insn
>> 6) & 0x3;
10403 op
= (insn
>> 4) & 0x3;
10408 /* Load/store exclusive byte/halfword/doubleword */
10415 /* Load-acquire/store-release */
10421 /* Load-acquire/store-release exclusive */
10427 if (is_lasr
&& !is_ld
) {
10428 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
10431 addr
= tcg_temp_local_new_i32();
10432 load_reg_var(s
, addr
, rn
);
10435 tmp
= tcg_temp_new_i32();
10438 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
10442 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
10446 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
10452 store_reg(s
, rs
, tmp
);
10454 tmp
= load_reg(s
, rs
);
10457 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
10461 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
10465 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
10471 tcg_temp_free_i32(tmp
);
10473 } else if (is_ld
) {
10474 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
10476 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
10478 tcg_temp_free_i32(addr
);
10480 if (is_lasr
&& is_ld
) {
10481 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
10485 /* Load/store multiple, RFE, SRS. */
10486 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
10487 /* RFE, SRS: not available in user mode or on M profile */
10488 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10491 if (insn
& (1 << 20)) {
10493 addr
= load_reg(s
, rn
);
10494 if ((insn
& (1 << 24)) == 0)
10495 tcg_gen_addi_i32(addr
, addr
, -8);
10496 /* Load PC into tmp and CPSR into tmp2. */
10497 tmp
= tcg_temp_new_i32();
10498 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10499 tcg_gen_addi_i32(addr
, addr
, 4);
10500 tmp2
= tcg_temp_new_i32();
10501 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
10502 if (insn
& (1 << 21)) {
10503 /* Base writeback. */
10504 if (insn
& (1 << 24)) {
10505 tcg_gen_addi_i32(addr
, addr
, 4);
10507 tcg_gen_addi_i32(addr
, addr
, -4);
10509 store_reg(s
, rn
, addr
);
10511 tcg_temp_free_i32(addr
);
10513 gen_rfe(s
, tmp
, tmp2
);
10516 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
10520 int i
, loaded_base
= 0;
10521 TCGv_i32 loaded_var
;
10522 bool wback
= extract32(insn
, 21, 1);
10523 /* Load/store multiple. */
10524 addr
= load_reg(s
, rn
);
10526 for (i
= 0; i
< 16; i
++) {
10527 if (insn
& (1 << i
))
10531 if (insn
& (1 << 24)) {
10532 tcg_gen_addi_i32(addr
, addr
, -offset
);
10535 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
10537 * If the writeback is incrementing SP rather than
10538 * decrementing it, and the initial SP is below the
10539 * stack limit but the final written-back SP would
10540 * be above, then then we must not perform any memory
10541 * accesses, but it is IMPDEF whether we generate
10542 * an exception. We choose to do so in this case.
10543 * At this point 'addr' is the lowest address, so
10544 * either the original SP (if incrementing) or our
10545 * final SP (if decrementing), so that's what we check.
10547 gen_helper_v8m_stackcheck(cpu_env
, addr
);
10551 for (i
= 0; i
< 16; i
++) {
10552 if ((insn
& (1 << i
)) == 0)
10554 if (insn
& (1 << 20)) {
10556 tmp
= tcg_temp_new_i32();
10557 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10559 gen_bx_excret(s
, tmp
);
10560 } else if (i
== rn
) {
10564 store_reg(s
, i
, tmp
);
10568 tmp
= load_reg(s
, i
);
10569 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10570 tcg_temp_free_i32(tmp
);
10572 tcg_gen_addi_i32(addr
, addr
, 4);
10575 store_reg(s
, rn
, loaded_var
);
10578 /* Base register writeback. */
10579 if (insn
& (1 << 24)) {
10580 tcg_gen_addi_i32(addr
, addr
, -offset
);
10582 /* Fault if writeback register is in register list. */
10583 if (insn
& (1 << rn
))
10585 store_reg(s
, rn
, addr
);
10587 tcg_temp_free_i32(addr
);
10594 op
= (insn
>> 21) & 0xf;
10596 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10599 /* Halfword pack. */
10600 tmp
= load_reg(s
, rn
);
10601 tmp2
= load_reg(s
, rm
);
10602 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
10603 if (insn
& (1 << 5)) {
10607 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
10608 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
10609 tcg_gen_ext16u_i32(tmp2
, tmp2
);
10613 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10614 tcg_gen_ext16u_i32(tmp
, tmp
);
10615 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10617 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10618 tcg_temp_free_i32(tmp2
);
10619 store_reg(s
, rd
, tmp
);
10621 /* Data processing register constant shift. */
10623 tmp
= tcg_temp_new_i32();
10624 tcg_gen_movi_i32(tmp
, 0);
10626 tmp
= load_reg(s
, rn
);
10628 tmp2
= load_reg(s
, rm
);
10630 shiftop
= (insn
>> 4) & 3;
10631 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10632 conds
= (insn
& (1 << 20)) != 0;
10633 logic_cc
= (conds
&& thumb2_logic_op(op
));
10634 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10635 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10637 tcg_temp_free_i32(tmp2
);
10639 ((op
== 2 && rn
== 15) ||
10640 (op
== 8 && rn
== 13) ||
10641 (op
== 13 && rn
== 13))) {
10642 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
10643 store_sp_checked(s
, tmp
);
10644 } else if (rd
!= 15) {
10645 store_reg(s
, rd
, tmp
);
10647 tcg_temp_free_i32(tmp
);
10651 case 13: /* Misc data processing. */
10652 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10653 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10656 case 0: /* Register controlled shift. */
10657 tmp
= load_reg(s
, rn
);
10658 tmp2
= load_reg(s
, rm
);
10659 if ((insn
& 0x70) != 0)
10662 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
10663 * - MOV, MOVS (register-shifted register), flagsetting
10665 op
= (insn
>> 21) & 3;
10666 logic_cc
= (insn
& (1 << 20)) != 0;
10667 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10670 store_reg(s
, rd
, tmp
);
10672 case 1: /* Sign/zero extend. */
10673 op
= (insn
>> 20) & 7;
10675 case 0: /* SXTAH, SXTH */
10676 case 1: /* UXTAH, UXTH */
10677 case 4: /* SXTAB, SXTB */
10678 case 5: /* UXTAB, UXTB */
10680 case 2: /* SXTAB16, SXTB16 */
10681 case 3: /* UXTAB16, UXTB16 */
10682 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10690 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10694 tmp
= load_reg(s
, rm
);
10695 shift
= (insn
>> 4) & 3;
10696 /* ??? In many cases it's not necessary to do a
10697 rotate, a shift is sufficient. */
10699 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10700 op
= (insn
>> 20) & 7;
10702 case 0: gen_sxth(tmp
); break;
10703 case 1: gen_uxth(tmp
); break;
10704 case 2: gen_sxtb16(tmp
); break;
10705 case 3: gen_uxtb16(tmp
); break;
10706 case 4: gen_sxtb(tmp
); break;
10707 case 5: gen_uxtb(tmp
); break;
10709 g_assert_not_reached();
10712 tmp2
= load_reg(s
, rn
);
10713 if ((op
>> 1) == 1) {
10714 gen_add16(tmp
, tmp2
);
10716 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10717 tcg_temp_free_i32(tmp2
);
10720 store_reg(s
, rd
, tmp
);
10722 case 2: /* SIMD add/subtract. */
10723 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10726 op
= (insn
>> 20) & 7;
10727 shift
= (insn
>> 4) & 7;
10728 if ((op
& 3) == 3 || (shift
& 3) == 3)
10730 tmp
= load_reg(s
, rn
);
10731 tmp2
= load_reg(s
, rm
);
10732 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10733 tcg_temp_free_i32(tmp2
);
10734 store_reg(s
, rd
, tmp
);
10736 case 3: /* Other data processing. */
10737 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10739 /* Saturating add/subtract. */
10740 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10743 tmp
= load_reg(s
, rn
);
10744 tmp2
= load_reg(s
, rm
);
10746 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10748 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10750 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10751 tcg_temp_free_i32(tmp2
);
10754 case 0x0a: /* rbit */
10755 case 0x08: /* rev */
10756 case 0x09: /* rev16 */
10757 case 0x0b: /* revsh */
10758 case 0x18: /* clz */
10760 case 0x10: /* sel */
10761 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10765 case 0x20: /* crc32/crc32c */
10771 if (!dc_isar_feature(aa32_crc32
, s
)) {
10778 tmp
= load_reg(s
, rn
);
10780 case 0x0a: /* rbit */
10781 gen_helper_rbit(tmp
, tmp
);
10783 case 0x08: /* rev */
10784 tcg_gen_bswap32_i32(tmp
, tmp
);
10786 case 0x09: /* rev16 */
10789 case 0x0b: /* revsh */
10792 case 0x10: /* sel */
10793 tmp2
= load_reg(s
, rm
);
10794 tmp3
= tcg_temp_new_i32();
10795 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10796 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10797 tcg_temp_free_i32(tmp3
);
10798 tcg_temp_free_i32(tmp2
);
10800 case 0x18: /* clz */
10801 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10811 uint32_t sz
= op
& 0x3;
10812 uint32_t c
= op
& 0x8;
10814 tmp2
= load_reg(s
, rm
);
10816 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10817 } else if (sz
== 1) {
10818 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10820 tmp3
= tcg_const_i32(1 << sz
);
10822 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10824 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10826 tcg_temp_free_i32(tmp2
);
10827 tcg_temp_free_i32(tmp3
);
10831 g_assert_not_reached();
10834 store_reg(s
, rd
, tmp
);
10836 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10837 switch ((insn
>> 20) & 7) {
10838 case 0: /* 32 x 32 -> 32 */
10839 case 7: /* Unsigned sum of absolute differences. */
10841 case 1: /* 16 x 16 -> 32 */
10842 case 2: /* Dual multiply add. */
10843 case 3: /* 32 * 16 -> 32msb */
10844 case 4: /* Dual multiply subtract. */
10845 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10846 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10851 op
= (insn
>> 4) & 0xf;
10852 tmp
= load_reg(s
, rn
);
10853 tmp2
= load_reg(s
, rm
);
10854 switch ((insn
>> 20) & 7) {
10855 case 0: /* 32 x 32 -> 32 */
10856 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10857 tcg_temp_free_i32(tmp2
);
10859 tmp2
= load_reg(s
, rs
);
10861 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10863 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10864 tcg_temp_free_i32(tmp2
);
10867 case 1: /* 16 x 16 -> 32 */
10868 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10869 tcg_temp_free_i32(tmp2
);
10871 tmp2
= load_reg(s
, rs
);
10872 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10873 tcg_temp_free_i32(tmp2
);
10876 case 2: /* Dual multiply add. */
10877 case 4: /* Dual multiply subtract. */
10879 gen_swap_half(tmp2
);
10880 gen_smul_dual(tmp
, tmp2
);
10881 if (insn
& (1 << 22)) {
10882 /* This subtraction cannot overflow. */
10883 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10885 /* This addition cannot overflow 32 bits;
10886 * however it may overflow considered as a signed
10887 * operation, in which case we must set the Q flag.
10889 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10891 tcg_temp_free_i32(tmp2
);
10894 tmp2
= load_reg(s
, rs
);
10895 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10896 tcg_temp_free_i32(tmp2
);
10899 case 3: /* 32 * 16 -> 32msb */
10901 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10904 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10905 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10906 tmp
= tcg_temp_new_i32();
10907 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10908 tcg_temp_free_i64(tmp64
);
10911 tmp2
= load_reg(s
, rs
);
10912 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10913 tcg_temp_free_i32(tmp2
);
10916 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10917 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10919 tmp
= load_reg(s
, rs
);
10920 if (insn
& (1 << 20)) {
10921 tmp64
= gen_addq_msw(tmp64
, tmp
);
10923 tmp64
= gen_subq_msw(tmp64
, tmp
);
10926 if (insn
& (1 << 4)) {
10927 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10929 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10930 tmp
= tcg_temp_new_i32();
10931 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10932 tcg_temp_free_i64(tmp64
);
10934 case 7: /* Unsigned sum of absolute differences. */
10935 gen_helper_usad8(tmp
, tmp
, tmp2
);
10936 tcg_temp_free_i32(tmp2
);
10938 tmp2
= load_reg(s
, rs
);
10939 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10940 tcg_temp_free_i32(tmp2
);
10944 store_reg(s
, rd
, tmp
);
10946 case 6: case 7: /* 64-bit multiply, Divide. */
10947 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10948 tmp
= load_reg(s
, rn
);
10949 tmp2
= load_reg(s
, rm
);
10950 if ((op
& 0x50) == 0x10) {
10952 if (!dc_isar_feature(thumb_div
, s
)) {
10956 gen_helper_udiv(tmp
, tmp
, tmp2
);
10958 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10959 tcg_temp_free_i32(tmp2
);
10960 store_reg(s
, rd
, tmp
);
10961 } else if ((op
& 0xe) == 0xc) {
10962 /* Dual multiply accumulate long. */
10963 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10964 tcg_temp_free_i32(tmp
);
10965 tcg_temp_free_i32(tmp2
);
10969 gen_swap_half(tmp2
);
10970 gen_smul_dual(tmp
, tmp2
);
10972 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10974 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10976 tcg_temp_free_i32(tmp2
);
10978 tmp64
= tcg_temp_new_i64();
10979 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10980 tcg_temp_free_i32(tmp
);
10981 gen_addq(s
, tmp64
, rs
, rd
);
10982 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10983 tcg_temp_free_i64(tmp64
);
10986 /* Unsigned 64-bit multiply */
10987 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10991 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10992 tcg_temp_free_i32(tmp2
);
10993 tcg_temp_free_i32(tmp
);
10996 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10997 tcg_temp_free_i32(tmp2
);
10998 tmp64
= tcg_temp_new_i64();
10999 tcg_gen_ext_i32_i64(tmp64
, tmp
);
11000 tcg_temp_free_i32(tmp
);
11002 /* Signed 64-bit multiply */
11003 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
11008 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11009 tcg_temp_free_i64(tmp64
);
11012 gen_addq_lo(s
, tmp64
, rs
);
11013 gen_addq_lo(s
, tmp64
, rd
);
11014 } else if (op
& 0x40) {
11015 /* 64-bit accumulate. */
11016 gen_addq(s
, tmp64
, rs
, rd
);
11018 gen_storeq_reg(s
, rs
, rd
, tmp64
);
11019 tcg_temp_free_i64(tmp64
);
11024 case 6: case 7: case 14: case 15:
11026 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11027 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
11028 if (extract32(insn
, 24, 2) == 3) {
11029 goto illegal_op
; /* op0 = 0b11 : unallocated */
11033 * Decode VLLDM and VLSTM first: these are nonstandard because:
11034 * * if there is no FPU then these insns must NOP in
11035 * Secure state and UNDEF in Nonsecure state
11036 * * if there is an FPU then these insns do not have
11037 * the usual behaviour that disas_vfp_insn() provides of
11038 * being controlled by CPACR/NSACR enable bits or the
11039 * lazy-stacking logic.
11041 if (arm_dc_feature(s
, ARM_FEATURE_V8
) &&
11042 (insn
& 0xffa00f00) == 0xec200a00) {
11043 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
11045 * We choose to UNDEF if the RAZ bits are non-zero.
11047 if (!s
->v8m_secure
|| (insn
& 0x0040f0ff)) {
11051 if (arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
11052 TCGv_i32 fptr
= load_reg(s
, rn
);
11054 if (extract32(insn
, 20, 1)) {
11055 gen_helper_v7m_vlldm(cpu_env
, fptr
);
11057 gen_helper_v7m_vlstm(cpu_env
, fptr
);
11059 tcg_temp_free_i32(fptr
);
11061 /* End the TB, because we have updated FP control bits */
11062 s
->base
.is_jmp
= DISAS_UPDATE
;
11066 if (arm_dc_feature(s
, ARM_FEATURE_VFP
) &&
11067 ((insn
>> 8) & 0xe) == 10) {
11068 /* FP, and the CPU supports it */
11069 if (disas_vfp_insn(s
, insn
)) {
11075 /* All other insns: NOCP */
11076 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
11077 default_exception_el(s
));
11080 if ((insn
& 0xfe000a00) == 0xfc000800
11081 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
11082 /* The Thumb2 and ARM encodings are identical. */
11083 if (disas_neon_insn_3same_ext(s
, insn
)) {
11086 } else if ((insn
& 0xff000a00) == 0xfe000800
11087 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
11088 /* The Thumb2 and ARM encodings are identical. */
11089 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
11092 } else if (((insn
>> 24) & 3) == 3) {
11093 /* Translate into the equivalent ARM encoding. */
11094 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
11095 if (disas_neon_data_insn(s
, insn
)) {
11098 } else if (((insn
>> 8) & 0xe) == 10) {
11099 if (disas_vfp_insn(s
, insn
)) {
11103 if (insn
& (1 << 28))
11105 if (disas_coproc_insn(s
, insn
)) {
11110 case 8: case 9: case 10: case 11:
11111 if (insn
& (1 << 15)) {
11112 /* Branches, misc control. */
11113 if (insn
& 0x5000) {
11114 /* Unconditional branch. */
11115 /* signextend(hw1[10:0]) -> offset[:12]. */
11116 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
11117 /* hw1[10:0] -> offset[11:1]. */
11118 offset
|= (insn
& 0x7ff) << 1;
11119 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11120 offset[24:22] already have the same value because of the
11121 sign extension above. */
11122 offset
^= ((~insn
) & (1 << 13)) << 10;
11123 offset
^= ((~insn
) & (1 << 11)) << 11;
11125 if (insn
& (1 << 14)) {
11126 /* Branch and link. */
11127 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
11131 if (insn
& (1 << 12)) {
11133 gen_jmp(s
, offset
);
11136 offset
&= ~(uint32_t)2;
11137 /* thumb2 bx, no need to check */
11138 gen_bx_im(s
, offset
);
11140 } else if (((insn
>> 23) & 7) == 7) {
11142 if (insn
& (1 << 13))
11145 if (insn
& (1 << 26)) {
11146 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11149 if (!(insn
& (1 << 20))) {
11150 /* Hypervisor call (v7) */
11151 int imm16
= extract32(insn
, 16, 4) << 12
11152 | extract32(insn
, 0, 12);
11159 /* Secure monitor call (v6+) */
11167 op
= (insn
>> 20) & 7;
11169 case 0: /* msr cpsr. */
11170 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11171 tmp
= load_reg(s
, rn
);
11172 /* the constant is the mask and SYSm fields */
11173 addr
= tcg_const_i32(insn
& 0xfff);
11174 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11175 tcg_temp_free_i32(addr
);
11176 tcg_temp_free_i32(tmp
);
11181 case 1: /* msr spsr. */
11182 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11186 if (extract32(insn
, 5, 1)) {
11188 int sysm
= extract32(insn
, 8, 4) |
11189 (extract32(insn
, 4, 1) << 4);
11192 gen_msr_banked(s
, r
, sysm
, rm
);
11196 /* MSR (for PSRs) */
11197 tmp
= load_reg(s
, rn
);
11199 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
11203 case 2: /* cps, nop-hint. */
11204 if (((insn
>> 8) & 7) == 0) {
11205 gen_nop_hint(s
, insn
& 0xff);
11207 /* Implemented as NOP in user mode. */
11212 if (insn
& (1 << 10)) {
11213 if (insn
& (1 << 7))
11215 if (insn
& (1 << 6))
11217 if (insn
& (1 << 5))
11219 if (insn
& (1 << 9))
11220 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
11222 if (insn
& (1 << 8)) {
11224 imm
|= (insn
& 0x1f);
11227 gen_set_psr_im(s
, offset
, 0, imm
);
11230 case 3: /* Special control operations. */
11231 if (!arm_dc_feature(s
, ARM_FEATURE_V7
) &&
11232 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11235 op
= (insn
>> 4) & 0xf;
11237 case 2: /* clrex */
11242 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
11245 /* We need to break the TB after this insn
11246 * to execute self-modifying code correctly
11247 * and also to take any pending interrupts
11250 gen_goto_tb(s
, 0, s
->pc
& ~1);
11253 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
11257 * TODO: There is no speculation barrier opcode
11258 * for TCG; MB and end the TB instead.
11260 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
11261 gen_goto_tb(s
, 0, s
->pc
& ~1);
11268 /* Trivial implementation equivalent to bx.
11269 * This instruction doesn't exist at all for M-profile.
11271 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11274 tmp
= load_reg(s
, rn
);
11277 case 5: /* Exception return. */
11281 if (rn
!= 14 || rd
!= 15) {
11284 if (s
->current_el
== 2) {
11285 /* ERET from Hyp uses ELR_Hyp, not LR */
11289 tmp
= load_cpu_field(elr_el
[2]);
11291 tmp
= load_reg(s
, rn
);
11292 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
11294 gen_exception_return(s
, tmp
);
11297 if (extract32(insn
, 5, 1) &&
11298 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11300 int sysm
= extract32(insn
, 16, 4) |
11301 (extract32(insn
, 4, 1) << 4);
11303 gen_mrs_banked(s
, 0, sysm
, rd
);
11307 if (extract32(insn
, 16, 4) != 0xf) {
11310 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
11311 extract32(insn
, 0, 8) != 0) {
11316 tmp
= tcg_temp_new_i32();
11317 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11318 addr
= tcg_const_i32(insn
& 0xff);
11319 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
11320 tcg_temp_free_i32(addr
);
11322 gen_helper_cpsr_read(tmp
, cpu_env
);
11324 store_reg(s
, rd
, tmp
);
11327 if (extract32(insn
, 5, 1) &&
11328 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11330 int sysm
= extract32(insn
, 16, 4) |
11331 (extract32(insn
, 4, 1) << 4);
11333 gen_mrs_banked(s
, 1, sysm
, rd
);
11338 /* Not accessible in user mode. */
11339 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
11343 if (extract32(insn
, 16, 4) != 0xf ||
11344 extract32(insn
, 0, 8) != 0) {
11348 tmp
= load_cpu_field(spsr
);
11349 store_reg(s
, rd
, tmp
);
11354 /* Conditional branch. */
11355 op
= (insn
>> 22) & 0xf;
11356 /* Generate a conditional jump to next instruction. */
11357 arm_skip_unless(s
, op
);
11359 /* offset[11:1] = insn[10:0] */
11360 offset
= (insn
& 0x7ff) << 1;
11361 /* offset[17:12] = insn[21:16]. */
11362 offset
|= (insn
& 0x003f0000) >> 4;
11363 /* offset[31:20] = insn[26]. */
11364 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
11365 /* offset[18] = insn[13]. */
11366 offset
|= (insn
& (1 << 13)) << 5;
11367 /* offset[19] = insn[11]. */
11368 offset
|= (insn
& (1 << 11)) << 8;
11370 /* jump to the offset */
11371 gen_jmp(s
, s
->pc
+ offset
);
11375 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11376 * - Data-processing (modified immediate, plain binary immediate)
11378 if (insn
& (1 << 25)) {
11380 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11381 * - Data-processing (plain binary immediate)
11383 if (insn
& (1 << 24)) {
11384 if (insn
& (1 << 20))
11386 /* Bitfield/Saturate. */
11387 op
= (insn
>> 21) & 7;
11389 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
11391 tmp
= tcg_temp_new_i32();
11392 tcg_gen_movi_i32(tmp
, 0);
11394 tmp
= load_reg(s
, rn
);
11397 case 2: /* Signed bitfield extract. */
11399 if (shift
+ imm
> 32)
11402 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
11405 case 6: /* Unsigned bitfield extract. */
11407 if (shift
+ imm
> 32)
11410 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
11413 case 3: /* Bitfield insert/clear. */
11416 imm
= imm
+ 1 - shift
;
11418 tmp2
= load_reg(s
, rd
);
11419 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
11420 tcg_temp_free_i32(tmp2
);
11425 default: /* Saturate. */
11428 tcg_gen_sari_i32(tmp
, tmp
, shift
);
11430 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11432 tmp2
= tcg_const_i32(imm
);
11435 if ((op
& 1) && shift
== 0) {
11436 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11437 tcg_temp_free_i32(tmp
);
11438 tcg_temp_free_i32(tmp2
);
11441 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
11443 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
11447 if ((op
& 1) && shift
== 0) {
11448 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11449 tcg_temp_free_i32(tmp
);
11450 tcg_temp_free_i32(tmp2
);
11453 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
11455 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
11458 tcg_temp_free_i32(tmp2
);
11461 store_reg(s
, rd
, tmp
);
11463 imm
= ((insn
& 0x04000000) >> 15)
11464 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
11465 if (insn
& (1 << 22)) {
11466 /* 16-bit immediate. */
11467 imm
|= (insn
>> 4) & 0xf000;
11468 if (insn
& (1 << 23)) {
11470 tmp
= load_reg(s
, rd
);
11471 tcg_gen_ext16u_i32(tmp
, tmp
);
11472 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
11475 tmp
= tcg_temp_new_i32();
11476 tcg_gen_movi_i32(tmp
, imm
);
11478 store_reg(s
, rd
, tmp
);
11480 /* Add/sub 12-bit immediate. */
11482 offset
= s
->pc
& ~(uint32_t)3;
11483 if (insn
& (1 << 23))
11487 tmp
= tcg_temp_new_i32();
11488 tcg_gen_movi_i32(tmp
, offset
);
11489 store_reg(s
, rd
, tmp
);
11491 tmp
= load_reg(s
, rn
);
11492 if (insn
& (1 << 23))
11493 tcg_gen_subi_i32(tmp
, tmp
, imm
);
11495 tcg_gen_addi_i32(tmp
, tmp
, imm
);
11496 if (rn
== 13 && rd
== 13) {
11497 /* ADD SP, SP, imm or SUB SP, SP, imm */
11498 store_sp_checked(s
, tmp
);
11500 store_reg(s
, rd
, tmp
);
11507 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11508 * - Data-processing (modified immediate)
11510 int shifter_out
= 0;
11511 /* modified 12-bit immediate. */
11512 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
11513 imm
= (insn
& 0xff);
11516 /* Nothing to do. */
11518 case 1: /* 00XY00XY */
11521 case 2: /* XY00XY00 */
11525 case 3: /* XYXYXYXY */
11529 default: /* Rotated constant. */
11530 shift
= (shift
<< 1) | (imm
>> 7);
11532 imm
= imm
<< (32 - shift
);
11536 tmp2
= tcg_temp_new_i32();
11537 tcg_gen_movi_i32(tmp2
, imm
);
11538 rn
= (insn
>> 16) & 0xf;
11540 tmp
= tcg_temp_new_i32();
11541 tcg_gen_movi_i32(tmp
, 0);
11543 tmp
= load_reg(s
, rn
);
11545 op
= (insn
>> 21) & 0xf;
11546 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
11547 shifter_out
, tmp
, tmp2
))
11549 tcg_temp_free_i32(tmp2
);
11550 rd
= (insn
>> 8) & 0xf;
11551 if (rd
== 13 && rn
== 13
11552 && (op
== 8 || op
== 13)) {
11553 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11554 store_sp_checked(s
, tmp
);
11555 } else if (rd
!= 15) {
11556 store_reg(s
, rd
, tmp
);
11558 tcg_temp_free_i32(tmp
);
11563 case 12: /* Load/store single data item. */
11570 if ((insn
& 0x01100000) == 0x01000000) {
11571 if (disas_neon_ls_insn(s
, insn
)) {
11576 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
11578 if (!(insn
& (1 << 20))) {
11582 /* Byte or halfword load space with dest == r15 : memory hints.
11583 * Catch them early so we don't emit pointless addressing code.
11584 * This space is a mix of:
11585 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11586 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11588 * unallocated hints, which must be treated as NOPs
11589 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11590 * which is easiest for the decoding logic
11591 * Some space which must UNDEF
11593 int op1
= (insn
>> 23) & 3;
11594 int op2
= (insn
>> 6) & 0x3f;
11599 /* UNPREDICTABLE, unallocated hint or
11600 * PLD/PLDW/PLI (literal)
11605 return; /* PLD/PLDW/PLI or unallocated hint */
11607 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
11608 return; /* PLD/PLDW/PLI or unallocated hint */
11610 /* UNDEF space, or an UNPREDICTABLE */
11614 memidx
= get_mem_index(s
);
11616 addr
= tcg_temp_new_i32();
11618 /* s->pc has already been incremented by 4. */
11619 imm
= s
->pc
& 0xfffffffc;
11620 if (insn
& (1 << 23))
11621 imm
+= insn
& 0xfff;
11623 imm
-= insn
& 0xfff;
11624 tcg_gen_movi_i32(addr
, imm
);
11626 addr
= load_reg(s
, rn
);
11627 if (insn
& (1 << 23)) {
11628 /* Positive offset. */
11629 imm
= insn
& 0xfff;
11630 tcg_gen_addi_i32(addr
, addr
, imm
);
11633 switch ((insn
>> 8) & 0xf) {
11634 case 0x0: /* Shifted Register. */
11635 shift
= (insn
>> 4) & 0xf;
11637 tcg_temp_free_i32(addr
);
11640 tmp
= load_reg(s
, rm
);
11642 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11643 tcg_gen_add_i32(addr
, addr
, tmp
);
11644 tcg_temp_free_i32(tmp
);
11646 case 0xc: /* Negative offset. */
11647 tcg_gen_addi_i32(addr
, addr
, -imm
);
11649 case 0xe: /* User privilege. */
11650 tcg_gen_addi_i32(addr
, addr
, imm
);
11651 memidx
= get_a32_user_mem_index(s
);
11653 case 0x9: /* Post-decrement. */
11655 /* Fall through. */
11656 case 0xb: /* Post-increment. */
11660 case 0xd: /* Pre-decrement. */
11662 /* Fall through. */
11663 case 0xf: /* Pre-increment. */
11667 tcg_temp_free_i32(addr
);
11673 issinfo
= writeback
? ISSInvalid
: rs
;
11675 if (s
->v8m_stackcheck
&& rn
== 13 && writeback
) {
11677 * Stackcheck. Here we know 'addr' is the current SP;
11678 * if imm is +ve we're moving SP up, else down. It is
11679 * UNKNOWN whether the limit check triggers when SP starts
11680 * below the limit and ends up above it; we chose to do so.
11682 if ((int32_t)imm
< 0) {
11683 TCGv_i32 newsp
= tcg_temp_new_i32();
11685 tcg_gen_addi_i32(newsp
, addr
, imm
);
11686 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
11687 tcg_temp_free_i32(newsp
);
11689 gen_helper_v8m_stackcheck(cpu_env
, addr
);
11693 if (writeback
&& !postinc
) {
11694 tcg_gen_addi_i32(addr
, addr
, imm
);
11697 if (insn
& (1 << 20)) {
11699 tmp
= tcg_temp_new_i32();
11702 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11705 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11708 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11711 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11714 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11717 tcg_temp_free_i32(tmp
);
11718 tcg_temp_free_i32(addr
);
11722 gen_bx_excret(s
, tmp
);
11724 store_reg(s
, rs
, tmp
);
11728 tmp
= load_reg(s
, rs
);
11731 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
11734 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
11737 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
11740 tcg_temp_free_i32(tmp
);
11741 tcg_temp_free_i32(addr
);
11744 tcg_temp_free_i32(tmp
);
11747 tcg_gen_addi_i32(addr
, addr
, imm
);
11749 store_reg(s
, rn
, addr
);
11751 tcg_temp_free_i32(addr
);
11760 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11761 default_exception_el(s
));
11764 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
11766 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
11773 switch (insn
>> 12) {
11777 op
= (insn
>> 11) & 3;
11780 * 0b0001_1xxx_xxxx_xxxx
11781 * - Add, subtract (three low registers)
11782 * - Add, subtract (two low registers and immediate)
11784 rn
= (insn
>> 3) & 7;
11785 tmp
= load_reg(s
, rn
);
11786 if (insn
& (1 << 10)) {
11788 tmp2
= tcg_temp_new_i32();
11789 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11792 rm
= (insn
>> 6) & 7;
11793 tmp2
= load_reg(s
, rm
);
11795 if (insn
& (1 << 9)) {
11796 if (s
->condexec_mask
)
11797 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11799 gen_sub_CC(tmp
, tmp
, tmp2
);
11801 if (s
->condexec_mask
)
11802 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11804 gen_add_CC(tmp
, tmp
, tmp2
);
11806 tcg_temp_free_i32(tmp2
);
11807 store_reg(s
, rd
, tmp
);
11809 /* shift immediate */
11810 rm
= (insn
>> 3) & 7;
11811 shift
= (insn
>> 6) & 0x1f;
11812 tmp
= load_reg(s
, rm
);
11813 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11814 if (!s
->condexec_mask
)
11816 store_reg(s
, rd
, tmp
);
11821 * 0b001x_xxxx_xxxx_xxxx
11822 * - Add, subtract, compare, move (one low register and immediate)
11824 op
= (insn
>> 11) & 3;
11825 rd
= (insn
>> 8) & 0x7;
11826 if (op
== 0) { /* mov */
11827 tmp
= tcg_temp_new_i32();
11828 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11829 if (!s
->condexec_mask
)
11831 store_reg(s
, rd
, tmp
);
11833 tmp
= load_reg(s
, rd
);
11834 tmp2
= tcg_temp_new_i32();
11835 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11838 gen_sub_CC(tmp
, tmp
, tmp2
);
11839 tcg_temp_free_i32(tmp
);
11840 tcg_temp_free_i32(tmp2
);
11843 if (s
->condexec_mask
)
11844 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11846 gen_add_CC(tmp
, tmp
, tmp2
);
11847 tcg_temp_free_i32(tmp2
);
11848 store_reg(s
, rd
, tmp
);
11851 if (s
->condexec_mask
)
11852 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11854 gen_sub_CC(tmp
, tmp
, tmp2
);
11855 tcg_temp_free_i32(tmp2
);
11856 store_reg(s
, rd
, tmp
);
11862 if (insn
& (1 << 11)) {
11863 rd
= (insn
>> 8) & 7;
11864 /* load pc-relative. Bit 1 of PC is ignored. */
11865 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11866 val
&= ~(uint32_t)2;
11867 addr
= tcg_temp_new_i32();
11868 tcg_gen_movi_i32(addr
, val
);
11869 tmp
= tcg_temp_new_i32();
11870 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11872 tcg_temp_free_i32(addr
);
11873 store_reg(s
, rd
, tmp
);
11876 if (insn
& (1 << 10)) {
11877 /* 0b0100_01xx_xxxx_xxxx
11878 * - data processing extended, branch and exchange
11880 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11881 rm
= (insn
>> 3) & 0xf;
11882 op
= (insn
>> 8) & 3;
11885 tmp
= load_reg(s
, rd
);
11886 tmp2
= load_reg(s
, rm
);
11887 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11888 tcg_temp_free_i32(tmp2
);
11890 /* ADD SP, SP, reg */
11891 store_sp_checked(s
, tmp
);
11893 store_reg(s
, rd
, tmp
);
11897 tmp
= load_reg(s
, rd
);
11898 tmp2
= load_reg(s
, rm
);
11899 gen_sub_CC(tmp
, tmp
, tmp2
);
11900 tcg_temp_free_i32(tmp2
);
11901 tcg_temp_free_i32(tmp
);
11903 case 2: /* mov/cpy */
11904 tmp
= load_reg(s
, rm
);
11907 store_sp_checked(s
, tmp
);
11909 store_reg(s
, rd
, tmp
);
11914 /* 0b0100_0111_xxxx_xxxx
11915 * - branch [and link] exchange thumb register
11917 bool link
= insn
& (1 << 7);
11926 /* BXNS/BLXNS: only exists for v8M with the
11927 * security extensions, and always UNDEF if NonSecure.
11928 * We don't implement these in the user-only mode
11929 * either (in theory you can use them from Secure User
11930 * mode but they are too tied in to system emulation.)
11932 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
11943 tmp
= load_reg(s
, rm
);
11945 val
= (uint32_t)s
->pc
| 1;
11946 tmp2
= tcg_temp_new_i32();
11947 tcg_gen_movi_i32(tmp2
, val
);
11948 store_reg(s
, 14, tmp2
);
11951 /* Only BX works as exception-return, not BLX */
11952 gen_bx_excret(s
, tmp
);
11961 * 0b0100_00xx_xxxx_xxxx
11962 * - Data-processing (two low registers)
11965 rm
= (insn
>> 3) & 7;
11966 op
= (insn
>> 6) & 0xf;
11967 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11968 /* the shift/rotate ops want the operands backwards */
11977 if (op
== 9) { /* neg */
11978 tmp
= tcg_temp_new_i32();
11979 tcg_gen_movi_i32(tmp
, 0);
11980 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11981 tmp
= load_reg(s
, rd
);
11986 tmp2
= load_reg(s
, rm
);
11988 case 0x0: /* and */
11989 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11990 if (!s
->condexec_mask
)
11993 case 0x1: /* eor */
11994 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11995 if (!s
->condexec_mask
)
11998 case 0x2: /* lsl */
11999 if (s
->condexec_mask
) {
12000 gen_shl(tmp2
, tmp2
, tmp
);
12002 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
12003 gen_logic_CC(tmp2
);
12006 case 0x3: /* lsr */
12007 if (s
->condexec_mask
) {
12008 gen_shr(tmp2
, tmp2
, tmp
);
12010 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
12011 gen_logic_CC(tmp2
);
12014 case 0x4: /* asr */
12015 if (s
->condexec_mask
) {
12016 gen_sar(tmp2
, tmp2
, tmp
);
12018 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
12019 gen_logic_CC(tmp2
);
12022 case 0x5: /* adc */
12023 if (s
->condexec_mask
) {
12024 gen_adc(tmp
, tmp2
);
12026 gen_adc_CC(tmp
, tmp
, tmp2
);
12029 case 0x6: /* sbc */
12030 if (s
->condexec_mask
) {
12031 gen_sub_carry(tmp
, tmp
, tmp2
);
12033 gen_sbc_CC(tmp
, tmp
, tmp2
);
12036 case 0x7: /* ror */
12037 if (s
->condexec_mask
) {
12038 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
12039 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
12041 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
12042 gen_logic_CC(tmp2
);
12045 case 0x8: /* tst */
12046 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
12050 case 0x9: /* neg */
12051 if (s
->condexec_mask
)
12052 tcg_gen_neg_i32(tmp
, tmp2
);
12054 gen_sub_CC(tmp
, tmp
, tmp2
);
12056 case 0xa: /* cmp */
12057 gen_sub_CC(tmp
, tmp
, tmp2
);
12060 case 0xb: /* cmn */
12061 gen_add_CC(tmp
, tmp
, tmp2
);
12064 case 0xc: /* orr */
12065 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
12066 if (!s
->condexec_mask
)
12069 case 0xd: /* mul */
12070 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
12071 if (!s
->condexec_mask
)
12074 case 0xe: /* bic */
12075 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
12076 if (!s
->condexec_mask
)
12079 case 0xf: /* mvn */
12080 tcg_gen_not_i32(tmp2
, tmp2
);
12081 if (!s
->condexec_mask
)
12082 gen_logic_CC(tmp2
);
12089 store_reg(s
, rm
, tmp2
);
12091 tcg_temp_free_i32(tmp
);
12093 store_reg(s
, rd
, tmp
);
12094 tcg_temp_free_i32(tmp2
);
12097 tcg_temp_free_i32(tmp
);
12098 tcg_temp_free_i32(tmp2
);
12103 /* load/store register offset. */
12105 rn
= (insn
>> 3) & 7;
12106 rm
= (insn
>> 6) & 7;
12107 op
= (insn
>> 9) & 7;
12108 addr
= load_reg(s
, rn
);
12109 tmp
= load_reg(s
, rm
);
12110 tcg_gen_add_i32(addr
, addr
, tmp
);
12111 tcg_temp_free_i32(tmp
);
12113 if (op
< 3) { /* store */
12114 tmp
= load_reg(s
, rd
);
12116 tmp
= tcg_temp_new_i32();
12121 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12124 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12127 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12129 case 3: /* ldrsb */
12130 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12133 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12136 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12139 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12141 case 7: /* ldrsh */
12142 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12145 if (op
>= 3) { /* load */
12146 store_reg(s
, rd
, tmp
);
12148 tcg_temp_free_i32(tmp
);
12150 tcg_temp_free_i32(addr
);
12154 /* load/store word immediate offset */
12156 rn
= (insn
>> 3) & 7;
12157 addr
= load_reg(s
, rn
);
12158 val
= (insn
>> 4) & 0x7c;
12159 tcg_gen_addi_i32(addr
, addr
, val
);
12161 if (insn
& (1 << 11)) {
12163 tmp
= tcg_temp_new_i32();
12164 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12165 store_reg(s
, rd
, tmp
);
12168 tmp
= load_reg(s
, rd
);
12169 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12170 tcg_temp_free_i32(tmp
);
12172 tcg_temp_free_i32(addr
);
12176 /* load/store byte immediate offset */
12178 rn
= (insn
>> 3) & 7;
12179 addr
= load_reg(s
, rn
);
12180 val
= (insn
>> 6) & 0x1f;
12181 tcg_gen_addi_i32(addr
, addr
, val
);
12183 if (insn
& (1 << 11)) {
12185 tmp
= tcg_temp_new_i32();
12186 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12187 store_reg(s
, rd
, tmp
);
12190 tmp
= load_reg(s
, rd
);
12191 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12192 tcg_temp_free_i32(tmp
);
12194 tcg_temp_free_i32(addr
);
12198 /* load/store halfword immediate offset */
12200 rn
= (insn
>> 3) & 7;
12201 addr
= load_reg(s
, rn
);
12202 val
= (insn
>> 5) & 0x3e;
12203 tcg_gen_addi_i32(addr
, addr
, val
);
12205 if (insn
& (1 << 11)) {
12207 tmp
= tcg_temp_new_i32();
12208 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12209 store_reg(s
, rd
, tmp
);
12212 tmp
= load_reg(s
, rd
);
12213 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12214 tcg_temp_free_i32(tmp
);
12216 tcg_temp_free_i32(addr
);
12220 /* load/store from stack */
12221 rd
= (insn
>> 8) & 7;
12222 addr
= load_reg(s
, 13);
12223 val
= (insn
& 0xff) * 4;
12224 tcg_gen_addi_i32(addr
, addr
, val
);
12226 if (insn
& (1 << 11)) {
12228 tmp
= tcg_temp_new_i32();
12229 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12230 store_reg(s
, rd
, tmp
);
12233 tmp
= load_reg(s
, rd
);
12234 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12235 tcg_temp_free_i32(tmp
);
12237 tcg_temp_free_i32(addr
);
12242 * 0b1010_xxxx_xxxx_xxxx
12243 * - Add PC/SP (immediate)
12245 rd
= (insn
>> 8) & 7;
12246 if (insn
& (1 << 11)) {
12248 tmp
= load_reg(s
, 13);
12250 /* PC. bit 1 is ignored. */
12251 tmp
= tcg_temp_new_i32();
12252 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
12254 val
= (insn
& 0xff) * 4;
12255 tcg_gen_addi_i32(tmp
, tmp
, val
);
12256 store_reg(s
, rd
, tmp
);
12261 op
= (insn
>> 8) & 0xf;
12265 * 0b1011_0000_xxxx_xxxx
12266 * - ADD (SP plus immediate)
12267 * - SUB (SP minus immediate)
12269 tmp
= load_reg(s
, 13);
12270 val
= (insn
& 0x7f) * 4;
12271 if (insn
& (1 << 7))
12272 val
= -(int32_t)val
;
12273 tcg_gen_addi_i32(tmp
, tmp
, val
);
12274 store_sp_checked(s
, tmp
);
12277 case 2: /* sign/zero extend. */
12280 rm
= (insn
>> 3) & 7;
12281 tmp
= load_reg(s
, rm
);
12282 switch ((insn
>> 6) & 3) {
12283 case 0: gen_sxth(tmp
); break;
12284 case 1: gen_sxtb(tmp
); break;
12285 case 2: gen_uxth(tmp
); break;
12286 case 3: gen_uxtb(tmp
); break;
12288 store_reg(s
, rd
, tmp
);
12290 case 4: case 5: case 0xc: case 0xd:
12292 * 0b1011_x10x_xxxx_xxxx
12295 addr
= load_reg(s
, 13);
12296 if (insn
& (1 << 8))
12300 for (i
= 0; i
< 8; i
++) {
12301 if (insn
& (1 << i
))
12304 if ((insn
& (1 << 11)) == 0) {
12305 tcg_gen_addi_i32(addr
, addr
, -offset
);
12308 if (s
->v8m_stackcheck
) {
12310 * Here 'addr' is the lower of "old SP" and "new SP";
12311 * if this is a pop that starts below the limit and ends
12312 * above it, it is UNKNOWN whether the limit check triggers;
12313 * we choose to trigger.
12315 gen_helper_v8m_stackcheck(cpu_env
, addr
);
12318 for (i
= 0; i
< 8; i
++) {
12319 if (insn
& (1 << i
)) {
12320 if (insn
& (1 << 11)) {
12322 tmp
= tcg_temp_new_i32();
12323 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12324 store_reg(s
, i
, tmp
);
12327 tmp
= load_reg(s
, i
);
12328 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12329 tcg_temp_free_i32(tmp
);
12331 /* advance to the next address. */
12332 tcg_gen_addi_i32(addr
, addr
, 4);
12336 if (insn
& (1 << 8)) {
12337 if (insn
& (1 << 11)) {
12339 tmp
= tcg_temp_new_i32();
12340 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12341 /* don't set the pc until the rest of the instruction
12345 tmp
= load_reg(s
, 14);
12346 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12347 tcg_temp_free_i32(tmp
);
12349 tcg_gen_addi_i32(addr
, addr
, 4);
12351 if ((insn
& (1 << 11)) == 0) {
12352 tcg_gen_addi_i32(addr
, addr
, -offset
);
12354 /* write back the new stack pointer */
12355 store_reg(s
, 13, addr
);
12356 /* set the new PC value */
12357 if ((insn
& 0x0900) == 0x0900) {
12358 store_reg_from_load(s
, 15, tmp
);
12362 case 1: case 3: case 9: case 11: /* czb */
12364 tmp
= load_reg(s
, rm
);
12365 arm_gen_condlabel(s
);
12366 if (insn
& (1 << 11))
12367 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
12369 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
12370 tcg_temp_free_i32(tmp
);
12371 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
12372 val
= (uint32_t)s
->pc
+ 2;
12377 case 15: /* IT, nop-hint. */
12378 if ((insn
& 0xf) == 0) {
12379 gen_nop_hint(s
, (insn
>> 4) & 0xf);
12383 s
->condexec_cond
= (insn
>> 4) & 0xe;
12384 s
->condexec_mask
= insn
& 0x1f;
12385 /* No actual code generated for this insn, just setup state. */
12388 case 0xe: /* bkpt */
12390 int imm8
= extract32(insn
, 0, 8);
12392 gen_exception_bkpt_insn(s
, 2, syn_aa32_bkpt(imm8
, true));
12396 case 0xa: /* rev, and hlt */
12398 int op1
= extract32(insn
, 6, 2);
12402 int imm6
= extract32(insn
, 0, 6);
12408 /* Otherwise this is rev */
12410 rn
= (insn
>> 3) & 0x7;
12412 tmp
= load_reg(s
, rn
);
12414 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
12415 case 1: gen_rev16(tmp
); break;
12416 case 3: gen_revsh(tmp
); break;
12418 g_assert_not_reached();
12420 store_reg(s
, rd
, tmp
);
12425 switch ((insn
>> 5) & 7) {
12429 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
12430 gen_helper_setend(cpu_env
);
12431 s
->base
.is_jmp
= DISAS_UPDATE
;
12440 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
12441 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
12444 addr
= tcg_const_i32(19);
12445 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12446 tcg_temp_free_i32(addr
);
12450 addr
= tcg_const_i32(16);
12451 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12452 tcg_temp_free_i32(addr
);
12454 tcg_temp_free_i32(tmp
);
12457 if (insn
& (1 << 4)) {
12458 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
12462 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
12477 /* load/store multiple */
12478 TCGv_i32 loaded_var
= NULL
;
12479 rn
= (insn
>> 8) & 0x7;
12480 addr
= load_reg(s
, rn
);
12481 for (i
= 0; i
< 8; i
++) {
12482 if (insn
& (1 << i
)) {
12483 if (insn
& (1 << 11)) {
12485 tmp
= tcg_temp_new_i32();
12486 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12490 store_reg(s
, i
, tmp
);
12494 tmp
= load_reg(s
, i
);
12495 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12496 tcg_temp_free_i32(tmp
);
12498 /* advance to the next address */
12499 tcg_gen_addi_i32(addr
, addr
, 4);
12502 if ((insn
& (1 << rn
)) == 0) {
12503 /* base reg not in list: base register writeback */
12504 store_reg(s
, rn
, addr
);
12506 /* base reg in list: if load, complete it now */
12507 if (insn
& (1 << 11)) {
12508 store_reg(s
, rn
, loaded_var
);
12510 tcg_temp_free_i32(addr
);
12515 /* conditional branch or swi */
12516 cond
= (insn
>> 8) & 0xf;
12522 gen_set_pc_im(s
, s
->pc
);
12523 s
->svc_imm
= extract32(insn
, 0, 8);
12524 s
->base
.is_jmp
= DISAS_SWI
;
12527 /* generate a conditional jump to next instruction */
12528 arm_skip_unless(s
, cond
);
12530 /* jump to the offset */
12531 val
= (uint32_t)s
->pc
+ 2;
12532 offset
= ((int32_t)insn
<< 24) >> 24;
12533 val
+= offset
<< 1;
12538 if (insn
& (1 << 11)) {
12539 /* thumb_insn_is_16bit() ensures we can't get here for
12540 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12541 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12543 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12545 offset
= ((insn
& 0x7ff) << 1);
12546 tmp
= load_reg(s
, 14);
12547 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12548 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
12550 tmp2
= tcg_temp_new_i32();
12551 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12552 store_reg(s
, 14, tmp2
);
12556 /* unconditional branch */
12557 val
= (uint32_t)s
->pc
;
12558 offset
= ((int32_t)insn
<< 21) >> 21;
12559 val
+= (offset
<< 1) + 2;
12564 /* thumb_insn_is_16bit() ensures we can't get here for
12565 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12567 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12569 if (insn
& (1 << 11)) {
12570 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12571 offset
= ((insn
& 0x7ff) << 1) | 1;
12572 tmp
= load_reg(s
, 14);
12573 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12575 tmp2
= tcg_temp_new_i32();
12576 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12577 store_reg(s
, 14, tmp2
);
12580 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12581 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
12583 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
12590 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
12591 default_exception_el(s
));
12594 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
12596 /* Return true if the insn at dc->pc might cross a page boundary.
12597 * (False positives are OK, false negatives are not.)
12598 * We know this is a Thumb insn, and our caller ensures we are
12599 * only called if dc->pc is less than 4 bytes from the page
12600 * boundary, so we cross the page if the first 16 bits indicate
12601 * that this is a 32 bit insn.
12603 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
12605 return !thumb_insn_is_16bit(s
, insn
);
12608 static void arm_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
12610 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12611 CPUARMState
*env
= cs
->env_ptr
;
12612 ARMCPU
*cpu
= env_archcpu(env
);
12613 uint32_t tb_flags
= dc
->base
.tb
->flags
;
12614 uint32_t condexec
, core_mmu_idx
;
12616 dc
->isar
= &cpu
->isar
;
12617 dc
->pc
= dc
->base
.pc_first
;
12621 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12622 * there is no secure EL1, so we route exceptions to EL3.
12624 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
12625 !arm_el_is_aa64(env
, 3);
12626 dc
->thumb
= FIELD_EX32(tb_flags
, TBFLAG_A32
, THUMB
);
12627 dc
->sctlr_b
= FIELD_EX32(tb_flags
, TBFLAG_A32
, SCTLR_B
);
12628 dc
->be_data
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, BE_DATA
) ? MO_BE
: MO_LE
;
12629 condexec
= FIELD_EX32(tb_flags
, TBFLAG_A32
, CONDEXEC
);
12630 dc
->condexec_mask
= (condexec
& 0xf) << 1;
12631 dc
->condexec_cond
= condexec
>> 4;
12632 core_mmu_idx
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, MMUIDX
);
12633 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, core_mmu_idx
);
12634 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
12635 #if !defined(CONFIG_USER_ONLY)
12636 dc
->user
= (dc
->current_el
== 0);
12638 dc
->ns
= FIELD_EX32(tb_flags
, TBFLAG_A32
, NS
);
12639 dc
->fp_excp_el
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, FPEXC_EL
);
12640 dc
->vfp_enabled
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VFPEN
);
12641 dc
->vec_len
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECLEN
);
12642 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
12643 dc
->c15_cpar
= FIELD_EX32(tb_flags
, TBFLAG_A32
, XSCALE_CPAR
);
12644 dc
->vec_stride
= 0;
12646 dc
->vec_stride
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECSTRIDE
);
12649 dc
->v7m_handler_mode
= FIELD_EX32(tb_flags
, TBFLAG_A32
, HANDLER
);
12650 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
12651 regime_is_secure(env
, dc
->mmu_idx
);
12652 dc
->v8m_stackcheck
= FIELD_EX32(tb_flags
, TBFLAG_A32
, STACKCHECK
);
12653 dc
->v8m_fpccr_s_wrong
= FIELD_EX32(tb_flags
, TBFLAG_A32
, FPCCR_S_WRONG
);
12654 dc
->v7m_new_fp_ctxt_needed
=
12655 FIELD_EX32(tb_flags
, TBFLAG_A32
, NEW_FP_CTXT_NEEDED
);
12656 dc
->v7m_lspact
= FIELD_EX32(tb_flags
, TBFLAG_A32
, LSPACT
);
12657 dc
->cp_regs
= cpu
->cp_regs
;
12658 dc
->features
= env
->features
;
12660 /* Single step state. The code-generation logic here is:
12662 * generate code with no special handling for single-stepping (except
12663 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12664 * this happens anyway because those changes are all system register or
12666 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12667 * emit code for one insn
12668 * emit code to clear PSTATE.SS
12669 * emit code to generate software step exception for completed step
12670 * end TB (as usual for having generated an exception)
12671 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12672 * emit code to generate a software step exception
12675 dc
->ss_active
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, SS_ACTIVE
);
12676 dc
->pstate_ss
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, PSTATE_SS
);
12677 dc
->is_ldex
= false;
12678 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
12680 dc
->page_start
= dc
->base
.pc_first
& TARGET_PAGE_MASK
;
12682 /* If architectural single step active, limit to 1. */
12683 if (is_singlestepping(dc
)) {
12684 dc
->base
.max_insns
= 1;
12687 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12688 to those left on the page. */
12690 int bound
= -(dc
->base
.pc_first
| TARGET_PAGE_MASK
) / 4;
12691 dc
->base
.max_insns
= MIN(dc
->base
.max_insns
, bound
);
12694 cpu_F0s
= tcg_temp_new_i32();
12695 cpu_F1s
= tcg_temp_new_i32();
12696 cpu_F0d
= tcg_temp_new_i64();
12697 cpu_F1d
= tcg_temp_new_i64();
12700 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12701 cpu_M0
= tcg_temp_new_i64();
12704 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12706 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12708 /* A note on handling of the condexec (IT) bits:
12710 * We want to avoid the overhead of having to write the updated condexec
12711 * bits back to the CPUARMState for every instruction in an IT block. So:
12712 * (1) if the condexec bits are not already zero then we write
12713 * zero back into the CPUARMState now. This avoids complications trying
12714 * to do it at the end of the block. (For example if we don't do this
12715 * it's hard to identify whether we can safely skip writing condexec
12716 * at the end of the TB, which we definitely want to do for the case
12717 * where a TB doesn't do anything with the IT state at all.)
12718 * (2) if we are going to leave the TB then we call gen_set_condexec()
12719 * which will write the correct value into CPUARMState if zero is wrong.
12720 * This is done both for leaving the TB at the end, and for leaving
12721 * it because of an exception we know will happen, which is done in
12722 * gen_exception_insn(). The latter is necessary because we need to
12723 * leave the TB with the PC/IT state just prior to execution of the
12724 * instruction which caused the exception.
12725 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12726 * then the CPUARMState will be wrong and we need to reset it.
12727 * This is handled in the same way as restoration of the
12728 * PC in these situations; we save the value of the condexec bits
12729 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12730 * then uses this to restore them after an exception.
12732 * Note that there are no instructions which can read the condexec
12733 * bits, and none which can write non-static values to them, so
12734 * we don't need to care about whether CPUARMState is correct in the
12738 /* Reset the conditional execution bits immediately. This avoids
12739 complications trying to do it at the end of the block. */
12740 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
12741 TCGv_i32 tmp
= tcg_temp_new_i32();
12742 tcg_gen_movi_i32(tmp
, 0);
12743 store_cpu_field(tmp
, condexec_bits
);
12747 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12749 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12751 tcg_gen_insn_start(dc
->pc
,
12752 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
12754 dc
->insn_start
= tcg_last_op();
12757 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
12758 const CPUBreakpoint
*bp
)
12760 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12762 if (bp
->flags
& BP_CPU
) {
12763 gen_set_condexec(dc
);
12764 gen_set_pc_im(dc
, dc
->pc
);
12765 gen_helper_check_breakpoints(cpu_env
);
12766 /* End the TB early; it's likely not going to be executed */
12767 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12769 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
12770 /* The address covered by the breakpoint must be
12771 included in [tb->pc, tb->pc + tb->size) in order
12772 to for it to be properly cleared -- thus we
12773 increment the PC here so that the logic setting
12774 tb->size below does the right thing. */
12775 /* TODO: Advance PC by correct instruction length to
12776 * avoid disassembler error messages */
12778 dc
->base
.is_jmp
= DISAS_NORETURN
;
12784 static bool arm_pre_translate_insn(DisasContext
*dc
)
12786 #ifdef CONFIG_USER_ONLY
12787 /* Intercept jump to the magic kernel page. */
12788 if (dc
->pc
>= 0xffff0000) {
12789 /* We always get here via a jump, so know we are not in a
12790 conditional execution block. */
12791 gen_exception_internal(EXCP_KERNEL_TRAP
);
12792 dc
->base
.is_jmp
= DISAS_NORETURN
;
12797 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12798 /* Singlestep state is Active-pending.
12799 * If we're in this state at the start of a TB then either
12800 * a) we just took an exception to an EL which is being debugged
12801 * and this is the first insn in the exception handler
12802 * b) debug exceptions were masked and we just unmasked them
12803 * without changing EL (eg by clearing PSTATE.D)
12804 * In either case we're going to take a swstep exception in the
12805 * "did not step an insn" case, and so the syndrome ISV and EX
12806 * bits should be zero.
12808 assert(dc
->base
.num_insns
== 1);
12809 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
12810 default_exception_el(dc
));
12811 dc
->base
.is_jmp
= DISAS_NORETURN
;
12818 static void arm_post_translate_insn(DisasContext
*dc
)
12820 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12821 gen_set_label(dc
->condlabel
);
12824 dc
->base
.pc_next
= dc
->pc
;
12825 translator_loop_temp_check(&dc
->base
);
12828 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12830 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12831 CPUARMState
*env
= cpu
->env_ptr
;
12834 if (arm_pre_translate_insn(dc
)) {
12838 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12841 disas_arm_insn(dc
, insn
);
12843 arm_post_translate_insn(dc
);
12845 /* ARM is a fixed-length ISA. We performed the cross-page check
12846 in init_disas_context by adjusting max_insns. */
12849 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
12851 /* Return true if this Thumb insn is always unconditional,
12852 * even inside an IT block. This is true of only a very few
12853 * instructions: BKPT, HLT, and SG.
12855 * A larger class of instructions are UNPREDICTABLE if used
12856 * inside an IT block; we do not need to detect those here, because
12857 * what we do by default (perform the cc check and update the IT
12858 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12859 * choice for those situations.
12861 * insn is either a 16-bit or a 32-bit instruction; the two are
12862 * distinguishable because for the 16-bit case the top 16 bits
12863 * are zeroes, and that isn't a valid 32-bit encoding.
12865 if ((insn
& 0xffffff00) == 0xbe00) {
12870 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12871 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
12872 /* HLT: v8A only. This is unconditional even when it is going to
12873 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12874 * For v7 cores this was a plain old undefined encoding and so
12875 * honours its cc check. (We might be using the encoding as
12876 * a semihosting trap, but we don't change the cc check behaviour
12877 * on that account, because a debugger connected to a real v7A
12878 * core and emulating semihosting traps by catching the UNDEF
12879 * exception would also only see cases where the cc check passed.
12880 * No guest code should be trying to do a HLT semihosting trap
12881 * in an IT block anyway.
12886 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12887 arm_dc_feature(s
, ARM_FEATURE_M
)) {
12895 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12897 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12898 CPUARMState
*env
= cpu
->env_ptr
;
12902 if (arm_pre_translate_insn(dc
)) {
12906 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12907 is_16bit
= thumb_insn_is_16bit(dc
, insn
);
12910 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12912 insn
= insn
<< 16 | insn2
;
12917 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
12918 uint32_t cond
= dc
->condexec_cond
;
12920 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
12921 arm_skip_unless(dc
, cond
);
12926 disas_thumb_insn(dc
, insn
);
12928 disas_thumb2_insn(dc
, insn
);
12931 /* Advance the Thumb condexec condition. */
12932 if (dc
->condexec_mask
) {
12933 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
12934 ((dc
->condexec_mask
>> 4) & 1));
12935 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12936 if (dc
->condexec_mask
== 0) {
12937 dc
->condexec_cond
= 0;
12941 arm_post_translate_insn(dc
);
12943 /* Thumb is a variable-length ISA. Stop translation when the next insn
12944 * will touch a new page. This ensures that prefetch aborts occur at
12947 * We want to stop the TB if the next insn starts in a new page,
12948 * or if it spans between this page and the next. This means that
12949 * if we're looking at the last halfword in the page we need to
12950 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12951 * or a 32-bit Thumb insn (which won't).
12952 * This is to avoid generating a silly TB with a single 16-bit insn
12953 * in it at the end of this page (which would execute correctly
12954 * but isn't very efficient).
12956 if (dc
->base
.is_jmp
== DISAS_NEXT
12957 && (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
12958 || (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
- 3
12959 && insn_crosses_page(env
, dc
)))) {
12960 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12964 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
12966 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12968 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
12969 /* FIXME: This can theoretically happen with self-modifying code. */
12970 cpu_abort(cpu
, "IO on conditional branch instruction");
12973 /* At this stage dc->condjmp will only be set when the skipped
12974 instruction was a conditional branch or trap, and the PC has
12975 already been written. */
12976 gen_set_condexec(dc
);
12977 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12978 /* Exception return branches need some special case code at the
12979 * end of the TB, which is complex enough that it has to
12980 * handle the single-step vs not and the condition-failed
12981 * insn codepath itself.
12983 gen_bx_excret_final_code(dc
);
12984 } else if (unlikely(is_singlestepping(dc
))) {
12985 /* Unconditional and "condition passed" instruction codepath. */
12986 switch (dc
->base
.is_jmp
) {
12988 gen_ss_advance(dc
);
12989 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12990 default_exception_el(dc
));
12993 gen_ss_advance(dc
);
12994 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12997 gen_ss_advance(dc
);
12998 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
13001 case DISAS_TOO_MANY
:
13003 gen_set_pc_im(dc
, dc
->pc
);
13006 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
13007 gen_singlestep_exception(dc
);
13009 case DISAS_NORETURN
:
13013 /* While branches must always occur at the end of an IT block,
13014 there are a few other things that can cause us to terminate
13015 the TB in the middle of an IT block:
13016 - Exception generating instructions (bkpt, swi, undefined).
13018 - Hardware watchpoints.
13019 Hardware breakpoints have already been handled and skip this code.
13021 switch(dc
->base
.is_jmp
) {
13023 case DISAS_TOO_MANY
:
13024 gen_goto_tb(dc
, 1, dc
->pc
);
13030 gen_set_pc_im(dc
, dc
->pc
);
13033 /* indicate that the hash table must be used to find the next TB */
13034 tcg_gen_exit_tb(NULL
, 0);
13036 case DISAS_NORETURN
:
13037 /* nothing more to generate */
13041 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
13042 !(dc
->insn
& (1U << 31))) ? 2 : 4);
13044 gen_helper_wfi(cpu_env
, tmp
);
13045 tcg_temp_free_i32(tmp
);
13046 /* The helper doesn't necessarily throw an exception, but we
13047 * must go back to the main loop to check for interrupts anyway.
13049 tcg_gen_exit_tb(NULL
, 0);
13053 gen_helper_wfe(cpu_env
);
13056 gen_helper_yield(cpu_env
);
13059 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
13060 default_exception_el(dc
));
13063 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
13066 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
13072 /* "Condition failed" instruction codepath for the branch/trap insn */
13073 gen_set_label(dc
->condlabel
);
13074 gen_set_condexec(dc
);
13075 if (unlikely(is_singlestepping(dc
))) {
13076 gen_set_pc_im(dc
, dc
->pc
);
13077 gen_singlestep_exception(dc
);
13079 gen_goto_tb(dc
, 1, dc
->pc
);
13083 /* Functions above can change dc->pc, so re-align db->pc_next */
13084 dc
->base
.pc_next
= dc
->pc
;
13087 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
13089 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
13091 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
13092 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
13095 static const TranslatorOps arm_translator_ops
= {
13096 .init_disas_context
= arm_tr_init_disas_context
,
13097 .tb_start
= arm_tr_tb_start
,
13098 .insn_start
= arm_tr_insn_start
,
13099 .breakpoint_check
= arm_tr_breakpoint_check
,
13100 .translate_insn
= arm_tr_translate_insn
,
13101 .tb_stop
= arm_tr_tb_stop
,
13102 .disas_log
= arm_tr_disas_log
,
13105 static const TranslatorOps thumb_translator_ops
= {
13106 .init_disas_context
= arm_tr_init_disas_context
,
13107 .tb_start
= arm_tr_tb_start
,
13108 .insn_start
= arm_tr_insn_start
,
13109 .breakpoint_check
= arm_tr_breakpoint_check
,
13110 .translate_insn
= thumb_tr_translate_insn
,
13111 .tb_stop
= arm_tr_tb_stop
,
13112 .disas_log
= arm_tr_disas_log
,
13115 /* generate intermediate code for basic block 'tb'. */
13116 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
13119 const TranslatorOps
*ops
= &arm_translator_ops
;
13121 if (FIELD_EX32(tb
->flags
, TBFLAG_A32
, THUMB
)) {
13122 ops
= &thumb_translator_ops
;
13124 #ifdef TARGET_AARCH64
13125 if (FIELD_EX32(tb
->flags
, TBFLAG_ANY
, AARCH64_STATE
)) {
13126 ops
= &aarch64_translator_ops
;
13130 translator_loop(ops
, &dc
.base
, cpu
, tb
, max_insns
);
13133 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
13135 ARMCPU
*cpu
= ARM_CPU(cs
);
13136 CPUARMState
*env
= &cpu
->env
;
13140 aarch64_cpu_dump_state(cs
, f
, flags
);
13144 for(i
=0;i
<16;i
++) {
13145 qemu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
13147 qemu_fprintf(f
, "\n");
13149 qemu_fprintf(f
, " ");
13152 if (arm_feature(env
, ARM_FEATURE_M
)) {
13153 uint32_t xpsr
= xpsr_read(env
);
13155 const char *ns_status
= "";
13157 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
13158 ns_status
= env
->v7m
.secure
? "S " : "NS ";
13161 if (xpsr
& XPSR_EXCP
) {
13164 if (env
->v7m
.control
[env
->v7m
.secure
] & R_V7M_CONTROL_NPRIV_MASK
) {
13165 mode
= "unpriv-thread";
13167 mode
= "priv-thread";
13171 qemu_fprintf(f
, "XPSR=%08x %c%c%c%c %c %s%s\n",
13173 xpsr
& XPSR_N
? 'N' : '-',
13174 xpsr
& XPSR_Z
? 'Z' : '-',
13175 xpsr
& XPSR_C
? 'C' : '-',
13176 xpsr
& XPSR_V
? 'V' : '-',
13177 xpsr
& XPSR_T
? 'T' : 'A',
13181 uint32_t psr
= cpsr_read(env
);
13182 const char *ns_status
= "";
13184 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
13185 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
13186 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
13189 qemu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13191 psr
& CPSR_N
? 'N' : '-',
13192 psr
& CPSR_Z
? 'Z' : '-',
13193 psr
& CPSR_C
? 'C' : '-',
13194 psr
& CPSR_V
? 'V' : '-',
13195 psr
& CPSR_T
? 'T' : 'A',
13197 aarch32_mode_name(psr
), (psr
& 0x10) ? 32 : 26);
13200 if (flags
& CPU_DUMP_FPU
) {
13201 int numvfpregs
= 0;
13202 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
13205 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
13208 for (i
= 0; i
< numvfpregs
; i
++) {
13209 uint64_t v
= *aa32_vfp_dreg(env
, i
);
13210 qemu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
13211 i
* 2, (uint32_t)v
,
13212 i
* 2 + 1, (uint32_t)(v
>> 32),
13215 qemu_fprintf(f
, "FPSCR: %08x\n", vfp_get_fpscr(env
));
13219 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
13220 target_ulong
*data
)
13224 env
->condexec_bits
= 0;
13225 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
13227 env
->regs
[15] = data
[0];
13228 env
->condexec_bits
= data
[1];
13229 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;