4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
28 #include "tcg-op-gvec.h"
30 #include "qemu/bitops.h"
32 #include "exec/semihost.h"
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
37 #include "trace-tcg.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J arm_dc_feature(s, ARM_FEATURE_JAZELLE)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
56 #if defined(CONFIG_USER_ONLY)
59 #define IS_USER(s) (s->user)
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
64 static TCGv_i32 cpu_R
[16];
65 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
66 TCGv_i64 cpu_exclusive_addr
;
67 TCGv_i64 cpu_exclusive_val
;
69 /* FIXME: These should be removed. */
70 static TCGv_i32 cpu_F0s
, cpu_F1s
;
71 static TCGv_i64 cpu_F0d
, cpu_F1d
;
73 #include "exec/gen-icount.h"
75 static const char *regnames
[] =
76 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
79 /* Function prototypes for gen_ functions calling Neon helpers. */
80 typedef void NeonGenThreeOpEnvFn(TCGv_i32
, TCGv_env
, TCGv_i32
,
83 /* initialize TCG globals. */
84 void arm_translate_init(void)
88 for (i
= 0; i
< 16; i
++) {
89 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
90 offsetof(CPUARMState
, regs
[i
]),
93 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
94 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
95 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
96 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
98 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
99 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
100 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
101 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
103 a64_translate_init();
106 /* Flags for the disas_set_da_iss info argument:
107 * lower bits hold the Rt register number, higher bits are flags.
109 typedef enum ISSInfo
{
112 ISSInvalid
= (1 << 5),
113 ISSIsAcqRel
= (1 << 6),
114 ISSIsWrite
= (1 << 7),
115 ISSIs16Bit
= (1 << 8),
118 /* Save the syndrome information for a Data Abort */
119 static void disas_set_da_iss(DisasContext
*s
, TCGMemOp memop
, ISSInfo issinfo
)
122 int sas
= memop
& MO_SIZE
;
123 bool sse
= memop
& MO_SIGN
;
124 bool is_acqrel
= issinfo
& ISSIsAcqRel
;
125 bool is_write
= issinfo
& ISSIsWrite
;
126 bool is_16bit
= issinfo
& ISSIs16Bit
;
127 int srt
= issinfo
& ISSRegMask
;
129 if (issinfo
& ISSInvalid
) {
130 /* Some callsites want to conditionally provide ISS info,
131 * eg "only if this was not a writeback"
137 /* For AArch32, insns where the src/dest is R15 never generate
138 * ISS information. Catching that here saves checking at all
144 syn
= syn_data_abort_with_iss(0, sas
, sse
, srt
, 0, is_acqrel
,
145 0, 0, 0, is_write
, 0, is_16bit
);
146 disas_set_insn_syndrome(s
, syn
);
149 static inline int get_a32_user_mem_index(DisasContext
*s
)
151 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
153 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
154 * otherwise, access as if at PL0.
156 switch (s
->mmu_idx
) {
157 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
158 case ARMMMUIdx_S12NSE0
:
159 case ARMMMUIdx_S12NSE1
:
160 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0
);
162 case ARMMMUIdx_S1SE0
:
163 case ARMMMUIdx_S1SE1
:
164 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0
);
165 case ARMMMUIdx_MUser
:
166 case ARMMMUIdx_MPriv
:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser
);
168 case ARMMMUIdx_MUserNegPri
:
169 case ARMMMUIdx_MPrivNegPri
:
170 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri
);
171 case ARMMMUIdx_MSUser
:
172 case ARMMMUIdx_MSPriv
:
173 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser
);
174 case ARMMMUIdx_MSUserNegPri
:
175 case ARMMMUIdx_MSPrivNegPri
:
176 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri
);
179 g_assert_not_reached();
183 static inline TCGv_i32
load_cpu_offset(int offset
)
185 TCGv_i32 tmp
= tcg_temp_new_i32();
186 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
190 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
192 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
194 tcg_gen_st_i32(var
, cpu_env
, offset
);
195 tcg_temp_free_i32(var
);
198 #define store_cpu_field(var, name) \
199 store_cpu_offset(var, offsetof(CPUARMState, name))
201 /* Set a variable to the value of a CPU register. */
202 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
206 /* normally, since we updated PC, we need only to add one insn */
208 addr
= (long)s
->pc
+ 2;
210 addr
= (long)s
->pc
+ 4;
211 tcg_gen_movi_i32(var
, addr
);
213 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
217 /* Create a new temporary and set it to the value of a CPU register. */
218 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
220 TCGv_i32 tmp
= tcg_temp_new_i32();
221 load_reg_var(s
, tmp
, reg
);
225 /* Set a CPU register. The source must be a temporary and will be
227 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
230 /* In Thumb mode, we must ignore bit 0.
231 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
232 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
233 * We choose to ignore [1:0] in ARM mode for all architecture versions.
235 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
236 s
->base
.is_jmp
= DISAS_JUMP
;
238 tcg_gen_mov_i32(cpu_R
[reg
], var
);
239 tcg_temp_free_i32(var
);
242 /* Value extensions. */
243 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
244 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
245 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
246 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
248 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
249 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
252 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
254 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
255 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
256 tcg_temp_free_i32(tmp_mask
);
258 /* Set NZCV flags from the high 4 bits of var. */
259 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
261 static void gen_exception_internal(int excp
)
263 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
265 assert(excp_is_internal(excp
));
266 gen_helper_exception_internal(cpu_env
, tcg_excp
);
267 tcg_temp_free_i32(tcg_excp
);
270 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
272 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
273 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
274 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
276 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
279 tcg_temp_free_i32(tcg_el
);
280 tcg_temp_free_i32(tcg_syn
);
281 tcg_temp_free_i32(tcg_excp
);
284 static void gen_ss_advance(DisasContext
*s
)
286 /* If the singlestep state is Active-not-pending, advance to
291 gen_helper_clear_pstate_ss(cpu_env
);
295 static void gen_step_complete_exception(DisasContext
*s
)
297 /* We just completed step of an insn. Move from Active-not-pending
298 * to Active-pending, and then also take the swstep exception.
299 * This corresponds to making the (IMPDEF) choice to prioritize
300 * swstep exceptions over asynchronous exceptions taken to an exception
301 * level where debug is disabled. This choice has the advantage that
302 * we do not need to maintain internal state corresponding to the
303 * ISV/EX syndrome bits between completion of the step and generation
304 * of the exception, and our syndrome information is always correct.
307 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
308 default_exception_el(s
));
309 s
->base
.is_jmp
= DISAS_NORETURN
;
312 static void gen_singlestep_exception(DisasContext
*s
)
314 /* Generate the right kind of exception for singlestep, which is
315 * either the architectural singlestep or EXCP_DEBUG for QEMU's
316 * gdb singlestepping.
319 gen_step_complete_exception(s
);
321 gen_exception_internal(EXCP_DEBUG
);
325 static inline bool is_singlestepping(DisasContext
*s
)
327 /* Return true if we are singlestepping either because of
328 * architectural singlestep or QEMU gdbstub singlestep. This does
329 * not include the command line '-singlestep' mode which is rather
330 * misnamed as it only means "one instruction per TB" and doesn't
331 * affect the code we generate.
333 return s
->base
.singlestep_enabled
|| s
->ss_active
;
336 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
338 TCGv_i32 tmp1
= tcg_temp_new_i32();
339 TCGv_i32 tmp2
= tcg_temp_new_i32();
340 tcg_gen_ext16s_i32(tmp1
, a
);
341 tcg_gen_ext16s_i32(tmp2
, b
);
342 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
343 tcg_temp_free_i32(tmp2
);
344 tcg_gen_sari_i32(a
, a
, 16);
345 tcg_gen_sari_i32(b
, b
, 16);
346 tcg_gen_mul_i32(b
, b
, a
);
347 tcg_gen_mov_i32(a
, tmp1
);
348 tcg_temp_free_i32(tmp1
);
351 /* Byteswap each halfword. */
352 static void gen_rev16(TCGv_i32 var
)
354 TCGv_i32 tmp
= tcg_temp_new_i32();
355 TCGv_i32 mask
= tcg_const_i32(0x00ff00ff);
356 tcg_gen_shri_i32(tmp
, var
, 8);
357 tcg_gen_and_i32(tmp
, tmp
, mask
);
358 tcg_gen_and_i32(var
, var
, mask
);
359 tcg_gen_shli_i32(var
, var
, 8);
360 tcg_gen_or_i32(var
, var
, tmp
);
361 tcg_temp_free_i32(mask
);
362 tcg_temp_free_i32(tmp
);
365 /* Byteswap low halfword and sign extend. */
366 static void gen_revsh(TCGv_i32 var
)
368 tcg_gen_ext16u_i32(var
, var
);
369 tcg_gen_bswap16_i32(var
, var
);
370 tcg_gen_ext16s_i32(var
, var
);
373 /* Return (b << 32) + a. Mark inputs as dead */
374 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
376 TCGv_i64 tmp64
= tcg_temp_new_i64();
378 tcg_gen_extu_i32_i64(tmp64
, b
);
379 tcg_temp_free_i32(b
);
380 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
381 tcg_gen_add_i64(a
, tmp64
, a
);
383 tcg_temp_free_i64(tmp64
);
387 /* Return (b << 32) - a. Mark inputs as dead. */
388 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
390 TCGv_i64 tmp64
= tcg_temp_new_i64();
392 tcg_gen_extu_i32_i64(tmp64
, b
);
393 tcg_temp_free_i32(b
);
394 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
395 tcg_gen_sub_i64(a
, tmp64
, a
);
397 tcg_temp_free_i64(tmp64
);
401 /* 32x32->64 multiply. Marks inputs as dead. */
402 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
404 TCGv_i32 lo
= tcg_temp_new_i32();
405 TCGv_i32 hi
= tcg_temp_new_i32();
408 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
409 tcg_temp_free_i32(a
);
410 tcg_temp_free_i32(b
);
412 ret
= tcg_temp_new_i64();
413 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
414 tcg_temp_free_i32(lo
);
415 tcg_temp_free_i32(hi
);
420 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
422 TCGv_i32 lo
= tcg_temp_new_i32();
423 TCGv_i32 hi
= tcg_temp_new_i32();
426 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
427 tcg_temp_free_i32(a
);
428 tcg_temp_free_i32(b
);
430 ret
= tcg_temp_new_i64();
431 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
432 tcg_temp_free_i32(lo
);
433 tcg_temp_free_i32(hi
);
438 /* Swap low and high halfwords. */
439 static void gen_swap_half(TCGv_i32 var
)
441 TCGv_i32 tmp
= tcg_temp_new_i32();
442 tcg_gen_shri_i32(tmp
, var
, 16);
443 tcg_gen_shli_i32(var
, var
, 16);
444 tcg_gen_or_i32(var
, var
, tmp
);
445 tcg_temp_free_i32(tmp
);
448 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
449 tmp = (t0 ^ t1) & 0x8000;
452 t0 = (t0 + t1) ^ tmp;
455 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
457 TCGv_i32 tmp
= tcg_temp_new_i32();
458 tcg_gen_xor_i32(tmp
, t0
, t1
);
459 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
460 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
461 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
462 tcg_gen_add_i32(t0
, t0
, t1
);
463 tcg_gen_xor_i32(t0
, t0
, tmp
);
464 tcg_temp_free_i32(tmp
);
465 tcg_temp_free_i32(t1
);
468 /* Set CF to the top bit of var. */
469 static void gen_set_CF_bit31(TCGv_i32 var
)
471 tcg_gen_shri_i32(cpu_CF
, var
, 31);
474 /* Set N and Z flags from var. */
475 static inline void gen_logic_CC(TCGv_i32 var
)
477 tcg_gen_mov_i32(cpu_NF
, var
);
478 tcg_gen_mov_i32(cpu_ZF
, var
);
482 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
484 tcg_gen_add_i32(t0
, t0
, t1
);
485 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
488 /* dest = T0 + T1 + CF. */
489 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
491 tcg_gen_add_i32(dest
, t0
, t1
);
492 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
495 /* dest = T0 - T1 + CF - 1. */
496 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
498 tcg_gen_sub_i32(dest
, t0
, t1
);
499 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
500 tcg_gen_subi_i32(dest
, dest
, 1);
503 /* dest = T0 + T1. Compute C, N, V and Z flags */
504 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
506 TCGv_i32 tmp
= tcg_temp_new_i32();
507 tcg_gen_movi_i32(tmp
, 0);
508 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
509 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
510 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
511 tcg_gen_xor_i32(tmp
, t0
, t1
);
512 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
513 tcg_temp_free_i32(tmp
);
514 tcg_gen_mov_i32(dest
, cpu_NF
);
517 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
518 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
520 TCGv_i32 tmp
= tcg_temp_new_i32();
521 if (TCG_TARGET_HAS_add2_i32
) {
522 tcg_gen_movi_i32(tmp
, 0);
523 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
524 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
526 TCGv_i64 q0
= tcg_temp_new_i64();
527 TCGv_i64 q1
= tcg_temp_new_i64();
528 tcg_gen_extu_i32_i64(q0
, t0
);
529 tcg_gen_extu_i32_i64(q1
, t1
);
530 tcg_gen_add_i64(q0
, q0
, q1
);
531 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
532 tcg_gen_add_i64(q0
, q0
, q1
);
533 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
534 tcg_temp_free_i64(q0
);
535 tcg_temp_free_i64(q1
);
537 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
538 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
539 tcg_gen_xor_i32(tmp
, t0
, t1
);
540 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
541 tcg_temp_free_i32(tmp
);
542 tcg_gen_mov_i32(dest
, cpu_NF
);
545 /* dest = T0 - T1. Compute C, N, V and Z flags */
546 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
549 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
550 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
551 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
552 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
553 tmp
= tcg_temp_new_i32();
554 tcg_gen_xor_i32(tmp
, t0
, t1
);
555 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
556 tcg_temp_free_i32(tmp
);
557 tcg_gen_mov_i32(dest
, cpu_NF
);
560 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
561 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
563 TCGv_i32 tmp
= tcg_temp_new_i32();
564 tcg_gen_not_i32(tmp
, t1
);
565 gen_adc_CC(dest
, t0
, tmp
);
566 tcg_temp_free_i32(tmp
);
569 #define GEN_SHIFT(name) \
570 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
572 TCGv_i32 tmp1, tmp2, tmp3; \
573 tmp1 = tcg_temp_new_i32(); \
574 tcg_gen_andi_i32(tmp1, t1, 0xff); \
575 tmp2 = tcg_const_i32(0); \
576 tmp3 = tcg_const_i32(0x1f); \
577 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
578 tcg_temp_free_i32(tmp3); \
579 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
580 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
581 tcg_temp_free_i32(tmp2); \
582 tcg_temp_free_i32(tmp1); \
588 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
591 tmp1
= tcg_temp_new_i32();
592 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
593 tmp2
= tcg_const_i32(0x1f);
594 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
595 tcg_temp_free_i32(tmp2
);
596 tcg_gen_sar_i32(dest
, t0
, tmp1
);
597 tcg_temp_free_i32(tmp1
);
600 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
602 TCGv_i32 c0
= tcg_const_i32(0);
603 TCGv_i32 tmp
= tcg_temp_new_i32();
604 tcg_gen_neg_i32(tmp
, src
);
605 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
606 tcg_temp_free_i32(c0
);
607 tcg_temp_free_i32(tmp
);
610 static void shifter_out_im(TCGv_i32 var
, int shift
)
613 tcg_gen_andi_i32(cpu_CF
, var
, 1);
615 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
617 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
622 /* Shift by immediate. Includes special handling for shift == 0. */
623 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
624 int shift
, int flags
)
630 shifter_out_im(var
, 32 - shift
);
631 tcg_gen_shli_i32(var
, var
, shift
);
637 tcg_gen_shri_i32(cpu_CF
, var
, 31);
639 tcg_gen_movi_i32(var
, 0);
642 shifter_out_im(var
, shift
- 1);
643 tcg_gen_shri_i32(var
, var
, shift
);
650 shifter_out_im(var
, shift
- 1);
653 tcg_gen_sari_i32(var
, var
, shift
);
655 case 3: /* ROR/RRX */
658 shifter_out_im(var
, shift
- 1);
659 tcg_gen_rotri_i32(var
, var
, shift
); break;
661 TCGv_i32 tmp
= tcg_temp_new_i32();
662 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
664 shifter_out_im(var
, 0);
665 tcg_gen_shri_i32(var
, var
, 1);
666 tcg_gen_or_i32(var
, var
, tmp
);
667 tcg_temp_free_i32(tmp
);
672 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
673 TCGv_i32 shift
, int flags
)
677 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
678 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
679 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
680 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
685 gen_shl(var
, var
, shift
);
688 gen_shr(var
, var
, shift
);
691 gen_sar(var
, var
, shift
);
693 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
694 tcg_gen_rotr_i32(var
, var
, shift
); break;
697 tcg_temp_free_i32(shift
);
700 #define PAS_OP(pfx) \
702 case 0: gen_pas_helper(glue(pfx,add16)); break; \
703 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
704 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
705 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
706 case 4: gen_pas_helper(glue(pfx,add8)); break; \
707 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
709 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
714 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
716 tmp
= tcg_temp_new_ptr();
717 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
719 tcg_temp_free_ptr(tmp
);
722 tmp
= tcg_temp_new_ptr();
723 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
725 tcg_temp_free_ptr(tmp
);
727 #undef gen_pas_helper
728 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
741 #undef gen_pas_helper
746 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
747 #define PAS_OP(pfx) \
749 case 0: gen_pas_helper(glue(pfx,add8)); break; \
750 case 1: gen_pas_helper(glue(pfx,add16)); break; \
751 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
752 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
753 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
754 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
756 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
761 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
763 tmp
= tcg_temp_new_ptr();
764 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
766 tcg_temp_free_ptr(tmp
);
769 tmp
= tcg_temp_new_ptr();
770 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
772 tcg_temp_free_ptr(tmp
);
774 #undef gen_pas_helper
775 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
788 #undef gen_pas_helper
794 * Generate a conditional based on ARM condition code cc.
795 * This is common between ARM and Aarch64 targets.
797 void arm_test_cc(DisasCompare
*cmp
, int cc
)
828 case 8: /* hi: C && !Z */
829 case 9: /* ls: !C || Z -> !(C && !Z) */
831 value
= tcg_temp_new_i32();
833 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
834 ZF is non-zero for !Z; so AND the two subexpressions. */
835 tcg_gen_neg_i32(value
, cpu_CF
);
836 tcg_gen_and_i32(value
, value
, cpu_ZF
);
839 case 10: /* ge: N == V -> N ^ V == 0 */
840 case 11: /* lt: N != V -> N ^ V != 0 */
841 /* Since we're only interested in the sign bit, == 0 is >= 0. */
843 value
= tcg_temp_new_i32();
845 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
848 case 12: /* gt: !Z && N == V */
849 case 13: /* le: Z || N != V */
851 value
= tcg_temp_new_i32();
853 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
854 * the sign bit then AND with ZF to yield the result. */
855 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
856 tcg_gen_sari_i32(value
, value
, 31);
857 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
860 case 14: /* always */
861 case 15: /* always */
862 /* Use the ALWAYS condition, which will fold early.
863 * It doesn't matter what we use for the value. */
864 cond
= TCG_COND_ALWAYS
;
869 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
874 cond
= tcg_invert_cond(cond
);
880 cmp
->value_global
= global
;
883 void arm_free_cc(DisasCompare
*cmp
)
885 if (!cmp
->value_global
) {
886 tcg_temp_free_i32(cmp
->value
);
890 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
892 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
895 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
898 arm_test_cc(&cmp
, cc
);
899 arm_jump_cc(&cmp
, label
);
903 static const uint8_t table_logic_cc
[16] = {
922 static inline void gen_set_condexec(DisasContext
*s
)
924 if (s
->condexec_mask
) {
925 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
926 TCGv_i32 tmp
= tcg_temp_new_i32();
927 tcg_gen_movi_i32(tmp
, val
);
928 store_cpu_field(tmp
, condexec_bits
);
932 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
934 tcg_gen_movi_i32(cpu_R
[15], val
);
937 /* Set PC and Thumb state from an immediate address. */
938 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
942 s
->base
.is_jmp
= DISAS_JUMP
;
943 if (s
->thumb
!= (addr
& 1)) {
944 tmp
= tcg_temp_new_i32();
945 tcg_gen_movi_i32(tmp
, addr
& 1);
946 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
947 tcg_temp_free_i32(tmp
);
949 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
952 /* Set PC and Thumb state from var. var is marked as dead. */
953 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
955 s
->base
.is_jmp
= DISAS_JUMP
;
956 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
957 tcg_gen_andi_i32(var
, var
, 1);
958 store_cpu_field(var
, thumb
);
961 /* Set PC and Thumb state from var. var is marked as dead.
962 * For M-profile CPUs, include logic to detect exception-return
963 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
964 * and BX reg, and no others, and happens only for code in Handler mode.
966 static inline void gen_bx_excret(DisasContext
*s
, TCGv_i32 var
)
968 /* Generate the same code here as for a simple bx, but flag via
969 * s->base.is_jmp that we need to do the rest of the work later.
972 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
) ||
973 (s
->v7m_handler_mode
&& arm_dc_feature(s
, ARM_FEATURE_M
))) {
974 s
->base
.is_jmp
= DISAS_BX_EXCRET
;
978 static inline void gen_bx_excret_final_code(DisasContext
*s
)
980 /* Generate the code to finish possible exception return and end the TB */
981 TCGLabel
*excret_label
= gen_new_label();
984 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
)) {
985 /* Covers FNC_RETURN and EXC_RETURN magic */
986 min_magic
= FNC_RETURN_MIN_MAGIC
;
988 /* EXC_RETURN magic only */
989 min_magic
= EXC_RETURN_MIN_MAGIC
;
992 /* Is the new PC value in the magic range indicating exception return? */
993 tcg_gen_brcondi_i32(TCG_COND_GEU
, cpu_R
[15], min_magic
, excret_label
);
994 /* No: end the TB as we would for a DISAS_JMP */
995 if (is_singlestepping(s
)) {
996 gen_singlestep_exception(s
);
1000 gen_set_label(excret_label
);
1001 /* Yes: this is an exception return.
1002 * At this point in runtime env->regs[15] and env->thumb will hold
1003 * the exception-return magic number, which do_v7m_exception_exit()
1004 * will read. Nothing else will be able to see those values because
1005 * the cpu-exec main loop guarantees that we will always go straight
1006 * from raising the exception to the exception-handling code.
1008 * gen_ss_advance(s) does nothing on M profile currently but
1009 * calling it is conceptually the right thing as we have executed
1010 * this instruction (compare SWI, HVC, SMC handling).
1013 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
1016 static inline void gen_bxns(DisasContext
*s
, int rm
)
1018 TCGv_i32 var
= load_reg(s
, rm
);
1020 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1021 * we need to sync state before calling it, but:
1022 * - we don't need to do gen_set_pc_im() because the bxns helper will
1023 * always set the PC itself
1024 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1025 * unless it's outside an IT block or the last insn in an IT block,
1026 * so we know that condexec == 0 (already set at the top of the TB)
1027 * is correct in the non-UNPREDICTABLE cases, and we can choose
1028 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1030 gen_helper_v7m_bxns(cpu_env
, var
);
1031 tcg_temp_free_i32(var
);
1032 s
->base
.is_jmp
= DISAS_EXIT
;
1035 static inline void gen_blxns(DisasContext
*s
, int rm
)
1037 TCGv_i32 var
= load_reg(s
, rm
);
1039 /* We don't need to sync condexec state, for the same reason as bxns.
1040 * We do however need to set the PC, because the blxns helper reads it.
1041 * The blxns helper may throw an exception.
1043 gen_set_pc_im(s
, s
->pc
);
1044 gen_helper_v7m_blxns(cpu_env
, var
);
1045 tcg_temp_free_i32(var
);
1046 s
->base
.is_jmp
= DISAS_EXIT
;
1049 /* Variant of store_reg which uses branch&exchange logic when storing
1050 to r15 in ARM architecture v7 and above. The source must be a temporary
1051 and will be marked as dead. */
1052 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
1054 if (reg
== 15 && ENABLE_ARCH_7
) {
1057 store_reg(s
, reg
, var
);
1061 /* Variant of store_reg which uses branch&exchange logic when storing
1062 * to r15 in ARM architecture v5T and above. This is used for storing
1063 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1064 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1065 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
1067 if (reg
== 15 && ENABLE_ARCH_5
) {
1068 gen_bx_excret(s
, var
);
1070 store_reg(s
, reg
, var
);
1074 #ifdef CONFIG_USER_ONLY
1075 #define IS_USER_ONLY 1
1077 #define IS_USER_ONLY 0
1080 /* Abstractions of "generate code to do a guest load/store for
1081 * AArch32", where a vaddr is always 32 bits (and is zero
1082 * extended if we're a 64 bit core) and data is also
1083 * 32 bits unless specifically doing a 64 bit access.
1084 * These functions work like tcg_gen_qemu_{ld,st}* except
1085 * that the address argument is TCGv_i32 rather than TCGv.
1088 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, TCGMemOp op
)
1090 TCGv addr
= tcg_temp_new();
1091 tcg_gen_extu_i32_tl(addr
, a32
);
1093 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1094 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
1095 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
1100 static void gen_aa32_ld_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1101 int index
, TCGMemOp opc
)
1103 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1104 tcg_gen_qemu_ld_i32(val
, addr
, index
, opc
);
1105 tcg_temp_free(addr
);
1108 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1109 int index
, TCGMemOp opc
)
1111 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1112 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
1113 tcg_temp_free(addr
);
1116 #define DO_GEN_LD(SUFF, OPC) \
1117 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1118 TCGv_i32 a32, int index) \
1120 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1122 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1124 TCGv_i32 a32, int index, \
1127 gen_aa32_ld##SUFF(s, val, a32, index); \
1128 disas_set_da_iss(s, OPC, issinfo); \
1131 #define DO_GEN_ST(SUFF, OPC) \
1132 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1133 TCGv_i32 a32, int index) \
1135 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1137 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1139 TCGv_i32 a32, int index, \
1142 gen_aa32_st##SUFF(s, val, a32, index); \
1143 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1146 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
1148 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1149 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1150 tcg_gen_rotri_i64(val
, val
, 32);
1154 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1155 int index
, TCGMemOp opc
)
1157 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1158 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
1159 gen_aa32_frob64(s
, val
);
1160 tcg_temp_free(addr
);
1163 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1164 TCGv_i32 a32
, int index
)
1166 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1169 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1170 int index
, TCGMemOp opc
)
1172 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1174 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1175 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1176 TCGv_i64 tmp
= tcg_temp_new_i64();
1177 tcg_gen_rotri_i64(tmp
, val
, 32);
1178 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
1179 tcg_temp_free_i64(tmp
);
1181 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
1183 tcg_temp_free(addr
);
1186 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1187 TCGv_i32 a32
, int index
)
1189 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1192 DO_GEN_LD(8s
, MO_SB
)
1193 DO_GEN_LD(8u, MO_UB
)
1194 DO_GEN_LD(16s
, MO_SW
)
1195 DO_GEN_LD(16u, MO_UW
)
1196 DO_GEN_LD(32u, MO_UL
)
1198 DO_GEN_ST(16, MO_UW
)
1199 DO_GEN_ST(32, MO_UL
)
1201 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1203 /* The pre HVC helper handles cases when HVC gets trapped
1204 * as an undefined insn by runtime configuration (ie before
1205 * the insn really executes).
1207 gen_set_pc_im(s
, s
->pc
- 4);
1208 gen_helper_pre_hvc(cpu_env
);
1209 /* Otherwise we will treat this as a real exception which
1210 * happens after execution of the insn. (The distinction matters
1211 * for the PC value reported to the exception handler and also
1212 * for single stepping.)
1215 gen_set_pc_im(s
, s
->pc
);
1216 s
->base
.is_jmp
= DISAS_HVC
;
1219 static inline void gen_smc(DisasContext
*s
)
1221 /* As with HVC, we may take an exception either before or after
1222 * the insn executes.
1226 gen_set_pc_im(s
, s
->pc
- 4);
1227 tmp
= tcg_const_i32(syn_aa32_smc());
1228 gen_helper_pre_smc(cpu_env
, tmp
);
1229 tcg_temp_free_i32(tmp
);
1230 gen_set_pc_im(s
, s
->pc
);
1231 s
->base
.is_jmp
= DISAS_SMC
;
1234 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1236 gen_set_condexec(s
);
1237 gen_set_pc_im(s
, s
->pc
- offset
);
1238 gen_exception_internal(excp
);
1239 s
->base
.is_jmp
= DISAS_NORETURN
;
1242 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1243 int syn
, uint32_t target_el
)
1245 gen_set_condexec(s
);
1246 gen_set_pc_im(s
, s
->pc
- offset
);
1247 gen_exception(excp
, syn
, target_el
);
1248 s
->base
.is_jmp
= DISAS_NORETURN
;
1251 static void gen_exception_bkpt_insn(DisasContext
*s
, int offset
, uint32_t syn
)
1255 gen_set_condexec(s
);
1256 gen_set_pc_im(s
, s
->pc
- offset
);
1257 tcg_syn
= tcg_const_i32(syn
);
1258 gen_helper_exception_bkpt_insn(cpu_env
, tcg_syn
);
1259 tcg_temp_free_i32(tcg_syn
);
1260 s
->base
.is_jmp
= DISAS_NORETURN
;
1263 /* Force a TB lookup after an instruction that changes the CPU state. */
1264 static inline void gen_lookup_tb(DisasContext
*s
)
1266 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1267 s
->base
.is_jmp
= DISAS_EXIT
;
1270 static inline void gen_hlt(DisasContext
*s
, int imm
)
1272 /* HLT. This has two purposes.
1273 * Architecturally, it is an external halting debug instruction.
1274 * Since QEMU doesn't implement external debug, we treat this as
1275 * it is required for halting debug disabled: it will UNDEF.
1276 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1277 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1278 * must trigger semihosting even for ARMv7 and earlier, where
1279 * HLT was an undefined encoding.
1280 * In system mode, we don't allow userspace access to
1281 * semihosting, to provide some semblance of security
1282 * (and for consistency with our 32-bit semihosting).
1284 if (semihosting_enabled() &&
1285 #ifndef CONFIG_USER_ONLY
1286 s
->current_el
!= 0 &&
1288 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1289 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1293 gen_exception_insn(s
, s
->thumb
? 2 : 4, EXCP_UDEF
, syn_uncategorized(),
1294 default_exception_el(s
));
1297 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1300 int val
, rm
, shift
, shiftop
;
1303 if (!(insn
& (1 << 25))) {
1306 if (!(insn
& (1 << 23)))
1309 tcg_gen_addi_i32(var
, var
, val
);
1311 /* shift/register */
1313 shift
= (insn
>> 7) & 0x1f;
1314 shiftop
= (insn
>> 5) & 3;
1315 offset
= load_reg(s
, rm
);
1316 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1317 if (!(insn
& (1 << 23)))
1318 tcg_gen_sub_i32(var
, var
, offset
);
1320 tcg_gen_add_i32(var
, var
, offset
);
1321 tcg_temp_free_i32(offset
);
1325 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1326 int extra
, TCGv_i32 var
)
1331 if (insn
& (1 << 22)) {
1333 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1334 if (!(insn
& (1 << 23)))
1338 tcg_gen_addi_i32(var
, var
, val
);
1342 tcg_gen_addi_i32(var
, var
, extra
);
1344 offset
= load_reg(s
, rm
);
1345 if (!(insn
& (1 << 23)))
1346 tcg_gen_sub_i32(var
, var
, offset
);
1348 tcg_gen_add_i32(var
, var
, offset
);
1349 tcg_temp_free_i32(offset
);
1353 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1355 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1358 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1360 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1362 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1366 #define VFP_OP2(name) \
1367 static inline void gen_vfp_##name(int dp) \
1369 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1371 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1373 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1375 tcg_temp_free_ptr(fpst); \
1385 static inline void gen_vfp_F1_mul(int dp
)
1387 /* Like gen_vfp_mul() but put result in F1 */
1388 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1390 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1392 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1394 tcg_temp_free_ptr(fpst
);
1397 static inline void gen_vfp_F1_neg(int dp
)
1399 /* Like gen_vfp_neg() but put result in F1 */
1401 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1403 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1407 static inline void gen_vfp_abs(int dp
)
1410 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1412 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1415 static inline void gen_vfp_neg(int dp
)
1418 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1420 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1423 static inline void gen_vfp_sqrt(int dp
)
1426 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1428 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1431 static inline void gen_vfp_cmp(int dp
)
1434 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1436 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1439 static inline void gen_vfp_cmpe(int dp
)
1442 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1444 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1447 static inline void gen_vfp_F1_ld0(int dp
)
1450 tcg_gen_movi_i64(cpu_F1d
, 0);
1452 tcg_gen_movi_i32(cpu_F1s
, 0);
1455 #define VFP_GEN_ITOF(name) \
1456 static inline void gen_vfp_##name(int dp, int neon) \
1458 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1460 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1462 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1464 tcg_temp_free_ptr(statusptr); \
1471 #define VFP_GEN_FTOI(name) \
1472 static inline void gen_vfp_##name(int dp, int neon) \
1474 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1476 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1478 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1480 tcg_temp_free_ptr(statusptr); \
1489 #define VFP_GEN_FIX(name, round) \
1490 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1492 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1493 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1495 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1498 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1501 tcg_temp_free_i32(tmp_shift); \
1502 tcg_temp_free_ptr(statusptr); \
1504 VFP_GEN_FIX(tosh
, _round_to_zero
)
1505 VFP_GEN_FIX(tosl
, _round_to_zero
)
1506 VFP_GEN_FIX(touh
, _round_to_zero
)
1507 VFP_GEN_FIX(toul
, _round_to_zero
)
1514 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1517 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1519 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1523 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1526 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1528 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1532 static inline long vfp_reg_offset(bool dp
, unsigned reg
)
1535 return offsetof(CPUARMState
, vfp
.zregs
[reg
>> 1].d
[reg
& 1]);
1537 long ofs
= offsetof(CPUARMState
, vfp
.zregs
[reg
>> 2].d
[(reg
>> 1) & 1]);
1539 ofs
+= offsetof(CPU_DoubleU
, l
.upper
);
1541 ofs
+= offsetof(CPU_DoubleU
, l
.lower
);
1547 /* Return the offset of a 32-bit piece of a NEON register.
1548 zero is the least significant end of the register. */
1550 neon_reg_offset (int reg
, int n
)
1554 return vfp_reg_offset(0, sreg
);
1557 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1559 TCGv_i32 tmp
= tcg_temp_new_i32();
1560 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1564 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1566 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1567 tcg_temp_free_i32(var
);
1570 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1572 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1575 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1577 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1580 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1582 TCGv_ptr ret
= tcg_temp_new_ptr();
1583 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1587 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1588 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1589 #define tcg_gen_st_f32 tcg_gen_st_i32
1590 #define tcg_gen_st_f64 tcg_gen_st_i64
1592 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1595 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1597 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1600 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1603 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1605 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1608 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1611 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1613 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1616 #define ARM_CP_RW_BIT (1 << 20)
1618 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1620 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1623 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1625 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1628 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1630 TCGv_i32 var
= tcg_temp_new_i32();
1631 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1635 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1637 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1638 tcg_temp_free_i32(var
);
1641 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1643 iwmmxt_store_reg(cpu_M0
, rn
);
1646 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1648 iwmmxt_load_reg(cpu_M0
, rn
);
1651 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1653 iwmmxt_load_reg(cpu_V1
, rn
);
1654 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1657 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1659 iwmmxt_load_reg(cpu_V1
, rn
);
1660 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1663 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1665 iwmmxt_load_reg(cpu_V1
, rn
);
1666 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1669 #define IWMMXT_OP(name) \
1670 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1672 iwmmxt_load_reg(cpu_V1, rn); \
1673 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1676 #define IWMMXT_OP_ENV(name) \
1677 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1679 iwmmxt_load_reg(cpu_V1, rn); \
1680 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1683 #define IWMMXT_OP_ENV_SIZE(name) \
1684 IWMMXT_OP_ENV(name##b) \
1685 IWMMXT_OP_ENV(name##w) \
1686 IWMMXT_OP_ENV(name##l)
1688 #define IWMMXT_OP_ENV1(name) \
1689 static inline void gen_op_iwmmxt_##name##_M0(void) \
1691 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1705 IWMMXT_OP_ENV_SIZE(unpackl
)
1706 IWMMXT_OP_ENV_SIZE(unpackh
)
1708 IWMMXT_OP_ENV1(unpacklub
)
1709 IWMMXT_OP_ENV1(unpackluw
)
1710 IWMMXT_OP_ENV1(unpacklul
)
1711 IWMMXT_OP_ENV1(unpackhub
)
1712 IWMMXT_OP_ENV1(unpackhuw
)
1713 IWMMXT_OP_ENV1(unpackhul
)
1714 IWMMXT_OP_ENV1(unpacklsb
)
1715 IWMMXT_OP_ENV1(unpacklsw
)
1716 IWMMXT_OP_ENV1(unpacklsl
)
1717 IWMMXT_OP_ENV1(unpackhsb
)
1718 IWMMXT_OP_ENV1(unpackhsw
)
1719 IWMMXT_OP_ENV1(unpackhsl
)
1721 IWMMXT_OP_ENV_SIZE(cmpeq
)
1722 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1723 IWMMXT_OP_ENV_SIZE(cmpgts
)
1725 IWMMXT_OP_ENV_SIZE(mins
)
1726 IWMMXT_OP_ENV_SIZE(minu
)
1727 IWMMXT_OP_ENV_SIZE(maxs
)
1728 IWMMXT_OP_ENV_SIZE(maxu
)
1730 IWMMXT_OP_ENV_SIZE(subn
)
1731 IWMMXT_OP_ENV_SIZE(addn
)
1732 IWMMXT_OP_ENV_SIZE(subu
)
1733 IWMMXT_OP_ENV_SIZE(addu
)
1734 IWMMXT_OP_ENV_SIZE(subs
)
1735 IWMMXT_OP_ENV_SIZE(adds
)
1737 IWMMXT_OP_ENV(avgb0
)
1738 IWMMXT_OP_ENV(avgb1
)
1739 IWMMXT_OP_ENV(avgw0
)
1740 IWMMXT_OP_ENV(avgw1
)
1742 IWMMXT_OP_ENV(packuw
)
1743 IWMMXT_OP_ENV(packul
)
1744 IWMMXT_OP_ENV(packuq
)
1745 IWMMXT_OP_ENV(packsw
)
1746 IWMMXT_OP_ENV(packsl
)
1747 IWMMXT_OP_ENV(packsq
)
1749 static void gen_op_iwmmxt_set_mup(void)
1752 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1753 tcg_gen_ori_i32(tmp
, tmp
, 2);
1754 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1757 static void gen_op_iwmmxt_set_cup(void)
1760 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1761 tcg_gen_ori_i32(tmp
, tmp
, 1);
1762 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1765 static void gen_op_iwmmxt_setpsr_nz(void)
1767 TCGv_i32 tmp
= tcg_temp_new_i32();
1768 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1769 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1772 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1774 iwmmxt_load_reg(cpu_V1
, rn
);
1775 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1776 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1779 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1786 rd
= (insn
>> 16) & 0xf;
1787 tmp
= load_reg(s
, rd
);
1789 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1790 if (insn
& (1 << 24)) {
1792 if (insn
& (1 << 23))
1793 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1795 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1796 tcg_gen_mov_i32(dest
, tmp
);
1797 if (insn
& (1 << 21))
1798 store_reg(s
, rd
, tmp
);
1800 tcg_temp_free_i32(tmp
);
1801 } else if (insn
& (1 << 21)) {
1803 tcg_gen_mov_i32(dest
, tmp
);
1804 if (insn
& (1 << 23))
1805 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1807 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1808 store_reg(s
, rd
, tmp
);
1809 } else if (!(insn
& (1 << 23)))
1814 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1816 int rd
= (insn
>> 0) & 0xf;
1819 if (insn
& (1 << 8)) {
1820 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1823 tmp
= iwmmxt_load_creg(rd
);
1826 tmp
= tcg_temp_new_i32();
1827 iwmmxt_load_reg(cpu_V0
, rd
);
1828 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1830 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1831 tcg_gen_mov_i32(dest
, tmp
);
1832 tcg_temp_free_i32(tmp
);
1836 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1837 (ie. an undefined instruction). */
1838 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1841 int rdhi
, rdlo
, rd0
, rd1
, i
;
1843 TCGv_i32 tmp
, tmp2
, tmp3
;
1845 if ((insn
& 0x0e000e00) == 0x0c000000) {
1846 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1848 rdlo
= (insn
>> 12) & 0xf;
1849 rdhi
= (insn
>> 16) & 0xf;
1850 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1851 iwmmxt_load_reg(cpu_V0
, wrd
);
1852 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1853 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1854 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1855 } else { /* TMCRR */
1856 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1857 iwmmxt_store_reg(cpu_V0
, wrd
);
1858 gen_op_iwmmxt_set_mup();
1863 wrd
= (insn
>> 12) & 0xf;
1864 addr
= tcg_temp_new_i32();
1865 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1866 tcg_temp_free_i32(addr
);
1869 if (insn
& ARM_CP_RW_BIT
) {
1870 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1871 tmp
= tcg_temp_new_i32();
1872 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1873 iwmmxt_store_creg(wrd
, tmp
);
1876 if (insn
& (1 << 8)) {
1877 if (insn
& (1 << 22)) { /* WLDRD */
1878 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1880 } else { /* WLDRW wRd */
1881 tmp
= tcg_temp_new_i32();
1882 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1885 tmp
= tcg_temp_new_i32();
1886 if (insn
& (1 << 22)) { /* WLDRH */
1887 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1888 } else { /* WLDRB */
1889 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1893 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1894 tcg_temp_free_i32(tmp
);
1896 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1899 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1900 tmp
= iwmmxt_load_creg(wrd
);
1901 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1903 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1904 tmp
= tcg_temp_new_i32();
1905 if (insn
& (1 << 8)) {
1906 if (insn
& (1 << 22)) { /* WSTRD */
1907 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1908 } else { /* WSTRW wRd */
1909 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1910 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1913 if (insn
& (1 << 22)) { /* WSTRH */
1914 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1915 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1916 } else { /* WSTRB */
1917 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1918 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1922 tcg_temp_free_i32(tmp
);
1924 tcg_temp_free_i32(addr
);
1928 if ((insn
& 0x0f000000) != 0x0e000000)
1931 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1932 case 0x000: /* WOR */
1933 wrd
= (insn
>> 12) & 0xf;
1934 rd0
= (insn
>> 0) & 0xf;
1935 rd1
= (insn
>> 16) & 0xf;
1936 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1937 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1938 gen_op_iwmmxt_setpsr_nz();
1939 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1940 gen_op_iwmmxt_set_mup();
1941 gen_op_iwmmxt_set_cup();
1943 case 0x011: /* TMCR */
1946 rd
= (insn
>> 12) & 0xf;
1947 wrd
= (insn
>> 16) & 0xf;
1949 case ARM_IWMMXT_wCID
:
1950 case ARM_IWMMXT_wCASF
:
1952 case ARM_IWMMXT_wCon
:
1953 gen_op_iwmmxt_set_cup();
1955 case ARM_IWMMXT_wCSSF
:
1956 tmp
= iwmmxt_load_creg(wrd
);
1957 tmp2
= load_reg(s
, rd
);
1958 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1959 tcg_temp_free_i32(tmp2
);
1960 iwmmxt_store_creg(wrd
, tmp
);
1962 case ARM_IWMMXT_wCGR0
:
1963 case ARM_IWMMXT_wCGR1
:
1964 case ARM_IWMMXT_wCGR2
:
1965 case ARM_IWMMXT_wCGR3
:
1966 gen_op_iwmmxt_set_cup();
1967 tmp
= load_reg(s
, rd
);
1968 iwmmxt_store_creg(wrd
, tmp
);
1974 case 0x100: /* WXOR */
1975 wrd
= (insn
>> 12) & 0xf;
1976 rd0
= (insn
>> 0) & 0xf;
1977 rd1
= (insn
>> 16) & 0xf;
1978 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1979 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1980 gen_op_iwmmxt_setpsr_nz();
1981 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1982 gen_op_iwmmxt_set_mup();
1983 gen_op_iwmmxt_set_cup();
1985 case 0x111: /* TMRC */
1988 rd
= (insn
>> 12) & 0xf;
1989 wrd
= (insn
>> 16) & 0xf;
1990 tmp
= iwmmxt_load_creg(wrd
);
1991 store_reg(s
, rd
, tmp
);
1993 case 0x300: /* WANDN */
1994 wrd
= (insn
>> 12) & 0xf;
1995 rd0
= (insn
>> 0) & 0xf;
1996 rd1
= (insn
>> 16) & 0xf;
1997 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1998 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1999 gen_op_iwmmxt_andq_M0_wRn(rd1
);
2000 gen_op_iwmmxt_setpsr_nz();
2001 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2002 gen_op_iwmmxt_set_mup();
2003 gen_op_iwmmxt_set_cup();
2005 case 0x200: /* WAND */
2006 wrd
= (insn
>> 12) & 0xf;
2007 rd0
= (insn
>> 0) & 0xf;
2008 rd1
= (insn
>> 16) & 0xf;
2009 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2010 gen_op_iwmmxt_andq_M0_wRn(rd1
);
2011 gen_op_iwmmxt_setpsr_nz();
2012 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2013 gen_op_iwmmxt_set_mup();
2014 gen_op_iwmmxt_set_cup();
2016 case 0x810: case 0xa10: /* WMADD */
2017 wrd
= (insn
>> 12) & 0xf;
2018 rd0
= (insn
>> 0) & 0xf;
2019 rd1
= (insn
>> 16) & 0xf;
2020 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2021 if (insn
& (1 << 21))
2022 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
2024 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
2025 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2026 gen_op_iwmmxt_set_mup();
2028 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2029 wrd
= (insn
>> 12) & 0xf;
2030 rd0
= (insn
>> 16) & 0xf;
2031 rd1
= (insn
>> 0) & 0xf;
2032 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2033 switch ((insn
>> 22) & 3) {
2035 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
2038 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
2041 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
2046 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2047 gen_op_iwmmxt_set_mup();
2048 gen_op_iwmmxt_set_cup();
2050 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2051 wrd
= (insn
>> 12) & 0xf;
2052 rd0
= (insn
>> 16) & 0xf;
2053 rd1
= (insn
>> 0) & 0xf;
2054 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2055 switch ((insn
>> 22) & 3) {
2057 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
2060 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
2063 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
2068 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2069 gen_op_iwmmxt_set_mup();
2070 gen_op_iwmmxt_set_cup();
2072 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2073 wrd
= (insn
>> 12) & 0xf;
2074 rd0
= (insn
>> 16) & 0xf;
2075 rd1
= (insn
>> 0) & 0xf;
2076 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2077 if (insn
& (1 << 22))
2078 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2080 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2081 if (!(insn
& (1 << 20)))
2082 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2083 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2084 gen_op_iwmmxt_set_mup();
2086 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2087 wrd
= (insn
>> 12) & 0xf;
2088 rd0
= (insn
>> 16) & 0xf;
2089 rd1
= (insn
>> 0) & 0xf;
2090 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2091 if (insn
& (1 << 21)) {
2092 if (insn
& (1 << 20))
2093 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2095 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2097 if (insn
& (1 << 20))
2098 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2100 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2102 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2103 gen_op_iwmmxt_set_mup();
2105 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2106 wrd
= (insn
>> 12) & 0xf;
2107 rd0
= (insn
>> 16) & 0xf;
2108 rd1
= (insn
>> 0) & 0xf;
2109 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2110 if (insn
& (1 << 21))
2111 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2113 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2114 if (!(insn
& (1 << 20))) {
2115 iwmmxt_load_reg(cpu_V1
, wrd
);
2116 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2118 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2119 gen_op_iwmmxt_set_mup();
2121 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2122 wrd
= (insn
>> 12) & 0xf;
2123 rd0
= (insn
>> 16) & 0xf;
2124 rd1
= (insn
>> 0) & 0xf;
2125 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2126 switch ((insn
>> 22) & 3) {
2128 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2131 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2134 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2139 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2140 gen_op_iwmmxt_set_mup();
2141 gen_op_iwmmxt_set_cup();
2143 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2144 wrd
= (insn
>> 12) & 0xf;
2145 rd0
= (insn
>> 16) & 0xf;
2146 rd1
= (insn
>> 0) & 0xf;
2147 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2148 if (insn
& (1 << 22)) {
2149 if (insn
& (1 << 20))
2150 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2152 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2154 if (insn
& (1 << 20))
2155 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2157 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2159 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2160 gen_op_iwmmxt_set_mup();
2161 gen_op_iwmmxt_set_cup();
2163 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2164 wrd
= (insn
>> 12) & 0xf;
2165 rd0
= (insn
>> 16) & 0xf;
2166 rd1
= (insn
>> 0) & 0xf;
2167 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2168 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2169 tcg_gen_andi_i32(tmp
, tmp
, 7);
2170 iwmmxt_load_reg(cpu_V1
, rd1
);
2171 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2172 tcg_temp_free_i32(tmp
);
2173 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2174 gen_op_iwmmxt_set_mup();
2176 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2177 if (((insn
>> 6) & 3) == 3)
2179 rd
= (insn
>> 12) & 0xf;
2180 wrd
= (insn
>> 16) & 0xf;
2181 tmp
= load_reg(s
, rd
);
2182 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2183 switch ((insn
>> 6) & 3) {
2185 tmp2
= tcg_const_i32(0xff);
2186 tmp3
= tcg_const_i32((insn
& 7) << 3);
2189 tmp2
= tcg_const_i32(0xffff);
2190 tmp3
= tcg_const_i32((insn
& 3) << 4);
2193 tmp2
= tcg_const_i32(0xffffffff);
2194 tmp3
= tcg_const_i32((insn
& 1) << 5);
2200 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2201 tcg_temp_free_i32(tmp3
);
2202 tcg_temp_free_i32(tmp2
);
2203 tcg_temp_free_i32(tmp
);
2204 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2205 gen_op_iwmmxt_set_mup();
2207 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2208 rd
= (insn
>> 12) & 0xf;
2209 wrd
= (insn
>> 16) & 0xf;
2210 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2212 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2213 tmp
= tcg_temp_new_i32();
2214 switch ((insn
>> 22) & 3) {
2216 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2217 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2219 tcg_gen_ext8s_i32(tmp
, tmp
);
2221 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2225 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2226 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2228 tcg_gen_ext16s_i32(tmp
, tmp
);
2230 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2234 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2235 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2238 store_reg(s
, rd
, tmp
);
2240 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2241 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2243 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2244 switch ((insn
>> 22) & 3) {
2246 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2249 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2252 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2255 tcg_gen_shli_i32(tmp
, tmp
, 28);
2257 tcg_temp_free_i32(tmp
);
2259 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2260 if (((insn
>> 6) & 3) == 3)
2262 rd
= (insn
>> 12) & 0xf;
2263 wrd
= (insn
>> 16) & 0xf;
2264 tmp
= load_reg(s
, rd
);
2265 switch ((insn
>> 6) & 3) {
2267 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2270 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2273 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2276 tcg_temp_free_i32(tmp
);
2277 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2278 gen_op_iwmmxt_set_mup();
2280 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2281 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2283 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2284 tmp2
= tcg_temp_new_i32();
2285 tcg_gen_mov_i32(tmp2
, tmp
);
2286 switch ((insn
>> 22) & 3) {
2288 for (i
= 0; i
< 7; i
++) {
2289 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2290 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2294 for (i
= 0; i
< 3; i
++) {
2295 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2296 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2300 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2301 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2305 tcg_temp_free_i32(tmp2
);
2306 tcg_temp_free_i32(tmp
);
2308 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2309 wrd
= (insn
>> 12) & 0xf;
2310 rd0
= (insn
>> 16) & 0xf;
2311 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2312 switch ((insn
>> 22) & 3) {
2314 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2317 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2320 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2325 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2326 gen_op_iwmmxt_set_mup();
2328 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2329 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2331 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2332 tmp2
= tcg_temp_new_i32();
2333 tcg_gen_mov_i32(tmp2
, tmp
);
2334 switch ((insn
>> 22) & 3) {
2336 for (i
= 0; i
< 7; i
++) {
2337 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2338 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2342 for (i
= 0; i
< 3; i
++) {
2343 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2344 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2348 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2349 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2353 tcg_temp_free_i32(tmp2
);
2354 tcg_temp_free_i32(tmp
);
2356 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2357 rd
= (insn
>> 12) & 0xf;
2358 rd0
= (insn
>> 16) & 0xf;
2359 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2361 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2362 tmp
= tcg_temp_new_i32();
2363 switch ((insn
>> 22) & 3) {
2365 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2368 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2371 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2374 store_reg(s
, rd
, tmp
);
2376 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2377 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2378 wrd
= (insn
>> 12) & 0xf;
2379 rd0
= (insn
>> 16) & 0xf;
2380 rd1
= (insn
>> 0) & 0xf;
2381 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2382 switch ((insn
>> 22) & 3) {
2384 if (insn
& (1 << 21))
2385 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2387 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2390 if (insn
& (1 << 21))
2391 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2393 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2396 if (insn
& (1 << 21))
2397 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2399 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2404 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2405 gen_op_iwmmxt_set_mup();
2406 gen_op_iwmmxt_set_cup();
2408 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2409 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2410 wrd
= (insn
>> 12) & 0xf;
2411 rd0
= (insn
>> 16) & 0xf;
2412 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2413 switch ((insn
>> 22) & 3) {
2415 if (insn
& (1 << 21))
2416 gen_op_iwmmxt_unpacklsb_M0();
2418 gen_op_iwmmxt_unpacklub_M0();
2421 if (insn
& (1 << 21))
2422 gen_op_iwmmxt_unpacklsw_M0();
2424 gen_op_iwmmxt_unpackluw_M0();
2427 if (insn
& (1 << 21))
2428 gen_op_iwmmxt_unpacklsl_M0();
2430 gen_op_iwmmxt_unpacklul_M0();
2435 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2436 gen_op_iwmmxt_set_mup();
2437 gen_op_iwmmxt_set_cup();
2439 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2440 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2441 wrd
= (insn
>> 12) & 0xf;
2442 rd0
= (insn
>> 16) & 0xf;
2443 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2444 switch ((insn
>> 22) & 3) {
2446 if (insn
& (1 << 21))
2447 gen_op_iwmmxt_unpackhsb_M0();
2449 gen_op_iwmmxt_unpackhub_M0();
2452 if (insn
& (1 << 21))
2453 gen_op_iwmmxt_unpackhsw_M0();
2455 gen_op_iwmmxt_unpackhuw_M0();
2458 if (insn
& (1 << 21))
2459 gen_op_iwmmxt_unpackhsl_M0();
2461 gen_op_iwmmxt_unpackhul_M0();
2466 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2467 gen_op_iwmmxt_set_mup();
2468 gen_op_iwmmxt_set_cup();
2470 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2471 case 0x214: case 0x614: case 0xa14: case 0xe14:
2472 if (((insn
>> 22) & 3) == 0)
2474 wrd
= (insn
>> 12) & 0xf;
2475 rd0
= (insn
>> 16) & 0xf;
2476 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2477 tmp
= tcg_temp_new_i32();
2478 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2479 tcg_temp_free_i32(tmp
);
2482 switch ((insn
>> 22) & 3) {
2484 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2487 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2490 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2493 tcg_temp_free_i32(tmp
);
2494 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2495 gen_op_iwmmxt_set_mup();
2496 gen_op_iwmmxt_set_cup();
2498 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2499 case 0x014: case 0x414: case 0x814: case 0xc14:
2500 if (((insn
>> 22) & 3) == 0)
2502 wrd
= (insn
>> 12) & 0xf;
2503 rd0
= (insn
>> 16) & 0xf;
2504 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2505 tmp
= tcg_temp_new_i32();
2506 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2507 tcg_temp_free_i32(tmp
);
2510 switch ((insn
>> 22) & 3) {
2512 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2515 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2518 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2521 tcg_temp_free_i32(tmp
);
2522 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2523 gen_op_iwmmxt_set_mup();
2524 gen_op_iwmmxt_set_cup();
2526 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2527 case 0x114: case 0x514: case 0x914: case 0xd14:
2528 if (((insn
>> 22) & 3) == 0)
2530 wrd
= (insn
>> 12) & 0xf;
2531 rd0
= (insn
>> 16) & 0xf;
2532 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2533 tmp
= tcg_temp_new_i32();
2534 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2535 tcg_temp_free_i32(tmp
);
2538 switch ((insn
>> 22) & 3) {
2540 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2543 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2546 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2549 tcg_temp_free_i32(tmp
);
2550 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2551 gen_op_iwmmxt_set_mup();
2552 gen_op_iwmmxt_set_cup();
2554 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2555 case 0x314: case 0x714: case 0xb14: case 0xf14:
2556 if (((insn
>> 22) & 3) == 0)
2558 wrd
= (insn
>> 12) & 0xf;
2559 rd0
= (insn
>> 16) & 0xf;
2560 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2561 tmp
= tcg_temp_new_i32();
2562 switch ((insn
>> 22) & 3) {
2564 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2565 tcg_temp_free_i32(tmp
);
2568 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2571 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2572 tcg_temp_free_i32(tmp
);
2575 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2578 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2579 tcg_temp_free_i32(tmp
);
2582 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2585 tcg_temp_free_i32(tmp
);
2586 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2587 gen_op_iwmmxt_set_mup();
2588 gen_op_iwmmxt_set_cup();
2590 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2591 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2592 wrd
= (insn
>> 12) & 0xf;
2593 rd0
= (insn
>> 16) & 0xf;
2594 rd1
= (insn
>> 0) & 0xf;
2595 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2596 switch ((insn
>> 22) & 3) {
2598 if (insn
& (1 << 21))
2599 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2601 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2604 if (insn
& (1 << 21))
2605 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2607 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2610 if (insn
& (1 << 21))
2611 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2613 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2618 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2619 gen_op_iwmmxt_set_mup();
2621 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2622 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2623 wrd
= (insn
>> 12) & 0xf;
2624 rd0
= (insn
>> 16) & 0xf;
2625 rd1
= (insn
>> 0) & 0xf;
2626 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2627 switch ((insn
>> 22) & 3) {
2629 if (insn
& (1 << 21))
2630 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2632 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2635 if (insn
& (1 << 21))
2636 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2638 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2641 if (insn
& (1 << 21))
2642 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2644 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2649 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2650 gen_op_iwmmxt_set_mup();
2652 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2653 case 0x402: case 0x502: case 0x602: case 0x702:
2654 wrd
= (insn
>> 12) & 0xf;
2655 rd0
= (insn
>> 16) & 0xf;
2656 rd1
= (insn
>> 0) & 0xf;
2657 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2658 tmp
= tcg_const_i32((insn
>> 20) & 3);
2659 iwmmxt_load_reg(cpu_V1
, rd1
);
2660 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2661 tcg_temp_free_i32(tmp
);
2662 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2663 gen_op_iwmmxt_set_mup();
2665 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2666 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2667 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2668 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2669 wrd
= (insn
>> 12) & 0xf;
2670 rd0
= (insn
>> 16) & 0xf;
2671 rd1
= (insn
>> 0) & 0xf;
2672 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2673 switch ((insn
>> 20) & 0xf) {
2675 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2678 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2681 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2684 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2687 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2690 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2693 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2696 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2699 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2704 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2705 gen_op_iwmmxt_set_mup();
2706 gen_op_iwmmxt_set_cup();
2708 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2709 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2710 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2711 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2712 wrd
= (insn
>> 12) & 0xf;
2713 rd0
= (insn
>> 16) & 0xf;
2714 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2715 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2716 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2717 tcg_temp_free_i32(tmp
);
2718 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2719 gen_op_iwmmxt_set_mup();
2720 gen_op_iwmmxt_set_cup();
2722 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2723 case 0x418: case 0x518: case 0x618: case 0x718:
2724 case 0x818: case 0x918: case 0xa18: case 0xb18:
2725 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2726 wrd
= (insn
>> 12) & 0xf;
2727 rd0
= (insn
>> 16) & 0xf;
2728 rd1
= (insn
>> 0) & 0xf;
2729 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2730 switch ((insn
>> 20) & 0xf) {
2732 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2735 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2738 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2741 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2744 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2747 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2750 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2753 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2756 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2761 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2762 gen_op_iwmmxt_set_mup();
2763 gen_op_iwmmxt_set_cup();
2765 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2766 case 0x408: case 0x508: case 0x608: case 0x708:
2767 case 0x808: case 0x908: case 0xa08: case 0xb08:
2768 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2769 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2771 wrd
= (insn
>> 12) & 0xf;
2772 rd0
= (insn
>> 16) & 0xf;
2773 rd1
= (insn
>> 0) & 0xf;
2774 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2775 switch ((insn
>> 22) & 3) {
2777 if (insn
& (1 << 21))
2778 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2780 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2783 if (insn
& (1 << 21))
2784 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2786 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2789 if (insn
& (1 << 21))
2790 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2792 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2795 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2796 gen_op_iwmmxt_set_mup();
2797 gen_op_iwmmxt_set_cup();
2799 case 0x201: case 0x203: case 0x205: case 0x207:
2800 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2801 case 0x211: case 0x213: case 0x215: case 0x217:
2802 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2803 wrd
= (insn
>> 5) & 0xf;
2804 rd0
= (insn
>> 12) & 0xf;
2805 rd1
= (insn
>> 0) & 0xf;
2806 if (rd0
== 0xf || rd1
== 0xf)
2808 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2809 tmp
= load_reg(s
, rd0
);
2810 tmp2
= load_reg(s
, rd1
);
2811 switch ((insn
>> 16) & 0xf) {
2812 case 0x0: /* TMIA */
2813 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2815 case 0x8: /* TMIAPH */
2816 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2818 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2819 if (insn
& (1 << 16))
2820 tcg_gen_shri_i32(tmp
, tmp
, 16);
2821 if (insn
& (1 << 17))
2822 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2823 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2826 tcg_temp_free_i32(tmp2
);
2827 tcg_temp_free_i32(tmp
);
2830 tcg_temp_free_i32(tmp2
);
2831 tcg_temp_free_i32(tmp
);
2832 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2833 gen_op_iwmmxt_set_mup();
2842 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2843 (ie. an undefined instruction). */
2844 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2846 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2849 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2850 /* Multiply with Internal Accumulate Format */
2851 rd0
= (insn
>> 12) & 0xf;
2853 acc
= (insn
>> 5) & 7;
2858 tmp
= load_reg(s
, rd0
);
2859 tmp2
= load_reg(s
, rd1
);
2860 switch ((insn
>> 16) & 0xf) {
2862 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2864 case 0x8: /* MIAPH */
2865 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2867 case 0xc: /* MIABB */
2868 case 0xd: /* MIABT */
2869 case 0xe: /* MIATB */
2870 case 0xf: /* MIATT */
2871 if (insn
& (1 << 16))
2872 tcg_gen_shri_i32(tmp
, tmp
, 16);
2873 if (insn
& (1 << 17))
2874 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2875 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2880 tcg_temp_free_i32(tmp2
);
2881 tcg_temp_free_i32(tmp
);
2883 gen_op_iwmmxt_movq_wRn_M0(acc
);
2887 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2888 /* Internal Accumulator Access Format */
2889 rdhi
= (insn
>> 16) & 0xf;
2890 rdlo
= (insn
>> 12) & 0xf;
2896 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2897 iwmmxt_load_reg(cpu_V0
, acc
);
2898 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2899 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2900 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2901 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2903 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2904 iwmmxt_store_reg(cpu_V0
, acc
);
2912 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2913 #define VFP_SREG(insn, bigbit, smallbit) \
2914 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2915 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2916 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2917 reg = (((insn) >> (bigbit)) & 0x0f) \
2918 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2920 if (insn & (1 << (smallbit))) \
2922 reg = ((insn) >> (bigbit)) & 0x0f; \
2925 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2926 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2927 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2928 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2929 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2930 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2932 /* Move between integer and VFP cores. */
2933 static TCGv_i32
gen_vfp_mrs(void)
2935 TCGv_i32 tmp
= tcg_temp_new_i32();
2936 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2940 static void gen_vfp_msr(TCGv_i32 tmp
)
2942 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2943 tcg_temp_free_i32(tmp
);
2946 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2948 TCGv_i32 tmp
= tcg_temp_new_i32();
2950 tcg_gen_shri_i32(var
, var
, shift
);
2951 tcg_gen_ext8u_i32(var
, var
);
2952 tcg_gen_shli_i32(tmp
, var
, 8);
2953 tcg_gen_or_i32(var
, var
, tmp
);
2954 tcg_gen_shli_i32(tmp
, var
, 16);
2955 tcg_gen_or_i32(var
, var
, tmp
);
2956 tcg_temp_free_i32(tmp
);
2959 static void gen_neon_dup_low16(TCGv_i32 var
)
2961 TCGv_i32 tmp
= tcg_temp_new_i32();
2962 tcg_gen_ext16u_i32(var
, var
);
2963 tcg_gen_shli_i32(tmp
, var
, 16);
2964 tcg_gen_or_i32(var
, var
, tmp
);
2965 tcg_temp_free_i32(tmp
);
2968 static void gen_neon_dup_high16(TCGv_i32 var
)
2970 TCGv_i32 tmp
= tcg_temp_new_i32();
2971 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2972 tcg_gen_shri_i32(tmp
, var
, 16);
2973 tcg_gen_or_i32(var
, var
, tmp
);
2974 tcg_temp_free_i32(tmp
);
2977 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2979 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2980 TCGv_i32 tmp
= tcg_temp_new_i32();
2983 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2984 gen_neon_dup_u8(tmp
, 0);
2987 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2988 gen_neon_dup_low16(tmp
);
2991 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2993 default: /* Avoid compiler warnings. */
2999 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
3002 uint32_t cc
= extract32(insn
, 20, 2);
3005 TCGv_i64 frn
, frm
, dest
;
3006 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
3008 zero
= tcg_const_i64(0);
3010 frn
= tcg_temp_new_i64();
3011 frm
= tcg_temp_new_i64();
3012 dest
= tcg_temp_new_i64();
3014 zf
= tcg_temp_new_i64();
3015 nf
= tcg_temp_new_i64();
3016 vf
= tcg_temp_new_i64();
3018 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
3019 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
3020 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
3022 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3023 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3026 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
3030 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
3033 case 2: /* ge: N == V -> N ^ V == 0 */
3034 tmp
= tcg_temp_new_i64();
3035 tcg_gen_xor_i64(tmp
, vf
, nf
);
3036 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
3038 tcg_temp_free_i64(tmp
);
3040 case 3: /* gt: !Z && N == V */
3041 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
3043 tmp
= tcg_temp_new_i64();
3044 tcg_gen_xor_i64(tmp
, vf
, nf
);
3045 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
3047 tcg_temp_free_i64(tmp
);
3050 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3051 tcg_temp_free_i64(frn
);
3052 tcg_temp_free_i64(frm
);
3053 tcg_temp_free_i64(dest
);
3055 tcg_temp_free_i64(zf
);
3056 tcg_temp_free_i64(nf
);
3057 tcg_temp_free_i64(vf
);
3059 tcg_temp_free_i64(zero
);
3061 TCGv_i32 frn
, frm
, dest
;
3064 zero
= tcg_const_i32(0);
3066 frn
= tcg_temp_new_i32();
3067 frm
= tcg_temp_new_i32();
3068 dest
= tcg_temp_new_i32();
3069 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3070 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3073 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
3077 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
3080 case 2: /* ge: N == V -> N ^ V == 0 */
3081 tmp
= tcg_temp_new_i32();
3082 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3083 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3085 tcg_temp_free_i32(tmp
);
3087 case 3: /* gt: !Z && N == V */
3088 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
3090 tmp
= tcg_temp_new_i32();
3091 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3092 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3094 tcg_temp_free_i32(tmp
);
3097 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3098 tcg_temp_free_i32(frn
);
3099 tcg_temp_free_i32(frm
);
3100 tcg_temp_free_i32(dest
);
3102 tcg_temp_free_i32(zero
);
3108 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
3109 uint32_t rm
, uint32_t dp
)
3111 uint32_t vmin
= extract32(insn
, 6, 1);
3112 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3115 TCGv_i64 frn
, frm
, dest
;
3117 frn
= tcg_temp_new_i64();
3118 frm
= tcg_temp_new_i64();
3119 dest
= tcg_temp_new_i64();
3121 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3122 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3124 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
3126 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
3128 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3129 tcg_temp_free_i64(frn
);
3130 tcg_temp_free_i64(frm
);
3131 tcg_temp_free_i64(dest
);
3133 TCGv_i32 frn
, frm
, dest
;
3135 frn
= tcg_temp_new_i32();
3136 frm
= tcg_temp_new_i32();
3137 dest
= tcg_temp_new_i32();
3139 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3140 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3142 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
3144 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
3146 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3147 tcg_temp_free_i32(frn
);
3148 tcg_temp_free_i32(frm
);
3149 tcg_temp_free_i32(dest
);
3152 tcg_temp_free_ptr(fpst
);
3156 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3159 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3162 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3163 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3168 tcg_op
= tcg_temp_new_i64();
3169 tcg_res
= tcg_temp_new_i64();
3170 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3171 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
3172 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3173 tcg_temp_free_i64(tcg_op
);
3174 tcg_temp_free_i64(tcg_res
);
3178 tcg_op
= tcg_temp_new_i32();
3179 tcg_res
= tcg_temp_new_i32();
3180 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3181 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
3182 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3183 tcg_temp_free_i32(tcg_op
);
3184 tcg_temp_free_i32(tcg_res
);
3187 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3188 tcg_temp_free_i32(tcg_rmode
);
3190 tcg_temp_free_ptr(fpst
);
3194 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3197 bool is_signed
= extract32(insn
, 7, 1);
3198 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3199 TCGv_i32 tcg_rmode
, tcg_shift
;
3201 tcg_shift
= tcg_const_i32(0);
3203 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3204 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3207 TCGv_i64 tcg_double
, tcg_res
;
3209 /* Rd is encoded as a single precision register even when the source
3210 * is double precision.
3212 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3213 tcg_double
= tcg_temp_new_i64();
3214 tcg_res
= tcg_temp_new_i64();
3215 tcg_tmp
= tcg_temp_new_i32();
3216 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3218 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3220 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3222 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3223 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3224 tcg_temp_free_i32(tcg_tmp
);
3225 tcg_temp_free_i64(tcg_res
);
3226 tcg_temp_free_i64(tcg_double
);
3228 TCGv_i32 tcg_single
, tcg_res
;
3229 tcg_single
= tcg_temp_new_i32();
3230 tcg_res
= tcg_temp_new_i32();
3231 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3233 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3235 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3237 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3238 tcg_temp_free_i32(tcg_res
);
3239 tcg_temp_free_i32(tcg_single
);
3242 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3243 tcg_temp_free_i32(tcg_rmode
);
3245 tcg_temp_free_i32(tcg_shift
);
3247 tcg_temp_free_ptr(fpst
);
3252 /* Table for converting the most common AArch32 encoding of
3253 * rounding mode to arm_fprounding order (which matches the
3254 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3256 static const uint8_t fp_decode_rm
[] = {
3263 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3265 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3267 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3272 VFP_DREG_D(rd
, insn
);
3273 VFP_DREG_N(rn
, insn
);
3274 VFP_DREG_M(rm
, insn
);
3276 rd
= VFP_SREG_D(insn
);
3277 rn
= VFP_SREG_N(insn
);
3278 rm
= VFP_SREG_M(insn
);
3281 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3282 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3283 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3284 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3285 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3286 /* VRINTA, VRINTN, VRINTP, VRINTM */
3287 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3288 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3289 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3290 /* VCVTA, VCVTN, VCVTP, VCVTM */
3291 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3292 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3297 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3298 (ie. an undefined instruction). */
3299 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3301 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3307 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3311 /* FIXME: this access check should not take precedence over UNDEF
3312 * for invalid encodings; we will generate incorrect syndrome information
3313 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3315 if (s
->fp_excp_el
) {
3316 gen_exception_insn(s
, 4, EXCP_UDEF
,
3317 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3321 if (!s
->vfp_enabled
) {
3322 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3323 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3325 rn
= (insn
>> 16) & 0xf;
3326 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3327 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3332 if (extract32(insn
, 28, 4) == 0xf) {
3333 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3334 * only used in v8 and above.
3336 return disas_vfp_v8_insn(s
, insn
);
3339 dp
= ((insn
& 0xf00) == 0xb00);
3340 switch ((insn
>> 24) & 0xf) {
3342 if (insn
& (1 << 4)) {
3343 /* single register transfer */
3344 rd
= (insn
>> 12) & 0xf;
3349 VFP_DREG_N(rn
, insn
);
3352 if (insn
& 0x00c00060
3353 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3357 pass
= (insn
>> 21) & 1;
3358 if (insn
& (1 << 22)) {
3360 offset
= ((insn
>> 5) & 3) * 8;
3361 } else if (insn
& (1 << 5)) {
3363 offset
= (insn
& (1 << 6)) ? 16 : 0;
3368 if (insn
& ARM_CP_RW_BIT
) {
3370 tmp
= neon_load_reg(rn
, pass
);
3374 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3375 if (insn
& (1 << 23))
3381 if (insn
& (1 << 23)) {
3383 tcg_gen_shri_i32(tmp
, tmp
, 16);
3389 tcg_gen_sari_i32(tmp
, tmp
, 16);
3398 store_reg(s
, rd
, tmp
);
3401 tmp
= load_reg(s
, rd
);
3402 if (insn
& (1 << 23)) {
3405 gen_neon_dup_u8(tmp
, 0);
3406 } else if (size
== 1) {
3407 gen_neon_dup_low16(tmp
);
3409 for (n
= 0; n
<= pass
* 2; n
++) {
3410 tmp2
= tcg_temp_new_i32();
3411 tcg_gen_mov_i32(tmp2
, tmp
);
3412 neon_store_reg(rn
, n
, tmp2
);
3414 neon_store_reg(rn
, n
, tmp
);
3419 tmp2
= neon_load_reg(rn
, pass
);
3420 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3421 tcg_temp_free_i32(tmp2
);
3424 tmp2
= neon_load_reg(rn
, pass
);
3425 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3426 tcg_temp_free_i32(tmp2
);
3431 neon_store_reg(rn
, pass
, tmp
);
3435 if ((insn
& 0x6f) != 0x00)
3437 rn
= VFP_SREG_N(insn
);
3438 if (insn
& ARM_CP_RW_BIT
) {
3440 if (insn
& (1 << 21)) {
3441 /* system register */
3446 /* VFP2 allows access to FSID from userspace.
3447 VFP3 restricts all id registers to privileged
3450 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3453 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3458 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3460 case ARM_VFP_FPINST
:
3461 case ARM_VFP_FPINST2
:
3462 /* Not present in VFP3. */
3464 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3467 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3471 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3472 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3474 tmp
= tcg_temp_new_i32();
3475 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3479 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3486 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3489 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3495 gen_mov_F0_vreg(0, rn
);
3496 tmp
= gen_vfp_mrs();
3499 /* Set the 4 flag bits in the CPSR. */
3501 tcg_temp_free_i32(tmp
);
3503 store_reg(s
, rd
, tmp
);
3507 if (insn
& (1 << 21)) {
3509 /* system register */
3514 /* Writes are ignored. */
3517 tmp
= load_reg(s
, rd
);
3518 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3519 tcg_temp_free_i32(tmp
);
3525 /* TODO: VFP subarchitecture support.
3526 * For now, keep the EN bit only */
3527 tmp
= load_reg(s
, rd
);
3528 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3529 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3532 case ARM_VFP_FPINST
:
3533 case ARM_VFP_FPINST2
:
3537 tmp
= load_reg(s
, rd
);
3538 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3544 tmp
= load_reg(s
, rd
);
3546 gen_mov_vreg_F0(0, rn
);
3551 /* data processing */
3552 /* The opcode is in bits 23, 21, 20 and 6. */
3553 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3557 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3559 /* rn is register number */
3560 VFP_DREG_N(rn
, insn
);
3563 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3564 ((rn
& 0x1e) == 0x6))) {
3565 /* Integer or single/half precision destination. */
3566 rd
= VFP_SREG_D(insn
);
3568 VFP_DREG_D(rd
, insn
);
3571 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3572 ((rn
& 0x1e) == 0x4))) {
3573 /* VCVT from int or half precision is always from S reg
3574 * regardless of dp bit. VCVT with immediate frac_bits
3575 * has same format as SREG_M.
3577 rm
= VFP_SREG_M(insn
);
3579 VFP_DREG_M(rm
, insn
);
3582 rn
= VFP_SREG_N(insn
);
3583 if (op
== 15 && rn
== 15) {
3584 /* Double precision destination. */
3585 VFP_DREG_D(rd
, insn
);
3587 rd
= VFP_SREG_D(insn
);
3589 /* NB that we implicitly rely on the encoding for the frac_bits
3590 * in VCVT of fixed to float being the same as that of an SREG_M
3592 rm
= VFP_SREG_M(insn
);
3595 veclen
= s
->vec_len
;
3596 if (op
== 15 && rn
> 3)
3599 /* Shut up compiler warnings. */
3610 /* Figure out what type of vector operation this is. */
3611 if ((rd
& bank_mask
) == 0) {
3616 delta_d
= (s
->vec_stride
>> 1) + 1;
3618 delta_d
= s
->vec_stride
+ 1;
3620 if ((rm
& bank_mask
) == 0) {
3621 /* mixed scalar/vector */
3630 /* Load the initial operands. */
3635 /* Integer source */
3636 gen_mov_F0_vreg(0, rm
);
3641 gen_mov_F0_vreg(dp
, rd
);
3642 gen_mov_F1_vreg(dp
, rm
);
3646 /* Compare with zero */
3647 gen_mov_F0_vreg(dp
, rd
);
3658 /* Source and destination the same. */
3659 gen_mov_F0_vreg(dp
, rd
);
3665 /* VCVTB, VCVTT: only present with the halfprec extension
3666 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3667 * (we choose to UNDEF)
3669 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3670 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3673 if (!extract32(rn
, 1, 1)) {
3674 /* Half precision source. */
3675 gen_mov_F0_vreg(0, rm
);
3678 /* Otherwise fall through */
3680 /* One source operand. */
3681 gen_mov_F0_vreg(dp
, rm
);
3685 /* Two source operands. */
3686 gen_mov_F0_vreg(dp
, rn
);
3687 gen_mov_F1_vreg(dp
, rm
);
3691 /* Perform the calculation. */
3693 case 0: /* VMLA: fd + (fn * fm) */
3694 /* Note that order of inputs to the add matters for NaNs */
3696 gen_mov_F0_vreg(dp
, rd
);
3699 case 1: /* VMLS: fd + -(fn * fm) */
3702 gen_mov_F0_vreg(dp
, rd
);
3705 case 2: /* VNMLS: -fd + (fn * fm) */
3706 /* Note that it isn't valid to replace (-A + B) with (B - A)
3707 * or similar plausible looking simplifications
3708 * because this will give wrong results for NaNs.
3711 gen_mov_F0_vreg(dp
, rd
);
3715 case 3: /* VNMLA: -fd + -(fn * fm) */
3718 gen_mov_F0_vreg(dp
, rd
);
3722 case 4: /* mul: fn * fm */
3725 case 5: /* nmul: -(fn * fm) */
3729 case 6: /* add: fn + fm */
3732 case 7: /* sub: fn - fm */
3735 case 8: /* div: fn / fm */
3738 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3739 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3740 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3741 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3742 /* These are fused multiply-add, and must be done as one
3743 * floating point operation with no rounding between the
3744 * multiplication and addition steps.
3745 * NB that doing the negations here as separate steps is
3746 * correct : an input NaN should come out with its sign bit
3747 * flipped if it is a negated-input.
3749 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3757 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3759 frd
= tcg_temp_new_i64();
3760 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3763 gen_helper_vfp_negd(frd
, frd
);
3765 fpst
= get_fpstatus_ptr(0);
3766 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3767 cpu_F1d
, frd
, fpst
);
3768 tcg_temp_free_ptr(fpst
);
3769 tcg_temp_free_i64(frd
);
3775 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3777 frd
= tcg_temp_new_i32();
3778 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3780 gen_helper_vfp_negs(frd
, frd
);
3782 fpst
= get_fpstatus_ptr(0);
3783 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3784 cpu_F1s
, frd
, fpst
);
3785 tcg_temp_free_ptr(fpst
);
3786 tcg_temp_free_i32(frd
);
3789 case 14: /* fconst */
3790 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3794 n
= (insn
<< 12) & 0x80000000;
3795 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3802 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3809 tcg_gen_movi_i32(cpu_F0s
, n
);
3812 case 15: /* extension space */
3826 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3827 tmp
= gen_vfp_mrs();
3828 tcg_gen_ext16u_i32(tmp
, tmp
);
3830 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3833 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3836 tcg_temp_free_i32(tmp
);
3838 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3839 tmp
= gen_vfp_mrs();
3840 tcg_gen_shri_i32(tmp
, tmp
, 16);
3842 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3845 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3848 tcg_temp_free_i32(tmp
);
3850 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3851 tmp
= tcg_temp_new_i32();
3853 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3856 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3859 gen_mov_F0_vreg(0, rd
);
3860 tmp2
= gen_vfp_mrs();
3861 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3862 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3863 tcg_temp_free_i32(tmp2
);
3866 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3867 tmp
= tcg_temp_new_i32();
3869 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3872 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3875 tcg_gen_shli_i32(tmp
, tmp
, 16);
3876 gen_mov_F0_vreg(0, rd
);
3877 tmp2
= gen_vfp_mrs();
3878 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3879 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3880 tcg_temp_free_i32(tmp2
);
3892 case 11: /* cmpez */
3896 case 12: /* vrintr */
3898 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3900 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3902 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3904 tcg_temp_free_ptr(fpst
);
3907 case 13: /* vrintz */
3909 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3911 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3912 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3914 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3916 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3918 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3919 tcg_temp_free_i32(tcg_rmode
);
3920 tcg_temp_free_ptr(fpst
);
3923 case 14: /* vrintx */
3925 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3927 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3929 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3931 tcg_temp_free_ptr(fpst
);
3934 case 15: /* single<->double conversion */
3936 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3938 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3940 case 16: /* fuito */
3941 gen_vfp_uito(dp
, 0);
3943 case 17: /* fsito */
3944 gen_vfp_sito(dp
, 0);
3946 case 20: /* fshto */
3947 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3950 gen_vfp_shto(dp
, 16 - rm
, 0);
3952 case 21: /* fslto */
3953 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3956 gen_vfp_slto(dp
, 32 - rm
, 0);
3958 case 22: /* fuhto */
3959 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3962 gen_vfp_uhto(dp
, 16 - rm
, 0);
3964 case 23: /* fulto */
3965 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3968 gen_vfp_ulto(dp
, 32 - rm
, 0);
3970 case 24: /* ftoui */
3971 gen_vfp_toui(dp
, 0);
3973 case 25: /* ftouiz */
3974 gen_vfp_touiz(dp
, 0);
3976 case 26: /* ftosi */
3977 gen_vfp_tosi(dp
, 0);
3979 case 27: /* ftosiz */
3980 gen_vfp_tosiz(dp
, 0);
3982 case 28: /* ftosh */
3983 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3986 gen_vfp_tosh(dp
, 16 - rm
, 0);
3988 case 29: /* ftosl */
3989 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3992 gen_vfp_tosl(dp
, 32 - rm
, 0);
3994 case 30: /* ftouh */
3995 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3998 gen_vfp_touh(dp
, 16 - rm
, 0);
4000 case 31: /* ftoul */
4001 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
4004 gen_vfp_toul(dp
, 32 - rm
, 0);
4006 default: /* undefined */
4010 default: /* undefined */
4014 /* Write back the result. */
4015 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
4016 /* Comparison, do nothing. */
4017 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
4018 (rn
& 0x1e) == 0x6)) {
4019 /* VCVT double to int: always integer result.
4020 * VCVT double to half precision is always a single
4023 gen_mov_vreg_F0(0, rd
);
4024 } else if (op
== 15 && rn
== 15) {
4026 gen_mov_vreg_F0(!dp
, rd
);
4028 gen_mov_vreg_F0(dp
, rd
);
4031 /* break out of the loop if we have finished */
4035 if (op
== 15 && delta_m
== 0) {
4036 /* single source one-many */
4038 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
4040 gen_mov_vreg_F0(dp
, rd
);
4044 /* Setup the next operands. */
4046 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
4050 /* One source operand. */
4051 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
4053 gen_mov_F0_vreg(dp
, rm
);
4055 /* Two source operands. */
4056 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
4058 gen_mov_F0_vreg(dp
, rn
);
4060 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
4062 gen_mov_F1_vreg(dp
, rm
);
4070 if ((insn
& 0x03e00000) == 0x00400000) {
4071 /* two-register transfer */
4072 rn
= (insn
>> 16) & 0xf;
4073 rd
= (insn
>> 12) & 0xf;
4075 VFP_DREG_M(rm
, insn
);
4077 rm
= VFP_SREG_M(insn
);
4080 if (insn
& ARM_CP_RW_BIT
) {
4083 gen_mov_F0_vreg(0, rm
* 2);
4084 tmp
= gen_vfp_mrs();
4085 store_reg(s
, rd
, tmp
);
4086 gen_mov_F0_vreg(0, rm
* 2 + 1);
4087 tmp
= gen_vfp_mrs();
4088 store_reg(s
, rn
, tmp
);
4090 gen_mov_F0_vreg(0, rm
);
4091 tmp
= gen_vfp_mrs();
4092 store_reg(s
, rd
, tmp
);
4093 gen_mov_F0_vreg(0, rm
+ 1);
4094 tmp
= gen_vfp_mrs();
4095 store_reg(s
, rn
, tmp
);
4100 tmp
= load_reg(s
, rd
);
4102 gen_mov_vreg_F0(0, rm
* 2);
4103 tmp
= load_reg(s
, rn
);
4105 gen_mov_vreg_F0(0, rm
* 2 + 1);
4107 tmp
= load_reg(s
, rd
);
4109 gen_mov_vreg_F0(0, rm
);
4110 tmp
= load_reg(s
, rn
);
4112 gen_mov_vreg_F0(0, rm
+ 1);
4117 rn
= (insn
>> 16) & 0xf;
4119 VFP_DREG_D(rd
, insn
);
4121 rd
= VFP_SREG_D(insn
);
4122 if ((insn
& 0x01200000) == 0x01000000) {
4123 /* Single load/store */
4124 offset
= (insn
& 0xff) << 2;
4125 if ((insn
& (1 << 23)) == 0)
4127 if (s
->thumb
&& rn
== 15) {
4128 /* This is actually UNPREDICTABLE */
4129 addr
= tcg_temp_new_i32();
4130 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4132 addr
= load_reg(s
, rn
);
4134 tcg_gen_addi_i32(addr
, addr
, offset
);
4135 if (insn
& (1 << 20)) {
4136 gen_vfp_ld(s
, dp
, addr
);
4137 gen_mov_vreg_F0(dp
, rd
);
4139 gen_mov_F0_vreg(dp
, rd
);
4140 gen_vfp_st(s
, dp
, addr
);
4142 tcg_temp_free_i32(addr
);
4144 /* load/store multiple */
4145 int w
= insn
& (1 << 21);
4147 n
= (insn
>> 1) & 0x7f;
4151 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
4152 /* P == U , W == 1 => UNDEF */
4155 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
4156 /* UNPREDICTABLE cases for bad immediates: we choose to
4157 * UNDEF to avoid generating huge numbers of TCG ops
4161 if (rn
== 15 && w
) {
4162 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4166 if (s
->thumb
&& rn
== 15) {
4167 /* This is actually UNPREDICTABLE */
4168 addr
= tcg_temp_new_i32();
4169 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4171 addr
= load_reg(s
, rn
);
4173 if (insn
& (1 << 24)) /* pre-decrement */
4174 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4180 for (i
= 0; i
< n
; i
++) {
4181 if (insn
& ARM_CP_RW_BIT
) {
4183 gen_vfp_ld(s
, dp
, addr
);
4184 gen_mov_vreg_F0(dp
, rd
+ i
);
4187 gen_mov_F0_vreg(dp
, rd
+ i
);
4188 gen_vfp_st(s
, dp
, addr
);
4190 tcg_gen_addi_i32(addr
, addr
, offset
);
4194 if (insn
& (1 << 24))
4195 offset
= -offset
* n
;
4196 else if (dp
&& (insn
& 1))
4202 tcg_gen_addi_i32(addr
, addr
, offset
);
4203 store_reg(s
, rn
, addr
);
4205 tcg_temp_free_i32(addr
);
4211 /* Should never happen. */
4217 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4219 #ifndef CONFIG_USER_ONLY
4220 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4221 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4227 static void gen_goto_ptr(void)
4229 tcg_gen_lookup_and_goto_ptr();
4232 /* This will end the TB but doesn't guarantee we'll return to
4233 * cpu_loop_exec. Any live exit_requests will be processed as we
4234 * enter the next TB.
4236 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4238 if (use_goto_tb(s
, dest
)) {
4240 gen_set_pc_im(s
, dest
);
4241 tcg_gen_exit_tb((uintptr_t)s
->base
.tb
+ n
);
4243 gen_set_pc_im(s
, dest
);
4246 s
->base
.is_jmp
= DISAS_NORETURN
;
4249 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4251 if (unlikely(is_singlestepping(s
))) {
4252 /* An indirect jump so that we still trigger the debug exception. */
4257 gen_goto_tb(s
, 0, dest
);
4261 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4264 tcg_gen_sari_i32(t0
, t0
, 16);
4268 tcg_gen_sari_i32(t1
, t1
, 16);
4271 tcg_gen_mul_i32(t0
, t0
, t1
);
4274 /* Return the mask of PSR bits set by a MSR instruction. */
4275 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4280 if (flags
& (1 << 0))
4282 if (flags
& (1 << 1))
4284 if (flags
& (1 << 2))
4286 if (flags
& (1 << 3))
4289 /* Mask out undefined bits. */
4290 mask
&= ~CPSR_RESERVED
;
4291 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4294 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4295 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4297 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4298 mask
&= ~(CPSR_E
| CPSR_GE
);
4300 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4303 /* Mask out execution state and reserved bits. */
4305 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4307 /* Mask out privileged bits. */
4313 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4314 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4318 /* ??? This is also undefined in system mode. */
4322 tmp
= load_cpu_field(spsr
);
4323 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4324 tcg_gen_andi_i32(t0
, t0
, mask
);
4325 tcg_gen_or_i32(tmp
, tmp
, t0
);
4326 store_cpu_field(tmp
, spsr
);
4328 gen_set_cpsr(t0
, mask
);
4330 tcg_temp_free_i32(t0
);
4335 /* Returns nonzero if access to the PSR is not permitted. */
4336 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4339 tmp
= tcg_temp_new_i32();
4340 tcg_gen_movi_i32(tmp
, val
);
4341 return gen_set_psr(s
, mask
, spsr
, tmp
);
4344 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4345 int *tgtmode
, int *regno
)
4347 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4348 * the target mode and register number, and identify the various
4349 * unpredictable cases.
4350 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4351 * + executed in user mode
4352 * + using R15 as the src/dest register
4353 * + accessing an unimplemented register
4354 * + accessing a register that's inaccessible at current PL/security state*
4355 * + accessing a register that you could access with a different insn
4356 * We choose to UNDEF in all these cases.
4357 * Since we don't know which of the various AArch32 modes we are in
4358 * we have to defer some checks to runtime.
4359 * Accesses to Monitor mode registers from Secure EL1 (which implies
4360 * that EL3 is AArch64) must trap to EL3.
4362 * If the access checks fail this function will emit code to take
4363 * an exception and return false. Otherwise it will return true,
4364 * and set *tgtmode and *regno appropriately.
4366 int exc_target
= default_exception_el(s
);
4368 /* These instructions are present only in ARMv8, or in ARMv7 with the
4369 * Virtualization Extensions.
4371 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4372 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4376 if (IS_USER(s
) || rn
== 15) {
4380 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4381 * of registers into (r, sysm).
4384 /* SPSRs for other modes */
4386 case 0xe: /* SPSR_fiq */
4387 *tgtmode
= ARM_CPU_MODE_FIQ
;
4389 case 0x10: /* SPSR_irq */
4390 *tgtmode
= ARM_CPU_MODE_IRQ
;
4392 case 0x12: /* SPSR_svc */
4393 *tgtmode
= ARM_CPU_MODE_SVC
;
4395 case 0x14: /* SPSR_abt */
4396 *tgtmode
= ARM_CPU_MODE_ABT
;
4398 case 0x16: /* SPSR_und */
4399 *tgtmode
= ARM_CPU_MODE_UND
;
4401 case 0x1c: /* SPSR_mon */
4402 *tgtmode
= ARM_CPU_MODE_MON
;
4404 case 0x1e: /* SPSR_hyp */
4405 *tgtmode
= ARM_CPU_MODE_HYP
;
4407 default: /* unallocated */
4410 /* We arbitrarily assign SPSR a register number of 16. */
4413 /* general purpose registers for other modes */
4415 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4416 *tgtmode
= ARM_CPU_MODE_USR
;
4419 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4420 *tgtmode
= ARM_CPU_MODE_FIQ
;
4423 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4424 *tgtmode
= ARM_CPU_MODE_IRQ
;
4425 *regno
= sysm
& 1 ? 13 : 14;
4427 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4428 *tgtmode
= ARM_CPU_MODE_SVC
;
4429 *regno
= sysm
& 1 ? 13 : 14;
4431 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4432 *tgtmode
= ARM_CPU_MODE_ABT
;
4433 *regno
= sysm
& 1 ? 13 : 14;
4435 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4436 *tgtmode
= ARM_CPU_MODE_UND
;
4437 *regno
= sysm
& 1 ? 13 : 14;
4439 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4440 *tgtmode
= ARM_CPU_MODE_MON
;
4441 *regno
= sysm
& 1 ? 13 : 14;
4443 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4444 *tgtmode
= ARM_CPU_MODE_HYP
;
4445 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4446 *regno
= sysm
& 1 ? 13 : 17;
4448 default: /* unallocated */
4453 /* Catch the 'accessing inaccessible register' cases we can detect
4454 * at translate time.
4457 case ARM_CPU_MODE_MON
:
4458 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4461 if (s
->current_el
== 1) {
4462 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4463 * then accesses to Mon registers trap to EL3
4469 case ARM_CPU_MODE_HYP
:
4470 /* Note that we can forbid accesses from EL2 here because they
4471 * must be from Hyp mode itself
4473 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4484 /* If we get here then some access check did not pass */
4485 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4489 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4491 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4492 int tgtmode
= 0, regno
= 0;
4494 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4498 /* Sync state because msr_banked() can raise exceptions */
4499 gen_set_condexec(s
);
4500 gen_set_pc_im(s
, s
->pc
- 4);
4501 tcg_reg
= load_reg(s
, rn
);
4502 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4503 tcg_regno
= tcg_const_i32(regno
);
4504 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4505 tcg_temp_free_i32(tcg_tgtmode
);
4506 tcg_temp_free_i32(tcg_regno
);
4507 tcg_temp_free_i32(tcg_reg
);
4508 s
->base
.is_jmp
= DISAS_UPDATE
;
4511 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4513 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4514 int tgtmode
= 0, regno
= 0;
4516 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4520 /* Sync state because mrs_banked() can raise exceptions */
4521 gen_set_condexec(s
);
4522 gen_set_pc_im(s
, s
->pc
- 4);
4523 tcg_reg
= tcg_temp_new_i32();
4524 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4525 tcg_regno
= tcg_const_i32(regno
);
4526 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4527 tcg_temp_free_i32(tcg_tgtmode
);
4528 tcg_temp_free_i32(tcg_regno
);
4529 store_reg(s
, rn
, tcg_reg
);
4530 s
->base
.is_jmp
= DISAS_UPDATE
;
4533 /* Store value to PC as for an exception return (ie don't
4534 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4535 * will do the masking based on the new value of the Thumb bit.
4537 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4539 tcg_gen_mov_i32(cpu_R
[15], pc
);
4540 tcg_temp_free_i32(pc
);
4543 /* Generate a v6 exception return. Marks both values as dead. */
4544 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4546 store_pc_exc_ret(s
, pc
);
4547 /* The cpsr_write_eret helper will mask the low bits of PC
4548 * appropriately depending on the new Thumb bit, so it must
4549 * be called after storing the new PC.
4551 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4552 tcg_temp_free_i32(cpsr
);
4553 /* Must exit loop to check un-masked IRQs */
4554 s
->base
.is_jmp
= DISAS_EXIT
;
4557 /* Generate an old-style exception return. Marks pc as dead. */
4558 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4560 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4564 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4565 * only call the helper when running single threaded TCG code to ensure
4566 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4567 * just skip this instruction. Currently the SEV/SEVL instructions
4568 * which are *one* of many ways to wake the CPU from WFE are not
4569 * implemented so we can't sleep like WFI does.
4571 static void gen_nop_hint(DisasContext
*s
, int val
)
4574 /* When running in MTTCG we don't generate jumps to the yield and
4575 * WFE helpers as it won't affect the scheduling of other vCPUs.
4576 * If we wanted to more completely model WFE/SEV so we don't busy
4577 * spin unnecessarily we would need to do something more involved.
4580 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4581 gen_set_pc_im(s
, s
->pc
);
4582 s
->base
.is_jmp
= DISAS_YIELD
;
4586 gen_set_pc_im(s
, s
->pc
);
4587 s
->base
.is_jmp
= DISAS_WFI
;
4590 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4591 gen_set_pc_im(s
, s
->pc
);
4592 s
->base
.is_jmp
= DISAS_WFE
;
4597 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4603 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4605 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4608 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4609 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4610 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4615 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4618 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4619 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4620 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4625 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4626 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4627 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4628 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4629 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4631 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4632 switch ((size << 1) | u) { \
4634 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4637 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4640 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4643 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4646 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4649 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4651 default: return 1; \
4654 #define GEN_NEON_INTEGER_OP(name) do { \
4655 switch ((size << 1) | u) { \
4657 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4660 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4663 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4666 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4669 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4672 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4674 default: return 1; \
4677 static TCGv_i32
neon_load_scratch(int scratch
)
4679 TCGv_i32 tmp
= tcg_temp_new_i32();
4680 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4684 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4686 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4687 tcg_temp_free_i32(var
);
4690 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4694 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4696 gen_neon_dup_high16(tmp
);
4698 gen_neon_dup_low16(tmp
);
4701 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4706 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4710 if (!q
&& size
== 2) {
4713 pd
= vfp_reg_ptr(true, rd
);
4714 pm
= vfp_reg_ptr(true, rm
);
4718 gen_helper_neon_qunzip8(pd
, pm
);
4721 gen_helper_neon_qunzip16(pd
, pm
);
4724 gen_helper_neon_qunzip32(pd
, pm
);
4732 gen_helper_neon_unzip8(pd
, pm
);
4735 gen_helper_neon_unzip16(pd
, pm
);
4741 tcg_temp_free_ptr(pd
);
4742 tcg_temp_free_ptr(pm
);
4746 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4750 if (!q
&& size
== 2) {
4753 pd
= vfp_reg_ptr(true, rd
);
4754 pm
= vfp_reg_ptr(true, rm
);
4758 gen_helper_neon_qzip8(pd
, pm
);
4761 gen_helper_neon_qzip16(pd
, pm
);
4764 gen_helper_neon_qzip32(pd
, pm
);
4772 gen_helper_neon_zip8(pd
, pm
);
4775 gen_helper_neon_zip16(pd
, pm
);
4781 tcg_temp_free_ptr(pd
);
4782 tcg_temp_free_ptr(pm
);
4786 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4790 rd
= tcg_temp_new_i32();
4791 tmp
= tcg_temp_new_i32();
4793 tcg_gen_shli_i32(rd
, t0
, 8);
4794 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4795 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4796 tcg_gen_or_i32(rd
, rd
, tmp
);
4798 tcg_gen_shri_i32(t1
, t1
, 8);
4799 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4800 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4801 tcg_gen_or_i32(t1
, t1
, tmp
);
4802 tcg_gen_mov_i32(t0
, rd
);
4804 tcg_temp_free_i32(tmp
);
4805 tcg_temp_free_i32(rd
);
4808 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4812 rd
= tcg_temp_new_i32();
4813 tmp
= tcg_temp_new_i32();
4815 tcg_gen_shli_i32(rd
, t0
, 16);
4816 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4817 tcg_gen_or_i32(rd
, rd
, tmp
);
4818 tcg_gen_shri_i32(t1
, t1
, 16);
4819 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4820 tcg_gen_or_i32(t1
, t1
, tmp
);
4821 tcg_gen_mov_i32(t0
, rd
);
4823 tcg_temp_free_i32(tmp
);
4824 tcg_temp_free_i32(rd
);
4832 } neon_ls_element_type
[11] = {
4846 /* Translate a NEON load/store element instruction. Return nonzero if the
4847 instruction is invalid. */
4848 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4867 /* FIXME: this access check should not take precedence over UNDEF
4868 * for invalid encodings; we will generate incorrect syndrome information
4869 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4871 if (s
->fp_excp_el
) {
4872 gen_exception_insn(s
, 4, EXCP_UDEF
,
4873 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4877 if (!s
->vfp_enabled
)
4879 VFP_DREG_D(rd
, insn
);
4880 rn
= (insn
>> 16) & 0xf;
4882 load
= (insn
& (1 << 21)) != 0;
4883 if ((insn
& (1 << 23)) == 0) {
4884 /* Load store all elements. */
4885 op
= (insn
>> 8) & 0xf;
4886 size
= (insn
>> 6) & 3;
4889 /* Catch UNDEF cases for bad values of align field */
4892 if (((insn
>> 5) & 1) == 1) {
4897 if (((insn
>> 4) & 3) == 3) {
4904 nregs
= neon_ls_element_type
[op
].nregs
;
4905 interleave
= neon_ls_element_type
[op
].interleave
;
4906 spacing
= neon_ls_element_type
[op
].spacing
;
4907 if (size
== 3 && (interleave
| spacing
) != 1)
4909 addr
= tcg_temp_new_i32();
4910 load_reg_var(s
, addr
, rn
);
4911 stride
= (1 << size
) * interleave
;
4912 for (reg
= 0; reg
< nregs
; reg
++) {
4913 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4914 load_reg_var(s
, addr
, rn
);
4915 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4916 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4917 load_reg_var(s
, addr
, rn
);
4918 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4921 tmp64
= tcg_temp_new_i64();
4923 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4924 neon_store_reg64(tmp64
, rd
);
4926 neon_load_reg64(tmp64
, rd
);
4927 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4929 tcg_temp_free_i64(tmp64
);
4930 tcg_gen_addi_i32(addr
, addr
, stride
);
4932 for (pass
= 0; pass
< 2; pass
++) {
4935 tmp
= tcg_temp_new_i32();
4936 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4937 neon_store_reg(rd
, pass
, tmp
);
4939 tmp
= neon_load_reg(rd
, pass
);
4940 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4941 tcg_temp_free_i32(tmp
);
4943 tcg_gen_addi_i32(addr
, addr
, stride
);
4944 } else if (size
== 1) {
4946 tmp
= tcg_temp_new_i32();
4947 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4948 tcg_gen_addi_i32(addr
, addr
, stride
);
4949 tmp2
= tcg_temp_new_i32();
4950 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4951 tcg_gen_addi_i32(addr
, addr
, stride
);
4952 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4953 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4954 tcg_temp_free_i32(tmp2
);
4955 neon_store_reg(rd
, pass
, tmp
);
4957 tmp
= neon_load_reg(rd
, pass
);
4958 tmp2
= tcg_temp_new_i32();
4959 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4960 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4961 tcg_temp_free_i32(tmp
);
4962 tcg_gen_addi_i32(addr
, addr
, stride
);
4963 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4964 tcg_temp_free_i32(tmp2
);
4965 tcg_gen_addi_i32(addr
, addr
, stride
);
4967 } else /* size == 0 */ {
4970 for (n
= 0; n
< 4; n
++) {
4971 tmp
= tcg_temp_new_i32();
4972 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4973 tcg_gen_addi_i32(addr
, addr
, stride
);
4977 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4978 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4979 tcg_temp_free_i32(tmp
);
4982 neon_store_reg(rd
, pass
, tmp2
);
4984 tmp2
= neon_load_reg(rd
, pass
);
4985 for (n
= 0; n
< 4; n
++) {
4986 tmp
= tcg_temp_new_i32();
4988 tcg_gen_mov_i32(tmp
, tmp2
);
4990 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4992 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4993 tcg_temp_free_i32(tmp
);
4994 tcg_gen_addi_i32(addr
, addr
, stride
);
4996 tcg_temp_free_i32(tmp2
);
5003 tcg_temp_free_i32(addr
);
5006 size
= (insn
>> 10) & 3;
5008 /* Load single element to all lanes. */
5009 int a
= (insn
>> 4) & 1;
5013 size
= (insn
>> 6) & 3;
5014 nregs
= ((insn
>> 8) & 3) + 1;
5017 if (nregs
!= 4 || a
== 0) {
5020 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5023 if (nregs
== 1 && a
== 1 && size
== 0) {
5026 if (nregs
== 3 && a
== 1) {
5029 addr
= tcg_temp_new_i32();
5030 load_reg_var(s
, addr
, rn
);
5032 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5033 tmp
= gen_load_and_replicate(s
, addr
, size
);
5034 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
5035 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
5036 if (insn
& (1 << 5)) {
5037 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
5038 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
5040 tcg_temp_free_i32(tmp
);
5042 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5043 stride
= (insn
& (1 << 5)) ? 2 : 1;
5044 for (reg
= 0; reg
< nregs
; reg
++) {
5045 tmp
= gen_load_and_replicate(s
, addr
, size
);
5046 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
5047 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
5048 tcg_temp_free_i32(tmp
);
5049 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5053 tcg_temp_free_i32(addr
);
5054 stride
= (1 << size
) * nregs
;
5056 /* Single element. */
5057 int idx
= (insn
>> 4) & 0xf;
5058 pass
= (insn
>> 7) & 1;
5061 shift
= ((insn
>> 5) & 3) * 8;
5065 shift
= ((insn
>> 6) & 1) * 16;
5066 stride
= (insn
& (1 << 5)) ? 2 : 1;
5070 stride
= (insn
& (1 << 6)) ? 2 : 1;
5075 nregs
= ((insn
>> 8) & 3) + 1;
5076 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5079 if (((idx
& (1 << size
)) != 0) ||
5080 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
5085 if ((idx
& 1) != 0) {
5090 if (size
== 2 && (idx
& 2) != 0) {
5095 if ((size
== 2) && ((idx
& 3) == 3)) {
5102 if ((rd
+ stride
* (nregs
- 1)) > 31) {
5103 /* Attempts to write off the end of the register file
5104 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5105 * the neon_load_reg() would write off the end of the array.
5109 addr
= tcg_temp_new_i32();
5110 load_reg_var(s
, addr
, rn
);
5111 for (reg
= 0; reg
< nregs
; reg
++) {
5113 tmp
= tcg_temp_new_i32();
5116 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
5119 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
5122 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
5124 default: /* Avoid compiler warnings. */
5128 tmp2
= neon_load_reg(rd
, pass
);
5129 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
5130 shift
, size
? 16 : 8);
5131 tcg_temp_free_i32(tmp2
);
5133 neon_store_reg(rd
, pass
, tmp
);
5134 } else { /* Store */
5135 tmp
= neon_load_reg(rd
, pass
);
5137 tcg_gen_shri_i32(tmp
, tmp
, shift
);
5140 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
5143 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
5146 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5149 tcg_temp_free_i32(tmp
);
5152 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5154 tcg_temp_free_i32(addr
);
5155 stride
= nregs
* (1 << size
);
5161 base
= load_reg(s
, rn
);
5163 tcg_gen_addi_i32(base
, base
, stride
);
5166 index
= load_reg(s
, rm
);
5167 tcg_gen_add_i32(base
, base
, index
);
5168 tcg_temp_free_i32(index
);
5170 store_reg(s
, rn
, base
);
5175 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5176 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
5178 tcg_gen_and_i32(t
, t
, c
);
5179 tcg_gen_andc_i32(f
, f
, c
);
5180 tcg_gen_or_i32(dest
, t
, f
);
5183 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5186 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
5187 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
5188 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
5193 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5196 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
5197 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
5198 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5203 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5206 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5207 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5208 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5213 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5216 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5217 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5218 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5223 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5229 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5230 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5235 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5236 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5243 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5244 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5249 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5250 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5257 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5261 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5262 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5263 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5268 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5269 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5270 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5274 tcg_temp_free_i32(src
);
5277 static inline void gen_neon_addl(int size
)
5280 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5281 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5282 case 2: tcg_gen_add_i64(CPU_V001
); break;
5287 static inline void gen_neon_subl(int size
)
5290 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5291 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5292 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5297 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5300 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5301 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5303 tcg_gen_neg_i64(var
, var
);
5309 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5312 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5313 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5318 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5323 switch ((size
<< 1) | u
) {
5324 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5325 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5326 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5327 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5329 tmp
= gen_muls_i64_i32(a
, b
);
5330 tcg_gen_mov_i64(dest
, tmp
);
5331 tcg_temp_free_i64(tmp
);
5334 tmp
= gen_mulu_i64_i32(a
, b
);
5335 tcg_gen_mov_i64(dest
, tmp
);
5336 tcg_temp_free_i64(tmp
);
5341 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5342 Don't forget to clean them now. */
5344 tcg_temp_free_i32(a
);
5345 tcg_temp_free_i32(b
);
5349 static void gen_neon_narrow_op(int op
, int u
, int size
,
5350 TCGv_i32 dest
, TCGv_i64 src
)
5354 gen_neon_unarrow_sats(size
, dest
, src
);
5356 gen_neon_narrow(size
, dest
, src
);
5360 gen_neon_narrow_satu(size
, dest
, src
);
5362 gen_neon_narrow_sats(size
, dest
, src
);
5367 /* Symbolic constants for op fields for Neon 3-register same-length.
5368 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5371 #define NEON_3R_VHADD 0
5372 #define NEON_3R_VQADD 1
5373 #define NEON_3R_VRHADD 2
5374 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5375 #define NEON_3R_VHSUB 4
5376 #define NEON_3R_VQSUB 5
5377 #define NEON_3R_VCGT 6
5378 #define NEON_3R_VCGE 7
5379 #define NEON_3R_VSHL 8
5380 #define NEON_3R_VQSHL 9
5381 #define NEON_3R_VRSHL 10
5382 #define NEON_3R_VQRSHL 11
5383 #define NEON_3R_VMAX 12
5384 #define NEON_3R_VMIN 13
5385 #define NEON_3R_VABD 14
5386 #define NEON_3R_VABA 15
5387 #define NEON_3R_VADD_VSUB 16
5388 #define NEON_3R_VTST_VCEQ 17
5389 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5390 #define NEON_3R_VMUL 19
5391 #define NEON_3R_VPMAX 20
5392 #define NEON_3R_VPMIN 21
5393 #define NEON_3R_VQDMULH_VQRDMULH 22
5394 #define NEON_3R_VPADD_VQRDMLAH 23
5395 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5396 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5397 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5398 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5399 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5400 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5401 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5402 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5404 static const uint8_t neon_3r_sizes
[] = {
5405 [NEON_3R_VHADD
] = 0x7,
5406 [NEON_3R_VQADD
] = 0xf,
5407 [NEON_3R_VRHADD
] = 0x7,
5408 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5409 [NEON_3R_VHSUB
] = 0x7,
5410 [NEON_3R_VQSUB
] = 0xf,
5411 [NEON_3R_VCGT
] = 0x7,
5412 [NEON_3R_VCGE
] = 0x7,
5413 [NEON_3R_VSHL
] = 0xf,
5414 [NEON_3R_VQSHL
] = 0xf,
5415 [NEON_3R_VRSHL
] = 0xf,
5416 [NEON_3R_VQRSHL
] = 0xf,
5417 [NEON_3R_VMAX
] = 0x7,
5418 [NEON_3R_VMIN
] = 0x7,
5419 [NEON_3R_VABD
] = 0x7,
5420 [NEON_3R_VABA
] = 0x7,
5421 [NEON_3R_VADD_VSUB
] = 0xf,
5422 [NEON_3R_VTST_VCEQ
] = 0x7,
5423 [NEON_3R_VML
] = 0x7,
5424 [NEON_3R_VMUL
] = 0x7,
5425 [NEON_3R_VPMAX
] = 0x7,
5426 [NEON_3R_VPMIN
] = 0x7,
5427 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5428 [NEON_3R_VPADD_VQRDMLAH
] = 0x7,
5429 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5430 [NEON_3R_VFM_VQRDMLSH
] = 0x7, /* For VFM, size bit 1 encodes op */
5431 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5432 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5433 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5434 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5435 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5436 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5439 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5440 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5443 #define NEON_2RM_VREV64 0
5444 #define NEON_2RM_VREV32 1
5445 #define NEON_2RM_VREV16 2
5446 #define NEON_2RM_VPADDL 4
5447 #define NEON_2RM_VPADDL_U 5
5448 #define NEON_2RM_AESE 6 /* Includes AESD */
5449 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5450 #define NEON_2RM_VCLS 8
5451 #define NEON_2RM_VCLZ 9
5452 #define NEON_2RM_VCNT 10
5453 #define NEON_2RM_VMVN 11
5454 #define NEON_2RM_VPADAL 12
5455 #define NEON_2RM_VPADAL_U 13
5456 #define NEON_2RM_VQABS 14
5457 #define NEON_2RM_VQNEG 15
5458 #define NEON_2RM_VCGT0 16
5459 #define NEON_2RM_VCGE0 17
5460 #define NEON_2RM_VCEQ0 18
5461 #define NEON_2RM_VCLE0 19
5462 #define NEON_2RM_VCLT0 20
5463 #define NEON_2RM_SHA1H 21
5464 #define NEON_2RM_VABS 22
5465 #define NEON_2RM_VNEG 23
5466 #define NEON_2RM_VCGT0_F 24
5467 #define NEON_2RM_VCGE0_F 25
5468 #define NEON_2RM_VCEQ0_F 26
5469 #define NEON_2RM_VCLE0_F 27
5470 #define NEON_2RM_VCLT0_F 28
5471 #define NEON_2RM_VABS_F 30
5472 #define NEON_2RM_VNEG_F 31
5473 #define NEON_2RM_VSWP 32
5474 #define NEON_2RM_VTRN 33
5475 #define NEON_2RM_VUZP 34
5476 #define NEON_2RM_VZIP 35
5477 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5478 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5479 #define NEON_2RM_VSHLL 38
5480 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5481 #define NEON_2RM_VRINTN 40
5482 #define NEON_2RM_VRINTX 41
5483 #define NEON_2RM_VRINTA 42
5484 #define NEON_2RM_VRINTZ 43
5485 #define NEON_2RM_VCVT_F16_F32 44
5486 #define NEON_2RM_VRINTM 45
5487 #define NEON_2RM_VCVT_F32_F16 46
5488 #define NEON_2RM_VRINTP 47
5489 #define NEON_2RM_VCVTAU 48
5490 #define NEON_2RM_VCVTAS 49
5491 #define NEON_2RM_VCVTNU 50
5492 #define NEON_2RM_VCVTNS 51
5493 #define NEON_2RM_VCVTPU 52
5494 #define NEON_2RM_VCVTPS 53
5495 #define NEON_2RM_VCVTMU 54
5496 #define NEON_2RM_VCVTMS 55
5497 #define NEON_2RM_VRECPE 56
5498 #define NEON_2RM_VRSQRTE 57
5499 #define NEON_2RM_VRECPE_F 58
5500 #define NEON_2RM_VRSQRTE_F 59
5501 #define NEON_2RM_VCVT_FS 60
5502 #define NEON_2RM_VCVT_FU 61
5503 #define NEON_2RM_VCVT_SF 62
5504 #define NEON_2RM_VCVT_UF 63
5506 static int neon_2rm_is_float_op(int op
)
5508 /* Return true if this neon 2reg-misc op is float-to-float */
5509 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5510 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5511 op
== NEON_2RM_VRINTM
||
5512 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5513 op
>= NEON_2RM_VRECPE_F
);
5516 static bool neon_2rm_is_v8_op(int op
)
5518 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5520 case NEON_2RM_VRINTN
:
5521 case NEON_2RM_VRINTA
:
5522 case NEON_2RM_VRINTM
:
5523 case NEON_2RM_VRINTP
:
5524 case NEON_2RM_VRINTZ
:
5525 case NEON_2RM_VRINTX
:
5526 case NEON_2RM_VCVTAU
:
5527 case NEON_2RM_VCVTAS
:
5528 case NEON_2RM_VCVTNU
:
5529 case NEON_2RM_VCVTNS
:
5530 case NEON_2RM_VCVTPU
:
5531 case NEON_2RM_VCVTPS
:
5532 case NEON_2RM_VCVTMU
:
5533 case NEON_2RM_VCVTMS
:
5540 /* Each entry in this array has bit n set if the insn allows
5541 * size value n (otherwise it will UNDEF). Since unallocated
5542 * op values will have no bits set they always UNDEF.
5544 static const uint8_t neon_2rm_sizes
[] = {
5545 [NEON_2RM_VREV64
] = 0x7,
5546 [NEON_2RM_VREV32
] = 0x3,
5547 [NEON_2RM_VREV16
] = 0x1,
5548 [NEON_2RM_VPADDL
] = 0x7,
5549 [NEON_2RM_VPADDL_U
] = 0x7,
5550 [NEON_2RM_AESE
] = 0x1,
5551 [NEON_2RM_AESMC
] = 0x1,
5552 [NEON_2RM_VCLS
] = 0x7,
5553 [NEON_2RM_VCLZ
] = 0x7,
5554 [NEON_2RM_VCNT
] = 0x1,
5555 [NEON_2RM_VMVN
] = 0x1,
5556 [NEON_2RM_VPADAL
] = 0x7,
5557 [NEON_2RM_VPADAL_U
] = 0x7,
5558 [NEON_2RM_VQABS
] = 0x7,
5559 [NEON_2RM_VQNEG
] = 0x7,
5560 [NEON_2RM_VCGT0
] = 0x7,
5561 [NEON_2RM_VCGE0
] = 0x7,
5562 [NEON_2RM_VCEQ0
] = 0x7,
5563 [NEON_2RM_VCLE0
] = 0x7,
5564 [NEON_2RM_VCLT0
] = 0x7,
5565 [NEON_2RM_SHA1H
] = 0x4,
5566 [NEON_2RM_VABS
] = 0x7,
5567 [NEON_2RM_VNEG
] = 0x7,
5568 [NEON_2RM_VCGT0_F
] = 0x4,
5569 [NEON_2RM_VCGE0_F
] = 0x4,
5570 [NEON_2RM_VCEQ0_F
] = 0x4,
5571 [NEON_2RM_VCLE0_F
] = 0x4,
5572 [NEON_2RM_VCLT0_F
] = 0x4,
5573 [NEON_2RM_VABS_F
] = 0x4,
5574 [NEON_2RM_VNEG_F
] = 0x4,
5575 [NEON_2RM_VSWP
] = 0x1,
5576 [NEON_2RM_VTRN
] = 0x7,
5577 [NEON_2RM_VUZP
] = 0x7,
5578 [NEON_2RM_VZIP
] = 0x7,
5579 [NEON_2RM_VMOVN
] = 0x7,
5580 [NEON_2RM_VQMOVN
] = 0x7,
5581 [NEON_2RM_VSHLL
] = 0x7,
5582 [NEON_2RM_SHA1SU1
] = 0x4,
5583 [NEON_2RM_VRINTN
] = 0x4,
5584 [NEON_2RM_VRINTX
] = 0x4,
5585 [NEON_2RM_VRINTA
] = 0x4,
5586 [NEON_2RM_VRINTZ
] = 0x4,
5587 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5588 [NEON_2RM_VRINTM
] = 0x4,
5589 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5590 [NEON_2RM_VRINTP
] = 0x4,
5591 [NEON_2RM_VCVTAU
] = 0x4,
5592 [NEON_2RM_VCVTAS
] = 0x4,
5593 [NEON_2RM_VCVTNU
] = 0x4,
5594 [NEON_2RM_VCVTNS
] = 0x4,
5595 [NEON_2RM_VCVTPU
] = 0x4,
5596 [NEON_2RM_VCVTPS
] = 0x4,
5597 [NEON_2RM_VCVTMU
] = 0x4,
5598 [NEON_2RM_VCVTMS
] = 0x4,
5599 [NEON_2RM_VRECPE
] = 0x4,
5600 [NEON_2RM_VRSQRTE
] = 0x4,
5601 [NEON_2RM_VRECPE_F
] = 0x4,
5602 [NEON_2RM_VRSQRTE_F
] = 0x4,
5603 [NEON_2RM_VCVT_FS
] = 0x4,
5604 [NEON_2RM_VCVT_FU
] = 0x4,
5605 [NEON_2RM_VCVT_SF
] = 0x4,
5606 [NEON_2RM_VCVT_UF
] = 0x4,
5610 /* Expand v8.1 simd helper. */
5611 static int do_v81_helper(DisasContext
*s
, gen_helper_gvec_3_ptr
*fn
,
5612 int q
, int rd
, int rn
, int rm
)
5614 if (arm_dc_feature(s
, ARM_FEATURE_V8_RDM
)) {
5615 int opr_sz
= (1 + q
) * 8;
5616 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
5617 vfp_reg_offset(1, rn
),
5618 vfp_reg_offset(1, rm
), cpu_env
,
5619 opr_sz
, opr_sz
, 0, fn
);
5625 /* Translate a NEON data processing instruction. Return nonzero if the
5626 instruction is invalid.
5627 We process data in a mixture of 32-bit and 64-bit chunks.
5628 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5630 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5642 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5643 TCGv_ptr ptr1
, ptr2
, ptr3
;
5646 /* FIXME: this access check should not take precedence over UNDEF
5647 * for invalid encodings; we will generate incorrect syndrome information
5648 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5650 if (s
->fp_excp_el
) {
5651 gen_exception_insn(s
, 4, EXCP_UDEF
,
5652 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5656 if (!s
->vfp_enabled
)
5658 q
= (insn
& (1 << 6)) != 0;
5659 u
= (insn
>> 24) & 1;
5660 VFP_DREG_D(rd
, insn
);
5661 VFP_DREG_N(rn
, insn
);
5662 VFP_DREG_M(rm
, insn
);
5663 size
= (insn
>> 20) & 3;
5664 if ((insn
& (1 << 23)) == 0) {
5665 /* Three register same length. */
5666 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5667 /* Catch invalid op and bad size combinations: UNDEF */
5668 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5671 /* All insns of this form UNDEF for either this condition or the
5672 * superset of cases "Q==1"; we catch the latter later.
5674 if (q
&& ((rd
| rn
| rm
) & 1)) {
5679 /* The SHA-1/SHA-256 3-register instructions require special
5680 * treatment here, as their size field is overloaded as an
5681 * op type selector, and they all consume their input in a
5687 if (!u
) { /* SHA-1 */
5688 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5691 ptr1
= vfp_reg_ptr(true, rd
);
5692 ptr2
= vfp_reg_ptr(true, rn
);
5693 ptr3
= vfp_reg_ptr(true, rm
);
5694 tmp4
= tcg_const_i32(size
);
5695 gen_helper_crypto_sha1_3reg(ptr1
, ptr2
, ptr3
, tmp4
);
5696 tcg_temp_free_i32(tmp4
);
5697 } else { /* SHA-256 */
5698 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5701 ptr1
= vfp_reg_ptr(true, rd
);
5702 ptr2
= vfp_reg_ptr(true, rn
);
5703 ptr3
= vfp_reg_ptr(true, rm
);
5706 gen_helper_crypto_sha256h(ptr1
, ptr2
, ptr3
);
5709 gen_helper_crypto_sha256h2(ptr1
, ptr2
, ptr3
);
5712 gen_helper_crypto_sha256su1(ptr1
, ptr2
, ptr3
);
5716 tcg_temp_free_ptr(ptr1
);
5717 tcg_temp_free_ptr(ptr2
);
5718 tcg_temp_free_ptr(ptr3
);
5721 case NEON_3R_VPADD_VQRDMLAH
:
5728 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s16
,
5731 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s32
,
5736 case NEON_3R_VFM_VQRDMLSH
:
5747 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s16
,
5750 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s32
,
5755 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5756 /* 64-bit element instructions. */
5757 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5758 neon_load_reg64(cpu_V0
, rn
+ pass
);
5759 neon_load_reg64(cpu_V1
, rm
+ pass
);
5763 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5766 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5772 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5775 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5781 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5783 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5788 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5791 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5797 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5799 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5802 case NEON_3R_VQRSHL
:
5804 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5807 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5811 case NEON_3R_VADD_VSUB
:
5813 tcg_gen_sub_i64(CPU_V001
);
5815 tcg_gen_add_i64(CPU_V001
);
5821 neon_store_reg64(cpu_V0
, rd
+ pass
);
5830 case NEON_3R_VQRSHL
:
5833 /* Shift instruction operands are reversed. */
5839 case NEON_3R_VPADD_VQRDMLAH
:
5844 case NEON_3R_FLOAT_ARITH
:
5845 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5847 case NEON_3R_FLOAT_MINMAX
:
5848 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5850 case NEON_3R_FLOAT_CMP
:
5852 /* no encoding for U=0 C=1x */
5856 case NEON_3R_FLOAT_ACMP
:
5861 case NEON_3R_FLOAT_MISC
:
5862 /* VMAXNM/VMINNM in ARMv8 */
5863 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5868 if (u
&& (size
!= 0)) {
5869 /* UNDEF on invalid size for polynomial subcase */
5873 case NEON_3R_VFM_VQRDMLSH
:
5874 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
5882 if (pairwise
&& q
) {
5883 /* All the pairwise insns UNDEF if Q is set */
5887 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5892 tmp
= neon_load_reg(rn
, 0);
5893 tmp2
= neon_load_reg(rn
, 1);
5895 tmp
= neon_load_reg(rm
, 0);
5896 tmp2
= neon_load_reg(rm
, 1);
5900 tmp
= neon_load_reg(rn
, pass
);
5901 tmp2
= neon_load_reg(rm
, pass
);
5905 GEN_NEON_INTEGER_OP(hadd
);
5908 GEN_NEON_INTEGER_OP_ENV(qadd
);
5910 case NEON_3R_VRHADD
:
5911 GEN_NEON_INTEGER_OP(rhadd
);
5913 case NEON_3R_LOGIC
: /* Logic ops. */
5914 switch ((u
<< 2) | size
) {
5916 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5919 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5922 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5925 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5928 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5931 tmp3
= neon_load_reg(rd
, pass
);
5932 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5933 tcg_temp_free_i32(tmp3
);
5936 tmp3
= neon_load_reg(rd
, pass
);
5937 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5938 tcg_temp_free_i32(tmp3
);
5941 tmp3
= neon_load_reg(rd
, pass
);
5942 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5943 tcg_temp_free_i32(tmp3
);
5948 GEN_NEON_INTEGER_OP(hsub
);
5951 GEN_NEON_INTEGER_OP_ENV(qsub
);
5954 GEN_NEON_INTEGER_OP(cgt
);
5957 GEN_NEON_INTEGER_OP(cge
);
5960 GEN_NEON_INTEGER_OP(shl
);
5963 GEN_NEON_INTEGER_OP_ENV(qshl
);
5966 GEN_NEON_INTEGER_OP(rshl
);
5968 case NEON_3R_VQRSHL
:
5969 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5972 GEN_NEON_INTEGER_OP(max
);
5975 GEN_NEON_INTEGER_OP(min
);
5978 GEN_NEON_INTEGER_OP(abd
);
5981 GEN_NEON_INTEGER_OP(abd
);
5982 tcg_temp_free_i32(tmp2
);
5983 tmp2
= neon_load_reg(rd
, pass
);
5984 gen_neon_add(size
, tmp
, tmp2
);
5986 case NEON_3R_VADD_VSUB
:
5987 if (!u
) { /* VADD */
5988 gen_neon_add(size
, tmp
, tmp2
);
5991 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5992 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5993 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5998 case NEON_3R_VTST_VCEQ
:
5999 if (!u
) { /* VTST */
6001 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
6002 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
6003 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
6008 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6009 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6010 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6015 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
6017 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6018 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6019 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6022 tcg_temp_free_i32(tmp2
);
6023 tmp2
= neon_load_reg(rd
, pass
);
6025 gen_neon_rsb(size
, tmp
, tmp2
);
6027 gen_neon_add(size
, tmp
, tmp2
);
6031 if (u
) { /* polynomial */
6032 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
6033 } else { /* Integer */
6035 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6036 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6037 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6043 GEN_NEON_INTEGER_OP(pmax
);
6046 GEN_NEON_INTEGER_OP(pmin
);
6048 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
6049 if (!u
) { /* VQDMULH */
6052 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6055 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6059 } else { /* VQRDMULH */
6062 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6065 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6071 case NEON_3R_VPADD_VQRDMLAH
:
6073 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
6074 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
6075 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
6079 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
6081 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6082 switch ((u
<< 2) | size
) {
6085 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6088 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
6091 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
6096 tcg_temp_free_ptr(fpstatus
);
6099 case NEON_3R_FLOAT_MULTIPLY
:
6101 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6102 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6104 tcg_temp_free_i32(tmp2
);
6105 tmp2
= neon_load_reg(rd
, pass
);
6107 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6109 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6112 tcg_temp_free_ptr(fpstatus
);
6115 case NEON_3R_FLOAT_CMP
:
6117 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6119 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6122 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6124 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6127 tcg_temp_free_ptr(fpstatus
);
6130 case NEON_3R_FLOAT_ACMP
:
6132 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6134 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6136 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6138 tcg_temp_free_ptr(fpstatus
);
6141 case NEON_3R_FLOAT_MINMAX
:
6143 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6145 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6147 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6149 tcg_temp_free_ptr(fpstatus
);
6152 case NEON_3R_FLOAT_MISC
:
6155 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6157 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6159 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6161 tcg_temp_free_ptr(fpstatus
);
6164 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6166 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6170 case NEON_3R_VFM_VQRDMLSH
:
6172 /* VFMA, VFMS: fused multiply-add */
6173 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6174 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6177 gen_helper_vfp_negs(tmp
, tmp
);
6179 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6180 tcg_temp_free_i32(tmp3
);
6181 tcg_temp_free_ptr(fpstatus
);
6187 tcg_temp_free_i32(tmp2
);
6189 /* Save the result. For elementwise operations we can put it
6190 straight into the destination register. For pairwise operations
6191 we have to be careful to avoid clobbering the source operands. */
6192 if (pairwise
&& rd
== rm
) {
6193 neon_store_scratch(pass
, tmp
);
6195 neon_store_reg(rd
, pass
, tmp
);
6199 if (pairwise
&& rd
== rm
) {
6200 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6201 tmp
= neon_load_scratch(pass
);
6202 neon_store_reg(rd
, pass
, tmp
);
6205 /* End of 3 register same size operations. */
6206 } else if (insn
& (1 << 4)) {
6207 if ((insn
& 0x00380080) != 0) {
6208 /* Two registers and shift. */
6209 op
= (insn
>> 8) & 0xf;
6210 if (insn
& (1 << 7)) {
6218 while ((insn
& (1 << (size
+ 19))) == 0)
6221 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6222 /* To avoid excessive duplication of ops we implement shift
6223 by immediate using the variable shift operations. */
6225 /* Shift by immediate:
6226 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6227 if (q
&& ((rd
| rm
) & 1)) {
6230 if (!u
&& (op
== 4 || op
== 6)) {
6233 /* Right shifts are encoded as N - shift, where N is the
6234 element size in bits. */
6236 shift
= shift
- (1 << (size
+ 3));
6244 imm
= (uint8_t) shift
;
6249 imm
= (uint16_t) shift
;
6260 for (pass
= 0; pass
< count
; pass
++) {
6262 neon_load_reg64(cpu_V0
, rm
+ pass
);
6263 tcg_gen_movi_i64(cpu_V1
, imm
);
6268 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6270 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6275 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6277 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6280 case 5: /* VSHL, VSLI */
6281 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6283 case 6: /* VQSHLU */
6284 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6289 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6292 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6297 if (op
== 1 || op
== 3) {
6299 neon_load_reg64(cpu_V1
, rd
+ pass
);
6300 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6301 } else if (op
== 4 || (op
== 5 && u
)) {
6303 neon_load_reg64(cpu_V1
, rd
+ pass
);
6305 if (shift
< -63 || shift
> 63) {
6309 mask
= 0xffffffffffffffffull
>> -shift
;
6311 mask
= 0xffffffffffffffffull
<< shift
;
6314 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6315 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6317 neon_store_reg64(cpu_V0
, rd
+ pass
);
6318 } else { /* size < 3 */
6319 /* Operands in T0 and T1. */
6320 tmp
= neon_load_reg(rm
, pass
);
6321 tmp2
= tcg_temp_new_i32();
6322 tcg_gen_movi_i32(tmp2
, imm
);
6326 GEN_NEON_INTEGER_OP(shl
);
6330 GEN_NEON_INTEGER_OP(rshl
);
6333 case 5: /* VSHL, VSLI */
6335 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6336 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6337 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6341 case 6: /* VQSHLU */
6344 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6348 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6352 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6360 GEN_NEON_INTEGER_OP_ENV(qshl
);
6363 tcg_temp_free_i32(tmp2
);
6365 if (op
== 1 || op
== 3) {
6367 tmp2
= neon_load_reg(rd
, pass
);
6368 gen_neon_add(size
, tmp
, tmp2
);
6369 tcg_temp_free_i32(tmp2
);
6370 } else if (op
== 4 || (op
== 5 && u
)) {
6375 mask
= 0xff >> -shift
;
6377 mask
= (uint8_t)(0xff << shift
);
6383 mask
= 0xffff >> -shift
;
6385 mask
= (uint16_t)(0xffff << shift
);
6389 if (shift
< -31 || shift
> 31) {
6393 mask
= 0xffffffffu
>> -shift
;
6395 mask
= 0xffffffffu
<< shift
;
6401 tmp2
= neon_load_reg(rd
, pass
);
6402 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6403 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6404 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6405 tcg_temp_free_i32(tmp2
);
6407 neon_store_reg(rd
, pass
, tmp
);
6410 } else if (op
< 10) {
6411 /* Shift by immediate and narrow:
6412 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6413 int input_unsigned
= (op
== 8) ? !u
: u
;
6417 shift
= shift
- (1 << (size
+ 3));
6420 tmp64
= tcg_const_i64(shift
);
6421 neon_load_reg64(cpu_V0
, rm
);
6422 neon_load_reg64(cpu_V1
, rm
+ 1);
6423 for (pass
= 0; pass
< 2; pass
++) {
6431 if (input_unsigned
) {
6432 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6434 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6437 if (input_unsigned
) {
6438 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6440 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6443 tmp
= tcg_temp_new_i32();
6444 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6445 neon_store_reg(rd
, pass
, tmp
);
6447 tcg_temp_free_i64(tmp64
);
6450 imm
= (uint16_t)shift
;
6454 imm
= (uint32_t)shift
;
6456 tmp2
= tcg_const_i32(imm
);
6457 tmp4
= neon_load_reg(rm
+ 1, 0);
6458 tmp5
= neon_load_reg(rm
+ 1, 1);
6459 for (pass
= 0; pass
< 2; pass
++) {
6461 tmp
= neon_load_reg(rm
, 0);
6465 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6468 tmp3
= neon_load_reg(rm
, 1);
6472 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6474 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6475 tcg_temp_free_i32(tmp
);
6476 tcg_temp_free_i32(tmp3
);
6477 tmp
= tcg_temp_new_i32();
6478 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6479 neon_store_reg(rd
, pass
, tmp
);
6481 tcg_temp_free_i32(tmp2
);
6483 } else if (op
== 10) {
6485 if (q
|| (rd
& 1)) {
6488 tmp
= neon_load_reg(rm
, 0);
6489 tmp2
= neon_load_reg(rm
, 1);
6490 for (pass
= 0; pass
< 2; pass
++) {
6494 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6497 /* The shift is less than the width of the source
6498 type, so we can just shift the whole register. */
6499 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6500 /* Widen the result of shift: we need to clear
6501 * the potential overflow bits resulting from
6502 * left bits of the narrow input appearing as
6503 * right bits of left the neighbour narrow
6505 if (size
< 2 || !u
) {
6508 imm
= (0xffu
>> (8 - shift
));
6510 } else if (size
== 1) {
6511 imm
= 0xffff >> (16 - shift
);
6514 imm
= 0xffffffff >> (32 - shift
);
6517 imm64
= imm
| (((uint64_t)imm
) << 32);
6521 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6524 neon_store_reg64(cpu_V0
, rd
+ pass
);
6526 } else if (op
>= 14) {
6527 /* VCVT fixed-point. */
6528 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6531 /* We have already masked out the must-be-1 top bit of imm6,
6532 * hence this 32-shift where the ARM ARM has 64-imm6.
6535 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6536 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6539 gen_vfp_ulto(0, shift
, 1);
6541 gen_vfp_slto(0, shift
, 1);
6544 gen_vfp_toul(0, shift
, 1);
6546 gen_vfp_tosl(0, shift
, 1);
6548 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6553 } else { /* (insn & 0x00380080) == 0 */
6555 if (q
&& (rd
& 1)) {
6559 op
= (insn
>> 8) & 0xf;
6560 /* One register and immediate. */
6561 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6562 invert
= (insn
& (1 << 5)) != 0;
6563 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6564 * We choose to not special-case this and will behave as if a
6565 * valid constant encoding of 0 had been given.
6584 imm
= (imm
<< 8) | (imm
<< 24);
6587 imm
= (imm
<< 8) | 0xff;
6590 imm
= (imm
<< 16) | 0xffff;
6593 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6601 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6602 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6608 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6609 if (op
& 1 && op
< 12) {
6610 tmp
= neon_load_reg(rd
, pass
);
6612 /* The immediate value has already been inverted, so
6614 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6616 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6620 tmp
= tcg_temp_new_i32();
6621 if (op
== 14 && invert
) {
6625 for (n
= 0; n
< 4; n
++) {
6626 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6627 val
|= 0xff << (n
* 8);
6629 tcg_gen_movi_i32(tmp
, val
);
6631 tcg_gen_movi_i32(tmp
, imm
);
6634 neon_store_reg(rd
, pass
, tmp
);
6637 } else { /* (insn & 0x00800010 == 0x00800000) */
6639 op
= (insn
>> 8) & 0xf;
6640 if ((insn
& (1 << 6)) == 0) {
6641 /* Three registers of different lengths. */
6645 /* undefreq: bit 0 : UNDEF if size == 0
6646 * bit 1 : UNDEF if size == 1
6647 * bit 2 : UNDEF if size == 2
6648 * bit 3 : UNDEF if U == 1
6649 * Note that [2:0] set implies 'always UNDEF'
6652 /* prewiden, src1_wide, src2_wide, undefreq */
6653 static const int neon_3reg_wide
[16][4] = {
6654 {1, 0, 0, 0}, /* VADDL */
6655 {1, 1, 0, 0}, /* VADDW */
6656 {1, 0, 0, 0}, /* VSUBL */
6657 {1, 1, 0, 0}, /* VSUBW */
6658 {0, 1, 1, 0}, /* VADDHN */
6659 {0, 0, 0, 0}, /* VABAL */
6660 {0, 1, 1, 0}, /* VSUBHN */
6661 {0, 0, 0, 0}, /* VABDL */
6662 {0, 0, 0, 0}, /* VMLAL */
6663 {0, 0, 0, 9}, /* VQDMLAL */
6664 {0, 0, 0, 0}, /* VMLSL */
6665 {0, 0, 0, 9}, /* VQDMLSL */
6666 {0, 0, 0, 0}, /* Integer VMULL */
6667 {0, 0, 0, 1}, /* VQDMULL */
6668 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6669 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6672 prewiden
= neon_3reg_wide
[op
][0];
6673 src1_wide
= neon_3reg_wide
[op
][1];
6674 src2_wide
= neon_3reg_wide
[op
][2];
6675 undefreq
= neon_3reg_wide
[op
][3];
6677 if ((undefreq
& (1 << size
)) ||
6678 ((undefreq
& 8) && u
)) {
6681 if ((src1_wide
&& (rn
& 1)) ||
6682 (src2_wide
&& (rm
& 1)) ||
6683 (!src2_wide
&& (rd
& 1))) {
6687 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6688 * outside the loop below as it only performs a single pass.
6690 if (op
== 14 && size
== 2) {
6691 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6693 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6696 tcg_rn
= tcg_temp_new_i64();
6697 tcg_rm
= tcg_temp_new_i64();
6698 tcg_rd
= tcg_temp_new_i64();
6699 neon_load_reg64(tcg_rn
, rn
);
6700 neon_load_reg64(tcg_rm
, rm
);
6701 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6702 neon_store_reg64(tcg_rd
, rd
);
6703 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6704 neon_store_reg64(tcg_rd
, rd
+ 1);
6705 tcg_temp_free_i64(tcg_rn
);
6706 tcg_temp_free_i64(tcg_rm
);
6707 tcg_temp_free_i64(tcg_rd
);
6711 /* Avoid overlapping operands. Wide source operands are
6712 always aligned so will never overlap with wide
6713 destinations in problematic ways. */
6714 if (rd
== rm
&& !src2_wide
) {
6715 tmp
= neon_load_reg(rm
, 1);
6716 neon_store_scratch(2, tmp
);
6717 } else if (rd
== rn
&& !src1_wide
) {
6718 tmp
= neon_load_reg(rn
, 1);
6719 neon_store_scratch(2, tmp
);
6722 for (pass
= 0; pass
< 2; pass
++) {
6724 neon_load_reg64(cpu_V0
, rn
+ pass
);
6727 if (pass
== 1 && rd
== rn
) {
6728 tmp
= neon_load_scratch(2);
6730 tmp
= neon_load_reg(rn
, pass
);
6733 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6737 neon_load_reg64(cpu_V1
, rm
+ pass
);
6740 if (pass
== 1 && rd
== rm
) {
6741 tmp2
= neon_load_scratch(2);
6743 tmp2
= neon_load_reg(rm
, pass
);
6746 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6750 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6751 gen_neon_addl(size
);
6753 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6754 gen_neon_subl(size
);
6756 case 5: case 7: /* VABAL, VABDL */
6757 switch ((size
<< 1) | u
) {
6759 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6762 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6765 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6768 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6771 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6774 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6778 tcg_temp_free_i32(tmp2
);
6779 tcg_temp_free_i32(tmp
);
6781 case 8: case 9: case 10: case 11: case 12: case 13:
6782 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6783 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6785 case 14: /* Polynomial VMULL */
6786 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6787 tcg_temp_free_i32(tmp2
);
6788 tcg_temp_free_i32(tmp
);
6790 default: /* 15 is RESERVED: caught earlier */
6795 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6796 neon_store_reg64(cpu_V0
, rd
+ pass
);
6797 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6799 neon_load_reg64(cpu_V1
, rd
+ pass
);
6801 case 10: /* VMLSL */
6802 gen_neon_negl(cpu_V0
, size
);
6804 case 5: case 8: /* VABAL, VMLAL */
6805 gen_neon_addl(size
);
6807 case 9: case 11: /* VQDMLAL, VQDMLSL */
6808 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6810 gen_neon_negl(cpu_V0
, size
);
6812 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6817 neon_store_reg64(cpu_V0
, rd
+ pass
);
6818 } else if (op
== 4 || op
== 6) {
6819 /* Narrowing operation. */
6820 tmp
= tcg_temp_new_i32();
6824 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6827 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6830 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6831 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6838 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6841 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6844 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6845 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6846 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6854 neon_store_reg(rd
, 0, tmp3
);
6855 neon_store_reg(rd
, 1, tmp
);
6858 /* Write back the result. */
6859 neon_store_reg64(cpu_V0
, rd
+ pass
);
6863 /* Two registers and a scalar. NB that for ops of this form
6864 * the ARM ARM labels bit 24 as Q, but it is in our variable
6871 case 1: /* Float VMLA scalar */
6872 case 5: /* Floating point VMLS scalar */
6873 case 9: /* Floating point VMUL scalar */
6878 case 0: /* Integer VMLA scalar */
6879 case 4: /* Integer VMLS scalar */
6880 case 8: /* Integer VMUL scalar */
6881 case 12: /* VQDMULH scalar */
6882 case 13: /* VQRDMULH scalar */
6883 if (u
&& ((rd
| rn
) & 1)) {
6886 tmp
= neon_get_scalar(size
, rm
);
6887 neon_store_scratch(0, tmp
);
6888 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6889 tmp
= neon_load_scratch(0);
6890 tmp2
= neon_load_reg(rn
, pass
);
6893 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6895 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6897 } else if (op
== 13) {
6899 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6901 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6903 } else if (op
& 1) {
6904 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6905 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6906 tcg_temp_free_ptr(fpstatus
);
6909 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6910 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6911 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6915 tcg_temp_free_i32(tmp2
);
6918 tmp2
= neon_load_reg(rd
, pass
);
6921 gen_neon_add(size
, tmp
, tmp2
);
6925 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6926 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6927 tcg_temp_free_ptr(fpstatus
);
6931 gen_neon_rsb(size
, tmp
, tmp2
);
6935 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6936 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6937 tcg_temp_free_ptr(fpstatus
);
6943 tcg_temp_free_i32(tmp2
);
6945 neon_store_reg(rd
, pass
, tmp
);
6948 case 3: /* VQDMLAL scalar */
6949 case 7: /* VQDMLSL scalar */
6950 case 11: /* VQDMULL scalar */
6955 case 2: /* VMLAL sclar */
6956 case 6: /* VMLSL scalar */
6957 case 10: /* VMULL scalar */
6961 tmp2
= neon_get_scalar(size
, rm
);
6962 /* We need a copy of tmp2 because gen_neon_mull
6963 * deletes it during pass 0. */
6964 tmp4
= tcg_temp_new_i32();
6965 tcg_gen_mov_i32(tmp4
, tmp2
);
6966 tmp3
= neon_load_reg(rn
, 1);
6968 for (pass
= 0; pass
< 2; pass
++) {
6970 tmp
= neon_load_reg(rn
, 0);
6975 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6977 neon_load_reg64(cpu_V1
, rd
+ pass
);
6981 gen_neon_negl(cpu_V0
, size
);
6984 gen_neon_addl(size
);
6987 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6989 gen_neon_negl(cpu_V0
, size
);
6991 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6997 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
7002 neon_store_reg64(cpu_V0
, rd
+ pass
);
7005 case 14: /* VQRDMLAH scalar */
7006 case 15: /* VQRDMLSH scalar */
7008 NeonGenThreeOpEnvFn
*fn
;
7010 if (!arm_dc_feature(s
, ARM_FEATURE_V8_RDM
)) {
7013 if (u
&& ((rd
| rn
) & 1)) {
7018 fn
= gen_helper_neon_qrdmlah_s16
;
7020 fn
= gen_helper_neon_qrdmlah_s32
;
7024 fn
= gen_helper_neon_qrdmlsh_s16
;
7026 fn
= gen_helper_neon_qrdmlsh_s32
;
7030 tmp2
= neon_get_scalar(size
, rm
);
7031 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
7032 tmp
= neon_load_reg(rn
, pass
);
7033 tmp3
= neon_load_reg(rd
, pass
);
7034 fn(tmp
, cpu_env
, tmp
, tmp2
, tmp3
);
7035 tcg_temp_free_i32(tmp3
);
7036 neon_store_reg(rd
, pass
, tmp
);
7038 tcg_temp_free_i32(tmp2
);
7042 g_assert_not_reached();
7045 } else { /* size == 3 */
7048 imm
= (insn
>> 8) & 0xf;
7053 if (q
&& ((rd
| rn
| rm
) & 1)) {
7058 neon_load_reg64(cpu_V0
, rn
);
7060 neon_load_reg64(cpu_V1
, rn
+ 1);
7062 } else if (imm
== 8) {
7063 neon_load_reg64(cpu_V0
, rn
+ 1);
7065 neon_load_reg64(cpu_V1
, rm
);
7068 tmp64
= tcg_temp_new_i64();
7070 neon_load_reg64(cpu_V0
, rn
);
7071 neon_load_reg64(tmp64
, rn
+ 1);
7073 neon_load_reg64(cpu_V0
, rn
+ 1);
7074 neon_load_reg64(tmp64
, rm
);
7076 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
7077 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
7078 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7080 neon_load_reg64(cpu_V1
, rm
);
7082 neon_load_reg64(cpu_V1
, rm
+ 1);
7085 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7086 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
7087 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
7088 tcg_temp_free_i64(tmp64
);
7091 neon_load_reg64(cpu_V0
, rn
);
7092 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
7093 neon_load_reg64(cpu_V1
, rm
);
7094 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7095 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7097 neon_store_reg64(cpu_V0
, rd
);
7099 neon_store_reg64(cpu_V1
, rd
+ 1);
7101 } else if ((insn
& (1 << 11)) == 0) {
7102 /* Two register misc. */
7103 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
7104 size
= (insn
>> 18) & 3;
7105 /* UNDEF for unknown op values and bad op-size combinations */
7106 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
7109 if (neon_2rm_is_v8_op(op
) &&
7110 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7113 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
7114 q
&& ((rm
| rd
) & 1)) {
7118 case NEON_2RM_VREV64
:
7119 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
7120 tmp
= neon_load_reg(rm
, pass
* 2);
7121 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
7123 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7124 case 1: gen_swap_half(tmp
); break;
7125 case 2: /* no-op */ break;
7128 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
7130 neon_store_reg(rd
, pass
* 2, tmp2
);
7133 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
7134 case 1: gen_swap_half(tmp2
); break;
7137 neon_store_reg(rd
, pass
* 2, tmp2
);
7141 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
7142 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
7143 for (pass
= 0; pass
< q
+ 1; pass
++) {
7144 tmp
= neon_load_reg(rm
, pass
* 2);
7145 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
7146 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
7147 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
7149 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
7150 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
7151 case 2: tcg_gen_add_i64(CPU_V001
); break;
7154 if (op
>= NEON_2RM_VPADAL
) {
7156 neon_load_reg64(cpu_V1
, rd
+ pass
);
7157 gen_neon_addl(size
);
7159 neon_store_reg64(cpu_V0
, rd
+ pass
);
7165 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7166 tmp
= neon_load_reg(rm
, n
);
7167 tmp2
= neon_load_reg(rd
, n
+ 1);
7168 neon_store_reg(rm
, n
, tmp2
);
7169 neon_store_reg(rd
, n
+ 1, tmp
);
7176 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7181 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7185 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7186 /* also VQMOVUN; op field and mnemonics don't line up */
7191 for (pass
= 0; pass
< 2; pass
++) {
7192 neon_load_reg64(cpu_V0
, rm
+ pass
);
7193 tmp
= tcg_temp_new_i32();
7194 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7199 neon_store_reg(rd
, 0, tmp2
);
7200 neon_store_reg(rd
, 1, tmp
);
7204 case NEON_2RM_VSHLL
:
7205 if (q
|| (rd
& 1)) {
7208 tmp
= neon_load_reg(rm
, 0);
7209 tmp2
= neon_load_reg(rm
, 1);
7210 for (pass
= 0; pass
< 2; pass
++) {
7213 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7214 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7215 neon_store_reg64(cpu_V0
, rd
+ pass
);
7218 case NEON_2RM_VCVT_F16_F32
:
7219 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7223 tmp
= tcg_temp_new_i32();
7224 tmp2
= tcg_temp_new_i32();
7225 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7226 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7227 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7228 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7229 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7230 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7231 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7232 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7233 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7234 neon_store_reg(rd
, 0, tmp2
);
7235 tmp2
= tcg_temp_new_i32();
7236 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7237 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7238 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7239 neon_store_reg(rd
, 1, tmp2
);
7240 tcg_temp_free_i32(tmp
);
7242 case NEON_2RM_VCVT_F32_F16
:
7243 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7247 tmp3
= tcg_temp_new_i32();
7248 tmp
= neon_load_reg(rm
, 0);
7249 tmp2
= neon_load_reg(rm
, 1);
7250 tcg_gen_ext16u_i32(tmp3
, tmp
);
7251 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7252 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7253 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7254 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7255 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7256 tcg_temp_free_i32(tmp
);
7257 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7258 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7259 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7260 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7261 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7262 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7263 tcg_temp_free_i32(tmp2
);
7264 tcg_temp_free_i32(tmp3
);
7266 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7267 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
7268 || ((rm
| rd
) & 1)) {
7271 ptr1
= vfp_reg_ptr(true, rd
);
7272 ptr2
= vfp_reg_ptr(true, rm
);
7274 /* Bit 6 is the lowest opcode bit; it distinguishes between
7275 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7277 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7279 if (op
== NEON_2RM_AESE
) {
7280 gen_helper_crypto_aese(ptr1
, ptr2
, tmp3
);
7282 gen_helper_crypto_aesmc(ptr1
, ptr2
, tmp3
);
7284 tcg_temp_free_ptr(ptr1
);
7285 tcg_temp_free_ptr(ptr2
);
7286 tcg_temp_free_i32(tmp3
);
7288 case NEON_2RM_SHA1H
:
7289 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7290 || ((rm
| rd
) & 1)) {
7293 ptr1
= vfp_reg_ptr(true, rd
);
7294 ptr2
= vfp_reg_ptr(true, rm
);
7296 gen_helper_crypto_sha1h(ptr1
, ptr2
);
7298 tcg_temp_free_ptr(ptr1
);
7299 tcg_temp_free_ptr(ptr2
);
7301 case NEON_2RM_SHA1SU1
:
7302 if ((rm
| rd
) & 1) {
7305 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7307 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7310 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7313 ptr1
= vfp_reg_ptr(true, rd
);
7314 ptr2
= vfp_reg_ptr(true, rm
);
7316 gen_helper_crypto_sha256su0(ptr1
, ptr2
);
7318 gen_helper_crypto_sha1su1(ptr1
, ptr2
);
7320 tcg_temp_free_ptr(ptr1
);
7321 tcg_temp_free_ptr(ptr2
);
7325 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7326 if (neon_2rm_is_float_op(op
)) {
7327 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7328 neon_reg_offset(rm
, pass
));
7331 tmp
= neon_load_reg(rm
, pass
);
7334 case NEON_2RM_VREV32
:
7336 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7337 case 1: gen_swap_half(tmp
); break;
7341 case NEON_2RM_VREV16
:
7346 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7347 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7348 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7354 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7355 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7356 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7361 gen_helper_neon_cnt_u8(tmp
, tmp
);
7364 tcg_gen_not_i32(tmp
, tmp
);
7366 case NEON_2RM_VQABS
:
7369 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7372 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7375 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7380 case NEON_2RM_VQNEG
:
7383 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7386 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7389 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7394 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7395 tmp2
= tcg_const_i32(0);
7397 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7398 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7399 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7402 tcg_temp_free_i32(tmp2
);
7403 if (op
== NEON_2RM_VCLE0
) {
7404 tcg_gen_not_i32(tmp
, tmp
);
7407 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7408 tmp2
= tcg_const_i32(0);
7410 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7411 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7412 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7415 tcg_temp_free_i32(tmp2
);
7416 if (op
== NEON_2RM_VCLT0
) {
7417 tcg_gen_not_i32(tmp
, tmp
);
7420 case NEON_2RM_VCEQ0
:
7421 tmp2
= tcg_const_i32(0);
7423 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7424 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7425 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7428 tcg_temp_free_i32(tmp2
);
7432 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7433 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7434 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7439 tmp2
= tcg_const_i32(0);
7440 gen_neon_rsb(size
, tmp
, tmp2
);
7441 tcg_temp_free_i32(tmp2
);
7443 case NEON_2RM_VCGT0_F
:
7445 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7446 tmp2
= tcg_const_i32(0);
7447 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7448 tcg_temp_free_i32(tmp2
);
7449 tcg_temp_free_ptr(fpstatus
);
7452 case NEON_2RM_VCGE0_F
:
7454 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7455 tmp2
= tcg_const_i32(0);
7456 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7457 tcg_temp_free_i32(tmp2
);
7458 tcg_temp_free_ptr(fpstatus
);
7461 case NEON_2RM_VCEQ0_F
:
7463 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7464 tmp2
= tcg_const_i32(0);
7465 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7466 tcg_temp_free_i32(tmp2
);
7467 tcg_temp_free_ptr(fpstatus
);
7470 case NEON_2RM_VCLE0_F
:
7472 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7473 tmp2
= tcg_const_i32(0);
7474 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7475 tcg_temp_free_i32(tmp2
);
7476 tcg_temp_free_ptr(fpstatus
);
7479 case NEON_2RM_VCLT0_F
:
7481 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7482 tmp2
= tcg_const_i32(0);
7483 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7484 tcg_temp_free_i32(tmp2
);
7485 tcg_temp_free_ptr(fpstatus
);
7488 case NEON_2RM_VABS_F
:
7491 case NEON_2RM_VNEG_F
:
7495 tmp2
= neon_load_reg(rd
, pass
);
7496 neon_store_reg(rm
, pass
, tmp2
);
7499 tmp2
= neon_load_reg(rd
, pass
);
7501 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7502 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7505 neon_store_reg(rm
, pass
, tmp2
);
7507 case NEON_2RM_VRINTN
:
7508 case NEON_2RM_VRINTA
:
7509 case NEON_2RM_VRINTM
:
7510 case NEON_2RM_VRINTP
:
7511 case NEON_2RM_VRINTZ
:
7514 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7517 if (op
== NEON_2RM_VRINTZ
) {
7518 rmode
= FPROUNDING_ZERO
;
7520 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7523 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7524 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7526 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7527 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7529 tcg_temp_free_ptr(fpstatus
);
7530 tcg_temp_free_i32(tcg_rmode
);
7533 case NEON_2RM_VRINTX
:
7535 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7536 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7537 tcg_temp_free_ptr(fpstatus
);
7540 case NEON_2RM_VCVTAU
:
7541 case NEON_2RM_VCVTAS
:
7542 case NEON_2RM_VCVTNU
:
7543 case NEON_2RM_VCVTNS
:
7544 case NEON_2RM_VCVTPU
:
7545 case NEON_2RM_VCVTPS
:
7546 case NEON_2RM_VCVTMU
:
7547 case NEON_2RM_VCVTMS
:
7549 bool is_signed
= !extract32(insn
, 7, 1);
7550 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7551 TCGv_i32 tcg_rmode
, tcg_shift
;
7552 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7554 tcg_shift
= tcg_const_i32(0);
7555 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7556 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7560 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7563 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7567 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7569 tcg_temp_free_i32(tcg_rmode
);
7570 tcg_temp_free_i32(tcg_shift
);
7571 tcg_temp_free_ptr(fpst
);
7574 case NEON_2RM_VRECPE
:
7576 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7577 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7578 tcg_temp_free_ptr(fpstatus
);
7581 case NEON_2RM_VRSQRTE
:
7583 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7584 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7585 tcg_temp_free_ptr(fpstatus
);
7588 case NEON_2RM_VRECPE_F
:
7590 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7591 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7592 tcg_temp_free_ptr(fpstatus
);
7595 case NEON_2RM_VRSQRTE_F
:
7597 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7598 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7599 tcg_temp_free_ptr(fpstatus
);
7602 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7605 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7608 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7609 gen_vfp_tosiz(0, 1);
7611 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7612 gen_vfp_touiz(0, 1);
7615 /* Reserved op values were caught by the
7616 * neon_2rm_sizes[] check earlier.
7620 if (neon_2rm_is_float_op(op
)) {
7621 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7622 neon_reg_offset(rd
, pass
));
7624 neon_store_reg(rd
, pass
, tmp
);
7629 } else if ((insn
& (1 << 10)) == 0) {
7631 int n
= ((insn
>> 8) & 3) + 1;
7632 if ((rn
+ n
) > 32) {
7633 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7634 * helper function running off the end of the register file.
7639 if (insn
& (1 << 6)) {
7640 tmp
= neon_load_reg(rd
, 0);
7642 tmp
= tcg_temp_new_i32();
7643 tcg_gen_movi_i32(tmp
, 0);
7645 tmp2
= neon_load_reg(rm
, 0);
7646 ptr1
= vfp_reg_ptr(true, rn
);
7647 tmp5
= tcg_const_i32(n
);
7648 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, ptr1
, tmp5
);
7649 tcg_temp_free_i32(tmp
);
7650 if (insn
& (1 << 6)) {
7651 tmp
= neon_load_reg(rd
, 1);
7653 tmp
= tcg_temp_new_i32();
7654 tcg_gen_movi_i32(tmp
, 0);
7656 tmp3
= neon_load_reg(rm
, 1);
7657 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, ptr1
, tmp5
);
7658 tcg_temp_free_i32(tmp5
);
7659 tcg_temp_free_ptr(ptr1
);
7660 neon_store_reg(rd
, 0, tmp2
);
7661 neon_store_reg(rd
, 1, tmp3
);
7662 tcg_temp_free_i32(tmp
);
7663 } else if ((insn
& 0x380) == 0) {
7665 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7668 if (insn
& (1 << 19)) {
7669 tmp
= neon_load_reg(rm
, 1);
7671 tmp
= neon_load_reg(rm
, 0);
7673 if (insn
& (1 << 16)) {
7674 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7675 } else if (insn
& (1 << 17)) {
7676 if ((insn
>> 18) & 1)
7677 gen_neon_dup_high16(tmp
);
7679 gen_neon_dup_low16(tmp
);
7681 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7682 tmp2
= tcg_temp_new_i32();
7683 tcg_gen_mov_i32(tmp2
, tmp
);
7684 neon_store_reg(rd
, pass
, tmp2
);
7686 tcg_temp_free_i32(tmp
);
7695 /* Advanced SIMD three registers of the same length extension.
7696 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7697 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7698 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7699 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7701 static int disas_neon_insn_3same_ext(DisasContext
*s
, uint32_t insn
)
7703 gen_helper_gvec_3_ptr
*fn_gvec_ptr
;
7704 int rd
, rn
, rm
, rot
, size
, opr_sz
;
7708 q
= extract32(insn
, 6, 1);
7709 VFP_DREG_D(rd
, insn
);
7710 VFP_DREG_N(rn
, insn
);
7711 VFP_DREG_M(rm
, insn
);
7712 if ((rd
| rn
| rm
) & q
) {
7716 if ((insn
& 0xfe200f10) == 0xfc200800) {
7717 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7718 size
= extract32(insn
, 20, 1);
7719 rot
= extract32(insn
, 23, 2);
7720 if (!arm_dc_feature(s
, ARM_FEATURE_V8_FCMA
)
7721 || (!size
&& !arm_dc_feature(s
, ARM_FEATURE_V8_FP16
))) {
7724 fn_gvec_ptr
= size
? gen_helper_gvec_fcmlas
: gen_helper_gvec_fcmlah
;
7725 } else if ((insn
& 0xfea00f10) == 0xfc800800) {
7726 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7727 size
= extract32(insn
, 20, 1);
7728 rot
= extract32(insn
, 24, 1);
7729 if (!arm_dc_feature(s
, ARM_FEATURE_V8_FCMA
)
7730 || (!size
&& !arm_dc_feature(s
, ARM_FEATURE_V8_FP16
))) {
7733 fn_gvec_ptr
= size
? gen_helper_gvec_fcadds
: gen_helper_gvec_fcaddh
;
7738 if (s
->fp_excp_el
) {
7739 gen_exception_insn(s
, 4, EXCP_UDEF
,
7740 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
7743 if (!s
->vfp_enabled
) {
7747 opr_sz
= (1 + q
) * 8;
7748 fpst
= get_fpstatus_ptr(1);
7749 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
7750 vfp_reg_offset(1, rn
),
7751 vfp_reg_offset(1, rm
), fpst
,
7752 opr_sz
, opr_sz
, rot
, fn_gvec_ptr
);
7753 tcg_temp_free_ptr(fpst
);
7757 /* Advanced SIMD two registers and a scalar extension.
7758 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7759 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7760 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7761 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7765 static int disas_neon_insn_2reg_scalar_ext(DisasContext
*s
, uint32_t insn
)
7767 int rd
, rn
, rm
, rot
, size
, opr_sz
;
7771 q
= extract32(insn
, 6, 1);
7772 VFP_DREG_D(rd
, insn
);
7773 VFP_DREG_N(rn
, insn
);
7774 VFP_DREG_M(rm
, insn
);
7775 if ((rd
| rn
) & q
) {
7779 if ((insn
& 0xff000f10) == 0xfe000800) {
7780 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7781 rot
= extract32(insn
, 20, 2);
7782 size
= extract32(insn
, 23, 1);
7783 if (!arm_dc_feature(s
, ARM_FEATURE_V8_FCMA
)
7784 || (!size
&& !arm_dc_feature(s
, ARM_FEATURE_V8_FP16
))) {
7791 if (s
->fp_excp_el
) {
7792 gen_exception_insn(s
, 4, EXCP_UDEF
,
7793 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
7796 if (!s
->vfp_enabled
) {
7800 opr_sz
= (1 + q
) * 8;
7801 fpst
= get_fpstatus_ptr(1);
7802 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
7803 vfp_reg_offset(1, rn
),
7804 vfp_reg_offset(1, rm
), fpst
,
7805 opr_sz
, opr_sz
, rot
,
7806 size
? gen_helper_gvec_fcmlas_idx
7807 : gen_helper_gvec_fcmlah_idx
);
7808 tcg_temp_free_ptr(fpst
);
7812 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7814 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7815 const ARMCPRegInfo
*ri
;
7817 cpnum
= (insn
>> 8) & 0xf;
7819 /* First check for coprocessor space used for XScale/iwMMXt insns */
7820 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7821 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7824 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7825 return disas_iwmmxt_insn(s
, insn
);
7826 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7827 return disas_dsp_insn(s
, insn
);
7832 /* Otherwise treat as a generic register access */
7833 is64
= (insn
& (1 << 25)) == 0;
7834 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7842 opc1
= (insn
>> 4) & 0xf;
7844 rt2
= (insn
>> 16) & 0xf;
7846 crn
= (insn
>> 16) & 0xf;
7847 opc1
= (insn
>> 21) & 7;
7848 opc2
= (insn
>> 5) & 7;
7851 isread
= (insn
>> 20) & 1;
7852 rt
= (insn
>> 12) & 0xf;
7854 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7855 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7857 /* Check access permissions */
7858 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7863 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7864 /* Emit code to perform further access permissions checks at
7865 * runtime; this may result in an exception.
7866 * Note that on XScale all cp0..c13 registers do an access check
7867 * call in order to handle c15_cpar.
7870 TCGv_i32 tcg_syn
, tcg_isread
;
7873 /* Note that since we are an implementation which takes an
7874 * exception on a trapped conditional instruction only if the
7875 * instruction passes its condition code check, we can take
7876 * advantage of the clause in the ARM ARM that allows us to set
7877 * the COND field in the instruction to 0xE in all cases.
7878 * We could fish the actual condition out of the insn (ARM)
7879 * or the condexec bits (Thumb) but it isn't necessary.
7884 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7887 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7893 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7896 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7901 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7902 * so this can only happen if this is an ARMv7 or earlier CPU,
7903 * in which case the syndrome information won't actually be
7906 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7907 syndrome
= syn_uncategorized();
7911 gen_set_condexec(s
);
7912 gen_set_pc_im(s
, s
->pc
- 4);
7913 tmpptr
= tcg_const_ptr(ri
);
7914 tcg_syn
= tcg_const_i32(syndrome
);
7915 tcg_isread
= tcg_const_i32(isread
);
7916 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7918 tcg_temp_free_ptr(tmpptr
);
7919 tcg_temp_free_i32(tcg_syn
);
7920 tcg_temp_free_i32(tcg_isread
);
7923 /* Handle special cases first */
7924 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7931 gen_set_pc_im(s
, s
->pc
);
7932 s
->base
.is_jmp
= DISAS_WFI
;
7938 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7947 if (ri
->type
& ARM_CP_CONST
) {
7948 tmp64
= tcg_const_i64(ri
->resetvalue
);
7949 } else if (ri
->readfn
) {
7951 tmp64
= tcg_temp_new_i64();
7952 tmpptr
= tcg_const_ptr(ri
);
7953 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7954 tcg_temp_free_ptr(tmpptr
);
7956 tmp64
= tcg_temp_new_i64();
7957 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7959 tmp
= tcg_temp_new_i32();
7960 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7961 store_reg(s
, rt
, tmp
);
7962 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7963 tmp
= tcg_temp_new_i32();
7964 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7965 tcg_temp_free_i64(tmp64
);
7966 store_reg(s
, rt2
, tmp
);
7969 if (ri
->type
& ARM_CP_CONST
) {
7970 tmp
= tcg_const_i32(ri
->resetvalue
);
7971 } else if (ri
->readfn
) {
7973 tmp
= tcg_temp_new_i32();
7974 tmpptr
= tcg_const_ptr(ri
);
7975 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7976 tcg_temp_free_ptr(tmpptr
);
7978 tmp
= load_cpu_offset(ri
->fieldoffset
);
7981 /* Destination register of r15 for 32 bit loads sets
7982 * the condition codes from the high 4 bits of the value
7985 tcg_temp_free_i32(tmp
);
7987 store_reg(s
, rt
, tmp
);
7992 if (ri
->type
& ARM_CP_CONST
) {
7993 /* If not forbidden by access permissions, treat as WI */
7998 TCGv_i32 tmplo
, tmphi
;
7999 TCGv_i64 tmp64
= tcg_temp_new_i64();
8000 tmplo
= load_reg(s
, rt
);
8001 tmphi
= load_reg(s
, rt2
);
8002 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
8003 tcg_temp_free_i32(tmplo
);
8004 tcg_temp_free_i32(tmphi
);
8006 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
8007 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
8008 tcg_temp_free_ptr(tmpptr
);
8010 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
8012 tcg_temp_free_i64(tmp64
);
8017 tmp
= load_reg(s
, rt
);
8018 tmpptr
= tcg_const_ptr(ri
);
8019 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
8020 tcg_temp_free_ptr(tmpptr
);
8021 tcg_temp_free_i32(tmp
);
8023 TCGv_i32 tmp
= load_reg(s
, rt
);
8024 store_cpu_offset(tmp
, ri
->fieldoffset
);
8029 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
8030 /* I/O operations must end the TB here (whether read or write) */
8033 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
8034 /* We default to ending the TB on a coprocessor register write,
8035 * but allow this to be suppressed by the register definition
8036 * (usually only necessary to work around guest bugs).
8044 /* Unknown register; this might be a guest error or a QEMU
8045 * unimplemented feature.
8048 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8049 "64 bit system register cp:%d opc1: %d crm:%d "
8051 isread
? "read" : "write", cpnum
, opc1
, crm
,
8052 s
->ns
? "non-secure" : "secure");
8054 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8055 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8057 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
8058 s
->ns
? "non-secure" : "secure");
8065 /* Store a 64-bit value to a register pair. Clobbers val. */
8066 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
8069 tmp
= tcg_temp_new_i32();
8070 tcg_gen_extrl_i64_i32(tmp
, val
);
8071 store_reg(s
, rlow
, tmp
);
8072 tmp
= tcg_temp_new_i32();
8073 tcg_gen_shri_i64(val
, val
, 32);
8074 tcg_gen_extrl_i64_i32(tmp
, val
);
8075 store_reg(s
, rhigh
, tmp
);
8078 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8079 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
8084 /* Load value and extend to 64 bits. */
8085 tmp
= tcg_temp_new_i64();
8086 tmp2
= load_reg(s
, rlow
);
8087 tcg_gen_extu_i32_i64(tmp
, tmp2
);
8088 tcg_temp_free_i32(tmp2
);
8089 tcg_gen_add_i64(val
, val
, tmp
);
8090 tcg_temp_free_i64(tmp
);
8093 /* load and add a 64-bit value from a register pair. */
8094 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
8100 /* Load 64-bit value rd:rn. */
8101 tmpl
= load_reg(s
, rlow
);
8102 tmph
= load_reg(s
, rhigh
);
8103 tmp
= tcg_temp_new_i64();
8104 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
8105 tcg_temp_free_i32(tmpl
);
8106 tcg_temp_free_i32(tmph
);
8107 tcg_gen_add_i64(val
, val
, tmp
);
8108 tcg_temp_free_i64(tmp
);
8111 /* Set N and Z flags from hi|lo. */
8112 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
8114 tcg_gen_mov_i32(cpu_NF
, hi
);
8115 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
8118 /* Load/Store exclusive instructions are implemented by remembering
8119 the value/address loaded, and seeing if these are the same
8120 when the store is performed. This should be sufficient to implement
8121 the architecturally mandated semantics, and avoids having to monitor
8122 regular stores. The compare vs the remembered value is done during
8123 the cmpxchg operation, but we must compare the addresses manually. */
8124 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
8125 TCGv_i32 addr
, int size
)
8127 TCGv_i32 tmp
= tcg_temp_new_i32();
8128 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8133 TCGv_i32 tmp2
= tcg_temp_new_i32();
8134 TCGv_i64 t64
= tcg_temp_new_i64();
8136 /* For AArch32, architecturally the 32-bit word at the lowest
8137 * address is always Rt and the one at addr+4 is Rt2, even if
8138 * the CPU is big-endian. That means we don't want to do a
8139 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8140 * for an architecturally 64-bit access, but instead do a
8141 * 64-bit access using MO_BE if appropriate and then split
8143 * This only makes a difference for BE32 user-mode, where
8144 * frob64() must not flip the two halves of the 64-bit data
8145 * but this code must treat BE32 user-mode like BE32 system.
8147 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
8149 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
8150 tcg_temp_free(taddr
);
8151 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
8152 if (s
->be_data
== MO_BE
) {
8153 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
8155 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
8157 tcg_temp_free_i64(t64
);
8159 store_reg(s
, rt2
, tmp2
);
8161 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
8162 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
8165 store_reg(s
, rt
, tmp
);
8166 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
8169 static void gen_clrex(DisasContext
*s
)
8171 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8174 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
8175 TCGv_i32 addr
, int size
)
8177 TCGv_i32 t0
, t1
, t2
;
8180 TCGLabel
*done_label
;
8181 TCGLabel
*fail_label
;
8182 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8184 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8190 fail_label
= gen_new_label();
8191 done_label
= gen_new_label();
8192 extaddr
= tcg_temp_new_i64();
8193 tcg_gen_extu_i32_i64(extaddr
, addr
);
8194 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
8195 tcg_temp_free_i64(extaddr
);
8197 taddr
= gen_aa32_addr(s
, addr
, opc
);
8198 t0
= tcg_temp_new_i32();
8199 t1
= load_reg(s
, rt
);
8201 TCGv_i64 o64
= tcg_temp_new_i64();
8202 TCGv_i64 n64
= tcg_temp_new_i64();
8204 t2
= load_reg(s
, rt2
);
8205 /* For AArch32, architecturally the 32-bit word at the lowest
8206 * address is always Rt and the one at addr+4 is Rt2, even if
8207 * the CPU is big-endian. Since we're going to treat this as a
8208 * single 64-bit BE store, we need to put the two halves in the
8209 * opposite order for BE to LE, so that they end up in the right
8211 * We don't want gen_aa32_frob64() because that does the wrong
8212 * thing for BE32 usermode.
8214 if (s
->be_data
== MO_BE
) {
8215 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
8217 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
8219 tcg_temp_free_i32(t2
);
8221 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
8222 get_mem_index(s
), opc
);
8223 tcg_temp_free_i64(n64
);
8225 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
8226 tcg_gen_extrl_i64_i32(t0
, o64
);
8228 tcg_temp_free_i64(o64
);
8230 t2
= tcg_temp_new_i32();
8231 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
8232 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
8233 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
8234 tcg_temp_free_i32(t2
);
8236 tcg_temp_free_i32(t1
);
8237 tcg_temp_free(taddr
);
8238 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
8239 tcg_temp_free_i32(t0
);
8240 tcg_gen_br(done_label
);
8242 gen_set_label(fail_label
);
8243 tcg_gen_movi_i32(cpu_R
[rd
], 1);
8244 gen_set_label(done_label
);
8245 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8251 * @mode: mode field from insn (which stack to store to)
8252 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8253 * @writeback: true if writeback bit set
8255 * Generate code for the SRS (Store Return State) insn.
8257 static void gen_srs(DisasContext
*s
,
8258 uint32_t mode
, uint32_t amode
, bool writeback
)
8265 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8266 * and specified mode is monitor mode
8267 * - UNDEFINED in Hyp mode
8268 * - UNPREDICTABLE in User or System mode
8269 * - UNPREDICTABLE if the specified mode is:
8270 * -- not implemented
8271 * -- not a valid mode number
8272 * -- a mode that's at a higher exception level
8273 * -- Monitor, if we are Non-secure
8274 * For the UNPREDICTABLE cases we choose to UNDEF.
8276 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
8277 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
8281 if (s
->current_el
== 0 || s
->current_el
== 2) {
8286 case ARM_CPU_MODE_USR
:
8287 case ARM_CPU_MODE_FIQ
:
8288 case ARM_CPU_MODE_IRQ
:
8289 case ARM_CPU_MODE_SVC
:
8290 case ARM_CPU_MODE_ABT
:
8291 case ARM_CPU_MODE_UND
:
8292 case ARM_CPU_MODE_SYS
:
8294 case ARM_CPU_MODE_HYP
:
8295 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
8299 case ARM_CPU_MODE_MON
:
8300 /* No need to check specifically for "are we non-secure" because
8301 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8302 * so if this isn't EL3 then we must be non-secure.
8304 if (s
->current_el
!= 3) {
8313 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8314 default_exception_el(s
));
8318 addr
= tcg_temp_new_i32();
8319 tmp
= tcg_const_i32(mode
);
8320 /* get_r13_banked() will raise an exception if called from System mode */
8321 gen_set_condexec(s
);
8322 gen_set_pc_im(s
, s
->pc
- 4);
8323 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8324 tcg_temp_free_i32(tmp
);
8341 tcg_gen_addi_i32(addr
, addr
, offset
);
8342 tmp
= load_reg(s
, 14);
8343 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8344 tcg_temp_free_i32(tmp
);
8345 tmp
= load_cpu_field(spsr
);
8346 tcg_gen_addi_i32(addr
, addr
, 4);
8347 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8348 tcg_temp_free_i32(tmp
);
8366 tcg_gen_addi_i32(addr
, addr
, offset
);
8367 tmp
= tcg_const_i32(mode
);
8368 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8369 tcg_temp_free_i32(tmp
);
8371 tcg_temp_free_i32(addr
);
8372 s
->base
.is_jmp
= DISAS_UPDATE
;
8375 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8377 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8384 /* M variants do not implement ARM mode; this must raise the INVSTATE
8385 * UsageFault exception.
8387 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8388 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8389 default_exception_el(s
));
8394 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8395 * choose to UNDEF. In ARMv5 and above the space is used
8396 * for miscellaneous unconditional instructions.
8400 /* Unconditional instructions. */
8401 if (((insn
>> 25) & 7) == 1) {
8402 /* NEON Data processing. */
8403 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8407 if (disas_neon_data_insn(s
, insn
)) {
8412 if ((insn
& 0x0f100000) == 0x04000000) {
8413 /* NEON load/store. */
8414 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8418 if (disas_neon_ls_insn(s
, insn
)) {
8423 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8425 if (disas_vfp_insn(s
, insn
)) {
8430 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8431 ((insn
& 0x0f30f010) == 0x0710f000)) {
8432 if ((insn
& (1 << 22)) == 0) {
8434 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8438 /* Otherwise PLD; v5TE+ */
8442 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8443 ((insn
& 0x0f70f010) == 0x0650f000)) {
8445 return; /* PLI; V7 */
8447 if (((insn
& 0x0f700000) == 0x04100000) ||
8448 ((insn
& 0x0f700010) == 0x06100000)) {
8449 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8452 return; /* v7MP: Unallocated memory hint: must NOP */
8455 if ((insn
& 0x0ffffdff) == 0x01010000) {
8458 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8459 gen_helper_setend(cpu_env
);
8460 s
->base
.is_jmp
= DISAS_UPDATE
;
8463 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8464 switch ((insn
>> 4) & 0xf) {
8472 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8475 /* We need to break the TB after this insn to execute
8476 * self-modifying code correctly and also to take
8477 * any pending interrupts immediately.
8479 gen_goto_tb(s
, 0, s
->pc
& ~1);
8484 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8487 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8489 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8495 rn
= (insn
>> 16) & 0xf;
8496 addr
= load_reg(s
, rn
);
8497 i
= (insn
>> 23) & 3;
8499 case 0: offset
= -4; break; /* DA */
8500 case 1: offset
= 0; break; /* IA */
8501 case 2: offset
= -8; break; /* DB */
8502 case 3: offset
= 4; break; /* IB */
8506 tcg_gen_addi_i32(addr
, addr
, offset
);
8507 /* Load PC into tmp and CPSR into tmp2. */
8508 tmp
= tcg_temp_new_i32();
8509 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8510 tcg_gen_addi_i32(addr
, addr
, 4);
8511 tmp2
= tcg_temp_new_i32();
8512 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8513 if (insn
& (1 << 21)) {
8514 /* Base writeback. */
8516 case 0: offset
= -8; break;
8517 case 1: offset
= 4; break;
8518 case 2: offset
= -4; break;
8519 case 3: offset
= 0; break;
8523 tcg_gen_addi_i32(addr
, addr
, offset
);
8524 store_reg(s
, rn
, addr
);
8526 tcg_temp_free_i32(addr
);
8528 gen_rfe(s
, tmp
, tmp2
);
8530 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8531 /* branch link and change to thumb (blx <offset>) */
8534 val
= (uint32_t)s
->pc
;
8535 tmp
= tcg_temp_new_i32();
8536 tcg_gen_movi_i32(tmp
, val
);
8537 store_reg(s
, 14, tmp
);
8538 /* Sign-extend the 24-bit offset */
8539 offset
= (((int32_t)insn
) << 8) >> 8;
8540 /* offset * 4 + bit24 * 2 + (thumb bit) */
8541 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8542 /* pipeline offset */
8544 /* protected by ARCH(5); above, near the start of uncond block */
8547 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8548 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8549 /* iWMMXt register transfer. */
8550 if (extract32(s
->c15_cpar
, 1, 1)) {
8551 if (!disas_iwmmxt_insn(s
, insn
)) {
8556 } else if ((insn
& 0x0e000a00) == 0x0c000800
8557 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8558 if (disas_neon_insn_3same_ext(s
, insn
)) {
8562 } else if ((insn
& 0x0f000a00) == 0x0e000800
8563 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8564 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
8568 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8569 /* Coprocessor double register transfer. */
8571 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8572 /* Additional coprocessor register transfer. */
8573 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8576 /* cps (privileged) */
8580 if (insn
& (1 << 19)) {
8581 if (insn
& (1 << 8))
8583 if (insn
& (1 << 7))
8585 if (insn
& (1 << 6))
8587 if (insn
& (1 << 18))
8590 if (insn
& (1 << 17)) {
8592 val
|= (insn
& 0x1f);
8595 gen_set_psr_im(s
, mask
, 0, val
);
8602 /* if not always execute, we generate a conditional jump to
8604 s
->condlabel
= gen_new_label();
8605 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8608 if ((insn
& 0x0f900000) == 0x03000000) {
8609 if ((insn
& (1 << 21)) == 0) {
8611 rd
= (insn
>> 12) & 0xf;
8612 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8613 if ((insn
& (1 << 22)) == 0) {
8615 tmp
= tcg_temp_new_i32();
8616 tcg_gen_movi_i32(tmp
, val
);
8619 tmp
= load_reg(s
, rd
);
8620 tcg_gen_ext16u_i32(tmp
, tmp
);
8621 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8623 store_reg(s
, rd
, tmp
);
8625 if (((insn
>> 12) & 0xf) != 0xf)
8627 if (((insn
>> 16) & 0xf) == 0) {
8628 gen_nop_hint(s
, insn
& 0xff);
8630 /* CPSR = immediate */
8632 shift
= ((insn
>> 8) & 0xf) * 2;
8634 val
= (val
>> shift
) | (val
<< (32 - shift
));
8635 i
= ((insn
& (1 << 22)) != 0);
8636 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8642 } else if ((insn
& 0x0f900000) == 0x01000000
8643 && (insn
& 0x00000090) != 0x00000090) {
8644 /* miscellaneous instructions */
8645 op1
= (insn
>> 21) & 3;
8646 sh
= (insn
>> 4) & 0xf;
8649 case 0x0: /* MSR, MRS */
8650 if (insn
& (1 << 9)) {
8651 /* MSR (banked) and MRS (banked) */
8652 int sysm
= extract32(insn
, 16, 4) |
8653 (extract32(insn
, 8, 1) << 4);
8654 int r
= extract32(insn
, 22, 1);
8658 gen_msr_banked(s
, r
, sysm
, rm
);
8661 int rd
= extract32(insn
, 12, 4);
8663 gen_mrs_banked(s
, r
, sysm
, rd
);
8668 /* MSR, MRS (for PSRs) */
8671 tmp
= load_reg(s
, rm
);
8672 i
= ((op1
& 2) != 0);
8673 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8677 rd
= (insn
>> 12) & 0xf;
8681 tmp
= load_cpu_field(spsr
);
8683 tmp
= tcg_temp_new_i32();
8684 gen_helper_cpsr_read(tmp
, cpu_env
);
8686 store_reg(s
, rd
, tmp
);
8691 /* branch/exchange thumb (bx). */
8693 tmp
= load_reg(s
, rm
);
8695 } else if (op1
== 3) {
8698 rd
= (insn
>> 12) & 0xf;
8699 tmp
= load_reg(s
, rm
);
8700 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8701 store_reg(s
, rd
, tmp
);
8709 /* Trivial implementation equivalent to bx. */
8710 tmp
= load_reg(s
, rm
);
8721 /* branch link/exchange thumb (blx) */
8722 tmp
= load_reg(s
, rm
);
8723 tmp2
= tcg_temp_new_i32();
8724 tcg_gen_movi_i32(tmp2
, s
->pc
);
8725 store_reg(s
, 14, tmp2
);
8731 uint32_t c
= extract32(insn
, 8, 4);
8733 /* Check this CPU supports ARMv8 CRC instructions.
8734 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8735 * Bits 8, 10 and 11 should be zero.
8737 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8742 rn
= extract32(insn
, 16, 4);
8743 rd
= extract32(insn
, 12, 4);
8745 tmp
= load_reg(s
, rn
);
8746 tmp2
= load_reg(s
, rm
);
8748 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8749 } else if (op1
== 1) {
8750 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8752 tmp3
= tcg_const_i32(1 << op1
);
8754 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8756 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8758 tcg_temp_free_i32(tmp2
);
8759 tcg_temp_free_i32(tmp3
);
8760 store_reg(s
, rd
, tmp
);
8763 case 0x5: /* saturating add/subtract */
8765 rd
= (insn
>> 12) & 0xf;
8766 rn
= (insn
>> 16) & 0xf;
8767 tmp
= load_reg(s
, rm
);
8768 tmp2
= load_reg(s
, rn
);
8770 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8772 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8774 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8775 tcg_temp_free_i32(tmp2
);
8776 store_reg(s
, rd
, tmp
);
8780 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8789 gen_exception_bkpt_insn(s
, 4, syn_aa32_bkpt(imm16
, false));
8792 /* Hypervisor call (v7) */
8800 /* Secure monitor call (v6+) */
8808 g_assert_not_reached();
8812 case 0x8: /* signed multiply */
8817 rs
= (insn
>> 8) & 0xf;
8818 rn
= (insn
>> 12) & 0xf;
8819 rd
= (insn
>> 16) & 0xf;
8821 /* (32 * 16) >> 16 */
8822 tmp
= load_reg(s
, rm
);
8823 tmp2
= load_reg(s
, rs
);
8825 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8828 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8829 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8830 tmp
= tcg_temp_new_i32();
8831 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8832 tcg_temp_free_i64(tmp64
);
8833 if ((sh
& 2) == 0) {
8834 tmp2
= load_reg(s
, rn
);
8835 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8836 tcg_temp_free_i32(tmp2
);
8838 store_reg(s
, rd
, tmp
);
8841 tmp
= load_reg(s
, rm
);
8842 tmp2
= load_reg(s
, rs
);
8843 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8844 tcg_temp_free_i32(tmp2
);
8846 tmp64
= tcg_temp_new_i64();
8847 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8848 tcg_temp_free_i32(tmp
);
8849 gen_addq(s
, tmp64
, rn
, rd
);
8850 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8851 tcg_temp_free_i64(tmp64
);
8854 tmp2
= load_reg(s
, rn
);
8855 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8856 tcg_temp_free_i32(tmp2
);
8858 store_reg(s
, rd
, tmp
);
8865 } else if (((insn
& 0x0e000000) == 0 &&
8866 (insn
& 0x00000090) != 0x90) ||
8867 ((insn
& 0x0e000000) == (1 << 25))) {
8868 int set_cc
, logic_cc
, shiftop
;
8870 op1
= (insn
>> 21) & 0xf;
8871 set_cc
= (insn
>> 20) & 1;
8872 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8874 /* data processing instruction */
8875 if (insn
& (1 << 25)) {
8876 /* immediate operand */
8878 shift
= ((insn
>> 8) & 0xf) * 2;
8880 val
= (val
>> shift
) | (val
<< (32 - shift
));
8882 tmp2
= tcg_temp_new_i32();
8883 tcg_gen_movi_i32(tmp2
, val
);
8884 if (logic_cc
&& shift
) {
8885 gen_set_CF_bit31(tmp2
);
8890 tmp2
= load_reg(s
, rm
);
8891 shiftop
= (insn
>> 5) & 3;
8892 if (!(insn
& (1 << 4))) {
8893 shift
= (insn
>> 7) & 0x1f;
8894 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8896 rs
= (insn
>> 8) & 0xf;
8897 tmp
= load_reg(s
, rs
);
8898 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8901 if (op1
!= 0x0f && op1
!= 0x0d) {
8902 rn
= (insn
>> 16) & 0xf;
8903 tmp
= load_reg(s
, rn
);
8907 rd
= (insn
>> 12) & 0xf;
8910 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8914 store_reg_bx(s
, rd
, tmp
);
8917 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8921 store_reg_bx(s
, rd
, tmp
);
8924 if (set_cc
&& rd
== 15) {
8925 /* SUBS r15, ... is used for exception return. */
8929 gen_sub_CC(tmp
, tmp
, tmp2
);
8930 gen_exception_return(s
, tmp
);
8933 gen_sub_CC(tmp
, tmp
, tmp2
);
8935 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8937 store_reg_bx(s
, rd
, tmp
);
8942 gen_sub_CC(tmp
, tmp2
, tmp
);
8944 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8946 store_reg_bx(s
, rd
, tmp
);
8950 gen_add_CC(tmp
, tmp
, tmp2
);
8952 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8954 store_reg_bx(s
, rd
, tmp
);
8958 gen_adc_CC(tmp
, tmp
, tmp2
);
8960 gen_add_carry(tmp
, tmp
, tmp2
);
8962 store_reg_bx(s
, rd
, tmp
);
8966 gen_sbc_CC(tmp
, tmp
, tmp2
);
8968 gen_sub_carry(tmp
, tmp
, tmp2
);
8970 store_reg_bx(s
, rd
, tmp
);
8974 gen_sbc_CC(tmp
, tmp2
, tmp
);
8976 gen_sub_carry(tmp
, tmp2
, tmp
);
8978 store_reg_bx(s
, rd
, tmp
);
8982 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8985 tcg_temp_free_i32(tmp
);
8989 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8992 tcg_temp_free_i32(tmp
);
8996 gen_sub_CC(tmp
, tmp
, tmp2
);
8998 tcg_temp_free_i32(tmp
);
9002 gen_add_CC(tmp
, tmp
, tmp2
);
9004 tcg_temp_free_i32(tmp
);
9007 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9011 store_reg_bx(s
, rd
, tmp
);
9014 if (logic_cc
&& rd
== 15) {
9015 /* MOVS r15, ... is used for exception return. */
9019 gen_exception_return(s
, tmp2
);
9024 store_reg_bx(s
, rd
, tmp2
);
9028 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9032 store_reg_bx(s
, rd
, tmp
);
9036 tcg_gen_not_i32(tmp2
, tmp2
);
9040 store_reg_bx(s
, rd
, tmp2
);
9043 if (op1
!= 0x0f && op1
!= 0x0d) {
9044 tcg_temp_free_i32(tmp2
);
9047 /* other instructions */
9048 op1
= (insn
>> 24) & 0xf;
9052 /* multiplies, extra load/stores */
9053 sh
= (insn
>> 5) & 3;
9056 rd
= (insn
>> 16) & 0xf;
9057 rn
= (insn
>> 12) & 0xf;
9058 rs
= (insn
>> 8) & 0xf;
9060 op1
= (insn
>> 20) & 0xf;
9062 case 0: case 1: case 2: case 3: case 6:
9064 tmp
= load_reg(s
, rs
);
9065 tmp2
= load_reg(s
, rm
);
9066 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9067 tcg_temp_free_i32(tmp2
);
9068 if (insn
& (1 << 22)) {
9069 /* Subtract (mls) */
9071 tmp2
= load_reg(s
, rn
);
9072 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9073 tcg_temp_free_i32(tmp2
);
9074 } else if (insn
& (1 << 21)) {
9076 tmp2
= load_reg(s
, rn
);
9077 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9078 tcg_temp_free_i32(tmp2
);
9080 if (insn
& (1 << 20))
9082 store_reg(s
, rd
, tmp
);
9085 /* 64 bit mul double accumulate (UMAAL) */
9087 tmp
= load_reg(s
, rs
);
9088 tmp2
= load_reg(s
, rm
);
9089 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9090 gen_addq_lo(s
, tmp64
, rn
);
9091 gen_addq_lo(s
, tmp64
, rd
);
9092 gen_storeq_reg(s
, rn
, rd
, tmp64
);
9093 tcg_temp_free_i64(tmp64
);
9095 case 8: case 9: case 10: case 11:
9096 case 12: case 13: case 14: case 15:
9097 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9098 tmp
= load_reg(s
, rs
);
9099 tmp2
= load_reg(s
, rm
);
9100 if (insn
& (1 << 22)) {
9101 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
9103 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
9105 if (insn
& (1 << 21)) { /* mult accumulate */
9106 TCGv_i32 al
= load_reg(s
, rn
);
9107 TCGv_i32 ah
= load_reg(s
, rd
);
9108 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
9109 tcg_temp_free_i32(al
);
9110 tcg_temp_free_i32(ah
);
9112 if (insn
& (1 << 20)) {
9113 gen_logicq_cc(tmp
, tmp2
);
9115 store_reg(s
, rn
, tmp
);
9116 store_reg(s
, rd
, tmp2
);
9122 rn
= (insn
>> 16) & 0xf;
9123 rd
= (insn
>> 12) & 0xf;
9124 if (insn
& (1 << 23)) {
9125 /* load/store exclusive */
9126 int op2
= (insn
>> 8) & 3;
9127 op1
= (insn
>> 21) & 0x3;
9130 case 0: /* lda/stl */
9136 case 1: /* reserved */
9138 case 2: /* ldaex/stlex */
9141 case 3: /* ldrex/strex */
9150 addr
= tcg_temp_local_new_i32();
9151 load_reg_var(s
, addr
, rn
);
9153 /* Since the emulation does not have barriers,
9154 the acquire/release semantics need no special
9157 if (insn
& (1 << 20)) {
9158 tmp
= tcg_temp_new_i32();
9161 gen_aa32_ld32u_iss(s
, tmp
, addr
,
9166 gen_aa32_ld8u_iss(s
, tmp
, addr
,
9171 gen_aa32_ld16u_iss(s
, tmp
, addr
,
9178 store_reg(s
, rd
, tmp
);
9181 tmp
= load_reg(s
, rm
);
9184 gen_aa32_st32_iss(s
, tmp
, addr
,
9189 gen_aa32_st8_iss(s
, tmp
, addr
,
9194 gen_aa32_st16_iss(s
, tmp
, addr
,
9201 tcg_temp_free_i32(tmp
);
9203 } else if (insn
& (1 << 20)) {
9206 gen_load_exclusive(s
, rd
, 15, addr
, 2);
9208 case 1: /* ldrexd */
9209 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
9211 case 2: /* ldrexb */
9212 gen_load_exclusive(s
, rd
, 15, addr
, 0);
9214 case 3: /* ldrexh */
9215 gen_load_exclusive(s
, rd
, 15, addr
, 1);
9224 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
9226 case 1: /* strexd */
9227 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
9229 case 2: /* strexb */
9230 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
9232 case 3: /* strexh */
9233 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
9239 tcg_temp_free_i32(addr
);
9242 TCGMemOp opc
= s
->be_data
;
9244 /* SWP instruction */
9247 if (insn
& (1 << 22)) {
9250 opc
|= MO_UL
| MO_ALIGN
;
9253 addr
= load_reg(s
, rn
);
9254 taddr
= gen_aa32_addr(s
, addr
, opc
);
9255 tcg_temp_free_i32(addr
);
9257 tmp
= load_reg(s
, rm
);
9258 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
9259 get_mem_index(s
), opc
);
9260 tcg_temp_free(taddr
);
9261 store_reg(s
, rd
, tmp
);
9266 bool load
= insn
& (1 << 20);
9267 bool wbit
= insn
& (1 << 21);
9268 bool pbit
= insn
& (1 << 24);
9269 bool doubleword
= false;
9272 /* Misc load/store */
9273 rn
= (insn
>> 16) & 0xf;
9274 rd
= (insn
>> 12) & 0xf;
9276 /* ISS not valid if writeback */
9277 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
9279 if (!load
&& (sh
& 2)) {
9283 /* UNPREDICTABLE; we choose to UNDEF */
9286 load
= (sh
& 1) == 0;
9290 addr
= load_reg(s
, rn
);
9292 gen_add_datah_offset(s
, insn
, 0, addr
);
9299 tmp
= load_reg(s
, rd
);
9300 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9301 tcg_temp_free_i32(tmp
);
9302 tcg_gen_addi_i32(addr
, addr
, 4);
9303 tmp
= load_reg(s
, rd
+ 1);
9304 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9305 tcg_temp_free_i32(tmp
);
9308 tmp
= tcg_temp_new_i32();
9309 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9310 store_reg(s
, rd
, tmp
);
9311 tcg_gen_addi_i32(addr
, addr
, 4);
9312 tmp
= tcg_temp_new_i32();
9313 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9316 address_offset
= -4;
9319 tmp
= tcg_temp_new_i32();
9322 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9326 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9331 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9337 tmp
= load_reg(s
, rd
);
9338 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9339 tcg_temp_free_i32(tmp
);
9341 /* Perform base writeback before the loaded value to
9342 ensure correct behavior with overlapping index registers.
9343 ldrd with base writeback is undefined if the
9344 destination and index registers overlap. */
9346 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9347 store_reg(s
, rn
, addr
);
9350 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9351 store_reg(s
, rn
, addr
);
9353 tcg_temp_free_i32(addr
);
9356 /* Complete the load. */
9357 store_reg(s
, rd
, tmp
);
9366 if (insn
& (1 << 4)) {
9368 /* Armv6 Media instructions. */
9370 rn
= (insn
>> 16) & 0xf;
9371 rd
= (insn
>> 12) & 0xf;
9372 rs
= (insn
>> 8) & 0xf;
9373 switch ((insn
>> 23) & 3) {
9374 case 0: /* Parallel add/subtract. */
9375 op1
= (insn
>> 20) & 7;
9376 tmp
= load_reg(s
, rn
);
9377 tmp2
= load_reg(s
, rm
);
9378 sh
= (insn
>> 5) & 7;
9379 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9381 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9382 tcg_temp_free_i32(tmp2
);
9383 store_reg(s
, rd
, tmp
);
9386 if ((insn
& 0x00700020) == 0) {
9387 /* Halfword pack. */
9388 tmp
= load_reg(s
, rn
);
9389 tmp2
= load_reg(s
, rm
);
9390 shift
= (insn
>> 7) & 0x1f;
9391 if (insn
& (1 << 6)) {
9395 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9396 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9397 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9401 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9402 tcg_gen_ext16u_i32(tmp
, tmp
);
9403 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9405 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9406 tcg_temp_free_i32(tmp2
);
9407 store_reg(s
, rd
, tmp
);
9408 } else if ((insn
& 0x00200020) == 0x00200000) {
9410 tmp
= load_reg(s
, rm
);
9411 shift
= (insn
>> 7) & 0x1f;
9412 if (insn
& (1 << 6)) {
9415 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9417 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9419 sh
= (insn
>> 16) & 0x1f;
9420 tmp2
= tcg_const_i32(sh
);
9421 if (insn
& (1 << 22))
9422 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9424 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9425 tcg_temp_free_i32(tmp2
);
9426 store_reg(s
, rd
, tmp
);
9427 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9429 tmp
= load_reg(s
, rm
);
9430 sh
= (insn
>> 16) & 0x1f;
9431 tmp2
= tcg_const_i32(sh
);
9432 if (insn
& (1 << 22))
9433 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9435 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9436 tcg_temp_free_i32(tmp2
);
9437 store_reg(s
, rd
, tmp
);
9438 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9440 tmp
= load_reg(s
, rn
);
9441 tmp2
= load_reg(s
, rm
);
9442 tmp3
= tcg_temp_new_i32();
9443 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9444 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9445 tcg_temp_free_i32(tmp3
);
9446 tcg_temp_free_i32(tmp2
);
9447 store_reg(s
, rd
, tmp
);
9448 } else if ((insn
& 0x000003e0) == 0x00000060) {
9449 tmp
= load_reg(s
, rm
);
9450 shift
= (insn
>> 10) & 3;
9451 /* ??? In many cases it's not necessary to do a
9452 rotate, a shift is sufficient. */
9454 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9455 op1
= (insn
>> 20) & 7;
9457 case 0: gen_sxtb16(tmp
); break;
9458 case 2: gen_sxtb(tmp
); break;
9459 case 3: gen_sxth(tmp
); break;
9460 case 4: gen_uxtb16(tmp
); break;
9461 case 6: gen_uxtb(tmp
); break;
9462 case 7: gen_uxth(tmp
); break;
9463 default: goto illegal_op
;
9466 tmp2
= load_reg(s
, rn
);
9467 if ((op1
& 3) == 0) {
9468 gen_add16(tmp
, tmp2
);
9470 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9471 tcg_temp_free_i32(tmp2
);
9474 store_reg(s
, rd
, tmp
);
9475 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9477 tmp
= load_reg(s
, rm
);
9478 if (insn
& (1 << 22)) {
9479 if (insn
& (1 << 7)) {
9483 gen_helper_rbit(tmp
, tmp
);
9486 if (insn
& (1 << 7))
9489 tcg_gen_bswap32_i32(tmp
, tmp
);
9491 store_reg(s
, rd
, tmp
);
9496 case 2: /* Multiplies (Type 3). */
9497 switch ((insn
>> 20) & 0x7) {
9499 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9500 /* op2 not 00x or 11x : UNDEF */
9503 /* Signed multiply most significant [accumulate].
9504 (SMMUL, SMMLA, SMMLS) */
9505 tmp
= load_reg(s
, rm
);
9506 tmp2
= load_reg(s
, rs
);
9507 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9510 tmp
= load_reg(s
, rd
);
9511 if (insn
& (1 << 6)) {
9512 tmp64
= gen_subq_msw(tmp64
, tmp
);
9514 tmp64
= gen_addq_msw(tmp64
, tmp
);
9517 if (insn
& (1 << 5)) {
9518 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9520 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9521 tmp
= tcg_temp_new_i32();
9522 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9523 tcg_temp_free_i64(tmp64
);
9524 store_reg(s
, rn
, tmp
);
9528 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9529 if (insn
& (1 << 7)) {
9532 tmp
= load_reg(s
, rm
);
9533 tmp2
= load_reg(s
, rs
);
9534 if (insn
& (1 << 5))
9535 gen_swap_half(tmp2
);
9536 gen_smul_dual(tmp
, tmp2
);
9537 if (insn
& (1 << 22)) {
9538 /* smlald, smlsld */
9541 tmp64
= tcg_temp_new_i64();
9542 tmp64_2
= tcg_temp_new_i64();
9543 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9544 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9545 tcg_temp_free_i32(tmp
);
9546 tcg_temp_free_i32(tmp2
);
9547 if (insn
& (1 << 6)) {
9548 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9550 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9552 tcg_temp_free_i64(tmp64_2
);
9553 gen_addq(s
, tmp64
, rd
, rn
);
9554 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9555 tcg_temp_free_i64(tmp64
);
9557 /* smuad, smusd, smlad, smlsd */
9558 if (insn
& (1 << 6)) {
9559 /* This subtraction cannot overflow. */
9560 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9562 /* This addition cannot overflow 32 bits;
9563 * however it may overflow considered as a
9564 * signed operation, in which case we must set
9567 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9569 tcg_temp_free_i32(tmp2
);
9572 tmp2
= load_reg(s
, rd
);
9573 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9574 tcg_temp_free_i32(tmp2
);
9576 store_reg(s
, rn
, tmp
);
9582 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9585 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9588 tmp
= load_reg(s
, rm
);
9589 tmp2
= load_reg(s
, rs
);
9590 if (insn
& (1 << 21)) {
9591 gen_helper_udiv(tmp
, tmp
, tmp2
);
9593 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9595 tcg_temp_free_i32(tmp2
);
9596 store_reg(s
, rn
, tmp
);
9603 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9605 case 0: /* Unsigned sum of absolute differences. */
9607 tmp
= load_reg(s
, rm
);
9608 tmp2
= load_reg(s
, rs
);
9609 gen_helper_usad8(tmp
, tmp
, tmp2
);
9610 tcg_temp_free_i32(tmp2
);
9612 tmp2
= load_reg(s
, rd
);
9613 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9614 tcg_temp_free_i32(tmp2
);
9616 store_reg(s
, rn
, tmp
);
9618 case 0x20: case 0x24: case 0x28: case 0x2c:
9619 /* Bitfield insert/clear. */
9621 shift
= (insn
>> 7) & 0x1f;
9622 i
= (insn
>> 16) & 0x1f;
9624 /* UNPREDICTABLE; we choose to UNDEF */
9629 tmp
= tcg_temp_new_i32();
9630 tcg_gen_movi_i32(tmp
, 0);
9632 tmp
= load_reg(s
, rm
);
9635 tmp2
= load_reg(s
, rd
);
9636 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9637 tcg_temp_free_i32(tmp2
);
9639 store_reg(s
, rd
, tmp
);
9641 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9642 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9644 tmp
= load_reg(s
, rm
);
9645 shift
= (insn
>> 7) & 0x1f;
9646 i
= ((insn
>> 16) & 0x1f) + 1;
9651 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9653 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9656 store_reg(s
, rd
, tmp
);
9666 /* Check for undefined extension instructions
9667 * per the ARM Bible IE:
9668 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9670 sh
= (0xf << 20) | (0xf << 4);
9671 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9675 /* load/store byte/word */
9676 rn
= (insn
>> 16) & 0xf;
9677 rd
= (insn
>> 12) & 0xf;
9678 tmp2
= load_reg(s
, rn
);
9679 if ((insn
& 0x01200000) == 0x00200000) {
9681 i
= get_a32_user_mem_index(s
);
9683 i
= get_mem_index(s
);
9685 if (insn
& (1 << 24))
9686 gen_add_data_offset(s
, insn
, tmp2
);
9687 if (insn
& (1 << 20)) {
9689 tmp
= tcg_temp_new_i32();
9690 if (insn
& (1 << 22)) {
9691 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9693 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9697 tmp
= load_reg(s
, rd
);
9698 if (insn
& (1 << 22)) {
9699 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9701 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9703 tcg_temp_free_i32(tmp
);
9705 if (!(insn
& (1 << 24))) {
9706 gen_add_data_offset(s
, insn
, tmp2
);
9707 store_reg(s
, rn
, tmp2
);
9708 } else if (insn
& (1 << 21)) {
9709 store_reg(s
, rn
, tmp2
);
9711 tcg_temp_free_i32(tmp2
);
9713 if (insn
& (1 << 20)) {
9714 /* Complete the load. */
9715 store_reg_from_load(s
, rd
, tmp
);
9721 int j
, n
, loaded_base
;
9722 bool exc_return
= false;
9723 bool is_load
= extract32(insn
, 20, 1);
9725 TCGv_i32 loaded_var
;
9726 /* load/store multiple words */
9727 /* XXX: store correct base if write back */
9728 if (insn
& (1 << 22)) {
9729 /* LDM (user), LDM (exception return) and STM (user) */
9731 goto illegal_op
; /* only usable in supervisor mode */
9733 if (is_load
&& extract32(insn
, 15, 1)) {
9739 rn
= (insn
>> 16) & 0xf;
9740 addr
= load_reg(s
, rn
);
9742 /* compute total size */
9747 if (insn
& (1 << i
))
9750 /* XXX: test invalid n == 0 case ? */
9751 if (insn
& (1 << 23)) {
9752 if (insn
& (1 << 24)) {
9754 tcg_gen_addi_i32(addr
, addr
, 4);
9756 /* post increment */
9759 if (insn
& (1 << 24)) {
9761 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9763 /* post decrement */
9765 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9770 if (insn
& (1 << i
)) {
9773 tmp
= tcg_temp_new_i32();
9774 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9776 tmp2
= tcg_const_i32(i
);
9777 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9778 tcg_temp_free_i32(tmp2
);
9779 tcg_temp_free_i32(tmp
);
9780 } else if (i
== rn
) {
9783 } else if (rn
== 15 && exc_return
) {
9784 store_pc_exc_ret(s
, tmp
);
9786 store_reg_from_load(s
, i
, tmp
);
9791 /* special case: r15 = PC + 8 */
9792 val
= (long)s
->pc
+ 4;
9793 tmp
= tcg_temp_new_i32();
9794 tcg_gen_movi_i32(tmp
, val
);
9796 tmp
= tcg_temp_new_i32();
9797 tmp2
= tcg_const_i32(i
);
9798 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9799 tcg_temp_free_i32(tmp2
);
9801 tmp
= load_reg(s
, i
);
9803 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9804 tcg_temp_free_i32(tmp
);
9807 /* no need to add after the last transfer */
9809 tcg_gen_addi_i32(addr
, addr
, 4);
9812 if (insn
& (1 << 21)) {
9814 if (insn
& (1 << 23)) {
9815 if (insn
& (1 << 24)) {
9818 /* post increment */
9819 tcg_gen_addi_i32(addr
, addr
, 4);
9822 if (insn
& (1 << 24)) {
9825 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9827 /* post decrement */
9828 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9831 store_reg(s
, rn
, addr
);
9833 tcg_temp_free_i32(addr
);
9836 store_reg(s
, rn
, loaded_var
);
9839 /* Restore CPSR from SPSR. */
9840 tmp
= load_cpu_field(spsr
);
9841 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9842 tcg_temp_free_i32(tmp
);
9843 /* Must exit loop to check un-masked IRQs */
9844 s
->base
.is_jmp
= DISAS_EXIT
;
9853 /* branch (and link) */
9854 val
= (int32_t)s
->pc
;
9855 if (insn
& (1 << 24)) {
9856 tmp
= tcg_temp_new_i32();
9857 tcg_gen_movi_i32(tmp
, val
);
9858 store_reg(s
, 14, tmp
);
9860 offset
= sextract32(insn
<< 2, 0, 26);
9868 if (((insn
>> 8) & 0xe) == 10) {
9870 if (disas_vfp_insn(s
, insn
)) {
9873 } else if (disas_coproc_insn(s
, insn
)) {
9880 gen_set_pc_im(s
, s
->pc
);
9881 s
->svc_imm
= extract32(insn
, 0, 24);
9882 s
->base
.is_jmp
= DISAS_SWI
;
9886 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9887 default_exception_el(s
));
9893 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t insn
)
9895 /* Return true if this is a 16 bit instruction. We must be precise
9896 * about this (matching the decode). We assume that s->pc still
9897 * points to the first 16 bits of the insn.
9899 if ((insn
>> 11) < 0x1d) {
9900 /* Definitely a 16-bit instruction */
9904 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9905 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9906 * end up actually treating this as two 16-bit insns, though,
9907 * if it's half of a bl/blx pair that might span a page boundary.
9909 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
9910 /* Thumb2 cores (including all M profile ones) always treat
9911 * 32-bit insns as 32-bit.
9916 if ((insn
>> 11) == 0x1e && (s
->pc
< s
->next_page_start
- 3)) {
9917 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9918 * is not on the next page; we merge this into a 32-bit
9923 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9924 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9925 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9926 * -- handle as single 16 bit insn
9931 /* Return true if this is a Thumb-2 logical op. */
9933 thumb2_logic_op(int op
)
9938 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9939 then set condition code flags based on the result of the operation.
9940 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9941 to the high bit of T1.
9942 Returns zero if the opcode is valid. */
9945 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9946 TCGv_i32 t0
, TCGv_i32 t1
)
9953 tcg_gen_and_i32(t0
, t0
, t1
);
9957 tcg_gen_andc_i32(t0
, t0
, t1
);
9961 tcg_gen_or_i32(t0
, t0
, t1
);
9965 tcg_gen_orc_i32(t0
, t0
, t1
);
9969 tcg_gen_xor_i32(t0
, t0
, t1
);
9974 gen_add_CC(t0
, t0
, t1
);
9976 tcg_gen_add_i32(t0
, t0
, t1
);
9980 gen_adc_CC(t0
, t0
, t1
);
9986 gen_sbc_CC(t0
, t0
, t1
);
9988 gen_sub_carry(t0
, t0
, t1
);
9993 gen_sub_CC(t0
, t0
, t1
);
9995 tcg_gen_sub_i32(t0
, t0
, t1
);
9999 gen_sub_CC(t0
, t1
, t0
);
10001 tcg_gen_sub_i32(t0
, t1
, t0
);
10003 default: /* 5, 6, 7, 9, 12, 15. */
10009 gen_set_CF_bit31(t1
);
10014 /* Translate a 32-bit thumb instruction. */
10015 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
10017 uint32_t imm
, shift
, offset
;
10018 uint32_t rd
, rn
, rm
, rs
;
10029 /* The only 32 bit insn that's allowed for Thumb1 is the combined
10030 * BL/BLX prefix and suffix.
10032 if ((insn
& 0xf800e800) != 0xf000e800) {
10036 rn
= (insn
>> 16) & 0xf;
10037 rs
= (insn
>> 12) & 0xf;
10038 rd
= (insn
>> 8) & 0xf;
10040 switch ((insn
>> 25) & 0xf) {
10041 case 0: case 1: case 2: case 3:
10042 /* 16-bit instructions. Should never happen. */
10045 if (insn
& (1 << 22)) {
10046 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10047 * - load/store doubleword, load/store exclusive, ldacq/strel,
10048 * table branch, TT.
10050 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_M
) &&
10051 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10052 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10054 * The bulk of the behaviour for this instruction is implemented
10055 * in v7m_handle_execute_nsc(), which deals with the insn when
10056 * it is executed by a CPU in non-secure state from memory
10057 * which is Secure & NonSecure-Callable.
10058 * Here we only need to handle the remaining cases:
10059 * * in NS memory (including the "security extension not
10060 * implemented" case) : NOP
10061 * * in S memory but CPU already secure (clear IT bits)
10062 * We know that the attribute for the memory this insn is
10063 * in must match the current CPU state, because otherwise
10064 * get_phys_addr_pmsav8 would have generated an exception.
10066 if (s
->v8m_secure
) {
10067 /* Like the IT insn, we don't need to generate any code */
10068 s
->condexec_cond
= 0;
10069 s
->condexec_mask
= 0;
10071 } else if (insn
& 0x01200000) {
10072 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10073 * - load/store dual (post-indexed)
10074 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10075 * - load/store dual (literal and immediate)
10076 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10077 * - load/store dual (pre-indexed)
10080 if (insn
& (1 << 21)) {
10081 /* UNPREDICTABLE */
10084 addr
= tcg_temp_new_i32();
10085 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
10087 addr
= load_reg(s
, rn
);
10089 offset
= (insn
& 0xff) * 4;
10090 if ((insn
& (1 << 23)) == 0)
10092 if (insn
& (1 << 24)) {
10093 tcg_gen_addi_i32(addr
, addr
, offset
);
10096 if (insn
& (1 << 20)) {
10098 tmp
= tcg_temp_new_i32();
10099 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10100 store_reg(s
, rs
, tmp
);
10101 tcg_gen_addi_i32(addr
, addr
, 4);
10102 tmp
= tcg_temp_new_i32();
10103 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10104 store_reg(s
, rd
, tmp
);
10107 tmp
= load_reg(s
, rs
);
10108 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10109 tcg_temp_free_i32(tmp
);
10110 tcg_gen_addi_i32(addr
, addr
, 4);
10111 tmp
= load_reg(s
, rd
);
10112 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10113 tcg_temp_free_i32(tmp
);
10115 if (insn
& (1 << 21)) {
10116 /* Base writeback. */
10117 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
10118 store_reg(s
, rn
, addr
);
10120 tcg_temp_free_i32(addr
);
10122 } else if ((insn
& (1 << 23)) == 0) {
10123 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10124 * - load/store exclusive word
10128 if (!(insn
& (1 << 20)) &&
10129 arm_dc_feature(s
, ARM_FEATURE_M
) &&
10130 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10131 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10134 bool alt
= insn
& (1 << 7);
10135 TCGv_i32 addr
, op
, ttresp
;
10137 if ((insn
& 0x3f) || rd
== 13 || rd
== 15 || rn
== 15) {
10138 /* we UNDEF for these UNPREDICTABLE cases */
10142 if (alt
&& !s
->v8m_secure
) {
10146 addr
= load_reg(s
, rn
);
10147 op
= tcg_const_i32(extract32(insn
, 6, 2));
10148 ttresp
= tcg_temp_new_i32();
10149 gen_helper_v7m_tt(ttresp
, cpu_env
, addr
, op
);
10150 tcg_temp_free_i32(addr
);
10151 tcg_temp_free_i32(op
);
10152 store_reg(s
, rd
, ttresp
);
10157 addr
= tcg_temp_local_new_i32();
10158 load_reg_var(s
, addr
, rn
);
10159 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
10160 if (insn
& (1 << 20)) {
10161 gen_load_exclusive(s
, rs
, 15, addr
, 2);
10163 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
10165 tcg_temp_free_i32(addr
);
10166 } else if ((insn
& (7 << 5)) == 0) {
10167 /* Table Branch. */
10169 addr
= tcg_temp_new_i32();
10170 tcg_gen_movi_i32(addr
, s
->pc
);
10172 addr
= load_reg(s
, rn
);
10174 tmp
= load_reg(s
, rm
);
10175 tcg_gen_add_i32(addr
, addr
, tmp
);
10176 if (insn
& (1 << 4)) {
10178 tcg_gen_add_i32(addr
, addr
, tmp
);
10179 tcg_temp_free_i32(tmp
);
10180 tmp
= tcg_temp_new_i32();
10181 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
10183 tcg_temp_free_i32(tmp
);
10184 tmp
= tcg_temp_new_i32();
10185 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
10187 tcg_temp_free_i32(addr
);
10188 tcg_gen_shli_i32(tmp
, tmp
, 1);
10189 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
10190 store_reg(s
, 15, tmp
);
10192 int op2
= (insn
>> 6) & 0x3;
10193 op
= (insn
>> 4) & 0x3;
10198 /* Load/store exclusive byte/halfword/doubleword */
10205 /* Load-acquire/store-release */
10211 /* Load-acquire/store-release exclusive */
10215 addr
= tcg_temp_local_new_i32();
10216 load_reg_var(s
, addr
, rn
);
10218 if (insn
& (1 << 20)) {
10219 tmp
= tcg_temp_new_i32();
10222 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
10226 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
10230 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
10236 store_reg(s
, rs
, tmp
);
10238 tmp
= load_reg(s
, rs
);
10241 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
10245 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
10249 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
10255 tcg_temp_free_i32(tmp
);
10257 } else if (insn
& (1 << 20)) {
10258 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
10260 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
10262 tcg_temp_free_i32(addr
);
10265 /* Load/store multiple, RFE, SRS. */
10266 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
10267 /* RFE, SRS: not available in user mode or on M profile */
10268 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10271 if (insn
& (1 << 20)) {
10273 addr
= load_reg(s
, rn
);
10274 if ((insn
& (1 << 24)) == 0)
10275 tcg_gen_addi_i32(addr
, addr
, -8);
10276 /* Load PC into tmp and CPSR into tmp2. */
10277 tmp
= tcg_temp_new_i32();
10278 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10279 tcg_gen_addi_i32(addr
, addr
, 4);
10280 tmp2
= tcg_temp_new_i32();
10281 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
10282 if (insn
& (1 << 21)) {
10283 /* Base writeback. */
10284 if (insn
& (1 << 24)) {
10285 tcg_gen_addi_i32(addr
, addr
, 4);
10287 tcg_gen_addi_i32(addr
, addr
, -4);
10289 store_reg(s
, rn
, addr
);
10291 tcg_temp_free_i32(addr
);
10293 gen_rfe(s
, tmp
, tmp2
);
10296 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
10300 int i
, loaded_base
= 0;
10301 TCGv_i32 loaded_var
;
10302 /* Load/store multiple. */
10303 addr
= load_reg(s
, rn
);
10305 for (i
= 0; i
< 16; i
++) {
10306 if (insn
& (1 << i
))
10309 if (insn
& (1 << 24)) {
10310 tcg_gen_addi_i32(addr
, addr
, -offset
);
10314 for (i
= 0; i
< 16; i
++) {
10315 if ((insn
& (1 << i
)) == 0)
10317 if (insn
& (1 << 20)) {
10319 tmp
= tcg_temp_new_i32();
10320 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10322 gen_bx_excret(s
, tmp
);
10323 } else if (i
== rn
) {
10327 store_reg(s
, i
, tmp
);
10331 tmp
= load_reg(s
, i
);
10332 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10333 tcg_temp_free_i32(tmp
);
10335 tcg_gen_addi_i32(addr
, addr
, 4);
10338 store_reg(s
, rn
, loaded_var
);
10340 if (insn
& (1 << 21)) {
10341 /* Base register writeback. */
10342 if (insn
& (1 << 24)) {
10343 tcg_gen_addi_i32(addr
, addr
, -offset
);
10345 /* Fault if writeback register is in register list. */
10346 if (insn
& (1 << rn
))
10348 store_reg(s
, rn
, addr
);
10350 tcg_temp_free_i32(addr
);
10357 op
= (insn
>> 21) & 0xf;
10359 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10362 /* Halfword pack. */
10363 tmp
= load_reg(s
, rn
);
10364 tmp2
= load_reg(s
, rm
);
10365 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
10366 if (insn
& (1 << 5)) {
10370 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
10371 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
10372 tcg_gen_ext16u_i32(tmp2
, tmp2
);
10376 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10377 tcg_gen_ext16u_i32(tmp
, tmp
);
10378 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10380 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10381 tcg_temp_free_i32(tmp2
);
10382 store_reg(s
, rd
, tmp
);
10384 /* Data processing register constant shift. */
10386 tmp
= tcg_temp_new_i32();
10387 tcg_gen_movi_i32(tmp
, 0);
10389 tmp
= load_reg(s
, rn
);
10391 tmp2
= load_reg(s
, rm
);
10393 shiftop
= (insn
>> 4) & 3;
10394 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10395 conds
= (insn
& (1 << 20)) != 0;
10396 logic_cc
= (conds
&& thumb2_logic_op(op
));
10397 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10398 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10400 tcg_temp_free_i32(tmp2
);
10402 store_reg(s
, rd
, tmp
);
10404 tcg_temp_free_i32(tmp
);
10408 case 13: /* Misc data processing. */
10409 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10410 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10413 case 0: /* Register controlled shift. */
10414 tmp
= load_reg(s
, rn
);
10415 tmp2
= load_reg(s
, rm
);
10416 if ((insn
& 0x70) != 0)
10418 op
= (insn
>> 21) & 3;
10419 logic_cc
= (insn
& (1 << 20)) != 0;
10420 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10423 store_reg(s
, rd
, tmp
);
10425 case 1: /* Sign/zero extend. */
10426 op
= (insn
>> 20) & 7;
10428 case 0: /* SXTAH, SXTH */
10429 case 1: /* UXTAH, UXTH */
10430 case 4: /* SXTAB, SXTB */
10431 case 5: /* UXTAB, UXTB */
10433 case 2: /* SXTAB16, SXTB16 */
10434 case 3: /* UXTAB16, UXTB16 */
10435 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10443 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10447 tmp
= load_reg(s
, rm
);
10448 shift
= (insn
>> 4) & 3;
10449 /* ??? In many cases it's not necessary to do a
10450 rotate, a shift is sufficient. */
10452 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10453 op
= (insn
>> 20) & 7;
10455 case 0: gen_sxth(tmp
); break;
10456 case 1: gen_uxth(tmp
); break;
10457 case 2: gen_sxtb16(tmp
); break;
10458 case 3: gen_uxtb16(tmp
); break;
10459 case 4: gen_sxtb(tmp
); break;
10460 case 5: gen_uxtb(tmp
); break;
10462 g_assert_not_reached();
10465 tmp2
= load_reg(s
, rn
);
10466 if ((op
>> 1) == 1) {
10467 gen_add16(tmp
, tmp2
);
10469 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10470 tcg_temp_free_i32(tmp2
);
10473 store_reg(s
, rd
, tmp
);
10475 case 2: /* SIMD add/subtract. */
10476 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10479 op
= (insn
>> 20) & 7;
10480 shift
= (insn
>> 4) & 7;
10481 if ((op
& 3) == 3 || (shift
& 3) == 3)
10483 tmp
= load_reg(s
, rn
);
10484 tmp2
= load_reg(s
, rm
);
10485 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10486 tcg_temp_free_i32(tmp2
);
10487 store_reg(s
, rd
, tmp
);
10489 case 3: /* Other data processing. */
10490 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10492 /* Saturating add/subtract. */
10493 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10496 tmp
= load_reg(s
, rn
);
10497 tmp2
= load_reg(s
, rm
);
10499 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10501 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10503 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10504 tcg_temp_free_i32(tmp2
);
10507 case 0x0a: /* rbit */
10508 case 0x08: /* rev */
10509 case 0x09: /* rev16 */
10510 case 0x0b: /* revsh */
10511 case 0x18: /* clz */
10513 case 0x10: /* sel */
10514 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10518 case 0x20: /* crc32/crc32c */
10524 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10531 tmp
= load_reg(s
, rn
);
10533 case 0x0a: /* rbit */
10534 gen_helper_rbit(tmp
, tmp
);
10536 case 0x08: /* rev */
10537 tcg_gen_bswap32_i32(tmp
, tmp
);
10539 case 0x09: /* rev16 */
10542 case 0x0b: /* revsh */
10545 case 0x10: /* sel */
10546 tmp2
= load_reg(s
, rm
);
10547 tmp3
= tcg_temp_new_i32();
10548 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10549 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10550 tcg_temp_free_i32(tmp3
);
10551 tcg_temp_free_i32(tmp2
);
10553 case 0x18: /* clz */
10554 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10564 uint32_t sz
= op
& 0x3;
10565 uint32_t c
= op
& 0x8;
10567 tmp2
= load_reg(s
, rm
);
10569 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10570 } else if (sz
== 1) {
10571 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10573 tmp3
= tcg_const_i32(1 << sz
);
10575 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10577 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10579 tcg_temp_free_i32(tmp2
);
10580 tcg_temp_free_i32(tmp3
);
10584 g_assert_not_reached();
10587 store_reg(s
, rd
, tmp
);
10589 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10590 switch ((insn
>> 20) & 7) {
10591 case 0: /* 32 x 32 -> 32 */
10592 case 7: /* Unsigned sum of absolute differences. */
10594 case 1: /* 16 x 16 -> 32 */
10595 case 2: /* Dual multiply add. */
10596 case 3: /* 32 * 16 -> 32msb */
10597 case 4: /* Dual multiply subtract. */
10598 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10599 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10604 op
= (insn
>> 4) & 0xf;
10605 tmp
= load_reg(s
, rn
);
10606 tmp2
= load_reg(s
, rm
);
10607 switch ((insn
>> 20) & 7) {
10608 case 0: /* 32 x 32 -> 32 */
10609 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10610 tcg_temp_free_i32(tmp2
);
10612 tmp2
= load_reg(s
, rs
);
10614 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10616 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10617 tcg_temp_free_i32(tmp2
);
10620 case 1: /* 16 x 16 -> 32 */
10621 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10622 tcg_temp_free_i32(tmp2
);
10624 tmp2
= load_reg(s
, rs
);
10625 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10626 tcg_temp_free_i32(tmp2
);
10629 case 2: /* Dual multiply add. */
10630 case 4: /* Dual multiply subtract. */
10632 gen_swap_half(tmp2
);
10633 gen_smul_dual(tmp
, tmp2
);
10634 if (insn
& (1 << 22)) {
10635 /* This subtraction cannot overflow. */
10636 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10638 /* This addition cannot overflow 32 bits;
10639 * however it may overflow considered as a signed
10640 * operation, in which case we must set the Q flag.
10642 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10644 tcg_temp_free_i32(tmp2
);
10647 tmp2
= load_reg(s
, rs
);
10648 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10649 tcg_temp_free_i32(tmp2
);
10652 case 3: /* 32 * 16 -> 32msb */
10654 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10657 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10658 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10659 tmp
= tcg_temp_new_i32();
10660 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10661 tcg_temp_free_i64(tmp64
);
10664 tmp2
= load_reg(s
, rs
);
10665 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10666 tcg_temp_free_i32(tmp2
);
10669 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10670 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10672 tmp
= load_reg(s
, rs
);
10673 if (insn
& (1 << 20)) {
10674 tmp64
= gen_addq_msw(tmp64
, tmp
);
10676 tmp64
= gen_subq_msw(tmp64
, tmp
);
10679 if (insn
& (1 << 4)) {
10680 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10682 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10683 tmp
= tcg_temp_new_i32();
10684 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10685 tcg_temp_free_i64(tmp64
);
10687 case 7: /* Unsigned sum of absolute differences. */
10688 gen_helper_usad8(tmp
, tmp
, tmp2
);
10689 tcg_temp_free_i32(tmp2
);
10691 tmp2
= load_reg(s
, rs
);
10692 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10693 tcg_temp_free_i32(tmp2
);
10697 store_reg(s
, rd
, tmp
);
10699 case 6: case 7: /* 64-bit multiply, Divide. */
10700 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10701 tmp
= load_reg(s
, rn
);
10702 tmp2
= load_reg(s
, rm
);
10703 if ((op
& 0x50) == 0x10) {
10705 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10709 gen_helper_udiv(tmp
, tmp
, tmp2
);
10711 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10712 tcg_temp_free_i32(tmp2
);
10713 store_reg(s
, rd
, tmp
);
10714 } else if ((op
& 0xe) == 0xc) {
10715 /* Dual multiply accumulate long. */
10716 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10717 tcg_temp_free_i32(tmp
);
10718 tcg_temp_free_i32(tmp2
);
10722 gen_swap_half(tmp2
);
10723 gen_smul_dual(tmp
, tmp2
);
10725 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10727 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10729 tcg_temp_free_i32(tmp2
);
10731 tmp64
= tcg_temp_new_i64();
10732 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10733 tcg_temp_free_i32(tmp
);
10734 gen_addq(s
, tmp64
, rs
, rd
);
10735 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10736 tcg_temp_free_i64(tmp64
);
10739 /* Unsigned 64-bit multiply */
10740 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10744 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10745 tcg_temp_free_i32(tmp2
);
10746 tcg_temp_free_i32(tmp
);
10749 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10750 tcg_temp_free_i32(tmp2
);
10751 tmp64
= tcg_temp_new_i64();
10752 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10753 tcg_temp_free_i32(tmp
);
10755 /* Signed 64-bit multiply */
10756 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10761 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10762 tcg_temp_free_i64(tmp64
);
10765 gen_addq_lo(s
, tmp64
, rs
);
10766 gen_addq_lo(s
, tmp64
, rd
);
10767 } else if (op
& 0x40) {
10768 /* 64-bit accumulate. */
10769 gen_addq(s
, tmp64
, rs
, rd
);
10771 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10772 tcg_temp_free_i64(tmp64
);
10777 case 6: case 7: case 14: case 15:
10779 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10780 /* We don't currently implement M profile FP support,
10781 * so this entire space should give a NOCP fault.
10783 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10784 default_exception_el(s
));
10787 if ((insn
& 0xfe000a00) == 0xfc000800
10788 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10789 /* The Thumb2 and ARM encodings are identical. */
10790 if (disas_neon_insn_3same_ext(s
, insn
)) {
10793 } else if ((insn
& 0xff000a00) == 0xfe000800
10794 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10795 /* The Thumb2 and ARM encodings are identical. */
10796 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
10799 } else if (((insn
>> 24) & 3) == 3) {
10800 /* Translate into the equivalent ARM encoding. */
10801 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10802 if (disas_neon_data_insn(s
, insn
)) {
10805 } else if (((insn
>> 8) & 0xe) == 10) {
10806 if (disas_vfp_insn(s
, insn
)) {
10810 if (insn
& (1 << 28))
10812 if (disas_coproc_insn(s
, insn
)) {
10817 case 8: case 9: case 10: case 11:
10818 if (insn
& (1 << 15)) {
10819 /* Branches, misc control. */
10820 if (insn
& 0x5000) {
10821 /* Unconditional branch. */
10822 /* signextend(hw1[10:0]) -> offset[:12]. */
10823 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10824 /* hw1[10:0] -> offset[11:1]. */
10825 offset
|= (insn
& 0x7ff) << 1;
10826 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10827 offset[24:22] already have the same value because of the
10828 sign extension above. */
10829 offset
^= ((~insn
) & (1 << 13)) << 10;
10830 offset
^= ((~insn
) & (1 << 11)) << 11;
10832 if (insn
& (1 << 14)) {
10833 /* Branch and link. */
10834 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10838 if (insn
& (1 << 12)) {
10840 gen_jmp(s
, offset
);
10843 offset
&= ~(uint32_t)2;
10844 /* thumb2 bx, no need to check */
10845 gen_bx_im(s
, offset
);
10847 } else if (((insn
>> 23) & 7) == 7) {
10849 if (insn
& (1 << 13))
10852 if (insn
& (1 << 26)) {
10853 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10856 if (!(insn
& (1 << 20))) {
10857 /* Hypervisor call (v7) */
10858 int imm16
= extract32(insn
, 16, 4) << 12
10859 | extract32(insn
, 0, 12);
10866 /* Secure monitor call (v6+) */
10874 op
= (insn
>> 20) & 7;
10876 case 0: /* msr cpsr. */
10877 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10878 tmp
= load_reg(s
, rn
);
10879 /* the constant is the mask and SYSm fields */
10880 addr
= tcg_const_i32(insn
& 0xfff);
10881 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10882 tcg_temp_free_i32(addr
);
10883 tcg_temp_free_i32(tmp
);
10888 case 1: /* msr spsr. */
10889 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10893 if (extract32(insn
, 5, 1)) {
10895 int sysm
= extract32(insn
, 8, 4) |
10896 (extract32(insn
, 4, 1) << 4);
10899 gen_msr_banked(s
, r
, sysm
, rm
);
10903 /* MSR (for PSRs) */
10904 tmp
= load_reg(s
, rn
);
10906 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10910 case 2: /* cps, nop-hint. */
10911 if (((insn
>> 8) & 7) == 0) {
10912 gen_nop_hint(s
, insn
& 0xff);
10914 /* Implemented as NOP in user mode. */
10919 if (insn
& (1 << 10)) {
10920 if (insn
& (1 << 7))
10922 if (insn
& (1 << 6))
10924 if (insn
& (1 << 5))
10926 if (insn
& (1 << 9))
10927 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10929 if (insn
& (1 << 8)) {
10931 imm
|= (insn
& 0x1f);
10934 gen_set_psr_im(s
, offset
, 0, imm
);
10937 case 3: /* Special control operations. */
10939 op
= (insn
>> 4) & 0xf;
10941 case 2: /* clrex */
10946 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10949 /* We need to break the TB after this insn
10950 * to execute self-modifying code correctly
10951 * and also to take any pending interrupts
10954 gen_goto_tb(s
, 0, s
->pc
& ~1);
10961 /* Trivial implementation equivalent to bx.
10962 * This instruction doesn't exist at all for M-profile.
10964 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10967 tmp
= load_reg(s
, rn
);
10970 case 5: /* Exception return. */
10974 if (rn
!= 14 || rd
!= 15) {
10977 tmp
= load_reg(s
, rn
);
10978 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10979 gen_exception_return(s
, tmp
);
10982 if (extract32(insn
, 5, 1) &&
10983 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10985 int sysm
= extract32(insn
, 16, 4) |
10986 (extract32(insn
, 4, 1) << 4);
10988 gen_mrs_banked(s
, 0, sysm
, rd
);
10992 if (extract32(insn
, 16, 4) != 0xf) {
10995 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10996 extract32(insn
, 0, 8) != 0) {
11001 tmp
= tcg_temp_new_i32();
11002 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11003 addr
= tcg_const_i32(insn
& 0xff);
11004 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
11005 tcg_temp_free_i32(addr
);
11007 gen_helper_cpsr_read(tmp
, cpu_env
);
11009 store_reg(s
, rd
, tmp
);
11012 if (extract32(insn
, 5, 1) &&
11013 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11015 int sysm
= extract32(insn
, 16, 4) |
11016 (extract32(insn
, 4, 1) << 4);
11018 gen_mrs_banked(s
, 1, sysm
, rd
);
11023 /* Not accessible in user mode. */
11024 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
11028 if (extract32(insn
, 16, 4) != 0xf ||
11029 extract32(insn
, 0, 8) != 0) {
11033 tmp
= load_cpu_field(spsr
);
11034 store_reg(s
, rd
, tmp
);
11039 /* Conditional branch. */
11040 op
= (insn
>> 22) & 0xf;
11041 /* Generate a conditional jump to next instruction. */
11042 s
->condlabel
= gen_new_label();
11043 arm_gen_test_cc(op
^ 1, s
->condlabel
);
11046 /* offset[11:1] = insn[10:0] */
11047 offset
= (insn
& 0x7ff) << 1;
11048 /* offset[17:12] = insn[21:16]. */
11049 offset
|= (insn
& 0x003f0000) >> 4;
11050 /* offset[31:20] = insn[26]. */
11051 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
11052 /* offset[18] = insn[13]. */
11053 offset
|= (insn
& (1 << 13)) << 5;
11054 /* offset[19] = insn[11]. */
11055 offset
|= (insn
& (1 << 11)) << 8;
11057 /* jump to the offset */
11058 gen_jmp(s
, s
->pc
+ offset
);
11061 /* Data processing immediate. */
11062 if (insn
& (1 << 25)) {
11063 if (insn
& (1 << 24)) {
11064 if (insn
& (1 << 20))
11066 /* Bitfield/Saturate. */
11067 op
= (insn
>> 21) & 7;
11069 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
11071 tmp
= tcg_temp_new_i32();
11072 tcg_gen_movi_i32(tmp
, 0);
11074 tmp
= load_reg(s
, rn
);
11077 case 2: /* Signed bitfield extract. */
11079 if (shift
+ imm
> 32)
11082 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
11085 case 6: /* Unsigned bitfield extract. */
11087 if (shift
+ imm
> 32)
11090 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
11093 case 3: /* Bitfield insert/clear. */
11096 imm
= imm
+ 1 - shift
;
11098 tmp2
= load_reg(s
, rd
);
11099 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
11100 tcg_temp_free_i32(tmp2
);
11105 default: /* Saturate. */
11108 tcg_gen_sari_i32(tmp
, tmp
, shift
);
11110 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11112 tmp2
= tcg_const_i32(imm
);
11115 if ((op
& 1) && shift
== 0) {
11116 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11117 tcg_temp_free_i32(tmp
);
11118 tcg_temp_free_i32(tmp2
);
11121 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
11123 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
11127 if ((op
& 1) && shift
== 0) {
11128 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11129 tcg_temp_free_i32(tmp
);
11130 tcg_temp_free_i32(tmp2
);
11133 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
11135 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
11138 tcg_temp_free_i32(tmp2
);
11141 store_reg(s
, rd
, tmp
);
11143 imm
= ((insn
& 0x04000000) >> 15)
11144 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
11145 if (insn
& (1 << 22)) {
11146 /* 16-bit immediate. */
11147 imm
|= (insn
>> 4) & 0xf000;
11148 if (insn
& (1 << 23)) {
11150 tmp
= load_reg(s
, rd
);
11151 tcg_gen_ext16u_i32(tmp
, tmp
);
11152 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
11155 tmp
= tcg_temp_new_i32();
11156 tcg_gen_movi_i32(tmp
, imm
);
11159 /* Add/sub 12-bit immediate. */
11161 offset
= s
->pc
& ~(uint32_t)3;
11162 if (insn
& (1 << 23))
11166 tmp
= tcg_temp_new_i32();
11167 tcg_gen_movi_i32(tmp
, offset
);
11169 tmp
= load_reg(s
, rn
);
11170 if (insn
& (1 << 23))
11171 tcg_gen_subi_i32(tmp
, tmp
, imm
);
11173 tcg_gen_addi_i32(tmp
, tmp
, imm
);
11176 store_reg(s
, rd
, tmp
);
11179 int shifter_out
= 0;
11180 /* modified 12-bit immediate. */
11181 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
11182 imm
= (insn
& 0xff);
11185 /* Nothing to do. */
11187 case 1: /* 00XY00XY */
11190 case 2: /* XY00XY00 */
11194 case 3: /* XYXYXYXY */
11198 default: /* Rotated constant. */
11199 shift
= (shift
<< 1) | (imm
>> 7);
11201 imm
= imm
<< (32 - shift
);
11205 tmp2
= tcg_temp_new_i32();
11206 tcg_gen_movi_i32(tmp2
, imm
);
11207 rn
= (insn
>> 16) & 0xf;
11209 tmp
= tcg_temp_new_i32();
11210 tcg_gen_movi_i32(tmp
, 0);
11212 tmp
= load_reg(s
, rn
);
11214 op
= (insn
>> 21) & 0xf;
11215 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
11216 shifter_out
, tmp
, tmp2
))
11218 tcg_temp_free_i32(tmp2
);
11219 rd
= (insn
>> 8) & 0xf;
11221 store_reg(s
, rd
, tmp
);
11223 tcg_temp_free_i32(tmp
);
11228 case 12: /* Load/store single data item. */
11235 if ((insn
& 0x01100000) == 0x01000000) {
11236 if (disas_neon_ls_insn(s
, insn
)) {
11241 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
11243 if (!(insn
& (1 << 20))) {
11247 /* Byte or halfword load space with dest == r15 : memory hints.
11248 * Catch them early so we don't emit pointless addressing code.
11249 * This space is a mix of:
11250 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11251 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11253 * unallocated hints, which must be treated as NOPs
11254 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11255 * which is easiest for the decoding logic
11256 * Some space which must UNDEF
11258 int op1
= (insn
>> 23) & 3;
11259 int op2
= (insn
>> 6) & 0x3f;
11264 /* UNPREDICTABLE, unallocated hint or
11265 * PLD/PLDW/PLI (literal)
11270 return; /* PLD/PLDW/PLI or unallocated hint */
11272 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
11273 return; /* PLD/PLDW/PLI or unallocated hint */
11275 /* UNDEF space, or an UNPREDICTABLE */
11279 memidx
= get_mem_index(s
);
11281 addr
= tcg_temp_new_i32();
11283 /* s->pc has already been incremented by 4. */
11284 imm
= s
->pc
& 0xfffffffc;
11285 if (insn
& (1 << 23))
11286 imm
+= insn
& 0xfff;
11288 imm
-= insn
& 0xfff;
11289 tcg_gen_movi_i32(addr
, imm
);
11291 addr
= load_reg(s
, rn
);
11292 if (insn
& (1 << 23)) {
11293 /* Positive offset. */
11294 imm
= insn
& 0xfff;
11295 tcg_gen_addi_i32(addr
, addr
, imm
);
11298 switch ((insn
>> 8) & 0xf) {
11299 case 0x0: /* Shifted Register. */
11300 shift
= (insn
>> 4) & 0xf;
11302 tcg_temp_free_i32(addr
);
11305 tmp
= load_reg(s
, rm
);
11307 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11308 tcg_gen_add_i32(addr
, addr
, tmp
);
11309 tcg_temp_free_i32(tmp
);
11311 case 0xc: /* Negative offset. */
11312 tcg_gen_addi_i32(addr
, addr
, -imm
);
11314 case 0xe: /* User privilege. */
11315 tcg_gen_addi_i32(addr
, addr
, imm
);
11316 memidx
= get_a32_user_mem_index(s
);
11318 case 0x9: /* Post-decrement. */
11320 /* Fall through. */
11321 case 0xb: /* Post-increment. */
11325 case 0xd: /* Pre-decrement. */
11327 /* Fall through. */
11328 case 0xf: /* Pre-increment. */
11329 tcg_gen_addi_i32(addr
, addr
, imm
);
11333 tcg_temp_free_i32(addr
);
11339 issinfo
= writeback
? ISSInvalid
: rs
;
11341 if (insn
& (1 << 20)) {
11343 tmp
= tcg_temp_new_i32();
11346 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11349 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11352 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11355 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11358 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11361 tcg_temp_free_i32(tmp
);
11362 tcg_temp_free_i32(addr
);
11366 gen_bx_excret(s
, tmp
);
11368 store_reg(s
, rs
, tmp
);
11372 tmp
= load_reg(s
, rs
);
11375 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
11378 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
11381 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
11384 tcg_temp_free_i32(tmp
);
11385 tcg_temp_free_i32(addr
);
11388 tcg_temp_free_i32(tmp
);
11391 tcg_gen_addi_i32(addr
, addr
, imm
);
11393 store_reg(s
, rn
, addr
);
11395 tcg_temp_free_i32(addr
);
11404 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11405 default_exception_el(s
));
11408 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
11410 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
11417 switch (insn
>> 12) {
11421 op
= (insn
>> 11) & 3;
11424 rn
= (insn
>> 3) & 7;
11425 tmp
= load_reg(s
, rn
);
11426 if (insn
& (1 << 10)) {
11428 tmp2
= tcg_temp_new_i32();
11429 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11432 rm
= (insn
>> 6) & 7;
11433 tmp2
= load_reg(s
, rm
);
11435 if (insn
& (1 << 9)) {
11436 if (s
->condexec_mask
)
11437 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11439 gen_sub_CC(tmp
, tmp
, tmp2
);
11441 if (s
->condexec_mask
)
11442 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11444 gen_add_CC(tmp
, tmp
, tmp2
);
11446 tcg_temp_free_i32(tmp2
);
11447 store_reg(s
, rd
, tmp
);
11449 /* shift immediate */
11450 rm
= (insn
>> 3) & 7;
11451 shift
= (insn
>> 6) & 0x1f;
11452 tmp
= load_reg(s
, rm
);
11453 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11454 if (!s
->condexec_mask
)
11456 store_reg(s
, rd
, tmp
);
11460 /* arithmetic large immediate */
11461 op
= (insn
>> 11) & 3;
11462 rd
= (insn
>> 8) & 0x7;
11463 if (op
== 0) { /* mov */
11464 tmp
= tcg_temp_new_i32();
11465 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11466 if (!s
->condexec_mask
)
11468 store_reg(s
, rd
, tmp
);
11470 tmp
= load_reg(s
, rd
);
11471 tmp2
= tcg_temp_new_i32();
11472 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11475 gen_sub_CC(tmp
, tmp
, tmp2
);
11476 tcg_temp_free_i32(tmp
);
11477 tcg_temp_free_i32(tmp2
);
11480 if (s
->condexec_mask
)
11481 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11483 gen_add_CC(tmp
, tmp
, tmp2
);
11484 tcg_temp_free_i32(tmp2
);
11485 store_reg(s
, rd
, tmp
);
11488 if (s
->condexec_mask
)
11489 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11491 gen_sub_CC(tmp
, tmp
, tmp2
);
11492 tcg_temp_free_i32(tmp2
);
11493 store_reg(s
, rd
, tmp
);
11499 if (insn
& (1 << 11)) {
11500 rd
= (insn
>> 8) & 7;
11501 /* load pc-relative. Bit 1 of PC is ignored. */
11502 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11503 val
&= ~(uint32_t)2;
11504 addr
= tcg_temp_new_i32();
11505 tcg_gen_movi_i32(addr
, val
);
11506 tmp
= tcg_temp_new_i32();
11507 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11509 tcg_temp_free_i32(addr
);
11510 store_reg(s
, rd
, tmp
);
11513 if (insn
& (1 << 10)) {
11514 /* 0b0100_01xx_xxxx_xxxx
11515 * - data processing extended, branch and exchange
11517 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11518 rm
= (insn
>> 3) & 0xf;
11519 op
= (insn
>> 8) & 3;
11522 tmp
= load_reg(s
, rd
);
11523 tmp2
= load_reg(s
, rm
);
11524 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11525 tcg_temp_free_i32(tmp2
);
11526 store_reg(s
, rd
, tmp
);
11529 tmp
= load_reg(s
, rd
);
11530 tmp2
= load_reg(s
, rm
);
11531 gen_sub_CC(tmp
, tmp
, tmp2
);
11532 tcg_temp_free_i32(tmp2
);
11533 tcg_temp_free_i32(tmp
);
11535 case 2: /* mov/cpy */
11536 tmp
= load_reg(s
, rm
);
11537 store_reg(s
, rd
, tmp
);
11541 /* 0b0100_0111_xxxx_xxxx
11542 * - branch [and link] exchange thumb register
11544 bool link
= insn
& (1 << 7);
11553 /* BXNS/BLXNS: only exists for v8M with the
11554 * security extensions, and always UNDEF if NonSecure.
11555 * We don't implement these in the user-only mode
11556 * either (in theory you can use them from Secure User
11557 * mode but they are too tied in to system emulation.)
11559 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
11570 tmp
= load_reg(s
, rm
);
11572 val
= (uint32_t)s
->pc
| 1;
11573 tmp2
= tcg_temp_new_i32();
11574 tcg_gen_movi_i32(tmp2
, val
);
11575 store_reg(s
, 14, tmp2
);
11578 /* Only BX works as exception-return, not BLX */
11579 gen_bx_excret(s
, tmp
);
11587 /* data processing register */
11589 rm
= (insn
>> 3) & 7;
11590 op
= (insn
>> 6) & 0xf;
11591 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11592 /* the shift/rotate ops want the operands backwards */
11601 if (op
== 9) { /* neg */
11602 tmp
= tcg_temp_new_i32();
11603 tcg_gen_movi_i32(tmp
, 0);
11604 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11605 tmp
= load_reg(s
, rd
);
11610 tmp2
= load_reg(s
, rm
);
11612 case 0x0: /* and */
11613 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11614 if (!s
->condexec_mask
)
11617 case 0x1: /* eor */
11618 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11619 if (!s
->condexec_mask
)
11622 case 0x2: /* lsl */
11623 if (s
->condexec_mask
) {
11624 gen_shl(tmp2
, tmp2
, tmp
);
11626 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11627 gen_logic_CC(tmp2
);
11630 case 0x3: /* lsr */
11631 if (s
->condexec_mask
) {
11632 gen_shr(tmp2
, tmp2
, tmp
);
11634 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11635 gen_logic_CC(tmp2
);
11638 case 0x4: /* asr */
11639 if (s
->condexec_mask
) {
11640 gen_sar(tmp2
, tmp2
, tmp
);
11642 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11643 gen_logic_CC(tmp2
);
11646 case 0x5: /* adc */
11647 if (s
->condexec_mask
) {
11648 gen_adc(tmp
, tmp2
);
11650 gen_adc_CC(tmp
, tmp
, tmp2
);
11653 case 0x6: /* sbc */
11654 if (s
->condexec_mask
) {
11655 gen_sub_carry(tmp
, tmp
, tmp2
);
11657 gen_sbc_CC(tmp
, tmp
, tmp2
);
11660 case 0x7: /* ror */
11661 if (s
->condexec_mask
) {
11662 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11663 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11665 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11666 gen_logic_CC(tmp2
);
11669 case 0x8: /* tst */
11670 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11674 case 0x9: /* neg */
11675 if (s
->condexec_mask
)
11676 tcg_gen_neg_i32(tmp
, tmp2
);
11678 gen_sub_CC(tmp
, tmp
, tmp2
);
11680 case 0xa: /* cmp */
11681 gen_sub_CC(tmp
, tmp
, tmp2
);
11684 case 0xb: /* cmn */
11685 gen_add_CC(tmp
, tmp
, tmp2
);
11688 case 0xc: /* orr */
11689 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11690 if (!s
->condexec_mask
)
11693 case 0xd: /* mul */
11694 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11695 if (!s
->condexec_mask
)
11698 case 0xe: /* bic */
11699 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11700 if (!s
->condexec_mask
)
11703 case 0xf: /* mvn */
11704 tcg_gen_not_i32(tmp2
, tmp2
);
11705 if (!s
->condexec_mask
)
11706 gen_logic_CC(tmp2
);
11713 store_reg(s
, rm
, tmp2
);
11715 tcg_temp_free_i32(tmp
);
11717 store_reg(s
, rd
, tmp
);
11718 tcg_temp_free_i32(tmp2
);
11721 tcg_temp_free_i32(tmp
);
11722 tcg_temp_free_i32(tmp2
);
11727 /* load/store register offset. */
11729 rn
= (insn
>> 3) & 7;
11730 rm
= (insn
>> 6) & 7;
11731 op
= (insn
>> 9) & 7;
11732 addr
= load_reg(s
, rn
);
11733 tmp
= load_reg(s
, rm
);
11734 tcg_gen_add_i32(addr
, addr
, tmp
);
11735 tcg_temp_free_i32(tmp
);
11737 if (op
< 3) { /* store */
11738 tmp
= load_reg(s
, rd
);
11740 tmp
= tcg_temp_new_i32();
11745 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11748 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11751 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11753 case 3: /* ldrsb */
11754 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11757 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11760 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11763 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11765 case 7: /* ldrsh */
11766 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11769 if (op
>= 3) { /* load */
11770 store_reg(s
, rd
, tmp
);
11772 tcg_temp_free_i32(tmp
);
11774 tcg_temp_free_i32(addr
);
11778 /* load/store word immediate offset */
11780 rn
= (insn
>> 3) & 7;
11781 addr
= load_reg(s
, rn
);
11782 val
= (insn
>> 4) & 0x7c;
11783 tcg_gen_addi_i32(addr
, addr
, val
);
11785 if (insn
& (1 << 11)) {
11787 tmp
= tcg_temp_new_i32();
11788 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11789 store_reg(s
, rd
, tmp
);
11792 tmp
= load_reg(s
, rd
);
11793 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11794 tcg_temp_free_i32(tmp
);
11796 tcg_temp_free_i32(addr
);
11800 /* load/store byte immediate offset */
11802 rn
= (insn
>> 3) & 7;
11803 addr
= load_reg(s
, rn
);
11804 val
= (insn
>> 6) & 0x1f;
11805 tcg_gen_addi_i32(addr
, addr
, val
);
11807 if (insn
& (1 << 11)) {
11809 tmp
= tcg_temp_new_i32();
11810 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11811 store_reg(s
, rd
, tmp
);
11814 tmp
= load_reg(s
, rd
);
11815 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11816 tcg_temp_free_i32(tmp
);
11818 tcg_temp_free_i32(addr
);
11822 /* load/store halfword immediate offset */
11824 rn
= (insn
>> 3) & 7;
11825 addr
= load_reg(s
, rn
);
11826 val
= (insn
>> 5) & 0x3e;
11827 tcg_gen_addi_i32(addr
, addr
, val
);
11829 if (insn
& (1 << 11)) {
11831 tmp
= tcg_temp_new_i32();
11832 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11833 store_reg(s
, rd
, tmp
);
11836 tmp
= load_reg(s
, rd
);
11837 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11838 tcg_temp_free_i32(tmp
);
11840 tcg_temp_free_i32(addr
);
11844 /* load/store from stack */
11845 rd
= (insn
>> 8) & 7;
11846 addr
= load_reg(s
, 13);
11847 val
= (insn
& 0xff) * 4;
11848 tcg_gen_addi_i32(addr
, addr
, val
);
11850 if (insn
& (1 << 11)) {
11852 tmp
= tcg_temp_new_i32();
11853 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11854 store_reg(s
, rd
, tmp
);
11857 tmp
= load_reg(s
, rd
);
11858 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11859 tcg_temp_free_i32(tmp
);
11861 tcg_temp_free_i32(addr
);
11865 /* add to high reg */
11866 rd
= (insn
>> 8) & 7;
11867 if (insn
& (1 << 11)) {
11869 tmp
= load_reg(s
, 13);
11871 /* PC. bit 1 is ignored. */
11872 tmp
= tcg_temp_new_i32();
11873 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11875 val
= (insn
& 0xff) * 4;
11876 tcg_gen_addi_i32(tmp
, tmp
, val
);
11877 store_reg(s
, rd
, tmp
);
11882 op
= (insn
>> 8) & 0xf;
11885 /* adjust stack pointer */
11886 tmp
= load_reg(s
, 13);
11887 val
= (insn
& 0x7f) * 4;
11888 if (insn
& (1 << 7))
11889 val
= -(int32_t)val
;
11890 tcg_gen_addi_i32(tmp
, tmp
, val
);
11891 store_reg(s
, 13, tmp
);
11894 case 2: /* sign/zero extend. */
11897 rm
= (insn
>> 3) & 7;
11898 tmp
= load_reg(s
, rm
);
11899 switch ((insn
>> 6) & 3) {
11900 case 0: gen_sxth(tmp
); break;
11901 case 1: gen_sxtb(tmp
); break;
11902 case 2: gen_uxth(tmp
); break;
11903 case 3: gen_uxtb(tmp
); break;
11905 store_reg(s
, rd
, tmp
);
11907 case 4: case 5: case 0xc: case 0xd:
11909 addr
= load_reg(s
, 13);
11910 if (insn
& (1 << 8))
11914 for (i
= 0; i
< 8; i
++) {
11915 if (insn
& (1 << i
))
11918 if ((insn
& (1 << 11)) == 0) {
11919 tcg_gen_addi_i32(addr
, addr
, -offset
);
11921 for (i
= 0; i
< 8; i
++) {
11922 if (insn
& (1 << i
)) {
11923 if (insn
& (1 << 11)) {
11925 tmp
= tcg_temp_new_i32();
11926 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11927 store_reg(s
, i
, tmp
);
11930 tmp
= load_reg(s
, i
);
11931 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11932 tcg_temp_free_i32(tmp
);
11934 /* advance to the next address. */
11935 tcg_gen_addi_i32(addr
, addr
, 4);
11939 if (insn
& (1 << 8)) {
11940 if (insn
& (1 << 11)) {
11942 tmp
= tcg_temp_new_i32();
11943 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11944 /* don't set the pc until the rest of the instruction
11948 tmp
= load_reg(s
, 14);
11949 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11950 tcg_temp_free_i32(tmp
);
11952 tcg_gen_addi_i32(addr
, addr
, 4);
11954 if ((insn
& (1 << 11)) == 0) {
11955 tcg_gen_addi_i32(addr
, addr
, -offset
);
11957 /* write back the new stack pointer */
11958 store_reg(s
, 13, addr
);
11959 /* set the new PC value */
11960 if ((insn
& 0x0900) == 0x0900) {
11961 store_reg_from_load(s
, 15, tmp
);
11965 case 1: case 3: case 9: case 11: /* czb */
11967 tmp
= load_reg(s
, rm
);
11968 s
->condlabel
= gen_new_label();
11970 if (insn
& (1 << 11))
11971 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11973 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11974 tcg_temp_free_i32(tmp
);
11975 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11976 val
= (uint32_t)s
->pc
+ 2;
11981 case 15: /* IT, nop-hint. */
11982 if ((insn
& 0xf) == 0) {
11983 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11987 s
->condexec_cond
= (insn
>> 4) & 0xe;
11988 s
->condexec_mask
= insn
& 0x1f;
11989 /* No actual code generated for this insn, just setup state. */
11992 case 0xe: /* bkpt */
11994 int imm8
= extract32(insn
, 0, 8);
11996 gen_exception_bkpt_insn(s
, 2, syn_aa32_bkpt(imm8
, true));
12000 case 0xa: /* rev, and hlt */
12002 int op1
= extract32(insn
, 6, 2);
12006 int imm6
= extract32(insn
, 0, 6);
12012 /* Otherwise this is rev */
12014 rn
= (insn
>> 3) & 0x7;
12016 tmp
= load_reg(s
, rn
);
12018 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
12019 case 1: gen_rev16(tmp
); break;
12020 case 3: gen_revsh(tmp
); break;
12022 g_assert_not_reached();
12024 store_reg(s
, rd
, tmp
);
12029 switch ((insn
>> 5) & 7) {
12033 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
12034 gen_helper_setend(cpu_env
);
12035 s
->base
.is_jmp
= DISAS_UPDATE
;
12044 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
12045 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
12048 addr
= tcg_const_i32(19);
12049 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12050 tcg_temp_free_i32(addr
);
12054 addr
= tcg_const_i32(16);
12055 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12056 tcg_temp_free_i32(addr
);
12058 tcg_temp_free_i32(tmp
);
12061 if (insn
& (1 << 4)) {
12062 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
12066 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
12081 /* load/store multiple */
12082 TCGv_i32 loaded_var
= NULL
;
12083 rn
= (insn
>> 8) & 0x7;
12084 addr
= load_reg(s
, rn
);
12085 for (i
= 0; i
< 8; i
++) {
12086 if (insn
& (1 << i
)) {
12087 if (insn
& (1 << 11)) {
12089 tmp
= tcg_temp_new_i32();
12090 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12094 store_reg(s
, i
, tmp
);
12098 tmp
= load_reg(s
, i
);
12099 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12100 tcg_temp_free_i32(tmp
);
12102 /* advance to the next address */
12103 tcg_gen_addi_i32(addr
, addr
, 4);
12106 if ((insn
& (1 << rn
)) == 0) {
12107 /* base reg not in list: base register writeback */
12108 store_reg(s
, rn
, addr
);
12110 /* base reg in list: if load, complete it now */
12111 if (insn
& (1 << 11)) {
12112 store_reg(s
, rn
, loaded_var
);
12114 tcg_temp_free_i32(addr
);
12119 /* conditional branch or swi */
12120 cond
= (insn
>> 8) & 0xf;
12126 gen_set_pc_im(s
, s
->pc
);
12127 s
->svc_imm
= extract32(insn
, 0, 8);
12128 s
->base
.is_jmp
= DISAS_SWI
;
12131 /* generate a conditional jump to next instruction */
12132 s
->condlabel
= gen_new_label();
12133 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
12136 /* jump to the offset */
12137 val
= (uint32_t)s
->pc
+ 2;
12138 offset
= ((int32_t)insn
<< 24) >> 24;
12139 val
+= offset
<< 1;
12144 if (insn
& (1 << 11)) {
12145 /* thumb_insn_is_16bit() ensures we can't get here for
12146 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12147 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12149 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12151 offset
= ((insn
& 0x7ff) << 1);
12152 tmp
= load_reg(s
, 14);
12153 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12154 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
12156 tmp2
= tcg_temp_new_i32();
12157 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12158 store_reg(s
, 14, tmp2
);
12162 /* unconditional branch */
12163 val
= (uint32_t)s
->pc
;
12164 offset
= ((int32_t)insn
<< 21) >> 21;
12165 val
+= (offset
<< 1) + 2;
12170 /* thumb_insn_is_16bit() ensures we can't get here for
12171 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12173 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12175 if (insn
& (1 << 11)) {
12176 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12177 offset
= ((insn
& 0x7ff) << 1) | 1;
12178 tmp
= load_reg(s
, 14);
12179 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12181 tmp2
= tcg_temp_new_i32();
12182 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12183 store_reg(s
, 14, tmp2
);
12186 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12187 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
12189 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
12196 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
12197 default_exception_el(s
));
12200 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
12202 /* Return true if the insn at dc->pc might cross a page boundary.
12203 * (False positives are OK, false negatives are not.)
12204 * We know this is a Thumb insn, and our caller ensures we are
12205 * only called if dc->pc is less than 4 bytes from the page
12206 * boundary, so we cross the page if the first 16 bits indicate
12207 * that this is a 32 bit insn.
12209 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
12211 return !thumb_insn_is_16bit(s
, insn
);
12214 static int arm_tr_init_disas_context(DisasContextBase
*dcbase
,
12215 CPUState
*cs
, int max_insns
)
12217 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12218 CPUARMState
*env
= cs
->env_ptr
;
12219 ARMCPU
*cpu
= arm_env_get_cpu(env
);
12221 dc
->pc
= dc
->base
.pc_first
;
12225 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12226 * there is no secure EL1, so we route exceptions to EL3.
12228 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
12229 !arm_el_is_aa64(env
, 3);
12230 dc
->thumb
= ARM_TBFLAG_THUMB(dc
->base
.tb
->flags
);
12231 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(dc
->base
.tb
->flags
);
12232 dc
->be_data
= ARM_TBFLAG_BE_DATA(dc
->base
.tb
->flags
) ? MO_BE
: MO_LE
;
12233 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) & 0xf) << 1;
12234 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) >> 4;
12235 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, ARM_TBFLAG_MMUIDX(dc
->base
.tb
->flags
));
12236 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
12237 #if !defined(CONFIG_USER_ONLY)
12238 dc
->user
= (dc
->current_el
== 0);
12240 dc
->ns
= ARM_TBFLAG_NS(dc
->base
.tb
->flags
);
12241 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(dc
->base
.tb
->flags
);
12242 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(dc
->base
.tb
->flags
);
12243 dc
->vec_len
= ARM_TBFLAG_VECLEN(dc
->base
.tb
->flags
);
12244 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(dc
->base
.tb
->flags
);
12245 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(dc
->base
.tb
->flags
);
12246 dc
->v7m_handler_mode
= ARM_TBFLAG_HANDLER(dc
->base
.tb
->flags
);
12247 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
12248 regime_is_secure(env
, dc
->mmu_idx
);
12249 dc
->cp_regs
= cpu
->cp_regs
;
12250 dc
->features
= env
->features
;
12252 /* Single step state. The code-generation logic here is:
12254 * generate code with no special handling for single-stepping (except
12255 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12256 * this happens anyway because those changes are all system register or
12258 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12259 * emit code for one insn
12260 * emit code to clear PSTATE.SS
12261 * emit code to generate software step exception for completed step
12262 * end TB (as usual for having generated an exception)
12263 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12264 * emit code to generate a software step exception
12267 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(dc
->base
.tb
->flags
);
12268 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(dc
->base
.tb
->flags
);
12269 dc
->is_ldex
= false;
12270 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
12272 dc
->next_page_start
=
12273 (dc
->base
.pc_first
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
12275 /* If architectural single step active, limit to 1. */
12276 if (is_singlestepping(dc
)) {
12280 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12281 to those left on the page. */
12283 int bound
= (dc
->next_page_start
- dc
->base
.pc_first
) / 4;
12284 max_insns
= MIN(max_insns
, bound
);
12287 cpu_F0s
= tcg_temp_new_i32();
12288 cpu_F1s
= tcg_temp_new_i32();
12289 cpu_F0d
= tcg_temp_new_i64();
12290 cpu_F1d
= tcg_temp_new_i64();
12293 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12294 cpu_M0
= tcg_temp_new_i64();
12299 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12301 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12303 /* A note on handling of the condexec (IT) bits:
12305 * We want to avoid the overhead of having to write the updated condexec
12306 * bits back to the CPUARMState for every instruction in an IT block. So:
12307 * (1) if the condexec bits are not already zero then we write
12308 * zero back into the CPUARMState now. This avoids complications trying
12309 * to do it at the end of the block. (For example if we don't do this
12310 * it's hard to identify whether we can safely skip writing condexec
12311 * at the end of the TB, which we definitely want to do for the case
12312 * where a TB doesn't do anything with the IT state at all.)
12313 * (2) if we are going to leave the TB then we call gen_set_condexec()
12314 * which will write the correct value into CPUARMState if zero is wrong.
12315 * This is done both for leaving the TB at the end, and for leaving
12316 * it because of an exception we know will happen, which is done in
12317 * gen_exception_insn(). The latter is necessary because we need to
12318 * leave the TB with the PC/IT state just prior to execution of the
12319 * instruction which caused the exception.
12320 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12321 * then the CPUARMState will be wrong and we need to reset it.
12322 * This is handled in the same way as restoration of the
12323 * PC in these situations; we save the value of the condexec bits
12324 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12325 * then uses this to restore them after an exception.
12327 * Note that there are no instructions which can read the condexec
12328 * bits, and none which can write non-static values to them, so
12329 * we don't need to care about whether CPUARMState is correct in the
12333 /* Reset the conditional execution bits immediately. This avoids
12334 complications trying to do it at the end of the block. */
12335 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
12336 TCGv_i32 tmp
= tcg_temp_new_i32();
12337 tcg_gen_movi_i32(tmp
, 0);
12338 store_cpu_field(tmp
, condexec_bits
);
12340 tcg_clear_temp_count();
12343 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12345 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12347 tcg_gen_insn_start(dc
->pc
,
12348 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
12350 dc
->insn_start
= tcg_last_op();
12353 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
12354 const CPUBreakpoint
*bp
)
12356 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12358 if (bp
->flags
& BP_CPU
) {
12359 gen_set_condexec(dc
);
12360 gen_set_pc_im(dc
, dc
->pc
);
12361 gen_helper_check_breakpoints(cpu_env
);
12362 /* End the TB early; it's likely not going to be executed */
12363 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12365 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
12366 /* The address covered by the breakpoint must be
12367 included in [tb->pc, tb->pc + tb->size) in order
12368 to for it to be properly cleared -- thus we
12369 increment the PC here so that the logic setting
12370 tb->size below does the right thing. */
12371 /* TODO: Advance PC by correct instruction length to
12372 * avoid disassembler error messages */
12374 dc
->base
.is_jmp
= DISAS_NORETURN
;
12380 static bool arm_pre_translate_insn(DisasContext
*dc
)
12382 #ifdef CONFIG_USER_ONLY
12383 /* Intercept jump to the magic kernel page. */
12384 if (dc
->pc
>= 0xffff0000) {
12385 /* We always get here via a jump, so know we are not in a
12386 conditional execution block. */
12387 gen_exception_internal(EXCP_KERNEL_TRAP
);
12388 dc
->base
.is_jmp
= DISAS_NORETURN
;
12393 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12394 /* Singlestep state is Active-pending.
12395 * If we're in this state at the start of a TB then either
12396 * a) we just took an exception to an EL which is being debugged
12397 * and this is the first insn in the exception handler
12398 * b) debug exceptions were masked and we just unmasked them
12399 * without changing EL (eg by clearing PSTATE.D)
12400 * In either case we're going to take a swstep exception in the
12401 * "did not step an insn" case, and so the syndrome ISV and EX
12402 * bits should be zero.
12404 assert(dc
->base
.num_insns
== 1);
12405 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
12406 default_exception_el(dc
));
12407 dc
->base
.is_jmp
= DISAS_NORETURN
;
12414 static void arm_post_translate_insn(DisasContext
*dc
)
12416 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12417 gen_set_label(dc
->condlabel
);
12420 dc
->base
.pc_next
= dc
->pc
;
12421 translator_loop_temp_check(&dc
->base
);
12424 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12426 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12427 CPUARMState
*env
= cpu
->env_ptr
;
12430 if (arm_pre_translate_insn(dc
)) {
12434 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12437 disas_arm_insn(dc
, insn
);
12439 arm_post_translate_insn(dc
);
12441 /* ARM is a fixed-length ISA. We performed the cross-page check
12442 in init_disas_context by adjusting max_insns. */
12445 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
12447 /* Return true if this Thumb insn is always unconditional,
12448 * even inside an IT block. This is true of only a very few
12449 * instructions: BKPT, HLT, and SG.
12451 * A larger class of instructions are UNPREDICTABLE if used
12452 * inside an IT block; we do not need to detect those here, because
12453 * what we do by default (perform the cc check and update the IT
12454 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12455 * choice for those situations.
12457 * insn is either a 16-bit or a 32-bit instruction; the two are
12458 * distinguishable because for the 16-bit case the top 16 bits
12459 * are zeroes, and that isn't a valid 32-bit encoding.
12461 if ((insn
& 0xffffff00) == 0xbe00) {
12466 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12467 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
12468 /* HLT: v8A only. This is unconditional even when it is going to
12469 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12470 * For v7 cores this was a plain old undefined encoding and so
12471 * honours its cc check. (We might be using the encoding as
12472 * a semihosting trap, but we don't change the cc check behaviour
12473 * on that account, because a debugger connected to a real v7A
12474 * core and emulating semihosting traps by catching the UNDEF
12475 * exception would also only see cases where the cc check passed.
12476 * No guest code should be trying to do a HLT semihosting trap
12477 * in an IT block anyway.
12482 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12483 arm_dc_feature(s
, ARM_FEATURE_M
)) {
12491 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12493 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12494 CPUARMState
*env
= cpu
->env_ptr
;
12498 if (arm_pre_translate_insn(dc
)) {
12502 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12503 is_16bit
= thumb_insn_is_16bit(dc
, insn
);
12506 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12508 insn
= insn
<< 16 | insn2
;
12513 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
12514 uint32_t cond
= dc
->condexec_cond
;
12516 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
12517 dc
->condlabel
= gen_new_label();
12518 arm_gen_test_cc(cond
^ 1, dc
->condlabel
);
12524 disas_thumb_insn(dc
, insn
);
12526 disas_thumb2_insn(dc
, insn
);
12529 /* Advance the Thumb condexec condition. */
12530 if (dc
->condexec_mask
) {
12531 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
12532 ((dc
->condexec_mask
>> 4) & 1));
12533 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12534 if (dc
->condexec_mask
== 0) {
12535 dc
->condexec_cond
= 0;
12539 arm_post_translate_insn(dc
);
12541 /* Thumb is a variable-length ISA. Stop translation when the next insn
12542 * will touch a new page. This ensures that prefetch aborts occur at
12545 * We want to stop the TB if the next insn starts in a new page,
12546 * or if it spans between this page and the next. This means that
12547 * if we're looking at the last halfword in the page we need to
12548 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12549 * or a 32-bit Thumb insn (which won't).
12550 * This is to avoid generating a silly TB with a single 16-bit insn
12551 * in it at the end of this page (which would execute correctly
12552 * but isn't very efficient).
12554 if (dc
->base
.is_jmp
== DISAS_NEXT
12555 && (dc
->pc
>= dc
->next_page_start
12556 || (dc
->pc
>= dc
->next_page_start
- 3
12557 && insn_crosses_page(env
, dc
)))) {
12558 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12562 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
12564 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12566 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
12567 /* FIXME: This can theoretically happen with self-modifying code. */
12568 cpu_abort(cpu
, "IO on conditional branch instruction");
12571 /* At this stage dc->condjmp will only be set when the skipped
12572 instruction was a conditional branch or trap, and the PC has
12573 already been written. */
12574 gen_set_condexec(dc
);
12575 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12576 /* Exception return branches need some special case code at the
12577 * end of the TB, which is complex enough that it has to
12578 * handle the single-step vs not and the condition-failed
12579 * insn codepath itself.
12581 gen_bx_excret_final_code(dc
);
12582 } else if (unlikely(is_singlestepping(dc
))) {
12583 /* Unconditional and "condition passed" instruction codepath. */
12584 switch (dc
->base
.is_jmp
) {
12586 gen_ss_advance(dc
);
12587 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12588 default_exception_el(dc
));
12591 gen_ss_advance(dc
);
12592 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12595 gen_ss_advance(dc
);
12596 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12599 case DISAS_TOO_MANY
:
12601 gen_set_pc_im(dc
, dc
->pc
);
12604 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12605 gen_singlestep_exception(dc
);
12607 case DISAS_NORETURN
:
12611 /* While branches must always occur at the end of an IT block,
12612 there are a few other things that can cause us to terminate
12613 the TB in the middle of an IT block:
12614 - Exception generating instructions (bkpt, swi, undefined).
12616 - Hardware watchpoints.
12617 Hardware breakpoints have already been handled and skip this code.
12619 switch(dc
->base
.is_jmp
) {
12621 case DISAS_TOO_MANY
:
12622 gen_goto_tb(dc
, 1, dc
->pc
);
12628 gen_set_pc_im(dc
, dc
->pc
);
12631 /* indicate that the hash table must be used to find the next TB */
12632 tcg_gen_exit_tb(0);
12634 case DISAS_NORETURN
:
12635 /* nothing more to generate */
12639 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
12640 !(dc
->insn
& (1U << 31))) ? 2 : 4);
12642 gen_helper_wfi(cpu_env
, tmp
);
12643 tcg_temp_free_i32(tmp
);
12644 /* The helper doesn't necessarily throw an exception, but we
12645 * must go back to the main loop to check for interrupts anyway.
12647 tcg_gen_exit_tb(0);
12651 gen_helper_wfe(cpu_env
);
12654 gen_helper_yield(cpu_env
);
12657 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12658 default_exception_el(dc
));
12661 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12664 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12670 /* "Condition failed" instruction codepath for the branch/trap insn */
12671 gen_set_label(dc
->condlabel
);
12672 gen_set_condexec(dc
);
12673 if (unlikely(is_singlestepping(dc
))) {
12674 gen_set_pc_im(dc
, dc
->pc
);
12675 gen_singlestep_exception(dc
);
12677 gen_goto_tb(dc
, 1, dc
->pc
);
12681 /* Functions above can change dc->pc, so re-align db->pc_next */
12682 dc
->base
.pc_next
= dc
->pc
;
12685 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
12687 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12689 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
12690 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
12693 static const TranslatorOps arm_translator_ops
= {
12694 .init_disas_context
= arm_tr_init_disas_context
,
12695 .tb_start
= arm_tr_tb_start
,
12696 .insn_start
= arm_tr_insn_start
,
12697 .breakpoint_check
= arm_tr_breakpoint_check
,
12698 .translate_insn
= arm_tr_translate_insn
,
12699 .tb_stop
= arm_tr_tb_stop
,
12700 .disas_log
= arm_tr_disas_log
,
12703 static const TranslatorOps thumb_translator_ops
= {
12704 .init_disas_context
= arm_tr_init_disas_context
,
12705 .tb_start
= arm_tr_tb_start
,
12706 .insn_start
= arm_tr_insn_start
,
12707 .breakpoint_check
= arm_tr_breakpoint_check
,
12708 .translate_insn
= thumb_tr_translate_insn
,
12709 .tb_stop
= arm_tr_tb_stop
,
12710 .disas_log
= arm_tr_disas_log
,
12713 /* generate intermediate code for basic block 'tb'. */
12714 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
)
12717 const TranslatorOps
*ops
= &arm_translator_ops
;
12719 if (ARM_TBFLAG_THUMB(tb
->flags
)) {
12720 ops
= &thumb_translator_ops
;
12722 #ifdef TARGET_AARCH64
12723 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
12724 ops
= &aarch64_translator_ops
;
12728 translator_loop(ops
, &dc
.base
, cpu
, tb
);
12731 static const char *cpu_mode_names
[16] = {
12732 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12733 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12736 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12739 ARMCPU
*cpu
= ARM_CPU(cs
);
12740 CPUARMState
*env
= &cpu
->env
;
12744 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12748 for(i
=0;i
<16;i
++) {
12749 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12751 cpu_fprintf(f
, "\n");
12753 cpu_fprintf(f
, " ");
12756 if (arm_feature(env
, ARM_FEATURE_M
)) {
12757 uint32_t xpsr
= xpsr_read(env
);
12759 const char *ns_status
= "";
12761 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
12762 ns_status
= env
->v7m
.secure
? "S " : "NS ";
12765 if (xpsr
& XPSR_EXCP
) {
12768 if (env
->v7m
.control
[env
->v7m
.secure
] & R_V7M_CONTROL_NPRIV_MASK
) {
12769 mode
= "unpriv-thread";
12771 mode
= "priv-thread";
12775 cpu_fprintf(f
, "XPSR=%08x %c%c%c%c %c %s%s\n",
12777 xpsr
& XPSR_N
? 'N' : '-',
12778 xpsr
& XPSR_Z
? 'Z' : '-',
12779 xpsr
& XPSR_C
? 'C' : '-',
12780 xpsr
& XPSR_V
? 'V' : '-',
12781 xpsr
& XPSR_T
? 'T' : 'A',
12785 uint32_t psr
= cpsr_read(env
);
12786 const char *ns_status
= "";
12788 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12789 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12790 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12793 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12795 psr
& CPSR_N
? 'N' : '-',
12796 psr
& CPSR_Z
? 'Z' : '-',
12797 psr
& CPSR_C
? 'C' : '-',
12798 psr
& CPSR_V
? 'V' : '-',
12799 psr
& CPSR_T
? 'T' : 'A',
12801 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12804 if (flags
& CPU_DUMP_FPU
) {
12805 int numvfpregs
= 0;
12806 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12809 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12812 for (i
= 0; i
< numvfpregs
; i
++) {
12813 uint64_t v
= *aa32_vfp_dreg(env
, i
);
12814 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12815 i
* 2, (uint32_t)v
,
12816 i
* 2 + 1, (uint32_t)(v
>> 32),
12819 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12823 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12824 target_ulong
*data
)
12828 env
->condexec_bits
= 0;
12829 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12831 env
->regs
[15] = data
[0];
12832 env
->condexec_bits
= data
[1];
12833 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;