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 void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1528 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1530 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1534 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1537 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1539 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1543 static inline long vfp_reg_offset(bool dp
, unsigned reg
)
1546 return offsetof(CPUARMState
, vfp
.zregs
[reg
>> 1].d
[reg
& 1]);
1548 long ofs
= offsetof(CPUARMState
, vfp
.zregs
[reg
>> 2].d
[(reg
>> 1) & 1]);
1550 ofs
+= offsetof(CPU_DoubleU
, l
.upper
);
1552 ofs
+= offsetof(CPU_DoubleU
, l
.lower
);
1558 /* Return the offset of a 32-bit piece of a NEON register.
1559 zero is the least significant end of the register. */
1561 neon_reg_offset (int reg
, int n
)
1565 return vfp_reg_offset(0, sreg
);
1568 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1569 * where 0 is the least significant end of the register.
1572 neon_element_offset(int reg
, int element
, TCGMemOp size
)
1574 int element_size
= 1 << size
;
1575 int ofs
= element
* element_size
;
1576 #ifdef HOST_WORDS_BIGENDIAN
1577 /* Calculate the offset assuming fully little-endian,
1578 * then XOR to account for the order of the 8-byte units.
1580 if (element_size
< 8) {
1581 ofs
^= 8 - element_size
;
1584 return neon_reg_offset(reg
, 0) + ofs
;
1587 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1589 TCGv_i32 tmp
= tcg_temp_new_i32();
1590 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1594 static void neon_load_element(TCGv_i32 var
, int reg
, int ele
, TCGMemOp mop
)
1596 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1600 tcg_gen_ld8u_i32(var
, cpu_env
, offset
);
1603 tcg_gen_ld16u_i32(var
, cpu_env
, offset
);
1606 tcg_gen_ld_i32(var
, cpu_env
, offset
);
1609 g_assert_not_reached();
1613 static void neon_load_element64(TCGv_i64 var
, int reg
, int ele
, TCGMemOp mop
)
1615 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1619 tcg_gen_ld8u_i64(var
, cpu_env
, offset
);
1622 tcg_gen_ld16u_i64(var
, cpu_env
, offset
);
1625 tcg_gen_ld32u_i64(var
, cpu_env
, offset
);
1628 tcg_gen_ld_i64(var
, cpu_env
, offset
);
1631 g_assert_not_reached();
1635 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1637 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1638 tcg_temp_free_i32(var
);
1641 static void neon_store_element(int reg
, int ele
, TCGMemOp size
, TCGv_i32 var
)
1643 long offset
= neon_element_offset(reg
, ele
, size
);
1647 tcg_gen_st8_i32(var
, cpu_env
, offset
);
1650 tcg_gen_st16_i32(var
, cpu_env
, offset
);
1653 tcg_gen_st_i32(var
, cpu_env
, offset
);
1656 g_assert_not_reached();
1660 static void neon_store_element64(int reg
, int ele
, TCGMemOp size
, TCGv_i64 var
)
1662 long offset
= neon_element_offset(reg
, ele
, size
);
1666 tcg_gen_st8_i64(var
, cpu_env
, offset
);
1669 tcg_gen_st16_i64(var
, cpu_env
, offset
);
1672 tcg_gen_st32_i64(var
, cpu_env
, offset
);
1675 tcg_gen_st_i64(var
, cpu_env
, offset
);
1678 g_assert_not_reached();
1682 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1684 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1687 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1689 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1692 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1694 TCGv_ptr ret
= tcg_temp_new_ptr();
1695 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1699 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1700 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1701 #define tcg_gen_st_f32 tcg_gen_st_i32
1702 #define tcg_gen_st_f64 tcg_gen_st_i64
1704 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1707 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1709 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1712 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1715 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1717 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1720 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1723 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1725 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1728 #define ARM_CP_RW_BIT (1 << 20)
1730 /* Include the VFP decoder */
1731 #include "translate-vfp.inc.c"
1733 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1735 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1738 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1740 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1743 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1745 TCGv_i32 var
= tcg_temp_new_i32();
1746 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1750 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1752 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1753 tcg_temp_free_i32(var
);
1756 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1758 iwmmxt_store_reg(cpu_M0
, rn
);
1761 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1763 iwmmxt_load_reg(cpu_M0
, rn
);
1766 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1768 iwmmxt_load_reg(cpu_V1
, rn
);
1769 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1772 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1774 iwmmxt_load_reg(cpu_V1
, rn
);
1775 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1778 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1780 iwmmxt_load_reg(cpu_V1
, rn
);
1781 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1784 #define IWMMXT_OP(name) \
1785 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1787 iwmmxt_load_reg(cpu_V1, rn); \
1788 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1791 #define IWMMXT_OP_ENV(name) \
1792 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1794 iwmmxt_load_reg(cpu_V1, rn); \
1795 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1798 #define IWMMXT_OP_ENV_SIZE(name) \
1799 IWMMXT_OP_ENV(name##b) \
1800 IWMMXT_OP_ENV(name##w) \
1801 IWMMXT_OP_ENV(name##l)
1803 #define IWMMXT_OP_ENV1(name) \
1804 static inline void gen_op_iwmmxt_##name##_M0(void) \
1806 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1820 IWMMXT_OP_ENV_SIZE(unpackl
)
1821 IWMMXT_OP_ENV_SIZE(unpackh
)
1823 IWMMXT_OP_ENV1(unpacklub
)
1824 IWMMXT_OP_ENV1(unpackluw
)
1825 IWMMXT_OP_ENV1(unpacklul
)
1826 IWMMXT_OP_ENV1(unpackhub
)
1827 IWMMXT_OP_ENV1(unpackhuw
)
1828 IWMMXT_OP_ENV1(unpackhul
)
1829 IWMMXT_OP_ENV1(unpacklsb
)
1830 IWMMXT_OP_ENV1(unpacklsw
)
1831 IWMMXT_OP_ENV1(unpacklsl
)
1832 IWMMXT_OP_ENV1(unpackhsb
)
1833 IWMMXT_OP_ENV1(unpackhsw
)
1834 IWMMXT_OP_ENV1(unpackhsl
)
1836 IWMMXT_OP_ENV_SIZE(cmpeq
)
1837 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1838 IWMMXT_OP_ENV_SIZE(cmpgts
)
1840 IWMMXT_OP_ENV_SIZE(mins
)
1841 IWMMXT_OP_ENV_SIZE(minu
)
1842 IWMMXT_OP_ENV_SIZE(maxs
)
1843 IWMMXT_OP_ENV_SIZE(maxu
)
1845 IWMMXT_OP_ENV_SIZE(subn
)
1846 IWMMXT_OP_ENV_SIZE(addn
)
1847 IWMMXT_OP_ENV_SIZE(subu
)
1848 IWMMXT_OP_ENV_SIZE(addu
)
1849 IWMMXT_OP_ENV_SIZE(subs
)
1850 IWMMXT_OP_ENV_SIZE(adds
)
1852 IWMMXT_OP_ENV(avgb0
)
1853 IWMMXT_OP_ENV(avgb1
)
1854 IWMMXT_OP_ENV(avgw0
)
1855 IWMMXT_OP_ENV(avgw1
)
1857 IWMMXT_OP_ENV(packuw
)
1858 IWMMXT_OP_ENV(packul
)
1859 IWMMXT_OP_ENV(packuq
)
1860 IWMMXT_OP_ENV(packsw
)
1861 IWMMXT_OP_ENV(packsl
)
1862 IWMMXT_OP_ENV(packsq
)
1864 static void gen_op_iwmmxt_set_mup(void)
1867 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1868 tcg_gen_ori_i32(tmp
, tmp
, 2);
1869 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1872 static void gen_op_iwmmxt_set_cup(void)
1875 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1876 tcg_gen_ori_i32(tmp
, tmp
, 1);
1877 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1880 static void gen_op_iwmmxt_setpsr_nz(void)
1882 TCGv_i32 tmp
= tcg_temp_new_i32();
1883 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1884 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1887 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1889 iwmmxt_load_reg(cpu_V1
, rn
);
1890 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1891 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1894 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1901 rd
= (insn
>> 16) & 0xf;
1902 tmp
= load_reg(s
, rd
);
1904 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1905 if (insn
& (1 << 24)) {
1907 if (insn
& (1 << 23))
1908 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1910 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1911 tcg_gen_mov_i32(dest
, tmp
);
1912 if (insn
& (1 << 21))
1913 store_reg(s
, rd
, tmp
);
1915 tcg_temp_free_i32(tmp
);
1916 } else if (insn
& (1 << 21)) {
1918 tcg_gen_mov_i32(dest
, tmp
);
1919 if (insn
& (1 << 23))
1920 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1922 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1923 store_reg(s
, rd
, tmp
);
1924 } else if (!(insn
& (1 << 23)))
1929 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1931 int rd
= (insn
>> 0) & 0xf;
1934 if (insn
& (1 << 8)) {
1935 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1938 tmp
= iwmmxt_load_creg(rd
);
1941 tmp
= tcg_temp_new_i32();
1942 iwmmxt_load_reg(cpu_V0
, rd
);
1943 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1945 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1946 tcg_gen_mov_i32(dest
, tmp
);
1947 tcg_temp_free_i32(tmp
);
1951 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1952 (ie. an undefined instruction). */
1953 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1956 int rdhi
, rdlo
, rd0
, rd1
, i
;
1958 TCGv_i32 tmp
, tmp2
, tmp3
;
1960 if ((insn
& 0x0e000e00) == 0x0c000000) {
1961 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1963 rdlo
= (insn
>> 12) & 0xf;
1964 rdhi
= (insn
>> 16) & 0xf;
1965 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1966 iwmmxt_load_reg(cpu_V0
, wrd
);
1967 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1968 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1969 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1970 } else { /* TMCRR */
1971 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1972 iwmmxt_store_reg(cpu_V0
, wrd
);
1973 gen_op_iwmmxt_set_mup();
1978 wrd
= (insn
>> 12) & 0xf;
1979 addr
= tcg_temp_new_i32();
1980 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1981 tcg_temp_free_i32(addr
);
1984 if (insn
& ARM_CP_RW_BIT
) {
1985 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1986 tmp
= tcg_temp_new_i32();
1987 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1988 iwmmxt_store_creg(wrd
, tmp
);
1991 if (insn
& (1 << 8)) {
1992 if (insn
& (1 << 22)) { /* WLDRD */
1993 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1995 } else { /* WLDRW wRd */
1996 tmp
= tcg_temp_new_i32();
1997 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2000 tmp
= tcg_temp_new_i32();
2001 if (insn
& (1 << 22)) { /* WLDRH */
2002 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2003 } else { /* WLDRB */
2004 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2008 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
2009 tcg_temp_free_i32(tmp
);
2011 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2014 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
2015 tmp
= iwmmxt_load_creg(wrd
);
2016 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
2018 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2019 tmp
= tcg_temp_new_i32();
2020 if (insn
& (1 << 8)) {
2021 if (insn
& (1 << 22)) { /* WSTRD */
2022 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
2023 } else { /* WSTRW wRd */
2024 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2025 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
2028 if (insn
& (1 << 22)) { /* WSTRH */
2029 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2030 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
2031 } else { /* WSTRB */
2032 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2033 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
2037 tcg_temp_free_i32(tmp
);
2039 tcg_temp_free_i32(addr
);
2043 if ((insn
& 0x0f000000) != 0x0e000000)
2046 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
2047 case 0x000: /* WOR */
2048 wrd
= (insn
>> 12) & 0xf;
2049 rd0
= (insn
>> 0) & 0xf;
2050 rd1
= (insn
>> 16) & 0xf;
2051 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2052 gen_op_iwmmxt_orq_M0_wRn(rd1
);
2053 gen_op_iwmmxt_setpsr_nz();
2054 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2055 gen_op_iwmmxt_set_mup();
2056 gen_op_iwmmxt_set_cup();
2058 case 0x011: /* TMCR */
2061 rd
= (insn
>> 12) & 0xf;
2062 wrd
= (insn
>> 16) & 0xf;
2064 case ARM_IWMMXT_wCID
:
2065 case ARM_IWMMXT_wCASF
:
2067 case ARM_IWMMXT_wCon
:
2068 gen_op_iwmmxt_set_cup();
2070 case ARM_IWMMXT_wCSSF
:
2071 tmp
= iwmmxt_load_creg(wrd
);
2072 tmp2
= load_reg(s
, rd
);
2073 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
2074 tcg_temp_free_i32(tmp2
);
2075 iwmmxt_store_creg(wrd
, tmp
);
2077 case ARM_IWMMXT_wCGR0
:
2078 case ARM_IWMMXT_wCGR1
:
2079 case ARM_IWMMXT_wCGR2
:
2080 case ARM_IWMMXT_wCGR3
:
2081 gen_op_iwmmxt_set_cup();
2082 tmp
= load_reg(s
, rd
);
2083 iwmmxt_store_creg(wrd
, tmp
);
2089 case 0x100: /* WXOR */
2090 wrd
= (insn
>> 12) & 0xf;
2091 rd0
= (insn
>> 0) & 0xf;
2092 rd1
= (insn
>> 16) & 0xf;
2093 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2094 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
2095 gen_op_iwmmxt_setpsr_nz();
2096 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2097 gen_op_iwmmxt_set_mup();
2098 gen_op_iwmmxt_set_cup();
2100 case 0x111: /* TMRC */
2103 rd
= (insn
>> 12) & 0xf;
2104 wrd
= (insn
>> 16) & 0xf;
2105 tmp
= iwmmxt_load_creg(wrd
);
2106 store_reg(s
, rd
, tmp
);
2108 case 0x300: /* WANDN */
2109 wrd
= (insn
>> 12) & 0xf;
2110 rd0
= (insn
>> 0) & 0xf;
2111 rd1
= (insn
>> 16) & 0xf;
2112 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2113 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
2114 gen_op_iwmmxt_andq_M0_wRn(rd1
);
2115 gen_op_iwmmxt_setpsr_nz();
2116 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2117 gen_op_iwmmxt_set_mup();
2118 gen_op_iwmmxt_set_cup();
2120 case 0x200: /* WAND */
2121 wrd
= (insn
>> 12) & 0xf;
2122 rd0
= (insn
>> 0) & 0xf;
2123 rd1
= (insn
>> 16) & 0xf;
2124 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2125 gen_op_iwmmxt_andq_M0_wRn(rd1
);
2126 gen_op_iwmmxt_setpsr_nz();
2127 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2128 gen_op_iwmmxt_set_mup();
2129 gen_op_iwmmxt_set_cup();
2131 case 0x810: case 0xa10: /* WMADD */
2132 wrd
= (insn
>> 12) & 0xf;
2133 rd0
= (insn
>> 0) & 0xf;
2134 rd1
= (insn
>> 16) & 0xf;
2135 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2136 if (insn
& (1 << 21))
2137 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
2139 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
2140 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2141 gen_op_iwmmxt_set_mup();
2143 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2144 wrd
= (insn
>> 12) & 0xf;
2145 rd0
= (insn
>> 16) & 0xf;
2146 rd1
= (insn
>> 0) & 0xf;
2147 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2148 switch ((insn
>> 22) & 3) {
2150 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
2153 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
2156 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
2161 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2162 gen_op_iwmmxt_set_mup();
2163 gen_op_iwmmxt_set_cup();
2165 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2166 wrd
= (insn
>> 12) & 0xf;
2167 rd0
= (insn
>> 16) & 0xf;
2168 rd1
= (insn
>> 0) & 0xf;
2169 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2170 switch ((insn
>> 22) & 3) {
2172 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
2175 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
2178 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
2183 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2184 gen_op_iwmmxt_set_mup();
2185 gen_op_iwmmxt_set_cup();
2187 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2188 wrd
= (insn
>> 12) & 0xf;
2189 rd0
= (insn
>> 16) & 0xf;
2190 rd1
= (insn
>> 0) & 0xf;
2191 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2192 if (insn
& (1 << 22))
2193 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2195 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2196 if (!(insn
& (1 << 20)))
2197 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2198 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2199 gen_op_iwmmxt_set_mup();
2201 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2202 wrd
= (insn
>> 12) & 0xf;
2203 rd0
= (insn
>> 16) & 0xf;
2204 rd1
= (insn
>> 0) & 0xf;
2205 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2206 if (insn
& (1 << 21)) {
2207 if (insn
& (1 << 20))
2208 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2210 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2212 if (insn
& (1 << 20))
2213 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2215 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2217 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2218 gen_op_iwmmxt_set_mup();
2220 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2221 wrd
= (insn
>> 12) & 0xf;
2222 rd0
= (insn
>> 16) & 0xf;
2223 rd1
= (insn
>> 0) & 0xf;
2224 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2225 if (insn
& (1 << 21))
2226 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2228 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2229 if (!(insn
& (1 << 20))) {
2230 iwmmxt_load_reg(cpu_V1
, wrd
);
2231 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2233 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2234 gen_op_iwmmxt_set_mup();
2236 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2237 wrd
= (insn
>> 12) & 0xf;
2238 rd0
= (insn
>> 16) & 0xf;
2239 rd1
= (insn
>> 0) & 0xf;
2240 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2241 switch ((insn
>> 22) & 3) {
2243 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2246 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2249 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2254 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2255 gen_op_iwmmxt_set_mup();
2256 gen_op_iwmmxt_set_cup();
2258 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2259 wrd
= (insn
>> 12) & 0xf;
2260 rd0
= (insn
>> 16) & 0xf;
2261 rd1
= (insn
>> 0) & 0xf;
2262 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2263 if (insn
& (1 << 22)) {
2264 if (insn
& (1 << 20))
2265 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2267 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2269 if (insn
& (1 << 20))
2270 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2272 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2274 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2275 gen_op_iwmmxt_set_mup();
2276 gen_op_iwmmxt_set_cup();
2278 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2279 wrd
= (insn
>> 12) & 0xf;
2280 rd0
= (insn
>> 16) & 0xf;
2281 rd1
= (insn
>> 0) & 0xf;
2282 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2283 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2284 tcg_gen_andi_i32(tmp
, tmp
, 7);
2285 iwmmxt_load_reg(cpu_V1
, rd1
);
2286 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2287 tcg_temp_free_i32(tmp
);
2288 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2289 gen_op_iwmmxt_set_mup();
2291 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2292 if (((insn
>> 6) & 3) == 3)
2294 rd
= (insn
>> 12) & 0xf;
2295 wrd
= (insn
>> 16) & 0xf;
2296 tmp
= load_reg(s
, rd
);
2297 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2298 switch ((insn
>> 6) & 3) {
2300 tmp2
= tcg_const_i32(0xff);
2301 tmp3
= tcg_const_i32((insn
& 7) << 3);
2304 tmp2
= tcg_const_i32(0xffff);
2305 tmp3
= tcg_const_i32((insn
& 3) << 4);
2308 tmp2
= tcg_const_i32(0xffffffff);
2309 tmp3
= tcg_const_i32((insn
& 1) << 5);
2315 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2316 tcg_temp_free_i32(tmp3
);
2317 tcg_temp_free_i32(tmp2
);
2318 tcg_temp_free_i32(tmp
);
2319 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2320 gen_op_iwmmxt_set_mup();
2322 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2323 rd
= (insn
>> 12) & 0xf;
2324 wrd
= (insn
>> 16) & 0xf;
2325 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2327 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2328 tmp
= tcg_temp_new_i32();
2329 switch ((insn
>> 22) & 3) {
2331 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2332 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2334 tcg_gen_ext8s_i32(tmp
, tmp
);
2336 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2340 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2341 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2343 tcg_gen_ext16s_i32(tmp
, tmp
);
2345 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2349 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2350 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2353 store_reg(s
, rd
, tmp
);
2355 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2356 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2358 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2359 switch ((insn
>> 22) & 3) {
2361 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2364 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2367 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2370 tcg_gen_shli_i32(tmp
, tmp
, 28);
2372 tcg_temp_free_i32(tmp
);
2374 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2375 if (((insn
>> 6) & 3) == 3)
2377 rd
= (insn
>> 12) & 0xf;
2378 wrd
= (insn
>> 16) & 0xf;
2379 tmp
= load_reg(s
, rd
);
2380 switch ((insn
>> 6) & 3) {
2382 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2385 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2388 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2391 tcg_temp_free_i32(tmp
);
2392 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2393 gen_op_iwmmxt_set_mup();
2395 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2396 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2398 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2399 tmp2
= tcg_temp_new_i32();
2400 tcg_gen_mov_i32(tmp2
, tmp
);
2401 switch ((insn
>> 22) & 3) {
2403 for (i
= 0; i
< 7; i
++) {
2404 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2405 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2409 for (i
= 0; i
< 3; i
++) {
2410 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2411 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2415 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2416 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2420 tcg_temp_free_i32(tmp2
);
2421 tcg_temp_free_i32(tmp
);
2423 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2424 wrd
= (insn
>> 12) & 0xf;
2425 rd0
= (insn
>> 16) & 0xf;
2426 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2427 switch ((insn
>> 22) & 3) {
2429 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2432 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2435 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2440 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2441 gen_op_iwmmxt_set_mup();
2443 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2444 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2446 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2447 tmp2
= tcg_temp_new_i32();
2448 tcg_gen_mov_i32(tmp2
, tmp
);
2449 switch ((insn
>> 22) & 3) {
2451 for (i
= 0; i
< 7; i
++) {
2452 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2453 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2457 for (i
= 0; i
< 3; i
++) {
2458 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2459 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2463 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2464 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2468 tcg_temp_free_i32(tmp2
);
2469 tcg_temp_free_i32(tmp
);
2471 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2472 rd
= (insn
>> 12) & 0xf;
2473 rd0
= (insn
>> 16) & 0xf;
2474 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2476 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2477 tmp
= tcg_temp_new_i32();
2478 switch ((insn
>> 22) & 3) {
2480 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2483 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2486 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2489 store_reg(s
, rd
, tmp
);
2491 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2492 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2493 wrd
= (insn
>> 12) & 0xf;
2494 rd0
= (insn
>> 16) & 0xf;
2495 rd1
= (insn
>> 0) & 0xf;
2496 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2497 switch ((insn
>> 22) & 3) {
2499 if (insn
& (1 << 21))
2500 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2502 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2505 if (insn
& (1 << 21))
2506 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2508 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2511 if (insn
& (1 << 21))
2512 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2514 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2519 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2520 gen_op_iwmmxt_set_mup();
2521 gen_op_iwmmxt_set_cup();
2523 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2524 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2525 wrd
= (insn
>> 12) & 0xf;
2526 rd0
= (insn
>> 16) & 0xf;
2527 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2528 switch ((insn
>> 22) & 3) {
2530 if (insn
& (1 << 21))
2531 gen_op_iwmmxt_unpacklsb_M0();
2533 gen_op_iwmmxt_unpacklub_M0();
2536 if (insn
& (1 << 21))
2537 gen_op_iwmmxt_unpacklsw_M0();
2539 gen_op_iwmmxt_unpackluw_M0();
2542 if (insn
& (1 << 21))
2543 gen_op_iwmmxt_unpacklsl_M0();
2545 gen_op_iwmmxt_unpacklul_M0();
2550 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2551 gen_op_iwmmxt_set_mup();
2552 gen_op_iwmmxt_set_cup();
2554 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2555 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2556 wrd
= (insn
>> 12) & 0xf;
2557 rd0
= (insn
>> 16) & 0xf;
2558 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2559 switch ((insn
>> 22) & 3) {
2561 if (insn
& (1 << 21))
2562 gen_op_iwmmxt_unpackhsb_M0();
2564 gen_op_iwmmxt_unpackhub_M0();
2567 if (insn
& (1 << 21))
2568 gen_op_iwmmxt_unpackhsw_M0();
2570 gen_op_iwmmxt_unpackhuw_M0();
2573 if (insn
& (1 << 21))
2574 gen_op_iwmmxt_unpackhsl_M0();
2576 gen_op_iwmmxt_unpackhul_M0();
2581 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2582 gen_op_iwmmxt_set_mup();
2583 gen_op_iwmmxt_set_cup();
2585 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2586 case 0x214: case 0x614: case 0xa14: case 0xe14:
2587 if (((insn
>> 22) & 3) == 0)
2589 wrd
= (insn
>> 12) & 0xf;
2590 rd0
= (insn
>> 16) & 0xf;
2591 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2592 tmp
= tcg_temp_new_i32();
2593 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2594 tcg_temp_free_i32(tmp
);
2597 switch ((insn
>> 22) & 3) {
2599 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2602 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2605 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2608 tcg_temp_free_i32(tmp
);
2609 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2610 gen_op_iwmmxt_set_mup();
2611 gen_op_iwmmxt_set_cup();
2613 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2614 case 0x014: case 0x414: case 0x814: case 0xc14:
2615 if (((insn
>> 22) & 3) == 0)
2617 wrd
= (insn
>> 12) & 0xf;
2618 rd0
= (insn
>> 16) & 0xf;
2619 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2620 tmp
= tcg_temp_new_i32();
2621 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2622 tcg_temp_free_i32(tmp
);
2625 switch ((insn
>> 22) & 3) {
2627 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2630 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2633 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2636 tcg_temp_free_i32(tmp
);
2637 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2638 gen_op_iwmmxt_set_mup();
2639 gen_op_iwmmxt_set_cup();
2641 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2642 case 0x114: case 0x514: case 0x914: case 0xd14:
2643 if (((insn
>> 22) & 3) == 0)
2645 wrd
= (insn
>> 12) & 0xf;
2646 rd0
= (insn
>> 16) & 0xf;
2647 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2648 tmp
= tcg_temp_new_i32();
2649 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2650 tcg_temp_free_i32(tmp
);
2653 switch ((insn
>> 22) & 3) {
2655 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2658 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2661 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2664 tcg_temp_free_i32(tmp
);
2665 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2666 gen_op_iwmmxt_set_mup();
2667 gen_op_iwmmxt_set_cup();
2669 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2670 case 0x314: case 0x714: case 0xb14: case 0xf14:
2671 if (((insn
>> 22) & 3) == 0)
2673 wrd
= (insn
>> 12) & 0xf;
2674 rd0
= (insn
>> 16) & 0xf;
2675 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2676 tmp
= tcg_temp_new_i32();
2677 switch ((insn
>> 22) & 3) {
2679 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2680 tcg_temp_free_i32(tmp
);
2683 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2686 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2687 tcg_temp_free_i32(tmp
);
2690 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2693 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2694 tcg_temp_free_i32(tmp
);
2697 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2700 tcg_temp_free_i32(tmp
);
2701 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2702 gen_op_iwmmxt_set_mup();
2703 gen_op_iwmmxt_set_cup();
2705 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2706 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2707 wrd
= (insn
>> 12) & 0xf;
2708 rd0
= (insn
>> 16) & 0xf;
2709 rd1
= (insn
>> 0) & 0xf;
2710 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2711 switch ((insn
>> 22) & 3) {
2713 if (insn
& (1 << 21))
2714 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2716 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2719 if (insn
& (1 << 21))
2720 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2722 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2725 if (insn
& (1 << 21))
2726 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2728 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2733 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2734 gen_op_iwmmxt_set_mup();
2736 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2737 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2738 wrd
= (insn
>> 12) & 0xf;
2739 rd0
= (insn
>> 16) & 0xf;
2740 rd1
= (insn
>> 0) & 0xf;
2741 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2742 switch ((insn
>> 22) & 3) {
2744 if (insn
& (1 << 21))
2745 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2747 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2750 if (insn
& (1 << 21))
2751 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2753 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2756 if (insn
& (1 << 21))
2757 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2759 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2764 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2765 gen_op_iwmmxt_set_mup();
2767 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2768 case 0x402: case 0x502: case 0x602: case 0x702:
2769 wrd
= (insn
>> 12) & 0xf;
2770 rd0
= (insn
>> 16) & 0xf;
2771 rd1
= (insn
>> 0) & 0xf;
2772 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2773 tmp
= tcg_const_i32((insn
>> 20) & 3);
2774 iwmmxt_load_reg(cpu_V1
, rd1
);
2775 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2776 tcg_temp_free_i32(tmp
);
2777 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2778 gen_op_iwmmxt_set_mup();
2780 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2781 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2782 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2783 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2784 wrd
= (insn
>> 12) & 0xf;
2785 rd0
= (insn
>> 16) & 0xf;
2786 rd1
= (insn
>> 0) & 0xf;
2787 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2788 switch ((insn
>> 20) & 0xf) {
2790 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2793 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2796 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2799 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2802 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2805 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2808 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2811 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2814 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2819 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2820 gen_op_iwmmxt_set_mup();
2821 gen_op_iwmmxt_set_cup();
2823 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2824 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2825 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2826 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2827 wrd
= (insn
>> 12) & 0xf;
2828 rd0
= (insn
>> 16) & 0xf;
2829 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2830 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2831 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2832 tcg_temp_free_i32(tmp
);
2833 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2834 gen_op_iwmmxt_set_mup();
2835 gen_op_iwmmxt_set_cup();
2837 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2838 case 0x418: case 0x518: case 0x618: case 0x718:
2839 case 0x818: case 0x918: case 0xa18: case 0xb18:
2840 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2841 wrd
= (insn
>> 12) & 0xf;
2842 rd0
= (insn
>> 16) & 0xf;
2843 rd1
= (insn
>> 0) & 0xf;
2844 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2845 switch ((insn
>> 20) & 0xf) {
2847 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2850 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2853 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2856 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2859 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2862 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2865 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2868 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2871 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2876 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2877 gen_op_iwmmxt_set_mup();
2878 gen_op_iwmmxt_set_cup();
2880 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2881 case 0x408: case 0x508: case 0x608: case 0x708:
2882 case 0x808: case 0x908: case 0xa08: case 0xb08:
2883 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2884 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2886 wrd
= (insn
>> 12) & 0xf;
2887 rd0
= (insn
>> 16) & 0xf;
2888 rd1
= (insn
>> 0) & 0xf;
2889 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2890 switch ((insn
>> 22) & 3) {
2892 if (insn
& (1 << 21))
2893 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2895 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2898 if (insn
& (1 << 21))
2899 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2901 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2904 if (insn
& (1 << 21))
2905 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2907 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2910 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2911 gen_op_iwmmxt_set_mup();
2912 gen_op_iwmmxt_set_cup();
2914 case 0x201: case 0x203: case 0x205: case 0x207:
2915 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2916 case 0x211: case 0x213: case 0x215: case 0x217:
2917 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2918 wrd
= (insn
>> 5) & 0xf;
2919 rd0
= (insn
>> 12) & 0xf;
2920 rd1
= (insn
>> 0) & 0xf;
2921 if (rd0
== 0xf || rd1
== 0xf)
2923 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2924 tmp
= load_reg(s
, rd0
);
2925 tmp2
= load_reg(s
, rd1
);
2926 switch ((insn
>> 16) & 0xf) {
2927 case 0x0: /* TMIA */
2928 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2930 case 0x8: /* TMIAPH */
2931 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2933 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2934 if (insn
& (1 << 16))
2935 tcg_gen_shri_i32(tmp
, tmp
, 16);
2936 if (insn
& (1 << 17))
2937 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2938 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2941 tcg_temp_free_i32(tmp2
);
2942 tcg_temp_free_i32(tmp
);
2945 tcg_temp_free_i32(tmp2
);
2946 tcg_temp_free_i32(tmp
);
2947 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2948 gen_op_iwmmxt_set_mup();
2957 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2958 (ie. an undefined instruction). */
2959 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2961 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2964 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2965 /* Multiply with Internal Accumulate Format */
2966 rd0
= (insn
>> 12) & 0xf;
2968 acc
= (insn
>> 5) & 7;
2973 tmp
= load_reg(s
, rd0
);
2974 tmp2
= load_reg(s
, rd1
);
2975 switch ((insn
>> 16) & 0xf) {
2977 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2979 case 0x8: /* MIAPH */
2980 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2982 case 0xc: /* MIABB */
2983 case 0xd: /* MIABT */
2984 case 0xe: /* MIATB */
2985 case 0xf: /* MIATT */
2986 if (insn
& (1 << 16))
2987 tcg_gen_shri_i32(tmp
, tmp
, 16);
2988 if (insn
& (1 << 17))
2989 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2990 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2995 tcg_temp_free_i32(tmp2
);
2996 tcg_temp_free_i32(tmp
);
2998 gen_op_iwmmxt_movq_wRn_M0(acc
);
3002 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
3003 /* Internal Accumulator Access Format */
3004 rdhi
= (insn
>> 16) & 0xf;
3005 rdlo
= (insn
>> 12) & 0xf;
3011 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
3012 iwmmxt_load_reg(cpu_V0
, acc
);
3013 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
3014 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
3015 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
3016 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
3018 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
3019 iwmmxt_store_reg(cpu_V0
, acc
);
3027 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
3028 #define VFP_SREG(insn, bigbit, smallbit) \
3029 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
3030 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
3031 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
3032 reg = (((insn) >> (bigbit)) & 0x0f) \
3033 | (((insn) >> ((smallbit) - 4)) & 0x10); \
3035 if (insn & (1 << (smallbit))) \
3037 reg = ((insn) >> (bigbit)) & 0x0f; \
3040 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
3041 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
3042 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
3043 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
3044 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
3045 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
3047 /* Move between integer and VFP cores. */
3048 static TCGv_i32
gen_vfp_mrs(void)
3050 TCGv_i32 tmp
= tcg_temp_new_i32();
3051 tcg_gen_mov_i32(tmp
, cpu_F0s
);
3055 static void gen_vfp_msr(TCGv_i32 tmp
)
3057 tcg_gen_mov_i32(cpu_F0s
, tmp
);
3058 tcg_temp_free_i32(tmp
);
3061 static void gen_neon_dup_low16(TCGv_i32 var
)
3063 TCGv_i32 tmp
= tcg_temp_new_i32();
3064 tcg_gen_ext16u_i32(var
, var
);
3065 tcg_gen_shli_i32(tmp
, var
, 16);
3066 tcg_gen_or_i32(var
, var
, tmp
);
3067 tcg_temp_free_i32(tmp
);
3070 static void gen_neon_dup_high16(TCGv_i32 var
)
3072 TCGv_i32 tmp
= tcg_temp_new_i32();
3073 tcg_gen_andi_i32(var
, var
, 0xffff0000);
3074 tcg_gen_shri_i32(tmp
, var
, 16);
3075 tcg_gen_or_i32(var
, var
, tmp
);
3076 tcg_temp_free_i32(tmp
);
3080 * Disassemble a VFP instruction. Returns nonzero if an error occurred
3081 * (ie. an undefined instruction).
3083 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3085 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3090 bool ignore_vfp_enabled
= false;
3092 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3097 * If the decodetree decoder handles this insn it will always
3098 * emit code to either execute the insn or generate an appropriate
3099 * exception; so we don't need to ever return non-zero to tell
3100 * the calling code to emit an UNDEF exception.
3102 if (extract32(insn
, 28, 4) == 0xf) {
3103 if (disas_vfp_uncond(s
, insn
)) {
3107 if (disas_vfp(s
, insn
)) {
3112 if (extract32(insn
, 28, 4) == 0xf) {
3114 * Encodings with T=1 (Thumb) or unconditional (ARM): these
3115 * were all handled by the decodetree decoder, so any insn
3116 * patterns which get here must be UNDEF.
3122 * FIXME: this access check should not take precedence over UNDEF
3123 * for invalid encodings; we will generate incorrect syndrome information
3124 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3126 if ((insn
& 0x0fe00fff) == 0x0ee00a10) {
3127 rn
= (insn
>> 16) & 0xf;
3128 if (rn
== ARM_VFP_FPSID
|| rn
== ARM_VFP_FPEXC
|| rn
== ARM_VFP_MVFR2
3129 || rn
== ARM_VFP_MVFR1
|| rn
== ARM_VFP_MVFR0
) {
3130 ignore_vfp_enabled
= true;
3133 if (!full_vfp_access_check(s
, ignore_vfp_enabled
)) {
3137 dp
= ((insn
& 0xf00) == 0xb00);
3138 switch ((insn
>> 24) & 0xf) {
3140 if (insn
& (1 << 4)) {
3141 /* single register transfer */
3142 rd
= (insn
>> 12) & 0xf;
3147 VFP_DREG_N(rn
, insn
);
3150 if (insn
& 0x00c00060
3151 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3155 pass
= (insn
>> 21) & 1;
3156 if (insn
& (1 << 22)) {
3158 offset
= ((insn
>> 5) & 3) * 8;
3159 } else if (insn
& (1 << 5)) {
3161 offset
= (insn
& (1 << 6)) ? 16 : 0;
3166 if (insn
& ARM_CP_RW_BIT
) {
3168 tmp
= neon_load_reg(rn
, pass
);
3172 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3173 if (insn
& (1 << 23))
3179 if (insn
& (1 << 23)) {
3181 tcg_gen_shri_i32(tmp
, tmp
, 16);
3187 tcg_gen_sari_i32(tmp
, tmp
, 16);
3196 store_reg(s
, rd
, tmp
);
3199 tmp
= load_reg(s
, rd
);
3200 if (insn
& (1 << 23)) {
3202 int vec_size
= pass
? 16 : 8;
3203 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rn
, 0),
3204 vec_size
, vec_size
, tmp
);
3205 tcg_temp_free_i32(tmp
);
3210 tmp2
= neon_load_reg(rn
, pass
);
3211 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3212 tcg_temp_free_i32(tmp2
);
3215 tmp2
= neon_load_reg(rn
, pass
);
3216 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3217 tcg_temp_free_i32(tmp2
);
3222 neon_store_reg(rn
, pass
, tmp
);
3228 if ((insn
& 0x6f) != 0x00)
3230 rn
= VFP_SREG_N(insn
);
3232 is_sysreg
= extract32(insn
, 21, 1);
3234 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
3236 * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
3237 * Writes to R15 are UNPREDICTABLE; we choose to undef.
3239 if (is_sysreg
&& (rd
== 15 || (rn
>> 1) != ARM_VFP_FPSCR
)) {
3244 if (insn
& ARM_CP_RW_BIT
) {
3247 /* system register */
3252 /* VFP2 allows access to FSID from userspace.
3253 VFP3 restricts all id registers to privileged
3256 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3259 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3264 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3266 case ARM_VFP_FPINST
:
3267 case ARM_VFP_FPINST2
:
3268 /* Not present in VFP3. */
3270 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3273 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3277 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3278 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3280 tmp
= tcg_temp_new_i32();
3281 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3285 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3292 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3295 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3301 gen_mov_F0_vreg(0, rn
);
3302 tmp
= gen_vfp_mrs();
3305 /* Set the 4 flag bits in the CPSR. */
3307 tcg_temp_free_i32(tmp
);
3309 store_reg(s
, rd
, tmp
);
3315 /* system register */
3320 /* Writes are ignored. */
3323 tmp
= load_reg(s
, rd
);
3324 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3325 tcg_temp_free_i32(tmp
);
3331 /* TODO: VFP subarchitecture support.
3332 * For now, keep the EN bit only */
3333 tmp
= load_reg(s
, rd
);
3334 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3335 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3338 case ARM_VFP_FPINST
:
3339 case ARM_VFP_FPINST2
:
3343 tmp
= load_reg(s
, rd
);
3344 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3350 tmp
= load_reg(s
, rd
);
3352 gen_mov_vreg_F0(0, rn
);
3357 /* data processing */
3360 bool no_output
= false;
3362 /* The opcode is in bits 23, 21, 20 and 6. */
3363 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3364 rn
= VFP_SREG_N(insn
);
3367 /* rn is opcode, encoded as per VFP_SREG_N. */
3369 case 0x00: /* vmov */
3370 case 0x01: /* vabs */
3371 case 0x02: /* vneg */
3372 case 0x03: /* vsqrt */
3375 case 0x04: /* vcvtb.f64.f16, vcvtb.f32.f16 */
3376 case 0x05: /* vcvtt.f64.f16, vcvtt.f32.f16 */
3378 * VCVTB, VCVTT: only present with the halfprec extension
3379 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3380 * (we choose to UNDEF)
3383 if (!dc_isar_feature(aa32_fp16_dpconv
, s
)) {
3387 if (!dc_isar_feature(aa32_fp16_spconv
, s
)) {
3393 case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3394 case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3396 if (!dc_isar_feature(aa32_fp16_dpconv
, s
)) {
3400 if (!dc_isar_feature(aa32_fp16_spconv
, s
)) {
3407 case 0x08: case 0x0a: /* vcmp, vcmpz */
3408 case 0x09: case 0x0b: /* vcmpe, vcmpez */
3412 case 0x0c: /* vrintr */
3413 case 0x0d: /* vrintz */
3414 case 0x0e: /* vrintx */
3417 case 0x0f: /* vcvt double<->single */
3421 case 0x10: /* vcvt.fxx.u32 */
3422 case 0x11: /* vcvt.fxx.s32 */
3425 case 0x18: /* vcvtr.u32.fxx */
3426 case 0x19: /* vcvtz.u32.fxx */
3427 case 0x1a: /* vcvtr.s32.fxx */
3428 case 0x1b: /* vcvtz.s32.fxx */
3432 case 0x14: /* vcvt fp <-> fixed */
3440 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3443 /* Immediate frac_bits has same format as SREG_M. */
3447 case 0x13: /* vjcvt */
3448 if (!dp
|| !dc_isar_feature(aa32_jscvt
, s
)) {
3458 /* rn is register number */
3459 VFP_DREG_N(rn
, insn
);
3463 VFP_DREG_D(rd
, insn
);
3465 rd
= VFP_SREG_D(insn
);
3468 VFP_DREG_M(rm
, insn
);
3470 rm
= VFP_SREG_M(insn
);
3473 veclen
= s
->vec_len
;
3474 if (op
== 15 && rn
> 3) {
3478 /* Shut up compiler warnings. */
3489 /* Figure out what type of vector operation this is. */
3490 if ((rd
& bank_mask
) == 0) {
3495 delta_d
= (s
->vec_stride
>> 1) + 1;
3497 delta_d
= s
->vec_stride
+ 1;
3499 if ((rm
& bank_mask
) == 0) {
3500 /* mixed scalar/vector */
3509 /* Load the initial operands. */
3512 case 0x08: case 0x09: /* Compare */
3513 gen_mov_F0_vreg(dp
, rd
);
3514 gen_mov_F1_vreg(dp
, rm
);
3516 case 0x0a: case 0x0b: /* Compare with zero */
3517 gen_mov_F0_vreg(dp
, rd
);
3520 case 0x14: /* vcvt fp <-> fixed */
3528 /* Source and destination the same. */
3529 gen_mov_F0_vreg(dp
, rd
);
3532 /* One source operand. */
3533 gen_mov_F0_vreg(rm_is_dp
, rm
);
3537 /* Two source operands. */
3538 gen_mov_F0_vreg(dp
, rn
);
3539 gen_mov_F1_vreg(dp
, rm
);
3543 /* Perform the calculation. */
3545 case 0: /* VMLA: fd + (fn * fm) */
3546 /* Note that order of inputs to the add matters for NaNs */
3548 gen_mov_F0_vreg(dp
, rd
);
3551 case 1: /* VMLS: fd + -(fn * fm) */
3554 gen_mov_F0_vreg(dp
, rd
);
3557 case 2: /* VNMLS: -fd + (fn * fm) */
3558 /* Note that it isn't valid to replace (-A + B) with (B - A)
3559 * or similar plausible looking simplifications
3560 * because this will give wrong results for NaNs.
3563 gen_mov_F0_vreg(dp
, rd
);
3567 case 3: /* VNMLA: -fd + -(fn * fm) */
3570 gen_mov_F0_vreg(dp
, rd
);
3574 case 4: /* mul: fn * fm */
3577 case 5: /* nmul: -(fn * fm) */
3581 case 6: /* add: fn + fm */
3584 case 7: /* sub: fn - fm */
3587 case 8: /* div: fn / fm */
3590 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3591 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3592 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3593 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3594 /* These are fused multiply-add, and must be done as one
3595 * floating point operation with no rounding between the
3596 * multiplication and addition steps.
3597 * NB that doing the negations here as separate steps is
3598 * correct : an input NaN should come out with its sign bit
3599 * flipped if it is a negated-input.
3601 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3609 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3611 frd
= tcg_temp_new_i64();
3612 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3615 gen_helper_vfp_negd(frd
, frd
);
3617 fpst
= get_fpstatus_ptr(0);
3618 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3619 cpu_F1d
, frd
, fpst
);
3620 tcg_temp_free_ptr(fpst
);
3621 tcg_temp_free_i64(frd
);
3627 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3629 frd
= tcg_temp_new_i32();
3630 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3632 gen_helper_vfp_negs(frd
, frd
);
3634 fpst
= get_fpstatus_ptr(0);
3635 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3636 cpu_F1s
, frd
, fpst
);
3637 tcg_temp_free_ptr(fpst
);
3638 tcg_temp_free_i32(frd
);
3641 case 14: /* fconst */
3642 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3646 n
= (insn
<< 12) & 0x80000000;
3647 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3654 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3661 tcg_gen_movi_i32(cpu_F0s
, n
);
3664 case 15: /* extension space */
3678 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3680 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3681 TCGv_i32 ahp_mode
= get_ahp_flag();
3682 tmp
= gen_vfp_mrs();
3683 tcg_gen_ext16u_i32(tmp
, tmp
);
3685 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3688 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3691 tcg_temp_free_i32(ahp_mode
);
3692 tcg_temp_free_ptr(fpst
);
3693 tcg_temp_free_i32(tmp
);
3696 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3698 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3699 TCGv_i32 ahp
= get_ahp_flag();
3700 tmp
= gen_vfp_mrs();
3701 tcg_gen_shri_i32(tmp
, tmp
, 16);
3703 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3706 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3709 tcg_temp_free_i32(tmp
);
3710 tcg_temp_free_i32(ahp
);
3711 tcg_temp_free_ptr(fpst
);
3714 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3716 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3717 TCGv_i32 ahp
= get_ahp_flag();
3718 tmp
= tcg_temp_new_i32();
3721 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3724 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3727 tcg_temp_free_i32(ahp
);
3728 tcg_temp_free_ptr(fpst
);
3729 gen_mov_F0_vreg(0, rd
);
3730 tmp2
= gen_vfp_mrs();
3731 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3732 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3733 tcg_temp_free_i32(tmp2
);
3737 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3739 TCGv_ptr fpst
= get_fpstatus_ptr(false);
3740 TCGv_i32 ahp
= get_ahp_flag();
3741 tmp
= tcg_temp_new_i32();
3743 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3746 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3749 tcg_temp_free_i32(ahp
);
3750 tcg_temp_free_ptr(fpst
);
3751 tcg_gen_shli_i32(tmp
, tmp
, 16);
3752 gen_mov_F0_vreg(0, rd
);
3753 tmp2
= gen_vfp_mrs();
3754 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3755 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3756 tcg_temp_free_i32(tmp2
);
3769 case 11: /* cmpez */
3773 case 12: /* vrintr */
3775 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3777 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3779 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3781 tcg_temp_free_ptr(fpst
);
3784 case 13: /* vrintz */
3786 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3788 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3789 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3791 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3793 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3795 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3796 tcg_temp_free_i32(tcg_rmode
);
3797 tcg_temp_free_ptr(fpst
);
3800 case 14: /* vrintx */
3802 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3804 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3806 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3808 tcg_temp_free_ptr(fpst
);
3811 case 15: /* single<->double conversion */
3813 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3815 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3818 case 16: /* fuito */
3819 gen_vfp_uito(dp
, 0);
3821 case 17: /* fsito */
3822 gen_vfp_sito(dp
, 0);
3824 case 19: /* vjcvt */
3825 gen_helper_vjcvt(cpu_F0s
, cpu_F0d
, cpu_env
);
3827 case 20: /* fshto */
3828 gen_vfp_shto(dp
, 16 - rm
, 0);
3830 case 21: /* fslto */
3831 gen_vfp_slto(dp
, 32 - rm
, 0);
3833 case 22: /* fuhto */
3834 gen_vfp_uhto(dp
, 16 - rm
, 0);
3836 case 23: /* fulto */
3837 gen_vfp_ulto(dp
, 32 - rm
, 0);
3839 case 24: /* ftoui */
3840 gen_vfp_toui(dp
, 0);
3842 case 25: /* ftouiz */
3843 gen_vfp_touiz(dp
, 0);
3845 case 26: /* ftosi */
3846 gen_vfp_tosi(dp
, 0);
3848 case 27: /* ftosiz */
3849 gen_vfp_tosiz(dp
, 0);
3851 case 28: /* ftosh */
3852 gen_vfp_tosh(dp
, 16 - rm
, 0);
3854 case 29: /* ftosl */
3855 gen_vfp_tosl(dp
, 32 - rm
, 0);
3857 case 30: /* ftouh */
3858 gen_vfp_touh(dp
, 16 - rm
, 0);
3860 case 31: /* ftoul */
3861 gen_vfp_toul(dp
, 32 - rm
, 0);
3863 default: /* undefined */
3864 g_assert_not_reached();
3867 default: /* undefined */
3871 /* Write back the result, if any. */
3873 gen_mov_vreg_F0(rd_is_dp
, rd
);
3876 /* break out of the loop if we have finished */
3881 if (op
== 15 && delta_m
== 0) {
3882 /* single source one-many */
3884 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3886 gen_mov_vreg_F0(dp
, rd
);
3890 /* Setup the next operands. */
3892 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3896 /* One source operand. */
3897 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3899 gen_mov_F0_vreg(dp
, rm
);
3901 /* Two source operands. */
3902 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3904 gen_mov_F0_vreg(dp
, rn
);
3906 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3908 gen_mov_F1_vreg(dp
, rm
);
3916 if ((insn
& 0x03e00000) == 0x00400000) {
3917 /* two-register transfer */
3918 rn
= (insn
>> 16) & 0xf;
3919 rd
= (insn
>> 12) & 0xf;
3921 VFP_DREG_M(rm
, insn
);
3923 rm
= VFP_SREG_M(insn
);
3926 if (insn
& ARM_CP_RW_BIT
) {
3929 gen_mov_F0_vreg(0, rm
* 2);
3930 tmp
= gen_vfp_mrs();
3931 store_reg(s
, rd
, tmp
);
3932 gen_mov_F0_vreg(0, rm
* 2 + 1);
3933 tmp
= gen_vfp_mrs();
3934 store_reg(s
, rn
, tmp
);
3936 gen_mov_F0_vreg(0, rm
);
3937 tmp
= gen_vfp_mrs();
3938 store_reg(s
, rd
, tmp
);
3939 gen_mov_F0_vreg(0, rm
+ 1);
3940 tmp
= gen_vfp_mrs();
3941 store_reg(s
, rn
, tmp
);
3946 tmp
= load_reg(s
, rd
);
3948 gen_mov_vreg_F0(0, rm
* 2);
3949 tmp
= load_reg(s
, rn
);
3951 gen_mov_vreg_F0(0, rm
* 2 + 1);
3953 tmp
= load_reg(s
, rd
);
3955 gen_mov_vreg_F0(0, rm
);
3956 tmp
= load_reg(s
, rn
);
3958 gen_mov_vreg_F0(0, rm
+ 1);
3963 rn
= (insn
>> 16) & 0xf;
3965 VFP_DREG_D(rd
, insn
);
3967 rd
= VFP_SREG_D(insn
);
3968 if ((insn
& 0x01200000) == 0x01000000) {
3969 /* Single load/store */
3970 offset
= (insn
& 0xff) << 2;
3971 if ((insn
& (1 << 23)) == 0)
3973 if (s
->thumb
&& rn
== 15) {
3974 /* This is actually UNPREDICTABLE */
3975 addr
= tcg_temp_new_i32();
3976 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3978 addr
= load_reg(s
, rn
);
3980 tcg_gen_addi_i32(addr
, addr
, offset
);
3981 if (insn
& (1 << 20)) {
3982 gen_vfp_ld(s
, dp
, addr
);
3983 gen_mov_vreg_F0(dp
, rd
);
3985 gen_mov_F0_vreg(dp
, rd
);
3986 gen_vfp_st(s
, dp
, addr
);
3988 tcg_temp_free_i32(addr
);
3990 /* load/store multiple */
3991 int w
= insn
& (1 << 21);
3993 n
= (insn
>> 1) & 0x7f;
3997 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3998 /* P == U , W == 1 => UNDEF */
4001 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
4002 /* UNPREDICTABLE cases for bad immediates: we choose to
4003 * UNDEF to avoid generating huge numbers of TCG ops
4007 if (rn
== 15 && w
) {
4008 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4012 if (s
->thumb
&& rn
== 15) {
4013 /* This is actually UNPREDICTABLE */
4014 addr
= tcg_temp_new_i32();
4015 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4017 addr
= load_reg(s
, rn
);
4019 if (insn
& (1 << 24)) /* pre-decrement */
4020 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4022 if (s
->v8m_stackcheck
&& rn
== 13 && w
) {
4024 * Here 'addr' is the lowest address we will store to,
4025 * and is either the old SP (if post-increment) or
4026 * the new SP (if pre-decrement). For post-increment
4027 * where the old value is below the limit and the new
4028 * value is above, it is UNKNOWN whether the limit check
4029 * triggers; we choose to trigger.
4031 gen_helper_v8m_stackcheck(cpu_env
, addr
);
4038 for (i
= 0; i
< n
; i
++) {
4039 if (insn
& ARM_CP_RW_BIT
) {
4041 gen_vfp_ld(s
, dp
, addr
);
4042 gen_mov_vreg_F0(dp
, rd
+ i
);
4045 gen_mov_F0_vreg(dp
, rd
+ i
);
4046 gen_vfp_st(s
, dp
, addr
);
4048 tcg_gen_addi_i32(addr
, addr
, offset
);
4052 if (insn
& (1 << 24))
4053 offset
= -offset
* n
;
4054 else if (dp
&& (insn
& 1))
4060 tcg_gen_addi_i32(addr
, addr
, offset
);
4061 store_reg(s
, rn
, addr
);
4063 tcg_temp_free_i32(addr
);
4069 /* Should never happen. */
4075 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4077 #ifndef CONFIG_USER_ONLY
4078 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4079 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4085 static void gen_goto_ptr(void)
4087 tcg_gen_lookup_and_goto_ptr();
4090 /* This will end the TB but doesn't guarantee we'll return to
4091 * cpu_loop_exec. Any live exit_requests will be processed as we
4092 * enter the next TB.
4094 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4096 if (use_goto_tb(s
, dest
)) {
4098 gen_set_pc_im(s
, dest
);
4099 tcg_gen_exit_tb(s
->base
.tb
, n
);
4101 gen_set_pc_im(s
, dest
);
4104 s
->base
.is_jmp
= DISAS_NORETURN
;
4107 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4109 if (unlikely(is_singlestepping(s
))) {
4110 /* An indirect jump so that we still trigger the debug exception. */
4115 gen_goto_tb(s
, 0, dest
);
4119 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4122 tcg_gen_sari_i32(t0
, t0
, 16);
4126 tcg_gen_sari_i32(t1
, t1
, 16);
4129 tcg_gen_mul_i32(t0
, t0
, t1
);
4132 /* Return the mask of PSR bits set by a MSR instruction. */
4133 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4138 if (flags
& (1 << 0))
4140 if (flags
& (1 << 1))
4142 if (flags
& (1 << 2))
4144 if (flags
& (1 << 3))
4147 /* Mask out undefined bits. */
4148 mask
&= ~CPSR_RESERVED
;
4149 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4152 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4153 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4155 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4156 mask
&= ~(CPSR_E
| CPSR_GE
);
4158 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4161 /* Mask out execution state and reserved bits. */
4163 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4165 /* Mask out privileged bits. */
4171 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4172 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4176 /* ??? This is also undefined in system mode. */
4180 tmp
= load_cpu_field(spsr
);
4181 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4182 tcg_gen_andi_i32(t0
, t0
, mask
);
4183 tcg_gen_or_i32(tmp
, tmp
, t0
);
4184 store_cpu_field(tmp
, spsr
);
4186 gen_set_cpsr(t0
, mask
);
4188 tcg_temp_free_i32(t0
);
4193 /* Returns nonzero if access to the PSR is not permitted. */
4194 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4197 tmp
= tcg_temp_new_i32();
4198 tcg_gen_movi_i32(tmp
, val
);
4199 return gen_set_psr(s
, mask
, spsr
, tmp
);
4202 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4203 int *tgtmode
, int *regno
)
4205 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4206 * the target mode and register number, and identify the various
4207 * unpredictable cases.
4208 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4209 * + executed in user mode
4210 * + using R15 as the src/dest register
4211 * + accessing an unimplemented register
4212 * + accessing a register that's inaccessible at current PL/security state*
4213 * + accessing a register that you could access with a different insn
4214 * We choose to UNDEF in all these cases.
4215 * Since we don't know which of the various AArch32 modes we are in
4216 * we have to defer some checks to runtime.
4217 * Accesses to Monitor mode registers from Secure EL1 (which implies
4218 * that EL3 is AArch64) must trap to EL3.
4220 * If the access checks fail this function will emit code to take
4221 * an exception and return false. Otherwise it will return true,
4222 * and set *tgtmode and *regno appropriately.
4224 int exc_target
= default_exception_el(s
);
4226 /* These instructions are present only in ARMv8, or in ARMv7 with the
4227 * Virtualization Extensions.
4229 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4230 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4234 if (IS_USER(s
) || rn
== 15) {
4238 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4239 * of registers into (r, sysm).
4242 /* SPSRs for other modes */
4244 case 0xe: /* SPSR_fiq */
4245 *tgtmode
= ARM_CPU_MODE_FIQ
;
4247 case 0x10: /* SPSR_irq */
4248 *tgtmode
= ARM_CPU_MODE_IRQ
;
4250 case 0x12: /* SPSR_svc */
4251 *tgtmode
= ARM_CPU_MODE_SVC
;
4253 case 0x14: /* SPSR_abt */
4254 *tgtmode
= ARM_CPU_MODE_ABT
;
4256 case 0x16: /* SPSR_und */
4257 *tgtmode
= ARM_CPU_MODE_UND
;
4259 case 0x1c: /* SPSR_mon */
4260 *tgtmode
= ARM_CPU_MODE_MON
;
4262 case 0x1e: /* SPSR_hyp */
4263 *tgtmode
= ARM_CPU_MODE_HYP
;
4265 default: /* unallocated */
4268 /* We arbitrarily assign SPSR a register number of 16. */
4271 /* general purpose registers for other modes */
4273 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4274 *tgtmode
= ARM_CPU_MODE_USR
;
4277 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4278 *tgtmode
= ARM_CPU_MODE_FIQ
;
4281 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4282 *tgtmode
= ARM_CPU_MODE_IRQ
;
4283 *regno
= sysm
& 1 ? 13 : 14;
4285 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4286 *tgtmode
= ARM_CPU_MODE_SVC
;
4287 *regno
= sysm
& 1 ? 13 : 14;
4289 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4290 *tgtmode
= ARM_CPU_MODE_ABT
;
4291 *regno
= sysm
& 1 ? 13 : 14;
4293 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4294 *tgtmode
= ARM_CPU_MODE_UND
;
4295 *regno
= sysm
& 1 ? 13 : 14;
4297 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4298 *tgtmode
= ARM_CPU_MODE_MON
;
4299 *regno
= sysm
& 1 ? 13 : 14;
4301 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4302 *tgtmode
= ARM_CPU_MODE_HYP
;
4303 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4304 *regno
= sysm
& 1 ? 13 : 17;
4306 default: /* unallocated */
4311 /* Catch the 'accessing inaccessible register' cases we can detect
4312 * at translate time.
4315 case ARM_CPU_MODE_MON
:
4316 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4319 if (s
->current_el
== 1) {
4320 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4321 * then accesses to Mon registers trap to EL3
4327 case ARM_CPU_MODE_HYP
:
4329 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
4330 * (and so we can forbid accesses from EL2 or below). elr_hyp
4331 * can be accessed also from Hyp mode, so forbid accesses from
4334 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 2 ||
4335 (s
->current_el
< 3 && *regno
!= 17)) {
4346 /* If we get here then some access check did not pass */
4347 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4351 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4353 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4354 int tgtmode
= 0, regno
= 0;
4356 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4360 /* Sync state because msr_banked() can raise exceptions */
4361 gen_set_condexec(s
);
4362 gen_set_pc_im(s
, s
->pc
- 4);
4363 tcg_reg
= load_reg(s
, rn
);
4364 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4365 tcg_regno
= tcg_const_i32(regno
);
4366 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4367 tcg_temp_free_i32(tcg_tgtmode
);
4368 tcg_temp_free_i32(tcg_regno
);
4369 tcg_temp_free_i32(tcg_reg
);
4370 s
->base
.is_jmp
= DISAS_UPDATE
;
4373 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4375 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4376 int tgtmode
= 0, regno
= 0;
4378 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4382 /* Sync state because mrs_banked() can raise exceptions */
4383 gen_set_condexec(s
);
4384 gen_set_pc_im(s
, s
->pc
- 4);
4385 tcg_reg
= tcg_temp_new_i32();
4386 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4387 tcg_regno
= tcg_const_i32(regno
);
4388 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4389 tcg_temp_free_i32(tcg_tgtmode
);
4390 tcg_temp_free_i32(tcg_regno
);
4391 store_reg(s
, rn
, tcg_reg
);
4392 s
->base
.is_jmp
= DISAS_UPDATE
;
4395 /* Store value to PC as for an exception return (ie don't
4396 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4397 * will do the masking based on the new value of the Thumb bit.
4399 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4401 tcg_gen_mov_i32(cpu_R
[15], pc
);
4402 tcg_temp_free_i32(pc
);
4405 /* Generate a v6 exception return. Marks both values as dead. */
4406 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4408 store_pc_exc_ret(s
, pc
);
4409 /* The cpsr_write_eret helper will mask the low bits of PC
4410 * appropriately depending on the new Thumb bit, so it must
4411 * be called after storing the new PC.
4413 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
4416 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4417 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
4420 tcg_temp_free_i32(cpsr
);
4421 /* Must exit loop to check un-masked IRQs */
4422 s
->base
.is_jmp
= DISAS_EXIT
;
4425 /* Generate an old-style exception return. Marks pc as dead. */
4426 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4428 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4432 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4433 * only call the helper when running single threaded TCG code to ensure
4434 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4435 * just skip this instruction. Currently the SEV/SEVL instructions
4436 * which are *one* of many ways to wake the CPU from WFE are not
4437 * implemented so we can't sleep like WFI does.
4439 static void gen_nop_hint(DisasContext
*s
, int val
)
4442 /* When running in MTTCG we don't generate jumps to the yield and
4443 * WFE helpers as it won't affect the scheduling of other vCPUs.
4444 * If we wanted to more completely model WFE/SEV so we don't busy
4445 * spin unnecessarily we would need to do something more involved.
4448 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4449 gen_set_pc_im(s
, s
->pc
);
4450 s
->base
.is_jmp
= DISAS_YIELD
;
4454 gen_set_pc_im(s
, s
->pc
);
4455 s
->base
.is_jmp
= DISAS_WFI
;
4458 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4459 gen_set_pc_im(s
, s
->pc
);
4460 s
->base
.is_jmp
= DISAS_WFE
;
4465 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4471 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4473 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4476 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4477 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4478 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4483 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4486 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4487 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4488 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4493 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4494 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
4495 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
4496 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
4497 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
4499 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4500 switch ((size << 1) | u) { \
4502 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4505 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4508 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4511 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4514 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4517 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4519 default: return 1; \
4522 #define GEN_NEON_INTEGER_OP(name) do { \
4523 switch ((size << 1) | u) { \
4525 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4528 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4531 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4534 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4537 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4540 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4542 default: return 1; \
4545 static TCGv_i32
neon_load_scratch(int scratch
)
4547 TCGv_i32 tmp
= tcg_temp_new_i32();
4548 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4552 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4554 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4555 tcg_temp_free_i32(var
);
4558 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4562 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4564 gen_neon_dup_high16(tmp
);
4566 gen_neon_dup_low16(tmp
);
4569 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4574 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4578 if (!q
&& size
== 2) {
4581 pd
= vfp_reg_ptr(true, rd
);
4582 pm
= vfp_reg_ptr(true, rm
);
4586 gen_helper_neon_qunzip8(pd
, pm
);
4589 gen_helper_neon_qunzip16(pd
, pm
);
4592 gen_helper_neon_qunzip32(pd
, pm
);
4600 gen_helper_neon_unzip8(pd
, pm
);
4603 gen_helper_neon_unzip16(pd
, pm
);
4609 tcg_temp_free_ptr(pd
);
4610 tcg_temp_free_ptr(pm
);
4614 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4618 if (!q
&& size
== 2) {
4621 pd
= vfp_reg_ptr(true, rd
);
4622 pm
= vfp_reg_ptr(true, rm
);
4626 gen_helper_neon_qzip8(pd
, pm
);
4629 gen_helper_neon_qzip16(pd
, pm
);
4632 gen_helper_neon_qzip32(pd
, pm
);
4640 gen_helper_neon_zip8(pd
, pm
);
4643 gen_helper_neon_zip16(pd
, pm
);
4649 tcg_temp_free_ptr(pd
);
4650 tcg_temp_free_ptr(pm
);
4654 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4658 rd
= tcg_temp_new_i32();
4659 tmp
= tcg_temp_new_i32();
4661 tcg_gen_shli_i32(rd
, t0
, 8);
4662 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4663 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4664 tcg_gen_or_i32(rd
, rd
, tmp
);
4666 tcg_gen_shri_i32(t1
, t1
, 8);
4667 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4668 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4669 tcg_gen_or_i32(t1
, t1
, tmp
);
4670 tcg_gen_mov_i32(t0
, rd
);
4672 tcg_temp_free_i32(tmp
);
4673 tcg_temp_free_i32(rd
);
4676 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4680 rd
= tcg_temp_new_i32();
4681 tmp
= tcg_temp_new_i32();
4683 tcg_gen_shli_i32(rd
, t0
, 16);
4684 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4685 tcg_gen_or_i32(rd
, rd
, tmp
);
4686 tcg_gen_shri_i32(t1
, t1
, 16);
4687 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4688 tcg_gen_or_i32(t1
, t1
, tmp
);
4689 tcg_gen_mov_i32(t0
, rd
);
4691 tcg_temp_free_i32(tmp
);
4692 tcg_temp_free_i32(rd
);
4700 } const neon_ls_element_type
[11] = {
4714 /* Translate a NEON load/store element instruction. Return nonzero if the
4715 instruction is invalid. */
4716 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4736 /* FIXME: this access check should not take precedence over UNDEF
4737 * for invalid encodings; we will generate incorrect syndrome information
4738 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4740 if (s
->fp_excp_el
) {
4741 gen_exception_insn(s
, 4, EXCP_UDEF
,
4742 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
4746 if (!s
->vfp_enabled
)
4748 VFP_DREG_D(rd
, insn
);
4749 rn
= (insn
>> 16) & 0xf;
4751 load
= (insn
& (1 << 21)) != 0;
4752 endian
= s
->be_data
;
4753 mmu_idx
= get_mem_index(s
);
4754 if ((insn
& (1 << 23)) == 0) {
4755 /* Load store all elements. */
4756 op
= (insn
>> 8) & 0xf;
4757 size
= (insn
>> 6) & 3;
4760 /* Catch UNDEF cases for bad values of align field */
4763 if (((insn
>> 5) & 1) == 1) {
4768 if (((insn
>> 4) & 3) == 3) {
4775 nregs
= neon_ls_element_type
[op
].nregs
;
4776 interleave
= neon_ls_element_type
[op
].interleave
;
4777 spacing
= neon_ls_element_type
[op
].spacing
;
4778 if (size
== 3 && (interleave
| spacing
) != 1) {
4781 /* For our purposes, bytes are always little-endian. */
4785 /* Consecutive little-endian elements from a single register
4786 * can be promoted to a larger little-endian operation.
4788 if (interleave
== 1 && endian
== MO_LE
) {
4791 tmp64
= tcg_temp_new_i64();
4792 addr
= tcg_temp_new_i32();
4793 tmp2
= tcg_const_i32(1 << size
);
4794 load_reg_var(s
, addr
, rn
);
4795 for (reg
= 0; reg
< nregs
; reg
++) {
4796 for (n
= 0; n
< 8 >> size
; n
++) {
4798 for (xs
= 0; xs
< interleave
; xs
++) {
4799 int tt
= rd
+ reg
+ spacing
* xs
;
4802 gen_aa32_ld_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
4803 neon_store_element64(tt
, n
, size
, tmp64
);
4805 neon_load_element64(tmp64
, tt
, n
, size
);
4806 gen_aa32_st_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
4808 tcg_gen_add_i32(addr
, addr
, tmp2
);
4812 tcg_temp_free_i32(addr
);
4813 tcg_temp_free_i32(tmp2
);
4814 tcg_temp_free_i64(tmp64
);
4815 stride
= nregs
* interleave
* 8;
4817 size
= (insn
>> 10) & 3;
4819 /* Load single element to all lanes. */
4820 int a
= (insn
>> 4) & 1;
4824 size
= (insn
>> 6) & 3;
4825 nregs
= ((insn
>> 8) & 3) + 1;
4828 if (nregs
!= 4 || a
== 0) {
4831 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4834 if (nregs
== 1 && a
== 1 && size
== 0) {
4837 if (nregs
== 3 && a
== 1) {
4840 addr
= tcg_temp_new_i32();
4841 load_reg_var(s
, addr
, rn
);
4843 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
4844 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
4846 stride
= (insn
& (1 << 5)) ? 2 : 1;
4847 vec_size
= nregs
== 1 ? stride
* 8 : 8;
4849 tmp
= tcg_temp_new_i32();
4850 for (reg
= 0; reg
< nregs
; reg
++) {
4851 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
4853 if ((rd
& 1) && vec_size
== 16) {
4854 /* We cannot write 16 bytes at once because the
4855 * destination is unaligned.
4857 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
4859 tcg_gen_gvec_mov(0, neon_reg_offset(rd
+ 1, 0),
4860 neon_reg_offset(rd
, 0), 8, 8);
4862 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
4863 vec_size
, vec_size
, tmp
);
4865 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4868 tcg_temp_free_i32(tmp
);
4869 tcg_temp_free_i32(addr
);
4870 stride
= (1 << size
) * nregs
;
4872 /* Single element. */
4873 int idx
= (insn
>> 4) & 0xf;
4877 reg_idx
= (insn
>> 5) & 7;
4881 reg_idx
= (insn
>> 6) & 3;
4882 stride
= (insn
& (1 << 5)) ? 2 : 1;
4885 reg_idx
= (insn
>> 7) & 1;
4886 stride
= (insn
& (1 << 6)) ? 2 : 1;
4891 nregs
= ((insn
>> 8) & 3) + 1;
4892 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4895 if (((idx
& (1 << size
)) != 0) ||
4896 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4901 if ((idx
& 1) != 0) {
4906 if (size
== 2 && (idx
& 2) != 0) {
4911 if ((size
== 2) && ((idx
& 3) == 3)) {
4918 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4919 /* Attempts to write off the end of the register file
4920 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4921 * the neon_load_reg() would write off the end of the array.
4925 tmp
= tcg_temp_new_i32();
4926 addr
= tcg_temp_new_i32();
4927 load_reg_var(s
, addr
, rn
);
4928 for (reg
= 0; reg
< nregs
; reg
++) {
4930 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
4932 neon_store_element(rd
, reg_idx
, size
, tmp
);
4933 } else { /* Store */
4934 neon_load_element(tmp
, rd
, reg_idx
, size
);
4935 gen_aa32_st_i32(s
, tmp
, addr
, get_mem_index(s
),
4939 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4941 tcg_temp_free_i32(addr
);
4942 tcg_temp_free_i32(tmp
);
4943 stride
= nregs
* (1 << size
);
4949 base
= load_reg(s
, rn
);
4951 tcg_gen_addi_i32(base
, base
, stride
);
4954 index
= load_reg(s
, rm
);
4955 tcg_gen_add_i32(base
, base
, index
);
4956 tcg_temp_free_i32(index
);
4958 store_reg(s
, rn
, base
);
4963 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4966 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4967 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4968 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4973 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4976 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4977 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4978 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4983 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4986 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4987 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4988 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4993 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4996 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4997 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4998 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5003 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5009 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5010 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5015 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5016 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5023 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5024 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5029 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5030 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5037 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5041 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5042 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5043 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5048 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5049 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5050 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5054 tcg_temp_free_i32(src
);
5057 static inline void gen_neon_addl(int size
)
5060 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5061 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5062 case 2: tcg_gen_add_i64(CPU_V001
); break;
5067 static inline void gen_neon_subl(int size
)
5070 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5071 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5072 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5077 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5080 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5081 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5083 tcg_gen_neg_i64(var
, var
);
5089 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5092 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5093 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5098 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5103 switch ((size
<< 1) | u
) {
5104 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5105 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5106 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5107 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5109 tmp
= gen_muls_i64_i32(a
, b
);
5110 tcg_gen_mov_i64(dest
, tmp
);
5111 tcg_temp_free_i64(tmp
);
5114 tmp
= gen_mulu_i64_i32(a
, b
);
5115 tcg_gen_mov_i64(dest
, tmp
);
5116 tcg_temp_free_i64(tmp
);
5121 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5122 Don't forget to clean them now. */
5124 tcg_temp_free_i32(a
);
5125 tcg_temp_free_i32(b
);
5129 static void gen_neon_narrow_op(int op
, int u
, int size
,
5130 TCGv_i32 dest
, TCGv_i64 src
)
5134 gen_neon_unarrow_sats(size
, dest
, src
);
5136 gen_neon_narrow(size
, dest
, src
);
5140 gen_neon_narrow_satu(size
, dest
, src
);
5142 gen_neon_narrow_sats(size
, dest
, src
);
5147 /* Symbolic constants for op fields for Neon 3-register same-length.
5148 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5151 #define NEON_3R_VHADD 0
5152 #define NEON_3R_VQADD 1
5153 #define NEON_3R_VRHADD 2
5154 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5155 #define NEON_3R_VHSUB 4
5156 #define NEON_3R_VQSUB 5
5157 #define NEON_3R_VCGT 6
5158 #define NEON_3R_VCGE 7
5159 #define NEON_3R_VSHL 8
5160 #define NEON_3R_VQSHL 9
5161 #define NEON_3R_VRSHL 10
5162 #define NEON_3R_VQRSHL 11
5163 #define NEON_3R_VMAX 12
5164 #define NEON_3R_VMIN 13
5165 #define NEON_3R_VABD 14
5166 #define NEON_3R_VABA 15
5167 #define NEON_3R_VADD_VSUB 16
5168 #define NEON_3R_VTST_VCEQ 17
5169 #define NEON_3R_VML 18 /* VMLA, VMLS */
5170 #define NEON_3R_VMUL 19
5171 #define NEON_3R_VPMAX 20
5172 #define NEON_3R_VPMIN 21
5173 #define NEON_3R_VQDMULH_VQRDMULH 22
5174 #define NEON_3R_VPADD_VQRDMLAH 23
5175 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5176 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5177 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5178 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5179 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5180 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5181 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5182 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5184 static const uint8_t neon_3r_sizes
[] = {
5185 [NEON_3R_VHADD
] = 0x7,
5186 [NEON_3R_VQADD
] = 0xf,
5187 [NEON_3R_VRHADD
] = 0x7,
5188 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5189 [NEON_3R_VHSUB
] = 0x7,
5190 [NEON_3R_VQSUB
] = 0xf,
5191 [NEON_3R_VCGT
] = 0x7,
5192 [NEON_3R_VCGE
] = 0x7,
5193 [NEON_3R_VSHL
] = 0xf,
5194 [NEON_3R_VQSHL
] = 0xf,
5195 [NEON_3R_VRSHL
] = 0xf,
5196 [NEON_3R_VQRSHL
] = 0xf,
5197 [NEON_3R_VMAX
] = 0x7,
5198 [NEON_3R_VMIN
] = 0x7,
5199 [NEON_3R_VABD
] = 0x7,
5200 [NEON_3R_VABA
] = 0x7,
5201 [NEON_3R_VADD_VSUB
] = 0xf,
5202 [NEON_3R_VTST_VCEQ
] = 0x7,
5203 [NEON_3R_VML
] = 0x7,
5204 [NEON_3R_VMUL
] = 0x7,
5205 [NEON_3R_VPMAX
] = 0x7,
5206 [NEON_3R_VPMIN
] = 0x7,
5207 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5208 [NEON_3R_VPADD_VQRDMLAH
] = 0x7,
5209 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5210 [NEON_3R_VFM_VQRDMLSH
] = 0x7, /* For VFM, size bit 1 encodes op */
5211 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5212 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5213 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5214 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5215 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5216 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5219 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5220 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5223 #define NEON_2RM_VREV64 0
5224 #define NEON_2RM_VREV32 1
5225 #define NEON_2RM_VREV16 2
5226 #define NEON_2RM_VPADDL 4
5227 #define NEON_2RM_VPADDL_U 5
5228 #define NEON_2RM_AESE 6 /* Includes AESD */
5229 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5230 #define NEON_2RM_VCLS 8
5231 #define NEON_2RM_VCLZ 9
5232 #define NEON_2RM_VCNT 10
5233 #define NEON_2RM_VMVN 11
5234 #define NEON_2RM_VPADAL 12
5235 #define NEON_2RM_VPADAL_U 13
5236 #define NEON_2RM_VQABS 14
5237 #define NEON_2RM_VQNEG 15
5238 #define NEON_2RM_VCGT0 16
5239 #define NEON_2RM_VCGE0 17
5240 #define NEON_2RM_VCEQ0 18
5241 #define NEON_2RM_VCLE0 19
5242 #define NEON_2RM_VCLT0 20
5243 #define NEON_2RM_SHA1H 21
5244 #define NEON_2RM_VABS 22
5245 #define NEON_2RM_VNEG 23
5246 #define NEON_2RM_VCGT0_F 24
5247 #define NEON_2RM_VCGE0_F 25
5248 #define NEON_2RM_VCEQ0_F 26
5249 #define NEON_2RM_VCLE0_F 27
5250 #define NEON_2RM_VCLT0_F 28
5251 #define NEON_2RM_VABS_F 30
5252 #define NEON_2RM_VNEG_F 31
5253 #define NEON_2RM_VSWP 32
5254 #define NEON_2RM_VTRN 33
5255 #define NEON_2RM_VUZP 34
5256 #define NEON_2RM_VZIP 35
5257 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5258 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5259 #define NEON_2RM_VSHLL 38
5260 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5261 #define NEON_2RM_VRINTN 40
5262 #define NEON_2RM_VRINTX 41
5263 #define NEON_2RM_VRINTA 42
5264 #define NEON_2RM_VRINTZ 43
5265 #define NEON_2RM_VCVT_F16_F32 44
5266 #define NEON_2RM_VRINTM 45
5267 #define NEON_2RM_VCVT_F32_F16 46
5268 #define NEON_2RM_VRINTP 47
5269 #define NEON_2RM_VCVTAU 48
5270 #define NEON_2RM_VCVTAS 49
5271 #define NEON_2RM_VCVTNU 50
5272 #define NEON_2RM_VCVTNS 51
5273 #define NEON_2RM_VCVTPU 52
5274 #define NEON_2RM_VCVTPS 53
5275 #define NEON_2RM_VCVTMU 54
5276 #define NEON_2RM_VCVTMS 55
5277 #define NEON_2RM_VRECPE 56
5278 #define NEON_2RM_VRSQRTE 57
5279 #define NEON_2RM_VRECPE_F 58
5280 #define NEON_2RM_VRSQRTE_F 59
5281 #define NEON_2RM_VCVT_FS 60
5282 #define NEON_2RM_VCVT_FU 61
5283 #define NEON_2RM_VCVT_SF 62
5284 #define NEON_2RM_VCVT_UF 63
5286 static int neon_2rm_is_float_op(int op
)
5288 /* Return true if this neon 2reg-misc op is float-to-float */
5289 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5290 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5291 op
== NEON_2RM_VRINTM
||
5292 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5293 op
>= NEON_2RM_VRECPE_F
);
5296 static bool neon_2rm_is_v8_op(int op
)
5298 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5300 case NEON_2RM_VRINTN
:
5301 case NEON_2RM_VRINTA
:
5302 case NEON_2RM_VRINTM
:
5303 case NEON_2RM_VRINTP
:
5304 case NEON_2RM_VRINTZ
:
5305 case NEON_2RM_VRINTX
:
5306 case NEON_2RM_VCVTAU
:
5307 case NEON_2RM_VCVTAS
:
5308 case NEON_2RM_VCVTNU
:
5309 case NEON_2RM_VCVTNS
:
5310 case NEON_2RM_VCVTPU
:
5311 case NEON_2RM_VCVTPS
:
5312 case NEON_2RM_VCVTMU
:
5313 case NEON_2RM_VCVTMS
:
5320 /* Each entry in this array has bit n set if the insn allows
5321 * size value n (otherwise it will UNDEF). Since unallocated
5322 * op values will have no bits set they always UNDEF.
5324 static const uint8_t neon_2rm_sizes
[] = {
5325 [NEON_2RM_VREV64
] = 0x7,
5326 [NEON_2RM_VREV32
] = 0x3,
5327 [NEON_2RM_VREV16
] = 0x1,
5328 [NEON_2RM_VPADDL
] = 0x7,
5329 [NEON_2RM_VPADDL_U
] = 0x7,
5330 [NEON_2RM_AESE
] = 0x1,
5331 [NEON_2RM_AESMC
] = 0x1,
5332 [NEON_2RM_VCLS
] = 0x7,
5333 [NEON_2RM_VCLZ
] = 0x7,
5334 [NEON_2RM_VCNT
] = 0x1,
5335 [NEON_2RM_VMVN
] = 0x1,
5336 [NEON_2RM_VPADAL
] = 0x7,
5337 [NEON_2RM_VPADAL_U
] = 0x7,
5338 [NEON_2RM_VQABS
] = 0x7,
5339 [NEON_2RM_VQNEG
] = 0x7,
5340 [NEON_2RM_VCGT0
] = 0x7,
5341 [NEON_2RM_VCGE0
] = 0x7,
5342 [NEON_2RM_VCEQ0
] = 0x7,
5343 [NEON_2RM_VCLE0
] = 0x7,
5344 [NEON_2RM_VCLT0
] = 0x7,
5345 [NEON_2RM_SHA1H
] = 0x4,
5346 [NEON_2RM_VABS
] = 0x7,
5347 [NEON_2RM_VNEG
] = 0x7,
5348 [NEON_2RM_VCGT0_F
] = 0x4,
5349 [NEON_2RM_VCGE0_F
] = 0x4,
5350 [NEON_2RM_VCEQ0_F
] = 0x4,
5351 [NEON_2RM_VCLE0_F
] = 0x4,
5352 [NEON_2RM_VCLT0_F
] = 0x4,
5353 [NEON_2RM_VABS_F
] = 0x4,
5354 [NEON_2RM_VNEG_F
] = 0x4,
5355 [NEON_2RM_VSWP
] = 0x1,
5356 [NEON_2RM_VTRN
] = 0x7,
5357 [NEON_2RM_VUZP
] = 0x7,
5358 [NEON_2RM_VZIP
] = 0x7,
5359 [NEON_2RM_VMOVN
] = 0x7,
5360 [NEON_2RM_VQMOVN
] = 0x7,
5361 [NEON_2RM_VSHLL
] = 0x7,
5362 [NEON_2RM_SHA1SU1
] = 0x4,
5363 [NEON_2RM_VRINTN
] = 0x4,
5364 [NEON_2RM_VRINTX
] = 0x4,
5365 [NEON_2RM_VRINTA
] = 0x4,
5366 [NEON_2RM_VRINTZ
] = 0x4,
5367 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5368 [NEON_2RM_VRINTM
] = 0x4,
5369 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5370 [NEON_2RM_VRINTP
] = 0x4,
5371 [NEON_2RM_VCVTAU
] = 0x4,
5372 [NEON_2RM_VCVTAS
] = 0x4,
5373 [NEON_2RM_VCVTNU
] = 0x4,
5374 [NEON_2RM_VCVTNS
] = 0x4,
5375 [NEON_2RM_VCVTPU
] = 0x4,
5376 [NEON_2RM_VCVTPS
] = 0x4,
5377 [NEON_2RM_VCVTMU
] = 0x4,
5378 [NEON_2RM_VCVTMS
] = 0x4,
5379 [NEON_2RM_VRECPE
] = 0x4,
5380 [NEON_2RM_VRSQRTE
] = 0x4,
5381 [NEON_2RM_VRECPE_F
] = 0x4,
5382 [NEON_2RM_VRSQRTE_F
] = 0x4,
5383 [NEON_2RM_VCVT_FS
] = 0x4,
5384 [NEON_2RM_VCVT_FU
] = 0x4,
5385 [NEON_2RM_VCVT_SF
] = 0x4,
5386 [NEON_2RM_VCVT_UF
] = 0x4,
5390 /* Expand v8.1 simd helper. */
5391 static int do_v81_helper(DisasContext
*s
, gen_helper_gvec_3_ptr
*fn
,
5392 int q
, int rd
, int rn
, int rm
)
5394 if (dc_isar_feature(aa32_rdm
, s
)) {
5395 int opr_sz
= (1 + q
) * 8;
5396 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
5397 vfp_reg_offset(1, rn
),
5398 vfp_reg_offset(1, rm
), cpu_env
,
5399 opr_sz
, opr_sz
, 0, fn
);
5405 static void gen_ssra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5407 tcg_gen_vec_sar8i_i64(a
, a
, shift
);
5408 tcg_gen_vec_add8_i64(d
, d
, a
);
5411 static void gen_ssra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5413 tcg_gen_vec_sar16i_i64(a
, a
, shift
);
5414 tcg_gen_vec_add16_i64(d
, d
, a
);
5417 static void gen_ssra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5419 tcg_gen_sari_i32(a
, a
, shift
);
5420 tcg_gen_add_i32(d
, d
, a
);
5423 static void gen_ssra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5425 tcg_gen_sari_i64(a
, a
, shift
);
5426 tcg_gen_add_i64(d
, d
, a
);
5429 static void gen_ssra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5431 tcg_gen_sari_vec(vece
, a
, a
, sh
);
5432 tcg_gen_add_vec(vece
, d
, d
, a
);
5435 static const TCGOpcode vecop_list_ssra
[] = {
5436 INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
5439 const GVecGen2i ssra_op
[4] = {
5440 { .fni8
= gen_ssra8_i64
,
5441 .fniv
= gen_ssra_vec
,
5443 .opt_opc
= vecop_list_ssra
,
5445 { .fni8
= gen_ssra16_i64
,
5446 .fniv
= gen_ssra_vec
,
5448 .opt_opc
= vecop_list_ssra
,
5450 { .fni4
= gen_ssra32_i32
,
5451 .fniv
= gen_ssra_vec
,
5453 .opt_opc
= vecop_list_ssra
,
5455 { .fni8
= gen_ssra64_i64
,
5456 .fniv
= gen_ssra_vec
,
5457 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5458 .opt_opc
= vecop_list_ssra
,
5463 static void gen_usra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5465 tcg_gen_vec_shr8i_i64(a
, a
, shift
);
5466 tcg_gen_vec_add8_i64(d
, d
, a
);
5469 static void gen_usra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5471 tcg_gen_vec_shr16i_i64(a
, a
, shift
);
5472 tcg_gen_vec_add16_i64(d
, d
, a
);
5475 static void gen_usra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5477 tcg_gen_shri_i32(a
, a
, shift
);
5478 tcg_gen_add_i32(d
, d
, a
);
5481 static void gen_usra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5483 tcg_gen_shri_i64(a
, a
, shift
);
5484 tcg_gen_add_i64(d
, d
, a
);
5487 static void gen_usra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5489 tcg_gen_shri_vec(vece
, a
, a
, sh
);
5490 tcg_gen_add_vec(vece
, d
, d
, a
);
5493 static const TCGOpcode vecop_list_usra
[] = {
5494 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
5497 const GVecGen2i usra_op
[4] = {
5498 { .fni8
= gen_usra8_i64
,
5499 .fniv
= gen_usra_vec
,
5501 .opt_opc
= vecop_list_usra
,
5503 { .fni8
= gen_usra16_i64
,
5504 .fniv
= gen_usra_vec
,
5506 .opt_opc
= vecop_list_usra
,
5508 { .fni4
= gen_usra32_i32
,
5509 .fniv
= gen_usra_vec
,
5511 .opt_opc
= vecop_list_usra
,
5513 { .fni8
= gen_usra64_i64
,
5514 .fniv
= gen_usra_vec
,
5515 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5517 .opt_opc
= vecop_list_usra
,
5521 static void gen_shr8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5523 uint64_t mask
= dup_const(MO_8
, 0xff >> shift
);
5524 TCGv_i64 t
= tcg_temp_new_i64();
5526 tcg_gen_shri_i64(t
, a
, shift
);
5527 tcg_gen_andi_i64(t
, t
, mask
);
5528 tcg_gen_andi_i64(d
, d
, ~mask
);
5529 tcg_gen_or_i64(d
, d
, t
);
5530 tcg_temp_free_i64(t
);
5533 static void gen_shr16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5535 uint64_t mask
= dup_const(MO_16
, 0xffff >> shift
);
5536 TCGv_i64 t
= tcg_temp_new_i64();
5538 tcg_gen_shri_i64(t
, a
, shift
);
5539 tcg_gen_andi_i64(t
, t
, mask
);
5540 tcg_gen_andi_i64(d
, d
, ~mask
);
5541 tcg_gen_or_i64(d
, d
, t
);
5542 tcg_temp_free_i64(t
);
5545 static void gen_shr32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5547 tcg_gen_shri_i32(a
, a
, shift
);
5548 tcg_gen_deposit_i32(d
, d
, a
, 0, 32 - shift
);
5551 static void gen_shr64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5553 tcg_gen_shri_i64(a
, a
, shift
);
5554 tcg_gen_deposit_i64(d
, d
, a
, 0, 64 - shift
);
5557 static void gen_shr_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5560 tcg_gen_mov_vec(d
, a
);
5562 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
5563 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
5565 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK((8 << vece
) - sh
, sh
));
5566 tcg_gen_shri_vec(vece
, t
, a
, sh
);
5567 tcg_gen_and_vec(vece
, d
, d
, m
);
5568 tcg_gen_or_vec(vece
, d
, d
, t
);
5570 tcg_temp_free_vec(t
);
5571 tcg_temp_free_vec(m
);
5575 static const TCGOpcode vecop_list_sri
[] = { INDEX_op_shri_vec
, 0 };
5577 const GVecGen2i sri_op
[4] = {
5578 { .fni8
= gen_shr8_ins_i64
,
5579 .fniv
= gen_shr_ins_vec
,
5581 .opt_opc
= vecop_list_sri
,
5583 { .fni8
= gen_shr16_ins_i64
,
5584 .fniv
= gen_shr_ins_vec
,
5586 .opt_opc
= vecop_list_sri
,
5588 { .fni4
= gen_shr32_ins_i32
,
5589 .fniv
= gen_shr_ins_vec
,
5591 .opt_opc
= vecop_list_sri
,
5593 { .fni8
= gen_shr64_ins_i64
,
5594 .fniv
= gen_shr_ins_vec
,
5595 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5597 .opt_opc
= vecop_list_sri
,
5601 static void gen_shl8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5603 uint64_t mask
= dup_const(MO_8
, 0xff << shift
);
5604 TCGv_i64 t
= tcg_temp_new_i64();
5606 tcg_gen_shli_i64(t
, a
, shift
);
5607 tcg_gen_andi_i64(t
, t
, mask
);
5608 tcg_gen_andi_i64(d
, d
, ~mask
);
5609 tcg_gen_or_i64(d
, d
, t
);
5610 tcg_temp_free_i64(t
);
5613 static void gen_shl16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5615 uint64_t mask
= dup_const(MO_16
, 0xffff << shift
);
5616 TCGv_i64 t
= tcg_temp_new_i64();
5618 tcg_gen_shli_i64(t
, a
, shift
);
5619 tcg_gen_andi_i64(t
, t
, mask
);
5620 tcg_gen_andi_i64(d
, d
, ~mask
);
5621 tcg_gen_or_i64(d
, d
, t
);
5622 tcg_temp_free_i64(t
);
5625 static void gen_shl32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
5627 tcg_gen_deposit_i32(d
, d
, a
, shift
, 32 - shift
);
5630 static void gen_shl64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
5632 tcg_gen_deposit_i64(d
, d
, a
, shift
, 64 - shift
);
5635 static void gen_shl_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
5638 tcg_gen_mov_vec(d
, a
);
5640 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
5641 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
5643 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK(0, sh
));
5644 tcg_gen_shli_vec(vece
, t
, a
, sh
);
5645 tcg_gen_and_vec(vece
, d
, d
, m
);
5646 tcg_gen_or_vec(vece
, d
, d
, t
);
5648 tcg_temp_free_vec(t
);
5649 tcg_temp_free_vec(m
);
5653 static const TCGOpcode vecop_list_sli
[] = { INDEX_op_shli_vec
, 0 };
5655 const GVecGen2i sli_op
[4] = {
5656 { .fni8
= gen_shl8_ins_i64
,
5657 .fniv
= gen_shl_ins_vec
,
5659 .opt_opc
= vecop_list_sli
,
5661 { .fni8
= gen_shl16_ins_i64
,
5662 .fniv
= gen_shl_ins_vec
,
5664 .opt_opc
= vecop_list_sli
,
5666 { .fni4
= gen_shl32_ins_i32
,
5667 .fniv
= gen_shl_ins_vec
,
5669 .opt_opc
= vecop_list_sli
,
5671 { .fni8
= gen_shl64_ins_i64
,
5672 .fniv
= gen_shl_ins_vec
,
5673 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5675 .opt_opc
= vecop_list_sli
,
5679 static void gen_mla8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5681 gen_helper_neon_mul_u8(a
, a
, b
);
5682 gen_helper_neon_add_u8(d
, d
, a
);
5685 static void gen_mls8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5687 gen_helper_neon_mul_u8(a
, a
, b
);
5688 gen_helper_neon_sub_u8(d
, d
, a
);
5691 static void gen_mla16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5693 gen_helper_neon_mul_u16(a
, a
, b
);
5694 gen_helper_neon_add_u16(d
, d
, a
);
5697 static void gen_mls16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5699 gen_helper_neon_mul_u16(a
, a
, b
);
5700 gen_helper_neon_sub_u16(d
, d
, a
);
5703 static void gen_mla32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5705 tcg_gen_mul_i32(a
, a
, b
);
5706 tcg_gen_add_i32(d
, d
, a
);
5709 static void gen_mls32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5711 tcg_gen_mul_i32(a
, a
, b
);
5712 tcg_gen_sub_i32(d
, d
, a
);
5715 static void gen_mla64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5717 tcg_gen_mul_i64(a
, a
, b
);
5718 tcg_gen_add_i64(d
, d
, a
);
5721 static void gen_mls64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5723 tcg_gen_mul_i64(a
, a
, b
);
5724 tcg_gen_sub_i64(d
, d
, a
);
5727 static void gen_mla_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5729 tcg_gen_mul_vec(vece
, a
, a
, b
);
5730 tcg_gen_add_vec(vece
, d
, d
, a
);
5733 static void gen_mls_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5735 tcg_gen_mul_vec(vece
, a
, a
, b
);
5736 tcg_gen_sub_vec(vece
, d
, d
, a
);
5739 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
5740 * these tables are shared with AArch64 which does support them.
5743 static const TCGOpcode vecop_list_mla
[] = {
5744 INDEX_op_mul_vec
, INDEX_op_add_vec
, 0
5747 static const TCGOpcode vecop_list_mls
[] = {
5748 INDEX_op_mul_vec
, INDEX_op_sub_vec
, 0
5751 const GVecGen3 mla_op
[4] = {
5752 { .fni4
= gen_mla8_i32
,
5753 .fniv
= gen_mla_vec
,
5755 .opt_opc
= vecop_list_mla
,
5757 { .fni4
= gen_mla16_i32
,
5758 .fniv
= gen_mla_vec
,
5760 .opt_opc
= vecop_list_mla
,
5762 { .fni4
= gen_mla32_i32
,
5763 .fniv
= gen_mla_vec
,
5765 .opt_opc
= vecop_list_mla
,
5767 { .fni8
= gen_mla64_i64
,
5768 .fniv
= gen_mla_vec
,
5769 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5771 .opt_opc
= vecop_list_mla
,
5775 const GVecGen3 mls_op
[4] = {
5776 { .fni4
= gen_mls8_i32
,
5777 .fniv
= gen_mls_vec
,
5779 .opt_opc
= vecop_list_mls
,
5781 { .fni4
= gen_mls16_i32
,
5782 .fniv
= gen_mls_vec
,
5784 .opt_opc
= vecop_list_mls
,
5786 { .fni4
= gen_mls32_i32
,
5787 .fniv
= gen_mls_vec
,
5789 .opt_opc
= vecop_list_mls
,
5791 { .fni8
= gen_mls64_i64
,
5792 .fniv
= gen_mls_vec
,
5793 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5795 .opt_opc
= vecop_list_mls
,
5799 /* CMTST : test is "if (X & Y != 0)". */
5800 static void gen_cmtst_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
5802 tcg_gen_and_i32(d
, a
, b
);
5803 tcg_gen_setcondi_i32(TCG_COND_NE
, d
, d
, 0);
5804 tcg_gen_neg_i32(d
, d
);
5807 void gen_cmtst_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
5809 tcg_gen_and_i64(d
, a
, b
);
5810 tcg_gen_setcondi_i64(TCG_COND_NE
, d
, d
, 0);
5811 tcg_gen_neg_i64(d
, d
);
5814 static void gen_cmtst_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
5816 tcg_gen_and_vec(vece
, d
, a
, b
);
5817 tcg_gen_dupi_vec(vece
, a
, 0);
5818 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, d
, d
, a
);
5821 static const TCGOpcode vecop_list_cmtst
[] = { INDEX_op_cmp_vec
, 0 };
5823 const GVecGen3 cmtst_op
[4] = {
5824 { .fni4
= gen_helper_neon_tst_u8
,
5825 .fniv
= gen_cmtst_vec
,
5826 .opt_opc
= vecop_list_cmtst
,
5828 { .fni4
= gen_helper_neon_tst_u16
,
5829 .fniv
= gen_cmtst_vec
,
5830 .opt_opc
= vecop_list_cmtst
,
5832 { .fni4
= gen_cmtst_i32
,
5833 .fniv
= gen_cmtst_vec
,
5834 .opt_opc
= vecop_list_cmtst
,
5836 { .fni8
= gen_cmtst_i64
,
5837 .fniv
= gen_cmtst_vec
,
5838 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
5839 .opt_opc
= vecop_list_cmtst
,
5843 static void gen_uqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5844 TCGv_vec a
, TCGv_vec b
)
5846 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5847 tcg_gen_add_vec(vece
, x
, a
, b
);
5848 tcg_gen_usadd_vec(vece
, t
, a
, b
);
5849 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5850 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5851 tcg_temp_free_vec(x
);
5854 static const TCGOpcode vecop_list_uqadd
[] = {
5855 INDEX_op_usadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
5858 const GVecGen4 uqadd_op
[4] = {
5859 { .fniv
= gen_uqadd_vec
,
5860 .fno
= gen_helper_gvec_uqadd_b
,
5862 .opt_opc
= vecop_list_uqadd
,
5864 { .fniv
= gen_uqadd_vec
,
5865 .fno
= gen_helper_gvec_uqadd_h
,
5867 .opt_opc
= vecop_list_uqadd
,
5869 { .fniv
= gen_uqadd_vec
,
5870 .fno
= gen_helper_gvec_uqadd_s
,
5872 .opt_opc
= vecop_list_uqadd
,
5874 { .fniv
= gen_uqadd_vec
,
5875 .fno
= gen_helper_gvec_uqadd_d
,
5877 .opt_opc
= vecop_list_uqadd
,
5881 static void gen_sqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5882 TCGv_vec a
, TCGv_vec b
)
5884 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5885 tcg_gen_add_vec(vece
, x
, a
, b
);
5886 tcg_gen_ssadd_vec(vece
, t
, a
, b
);
5887 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5888 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5889 tcg_temp_free_vec(x
);
5892 static const TCGOpcode vecop_list_sqadd
[] = {
5893 INDEX_op_ssadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
5896 const GVecGen4 sqadd_op
[4] = {
5897 { .fniv
= gen_sqadd_vec
,
5898 .fno
= gen_helper_gvec_sqadd_b
,
5899 .opt_opc
= vecop_list_sqadd
,
5902 { .fniv
= gen_sqadd_vec
,
5903 .fno
= gen_helper_gvec_sqadd_h
,
5904 .opt_opc
= vecop_list_sqadd
,
5907 { .fniv
= gen_sqadd_vec
,
5908 .fno
= gen_helper_gvec_sqadd_s
,
5909 .opt_opc
= vecop_list_sqadd
,
5912 { .fniv
= gen_sqadd_vec
,
5913 .fno
= gen_helper_gvec_sqadd_d
,
5914 .opt_opc
= vecop_list_sqadd
,
5919 static void gen_uqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5920 TCGv_vec a
, TCGv_vec b
)
5922 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5923 tcg_gen_sub_vec(vece
, x
, a
, b
);
5924 tcg_gen_ussub_vec(vece
, t
, a
, b
);
5925 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5926 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5927 tcg_temp_free_vec(x
);
5930 static const TCGOpcode vecop_list_uqsub
[] = {
5931 INDEX_op_ussub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
5934 const GVecGen4 uqsub_op
[4] = {
5935 { .fniv
= gen_uqsub_vec
,
5936 .fno
= gen_helper_gvec_uqsub_b
,
5937 .opt_opc
= vecop_list_uqsub
,
5940 { .fniv
= gen_uqsub_vec
,
5941 .fno
= gen_helper_gvec_uqsub_h
,
5942 .opt_opc
= vecop_list_uqsub
,
5945 { .fniv
= gen_uqsub_vec
,
5946 .fno
= gen_helper_gvec_uqsub_s
,
5947 .opt_opc
= vecop_list_uqsub
,
5950 { .fniv
= gen_uqsub_vec
,
5951 .fno
= gen_helper_gvec_uqsub_d
,
5952 .opt_opc
= vecop_list_uqsub
,
5957 static void gen_sqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
5958 TCGv_vec a
, TCGv_vec b
)
5960 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
5961 tcg_gen_sub_vec(vece
, x
, a
, b
);
5962 tcg_gen_sssub_vec(vece
, t
, a
, b
);
5963 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
5964 tcg_gen_or_vec(vece
, sat
, sat
, x
);
5965 tcg_temp_free_vec(x
);
5968 static const TCGOpcode vecop_list_sqsub
[] = {
5969 INDEX_op_sssub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
5972 const GVecGen4 sqsub_op
[4] = {
5973 { .fniv
= gen_sqsub_vec
,
5974 .fno
= gen_helper_gvec_sqsub_b
,
5975 .opt_opc
= vecop_list_sqsub
,
5978 { .fniv
= gen_sqsub_vec
,
5979 .fno
= gen_helper_gvec_sqsub_h
,
5980 .opt_opc
= vecop_list_sqsub
,
5983 { .fniv
= gen_sqsub_vec
,
5984 .fno
= gen_helper_gvec_sqsub_s
,
5985 .opt_opc
= vecop_list_sqsub
,
5988 { .fniv
= gen_sqsub_vec
,
5989 .fno
= gen_helper_gvec_sqsub_d
,
5990 .opt_opc
= vecop_list_sqsub
,
5995 /* Translate a NEON data processing instruction. Return nonzero if the
5996 instruction is invalid.
5997 We process data in a mixture of 32-bit and 64-bit chunks.
5998 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
6000 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
6004 int rd
, rn
, rm
, rd_ofs
, rn_ofs
, rm_ofs
;
6013 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
6014 TCGv_ptr ptr1
, ptr2
, ptr3
;
6017 /* FIXME: this access check should not take precedence over UNDEF
6018 * for invalid encodings; we will generate incorrect syndrome information
6019 * for attempts to execute invalid vfp/neon encodings with FP disabled.
6021 if (s
->fp_excp_el
) {
6022 gen_exception_insn(s
, 4, EXCP_UDEF
,
6023 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
6027 if (!s
->vfp_enabled
)
6029 q
= (insn
& (1 << 6)) != 0;
6030 u
= (insn
>> 24) & 1;
6031 VFP_DREG_D(rd
, insn
);
6032 VFP_DREG_N(rn
, insn
);
6033 VFP_DREG_M(rm
, insn
);
6034 size
= (insn
>> 20) & 3;
6035 vec_size
= q
? 16 : 8;
6036 rd_ofs
= neon_reg_offset(rd
, 0);
6037 rn_ofs
= neon_reg_offset(rn
, 0);
6038 rm_ofs
= neon_reg_offset(rm
, 0);
6040 if ((insn
& (1 << 23)) == 0) {
6041 /* Three register same length. */
6042 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
6043 /* Catch invalid op and bad size combinations: UNDEF */
6044 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
6047 /* All insns of this form UNDEF for either this condition or the
6048 * superset of cases "Q==1"; we catch the latter later.
6050 if (q
&& ((rd
| rn
| rm
) & 1)) {
6055 /* The SHA-1/SHA-256 3-register instructions require special
6056 * treatment here, as their size field is overloaded as an
6057 * op type selector, and they all consume their input in a
6063 if (!u
) { /* SHA-1 */
6064 if (!dc_isar_feature(aa32_sha1
, s
)) {
6067 ptr1
= vfp_reg_ptr(true, rd
);
6068 ptr2
= vfp_reg_ptr(true, rn
);
6069 ptr3
= vfp_reg_ptr(true, rm
);
6070 tmp4
= tcg_const_i32(size
);
6071 gen_helper_crypto_sha1_3reg(ptr1
, ptr2
, ptr3
, tmp4
);
6072 tcg_temp_free_i32(tmp4
);
6073 } else { /* SHA-256 */
6074 if (!dc_isar_feature(aa32_sha2
, s
) || size
== 3) {
6077 ptr1
= vfp_reg_ptr(true, rd
);
6078 ptr2
= vfp_reg_ptr(true, rn
);
6079 ptr3
= vfp_reg_ptr(true, rm
);
6082 gen_helper_crypto_sha256h(ptr1
, ptr2
, ptr3
);
6085 gen_helper_crypto_sha256h2(ptr1
, ptr2
, ptr3
);
6088 gen_helper_crypto_sha256su1(ptr1
, ptr2
, ptr3
);
6092 tcg_temp_free_ptr(ptr1
);
6093 tcg_temp_free_ptr(ptr2
);
6094 tcg_temp_free_ptr(ptr3
);
6097 case NEON_3R_VPADD_VQRDMLAH
:
6104 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s16
,
6107 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s32
,
6112 case NEON_3R_VFM_VQRDMLSH
:
6123 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s16
,
6126 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s32
,
6131 case NEON_3R_LOGIC
: /* Logic ops. */
6132 switch ((u
<< 2) | size
) {
6134 tcg_gen_gvec_and(0, rd_ofs
, rn_ofs
, rm_ofs
,
6135 vec_size
, vec_size
);
6138 tcg_gen_gvec_andc(0, rd_ofs
, rn_ofs
, rm_ofs
,
6139 vec_size
, vec_size
);
6142 tcg_gen_gvec_or(0, rd_ofs
, rn_ofs
, rm_ofs
,
6143 vec_size
, vec_size
);
6146 tcg_gen_gvec_orc(0, rd_ofs
, rn_ofs
, rm_ofs
,
6147 vec_size
, vec_size
);
6150 tcg_gen_gvec_xor(0, rd_ofs
, rn_ofs
, rm_ofs
,
6151 vec_size
, vec_size
);
6154 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rd_ofs
, rn_ofs
, rm_ofs
,
6155 vec_size
, vec_size
);
6158 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rn_ofs
, rd_ofs
,
6159 vec_size
, vec_size
);
6162 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rd_ofs
, rn_ofs
,
6163 vec_size
, vec_size
);
6168 case NEON_3R_VADD_VSUB
:
6170 tcg_gen_gvec_sub(size
, rd_ofs
, rn_ofs
, rm_ofs
,
6171 vec_size
, vec_size
);
6173 tcg_gen_gvec_add(size
, rd_ofs
, rn_ofs
, rm_ofs
,
6174 vec_size
, vec_size
);
6179 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
6180 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
6181 (u
? uqadd_op
: sqadd_op
) + size
);
6185 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
6186 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
6187 (u
? uqsub_op
: sqsub_op
) + size
);
6190 case NEON_3R_VMUL
: /* VMUL */
6192 /* Polynomial case allows only P8 and is handled below. */
6197 tcg_gen_gvec_mul(size
, rd_ofs
, rn_ofs
, rm_ofs
,
6198 vec_size
, vec_size
);
6203 case NEON_3R_VML
: /* VMLA, VMLS */
6204 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
,
6205 u
? &mls_op
[size
] : &mla_op
[size
]);
6208 case NEON_3R_VTST_VCEQ
:
6210 tcg_gen_gvec_cmp(TCG_COND_EQ
, size
, rd_ofs
, rn_ofs
, rm_ofs
,
6211 vec_size
, vec_size
);
6213 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
,
6214 vec_size
, vec_size
, &cmtst_op
[size
]);
6219 tcg_gen_gvec_cmp(u
? TCG_COND_GTU
: TCG_COND_GT
, size
,
6220 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
6224 tcg_gen_gvec_cmp(u
? TCG_COND_GEU
: TCG_COND_GE
, size
,
6225 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
6230 tcg_gen_gvec_umax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
6231 vec_size
, vec_size
);
6233 tcg_gen_gvec_smax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
6234 vec_size
, vec_size
);
6239 tcg_gen_gvec_umin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
6240 vec_size
, vec_size
);
6242 tcg_gen_gvec_smin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
6243 vec_size
, vec_size
);
6249 /* 64-bit element instructions. */
6250 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6251 neon_load_reg64(cpu_V0
, rn
+ pass
);
6252 neon_load_reg64(cpu_V1
, rm
+ pass
);
6256 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
6258 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
6263 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6266 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6272 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
6274 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
6277 case NEON_3R_VQRSHL
:
6279 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
6282 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
6289 neon_store_reg64(cpu_V0
, rd
+ pass
);
6298 case NEON_3R_VQRSHL
:
6301 /* Shift instruction operands are reversed. */
6307 case NEON_3R_VPADD_VQRDMLAH
:
6312 case NEON_3R_FLOAT_ARITH
:
6313 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
6315 case NEON_3R_FLOAT_MINMAX
:
6316 pairwise
= u
; /* if VPMIN/VPMAX (float) */
6318 case NEON_3R_FLOAT_CMP
:
6320 /* no encoding for U=0 C=1x */
6324 case NEON_3R_FLOAT_ACMP
:
6329 case NEON_3R_FLOAT_MISC
:
6330 /* VMAXNM/VMINNM in ARMv8 */
6331 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6335 case NEON_3R_VFM_VQRDMLSH
:
6336 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
6344 if (pairwise
&& q
) {
6345 /* All the pairwise insns UNDEF if Q is set */
6349 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6354 tmp
= neon_load_reg(rn
, 0);
6355 tmp2
= neon_load_reg(rn
, 1);
6357 tmp
= neon_load_reg(rm
, 0);
6358 tmp2
= neon_load_reg(rm
, 1);
6362 tmp
= neon_load_reg(rn
, pass
);
6363 tmp2
= neon_load_reg(rm
, pass
);
6367 GEN_NEON_INTEGER_OP(hadd
);
6369 case NEON_3R_VRHADD
:
6370 GEN_NEON_INTEGER_OP(rhadd
);
6373 GEN_NEON_INTEGER_OP(hsub
);
6376 GEN_NEON_INTEGER_OP(shl
);
6379 GEN_NEON_INTEGER_OP_ENV(qshl
);
6382 GEN_NEON_INTEGER_OP(rshl
);
6384 case NEON_3R_VQRSHL
:
6385 GEN_NEON_INTEGER_OP_ENV(qrshl
);
6388 GEN_NEON_INTEGER_OP(abd
);
6391 GEN_NEON_INTEGER_OP(abd
);
6392 tcg_temp_free_i32(tmp2
);
6393 tmp2
= neon_load_reg(rd
, pass
);
6394 gen_neon_add(size
, tmp
, tmp2
);
6397 /* VMUL.P8; other cases already eliminated. */
6398 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
6401 GEN_NEON_INTEGER_OP(pmax
);
6404 GEN_NEON_INTEGER_OP(pmin
);
6406 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
6407 if (!u
) { /* VQDMULH */
6410 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6413 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6417 } else { /* VQRDMULH */
6420 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6423 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6429 case NEON_3R_VPADD_VQRDMLAH
:
6431 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
6432 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
6433 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
6437 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
6439 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6440 switch ((u
<< 2) | size
) {
6443 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6446 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
6449 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
6454 tcg_temp_free_ptr(fpstatus
);
6457 case NEON_3R_FLOAT_MULTIPLY
:
6459 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6460 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6462 tcg_temp_free_i32(tmp2
);
6463 tmp2
= neon_load_reg(rd
, pass
);
6465 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6467 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6470 tcg_temp_free_ptr(fpstatus
);
6473 case NEON_3R_FLOAT_CMP
:
6475 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6477 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6480 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6482 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6485 tcg_temp_free_ptr(fpstatus
);
6488 case NEON_3R_FLOAT_ACMP
:
6490 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6492 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6494 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6496 tcg_temp_free_ptr(fpstatus
);
6499 case NEON_3R_FLOAT_MINMAX
:
6501 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6503 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6505 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6507 tcg_temp_free_ptr(fpstatus
);
6510 case NEON_3R_FLOAT_MISC
:
6513 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6515 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6517 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6519 tcg_temp_free_ptr(fpstatus
);
6522 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6524 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6528 case NEON_3R_VFM_VQRDMLSH
:
6530 /* VFMA, VFMS: fused multiply-add */
6531 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6532 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6535 gen_helper_vfp_negs(tmp
, tmp
);
6537 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6538 tcg_temp_free_i32(tmp3
);
6539 tcg_temp_free_ptr(fpstatus
);
6545 tcg_temp_free_i32(tmp2
);
6547 /* Save the result. For elementwise operations we can put it
6548 straight into the destination register. For pairwise operations
6549 we have to be careful to avoid clobbering the source operands. */
6550 if (pairwise
&& rd
== rm
) {
6551 neon_store_scratch(pass
, tmp
);
6553 neon_store_reg(rd
, pass
, tmp
);
6557 if (pairwise
&& rd
== rm
) {
6558 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6559 tmp
= neon_load_scratch(pass
);
6560 neon_store_reg(rd
, pass
, tmp
);
6563 /* End of 3 register same size operations. */
6564 } else if (insn
& (1 << 4)) {
6565 if ((insn
& 0x00380080) != 0) {
6566 /* Two registers and shift. */
6567 op
= (insn
>> 8) & 0xf;
6568 if (insn
& (1 << 7)) {
6576 while ((insn
& (1 << (size
+ 19))) == 0)
6579 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6581 /* Shift by immediate:
6582 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6583 if (q
&& ((rd
| rm
) & 1)) {
6586 if (!u
&& (op
== 4 || op
== 6)) {
6589 /* Right shifts are encoded as N - shift, where N is the
6590 element size in bits. */
6592 shift
= shift
- (1 << (size
+ 3));
6597 /* Right shift comes here negative. */
6599 /* Shifts larger than the element size are architecturally
6600 * valid. Unsigned results in all zeros; signed results
6604 tcg_gen_gvec_sari(size
, rd_ofs
, rm_ofs
,
6605 MIN(shift
, (8 << size
) - 1),
6606 vec_size
, vec_size
);
6607 } else if (shift
>= 8 << size
) {
6608 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
6610 tcg_gen_gvec_shri(size
, rd_ofs
, rm_ofs
, shift
,
6611 vec_size
, vec_size
);
6616 /* Right shift comes here negative. */
6618 /* Shifts larger than the element size are architecturally
6619 * valid. Unsigned results in all zeros; signed results
6623 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6624 MIN(shift
, (8 << size
) - 1),
6626 } else if (shift
>= 8 << size
) {
6629 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6630 shift
, &usra_op
[size
]);
6638 /* Right shift comes here negative. */
6640 /* Shift out of range leaves destination unchanged. */
6641 if (shift
< 8 << size
) {
6642 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
6643 shift
, &sri_op
[size
]);
6647 case 5: /* VSHL, VSLI */
6649 /* Shift out of range leaves destination unchanged. */
6650 if (shift
< 8 << size
) {
6651 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
,
6652 vec_size
, shift
, &sli_op
[size
]);
6655 /* Shifts larger than the element size are
6656 * architecturally valid and results in zero.
6658 if (shift
>= 8 << size
) {
6659 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
6661 tcg_gen_gvec_shli(size
, rd_ofs
, rm_ofs
, shift
,
6662 vec_size
, vec_size
);
6674 /* To avoid excessive duplication of ops we implement shift
6675 * by immediate using the variable shift operations.
6677 imm
= dup_const(size
, shift
);
6679 for (pass
= 0; pass
< count
; pass
++) {
6681 neon_load_reg64(cpu_V0
, rm
+ pass
);
6682 tcg_gen_movi_i64(cpu_V1
, imm
);
6687 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6689 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6691 case 6: /* VQSHLU */
6692 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6697 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6700 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6705 g_assert_not_reached();
6709 neon_load_reg64(cpu_V1
, rd
+ pass
);
6710 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6712 neon_store_reg64(cpu_V0
, rd
+ pass
);
6713 } else { /* size < 3 */
6714 /* Operands in T0 and T1. */
6715 tmp
= neon_load_reg(rm
, pass
);
6716 tmp2
= tcg_temp_new_i32();
6717 tcg_gen_movi_i32(tmp2
, imm
);
6721 GEN_NEON_INTEGER_OP(rshl
);
6723 case 6: /* VQSHLU */
6726 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6730 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6734 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6742 GEN_NEON_INTEGER_OP_ENV(qshl
);
6745 g_assert_not_reached();
6747 tcg_temp_free_i32(tmp2
);
6751 tmp2
= neon_load_reg(rd
, pass
);
6752 gen_neon_add(size
, tmp
, tmp2
);
6753 tcg_temp_free_i32(tmp2
);
6755 neon_store_reg(rd
, pass
, tmp
);
6758 } else if (op
< 10) {
6759 /* Shift by immediate and narrow:
6760 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6761 int input_unsigned
= (op
== 8) ? !u
: u
;
6765 shift
= shift
- (1 << (size
+ 3));
6768 tmp64
= tcg_const_i64(shift
);
6769 neon_load_reg64(cpu_V0
, rm
);
6770 neon_load_reg64(cpu_V1
, rm
+ 1);
6771 for (pass
= 0; pass
< 2; pass
++) {
6779 if (input_unsigned
) {
6780 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6782 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6785 if (input_unsigned
) {
6786 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6788 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6791 tmp
= tcg_temp_new_i32();
6792 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6793 neon_store_reg(rd
, pass
, tmp
);
6795 tcg_temp_free_i64(tmp64
);
6798 imm
= (uint16_t)shift
;
6802 imm
= (uint32_t)shift
;
6804 tmp2
= tcg_const_i32(imm
);
6805 tmp4
= neon_load_reg(rm
+ 1, 0);
6806 tmp5
= neon_load_reg(rm
+ 1, 1);
6807 for (pass
= 0; pass
< 2; pass
++) {
6809 tmp
= neon_load_reg(rm
, 0);
6813 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6816 tmp3
= neon_load_reg(rm
, 1);
6820 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6822 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6823 tcg_temp_free_i32(tmp
);
6824 tcg_temp_free_i32(tmp3
);
6825 tmp
= tcg_temp_new_i32();
6826 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6827 neon_store_reg(rd
, pass
, tmp
);
6829 tcg_temp_free_i32(tmp2
);
6831 } else if (op
== 10) {
6833 if (q
|| (rd
& 1)) {
6836 tmp
= neon_load_reg(rm
, 0);
6837 tmp2
= neon_load_reg(rm
, 1);
6838 for (pass
= 0; pass
< 2; pass
++) {
6842 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6845 /* The shift is less than the width of the source
6846 type, so we can just shift the whole register. */
6847 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6848 /* Widen the result of shift: we need to clear
6849 * the potential overflow bits resulting from
6850 * left bits of the narrow input appearing as
6851 * right bits of left the neighbour narrow
6853 if (size
< 2 || !u
) {
6856 imm
= (0xffu
>> (8 - shift
));
6858 } else if (size
== 1) {
6859 imm
= 0xffff >> (16 - shift
);
6862 imm
= 0xffffffff >> (32 - shift
);
6865 imm64
= imm
| (((uint64_t)imm
) << 32);
6869 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6872 neon_store_reg64(cpu_V0
, rd
+ pass
);
6874 } else if (op
>= 14) {
6875 /* VCVT fixed-point. */
6876 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6879 /* We have already masked out the must-be-1 top bit of imm6,
6880 * hence this 32-shift where the ARM ARM has 64-imm6.
6883 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6884 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6887 gen_vfp_ulto(0, shift
, 1);
6889 gen_vfp_slto(0, shift
, 1);
6892 gen_vfp_toul(0, shift
, 1);
6894 gen_vfp_tosl(0, shift
, 1);
6896 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6901 } else { /* (insn & 0x00380080) == 0 */
6902 int invert
, reg_ofs
, vec_size
;
6904 if (q
&& (rd
& 1)) {
6908 op
= (insn
>> 8) & 0xf;
6909 /* One register and immediate. */
6910 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6911 invert
= (insn
& (1 << 5)) != 0;
6912 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6913 * We choose to not special-case this and will behave as if a
6914 * valid constant encoding of 0 had been given.
6933 imm
= (imm
<< 8) | (imm
<< 24);
6936 imm
= (imm
<< 8) | 0xff;
6939 imm
= (imm
<< 16) | 0xffff;
6942 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6951 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6952 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6959 reg_ofs
= neon_reg_offset(rd
, 0);
6960 vec_size
= q
? 16 : 8;
6962 if (op
& 1 && op
< 12) {
6964 /* The immediate value has already been inverted,
6965 * so BIC becomes AND.
6967 tcg_gen_gvec_andi(MO_32
, reg_ofs
, reg_ofs
, imm
,
6968 vec_size
, vec_size
);
6970 tcg_gen_gvec_ori(MO_32
, reg_ofs
, reg_ofs
, imm
,
6971 vec_size
, vec_size
);
6975 if (op
== 14 && invert
) {
6976 TCGv_i64 t64
= tcg_temp_new_i64();
6978 for (pass
= 0; pass
<= q
; ++pass
) {
6982 for (n
= 0; n
< 8; n
++) {
6983 if (imm
& (1 << (n
+ pass
* 8))) {
6984 val
|= 0xffull
<< (n
* 8);
6987 tcg_gen_movi_i64(t64
, val
);
6988 neon_store_reg64(t64
, rd
+ pass
);
6990 tcg_temp_free_i64(t64
);
6992 tcg_gen_gvec_dup32i(reg_ofs
, vec_size
, vec_size
, imm
);
6996 } else { /* (insn & 0x00800010 == 0x00800000) */
6998 op
= (insn
>> 8) & 0xf;
6999 if ((insn
& (1 << 6)) == 0) {
7000 /* Three registers of different lengths. */
7004 /* undefreq: bit 0 : UNDEF if size == 0
7005 * bit 1 : UNDEF if size == 1
7006 * bit 2 : UNDEF if size == 2
7007 * bit 3 : UNDEF if U == 1
7008 * Note that [2:0] set implies 'always UNDEF'
7011 /* prewiden, src1_wide, src2_wide, undefreq */
7012 static const int neon_3reg_wide
[16][4] = {
7013 {1, 0, 0, 0}, /* VADDL */
7014 {1, 1, 0, 0}, /* VADDW */
7015 {1, 0, 0, 0}, /* VSUBL */
7016 {1, 1, 0, 0}, /* VSUBW */
7017 {0, 1, 1, 0}, /* VADDHN */
7018 {0, 0, 0, 0}, /* VABAL */
7019 {0, 1, 1, 0}, /* VSUBHN */
7020 {0, 0, 0, 0}, /* VABDL */
7021 {0, 0, 0, 0}, /* VMLAL */
7022 {0, 0, 0, 9}, /* VQDMLAL */
7023 {0, 0, 0, 0}, /* VMLSL */
7024 {0, 0, 0, 9}, /* VQDMLSL */
7025 {0, 0, 0, 0}, /* Integer VMULL */
7026 {0, 0, 0, 1}, /* VQDMULL */
7027 {0, 0, 0, 0xa}, /* Polynomial VMULL */
7028 {0, 0, 0, 7}, /* Reserved: always UNDEF */
7031 prewiden
= neon_3reg_wide
[op
][0];
7032 src1_wide
= neon_3reg_wide
[op
][1];
7033 src2_wide
= neon_3reg_wide
[op
][2];
7034 undefreq
= neon_3reg_wide
[op
][3];
7036 if ((undefreq
& (1 << size
)) ||
7037 ((undefreq
& 8) && u
)) {
7040 if ((src1_wide
&& (rn
& 1)) ||
7041 (src2_wide
&& (rm
& 1)) ||
7042 (!src2_wide
&& (rd
& 1))) {
7046 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
7047 * outside the loop below as it only performs a single pass.
7049 if (op
== 14 && size
== 2) {
7050 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
7052 if (!dc_isar_feature(aa32_pmull
, s
)) {
7055 tcg_rn
= tcg_temp_new_i64();
7056 tcg_rm
= tcg_temp_new_i64();
7057 tcg_rd
= tcg_temp_new_i64();
7058 neon_load_reg64(tcg_rn
, rn
);
7059 neon_load_reg64(tcg_rm
, rm
);
7060 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
7061 neon_store_reg64(tcg_rd
, rd
);
7062 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
7063 neon_store_reg64(tcg_rd
, rd
+ 1);
7064 tcg_temp_free_i64(tcg_rn
);
7065 tcg_temp_free_i64(tcg_rm
);
7066 tcg_temp_free_i64(tcg_rd
);
7070 /* Avoid overlapping operands. Wide source operands are
7071 always aligned so will never overlap with wide
7072 destinations in problematic ways. */
7073 if (rd
== rm
&& !src2_wide
) {
7074 tmp
= neon_load_reg(rm
, 1);
7075 neon_store_scratch(2, tmp
);
7076 } else if (rd
== rn
&& !src1_wide
) {
7077 tmp
= neon_load_reg(rn
, 1);
7078 neon_store_scratch(2, tmp
);
7081 for (pass
= 0; pass
< 2; pass
++) {
7083 neon_load_reg64(cpu_V0
, rn
+ pass
);
7086 if (pass
== 1 && rd
== rn
) {
7087 tmp
= neon_load_scratch(2);
7089 tmp
= neon_load_reg(rn
, pass
);
7092 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
7096 neon_load_reg64(cpu_V1
, rm
+ pass
);
7099 if (pass
== 1 && rd
== rm
) {
7100 tmp2
= neon_load_scratch(2);
7102 tmp2
= neon_load_reg(rm
, pass
);
7105 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
7109 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
7110 gen_neon_addl(size
);
7112 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
7113 gen_neon_subl(size
);
7115 case 5: case 7: /* VABAL, VABDL */
7116 switch ((size
<< 1) | u
) {
7118 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
7121 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
7124 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
7127 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
7130 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
7133 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
7137 tcg_temp_free_i32(tmp2
);
7138 tcg_temp_free_i32(tmp
);
7140 case 8: case 9: case 10: case 11: case 12: case 13:
7141 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
7142 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
7144 case 14: /* Polynomial VMULL */
7145 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
7146 tcg_temp_free_i32(tmp2
);
7147 tcg_temp_free_i32(tmp
);
7149 default: /* 15 is RESERVED: caught earlier */
7154 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
7155 neon_store_reg64(cpu_V0
, rd
+ pass
);
7156 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
7158 neon_load_reg64(cpu_V1
, rd
+ pass
);
7160 case 10: /* VMLSL */
7161 gen_neon_negl(cpu_V0
, size
);
7163 case 5: case 8: /* VABAL, VMLAL */
7164 gen_neon_addl(size
);
7166 case 9: case 11: /* VQDMLAL, VQDMLSL */
7167 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
7169 gen_neon_negl(cpu_V0
, size
);
7171 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
7176 neon_store_reg64(cpu_V0
, rd
+ pass
);
7177 } else if (op
== 4 || op
== 6) {
7178 /* Narrowing operation. */
7179 tmp
= tcg_temp_new_i32();
7183 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
7186 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
7189 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
7190 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
7197 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
7200 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
7203 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
7204 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
7205 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
7213 neon_store_reg(rd
, 0, tmp3
);
7214 neon_store_reg(rd
, 1, tmp
);
7217 /* Write back the result. */
7218 neon_store_reg64(cpu_V0
, rd
+ pass
);
7222 /* Two registers and a scalar. NB that for ops of this form
7223 * the ARM ARM labels bit 24 as Q, but it is in our variable
7230 case 1: /* Float VMLA scalar */
7231 case 5: /* Floating point VMLS scalar */
7232 case 9: /* Floating point VMUL scalar */
7237 case 0: /* Integer VMLA scalar */
7238 case 4: /* Integer VMLS scalar */
7239 case 8: /* Integer VMUL scalar */
7240 case 12: /* VQDMULH scalar */
7241 case 13: /* VQRDMULH scalar */
7242 if (u
&& ((rd
| rn
) & 1)) {
7245 tmp
= neon_get_scalar(size
, rm
);
7246 neon_store_scratch(0, tmp
);
7247 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
7248 tmp
= neon_load_scratch(0);
7249 tmp2
= neon_load_reg(rn
, pass
);
7252 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
7254 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
7256 } else if (op
== 13) {
7258 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
7260 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
7262 } else if (op
& 1) {
7263 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7264 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
7265 tcg_temp_free_ptr(fpstatus
);
7268 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
7269 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
7270 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
7274 tcg_temp_free_i32(tmp2
);
7277 tmp2
= neon_load_reg(rd
, pass
);
7280 gen_neon_add(size
, tmp
, tmp2
);
7284 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7285 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
7286 tcg_temp_free_ptr(fpstatus
);
7290 gen_neon_rsb(size
, tmp
, tmp2
);
7294 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7295 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
7296 tcg_temp_free_ptr(fpstatus
);
7302 tcg_temp_free_i32(tmp2
);
7304 neon_store_reg(rd
, pass
, tmp
);
7307 case 3: /* VQDMLAL scalar */
7308 case 7: /* VQDMLSL scalar */
7309 case 11: /* VQDMULL scalar */
7314 case 2: /* VMLAL sclar */
7315 case 6: /* VMLSL scalar */
7316 case 10: /* VMULL scalar */
7320 tmp2
= neon_get_scalar(size
, rm
);
7321 /* We need a copy of tmp2 because gen_neon_mull
7322 * deletes it during pass 0. */
7323 tmp4
= tcg_temp_new_i32();
7324 tcg_gen_mov_i32(tmp4
, tmp2
);
7325 tmp3
= neon_load_reg(rn
, 1);
7327 for (pass
= 0; pass
< 2; pass
++) {
7329 tmp
= neon_load_reg(rn
, 0);
7334 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
7336 neon_load_reg64(cpu_V1
, rd
+ pass
);
7340 gen_neon_negl(cpu_V0
, size
);
7343 gen_neon_addl(size
);
7346 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
7348 gen_neon_negl(cpu_V0
, size
);
7350 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
7356 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
7361 neon_store_reg64(cpu_V0
, rd
+ pass
);
7364 case 14: /* VQRDMLAH scalar */
7365 case 15: /* VQRDMLSH scalar */
7367 NeonGenThreeOpEnvFn
*fn
;
7369 if (!dc_isar_feature(aa32_rdm
, s
)) {
7372 if (u
&& ((rd
| rn
) & 1)) {
7377 fn
= gen_helper_neon_qrdmlah_s16
;
7379 fn
= gen_helper_neon_qrdmlah_s32
;
7383 fn
= gen_helper_neon_qrdmlsh_s16
;
7385 fn
= gen_helper_neon_qrdmlsh_s32
;
7389 tmp2
= neon_get_scalar(size
, rm
);
7390 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
7391 tmp
= neon_load_reg(rn
, pass
);
7392 tmp3
= neon_load_reg(rd
, pass
);
7393 fn(tmp
, cpu_env
, tmp
, tmp2
, tmp3
);
7394 tcg_temp_free_i32(tmp3
);
7395 neon_store_reg(rd
, pass
, tmp
);
7397 tcg_temp_free_i32(tmp2
);
7401 g_assert_not_reached();
7404 } else { /* size == 3 */
7407 imm
= (insn
>> 8) & 0xf;
7412 if (q
&& ((rd
| rn
| rm
) & 1)) {
7417 neon_load_reg64(cpu_V0
, rn
);
7419 neon_load_reg64(cpu_V1
, rn
+ 1);
7421 } else if (imm
== 8) {
7422 neon_load_reg64(cpu_V0
, rn
+ 1);
7424 neon_load_reg64(cpu_V1
, rm
);
7427 tmp64
= tcg_temp_new_i64();
7429 neon_load_reg64(cpu_V0
, rn
);
7430 neon_load_reg64(tmp64
, rn
+ 1);
7432 neon_load_reg64(cpu_V0
, rn
+ 1);
7433 neon_load_reg64(tmp64
, rm
);
7435 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
7436 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
7437 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7439 neon_load_reg64(cpu_V1
, rm
);
7441 neon_load_reg64(cpu_V1
, rm
+ 1);
7444 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7445 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
7446 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
7447 tcg_temp_free_i64(tmp64
);
7450 neon_load_reg64(cpu_V0
, rn
);
7451 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
7452 neon_load_reg64(cpu_V1
, rm
);
7453 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7454 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7456 neon_store_reg64(cpu_V0
, rd
);
7458 neon_store_reg64(cpu_V1
, rd
+ 1);
7460 } else if ((insn
& (1 << 11)) == 0) {
7461 /* Two register misc. */
7462 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
7463 size
= (insn
>> 18) & 3;
7464 /* UNDEF for unknown op values and bad op-size combinations */
7465 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
7468 if (neon_2rm_is_v8_op(op
) &&
7469 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7472 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
7473 q
&& ((rm
| rd
) & 1)) {
7477 case NEON_2RM_VREV64
:
7478 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
7479 tmp
= neon_load_reg(rm
, pass
* 2);
7480 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
7482 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7483 case 1: gen_swap_half(tmp
); break;
7484 case 2: /* no-op */ break;
7487 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
7489 neon_store_reg(rd
, pass
* 2, tmp2
);
7492 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
7493 case 1: gen_swap_half(tmp2
); break;
7496 neon_store_reg(rd
, pass
* 2, tmp2
);
7500 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
7501 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
7502 for (pass
= 0; pass
< q
+ 1; pass
++) {
7503 tmp
= neon_load_reg(rm
, pass
* 2);
7504 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
7505 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
7506 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
7508 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
7509 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
7510 case 2: tcg_gen_add_i64(CPU_V001
); break;
7513 if (op
>= NEON_2RM_VPADAL
) {
7515 neon_load_reg64(cpu_V1
, rd
+ pass
);
7516 gen_neon_addl(size
);
7518 neon_store_reg64(cpu_V0
, rd
+ pass
);
7524 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7525 tmp
= neon_load_reg(rm
, n
);
7526 tmp2
= neon_load_reg(rd
, n
+ 1);
7527 neon_store_reg(rm
, n
, tmp2
);
7528 neon_store_reg(rd
, n
+ 1, tmp
);
7535 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7540 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7544 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7545 /* also VQMOVUN; op field and mnemonics don't line up */
7550 for (pass
= 0; pass
< 2; pass
++) {
7551 neon_load_reg64(cpu_V0
, rm
+ pass
);
7552 tmp
= tcg_temp_new_i32();
7553 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7558 neon_store_reg(rd
, 0, tmp2
);
7559 neon_store_reg(rd
, 1, tmp
);
7563 case NEON_2RM_VSHLL
:
7564 if (q
|| (rd
& 1)) {
7567 tmp
= neon_load_reg(rm
, 0);
7568 tmp2
= neon_load_reg(rm
, 1);
7569 for (pass
= 0; pass
< 2; pass
++) {
7572 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7573 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7574 neon_store_reg64(cpu_V0
, rd
+ pass
);
7577 case NEON_2RM_VCVT_F16_F32
:
7582 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
7586 tmp
= tcg_temp_new_i32();
7587 tmp2
= tcg_temp_new_i32();
7588 fpst
= get_fpstatus_ptr(true);
7589 ahp
= get_ahp_flag();
7590 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7591 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, fpst
, ahp
);
7592 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7593 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, cpu_F0s
, fpst
, ahp
);
7594 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7595 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7596 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7597 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, fpst
, ahp
);
7598 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7599 neon_store_reg(rd
, 0, tmp2
);
7600 tmp2
= tcg_temp_new_i32();
7601 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, cpu_F0s
, fpst
, ahp
);
7602 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7603 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7604 neon_store_reg(rd
, 1, tmp2
);
7605 tcg_temp_free_i32(tmp
);
7606 tcg_temp_free_i32(ahp
);
7607 tcg_temp_free_ptr(fpst
);
7610 case NEON_2RM_VCVT_F32_F16
:
7614 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
7618 fpst
= get_fpstatus_ptr(true);
7619 ahp
= get_ahp_flag();
7620 tmp3
= tcg_temp_new_i32();
7621 tmp
= neon_load_reg(rm
, 0);
7622 tmp2
= neon_load_reg(rm
, 1);
7623 tcg_gen_ext16u_i32(tmp3
, tmp
);
7624 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7625 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7626 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7627 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7628 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7629 tcg_temp_free_i32(tmp
);
7630 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7631 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7632 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7633 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7634 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp3
, fpst
, ahp
);
7635 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7636 tcg_temp_free_i32(tmp2
);
7637 tcg_temp_free_i32(tmp3
);
7638 tcg_temp_free_i32(ahp
);
7639 tcg_temp_free_ptr(fpst
);
7642 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7643 if (!dc_isar_feature(aa32_aes
, s
) || ((rm
| rd
) & 1)) {
7646 ptr1
= vfp_reg_ptr(true, rd
);
7647 ptr2
= vfp_reg_ptr(true, rm
);
7649 /* Bit 6 is the lowest opcode bit; it distinguishes between
7650 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7652 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7654 if (op
== NEON_2RM_AESE
) {
7655 gen_helper_crypto_aese(ptr1
, ptr2
, tmp3
);
7657 gen_helper_crypto_aesmc(ptr1
, ptr2
, tmp3
);
7659 tcg_temp_free_ptr(ptr1
);
7660 tcg_temp_free_ptr(ptr2
);
7661 tcg_temp_free_i32(tmp3
);
7663 case NEON_2RM_SHA1H
:
7664 if (!dc_isar_feature(aa32_sha1
, s
) || ((rm
| rd
) & 1)) {
7667 ptr1
= vfp_reg_ptr(true, rd
);
7668 ptr2
= vfp_reg_ptr(true, rm
);
7670 gen_helper_crypto_sha1h(ptr1
, ptr2
);
7672 tcg_temp_free_ptr(ptr1
);
7673 tcg_temp_free_ptr(ptr2
);
7675 case NEON_2RM_SHA1SU1
:
7676 if ((rm
| rd
) & 1) {
7679 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7681 if (!dc_isar_feature(aa32_sha2
, s
)) {
7684 } else if (!dc_isar_feature(aa32_sha1
, s
)) {
7687 ptr1
= vfp_reg_ptr(true, rd
);
7688 ptr2
= vfp_reg_ptr(true, rm
);
7690 gen_helper_crypto_sha256su0(ptr1
, ptr2
);
7692 gen_helper_crypto_sha1su1(ptr1
, ptr2
);
7694 tcg_temp_free_ptr(ptr1
);
7695 tcg_temp_free_ptr(ptr2
);
7699 tcg_gen_gvec_not(0, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7702 tcg_gen_gvec_neg(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7705 tcg_gen_gvec_abs(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
7710 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7711 if (neon_2rm_is_float_op(op
)) {
7712 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7713 neon_reg_offset(rm
, pass
));
7716 tmp
= neon_load_reg(rm
, pass
);
7719 case NEON_2RM_VREV32
:
7721 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7722 case 1: gen_swap_half(tmp
); break;
7726 case NEON_2RM_VREV16
:
7731 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7732 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7733 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7739 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7740 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7741 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7746 gen_helper_neon_cnt_u8(tmp
, tmp
);
7748 case NEON_2RM_VQABS
:
7751 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7754 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7757 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7762 case NEON_2RM_VQNEG
:
7765 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7768 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7771 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7776 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7777 tmp2
= tcg_const_i32(0);
7779 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7780 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7781 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7784 tcg_temp_free_i32(tmp2
);
7785 if (op
== NEON_2RM_VCLE0
) {
7786 tcg_gen_not_i32(tmp
, tmp
);
7789 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7790 tmp2
= tcg_const_i32(0);
7792 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7793 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7794 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7797 tcg_temp_free_i32(tmp2
);
7798 if (op
== NEON_2RM_VCLT0
) {
7799 tcg_gen_not_i32(tmp
, tmp
);
7802 case NEON_2RM_VCEQ0
:
7803 tmp2
= tcg_const_i32(0);
7805 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7806 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7807 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7810 tcg_temp_free_i32(tmp2
);
7812 case NEON_2RM_VCGT0_F
:
7814 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7815 tmp2
= tcg_const_i32(0);
7816 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7817 tcg_temp_free_i32(tmp2
);
7818 tcg_temp_free_ptr(fpstatus
);
7821 case NEON_2RM_VCGE0_F
:
7823 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7824 tmp2
= tcg_const_i32(0);
7825 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7826 tcg_temp_free_i32(tmp2
);
7827 tcg_temp_free_ptr(fpstatus
);
7830 case NEON_2RM_VCEQ0_F
:
7832 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7833 tmp2
= tcg_const_i32(0);
7834 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7835 tcg_temp_free_i32(tmp2
);
7836 tcg_temp_free_ptr(fpstatus
);
7839 case NEON_2RM_VCLE0_F
:
7841 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7842 tmp2
= tcg_const_i32(0);
7843 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7844 tcg_temp_free_i32(tmp2
);
7845 tcg_temp_free_ptr(fpstatus
);
7848 case NEON_2RM_VCLT0_F
:
7850 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7851 tmp2
= tcg_const_i32(0);
7852 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7853 tcg_temp_free_i32(tmp2
);
7854 tcg_temp_free_ptr(fpstatus
);
7857 case NEON_2RM_VABS_F
:
7860 case NEON_2RM_VNEG_F
:
7864 tmp2
= neon_load_reg(rd
, pass
);
7865 neon_store_reg(rm
, pass
, tmp2
);
7868 tmp2
= neon_load_reg(rd
, pass
);
7870 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7871 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7874 neon_store_reg(rm
, pass
, tmp2
);
7876 case NEON_2RM_VRINTN
:
7877 case NEON_2RM_VRINTA
:
7878 case NEON_2RM_VRINTM
:
7879 case NEON_2RM_VRINTP
:
7880 case NEON_2RM_VRINTZ
:
7883 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7886 if (op
== NEON_2RM_VRINTZ
) {
7887 rmode
= FPROUNDING_ZERO
;
7889 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7892 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7893 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7895 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7896 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7898 tcg_temp_free_ptr(fpstatus
);
7899 tcg_temp_free_i32(tcg_rmode
);
7902 case NEON_2RM_VRINTX
:
7904 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7905 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7906 tcg_temp_free_ptr(fpstatus
);
7909 case NEON_2RM_VCVTAU
:
7910 case NEON_2RM_VCVTAS
:
7911 case NEON_2RM_VCVTNU
:
7912 case NEON_2RM_VCVTNS
:
7913 case NEON_2RM_VCVTPU
:
7914 case NEON_2RM_VCVTPS
:
7915 case NEON_2RM_VCVTMU
:
7916 case NEON_2RM_VCVTMS
:
7918 bool is_signed
= !extract32(insn
, 7, 1);
7919 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7920 TCGv_i32 tcg_rmode
, tcg_shift
;
7921 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7923 tcg_shift
= tcg_const_i32(0);
7924 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7925 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7929 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7932 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7936 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7938 tcg_temp_free_i32(tcg_rmode
);
7939 tcg_temp_free_i32(tcg_shift
);
7940 tcg_temp_free_ptr(fpst
);
7943 case NEON_2RM_VRECPE
:
7945 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7946 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7947 tcg_temp_free_ptr(fpstatus
);
7950 case NEON_2RM_VRSQRTE
:
7952 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7953 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7954 tcg_temp_free_ptr(fpstatus
);
7957 case NEON_2RM_VRECPE_F
:
7959 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7960 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7961 tcg_temp_free_ptr(fpstatus
);
7964 case NEON_2RM_VRSQRTE_F
:
7966 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7967 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7968 tcg_temp_free_ptr(fpstatus
);
7971 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7974 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7977 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7978 gen_vfp_tosiz(0, 1);
7980 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7981 gen_vfp_touiz(0, 1);
7984 /* Reserved op values were caught by the
7985 * neon_2rm_sizes[] check earlier.
7989 if (neon_2rm_is_float_op(op
)) {
7990 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7991 neon_reg_offset(rd
, pass
));
7993 neon_store_reg(rd
, pass
, tmp
);
7998 } else if ((insn
& (1 << 10)) == 0) {
8000 int n
= ((insn
>> 8) & 3) + 1;
8001 if ((rn
+ n
) > 32) {
8002 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
8003 * helper function running off the end of the register file.
8008 if (insn
& (1 << 6)) {
8009 tmp
= neon_load_reg(rd
, 0);
8011 tmp
= tcg_temp_new_i32();
8012 tcg_gen_movi_i32(tmp
, 0);
8014 tmp2
= neon_load_reg(rm
, 0);
8015 ptr1
= vfp_reg_ptr(true, rn
);
8016 tmp5
= tcg_const_i32(n
);
8017 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, ptr1
, tmp5
);
8018 tcg_temp_free_i32(tmp
);
8019 if (insn
& (1 << 6)) {
8020 tmp
= neon_load_reg(rd
, 1);
8022 tmp
= tcg_temp_new_i32();
8023 tcg_gen_movi_i32(tmp
, 0);
8025 tmp3
= neon_load_reg(rm
, 1);
8026 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, ptr1
, tmp5
);
8027 tcg_temp_free_i32(tmp5
);
8028 tcg_temp_free_ptr(ptr1
);
8029 neon_store_reg(rd
, 0, tmp2
);
8030 neon_store_reg(rd
, 1, tmp3
);
8031 tcg_temp_free_i32(tmp
);
8032 } else if ((insn
& 0x380) == 0) {
8037 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
8040 if (insn
& (1 << 16)) {
8042 element
= (insn
>> 17) & 7;
8043 } else if (insn
& (1 << 17)) {
8045 element
= (insn
>> 18) & 3;
8048 element
= (insn
>> 19) & 1;
8050 tcg_gen_gvec_dup_mem(size
, neon_reg_offset(rd
, 0),
8051 neon_element_offset(rm
, element
, size
),
8052 q
? 16 : 8, q
? 16 : 8);
8061 /* Advanced SIMD three registers of the same length extension.
8062 * 31 25 23 22 20 16 12 11 10 9 8 3 0
8063 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8064 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8065 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8067 static int disas_neon_insn_3same_ext(DisasContext
*s
, uint32_t insn
)
8069 gen_helper_gvec_3
*fn_gvec
= NULL
;
8070 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
8071 int rd
, rn
, rm
, opr_sz
;
8074 bool is_long
= false, q
= extract32(insn
, 6, 1);
8075 bool ptr_is_env
= false;
8077 if ((insn
& 0xfe200f10) == 0xfc200800) {
8078 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
8079 int size
= extract32(insn
, 20, 1);
8080 data
= extract32(insn
, 23, 2); /* rot */
8081 if (!dc_isar_feature(aa32_vcma
, s
)
8082 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
8085 fn_gvec_ptr
= size
? gen_helper_gvec_fcmlas
: gen_helper_gvec_fcmlah
;
8086 } else if ((insn
& 0xfea00f10) == 0xfc800800) {
8087 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
8088 int size
= extract32(insn
, 20, 1);
8089 data
= extract32(insn
, 24, 1); /* rot */
8090 if (!dc_isar_feature(aa32_vcma
, s
)
8091 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
8094 fn_gvec_ptr
= size
? gen_helper_gvec_fcadds
: gen_helper_gvec_fcaddh
;
8095 } else if ((insn
& 0xfeb00f00) == 0xfc200d00) {
8096 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
8097 bool u
= extract32(insn
, 4, 1);
8098 if (!dc_isar_feature(aa32_dp
, s
)) {
8101 fn_gvec
= u
? gen_helper_gvec_udot_b
: gen_helper_gvec_sdot_b
;
8102 } else if ((insn
& 0xff300f10) == 0xfc200810) {
8103 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
8104 int is_s
= extract32(insn
, 23, 1);
8105 if (!dc_isar_feature(aa32_fhm
, s
)) {
8109 data
= is_s
; /* is_2 == 0 */
8110 fn_gvec_ptr
= gen_helper_gvec_fmlal_a32
;
8116 VFP_DREG_D(rd
, insn
);
8120 if (q
|| !is_long
) {
8121 VFP_DREG_N(rn
, insn
);
8122 VFP_DREG_M(rm
, insn
);
8123 if ((rn
| rm
) & q
& !is_long
) {
8126 off_rn
= vfp_reg_offset(1, rn
);
8127 off_rm
= vfp_reg_offset(1, rm
);
8129 rn
= VFP_SREG_N(insn
);
8130 rm
= VFP_SREG_M(insn
);
8131 off_rn
= vfp_reg_offset(0, rn
);
8132 off_rm
= vfp_reg_offset(0, rm
);
8135 if (s
->fp_excp_el
) {
8136 gen_exception_insn(s
, 4, EXCP_UDEF
,
8137 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
8140 if (!s
->vfp_enabled
) {
8144 opr_sz
= (1 + q
) * 8;
8150 ptr
= get_fpstatus_ptr(1);
8152 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
8153 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
8155 tcg_temp_free_ptr(ptr
);
8158 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
8159 opr_sz
, opr_sz
, data
, fn_gvec
);
8164 /* Advanced SIMD two registers and a scalar extension.
8165 * 31 24 23 22 20 16 12 11 10 9 8 3 0
8166 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8167 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8168 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8172 static int disas_neon_insn_2reg_scalar_ext(DisasContext
*s
, uint32_t insn
)
8174 gen_helper_gvec_3
*fn_gvec
= NULL
;
8175 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
8176 int rd
, rn
, rm
, opr_sz
, data
;
8178 bool is_long
= false, q
= extract32(insn
, 6, 1);
8179 bool ptr_is_env
= false;
8181 if ((insn
& 0xff000f10) == 0xfe000800) {
8182 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
8183 int rot
= extract32(insn
, 20, 2);
8184 int size
= extract32(insn
, 23, 1);
8187 if (!dc_isar_feature(aa32_vcma
, s
)) {
8191 if (!dc_isar_feature(aa32_fp16_arith
, s
)) {
8194 /* For fp16, rm is just Vm, and index is M. */
8195 rm
= extract32(insn
, 0, 4);
8196 index
= extract32(insn
, 5, 1);
8198 /* For fp32, rm is the usual M:Vm, and index is 0. */
8199 VFP_DREG_M(rm
, insn
);
8202 data
= (index
<< 2) | rot
;
8203 fn_gvec_ptr
= (size
? gen_helper_gvec_fcmlas_idx
8204 : gen_helper_gvec_fcmlah_idx
);
8205 } else if ((insn
& 0xffb00f00) == 0xfe200d00) {
8206 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
8207 int u
= extract32(insn
, 4, 1);
8209 if (!dc_isar_feature(aa32_dp
, s
)) {
8212 fn_gvec
= u
? gen_helper_gvec_udot_idx_b
: gen_helper_gvec_sdot_idx_b
;
8213 /* rm is just Vm, and index is M. */
8214 data
= extract32(insn
, 5, 1); /* index */
8215 rm
= extract32(insn
, 0, 4);
8216 } else if ((insn
& 0xffa00f10) == 0xfe000810) {
8217 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
8218 int is_s
= extract32(insn
, 20, 1);
8219 int vm20
= extract32(insn
, 0, 3);
8220 int vm3
= extract32(insn
, 3, 1);
8221 int m
= extract32(insn
, 5, 1);
8224 if (!dc_isar_feature(aa32_fhm
, s
)) {
8229 index
= m
* 2 + vm3
;
8235 data
= (index
<< 2) | is_s
; /* is_2 == 0 */
8236 fn_gvec_ptr
= gen_helper_gvec_fmlal_idx_a32
;
8242 VFP_DREG_D(rd
, insn
);
8246 if (q
|| !is_long
) {
8247 VFP_DREG_N(rn
, insn
);
8248 if (rn
& q
& !is_long
) {
8251 off_rn
= vfp_reg_offset(1, rn
);
8252 off_rm
= vfp_reg_offset(1, rm
);
8254 rn
= VFP_SREG_N(insn
);
8255 off_rn
= vfp_reg_offset(0, rn
);
8256 off_rm
= vfp_reg_offset(0, rm
);
8258 if (s
->fp_excp_el
) {
8259 gen_exception_insn(s
, 4, EXCP_UDEF
,
8260 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
8263 if (!s
->vfp_enabled
) {
8267 opr_sz
= (1 + q
) * 8;
8273 ptr
= get_fpstatus_ptr(1);
8275 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
8276 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
8278 tcg_temp_free_ptr(ptr
);
8281 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
8282 opr_sz
, opr_sz
, data
, fn_gvec
);
8287 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
8289 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
8290 const ARMCPRegInfo
*ri
;
8292 cpnum
= (insn
>> 8) & 0xf;
8294 /* First check for coprocessor space used for XScale/iwMMXt insns */
8295 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
8296 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
8299 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8300 return disas_iwmmxt_insn(s
, insn
);
8301 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
8302 return disas_dsp_insn(s
, insn
);
8307 /* Otherwise treat as a generic register access */
8308 is64
= (insn
& (1 << 25)) == 0;
8309 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
8317 opc1
= (insn
>> 4) & 0xf;
8319 rt2
= (insn
>> 16) & 0xf;
8321 crn
= (insn
>> 16) & 0xf;
8322 opc1
= (insn
>> 21) & 7;
8323 opc2
= (insn
>> 5) & 7;
8326 isread
= (insn
>> 20) & 1;
8327 rt
= (insn
>> 12) & 0xf;
8329 ri
= get_arm_cp_reginfo(s
->cp_regs
,
8330 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
8332 /* Check access permissions */
8333 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
8338 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
8339 /* Emit code to perform further access permissions checks at
8340 * runtime; this may result in an exception.
8341 * Note that on XScale all cp0..c13 registers do an access check
8342 * call in order to handle c15_cpar.
8345 TCGv_i32 tcg_syn
, tcg_isread
;
8348 /* Note that since we are an implementation which takes an
8349 * exception on a trapped conditional instruction only if the
8350 * instruction passes its condition code check, we can take
8351 * advantage of the clause in the ARM ARM that allows us to set
8352 * the COND field in the instruction to 0xE in all cases.
8353 * We could fish the actual condition out of the insn (ARM)
8354 * or the condexec bits (Thumb) but it isn't necessary.
8359 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
8362 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
8368 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
8371 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
8376 /* ARMv8 defines that only coprocessors 14 and 15 exist,
8377 * so this can only happen if this is an ARMv7 or earlier CPU,
8378 * in which case the syndrome information won't actually be
8381 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
8382 syndrome
= syn_uncategorized();
8386 gen_set_condexec(s
);
8387 gen_set_pc_im(s
, s
->pc
- 4);
8388 tmpptr
= tcg_const_ptr(ri
);
8389 tcg_syn
= tcg_const_i32(syndrome
);
8390 tcg_isread
= tcg_const_i32(isread
);
8391 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
8393 tcg_temp_free_ptr(tmpptr
);
8394 tcg_temp_free_i32(tcg_syn
);
8395 tcg_temp_free_i32(tcg_isread
);
8398 /* Handle special cases first */
8399 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
8406 gen_set_pc_im(s
, s
->pc
);
8407 s
->base
.is_jmp
= DISAS_WFI
;
8413 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
8422 if (ri
->type
& ARM_CP_CONST
) {
8423 tmp64
= tcg_const_i64(ri
->resetvalue
);
8424 } else if (ri
->readfn
) {
8426 tmp64
= tcg_temp_new_i64();
8427 tmpptr
= tcg_const_ptr(ri
);
8428 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
8429 tcg_temp_free_ptr(tmpptr
);
8431 tmp64
= tcg_temp_new_i64();
8432 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
8434 tmp
= tcg_temp_new_i32();
8435 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8436 store_reg(s
, rt
, tmp
);
8437 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8438 tmp
= tcg_temp_new_i32();
8439 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8440 tcg_temp_free_i64(tmp64
);
8441 store_reg(s
, rt2
, tmp
);
8444 if (ri
->type
& ARM_CP_CONST
) {
8445 tmp
= tcg_const_i32(ri
->resetvalue
);
8446 } else if (ri
->readfn
) {
8448 tmp
= tcg_temp_new_i32();
8449 tmpptr
= tcg_const_ptr(ri
);
8450 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
8451 tcg_temp_free_ptr(tmpptr
);
8453 tmp
= load_cpu_offset(ri
->fieldoffset
);
8456 /* Destination register of r15 for 32 bit loads sets
8457 * the condition codes from the high 4 bits of the value
8460 tcg_temp_free_i32(tmp
);
8462 store_reg(s
, rt
, tmp
);
8467 if (ri
->type
& ARM_CP_CONST
) {
8468 /* If not forbidden by access permissions, treat as WI */
8473 TCGv_i32 tmplo
, tmphi
;
8474 TCGv_i64 tmp64
= tcg_temp_new_i64();
8475 tmplo
= load_reg(s
, rt
);
8476 tmphi
= load_reg(s
, rt2
);
8477 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
8478 tcg_temp_free_i32(tmplo
);
8479 tcg_temp_free_i32(tmphi
);
8481 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
8482 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
8483 tcg_temp_free_ptr(tmpptr
);
8485 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
8487 tcg_temp_free_i64(tmp64
);
8492 tmp
= load_reg(s
, rt
);
8493 tmpptr
= tcg_const_ptr(ri
);
8494 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
8495 tcg_temp_free_ptr(tmpptr
);
8496 tcg_temp_free_i32(tmp
);
8498 TCGv_i32 tmp
= load_reg(s
, rt
);
8499 store_cpu_offset(tmp
, ri
->fieldoffset
);
8504 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
8505 /* I/O operations must end the TB here (whether read or write) */
8508 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
8509 /* We default to ending the TB on a coprocessor register write,
8510 * but allow this to be suppressed by the register definition
8511 * (usually only necessary to work around guest bugs).
8519 /* Unknown register; this might be a guest error or a QEMU
8520 * unimplemented feature.
8523 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8524 "64 bit system register cp:%d opc1: %d crm:%d "
8526 isread
? "read" : "write", cpnum
, opc1
, crm
,
8527 s
->ns
? "non-secure" : "secure");
8529 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8530 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8532 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
8533 s
->ns
? "non-secure" : "secure");
8540 /* Store a 64-bit value to a register pair. Clobbers val. */
8541 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
8544 tmp
= tcg_temp_new_i32();
8545 tcg_gen_extrl_i64_i32(tmp
, val
);
8546 store_reg(s
, rlow
, tmp
);
8547 tmp
= tcg_temp_new_i32();
8548 tcg_gen_shri_i64(val
, val
, 32);
8549 tcg_gen_extrl_i64_i32(tmp
, val
);
8550 store_reg(s
, rhigh
, tmp
);
8553 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8554 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
8559 /* Load value and extend to 64 bits. */
8560 tmp
= tcg_temp_new_i64();
8561 tmp2
= load_reg(s
, rlow
);
8562 tcg_gen_extu_i32_i64(tmp
, tmp2
);
8563 tcg_temp_free_i32(tmp2
);
8564 tcg_gen_add_i64(val
, val
, tmp
);
8565 tcg_temp_free_i64(tmp
);
8568 /* load and add a 64-bit value from a register pair. */
8569 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
8575 /* Load 64-bit value rd:rn. */
8576 tmpl
= load_reg(s
, rlow
);
8577 tmph
= load_reg(s
, rhigh
);
8578 tmp
= tcg_temp_new_i64();
8579 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
8580 tcg_temp_free_i32(tmpl
);
8581 tcg_temp_free_i32(tmph
);
8582 tcg_gen_add_i64(val
, val
, tmp
);
8583 tcg_temp_free_i64(tmp
);
8586 /* Set N and Z flags from hi|lo. */
8587 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
8589 tcg_gen_mov_i32(cpu_NF
, hi
);
8590 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
8593 /* Load/Store exclusive instructions are implemented by remembering
8594 the value/address loaded, and seeing if these are the same
8595 when the store is performed. This should be sufficient to implement
8596 the architecturally mandated semantics, and avoids having to monitor
8597 regular stores. The compare vs the remembered value is done during
8598 the cmpxchg operation, but we must compare the addresses manually. */
8599 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
8600 TCGv_i32 addr
, int size
)
8602 TCGv_i32 tmp
= tcg_temp_new_i32();
8603 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8608 TCGv_i32 tmp2
= tcg_temp_new_i32();
8609 TCGv_i64 t64
= tcg_temp_new_i64();
8611 /* For AArch32, architecturally the 32-bit word at the lowest
8612 * address is always Rt and the one at addr+4 is Rt2, even if
8613 * the CPU is big-endian. That means we don't want to do a
8614 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8615 * for an architecturally 64-bit access, but instead do a
8616 * 64-bit access using MO_BE if appropriate and then split
8618 * This only makes a difference for BE32 user-mode, where
8619 * frob64() must not flip the two halves of the 64-bit data
8620 * but this code must treat BE32 user-mode like BE32 system.
8622 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
8624 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
8625 tcg_temp_free(taddr
);
8626 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
8627 if (s
->be_data
== MO_BE
) {
8628 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
8630 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
8632 tcg_temp_free_i64(t64
);
8634 store_reg(s
, rt2
, tmp2
);
8636 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
8637 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
8640 store_reg(s
, rt
, tmp
);
8641 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
8644 static void gen_clrex(DisasContext
*s
)
8646 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8649 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
8650 TCGv_i32 addr
, int size
)
8652 TCGv_i32 t0
, t1
, t2
;
8655 TCGLabel
*done_label
;
8656 TCGLabel
*fail_label
;
8657 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8659 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8665 fail_label
= gen_new_label();
8666 done_label
= gen_new_label();
8667 extaddr
= tcg_temp_new_i64();
8668 tcg_gen_extu_i32_i64(extaddr
, addr
);
8669 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
8670 tcg_temp_free_i64(extaddr
);
8672 taddr
= gen_aa32_addr(s
, addr
, opc
);
8673 t0
= tcg_temp_new_i32();
8674 t1
= load_reg(s
, rt
);
8676 TCGv_i64 o64
= tcg_temp_new_i64();
8677 TCGv_i64 n64
= tcg_temp_new_i64();
8679 t2
= load_reg(s
, rt2
);
8680 /* For AArch32, architecturally the 32-bit word at the lowest
8681 * address is always Rt and the one at addr+4 is Rt2, even if
8682 * the CPU is big-endian. Since we're going to treat this as a
8683 * single 64-bit BE store, we need to put the two halves in the
8684 * opposite order for BE to LE, so that they end up in the right
8686 * We don't want gen_aa32_frob64() because that does the wrong
8687 * thing for BE32 usermode.
8689 if (s
->be_data
== MO_BE
) {
8690 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
8692 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
8694 tcg_temp_free_i32(t2
);
8696 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
8697 get_mem_index(s
), opc
);
8698 tcg_temp_free_i64(n64
);
8700 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
8701 tcg_gen_extrl_i64_i32(t0
, o64
);
8703 tcg_temp_free_i64(o64
);
8705 t2
= tcg_temp_new_i32();
8706 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
8707 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
8708 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
8709 tcg_temp_free_i32(t2
);
8711 tcg_temp_free_i32(t1
);
8712 tcg_temp_free(taddr
);
8713 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
8714 tcg_temp_free_i32(t0
);
8715 tcg_gen_br(done_label
);
8717 gen_set_label(fail_label
);
8718 tcg_gen_movi_i32(cpu_R
[rd
], 1);
8719 gen_set_label(done_label
);
8720 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8726 * @mode: mode field from insn (which stack to store to)
8727 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8728 * @writeback: true if writeback bit set
8730 * Generate code for the SRS (Store Return State) insn.
8732 static void gen_srs(DisasContext
*s
,
8733 uint32_t mode
, uint32_t amode
, bool writeback
)
8740 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8741 * and specified mode is monitor mode
8742 * - UNDEFINED in Hyp mode
8743 * - UNPREDICTABLE in User or System mode
8744 * - UNPREDICTABLE if the specified mode is:
8745 * -- not implemented
8746 * -- not a valid mode number
8747 * -- a mode that's at a higher exception level
8748 * -- Monitor, if we are Non-secure
8749 * For the UNPREDICTABLE cases we choose to UNDEF.
8751 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
8752 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
8756 if (s
->current_el
== 0 || s
->current_el
== 2) {
8761 case ARM_CPU_MODE_USR
:
8762 case ARM_CPU_MODE_FIQ
:
8763 case ARM_CPU_MODE_IRQ
:
8764 case ARM_CPU_MODE_SVC
:
8765 case ARM_CPU_MODE_ABT
:
8766 case ARM_CPU_MODE_UND
:
8767 case ARM_CPU_MODE_SYS
:
8769 case ARM_CPU_MODE_HYP
:
8770 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
8774 case ARM_CPU_MODE_MON
:
8775 /* No need to check specifically for "are we non-secure" because
8776 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8777 * so if this isn't EL3 then we must be non-secure.
8779 if (s
->current_el
!= 3) {
8788 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8789 default_exception_el(s
));
8793 addr
= tcg_temp_new_i32();
8794 tmp
= tcg_const_i32(mode
);
8795 /* get_r13_banked() will raise an exception if called from System mode */
8796 gen_set_condexec(s
);
8797 gen_set_pc_im(s
, s
->pc
- 4);
8798 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8799 tcg_temp_free_i32(tmp
);
8816 tcg_gen_addi_i32(addr
, addr
, offset
);
8817 tmp
= load_reg(s
, 14);
8818 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8819 tcg_temp_free_i32(tmp
);
8820 tmp
= load_cpu_field(spsr
);
8821 tcg_gen_addi_i32(addr
, addr
, 4);
8822 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8823 tcg_temp_free_i32(tmp
);
8841 tcg_gen_addi_i32(addr
, addr
, offset
);
8842 tmp
= tcg_const_i32(mode
);
8843 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8844 tcg_temp_free_i32(tmp
);
8846 tcg_temp_free_i32(addr
);
8847 s
->base
.is_jmp
= DISAS_UPDATE
;
8850 /* Generate a label used for skipping this instruction */
8851 static void arm_gen_condlabel(DisasContext
*s
)
8854 s
->condlabel
= gen_new_label();
8859 /* Skip this instruction if the ARM condition is false */
8860 static void arm_skip_unless(DisasContext
*s
, uint32_t cond
)
8862 arm_gen_condlabel(s
);
8863 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8866 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8868 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8875 /* M variants do not implement ARM mode; this must raise the INVSTATE
8876 * UsageFault exception.
8878 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8879 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8880 default_exception_el(s
));
8885 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8886 * choose to UNDEF. In ARMv5 and above the space is used
8887 * for miscellaneous unconditional instructions.
8891 /* Unconditional instructions. */
8892 if (((insn
>> 25) & 7) == 1) {
8893 /* NEON Data processing. */
8894 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8898 if (disas_neon_data_insn(s
, insn
)) {
8903 if ((insn
& 0x0f100000) == 0x04000000) {
8904 /* NEON load/store. */
8905 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8909 if (disas_neon_ls_insn(s
, insn
)) {
8914 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8916 if (disas_vfp_insn(s
, insn
)) {
8921 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8922 ((insn
& 0x0f30f010) == 0x0710f000)) {
8923 if ((insn
& (1 << 22)) == 0) {
8925 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8929 /* Otherwise PLD; v5TE+ */
8933 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8934 ((insn
& 0x0f70f010) == 0x0650f000)) {
8936 return; /* PLI; V7 */
8938 if (((insn
& 0x0f700000) == 0x04100000) ||
8939 ((insn
& 0x0f700010) == 0x06100000)) {
8940 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8943 return; /* v7MP: Unallocated memory hint: must NOP */
8946 if ((insn
& 0x0ffffdff) == 0x01010000) {
8949 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8950 gen_helper_setend(cpu_env
);
8951 s
->base
.is_jmp
= DISAS_UPDATE
;
8954 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8955 switch ((insn
>> 4) & 0xf) {
8963 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8966 /* We need to break the TB after this insn to execute
8967 * self-modifying code correctly and also to take
8968 * any pending interrupts immediately.
8970 gen_goto_tb(s
, 0, s
->pc
& ~1);
8973 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
8977 * TODO: There is no speculation barrier opcode
8978 * for TCG; MB and end the TB instead.
8980 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8981 gen_goto_tb(s
, 0, s
->pc
& ~1);
8986 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8989 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8991 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8997 rn
= (insn
>> 16) & 0xf;
8998 addr
= load_reg(s
, rn
);
8999 i
= (insn
>> 23) & 3;
9001 case 0: offset
= -4; break; /* DA */
9002 case 1: offset
= 0; break; /* IA */
9003 case 2: offset
= -8; break; /* DB */
9004 case 3: offset
= 4; break; /* IB */
9008 tcg_gen_addi_i32(addr
, addr
, offset
);
9009 /* Load PC into tmp and CPSR into tmp2. */
9010 tmp
= tcg_temp_new_i32();
9011 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9012 tcg_gen_addi_i32(addr
, addr
, 4);
9013 tmp2
= tcg_temp_new_i32();
9014 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9015 if (insn
& (1 << 21)) {
9016 /* Base writeback. */
9018 case 0: offset
= -8; break;
9019 case 1: offset
= 4; break;
9020 case 2: offset
= -4; break;
9021 case 3: offset
= 0; break;
9025 tcg_gen_addi_i32(addr
, addr
, offset
);
9026 store_reg(s
, rn
, addr
);
9028 tcg_temp_free_i32(addr
);
9030 gen_rfe(s
, tmp
, tmp2
);
9032 } else if ((insn
& 0x0e000000) == 0x0a000000) {
9033 /* branch link and change to thumb (blx <offset>) */
9036 val
= (uint32_t)s
->pc
;
9037 tmp
= tcg_temp_new_i32();
9038 tcg_gen_movi_i32(tmp
, val
);
9039 store_reg(s
, 14, tmp
);
9040 /* Sign-extend the 24-bit offset */
9041 offset
= (((int32_t)insn
) << 8) >> 8;
9042 /* offset * 4 + bit24 * 2 + (thumb bit) */
9043 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
9044 /* pipeline offset */
9046 /* protected by ARCH(5); above, near the start of uncond block */
9049 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
9050 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
9051 /* iWMMXt register transfer. */
9052 if (extract32(s
->c15_cpar
, 1, 1)) {
9053 if (!disas_iwmmxt_insn(s
, insn
)) {
9058 } else if ((insn
& 0x0e000a00) == 0x0c000800
9059 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
9060 if (disas_neon_insn_3same_ext(s
, insn
)) {
9064 } else if ((insn
& 0x0f000a00) == 0x0e000800
9065 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
9066 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
9070 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
9071 /* Coprocessor double register transfer. */
9073 } else if ((insn
& 0x0f000010) == 0x0e000010) {
9074 /* Additional coprocessor register transfer. */
9075 } else if ((insn
& 0x0ff10020) == 0x01000000) {
9078 /* cps (privileged) */
9082 if (insn
& (1 << 19)) {
9083 if (insn
& (1 << 8))
9085 if (insn
& (1 << 7))
9087 if (insn
& (1 << 6))
9089 if (insn
& (1 << 18))
9092 if (insn
& (1 << 17)) {
9094 val
|= (insn
& 0x1f);
9097 gen_set_psr_im(s
, mask
, 0, val
);
9104 /* if not always execute, we generate a conditional jump to
9106 arm_skip_unless(s
, cond
);
9108 if ((insn
& 0x0f900000) == 0x03000000) {
9109 if ((insn
& (1 << 21)) == 0) {
9111 rd
= (insn
>> 12) & 0xf;
9112 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
9113 if ((insn
& (1 << 22)) == 0) {
9115 tmp
= tcg_temp_new_i32();
9116 tcg_gen_movi_i32(tmp
, val
);
9119 tmp
= load_reg(s
, rd
);
9120 tcg_gen_ext16u_i32(tmp
, tmp
);
9121 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
9123 store_reg(s
, rd
, tmp
);
9125 if (((insn
>> 12) & 0xf) != 0xf)
9127 if (((insn
>> 16) & 0xf) == 0) {
9128 gen_nop_hint(s
, insn
& 0xff);
9130 /* CPSR = immediate */
9132 shift
= ((insn
>> 8) & 0xf) * 2;
9134 val
= (val
>> shift
) | (val
<< (32 - shift
));
9135 i
= ((insn
& (1 << 22)) != 0);
9136 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
9142 } else if ((insn
& 0x0f900000) == 0x01000000
9143 && (insn
& 0x00000090) != 0x00000090) {
9144 /* miscellaneous instructions */
9145 op1
= (insn
>> 21) & 3;
9146 sh
= (insn
>> 4) & 0xf;
9149 case 0x0: /* MSR, MRS */
9150 if (insn
& (1 << 9)) {
9151 /* MSR (banked) and MRS (banked) */
9152 int sysm
= extract32(insn
, 16, 4) |
9153 (extract32(insn
, 8, 1) << 4);
9154 int r
= extract32(insn
, 22, 1);
9158 gen_msr_banked(s
, r
, sysm
, rm
);
9161 int rd
= extract32(insn
, 12, 4);
9163 gen_mrs_banked(s
, r
, sysm
, rd
);
9168 /* MSR, MRS (for PSRs) */
9171 tmp
= load_reg(s
, rm
);
9172 i
= ((op1
& 2) != 0);
9173 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
9177 rd
= (insn
>> 12) & 0xf;
9181 tmp
= load_cpu_field(spsr
);
9183 tmp
= tcg_temp_new_i32();
9184 gen_helper_cpsr_read(tmp
, cpu_env
);
9186 store_reg(s
, rd
, tmp
);
9191 /* branch/exchange thumb (bx). */
9193 tmp
= load_reg(s
, rm
);
9195 } else if (op1
== 3) {
9198 rd
= (insn
>> 12) & 0xf;
9199 tmp
= load_reg(s
, rm
);
9200 tcg_gen_clzi_i32(tmp
, tmp
, 32);
9201 store_reg(s
, rd
, tmp
);
9209 /* Trivial implementation equivalent to bx. */
9210 tmp
= load_reg(s
, rm
);
9221 /* branch link/exchange thumb (blx) */
9222 tmp
= load_reg(s
, rm
);
9223 tmp2
= tcg_temp_new_i32();
9224 tcg_gen_movi_i32(tmp2
, s
->pc
);
9225 store_reg(s
, 14, tmp2
);
9231 uint32_t c
= extract32(insn
, 8, 4);
9233 /* Check this CPU supports ARMv8 CRC instructions.
9234 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
9235 * Bits 8, 10 and 11 should be zero.
9237 if (!dc_isar_feature(aa32_crc32
, s
) || op1
== 0x3 || (c
& 0xd) != 0) {
9241 rn
= extract32(insn
, 16, 4);
9242 rd
= extract32(insn
, 12, 4);
9244 tmp
= load_reg(s
, rn
);
9245 tmp2
= load_reg(s
, rm
);
9247 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9248 } else if (op1
== 1) {
9249 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9251 tmp3
= tcg_const_i32(1 << op1
);
9253 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9255 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9257 tcg_temp_free_i32(tmp2
);
9258 tcg_temp_free_i32(tmp3
);
9259 store_reg(s
, rd
, tmp
);
9262 case 0x5: /* saturating add/subtract */
9264 rd
= (insn
>> 12) & 0xf;
9265 rn
= (insn
>> 16) & 0xf;
9266 tmp
= load_reg(s
, rm
);
9267 tmp2
= load_reg(s
, rn
);
9269 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
9271 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9273 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9274 tcg_temp_free_i32(tmp2
);
9275 store_reg(s
, rd
, tmp
);
9277 case 0x6: /* ERET */
9281 if (!arm_dc_feature(s
, ARM_FEATURE_V7VE
)) {
9284 if ((insn
& 0x000fff0f) != 0x0000000e) {
9285 /* UNPREDICTABLE; we choose to UNDEF */
9289 if (s
->current_el
== 2) {
9290 tmp
= load_cpu_field(elr_el
[2]);
9292 tmp
= load_reg(s
, 14);
9294 gen_exception_return(s
, tmp
);
9298 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
9307 gen_exception_bkpt_insn(s
, 4, syn_aa32_bkpt(imm16
, false));
9310 /* Hypervisor call (v7) */
9318 /* Secure monitor call (v6+) */
9326 g_assert_not_reached();
9330 case 0x8: /* signed multiply */
9335 rs
= (insn
>> 8) & 0xf;
9336 rn
= (insn
>> 12) & 0xf;
9337 rd
= (insn
>> 16) & 0xf;
9339 /* (32 * 16) >> 16 */
9340 tmp
= load_reg(s
, rm
);
9341 tmp2
= load_reg(s
, rs
);
9343 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9346 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9347 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9348 tmp
= tcg_temp_new_i32();
9349 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9350 tcg_temp_free_i64(tmp64
);
9351 if ((sh
& 2) == 0) {
9352 tmp2
= load_reg(s
, rn
);
9353 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9354 tcg_temp_free_i32(tmp2
);
9356 store_reg(s
, rd
, tmp
);
9359 tmp
= load_reg(s
, rm
);
9360 tmp2
= load_reg(s
, rs
);
9361 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
9362 tcg_temp_free_i32(tmp2
);
9364 tmp64
= tcg_temp_new_i64();
9365 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9366 tcg_temp_free_i32(tmp
);
9367 gen_addq(s
, tmp64
, rn
, rd
);
9368 gen_storeq_reg(s
, rn
, rd
, tmp64
);
9369 tcg_temp_free_i64(tmp64
);
9372 tmp2
= load_reg(s
, rn
);
9373 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9374 tcg_temp_free_i32(tmp2
);
9376 store_reg(s
, rd
, tmp
);
9383 } else if (((insn
& 0x0e000000) == 0 &&
9384 (insn
& 0x00000090) != 0x90) ||
9385 ((insn
& 0x0e000000) == (1 << 25))) {
9386 int set_cc
, logic_cc
, shiftop
;
9388 op1
= (insn
>> 21) & 0xf;
9389 set_cc
= (insn
>> 20) & 1;
9390 logic_cc
= table_logic_cc
[op1
] & set_cc
;
9392 /* data processing instruction */
9393 if (insn
& (1 << 25)) {
9394 /* immediate operand */
9396 shift
= ((insn
>> 8) & 0xf) * 2;
9398 val
= (val
>> shift
) | (val
<< (32 - shift
));
9400 tmp2
= tcg_temp_new_i32();
9401 tcg_gen_movi_i32(tmp2
, val
);
9402 if (logic_cc
&& shift
) {
9403 gen_set_CF_bit31(tmp2
);
9408 tmp2
= load_reg(s
, rm
);
9409 shiftop
= (insn
>> 5) & 3;
9410 if (!(insn
& (1 << 4))) {
9411 shift
= (insn
>> 7) & 0x1f;
9412 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9414 rs
= (insn
>> 8) & 0xf;
9415 tmp
= load_reg(s
, rs
);
9416 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
9419 if (op1
!= 0x0f && op1
!= 0x0d) {
9420 rn
= (insn
>> 16) & 0xf;
9421 tmp
= load_reg(s
, rn
);
9425 rd
= (insn
>> 12) & 0xf;
9428 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9432 store_reg_bx(s
, rd
, tmp
);
9435 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9439 store_reg_bx(s
, rd
, tmp
);
9442 if (set_cc
&& rd
== 15) {
9443 /* SUBS r15, ... is used for exception return. */
9447 gen_sub_CC(tmp
, tmp
, tmp2
);
9448 gen_exception_return(s
, tmp
);
9451 gen_sub_CC(tmp
, tmp
, tmp2
);
9453 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9455 store_reg_bx(s
, rd
, tmp
);
9460 gen_sub_CC(tmp
, tmp2
, tmp
);
9462 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9464 store_reg_bx(s
, rd
, tmp
);
9468 gen_add_CC(tmp
, tmp
, tmp2
);
9470 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9472 store_reg_bx(s
, rd
, tmp
);
9476 gen_adc_CC(tmp
, tmp
, tmp2
);
9478 gen_add_carry(tmp
, tmp
, tmp2
);
9480 store_reg_bx(s
, rd
, tmp
);
9484 gen_sbc_CC(tmp
, tmp
, tmp2
);
9486 gen_sub_carry(tmp
, tmp
, tmp2
);
9488 store_reg_bx(s
, rd
, tmp
);
9492 gen_sbc_CC(tmp
, tmp2
, tmp
);
9494 gen_sub_carry(tmp
, tmp2
, tmp
);
9496 store_reg_bx(s
, rd
, tmp
);
9500 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9503 tcg_temp_free_i32(tmp
);
9507 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9510 tcg_temp_free_i32(tmp
);
9514 gen_sub_CC(tmp
, tmp
, tmp2
);
9516 tcg_temp_free_i32(tmp
);
9520 gen_add_CC(tmp
, tmp
, tmp2
);
9522 tcg_temp_free_i32(tmp
);
9525 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9529 store_reg_bx(s
, rd
, tmp
);
9532 if (logic_cc
&& rd
== 15) {
9533 /* MOVS r15, ... is used for exception return. */
9537 gen_exception_return(s
, tmp2
);
9542 store_reg_bx(s
, rd
, tmp2
);
9546 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9550 store_reg_bx(s
, rd
, tmp
);
9554 tcg_gen_not_i32(tmp2
, tmp2
);
9558 store_reg_bx(s
, rd
, tmp2
);
9561 if (op1
!= 0x0f && op1
!= 0x0d) {
9562 tcg_temp_free_i32(tmp2
);
9565 /* other instructions */
9566 op1
= (insn
>> 24) & 0xf;
9570 /* multiplies, extra load/stores */
9571 sh
= (insn
>> 5) & 3;
9574 rd
= (insn
>> 16) & 0xf;
9575 rn
= (insn
>> 12) & 0xf;
9576 rs
= (insn
>> 8) & 0xf;
9578 op1
= (insn
>> 20) & 0xf;
9580 case 0: case 1: case 2: case 3: case 6:
9582 tmp
= load_reg(s
, rs
);
9583 tmp2
= load_reg(s
, rm
);
9584 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9585 tcg_temp_free_i32(tmp2
);
9586 if (insn
& (1 << 22)) {
9587 /* Subtract (mls) */
9589 tmp2
= load_reg(s
, rn
);
9590 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9591 tcg_temp_free_i32(tmp2
);
9592 } else if (insn
& (1 << 21)) {
9594 tmp2
= load_reg(s
, rn
);
9595 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9596 tcg_temp_free_i32(tmp2
);
9598 if (insn
& (1 << 20))
9600 store_reg(s
, rd
, tmp
);
9603 /* 64 bit mul double accumulate (UMAAL) */
9605 tmp
= load_reg(s
, rs
);
9606 tmp2
= load_reg(s
, rm
);
9607 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9608 gen_addq_lo(s
, tmp64
, rn
);
9609 gen_addq_lo(s
, tmp64
, rd
);
9610 gen_storeq_reg(s
, rn
, rd
, tmp64
);
9611 tcg_temp_free_i64(tmp64
);
9613 case 8: case 9: case 10: case 11:
9614 case 12: case 13: case 14: case 15:
9615 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9616 tmp
= load_reg(s
, rs
);
9617 tmp2
= load_reg(s
, rm
);
9618 if (insn
& (1 << 22)) {
9619 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
9621 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
9623 if (insn
& (1 << 21)) { /* mult accumulate */
9624 TCGv_i32 al
= load_reg(s
, rn
);
9625 TCGv_i32 ah
= load_reg(s
, rd
);
9626 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
9627 tcg_temp_free_i32(al
);
9628 tcg_temp_free_i32(ah
);
9630 if (insn
& (1 << 20)) {
9631 gen_logicq_cc(tmp
, tmp2
);
9633 store_reg(s
, rn
, tmp
);
9634 store_reg(s
, rd
, tmp2
);
9640 rn
= (insn
>> 16) & 0xf;
9641 rd
= (insn
>> 12) & 0xf;
9642 if (insn
& (1 << 23)) {
9643 /* load/store exclusive */
9644 bool is_ld
= extract32(insn
, 20, 1);
9645 bool is_lasr
= !extract32(insn
, 8, 1);
9646 int op2
= (insn
>> 8) & 3;
9647 op1
= (insn
>> 21) & 0x3;
9650 case 0: /* lda/stl */
9656 case 1: /* reserved */
9658 case 2: /* ldaex/stlex */
9661 case 3: /* ldrex/strex */
9670 addr
= tcg_temp_local_new_i32();
9671 load_reg_var(s
, addr
, rn
);
9673 if (is_lasr
&& !is_ld
) {
9674 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
9679 tmp
= tcg_temp_new_i32();
9682 gen_aa32_ld32u_iss(s
, tmp
, addr
,
9687 gen_aa32_ld8u_iss(s
, tmp
, addr
,
9692 gen_aa32_ld16u_iss(s
, tmp
, addr
,
9699 store_reg(s
, rd
, tmp
);
9702 tmp
= load_reg(s
, rm
);
9705 gen_aa32_st32_iss(s
, tmp
, addr
,
9710 gen_aa32_st8_iss(s
, tmp
, addr
,
9715 gen_aa32_st16_iss(s
, tmp
, addr
,
9722 tcg_temp_free_i32(tmp
);
9727 gen_load_exclusive(s
, rd
, 15, addr
, 2);
9729 case 1: /* ldrexd */
9730 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
9732 case 2: /* ldrexb */
9733 gen_load_exclusive(s
, rd
, 15, addr
, 0);
9735 case 3: /* ldrexh */
9736 gen_load_exclusive(s
, rd
, 15, addr
, 1);
9745 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
9747 case 1: /* strexd */
9748 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
9750 case 2: /* strexb */
9751 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
9753 case 3: /* strexh */
9754 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
9760 tcg_temp_free_i32(addr
);
9762 if (is_lasr
&& is_ld
) {
9763 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
9765 } else if ((insn
& 0x00300f00) == 0) {
9766 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9771 TCGMemOp opc
= s
->be_data
;
9775 if (insn
& (1 << 22)) {
9778 opc
|= MO_UL
| MO_ALIGN
;
9781 addr
= load_reg(s
, rn
);
9782 taddr
= gen_aa32_addr(s
, addr
, opc
);
9783 tcg_temp_free_i32(addr
);
9785 tmp
= load_reg(s
, rm
);
9786 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
9787 get_mem_index(s
), opc
);
9788 tcg_temp_free(taddr
);
9789 store_reg(s
, rd
, tmp
);
9796 bool load
= insn
& (1 << 20);
9797 bool wbit
= insn
& (1 << 21);
9798 bool pbit
= insn
& (1 << 24);
9799 bool doubleword
= false;
9802 /* Misc load/store */
9803 rn
= (insn
>> 16) & 0xf;
9804 rd
= (insn
>> 12) & 0xf;
9806 /* ISS not valid if writeback */
9807 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
9809 if (!load
&& (sh
& 2)) {
9813 /* UNPREDICTABLE; we choose to UNDEF */
9816 load
= (sh
& 1) == 0;
9820 addr
= load_reg(s
, rn
);
9822 gen_add_datah_offset(s
, insn
, 0, addr
);
9829 tmp
= load_reg(s
, rd
);
9830 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9831 tcg_temp_free_i32(tmp
);
9832 tcg_gen_addi_i32(addr
, addr
, 4);
9833 tmp
= load_reg(s
, rd
+ 1);
9834 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9835 tcg_temp_free_i32(tmp
);
9838 tmp
= tcg_temp_new_i32();
9839 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9840 store_reg(s
, rd
, tmp
);
9841 tcg_gen_addi_i32(addr
, addr
, 4);
9842 tmp
= tcg_temp_new_i32();
9843 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9846 address_offset
= -4;
9849 tmp
= tcg_temp_new_i32();
9852 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9856 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9861 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9867 tmp
= load_reg(s
, rd
);
9868 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9869 tcg_temp_free_i32(tmp
);
9871 /* Perform base writeback before the loaded value to
9872 ensure correct behavior with overlapping index registers.
9873 ldrd with base writeback is undefined if the
9874 destination and index registers overlap. */
9876 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9877 store_reg(s
, rn
, addr
);
9880 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9881 store_reg(s
, rn
, addr
);
9883 tcg_temp_free_i32(addr
);
9886 /* Complete the load. */
9887 store_reg(s
, rd
, tmp
);
9896 if (insn
& (1 << 4)) {
9898 /* Armv6 Media instructions. */
9900 rn
= (insn
>> 16) & 0xf;
9901 rd
= (insn
>> 12) & 0xf;
9902 rs
= (insn
>> 8) & 0xf;
9903 switch ((insn
>> 23) & 3) {
9904 case 0: /* Parallel add/subtract. */
9905 op1
= (insn
>> 20) & 7;
9906 tmp
= load_reg(s
, rn
);
9907 tmp2
= load_reg(s
, rm
);
9908 sh
= (insn
>> 5) & 7;
9909 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9911 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9912 tcg_temp_free_i32(tmp2
);
9913 store_reg(s
, rd
, tmp
);
9916 if ((insn
& 0x00700020) == 0) {
9917 /* Halfword pack. */
9918 tmp
= load_reg(s
, rn
);
9919 tmp2
= load_reg(s
, rm
);
9920 shift
= (insn
>> 7) & 0x1f;
9921 if (insn
& (1 << 6)) {
9925 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9926 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9927 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9931 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9932 tcg_gen_ext16u_i32(tmp
, tmp
);
9933 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9935 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9936 tcg_temp_free_i32(tmp2
);
9937 store_reg(s
, rd
, tmp
);
9938 } else if ((insn
& 0x00200020) == 0x00200000) {
9940 tmp
= load_reg(s
, rm
);
9941 shift
= (insn
>> 7) & 0x1f;
9942 if (insn
& (1 << 6)) {
9945 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9947 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9949 sh
= (insn
>> 16) & 0x1f;
9950 tmp2
= tcg_const_i32(sh
);
9951 if (insn
& (1 << 22))
9952 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9954 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9955 tcg_temp_free_i32(tmp2
);
9956 store_reg(s
, rd
, tmp
);
9957 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9959 tmp
= load_reg(s
, rm
);
9960 sh
= (insn
>> 16) & 0x1f;
9961 tmp2
= tcg_const_i32(sh
);
9962 if (insn
& (1 << 22))
9963 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9965 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9966 tcg_temp_free_i32(tmp2
);
9967 store_reg(s
, rd
, tmp
);
9968 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9970 tmp
= load_reg(s
, rn
);
9971 tmp2
= load_reg(s
, rm
);
9972 tmp3
= tcg_temp_new_i32();
9973 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9974 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9975 tcg_temp_free_i32(tmp3
);
9976 tcg_temp_free_i32(tmp2
);
9977 store_reg(s
, rd
, tmp
);
9978 } else if ((insn
& 0x000003e0) == 0x00000060) {
9979 tmp
= load_reg(s
, rm
);
9980 shift
= (insn
>> 10) & 3;
9981 /* ??? In many cases it's not necessary to do a
9982 rotate, a shift is sufficient. */
9984 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9985 op1
= (insn
>> 20) & 7;
9987 case 0: gen_sxtb16(tmp
); break;
9988 case 2: gen_sxtb(tmp
); break;
9989 case 3: gen_sxth(tmp
); break;
9990 case 4: gen_uxtb16(tmp
); break;
9991 case 6: gen_uxtb(tmp
); break;
9992 case 7: gen_uxth(tmp
); break;
9993 default: goto illegal_op
;
9996 tmp2
= load_reg(s
, rn
);
9997 if ((op1
& 3) == 0) {
9998 gen_add16(tmp
, tmp2
);
10000 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10001 tcg_temp_free_i32(tmp2
);
10004 store_reg(s
, rd
, tmp
);
10005 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
10007 tmp
= load_reg(s
, rm
);
10008 if (insn
& (1 << 22)) {
10009 if (insn
& (1 << 7)) {
10013 gen_helper_rbit(tmp
, tmp
);
10016 if (insn
& (1 << 7))
10019 tcg_gen_bswap32_i32(tmp
, tmp
);
10021 store_reg(s
, rd
, tmp
);
10026 case 2: /* Multiplies (Type 3). */
10027 switch ((insn
>> 20) & 0x7) {
10029 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
10030 /* op2 not 00x or 11x : UNDEF */
10033 /* Signed multiply most significant [accumulate].
10034 (SMMUL, SMMLA, SMMLS) */
10035 tmp
= load_reg(s
, rm
);
10036 tmp2
= load_reg(s
, rs
);
10037 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10040 tmp
= load_reg(s
, rd
);
10041 if (insn
& (1 << 6)) {
10042 tmp64
= gen_subq_msw(tmp64
, tmp
);
10044 tmp64
= gen_addq_msw(tmp64
, tmp
);
10047 if (insn
& (1 << 5)) {
10048 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10050 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10051 tmp
= tcg_temp_new_i32();
10052 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10053 tcg_temp_free_i64(tmp64
);
10054 store_reg(s
, rn
, tmp
);
10058 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
10059 if (insn
& (1 << 7)) {
10062 tmp
= load_reg(s
, rm
);
10063 tmp2
= load_reg(s
, rs
);
10064 if (insn
& (1 << 5))
10065 gen_swap_half(tmp2
);
10066 gen_smul_dual(tmp
, tmp2
);
10067 if (insn
& (1 << 22)) {
10068 /* smlald, smlsld */
10071 tmp64
= tcg_temp_new_i64();
10072 tmp64_2
= tcg_temp_new_i64();
10073 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10074 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
10075 tcg_temp_free_i32(tmp
);
10076 tcg_temp_free_i32(tmp2
);
10077 if (insn
& (1 << 6)) {
10078 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
10080 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
10082 tcg_temp_free_i64(tmp64_2
);
10083 gen_addq(s
, tmp64
, rd
, rn
);
10084 gen_storeq_reg(s
, rd
, rn
, tmp64
);
10085 tcg_temp_free_i64(tmp64
);
10087 /* smuad, smusd, smlad, smlsd */
10088 if (insn
& (1 << 6)) {
10089 /* This subtraction cannot overflow. */
10090 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10092 /* This addition cannot overflow 32 bits;
10093 * however it may overflow considered as a
10094 * signed operation, in which case we must set
10097 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10099 tcg_temp_free_i32(tmp2
);
10102 tmp2
= load_reg(s
, rd
);
10103 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10104 tcg_temp_free_i32(tmp2
);
10106 store_reg(s
, rn
, tmp
);
10112 if (!dc_isar_feature(arm_div
, s
)) {
10115 if (((insn
>> 5) & 7) || (rd
!= 15)) {
10118 tmp
= load_reg(s
, rm
);
10119 tmp2
= load_reg(s
, rs
);
10120 if (insn
& (1 << 21)) {
10121 gen_helper_udiv(tmp
, tmp
, tmp2
);
10123 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10125 tcg_temp_free_i32(tmp2
);
10126 store_reg(s
, rn
, tmp
);
10133 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
10135 case 0: /* Unsigned sum of absolute differences. */
10137 tmp
= load_reg(s
, rm
);
10138 tmp2
= load_reg(s
, rs
);
10139 gen_helper_usad8(tmp
, tmp
, tmp2
);
10140 tcg_temp_free_i32(tmp2
);
10142 tmp2
= load_reg(s
, rd
);
10143 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10144 tcg_temp_free_i32(tmp2
);
10146 store_reg(s
, rn
, tmp
);
10148 case 0x20: case 0x24: case 0x28: case 0x2c:
10149 /* Bitfield insert/clear. */
10151 shift
= (insn
>> 7) & 0x1f;
10152 i
= (insn
>> 16) & 0x1f;
10154 /* UNPREDICTABLE; we choose to UNDEF */
10159 tmp
= tcg_temp_new_i32();
10160 tcg_gen_movi_i32(tmp
, 0);
10162 tmp
= load_reg(s
, rm
);
10165 tmp2
= load_reg(s
, rd
);
10166 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
10167 tcg_temp_free_i32(tmp2
);
10169 store_reg(s
, rd
, tmp
);
10171 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
10172 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
10174 tmp
= load_reg(s
, rm
);
10175 shift
= (insn
>> 7) & 0x1f;
10176 i
= ((insn
>> 16) & 0x1f) + 1;
10177 if (shift
+ i
> 32)
10181 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
10183 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
10186 store_reg(s
, rd
, tmp
);
10196 /* Check for undefined extension instructions
10197 * per the ARM Bible IE:
10198 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
10200 sh
= (0xf << 20) | (0xf << 4);
10201 if (op1
== 0x7 && ((insn
& sh
) == sh
))
10205 /* load/store byte/word */
10206 rn
= (insn
>> 16) & 0xf;
10207 rd
= (insn
>> 12) & 0xf;
10208 tmp2
= load_reg(s
, rn
);
10209 if ((insn
& 0x01200000) == 0x00200000) {
10211 i
= get_a32_user_mem_index(s
);
10213 i
= get_mem_index(s
);
10215 if (insn
& (1 << 24))
10216 gen_add_data_offset(s
, insn
, tmp2
);
10217 if (insn
& (1 << 20)) {
10219 tmp
= tcg_temp_new_i32();
10220 if (insn
& (1 << 22)) {
10221 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
10223 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
10227 tmp
= load_reg(s
, rd
);
10228 if (insn
& (1 << 22)) {
10229 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
10231 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
10233 tcg_temp_free_i32(tmp
);
10235 if (!(insn
& (1 << 24))) {
10236 gen_add_data_offset(s
, insn
, tmp2
);
10237 store_reg(s
, rn
, tmp2
);
10238 } else if (insn
& (1 << 21)) {
10239 store_reg(s
, rn
, tmp2
);
10241 tcg_temp_free_i32(tmp2
);
10243 if (insn
& (1 << 20)) {
10244 /* Complete the load. */
10245 store_reg_from_load(s
, rd
, tmp
);
10251 int j
, n
, loaded_base
;
10252 bool exc_return
= false;
10253 bool is_load
= extract32(insn
, 20, 1);
10255 TCGv_i32 loaded_var
;
10256 /* load/store multiple words */
10257 /* XXX: store correct base if write back */
10258 if (insn
& (1 << 22)) {
10259 /* LDM (user), LDM (exception return) and STM (user) */
10261 goto illegal_op
; /* only usable in supervisor mode */
10263 if (is_load
&& extract32(insn
, 15, 1)) {
10269 rn
= (insn
>> 16) & 0xf;
10270 addr
= load_reg(s
, rn
);
10272 /* compute total size */
10276 for(i
=0;i
<16;i
++) {
10277 if (insn
& (1 << i
))
10280 /* XXX: test invalid n == 0 case ? */
10281 if (insn
& (1 << 23)) {
10282 if (insn
& (1 << 24)) {
10283 /* pre increment */
10284 tcg_gen_addi_i32(addr
, addr
, 4);
10286 /* post increment */
10289 if (insn
& (1 << 24)) {
10290 /* pre decrement */
10291 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
10293 /* post decrement */
10295 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
10299 for(i
=0;i
<16;i
++) {
10300 if (insn
& (1 << i
)) {
10303 tmp
= tcg_temp_new_i32();
10304 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10306 tmp2
= tcg_const_i32(i
);
10307 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
10308 tcg_temp_free_i32(tmp2
);
10309 tcg_temp_free_i32(tmp
);
10310 } else if (i
== rn
) {
10313 } else if (i
== 15 && exc_return
) {
10314 store_pc_exc_ret(s
, tmp
);
10316 store_reg_from_load(s
, i
, tmp
);
10321 /* special case: r15 = PC + 8 */
10322 val
= (long)s
->pc
+ 4;
10323 tmp
= tcg_temp_new_i32();
10324 tcg_gen_movi_i32(tmp
, val
);
10326 tmp
= tcg_temp_new_i32();
10327 tmp2
= tcg_const_i32(i
);
10328 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
10329 tcg_temp_free_i32(tmp2
);
10331 tmp
= load_reg(s
, i
);
10333 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10334 tcg_temp_free_i32(tmp
);
10337 /* no need to add after the last transfer */
10339 tcg_gen_addi_i32(addr
, addr
, 4);
10342 if (insn
& (1 << 21)) {
10344 if (insn
& (1 << 23)) {
10345 if (insn
& (1 << 24)) {
10346 /* pre increment */
10348 /* post increment */
10349 tcg_gen_addi_i32(addr
, addr
, 4);
10352 if (insn
& (1 << 24)) {
10353 /* pre decrement */
10355 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
10357 /* post decrement */
10358 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
10361 store_reg(s
, rn
, addr
);
10363 tcg_temp_free_i32(addr
);
10366 store_reg(s
, rn
, loaded_var
);
10369 /* Restore CPSR from SPSR. */
10370 tmp
= load_cpu_field(spsr
);
10371 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
10374 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
10375 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
10378 tcg_temp_free_i32(tmp
);
10379 /* Must exit loop to check un-masked IRQs */
10380 s
->base
.is_jmp
= DISAS_EXIT
;
10389 /* branch (and link) */
10390 val
= (int32_t)s
->pc
;
10391 if (insn
& (1 << 24)) {
10392 tmp
= tcg_temp_new_i32();
10393 tcg_gen_movi_i32(tmp
, val
);
10394 store_reg(s
, 14, tmp
);
10396 offset
= sextract32(insn
<< 2, 0, 26);
10404 if (((insn
>> 8) & 0xe) == 10) {
10406 if (disas_vfp_insn(s
, insn
)) {
10409 } else if (disas_coproc_insn(s
, insn
)) {
10416 gen_set_pc_im(s
, s
->pc
);
10417 s
->svc_imm
= extract32(insn
, 0, 24);
10418 s
->base
.is_jmp
= DISAS_SWI
;
10422 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
10423 default_exception_el(s
));
10429 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t insn
)
10431 /* Return true if this is a 16 bit instruction. We must be precise
10432 * about this (matching the decode). We assume that s->pc still
10433 * points to the first 16 bits of the insn.
10435 if ((insn
>> 11) < 0x1d) {
10436 /* Definitely a 16-bit instruction */
10440 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10441 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10442 * end up actually treating this as two 16-bit insns, though,
10443 * if it's half of a bl/blx pair that might span a page boundary.
10445 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
) ||
10446 arm_dc_feature(s
, ARM_FEATURE_M
)) {
10447 /* Thumb2 cores (including all M profile ones) always treat
10448 * 32-bit insns as 32-bit.
10453 if ((insn
>> 11) == 0x1e && s
->pc
- s
->page_start
< TARGET_PAGE_SIZE
- 3) {
10454 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10455 * is not on the next page; we merge this into a 32-bit
10460 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10461 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10462 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10463 * -- handle as single 16 bit insn
10468 /* Return true if this is a Thumb-2 logical op. */
10470 thumb2_logic_op(int op
)
10475 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10476 then set condition code flags based on the result of the operation.
10477 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10478 to the high bit of T1.
10479 Returns zero if the opcode is valid. */
10482 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
10483 TCGv_i32 t0
, TCGv_i32 t1
)
10490 tcg_gen_and_i32(t0
, t0
, t1
);
10494 tcg_gen_andc_i32(t0
, t0
, t1
);
10498 tcg_gen_or_i32(t0
, t0
, t1
);
10502 tcg_gen_orc_i32(t0
, t0
, t1
);
10506 tcg_gen_xor_i32(t0
, t0
, t1
);
10511 gen_add_CC(t0
, t0
, t1
);
10513 tcg_gen_add_i32(t0
, t0
, t1
);
10517 gen_adc_CC(t0
, t0
, t1
);
10523 gen_sbc_CC(t0
, t0
, t1
);
10525 gen_sub_carry(t0
, t0
, t1
);
10530 gen_sub_CC(t0
, t0
, t1
);
10532 tcg_gen_sub_i32(t0
, t0
, t1
);
10536 gen_sub_CC(t0
, t1
, t0
);
10538 tcg_gen_sub_i32(t0
, t1
, t0
);
10540 default: /* 5, 6, 7, 9, 12, 15. */
10546 gen_set_CF_bit31(t1
);
10551 /* Translate a 32-bit thumb instruction. */
10552 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
10554 uint32_t imm
, shift
, offset
;
10555 uint32_t rd
, rn
, rm
, rs
;
10567 * ARMv6-M supports a limited subset of Thumb2 instructions.
10568 * Other Thumb1 architectures allow only 32-bit
10569 * combined BL/BLX prefix and suffix.
10571 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
10572 !arm_dc_feature(s
, ARM_FEATURE_V7
)) {
10574 bool found
= false;
10575 static const uint32_t armv6m_insn
[] = {0xf3808000 /* msr */,
10576 0xf3b08040 /* dsb */,
10577 0xf3b08050 /* dmb */,
10578 0xf3b08060 /* isb */,
10579 0xf3e08000 /* mrs */,
10580 0xf000d000 /* bl */};
10581 static const uint32_t armv6m_mask
[] = {0xffe0d000,
10588 for (i
= 0; i
< ARRAY_SIZE(armv6m_insn
); i
++) {
10589 if ((insn
& armv6m_mask
[i
]) == armv6m_insn
[i
]) {
10597 } else if ((insn
& 0xf800e800) != 0xf000e800) {
10601 rn
= (insn
>> 16) & 0xf;
10602 rs
= (insn
>> 12) & 0xf;
10603 rd
= (insn
>> 8) & 0xf;
10605 switch ((insn
>> 25) & 0xf) {
10606 case 0: case 1: case 2: case 3:
10607 /* 16-bit instructions. Should never happen. */
10610 if (insn
& (1 << 22)) {
10611 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10612 * - load/store doubleword, load/store exclusive, ldacq/strel,
10613 * table branch, TT.
10615 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_M
) &&
10616 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10617 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10619 * The bulk of the behaviour for this instruction is implemented
10620 * in v7m_handle_execute_nsc(), which deals with the insn when
10621 * it is executed by a CPU in non-secure state from memory
10622 * which is Secure & NonSecure-Callable.
10623 * Here we only need to handle the remaining cases:
10624 * * in NS memory (including the "security extension not
10625 * implemented" case) : NOP
10626 * * in S memory but CPU already secure (clear IT bits)
10627 * We know that the attribute for the memory this insn is
10628 * in must match the current CPU state, because otherwise
10629 * get_phys_addr_pmsav8 would have generated an exception.
10631 if (s
->v8m_secure
) {
10632 /* Like the IT insn, we don't need to generate any code */
10633 s
->condexec_cond
= 0;
10634 s
->condexec_mask
= 0;
10636 } else if (insn
& 0x01200000) {
10637 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10638 * - load/store dual (post-indexed)
10639 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10640 * - load/store dual (literal and immediate)
10641 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10642 * - load/store dual (pre-indexed)
10644 bool wback
= extract32(insn
, 21, 1);
10647 if (insn
& (1 << 21)) {
10648 /* UNPREDICTABLE */
10651 addr
= tcg_temp_new_i32();
10652 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
10654 addr
= load_reg(s
, rn
);
10656 offset
= (insn
& 0xff) * 4;
10657 if ((insn
& (1 << 23)) == 0) {
10661 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
10663 * Here 'addr' is the current SP; if offset is +ve we're
10664 * moving SP up, else down. It is UNKNOWN whether the limit
10665 * check triggers when SP starts below the limit and ends
10666 * up above it; check whichever of the current and final
10667 * SP is lower, so QEMU will trigger in that situation.
10669 if ((int32_t)offset
< 0) {
10670 TCGv_i32 newsp
= tcg_temp_new_i32();
10672 tcg_gen_addi_i32(newsp
, addr
, offset
);
10673 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
10674 tcg_temp_free_i32(newsp
);
10676 gen_helper_v8m_stackcheck(cpu_env
, addr
);
10680 if (insn
& (1 << 24)) {
10681 tcg_gen_addi_i32(addr
, addr
, offset
);
10684 if (insn
& (1 << 20)) {
10686 tmp
= tcg_temp_new_i32();
10687 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10688 store_reg(s
, rs
, tmp
);
10689 tcg_gen_addi_i32(addr
, addr
, 4);
10690 tmp
= tcg_temp_new_i32();
10691 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10692 store_reg(s
, rd
, tmp
);
10695 tmp
= load_reg(s
, rs
);
10696 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10697 tcg_temp_free_i32(tmp
);
10698 tcg_gen_addi_i32(addr
, addr
, 4);
10699 tmp
= load_reg(s
, rd
);
10700 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10701 tcg_temp_free_i32(tmp
);
10704 /* Base writeback. */
10705 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
10706 store_reg(s
, rn
, addr
);
10708 tcg_temp_free_i32(addr
);
10710 } else if ((insn
& (1 << 23)) == 0) {
10711 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10712 * - load/store exclusive word
10716 if (!(insn
& (1 << 20)) &&
10717 arm_dc_feature(s
, ARM_FEATURE_M
) &&
10718 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10719 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10722 bool alt
= insn
& (1 << 7);
10723 TCGv_i32 addr
, op
, ttresp
;
10725 if ((insn
& 0x3f) || rd
== 13 || rd
== 15 || rn
== 15) {
10726 /* we UNDEF for these UNPREDICTABLE cases */
10730 if (alt
&& !s
->v8m_secure
) {
10734 addr
= load_reg(s
, rn
);
10735 op
= tcg_const_i32(extract32(insn
, 6, 2));
10736 ttresp
= tcg_temp_new_i32();
10737 gen_helper_v7m_tt(ttresp
, cpu_env
, addr
, op
);
10738 tcg_temp_free_i32(addr
);
10739 tcg_temp_free_i32(op
);
10740 store_reg(s
, rd
, ttresp
);
10745 addr
= tcg_temp_local_new_i32();
10746 load_reg_var(s
, addr
, rn
);
10747 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
10748 if (insn
& (1 << 20)) {
10749 gen_load_exclusive(s
, rs
, 15, addr
, 2);
10751 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
10753 tcg_temp_free_i32(addr
);
10754 } else if ((insn
& (7 << 5)) == 0) {
10755 /* Table Branch. */
10757 addr
= tcg_temp_new_i32();
10758 tcg_gen_movi_i32(addr
, s
->pc
);
10760 addr
= load_reg(s
, rn
);
10762 tmp
= load_reg(s
, rm
);
10763 tcg_gen_add_i32(addr
, addr
, tmp
);
10764 if (insn
& (1 << 4)) {
10766 tcg_gen_add_i32(addr
, addr
, tmp
);
10767 tcg_temp_free_i32(tmp
);
10768 tmp
= tcg_temp_new_i32();
10769 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
10771 tcg_temp_free_i32(tmp
);
10772 tmp
= tcg_temp_new_i32();
10773 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
10775 tcg_temp_free_i32(addr
);
10776 tcg_gen_shli_i32(tmp
, tmp
, 1);
10777 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
10778 store_reg(s
, 15, tmp
);
10780 bool is_lasr
= false;
10781 bool is_ld
= extract32(insn
, 20, 1);
10782 int op2
= (insn
>> 6) & 0x3;
10783 op
= (insn
>> 4) & 0x3;
10788 /* Load/store exclusive byte/halfword/doubleword */
10795 /* Load-acquire/store-release */
10801 /* Load-acquire/store-release exclusive */
10807 if (is_lasr
&& !is_ld
) {
10808 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
10811 addr
= tcg_temp_local_new_i32();
10812 load_reg_var(s
, addr
, rn
);
10815 tmp
= tcg_temp_new_i32();
10818 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
10822 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
10826 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
10832 store_reg(s
, rs
, tmp
);
10834 tmp
= load_reg(s
, rs
);
10837 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
10841 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
10845 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
10851 tcg_temp_free_i32(tmp
);
10853 } else if (is_ld
) {
10854 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
10856 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
10858 tcg_temp_free_i32(addr
);
10860 if (is_lasr
&& is_ld
) {
10861 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
10865 /* Load/store multiple, RFE, SRS. */
10866 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
10867 /* RFE, SRS: not available in user mode or on M profile */
10868 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10871 if (insn
& (1 << 20)) {
10873 addr
= load_reg(s
, rn
);
10874 if ((insn
& (1 << 24)) == 0)
10875 tcg_gen_addi_i32(addr
, addr
, -8);
10876 /* Load PC into tmp and CPSR into tmp2. */
10877 tmp
= tcg_temp_new_i32();
10878 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10879 tcg_gen_addi_i32(addr
, addr
, 4);
10880 tmp2
= tcg_temp_new_i32();
10881 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
10882 if (insn
& (1 << 21)) {
10883 /* Base writeback. */
10884 if (insn
& (1 << 24)) {
10885 tcg_gen_addi_i32(addr
, addr
, 4);
10887 tcg_gen_addi_i32(addr
, addr
, -4);
10889 store_reg(s
, rn
, addr
);
10891 tcg_temp_free_i32(addr
);
10893 gen_rfe(s
, tmp
, tmp2
);
10896 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
10900 int i
, loaded_base
= 0;
10901 TCGv_i32 loaded_var
;
10902 bool wback
= extract32(insn
, 21, 1);
10903 /* Load/store multiple. */
10904 addr
= load_reg(s
, rn
);
10906 for (i
= 0; i
< 16; i
++) {
10907 if (insn
& (1 << i
))
10911 if (insn
& (1 << 24)) {
10912 tcg_gen_addi_i32(addr
, addr
, -offset
);
10915 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
10917 * If the writeback is incrementing SP rather than
10918 * decrementing it, and the initial SP is below the
10919 * stack limit but the final written-back SP would
10920 * be above, then then we must not perform any memory
10921 * accesses, but it is IMPDEF whether we generate
10922 * an exception. We choose to do so in this case.
10923 * At this point 'addr' is the lowest address, so
10924 * either the original SP (if incrementing) or our
10925 * final SP (if decrementing), so that's what we check.
10927 gen_helper_v8m_stackcheck(cpu_env
, addr
);
10931 for (i
= 0; i
< 16; i
++) {
10932 if ((insn
& (1 << i
)) == 0)
10934 if (insn
& (1 << 20)) {
10936 tmp
= tcg_temp_new_i32();
10937 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10939 gen_bx_excret(s
, tmp
);
10940 } else if (i
== rn
) {
10944 store_reg(s
, i
, tmp
);
10948 tmp
= load_reg(s
, i
);
10949 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10950 tcg_temp_free_i32(tmp
);
10952 tcg_gen_addi_i32(addr
, addr
, 4);
10955 store_reg(s
, rn
, loaded_var
);
10958 /* Base register writeback. */
10959 if (insn
& (1 << 24)) {
10960 tcg_gen_addi_i32(addr
, addr
, -offset
);
10962 /* Fault if writeback register is in register list. */
10963 if (insn
& (1 << rn
))
10965 store_reg(s
, rn
, addr
);
10967 tcg_temp_free_i32(addr
);
10974 op
= (insn
>> 21) & 0xf;
10976 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10979 /* Halfword pack. */
10980 tmp
= load_reg(s
, rn
);
10981 tmp2
= load_reg(s
, rm
);
10982 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
10983 if (insn
& (1 << 5)) {
10987 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
10988 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
10989 tcg_gen_ext16u_i32(tmp2
, tmp2
);
10993 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10994 tcg_gen_ext16u_i32(tmp
, tmp
);
10995 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10997 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10998 tcg_temp_free_i32(tmp2
);
10999 store_reg(s
, rd
, tmp
);
11001 /* Data processing register constant shift. */
11003 tmp
= tcg_temp_new_i32();
11004 tcg_gen_movi_i32(tmp
, 0);
11006 tmp
= load_reg(s
, rn
);
11008 tmp2
= load_reg(s
, rm
);
11010 shiftop
= (insn
>> 4) & 3;
11011 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
11012 conds
= (insn
& (1 << 20)) != 0;
11013 logic_cc
= (conds
&& thumb2_logic_op(op
));
11014 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
11015 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
11017 tcg_temp_free_i32(tmp2
);
11019 ((op
== 2 && rn
== 15) ||
11020 (op
== 8 && rn
== 13) ||
11021 (op
== 13 && rn
== 13))) {
11022 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
11023 store_sp_checked(s
, tmp
);
11024 } else if (rd
!= 15) {
11025 store_reg(s
, rd
, tmp
);
11027 tcg_temp_free_i32(tmp
);
11031 case 13: /* Misc data processing. */
11032 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
11033 if (op
< 4 && (insn
& 0xf000) != 0xf000)
11036 case 0: /* Register controlled shift. */
11037 tmp
= load_reg(s
, rn
);
11038 tmp2
= load_reg(s
, rm
);
11039 if ((insn
& 0x70) != 0)
11042 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
11043 * - MOV, MOVS (register-shifted register), flagsetting
11045 op
= (insn
>> 21) & 3;
11046 logic_cc
= (insn
& (1 << 20)) != 0;
11047 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
11050 store_reg(s
, rd
, tmp
);
11052 case 1: /* Sign/zero extend. */
11053 op
= (insn
>> 20) & 7;
11055 case 0: /* SXTAH, SXTH */
11056 case 1: /* UXTAH, UXTH */
11057 case 4: /* SXTAB, SXTB */
11058 case 5: /* UXTAB, UXTB */
11060 case 2: /* SXTAB16, SXTB16 */
11061 case 3: /* UXTAB16, UXTB16 */
11062 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11070 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11074 tmp
= load_reg(s
, rm
);
11075 shift
= (insn
>> 4) & 3;
11076 /* ??? In many cases it's not necessary to do a
11077 rotate, a shift is sufficient. */
11079 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
11080 op
= (insn
>> 20) & 7;
11082 case 0: gen_sxth(tmp
); break;
11083 case 1: gen_uxth(tmp
); break;
11084 case 2: gen_sxtb16(tmp
); break;
11085 case 3: gen_uxtb16(tmp
); break;
11086 case 4: gen_sxtb(tmp
); break;
11087 case 5: gen_uxtb(tmp
); break;
11089 g_assert_not_reached();
11092 tmp2
= load_reg(s
, rn
);
11093 if ((op
>> 1) == 1) {
11094 gen_add16(tmp
, tmp2
);
11096 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11097 tcg_temp_free_i32(tmp2
);
11100 store_reg(s
, rd
, tmp
);
11102 case 2: /* SIMD add/subtract. */
11103 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11106 op
= (insn
>> 20) & 7;
11107 shift
= (insn
>> 4) & 7;
11108 if ((op
& 3) == 3 || (shift
& 3) == 3)
11110 tmp
= load_reg(s
, rn
);
11111 tmp2
= load_reg(s
, rm
);
11112 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
11113 tcg_temp_free_i32(tmp2
);
11114 store_reg(s
, rd
, tmp
);
11116 case 3: /* Other data processing. */
11117 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
11119 /* Saturating add/subtract. */
11120 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11123 tmp
= load_reg(s
, rn
);
11124 tmp2
= load_reg(s
, rm
);
11126 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
11128 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
11130 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
11131 tcg_temp_free_i32(tmp2
);
11134 case 0x0a: /* rbit */
11135 case 0x08: /* rev */
11136 case 0x09: /* rev16 */
11137 case 0x0b: /* revsh */
11138 case 0x18: /* clz */
11140 case 0x10: /* sel */
11141 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11145 case 0x20: /* crc32/crc32c */
11151 if (!dc_isar_feature(aa32_crc32
, s
)) {
11158 tmp
= load_reg(s
, rn
);
11160 case 0x0a: /* rbit */
11161 gen_helper_rbit(tmp
, tmp
);
11163 case 0x08: /* rev */
11164 tcg_gen_bswap32_i32(tmp
, tmp
);
11166 case 0x09: /* rev16 */
11169 case 0x0b: /* revsh */
11172 case 0x10: /* sel */
11173 tmp2
= load_reg(s
, rm
);
11174 tmp3
= tcg_temp_new_i32();
11175 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
11176 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
11177 tcg_temp_free_i32(tmp3
);
11178 tcg_temp_free_i32(tmp2
);
11180 case 0x18: /* clz */
11181 tcg_gen_clzi_i32(tmp
, tmp
, 32);
11191 uint32_t sz
= op
& 0x3;
11192 uint32_t c
= op
& 0x8;
11194 tmp2
= load_reg(s
, rm
);
11196 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
11197 } else if (sz
== 1) {
11198 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
11200 tmp3
= tcg_const_i32(1 << sz
);
11202 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
11204 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
11206 tcg_temp_free_i32(tmp2
);
11207 tcg_temp_free_i32(tmp3
);
11211 g_assert_not_reached();
11214 store_reg(s
, rd
, tmp
);
11216 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
11217 switch ((insn
>> 20) & 7) {
11218 case 0: /* 32 x 32 -> 32 */
11219 case 7: /* Unsigned sum of absolute differences. */
11221 case 1: /* 16 x 16 -> 32 */
11222 case 2: /* Dual multiply add. */
11223 case 3: /* 32 * 16 -> 32msb */
11224 case 4: /* Dual multiply subtract. */
11225 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11226 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11231 op
= (insn
>> 4) & 0xf;
11232 tmp
= load_reg(s
, rn
);
11233 tmp2
= load_reg(s
, rm
);
11234 switch ((insn
>> 20) & 7) {
11235 case 0: /* 32 x 32 -> 32 */
11236 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11237 tcg_temp_free_i32(tmp2
);
11239 tmp2
= load_reg(s
, rs
);
11241 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
11243 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11244 tcg_temp_free_i32(tmp2
);
11247 case 1: /* 16 x 16 -> 32 */
11248 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
11249 tcg_temp_free_i32(tmp2
);
11251 tmp2
= load_reg(s
, rs
);
11252 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
11253 tcg_temp_free_i32(tmp2
);
11256 case 2: /* Dual multiply add. */
11257 case 4: /* Dual multiply subtract. */
11259 gen_swap_half(tmp2
);
11260 gen_smul_dual(tmp
, tmp2
);
11261 if (insn
& (1 << 22)) {
11262 /* This subtraction cannot overflow. */
11263 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11265 /* This addition cannot overflow 32 bits;
11266 * however it may overflow considered as a signed
11267 * operation, in which case we must set the Q flag.
11269 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
11271 tcg_temp_free_i32(tmp2
);
11274 tmp2
= load_reg(s
, rs
);
11275 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
11276 tcg_temp_free_i32(tmp2
);
11279 case 3: /* 32 * 16 -> 32msb */
11281 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
11284 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
11285 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
11286 tmp
= tcg_temp_new_i32();
11287 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
11288 tcg_temp_free_i64(tmp64
);
11291 tmp2
= load_reg(s
, rs
);
11292 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
11293 tcg_temp_free_i32(tmp2
);
11296 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11297 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
11299 tmp
= load_reg(s
, rs
);
11300 if (insn
& (1 << 20)) {
11301 tmp64
= gen_addq_msw(tmp64
, tmp
);
11303 tmp64
= gen_subq_msw(tmp64
, tmp
);
11306 if (insn
& (1 << 4)) {
11307 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
11309 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
11310 tmp
= tcg_temp_new_i32();
11311 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
11312 tcg_temp_free_i64(tmp64
);
11314 case 7: /* Unsigned sum of absolute differences. */
11315 gen_helper_usad8(tmp
, tmp
, tmp2
);
11316 tcg_temp_free_i32(tmp2
);
11318 tmp2
= load_reg(s
, rs
);
11319 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11320 tcg_temp_free_i32(tmp2
);
11324 store_reg(s
, rd
, tmp
);
11326 case 6: case 7: /* 64-bit multiply, Divide. */
11327 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
11328 tmp
= load_reg(s
, rn
);
11329 tmp2
= load_reg(s
, rm
);
11330 if ((op
& 0x50) == 0x10) {
11332 if (!dc_isar_feature(thumb_div
, s
)) {
11336 gen_helper_udiv(tmp
, tmp
, tmp2
);
11338 gen_helper_sdiv(tmp
, tmp
, tmp2
);
11339 tcg_temp_free_i32(tmp2
);
11340 store_reg(s
, rd
, tmp
);
11341 } else if ((op
& 0xe) == 0xc) {
11342 /* Dual multiply accumulate long. */
11343 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11344 tcg_temp_free_i32(tmp
);
11345 tcg_temp_free_i32(tmp2
);
11349 gen_swap_half(tmp2
);
11350 gen_smul_dual(tmp
, tmp2
);
11352 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11354 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11356 tcg_temp_free_i32(tmp2
);
11358 tmp64
= tcg_temp_new_i64();
11359 tcg_gen_ext_i32_i64(tmp64
, tmp
);
11360 tcg_temp_free_i32(tmp
);
11361 gen_addq(s
, tmp64
, rs
, rd
);
11362 gen_storeq_reg(s
, rs
, rd
, tmp64
);
11363 tcg_temp_free_i64(tmp64
);
11366 /* Unsigned 64-bit multiply */
11367 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
11371 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11372 tcg_temp_free_i32(tmp2
);
11373 tcg_temp_free_i32(tmp
);
11376 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
11377 tcg_temp_free_i32(tmp2
);
11378 tmp64
= tcg_temp_new_i64();
11379 tcg_gen_ext_i32_i64(tmp64
, tmp
);
11380 tcg_temp_free_i32(tmp
);
11382 /* Signed 64-bit multiply */
11383 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
11388 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11389 tcg_temp_free_i64(tmp64
);
11392 gen_addq_lo(s
, tmp64
, rs
);
11393 gen_addq_lo(s
, tmp64
, rd
);
11394 } else if (op
& 0x40) {
11395 /* 64-bit accumulate. */
11396 gen_addq(s
, tmp64
, rs
, rd
);
11398 gen_storeq_reg(s
, rs
, rd
, tmp64
);
11399 tcg_temp_free_i64(tmp64
);
11404 case 6: case 7: case 14: case 15:
11406 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11407 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
11408 if (extract32(insn
, 24, 2) == 3) {
11409 goto illegal_op
; /* op0 = 0b11 : unallocated */
11413 * Decode VLLDM and VLSTM first: these are nonstandard because:
11414 * * if there is no FPU then these insns must NOP in
11415 * Secure state and UNDEF in Nonsecure state
11416 * * if there is an FPU then these insns do not have
11417 * the usual behaviour that disas_vfp_insn() provides of
11418 * being controlled by CPACR/NSACR enable bits or the
11419 * lazy-stacking logic.
11421 if (arm_dc_feature(s
, ARM_FEATURE_V8
) &&
11422 (insn
& 0xffa00f00) == 0xec200a00) {
11423 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
11425 * We choose to UNDEF if the RAZ bits are non-zero.
11427 if (!s
->v8m_secure
|| (insn
& 0x0040f0ff)) {
11431 if (arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
11432 TCGv_i32 fptr
= load_reg(s
, rn
);
11434 if (extract32(insn
, 20, 1)) {
11435 gen_helper_v7m_vlldm(cpu_env
, fptr
);
11437 gen_helper_v7m_vlstm(cpu_env
, fptr
);
11439 tcg_temp_free_i32(fptr
);
11441 /* End the TB, because we have updated FP control bits */
11442 s
->base
.is_jmp
= DISAS_UPDATE
;
11446 if (arm_dc_feature(s
, ARM_FEATURE_VFP
) &&
11447 ((insn
>> 8) & 0xe) == 10) {
11448 /* FP, and the CPU supports it */
11449 if (disas_vfp_insn(s
, insn
)) {
11455 /* All other insns: NOCP */
11456 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
11457 default_exception_el(s
));
11460 if ((insn
& 0xfe000a00) == 0xfc000800
11461 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
11462 /* The Thumb2 and ARM encodings are identical. */
11463 if (disas_neon_insn_3same_ext(s
, insn
)) {
11466 } else if ((insn
& 0xff000a00) == 0xfe000800
11467 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
11468 /* The Thumb2 and ARM encodings are identical. */
11469 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
11472 } else if (((insn
>> 24) & 3) == 3) {
11473 /* Translate into the equivalent ARM encoding. */
11474 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
11475 if (disas_neon_data_insn(s
, insn
)) {
11478 } else if (((insn
>> 8) & 0xe) == 10) {
11479 if (disas_vfp_insn(s
, insn
)) {
11483 if (insn
& (1 << 28))
11485 if (disas_coproc_insn(s
, insn
)) {
11490 case 8: case 9: case 10: case 11:
11491 if (insn
& (1 << 15)) {
11492 /* Branches, misc control. */
11493 if (insn
& 0x5000) {
11494 /* Unconditional branch. */
11495 /* signextend(hw1[10:0]) -> offset[:12]. */
11496 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
11497 /* hw1[10:0] -> offset[11:1]. */
11498 offset
|= (insn
& 0x7ff) << 1;
11499 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11500 offset[24:22] already have the same value because of the
11501 sign extension above. */
11502 offset
^= ((~insn
) & (1 << 13)) << 10;
11503 offset
^= ((~insn
) & (1 << 11)) << 11;
11505 if (insn
& (1 << 14)) {
11506 /* Branch and link. */
11507 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
11511 if (insn
& (1 << 12)) {
11513 gen_jmp(s
, offset
);
11516 offset
&= ~(uint32_t)2;
11517 /* thumb2 bx, no need to check */
11518 gen_bx_im(s
, offset
);
11520 } else if (((insn
>> 23) & 7) == 7) {
11522 if (insn
& (1 << 13))
11525 if (insn
& (1 << 26)) {
11526 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11529 if (!(insn
& (1 << 20))) {
11530 /* Hypervisor call (v7) */
11531 int imm16
= extract32(insn
, 16, 4) << 12
11532 | extract32(insn
, 0, 12);
11539 /* Secure monitor call (v6+) */
11547 op
= (insn
>> 20) & 7;
11549 case 0: /* msr cpsr. */
11550 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11551 tmp
= load_reg(s
, rn
);
11552 /* the constant is the mask and SYSm fields */
11553 addr
= tcg_const_i32(insn
& 0xfff);
11554 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11555 tcg_temp_free_i32(addr
);
11556 tcg_temp_free_i32(tmp
);
11561 case 1: /* msr spsr. */
11562 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11566 if (extract32(insn
, 5, 1)) {
11568 int sysm
= extract32(insn
, 8, 4) |
11569 (extract32(insn
, 4, 1) << 4);
11572 gen_msr_banked(s
, r
, sysm
, rm
);
11576 /* MSR (for PSRs) */
11577 tmp
= load_reg(s
, rn
);
11579 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
11583 case 2: /* cps, nop-hint. */
11584 if (((insn
>> 8) & 7) == 0) {
11585 gen_nop_hint(s
, insn
& 0xff);
11587 /* Implemented as NOP in user mode. */
11592 if (insn
& (1 << 10)) {
11593 if (insn
& (1 << 7))
11595 if (insn
& (1 << 6))
11597 if (insn
& (1 << 5))
11599 if (insn
& (1 << 9))
11600 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
11602 if (insn
& (1 << 8)) {
11604 imm
|= (insn
& 0x1f);
11607 gen_set_psr_im(s
, offset
, 0, imm
);
11610 case 3: /* Special control operations. */
11611 if (!arm_dc_feature(s
, ARM_FEATURE_V7
) &&
11612 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11615 op
= (insn
>> 4) & 0xf;
11617 case 2: /* clrex */
11622 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
11625 /* We need to break the TB after this insn
11626 * to execute self-modifying code correctly
11627 * and also to take any pending interrupts
11630 gen_goto_tb(s
, 0, s
->pc
& ~1);
11633 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
11637 * TODO: There is no speculation barrier opcode
11638 * for TCG; MB and end the TB instead.
11640 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
11641 gen_goto_tb(s
, 0, s
->pc
& ~1);
11648 /* Trivial implementation equivalent to bx.
11649 * This instruction doesn't exist at all for M-profile.
11651 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11654 tmp
= load_reg(s
, rn
);
11657 case 5: /* Exception return. */
11661 if (rn
!= 14 || rd
!= 15) {
11664 if (s
->current_el
== 2) {
11665 /* ERET from Hyp uses ELR_Hyp, not LR */
11669 tmp
= load_cpu_field(elr_el
[2]);
11671 tmp
= load_reg(s
, rn
);
11672 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
11674 gen_exception_return(s
, tmp
);
11677 if (extract32(insn
, 5, 1) &&
11678 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11680 int sysm
= extract32(insn
, 16, 4) |
11681 (extract32(insn
, 4, 1) << 4);
11683 gen_mrs_banked(s
, 0, sysm
, rd
);
11687 if (extract32(insn
, 16, 4) != 0xf) {
11690 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
11691 extract32(insn
, 0, 8) != 0) {
11696 tmp
= tcg_temp_new_i32();
11697 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11698 addr
= tcg_const_i32(insn
& 0xff);
11699 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
11700 tcg_temp_free_i32(addr
);
11702 gen_helper_cpsr_read(tmp
, cpu_env
);
11704 store_reg(s
, rd
, tmp
);
11707 if (extract32(insn
, 5, 1) &&
11708 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11710 int sysm
= extract32(insn
, 16, 4) |
11711 (extract32(insn
, 4, 1) << 4);
11713 gen_mrs_banked(s
, 1, sysm
, rd
);
11718 /* Not accessible in user mode. */
11719 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
11723 if (extract32(insn
, 16, 4) != 0xf ||
11724 extract32(insn
, 0, 8) != 0) {
11728 tmp
= load_cpu_field(spsr
);
11729 store_reg(s
, rd
, tmp
);
11734 /* Conditional branch. */
11735 op
= (insn
>> 22) & 0xf;
11736 /* Generate a conditional jump to next instruction. */
11737 arm_skip_unless(s
, op
);
11739 /* offset[11:1] = insn[10:0] */
11740 offset
= (insn
& 0x7ff) << 1;
11741 /* offset[17:12] = insn[21:16]. */
11742 offset
|= (insn
& 0x003f0000) >> 4;
11743 /* offset[31:20] = insn[26]. */
11744 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
11745 /* offset[18] = insn[13]. */
11746 offset
|= (insn
& (1 << 13)) << 5;
11747 /* offset[19] = insn[11]. */
11748 offset
|= (insn
& (1 << 11)) << 8;
11750 /* jump to the offset */
11751 gen_jmp(s
, s
->pc
+ offset
);
11755 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11756 * - Data-processing (modified immediate, plain binary immediate)
11758 if (insn
& (1 << 25)) {
11760 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11761 * - Data-processing (plain binary immediate)
11763 if (insn
& (1 << 24)) {
11764 if (insn
& (1 << 20))
11766 /* Bitfield/Saturate. */
11767 op
= (insn
>> 21) & 7;
11769 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
11771 tmp
= tcg_temp_new_i32();
11772 tcg_gen_movi_i32(tmp
, 0);
11774 tmp
= load_reg(s
, rn
);
11777 case 2: /* Signed bitfield extract. */
11779 if (shift
+ imm
> 32)
11782 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
11785 case 6: /* Unsigned bitfield extract. */
11787 if (shift
+ imm
> 32)
11790 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
11793 case 3: /* Bitfield insert/clear. */
11796 imm
= imm
+ 1 - shift
;
11798 tmp2
= load_reg(s
, rd
);
11799 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
11800 tcg_temp_free_i32(tmp2
);
11805 default: /* Saturate. */
11808 tcg_gen_sari_i32(tmp
, tmp
, shift
);
11810 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11812 tmp2
= tcg_const_i32(imm
);
11815 if ((op
& 1) && shift
== 0) {
11816 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11817 tcg_temp_free_i32(tmp
);
11818 tcg_temp_free_i32(tmp2
);
11821 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
11823 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
11827 if ((op
& 1) && shift
== 0) {
11828 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11829 tcg_temp_free_i32(tmp
);
11830 tcg_temp_free_i32(tmp2
);
11833 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
11835 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
11838 tcg_temp_free_i32(tmp2
);
11841 store_reg(s
, rd
, tmp
);
11843 imm
= ((insn
& 0x04000000) >> 15)
11844 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
11845 if (insn
& (1 << 22)) {
11846 /* 16-bit immediate. */
11847 imm
|= (insn
>> 4) & 0xf000;
11848 if (insn
& (1 << 23)) {
11850 tmp
= load_reg(s
, rd
);
11851 tcg_gen_ext16u_i32(tmp
, tmp
);
11852 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
11855 tmp
= tcg_temp_new_i32();
11856 tcg_gen_movi_i32(tmp
, imm
);
11858 store_reg(s
, rd
, tmp
);
11860 /* Add/sub 12-bit immediate. */
11862 offset
= s
->pc
& ~(uint32_t)3;
11863 if (insn
& (1 << 23))
11867 tmp
= tcg_temp_new_i32();
11868 tcg_gen_movi_i32(tmp
, offset
);
11869 store_reg(s
, rd
, tmp
);
11871 tmp
= load_reg(s
, rn
);
11872 if (insn
& (1 << 23))
11873 tcg_gen_subi_i32(tmp
, tmp
, imm
);
11875 tcg_gen_addi_i32(tmp
, tmp
, imm
);
11876 if (rn
== 13 && rd
== 13) {
11877 /* ADD SP, SP, imm or SUB SP, SP, imm */
11878 store_sp_checked(s
, tmp
);
11880 store_reg(s
, rd
, tmp
);
11887 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11888 * - Data-processing (modified immediate)
11890 int shifter_out
= 0;
11891 /* modified 12-bit immediate. */
11892 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
11893 imm
= (insn
& 0xff);
11896 /* Nothing to do. */
11898 case 1: /* 00XY00XY */
11901 case 2: /* XY00XY00 */
11905 case 3: /* XYXYXYXY */
11909 default: /* Rotated constant. */
11910 shift
= (shift
<< 1) | (imm
>> 7);
11912 imm
= imm
<< (32 - shift
);
11916 tmp2
= tcg_temp_new_i32();
11917 tcg_gen_movi_i32(tmp2
, imm
);
11918 rn
= (insn
>> 16) & 0xf;
11920 tmp
= tcg_temp_new_i32();
11921 tcg_gen_movi_i32(tmp
, 0);
11923 tmp
= load_reg(s
, rn
);
11925 op
= (insn
>> 21) & 0xf;
11926 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
11927 shifter_out
, tmp
, tmp2
))
11929 tcg_temp_free_i32(tmp2
);
11930 rd
= (insn
>> 8) & 0xf;
11931 if (rd
== 13 && rn
== 13
11932 && (op
== 8 || op
== 13)) {
11933 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11934 store_sp_checked(s
, tmp
);
11935 } else if (rd
!= 15) {
11936 store_reg(s
, rd
, tmp
);
11938 tcg_temp_free_i32(tmp
);
11943 case 12: /* Load/store single data item. */
11950 if ((insn
& 0x01100000) == 0x01000000) {
11951 if (disas_neon_ls_insn(s
, insn
)) {
11956 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
11958 if (!(insn
& (1 << 20))) {
11962 /* Byte or halfword load space with dest == r15 : memory hints.
11963 * Catch them early so we don't emit pointless addressing code.
11964 * This space is a mix of:
11965 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11966 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11968 * unallocated hints, which must be treated as NOPs
11969 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11970 * which is easiest for the decoding logic
11971 * Some space which must UNDEF
11973 int op1
= (insn
>> 23) & 3;
11974 int op2
= (insn
>> 6) & 0x3f;
11979 /* UNPREDICTABLE, unallocated hint or
11980 * PLD/PLDW/PLI (literal)
11985 return; /* PLD/PLDW/PLI or unallocated hint */
11987 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
11988 return; /* PLD/PLDW/PLI or unallocated hint */
11990 /* UNDEF space, or an UNPREDICTABLE */
11994 memidx
= get_mem_index(s
);
11996 addr
= tcg_temp_new_i32();
11998 /* s->pc has already been incremented by 4. */
11999 imm
= s
->pc
& 0xfffffffc;
12000 if (insn
& (1 << 23))
12001 imm
+= insn
& 0xfff;
12003 imm
-= insn
& 0xfff;
12004 tcg_gen_movi_i32(addr
, imm
);
12006 addr
= load_reg(s
, rn
);
12007 if (insn
& (1 << 23)) {
12008 /* Positive offset. */
12009 imm
= insn
& 0xfff;
12010 tcg_gen_addi_i32(addr
, addr
, imm
);
12013 switch ((insn
>> 8) & 0xf) {
12014 case 0x0: /* Shifted Register. */
12015 shift
= (insn
>> 4) & 0xf;
12017 tcg_temp_free_i32(addr
);
12020 tmp
= load_reg(s
, rm
);
12022 tcg_gen_shli_i32(tmp
, tmp
, shift
);
12023 tcg_gen_add_i32(addr
, addr
, tmp
);
12024 tcg_temp_free_i32(tmp
);
12026 case 0xc: /* Negative offset. */
12027 tcg_gen_addi_i32(addr
, addr
, -imm
);
12029 case 0xe: /* User privilege. */
12030 tcg_gen_addi_i32(addr
, addr
, imm
);
12031 memidx
= get_a32_user_mem_index(s
);
12033 case 0x9: /* Post-decrement. */
12035 /* Fall through. */
12036 case 0xb: /* Post-increment. */
12040 case 0xd: /* Pre-decrement. */
12042 /* Fall through. */
12043 case 0xf: /* Pre-increment. */
12047 tcg_temp_free_i32(addr
);
12053 issinfo
= writeback
? ISSInvalid
: rs
;
12055 if (s
->v8m_stackcheck
&& rn
== 13 && writeback
) {
12057 * Stackcheck. Here we know 'addr' is the current SP;
12058 * if imm is +ve we're moving SP up, else down. It is
12059 * UNKNOWN whether the limit check triggers when SP starts
12060 * below the limit and ends up above it; we chose to do so.
12062 if ((int32_t)imm
< 0) {
12063 TCGv_i32 newsp
= tcg_temp_new_i32();
12065 tcg_gen_addi_i32(newsp
, addr
, imm
);
12066 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
12067 tcg_temp_free_i32(newsp
);
12069 gen_helper_v8m_stackcheck(cpu_env
, addr
);
12073 if (writeback
&& !postinc
) {
12074 tcg_gen_addi_i32(addr
, addr
, imm
);
12077 if (insn
& (1 << 20)) {
12079 tmp
= tcg_temp_new_i32();
12082 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
12085 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
12088 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
12091 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
12094 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
12097 tcg_temp_free_i32(tmp
);
12098 tcg_temp_free_i32(addr
);
12102 gen_bx_excret(s
, tmp
);
12104 store_reg(s
, rs
, tmp
);
12108 tmp
= load_reg(s
, rs
);
12111 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
12114 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
12117 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
12120 tcg_temp_free_i32(tmp
);
12121 tcg_temp_free_i32(addr
);
12124 tcg_temp_free_i32(tmp
);
12127 tcg_gen_addi_i32(addr
, addr
, imm
);
12129 store_reg(s
, rn
, addr
);
12131 tcg_temp_free_i32(addr
);
12140 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
12141 default_exception_el(s
));
12144 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
12146 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
12153 switch (insn
>> 12) {
12157 op
= (insn
>> 11) & 3;
12160 * 0b0001_1xxx_xxxx_xxxx
12161 * - Add, subtract (three low registers)
12162 * - Add, subtract (two low registers and immediate)
12164 rn
= (insn
>> 3) & 7;
12165 tmp
= load_reg(s
, rn
);
12166 if (insn
& (1 << 10)) {
12168 tmp2
= tcg_temp_new_i32();
12169 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
12172 rm
= (insn
>> 6) & 7;
12173 tmp2
= load_reg(s
, rm
);
12175 if (insn
& (1 << 9)) {
12176 if (s
->condexec_mask
)
12177 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
12179 gen_sub_CC(tmp
, tmp
, tmp2
);
12181 if (s
->condexec_mask
)
12182 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
12184 gen_add_CC(tmp
, tmp
, tmp2
);
12186 tcg_temp_free_i32(tmp2
);
12187 store_reg(s
, rd
, tmp
);
12189 /* shift immediate */
12190 rm
= (insn
>> 3) & 7;
12191 shift
= (insn
>> 6) & 0x1f;
12192 tmp
= load_reg(s
, rm
);
12193 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
12194 if (!s
->condexec_mask
)
12196 store_reg(s
, rd
, tmp
);
12201 * 0b001x_xxxx_xxxx_xxxx
12202 * - Add, subtract, compare, move (one low register and immediate)
12204 op
= (insn
>> 11) & 3;
12205 rd
= (insn
>> 8) & 0x7;
12206 if (op
== 0) { /* mov */
12207 tmp
= tcg_temp_new_i32();
12208 tcg_gen_movi_i32(tmp
, insn
& 0xff);
12209 if (!s
->condexec_mask
)
12211 store_reg(s
, rd
, tmp
);
12213 tmp
= load_reg(s
, rd
);
12214 tmp2
= tcg_temp_new_i32();
12215 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
12218 gen_sub_CC(tmp
, tmp
, tmp2
);
12219 tcg_temp_free_i32(tmp
);
12220 tcg_temp_free_i32(tmp2
);
12223 if (s
->condexec_mask
)
12224 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
12226 gen_add_CC(tmp
, tmp
, tmp2
);
12227 tcg_temp_free_i32(tmp2
);
12228 store_reg(s
, rd
, tmp
);
12231 if (s
->condexec_mask
)
12232 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
12234 gen_sub_CC(tmp
, tmp
, tmp2
);
12235 tcg_temp_free_i32(tmp2
);
12236 store_reg(s
, rd
, tmp
);
12242 if (insn
& (1 << 11)) {
12243 rd
= (insn
>> 8) & 7;
12244 /* load pc-relative. Bit 1 of PC is ignored. */
12245 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
12246 val
&= ~(uint32_t)2;
12247 addr
= tcg_temp_new_i32();
12248 tcg_gen_movi_i32(addr
, val
);
12249 tmp
= tcg_temp_new_i32();
12250 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
12252 tcg_temp_free_i32(addr
);
12253 store_reg(s
, rd
, tmp
);
12256 if (insn
& (1 << 10)) {
12257 /* 0b0100_01xx_xxxx_xxxx
12258 * - data processing extended, branch and exchange
12260 rd
= (insn
& 7) | ((insn
>> 4) & 8);
12261 rm
= (insn
>> 3) & 0xf;
12262 op
= (insn
>> 8) & 3;
12265 tmp
= load_reg(s
, rd
);
12266 tmp2
= load_reg(s
, rm
);
12267 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
12268 tcg_temp_free_i32(tmp2
);
12270 /* ADD SP, SP, reg */
12271 store_sp_checked(s
, tmp
);
12273 store_reg(s
, rd
, tmp
);
12277 tmp
= load_reg(s
, rd
);
12278 tmp2
= load_reg(s
, rm
);
12279 gen_sub_CC(tmp
, tmp
, tmp2
);
12280 tcg_temp_free_i32(tmp2
);
12281 tcg_temp_free_i32(tmp
);
12283 case 2: /* mov/cpy */
12284 tmp
= load_reg(s
, rm
);
12287 store_sp_checked(s
, tmp
);
12289 store_reg(s
, rd
, tmp
);
12294 /* 0b0100_0111_xxxx_xxxx
12295 * - branch [and link] exchange thumb register
12297 bool link
= insn
& (1 << 7);
12306 /* BXNS/BLXNS: only exists for v8M with the
12307 * security extensions, and always UNDEF if NonSecure.
12308 * We don't implement these in the user-only mode
12309 * either (in theory you can use them from Secure User
12310 * mode but they are too tied in to system emulation.)
12312 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
12323 tmp
= load_reg(s
, rm
);
12325 val
= (uint32_t)s
->pc
| 1;
12326 tmp2
= tcg_temp_new_i32();
12327 tcg_gen_movi_i32(tmp2
, val
);
12328 store_reg(s
, 14, tmp2
);
12331 /* Only BX works as exception-return, not BLX */
12332 gen_bx_excret(s
, tmp
);
12341 * 0b0100_00xx_xxxx_xxxx
12342 * - Data-processing (two low registers)
12345 rm
= (insn
>> 3) & 7;
12346 op
= (insn
>> 6) & 0xf;
12347 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
12348 /* the shift/rotate ops want the operands backwards */
12357 if (op
== 9) { /* neg */
12358 tmp
= tcg_temp_new_i32();
12359 tcg_gen_movi_i32(tmp
, 0);
12360 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
12361 tmp
= load_reg(s
, rd
);
12366 tmp2
= load_reg(s
, rm
);
12368 case 0x0: /* and */
12369 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
12370 if (!s
->condexec_mask
)
12373 case 0x1: /* eor */
12374 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
12375 if (!s
->condexec_mask
)
12378 case 0x2: /* lsl */
12379 if (s
->condexec_mask
) {
12380 gen_shl(tmp2
, tmp2
, tmp
);
12382 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
12383 gen_logic_CC(tmp2
);
12386 case 0x3: /* lsr */
12387 if (s
->condexec_mask
) {
12388 gen_shr(tmp2
, tmp2
, tmp
);
12390 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
12391 gen_logic_CC(tmp2
);
12394 case 0x4: /* asr */
12395 if (s
->condexec_mask
) {
12396 gen_sar(tmp2
, tmp2
, tmp
);
12398 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
12399 gen_logic_CC(tmp2
);
12402 case 0x5: /* adc */
12403 if (s
->condexec_mask
) {
12404 gen_adc(tmp
, tmp2
);
12406 gen_adc_CC(tmp
, tmp
, tmp2
);
12409 case 0x6: /* sbc */
12410 if (s
->condexec_mask
) {
12411 gen_sub_carry(tmp
, tmp
, tmp2
);
12413 gen_sbc_CC(tmp
, tmp
, tmp2
);
12416 case 0x7: /* ror */
12417 if (s
->condexec_mask
) {
12418 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
12419 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
12421 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
12422 gen_logic_CC(tmp2
);
12425 case 0x8: /* tst */
12426 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
12430 case 0x9: /* neg */
12431 if (s
->condexec_mask
)
12432 tcg_gen_neg_i32(tmp
, tmp2
);
12434 gen_sub_CC(tmp
, tmp
, tmp2
);
12436 case 0xa: /* cmp */
12437 gen_sub_CC(tmp
, tmp
, tmp2
);
12440 case 0xb: /* cmn */
12441 gen_add_CC(tmp
, tmp
, tmp2
);
12444 case 0xc: /* orr */
12445 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
12446 if (!s
->condexec_mask
)
12449 case 0xd: /* mul */
12450 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
12451 if (!s
->condexec_mask
)
12454 case 0xe: /* bic */
12455 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
12456 if (!s
->condexec_mask
)
12459 case 0xf: /* mvn */
12460 tcg_gen_not_i32(tmp2
, tmp2
);
12461 if (!s
->condexec_mask
)
12462 gen_logic_CC(tmp2
);
12469 store_reg(s
, rm
, tmp2
);
12471 tcg_temp_free_i32(tmp
);
12473 store_reg(s
, rd
, tmp
);
12474 tcg_temp_free_i32(tmp2
);
12477 tcg_temp_free_i32(tmp
);
12478 tcg_temp_free_i32(tmp2
);
12483 /* load/store register offset. */
12485 rn
= (insn
>> 3) & 7;
12486 rm
= (insn
>> 6) & 7;
12487 op
= (insn
>> 9) & 7;
12488 addr
= load_reg(s
, rn
);
12489 tmp
= load_reg(s
, rm
);
12490 tcg_gen_add_i32(addr
, addr
, tmp
);
12491 tcg_temp_free_i32(tmp
);
12493 if (op
< 3) { /* store */
12494 tmp
= load_reg(s
, rd
);
12496 tmp
= tcg_temp_new_i32();
12501 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12504 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12507 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12509 case 3: /* ldrsb */
12510 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12513 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12516 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12519 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12521 case 7: /* ldrsh */
12522 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12525 if (op
>= 3) { /* load */
12526 store_reg(s
, rd
, tmp
);
12528 tcg_temp_free_i32(tmp
);
12530 tcg_temp_free_i32(addr
);
12534 /* load/store word immediate offset */
12536 rn
= (insn
>> 3) & 7;
12537 addr
= load_reg(s
, rn
);
12538 val
= (insn
>> 4) & 0x7c;
12539 tcg_gen_addi_i32(addr
, addr
, val
);
12541 if (insn
& (1 << 11)) {
12543 tmp
= tcg_temp_new_i32();
12544 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12545 store_reg(s
, rd
, tmp
);
12548 tmp
= load_reg(s
, rd
);
12549 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12550 tcg_temp_free_i32(tmp
);
12552 tcg_temp_free_i32(addr
);
12556 /* load/store byte immediate offset */
12558 rn
= (insn
>> 3) & 7;
12559 addr
= load_reg(s
, rn
);
12560 val
= (insn
>> 6) & 0x1f;
12561 tcg_gen_addi_i32(addr
, addr
, val
);
12563 if (insn
& (1 << 11)) {
12565 tmp
= tcg_temp_new_i32();
12566 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12567 store_reg(s
, rd
, tmp
);
12570 tmp
= load_reg(s
, rd
);
12571 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12572 tcg_temp_free_i32(tmp
);
12574 tcg_temp_free_i32(addr
);
12578 /* load/store halfword immediate offset */
12580 rn
= (insn
>> 3) & 7;
12581 addr
= load_reg(s
, rn
);
12582 val
= (insn
>> 5) & 0x3e;
12583 tcg_gen_addi_i32(addr
, addr
, val
);
12585 if (insn
& (1 << 11)) {
12587 tmp
= tcg_temp_new_i32();
12588 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12589 store_reg(s
, rd
, tmp
);
12592 tmp
= load_reg(s
, rd
);
12593 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12594 tcg_temp_free_i32(tmp
);
12596 tcg_temp_free_i32(addr
);
12600 /* load/store from stack */
12601 rd
= (insn
>> 8) & 7;
12602 addr
= load_reg(s
, 13);
12603 val
= (insn
& 0xff) * 4;
12604 tcg_gen_addi_i32(addr
, addr
, val
);
12606 if (insn
& (1 << 11)) {
12608 tmp
= tcg_temp_new_i32();
12609 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12610 store_reg(s
, rd
, tmp
);
12613 tmp
= load_reg(s
, rd
);
12614 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
12615 tcg_temp_free_i32(tmp
);
12617 tcg_temp_free_i32(addr
);
12622 * 0b1010_xxxx_xxxx_xxxx
12623 * - Add PC/SP (immediate)
12625 rd
= (insn
>> 8) & 7;
12626 if (insn
& (1 << 11)) {
12628 tmp
= load_reg(s
, 13);
12630 /* PC. bit 1 is ignored. */
12631 tmp
= tcg_temp_new_i32();
12632 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
12634 val
= (insn
& 0xff) * 4;
12635 tcg_gen_addi_i32(tmp
, tmp
, val
);
12636 store_reg(s
, rd
, tmp
);
12641 op
= (insn
>> 8) & 0xf;
12645 * 0b1011_0000_xxxx_xxxx
12646 * - ADD (SP plus immediate)
12647 * - SUB (SP minus immediate)
12649 tmp
= load_reg(s
, 13);
12650 val
= (insn
& 0x7f) * 4;
12651 if (insn
& (1 << 7))
12652 val
= -(int32_t)val
;
12653 tcg_gen_addi_i32(tmp
, tmp
, val
);
12654 store_sp_checked(s
, tmp
);
12657 case 2: /* sign/zero extend. */
12660 rm
= (insn
>> 3) & 7;
12661 tmp
= load_reg(s
, rm
);
12662 switch ((insn
>> 6) & 3) {
12663 case 0: gen_sxth(tmp
); break;
12664 case 1: gen_sxtb(tmp
); break;
12665 case 2: gen_uxth(tmp
); break;
12666 case 3: gen_uxtb(tmp
); break;
12668 store_reg(s
, rd
, tmp
);
12670 case 4: case 5: case 0xc: case 0xd:
12672 * 0b1011_x10x_xxxx_xxxx
12675 addr
= load_reg(s
, 13);
12676 if (insn
& (1 << 8))
12680 for (i
= 0; i
< 8; i
++) {
12681 if (insn
& (1 << i
))
12684 if ((insn
& (1 << 11)) == 0) {
12685 tcg_gen_addi_i32(addr
, addr
, -offset
);
12688 if (s
->v8m_stackcheck
) {
12690 * Here 'addr' is the lower of "old SP" and "new SP";
12691 * if this is a pop that starts below the limit and ends
12692 * above it, it is UNKNOWN whether the limit check triggers;
12693 * we choose to trigger.
12695 gen_helper_v8m_stackcheck(cpu_env
, addr
);
12698 for (i
= 0; i
< 8; i
++) {
12699 if (insn
& (1 << i
)) {
12700 if (insn
& (1 << 11)) {
12702 tmp
= tcg_temp_new_i32();
12703 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12704 store_reg(s
, i
, tmp
);
12707 tmp
= load_reg(s
, i
);
12708 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12709 tcg_temp_free_i32(tmp
);
12711 /* advance to the next address. */
12712 tcg_gen_addi_i32(addr
, addr
, 4);
12716 if (insn
& (1 << 8)) {
12717 if (insn
& (1 << 11)) {
12719 tmp
= tcg_temp_new_i32();
12720 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12721 /* don't set the pc until the rest of the instruction
12725 tmp
= load_reg(s
, 14);
12726 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12727 tcg_temp_free_i32(tmp
);
12729 tcg_gen_addi_i32(addr
, addr
, 4);
12731 if ((insn
& (1 << 11)) == 0) {
12732 tcg_gen_addi_i32(addr
, addr
, -offset
);
12734 /* write back the new stack pointer */
12735 store_reg(s
, 13, addr
);
12736 /* set the new PC value */
12737 if ((insn
& 0x0900) == 0x0900) {
12738 store_reg_from_load(s
, 15, tmp
);
12742 case 1: case 3: case 9: case 11: /* czb */
12744 tmp
= load_reg(s
, rm
);
12745 arm_gen_condlabel(s
);
12746 if (insn
& (1 << 11))
12747 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
12749 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
12750 tcg_temp_free_i32(tmp
);
12751 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
12752 val
= (uint32_t)s
->pc
+ 2;
12757 case 15: /* IT, nop-hint. */
12758 if ((insn
& 0xf) == 0) {
12759 gen_nop_hint(s
, (insn
>> 4) & 0xf);
12763 s
->condexec_cond
= (insn
>> 4) & 0xe;
12764 s
->condexec_mask
= insn
& 0x1f;
12765 /* No actual code generated for this insn, just setup state. */
12768 case 0xe: /* bkpt */
12770 int imm8
= extract32(insn
, 0, 8);
12772 gen_exception_bkpt_insn(s
, 2, syn_aa32_bkpt(imm8
, true));
12776 case 0xa: /* rev, and hlt */
12778 int op1
= extract32(insn
, 6, 2);
12782 int imm6
= extract32(insn
, 0, 6);
12788 /* Otherwise this is rev */
12790 rn
= (insn
>> 3) & 0x7;
12792 tmp
= load_reg(s
, rn
);
12794 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
12795 case 1: gen_rev16(tmp
); break;
12796 case 3: gen_revsh(tmp
); break;
12798 g_assert_not_reached();
12800 store_reg(s
, rd
, tmp
);
12805 switch ((insn
>> 5) & 7) {
12809 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
12810 gen_helper_setend(cpu_env
);
12811 s
->base
.is_jmp
= DISAS_UPDATE
;
12820 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
12821 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
12824 addr
= tcg_const_i32(19);
12825 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12826 tcg_temp_free_i32(addr
);
12830 addr
= tcg_const_i32(16);
12831 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12832 tcg_temp_free_i32(addr
);
12834 tcg_temp_free_i32(tmp
);
12837 if (insn
& (1 << 4)) {
12838 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
12842 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
12857 /* load/store multiple */
12858 TCGv_i32 loaded_var
= NULL
;
12859 rn
= (insn
>> 8) & 0x7;
12860 addr
= load_reg(s
, rn
);
12861 for (i
= 0; i
< 8; i
++) {
12862 if (insn
& (1 << i
)) {
12863 if (insn
& (1 << 11)) {
12865 tmp
= tcg_temp_new_i32();
12866 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12870 store_reg(s
, i
, tmp
);
12874 tmp
= load_reg(s
, i
);
12875 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12876 tcg_temp_free_i32(tmp
);
12878 /* advance to the next address */
12879 tcg_gen_addi_i32(addr
, addr
, 4);
12882 if ((insn
& (1 << rn
)) == 0) {
12883 /* base reg not in list: base register writeback */
12884 store_reg(s
, rn
, addr
);
12886 /* base reg in list: if load, complete it now */
12887 if (insn
& (1 << 11)) {
12888 store_reg(s
, rn
, loaded_var
);
12890 tcg_temp_free_i32(addr
);
12895 /* conditional branch or swi */
12896 cond
= (insn
>> 8) & 0xf;
12902 gen_set_pc_im(s
, s
->pc
);
12903 s
->svc_imm
= extract32(insn
, 0, 8);
12904 s
->base
.is_jmp
= DISAS_SWI
;
12907 /* generate a conditional jump to next instruction */
12908 arm_skip_unless(s
, cond
);
12910 /* jump to the offset */
12911 val
= (uint32_t)s
->pc
+ 2;
12912 offset
= ((int32_t)insn
<< 24) >> 24;
12913 val
+= offset
<< 1;
12918 if (insn
& (1 << 11)) {
12919 /* thumb_insn_is_16bit() ensures we can't get here for
12920 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12921 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12923 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12925 offset
= ((insn
& 0x7ff) << 1);
12926 tmp
= load_reg(s
, 14);
12927 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12928 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
12930 tmp2
= tcg_temp_new_i32();
12931 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12932 store_reg(s
, 14, tmp2
);
12936 /* unconditional branch */
12937 val
= (uint32_t)s
->pc
;
12938 offset
= ((int32_t)insn
<< 21) >> 21;
12939 val
+= (offset
<< 1) + 2;
12944 /* thumb_insn_is_16bit() ensures we can't get here for
12945 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12947 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12949 if (insn
& (1 << 11)) {
12950 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12951 offset
= ((insn
& 0x7ff) << 1) | 1;
12952 tmp
= load_reg(s
, 14);
12953 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12955 tmp2
= tcg_temp_new_i32();
12956 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12957 store_reg(s
, 14, tmp2
);
12960 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12961 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
12963 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
12970 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
12971 default_exception_el(s
));
12974 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
12976 /* Return true if the insn at dc->pc might cross a page boundary.
12977 * (False positives are OK, false negatives are not.)
12978 * We know this is a Thumb insn, and our caller ensures we are
12979 * only called if dc->pc is less than 4 bytes from the page
12980 * boundary, so we cross the page if the first 16 bits indicate
12981 * that this is a 32 bit insn.
12983 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
12985 return !thumb_insn_is_16bit(s
, insn
);
12988 static void arm_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
12990 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12991 CPUARMState
*env
= cs
->env_ptr
;
12992 ARMCPU
*cpu
= env_archcpu(env
);
12993 uint32_t tb_flags
= dc
->base
.tb
->flags
;
12994 uint32_t condexec
, core_mmu_idx
;
12996 dc
->isar
= &cpu
->isar
;
12997 dc
->pc
= dc
->base
.pc_first
;
13001 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
13002 * there is no secure EL1, so we route exceptions to EL3.
13004 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
13005 !arm_el_is_aa64(env
, 3);
13006 dc
->thumb
= FIELD_EX32(tb_flags
, TBFLAG_A32
, THUMB
);
13007 dc
->sctlr_b
= FIELD_EX32(tb_flags
, TBFLAG_A32
, SCTLR_B
);
13008 dc
->be_data
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, BE_DATA
) ? MO_BE
: MO_LE
;
13009 condexec
= FIELD_EX32(tb_flags
, TBFLAG_A32
, CONDEXEC
);
13010 dc
->condexec_mask
= (condexec
& 0xf) << 1;
13011 dc
->condexec_cond
= condexec
>> 4;
13012 core_mmu_idx
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, MMUIDX
);
13013 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, core_mmu_idx
);
13014 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
13015 #if !defined(CONFIG_USER_ONLY)
13016 dc
->user
= (dc
->current_el
== 0);
13018 dc
->ns
= FIELD_EX32(tb_flags
, TBFLAG_A32
, NS
);
13019 dc
->fp_excp_el
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, FPEXC_EL
);
13020 dc
->vfp_enabled
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VFPEN
);
13021 dc
->vec_len
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECLEN
);
13022 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
13023 dc
->c15_cpar
= FIELD_EX32(tb_flags
, TBFLAG_A32
, XSCALE_CPAR
);
13024 dc
->vec_stride
= 0;
13026 dc
->vec_stride
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECSTRIDE
);
13029 dc
->v7m_handler_mode
= FIELD_EX32(tb_flags
, TBFLAG_A32
, HANDLER
);
13030 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
13031 regime_is_secure(env
, dc
->mmu_idx
);
13032 dc
->v8m_stackcheck
= FIELD_EX32(tb_flags
, TBFLAG_A32
, STACKCHECK
);
13033 dc
->v8m_fpccr_s_wrong
= FIELD_EX32(tb_flags
, TBFLAG_A32
, FPCCR_S_WRONG
);
13034 dc
->v7m_new_fp_ctxt_needed
=
13035 FIELD_EX32(tb_flags
, TBFLAG_A32
, NEW_FP_CTXT_NEEDED
);
13036 dc
->v7m_lspact
= FIELD_EX32(tb_flags
, TBFLAG_A32
, LSPACT
);
13037 dc
->cp_regs
= cpu
->cp_regs
;
13038 dc
->features
= env
->features
;
13040 /* Single step state. The code-generation logic here is:
13042 * generate code with no special handling for single-stepping (except
13043 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
13044 * this happens anyway because those changes are all system register or
13046 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
13047 * emit code for one insn
13048 * emit code to clear PSTATE.SS
13049 * emit code to generate software step exception for completed step
13050 * end TB (as usual for having generated an exception)
13051 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
13052 * emit code to generate a software step exception
13055 dc
->ss_active
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, SS_ACTIVE
);
13056 dc
->pstate_ss
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, PSTATE_SS
);
13057 dc
->is_ldex
= false;
13058 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
13060 dc
->page_start
= dc
->base
.pc_first
& TARGET_PAGE_MASK
;
13062 /* If architectural single step active, limit to 1. */
13063 if (is_singlestepping(dc
)) {
13064 dc
->base
.max_insns
= 1;
13067 /* ARM is a fixed-length ISA. Bound the number of insns to execute
13068 to those left on the page. */
13070 int bound
= -(dc
->base
.pc_first
| TARGET_PAGE_MASK
) / 4;
13071 dc
->base
.max_insns
= MIN(dc
->base
.max_insns
, bound
);
13074 cpu_F0s
= tcg_temp_new_i32();
13075 cpu_F1s
= tcg_temp_new_i32();
13076 cpu_F0d
= tcg_temp_new_i64();
13077 cpu_F1d
= tcg_temp_new_i64();
13080 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
13081 cpu_M0
= tcg_temp_new_i64();
13084 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
13086 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
13088 /* A note on handling of the condexec (IT) bits:
13090 * We want to avoid the overhead of having to write the updated condexec
13091 * bits back to the CPUARMState for every instruction in an IT block. So:
13092 * (1) if the condexec bits are not already zero then we write
13093 * zero back into the CPUARMState now. This avoids complications trying
13094 * to do it at the end of the block. (For example if we don't do this
13095 * it's hard to identify whether we can safely skip writing condexec
13096 * at the end of the TB, which we definitely want to do for the case
13097 * where a TB doesn't do anything with the IT state at all.)
13098 * (2) if we are going to leave the TB then we call gen_set_condexec()
13099 * which will write the correct value into CPUARMState if zero is wrong.
13100 * This is done both for leaving the TB at the end, and for leaving
13101 * it because of an exception we know will happen, which is done in
13102 * gen_exception_insn(). The latter is necessary because we need to
13103 * leave the TB with the PC/IT state just prior to execution of the
13104 * instruction which caused the exception.
13105 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
13106 * then the CPUARMState will be wrong and we need to reset it.
13107 * This is handled in the same way as restoration of the
13108 * PC in these situations; we save the value of the condexec bits
13109 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
13110 * then uses this to restore them after an exception.
13112 * Note that there are no instructions which can read the condexec
13113 * bits, and none which can write non-static values to them, so
13114 * we don't need to care about whether CPUARMState is correct in the
13118 /* Reset the conditional execution bits immediately. This avoids
13119 complications trying to do it at the end of the block. */
13120 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
13121 TCGv_i32 tmp
= tcg_temp_new_i32();
13122 tcg_gen_movi_i32(tmp
, 0);
13123 store_cpu_field(tmp
, condexec_bits
);
13127 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
13129 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
13131 tcg_gen_insn_start(dc
->pc
,
13132 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
13134 dc
->insn_start
= tcg_last_op();
13137 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
13138 const CPUBreakpoint
*bp
)
13140 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
13142 if (bp
->flags
& BP_CPU
) {
13143 gen_set_condexec(dc
);
13144 gen_set_pc_im(dc
, dc
->pc
);
13145 gen_helper_check_breakpoints(cpu_env
);
13146 /* End the TB early; it's likely not going to be executed */
13147 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
13149 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
13150 /* The address covered by the breakpoint must be
13151 included in [tb->pc, tb->pc + tb->size) in order
13152 to for it to be properly cleared -- thus we
13153 increment the PC here so that the logic setting
13154 tb->size below does the right thing. */
13155 /* TODO: Advance PC by correct instruction length to
13156 * avoid disassembler error messages */
13158 dc
->base
.is_jmp
= DISAS_NORETURN
;
13164 static bool arm_pre_translate_insn(DisasContext
*dc
)
13166 #ifdef CONFIG_USER_ONLY
13167 /* Intercept jump to the magic kernel page. */
13168 if (dc
->pc
>= 0xffff0000) {
13169 /* We always get here via a jump, so know we are not in a
13170 conditional execution block. */
13171 gen_exception_internal(EXCP_KERNEL_TRAP
);
13172 dc
->base
.is_jmp
= DISAS_NORETURN
;
13177 if (dc
->ss_active
&& !dc
->pstate_ss
) {
13178 /* Singlestep state is Active-pending.
13179 * If we're in this state at the start of a TB then either
13180 * a) we just took an exception to an EL which is being debugged
13181 * and this is the first insn in the exception handler
13182 * b) debug exceptions were masked and we just unmasked them
13183 * without changing EL (eg by clearing PSTATE.D)
13184 * In either case we're going to take a swstep exception in the
13185 * "did not step an insn" case, and so the syndrome ISV and EX
13186 * bits should be zero.
13188 assert(dc
->base
.num_insns
== 1);
13189 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
13190 default_exception_el(dc
));
13191 dc
->base
.is_jmp
= DISAS_NORETURN
;
13198 static void arm_post_translate_insn(DisasContext
*dc
)
13200 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
13201 gen_set_label(dc
->condlabel
);
13204 dc
->base
.pc_next
= dc
->pc
;
13205 translator_loop_temp_check(&dc
->base
);
13208 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
13210 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
13211 CPUARMState
*env
= cpu
->env_ptr
;
13214 if (arm_pre_translate_insn(dc
)) {
13218 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
13221 disas_arm_insn(dc
, insn
);
13223 arm_post_translate_insn(dc
);
13225 /* ARM is a fixed-length ISA. We performed the cross-page check
13226 in init_disas_context by adjusting max_insns. */
13229 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
13231 /* Return true if this Thumb insn is always unconditional,
13232 * even inside an IT block. This is true of only a very few
13233 * instructions: BKPT, HLT, and SG.
13235 * A larger class of instructions are UNPREDICTABLE if used
13236 * inside an IT block; we do not need to detect those here, because
13237 * what we do by default (perform the cc check and update the IT
13238 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
13239 * choice for those situations.
13241 * insn is either a 16-bit or a 32-bit instruction; the two are
13242 * distinguishable because for the 16-bit case the top 16 bits
13243 * are zeroes, and that isn't a valid 32-bit encoding.
13245 if ((insn
& 0xffffff00) == 0xbe00) {
13250 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
13251 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
13252 /* HLT: v8A only. This is unconditional even when it is going to
13253 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
13254 * For v7 cores this was a plain old undefined encoding and so
13255 * honours its cc check. (We might be using the encoding as
13256 * a semihosting trap, but we don't change the cc check behaviour
13257 * on that account, because a debugger connected to a real v7A
13258 * core and emulating semihosting traps by catching the UNDEF
13259 * exception would also only see cases where the cc check passed.
13260 * No guest code should be trying to do a HLT semihosting trap
13261 * in an IT block anyway.
13266 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
13267 arm_dc_feature(s
, ARM_FEATURE_M
)) {
13275 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
13277 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
13278 CPUARMState
*env
= cpu
->env_ptr
;
13282 if (arm_pre_translate_insn(dc
)) {
13286 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
13287 is_16bit
= thumb_insn_is_16bit(dc
, insn
);
13290 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
13292 insn
= insn
<< 16 | insn2
;
13297 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
13298 uint32_t cond
= dc
->condexec_cond
;
13300 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
13301 arm_skip_unless(dc
, cond
);
13306 disas_thumb_insn(dc
, insn
);
13308 disas_thumb2_insn(dc
, insn
);
13311 /* Advance the Thumb condexec condition. */
13312 if (dc
->condexec_mask
) {
13313 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
13314 ((dc
->condexec_mask
>> 4) & 1));
13315 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
13316 if (dc
->condexec_mask
== 0) {
13317 dc
->condexec_cond
= 0;
13321 arm_post_translate_insn(dc
);
13323 /* Thumb is a variable-length ISA. Stop translation when the next insn
13324 * will touch a new page. This ensures that prefetch aborts occur at
13327 * We want to stop the TB if the next insn starts in a new page,
13328 * or if it spans between this page and the next. This means that
13329 * if we're looking at the last halfword in the page we need to
13330 * see if it's a 16-bit Thumb insn (which will fit in this TB)
13331 * or a 32-bit Thumb insn (which won't).
13332 * This is to avoid generating a silly TB with a single 16-bit insn
13333 * in it at the end of this page (which would execute correctly
13334 * but isn't very efficient).
13336 if (dc
->base
.is_jmp
== DISAS_NEXT
13337 && (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
13338 || (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
- 3
13339 && insn_crosses_page(env
, dc
)))) {
13340 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
13344 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
13346 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
13348 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
13349 /* FIXME: This can theoretically happen with self-modifying code. */
13350 cpu_abort(cpu
, "IO on conditional branch instruction");
13353 /* At this stage dc->condjmp will only be set when the skipped
13354 instruction was a conditional branch or trap, and the PC has
13355 already been written. */
13356 gen_set_condexec(dc
);
13357 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
13358 /* Exception return branches need some special case code at the
13359 * end of the TB, which is complex enough that it has to
13360 * handle the single-step vs not and the condition-failed
13361 * insn codepath itself.
13363 gen_bx_excret_final_code(dc
);
13364 } else if (unlikely(is_singlestepping(dc
))) {
13365 /* Unconditional and "condition passed" instruction codepath. */
13366 switch (dc
->base
.is_jmp
) {
13368 gen_ss_advance(dc
);
13369 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
13370 default_exception_el(dc
));
13373 gen_ss_advance(dc
);
13374 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
13377 gen_ss_advance(dc
);
13378 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
13381 case DISAS_TOO_MANY
:
13383 gen_set_pc_im(dc
, dc
->pc
);
13386 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
13387 gen_singlestep_exception(dc
);
13389 case DISAS_NORETURN
:
13393 /* While branches must always occur at the end of an IT block,
13394 there are a few other things that can cause us to terminate
13395 the TB in the middle of an IT block:
13396 - Exception generating instructions (bkpt, swi, undefined).
13398 - Hardware watchpoints.
13399 Hardware breakpoints have already been handled and skip this code.
13401 switch(dc
->base
.is_jmp
) {
13403 case DISAS_TOO_MANY
:
13404 gen_goto_tb(dc
, 1, dc
->pc
);
13410 gen_set_pc_im(dc
, dc
->pc
);
13413 /* indicate that the hash table must be used to find the next TB */
13414 tcg_gen_exit_tb(NULL
, 0);
13416 case DISAS_NORETURN
:
13417 /* nothing more to generate */
13421 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
13422 !(dc
->insn
& (1U << 31))) ? 2 : 4);
13424 gen_helper_wfi(cpu_env
, tmp
);
13425 tcg_temp_free_i32(tmp
);
13426 /* The helper doesn't necessarily throw an exception, but we
13427 * must go back to the main loop to check for interrupts anyway.
13429 tcg_gen_exit_tb(NULL
, 0);
13433 gen_helper_wfe(cpu_env
);
13436 gen_helper_yield(cpu_env
);
13439 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
13440 default_exception_el(dc
));
13443 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
13446 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
13452 /* "Condition failed" instruction codepath for the branch/trap insn */
13453 gen_set_label(dc
->condlabel
);
13454 gen_set_condexec(dc
);
13455 if (unlikely(is_singlestepping(dc
))) {
13456 gen_set_pc_im(dc
, dc
->pc
);
13457 gen_singlestep_exception(dc
);
13459 gen_goto_tb(dc
, 1, dc
->pc
);
13463 /* Functions above can change dc->pc, so re-align db->pc_next */
13464 dc
->base
.pc_next
= dc
->pc
;
13467 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
13469 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
13471 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
13472 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
13475 static const TranslatorOps arm_translator_ops
= {
13476 .init_disas_context
= arm_tr_init_disas_context
,
13477 .tb_start
= arm_tr_tb_start
,
13478 .insn_start
= arm_tr_insn_start
,
13479 .breakpoint_check
= arm_tr_breakpoint_check
,
13480 .translate_insn
= arm_tr_translate_insn
,
13481 .tb_stop
= arm_tr_tb_stop
,
13482 .disas_log
= arm_tr_disas_log
,
13485 static const TranslatorOps thumb_translator_ops
= {
13486 .init_disas_context
= arm_tr_init_disas_context
,
13487 .tb_start
= arm_tr_tb_start
,
13488 .insn_start
= arm_tr_insn_start
,
13489 .breakpoint_check
= arm_tr_breakpoint_check
,
13490 .translate_insn
= thumb_tr_translate_insn
,
13491 .tb_stop
= arm_tr_tb_stop
,
13492 .disas_log
= arm_tr_disas_log
,
13495 /* generate intermediate code for basic block 'tb'. */
13496 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
13499 const TranslatorOps
*ops
= &arm_translator_ops
;
13501 if (FIELD_EX32(tb
->flags
, TBFLAG_A32
, THUMB
)) {
13502 ops
= &thumb_translator_ops
;
13504 #ifdef TARGET_AARCH64
13505 if (FIELD_EX32(tb
->flags
, TBFLAG_ANY
, AARCH64_STATE
)) {
13506 ops
= &aarch64_translator_ops
;
13510 translator_loop(ops
, &dc
.base
, cpu
, tb
, max_insns
);
13513 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
13515 ARMCPU
*cpu
= ARM_CPU(cs
);
13516 CPUARMState
*env
= &cpu
->env
;
13520 aarch64_cpu_dump_state(cs
, f
, flags
);
13524 for(i
=0;i
<16;i
++) {
13525 qemu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
13527 qemu_fprintf(f
, "\n");
13529 qemu_fprintf(f
, " ");
13532 if (arm_feature(env
, ARM_FEATURE_M
)) {
13533 uint32_t xpsr
= xpsr_read(env
);
13535 const char *ns_status
= "";
13537 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
13538 ns_status
= env
->v7m
.secure
? "S " : "NS ";
13541 if (xpsr
& XPSR_EXCP
) {
13544 if (env
->v7m
.control
[env
->v7m
.secure
] & R_V7M_CONTROL_NPRIV_MASK
) {
13545 mode
= "unpriv-thread";
13547 mode
= "priv-thread";
13551 qemu_fprintf(f
, "XPSR=%08x %c%c%c%c %c %s%s\n",
13553 xpsr
& XPSR_N
? 'N' : '-',
13554 xpsr
& XPSR_Z
? 'Z' : '-',
13555 xpsr
& XPSR_C
? 'C' : '-',
13556 xpsr
& XPSR_V
? 'V' : '-',
13557 xpsr
& XPSR_T
? 'T' : 'A',
13561 uint32_t psr
= cpsr_read(env
);
13562 const char *ns_status
= "";
13564 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
13565 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
13566 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
13569 qemu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13571 psr
& CPSR_N
? 'N' : '-',
13572 psr
& CPSR_Z
? 'Z' : '-',
13573 psr
& CPSR_C
? 'C' : '-',
13574 psr
& CPSR_V
? 'V' : '-',
13575 psr
& CPSR_T
? 'T' : 'A',
13577 aarch32_mode_name(psr
), (psr
& 0x10) ? 32 : 26);
13580 if (flags
& CPU_DUMP_FPU
) {
13581 int numvfpregs
= 0;
13582 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
13585 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
13588 for (i
= 0; i
< numvfpregs
; i
++) {
13589 uint64_t v
= *aa32_vfp_dreg(env
, i
);
13590 qemu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
13591 i
* 2, (uint32_t)v
,
13592 i
* 2 + 1, (uint32_t)(v
>> 32),
13595 qemu_fprintf(f
, "FPSCR: %08x\n", vfp_get_fpscr(env
));
13599 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
13600 target_ulong
*data
)
13604 env
->condexec_bits
= 0;
13605 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
13607 env
->regs
[15] = data
[0];
13608 env
->condexec_bits
= data
[1];
13609 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;