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 /* Force a TB lookup after an instruction that changes the CPU state. */
1252 static inline void gen_lookup_tb(DisasContext
*s
)
1254 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1255 s
->base
.is_jmp
= DISAS_EXIT
;
1258 static inline void gen_hlt(DisasContext
*s
, int imm
)
1260 /* HLT. This has two purposes.
1261 * Architecturally, it is an external halting debug instruction.
1262 * Since QEMU doesn't implement external debug, we treat this as
1263 * it is required for halting debug disabled: it will UNDEF.
1264 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1265 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1266 * must trigger semihosting even for ARMv7 and earlier, where
1267 * HLT was an undefined encoding.
1268 * In system mode, we don't allow userspace access to
1269 * semihosting, to provide some semblance of security
1270 * (and for consistency with our 32-bit semihosting).
1272 if (semihosting_enabled() &&
1273 #ifndef CONFIG_USER_ONLY
1274 s
->current_el
!= 0 &&
1276 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1277 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1281 gen_exception_insn(s
, s
->thumb
? 2 : 4, EXCP_UDEF
, syn_uncategorized(),
1282 default_exception_el(s
));
1285 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1288 int val
, rm
, shift
, shiftop
;
1291 if (!(insn
& (1 << 25))) {
1294 if (!(insn
& (1 << 23)))
1297 tcg_gen_addi_i32(var
, var
, val
);
1299 /* shift/register */
1301 shift
= (insn
>> 7) & 0x1f;
1302 shiftop
= (insn
>> 5) & 3;
1303 offset
= load_reg(s
, rm
);
1304 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1305 if (!(insn
& (1 << 23)))
1306 tcg_gen_sub_i32(var
, var
, offset
);
1308 tcg_gen_add_i32(var
, var
, offset
);
1309 tcg_temp_free_i32(offset
);
1313 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1314 int extra
, TCGv_i32 var
)
1319 if (insn
& (1 << 22)) {
1321 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1322 if (!(insn
& (1 << 23)))
1326 tcg_gen_addi_i32(var
, var
, val
);
1330 tcg_gen_addi_i32(var
, var
, extra
);
1332 offset
= load_reg(s
, rm
);
1333 if (!(insn
& (1 << 23)))
1334 tcg_gen_sub_i32(var
, var
, offset
);
1336 tcg_gen_add_i32(var
, var
, offset
);
1337 tcg_temp_free_i32(offset
);
1341 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1343 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1346 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1348 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1350 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1354 #define VFP_OP2(name) \
1355 static inline void gen_vfp_##name(int dp) \
1357 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1359 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1361 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1363 tcg_temp_free_ptr(fpst); \
1373 static inline void gen_vfp_F1_mul(int dp
)
1375 /* Like gen_vfp_mul() but put result in F1 */
1376 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1378 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1380 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1382 tcg_temp_free_ptr(fpst
);
1385 static inline void gen_vfp_F1_neg(int dp
)
1387 /* Like gen_vfp_neg() but put result in F1 */
1389 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1391 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1395 static inline void gen_vfp_abs(int dp
)
1398 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1400 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1403 static inline void gen_vfp_neg(int dp
)
1406 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1408 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1411 static inline void gen_vfp_sqrt(int dp
)
1414 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1416 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1419 static inline void gen_vfp_cmp(int dp
)
1422 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1424 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1427 static inline void gen_vfp_cmpe(int dp
)
1430 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1432 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1435 static inline void gen_vfp_F1_ld0(int dp
)
1438 tcg_gen_movi_i64(cpu_F1d
, 0);
1440 tcg_gen_movi_i32(cpu_F1s
, 0);
1443 #define VFP_GEN_ITOF(name) \
1444 static inline void gen_vfp_##name(int dp, int neon) \
1446 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1448 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1450 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1452 tcg_temp_free_ptr(statusptr); \
1459 #define VFP_GEN_FTOI(name) \
1460 static inline void gen_vfp_##name(int dp, int neon) \
1462 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1464 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1466 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1468 tcg_temp_free_ptr(statusptr); \
1477 #define VFP_GEN_FIX(name, round) \
1478 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1480 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1481 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1483 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1486 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1489 tcg_temp_free_i32(tmp_shift); \
1490 tcg_temp_free_ptr(statusptr); \
1492 VFP_GEN_FIX(tosh
, _round_to_zero
)
1493 VFP_GEN_FIX(tosl
, _round_to_zero
)
1494 VFP_GEN_FIX(touh
, _round_to_zero
)
1495 VFP_GEN_FIX(toul
, _round_to_zero
)
1502 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1505 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1507 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1511 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1514 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1516 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1520 static inline long vfp_reg_offset(bool dp
, unsigned reg
)
1523 return offsetof(CPUARMState
, vfp
.zregs
[reg
>> 1].d
[reg
& 1]);
1525 long ofs
= offsetof(CPUARMState
, vfp
.zregs
[reg
>> 2].d
[(reg
>> 1) & 1]);
1527 ofs
+= offsetof(CPU_DoubleU
, l
.upper
);
1529 ofs
+= offsetof(CPU_DoubleU
, l
.lower
);
1535 /* Return the offset of a 32-bit piece of a NEON register.
1536 zero is the least significant end of the register. */
1538 neon_reg_offset (int reg
, int n
)
1542 return vfp_reg_offset(0, sreg
);
1545 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1547 TCGv_i32 tmp
= tcg_temp_new_i32();
1548 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1552 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1554 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1555 tcg_temp_free_i32(var
);
1558 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1560 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1563 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1565 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1568 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1570 TCGv_ptr ret
= tcg_temp_new_ptr();
1571 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1575 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1576 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1577 #define tcg_gen_st_f32 tcg_gen_st_i32
1578 #define tcg_gen_st_f64 tcg_gen_st_i64
1580 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1583 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1585 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1588 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1591 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1593 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1596 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1599 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1601 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1604 #define ARM_CP_RW_BIT (1 << 20)
1606 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1608 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1611 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1613 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1616 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1618 TCGv_i32 var
= tcg_temp_new_i32();
1619 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1623 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1625 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1626 tcg_temp_free_i32(var
);
1629 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1631 iwmmxt_store_reg(cpu_M0
, rn
);
1634 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1636 iwmmxt_load_reg(cpu_M0
, rn
);
1639 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1641 iwmmxt_load_reg(cpu_V1
, rn
);
1642 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1645 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1647 iwmmxt_load_reg(cpu_V1
, rn
);
1648 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1651 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1653 iwmmxt_load_reg(cpu_V1
, rn
);
1654 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1657 #define IWMMXT_OP(name) \
1658 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1660 iwmmxt_load_reg(cpu_V1, rn); \
1661 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1664 #define IWMMXT_OP_ENV(name) \
1665 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1667 iwmmxt_load_reg(cpu_V1, rn); \
1668 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1671 #define IWMMXT_OP_ENV_SIZE(name) \
1672 IWMMXT_OP_ENV(name##b) \
1673 IWMMXT_OP_ENV(name##w) \
1674 IWMMXT_OP_ENV(name##l)
1676 #define IWMMXT_OP_ENV1(name) \
1677 static inline void gen_op_iwmmxt_##name##_M0(void) \
1679 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1693 IWMMXT_OP_ENV_SIZE(unpackl
)
1694 IWMMXT_OP_ENV_SIZE(unpackh
)
1696 IWMMXT_OP_ENV1(unpacklub
)
1697 IWMMXT_OP_ENV1(unpackluw
)
1698 IWMMXT_OP_ENV1(unpacklul
)
1699 IWMMXT_OP_ENV1(unpackhub
)
1700 IWMMXT_OP_ENV1(unpackhuw
)
1701 IWMMXT_OP_ENV1(unpackhul
)
1702 IWMMXT_OP_ENV1(unpacklsb
)
1703 IWMMXT_OP_ENV1(unpacklsw
)
1704 IWMMXT_OP_ENV1(unpacklsl
)
1705 IWMMXT_OP_ENV1(unpackhsb
)
1706 IWMMXT_OP_ENV1(unpackhsw
)
1707 IWMMXT_OP_ENV1(unpackhsl
)
1709 IWMMXT_OP_ENV_SIZE(cmpeq
)
1710 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1711 IWMMXT_OP_ENV_SIZE(cmpgts
)
1713 IWMMXT_OP_ENV_SIZE(mins
)
1714 IWMMXT_OP_ENV_SIZE(minu
)
1715 IWMMXT_OP_ENV_SIZE(maxs
)
1716 IWMMXT_OP_ENV_SIZE(maxu
)
1718 IWMMXT_OP_ENV_SIZE(subn
)
1719 IWMMXT_OP_ENV_SIZE(addn
)
1720 IWMMXT_OP_ENV_SIZE(subu
)
1721 IWMMXT_OP_ENV_SIZE(addu
)
1722 IWMMXT_OP_ENV_SIZE(subs
)
1723 IWMMXT_OP_ENV_SIZE(adds
)
1725 IWMMXT_OP_ENV(avgb0
)
1726 IWMMXT_OP_ENV(avgb1
)
1727 IWMMXT_OP_ENV(avgw0
)
1728 IWMMXT_OP_ENV(avgw1
)
1730 IWMMXT_OP_ENV(packuw
)
1731 IWMMXT_OP_ENV(packul
)
1732 IWMMXT_OP_ENV(packuq
)
1733 IWMMXT_OP_ENV(packsw
)
1734 IWMMXT_OP_ENV(packsl
)
1735 IWMMXT_OP_ENV(packsq
)
1737 static void gen_op_iwmmxt_set_mup(void)
1740 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1741 tcg_gen_ori_i32(tmp
, tmp
, 2);
1742 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1745 static void gen_op_iwmmxt_set_cup(void)
1748 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1749 tcg_gen_ori_i32(tmp
, tmp
, 1);
1750 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1753 static void gen_op_iwmmxt_setpsr_nz(void)
1755 TCGv_i32 tmp
= tcg_temp_new_i32();
1756 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1757 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1760 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1762 iwmmxt_load_reg(cpu_V1
, rn
);
1763 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1764 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1767 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1774 rd
= (insn
>> 16) & 0xf;
1775 tmp
= load_reg(s
, rd
);
1777 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1778 if (insn
& (1 << 24)) {
1780 if (insn
& (1 << 23))
1781 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1783 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1784 tcg_gen_mov_i32(dest
, tmp
);
1785 if (insn
& (1 << 21))
1786 store_reg(s
, rd
, tmp
);
1788 tcg_temp_free_i32(tmp
);
1789 } else if (insn
& (1 << 21)) {
1791 tcg_gen_mov_i32(dest
, tmp
);
1792 if (insn
& (1 << 23))
1793 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1795 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1796 store_reg(s
, rd
, tmp
);
1797 } else if (!(insn
& (1 << 23)))
1802 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1804 int rd
= (insn
>> 0) & 0xf;
1807 if (insn
& (1 << 8)) {
1808 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1811 tmp
= iwmmxt_load_creg(rd
);
1814 tmp
= tcg_temp_new_i32();
1815 iwmmxt_load_reg(cpu_V0
, rd
);
1816 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1818 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1819 tcg_gen_mov_i32(dest
, tmp
);
1820 tcg_temp_free_i32(tmp
);
1824 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1825 (ie. an undefined instruction). */
1826 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1829 int rdhi
, rdlo
, rd0
, rd1
, i
;
1831 TCGv_i32 tmp
, tmp2
, tmp3
;
1833 if ((insn
& 0x0e000e00) == 0x0c000000) {
1834 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1836 rdlo
= (insn
>> 12) & 0xf;
1837 rdhi
= (insn
>> 16) & 0xf;
1838 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1839 iwmmxt_load_reg(cpu_V0
, wrd
);
1840 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1841 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1842 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1843 } else { /* TMCRR */
1844 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1845 iwmmxt_store_reg(cpu_V0
, wrd
);
1846 gen_op_iwmmxt_set_mup();
1851 wrd
= (insn
>> 12) & 0xf;
1852 addr
= tcg_temp_new_i32();
1853 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1854 tcg_temp_free_i32(addr
);
1857 if (insn
& ARM_CP_RW_BIT
) {
1858 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1859 tmp
= tcg_temp_new_i32();
1860 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1861 iwmmxt_store_creg(wrd
, tmp
);
1864 if (insn
& (1 << 8)) {
1865 if (insn
& (1 << 22)) { /* WLDRD */
1866 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1868 } else { /* WLDRW wRd */
1869 tmp
= tcg_temp_new_i32();
1870 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1873 tmp
= tcg_temp_new_i32();
1874 if (insn
& (1 << 22)) { /* WLDRH */
1875 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1876 } else { /* WLDRB */
1877 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1881 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1882 tcg_temp_free_i32(tmp
);
1884 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1887 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1888 tmp
= iwmmxt_load_creg(wrd
);
1889 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1891 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1892 tmp
= tcg_temp_new_i32();
1893 if (insn
& (1 << 8)) {
1894 if (insn
& (1 << 22)) { /* WSTRD */
1895 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1896 } else { /* WSTRW wRd */
1897 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1898 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1901 if (insn
& (1 << 22)) { /* WSTRH */
1902 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1903 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1904 } else { /* WSTRB */
1905 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1906 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1910 tcg_temp_free_i32(tmp
);
1912 tcg_temp_free_i32(addr
);
1916 if ((insn
& 0x0f000000) != 0x0e000000)
1919 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1920 case 0x000: /* WOR */
1921 wrd
= (insn
>> 12) & 0xf;
1922 rd0
= (insn
>> 0) & 0xf;
1923 rd1
= (insn
>> 16) & 0xf;
1924 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1925 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1926 gen_op_iwmmxt_setpsr_nz();
1927 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1928 gen_op_iwmmxt_set_mup();
1929 gen_op_iwmmxt_set_cup();
1931 case 0x011: /* TMCR */
1934 rd
= (insn
>> 12) & 0xf;
1935 wrd
= (insn
>> 16) & 0xf;
1937 case ARM_IWMMXT_wCID
:
1938 case ARM_IWMMXT_wCASF
:
1940 case ARM_IWMMXT_wCon
:
1941 gen_op_iwmmxt_set_cup();
1943 case ARM_IWMMXT_wCSSF
:
1944 tmp
= iwmmxt_load_creg(wrd
);
1945 tmp2
= load_reg(s
, rd
);
1946 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1947 tcg_temp_free_i32(tmp2
);
1948 iwmmxt_store_creg(wrd
, tmp
);
1950 case ARM_IWMMXT_wCGR0
:
1951 case ARM_IWMMXT_wCGR1
:
1952 case ARM_IWMMXT_wCGR2
:
1953 case ARM_IWMMXT_wCGR3
:
1954 gen_op_iwmmxt_set_cup();
1955 tmp
= load_reg(s
, rd
);
1956 iwmmxt_store_creg(wrd
, tmp
);
1962 case 0x100: /* WXOR */
1963 wrd
= (insn
>> 12) & 0xf;
1964 rd0
= (insn
>> 0) & 0xf;
1965 rd1
= (insn
>> 16) & 0xf;
1966 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1967 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1968 gen_op_iwmmxt_setpsr_nz();
1969 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1970 gen_op_iwmmxt_set_mup();
1971 gen_op_iwmmxt_set_cup();
1973 case 0x111: /* TMRC */
1976 rd
= (insn
>> 12) & 0xf;
1977 wrd
= (insn
>> 16) & 0xf;
1978 tmp
= iwmmxt_load_creg(wrd
);
1979 store_reg(s
, rd
, tmp
);
1981 case 0x300: /* WANDN */
1982 wrd
= (insn
>> 12) & 0xf;
1983 rd0
= (insn
>> 0) & 0xf;
1984 rd1
= (insn
>> 16) & 0xf;
1985 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1986 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1987 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1988 gen_op_iwmmxt_setpsr_nz();
1989 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1990 gen_op_iwmmxt_set_mup();
1991 gen_op_iwmmxt_set_cup();
1993 case 0x200: /* WAND */
1994 wrd
= (insn
>> 12) & 0xf;
1995 rd0
= (insn
>> 0) & 0xf;
1996 rd1
= (insn
>> 16) & 0xf;
1997 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1998 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1999 gen_op_iwmmxt_setpsr_nz();
2000 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2001 gen_op_iwmmxt_set_mup();
2002 gen_op_iwmmxt_set_cup();
2004 case 0x810: case 0xa10: /* WMADD */
2005 wrd
= (insn
>> 12) & 0xf;
2006 rd0
= (insn
>> 0) & 0xf;
2007 rd1
= (insn
>> 16) & 0xf;
2008 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2009 if (insn
& (1 << 21))
2010 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
2012 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
2013 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2014 gen_op_iwmmxt_set_mup();
2016 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2017 wrd
= (insn
>> 12) & 0xf;
2018 rd0
= (insn
>> 16) & 0xf;
2019 rd1
= (insn
>> 0) & 0xf;
2020 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2021 switch ((insn
>> 22) & 3) {
2023 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
2026 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
2029 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
2034 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2035 gen_op_iwmmxt_set_mup();
2036 gen_op_iwmmxt_set_cup();
2038 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2039 wrd
= (insn
>> 12) & 0xf;
2040 rd0
= (insn
>> 16) & 0xf;
2041 rd1
= (insn
>> 0) & 0xf;
2042 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2043 switch ((insn
>> 22) & 3) {
2045 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
2048 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
2051 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
2056 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2057 gen_op_iwmmxt_set_mup();
2058 gen_op_iwmmxt_set_cup();
2060 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2061 wrd
= (insn
>> 12) & 0xf;
2062 rd0
= (insn
>> 16) & 0xf;
2063 rd1
= (insn
>> 0) & 0xf;
2064 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2065 if (insn
& (1 << 22))
2066 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2068 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2069 if (!(insn
& (1 << 20)))
2070 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2071 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2072 gen_op_iwmmxt_set_mup();
2074 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2075 wrd
= (insn
>> 12) & 0xf;
2076 rd0
= (insn
>> 16) & 0xf;
2077 rd1
= (insn
>> 0) & 0xf;
2078 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2079 if (insn
& (1 << 21)) {
2080 if (insn
& (1 << 20))
2081 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2083 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2085 if (insn
& (1 << 20))
2086 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2088 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2090 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2091 gen_op_iwmmxt_set_mup();
2093 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2094 wrd
= (insn
>> 12) & 0xf;
2095 rd0
= (insn
>> 16) & 0xf;
2096 rd1
= (insn
>> 0) & 0xf;
2097 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2098 if (insn
& (1 << 21))
2099 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2101 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2102 if (!(insn
& (1 << 20))) {
2103 iwmmxt_load_reg(cpu_V1
, wrd
);
2104 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2106 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2107 gen_op_iwmmxt_set_mup();
2109 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2110 wrd
= (insn
>> 12) & 0xf;
2111 rd0
= (insn
>> 16) & 0xf;
2112 rd1
= (insn
>> 0) & 0xf;
2113 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2114 switch ((insn
>> 22) & 3) {
2116 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2119 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2122 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2127 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2128 gen_op_iwmmxt_set_mup();
2129 gen_op_iwmmxt_set_cup();
2131 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2132 wrd
= (insn
>> 12) & 0xf;
2133 rd0
= (insn
>> 16) & 0xf;
2134 rd1
= (insn
>> 0) & 0xf;
2135 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2136 if (insn
& (1 << 22)) {
2137 if (insn
& (1 << 20))
2138 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2140 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2142 if (insn
& (1 << 20))
2143 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2145 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2147 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2148 gen_op_iwmmxt_set_mup();
2149 gen_op_iwmmxt_set_cup();
2151 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2152 wrd
= (insn
>> 12) & 0xf;
2153 rd0
= (insn
>> 16) & 0xf;
2154 rd1
= (insn
>> 0) & 0xf;
2155 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2156 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2157 tcg_gen_andi_i32(tmp
, tmp
, 7);
2158 iwmmxt_load_reg(cpu_V1
, rd1
);
2159 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2160 tcg_temp_free_i32(tmp
);
2161 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2162 gen_op_iwmmxt_set_mup();
2164 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2165 if (((insn
>> 6) & 3) == 3)
2167 rd
= (insn
>> 12) & 0xf;
2168 wrd
= (insn
>> 16) & 0xf;
2169 tmp
= load_reg(s
, rd
);
2170 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2171 switch ((insn
>> 6) & 3) {
2173 tmp2
= tcg_const_i32(0xff);
2174 tmp3
= tcg_const_i32((insn
& 7) << 3);
2177 tmp2
= tcg_const_i32(0xffff);
2178 tmp3
= tcg_const_i32((insn
& 3) << 4);
2181 tmp2
= tcg_const_i32(0xffffffff);
2182 tmp3
= tcg_const_i32((insn
& 1) << 5);
2188 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2189 tcg_temp_free_i32(tmp3
);
2190 tcg_temp_free_i32(tmp2
);
2191 tcg_temp_free_i32(tmp
);
2192 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2193 gen_op_iwmmxt_set_mup();
2195 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2196 rd
= (insn
>> 12) & 0xf;
2197 wrd
= (insn
>> 16) & 0xf;
2198 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2200 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2201 tmp
= tcg_temp_new_i32();
2202 switch ((insn
>> 22) & 3) {
2204 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2205 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2207 tcg_gen_ext8s_i32(tmp
, tmp
);
2209 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2213 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2214 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2216 tcg_gen_ext16s_i32(tmp
, tmp
);
2218 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2222 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2223 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2226 store_reg(s
, rd
, tmp
);
2228 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2229 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2231 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2232 switch ((insn
>> 22) & 3) {
2234 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2237 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2240 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2243 tcg_gen_shli_i32(tmp
, tmp
, 28);
2245 tcg_temp_free_i32(tmp
);
2247 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2248 if (((insn
>> 6) & 3) == 3)
2250 rd
= (insn
>> 12) & 0xf;
2251 wrd
= (insn
>> 16) & 0xf;
2252 tmp
= load_reg(s
, rd
);
2253 switch ((insn
>> 6) & 3) {
2255 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2258 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2261 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2264 tcg_temp_free_i32(tmp
);
2265 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2266 gen_op_iwmmxt_set_mup();
2268 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2269 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2271 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2272 tmp2
= tcg_temp_new_i32();
2273 tcg_gen_mov_i32(tmp2
, tmp
);
2274 switch ((insn
>> 22) & 3) {
2276 for (i
= 0; i
< 7; i
++) {
2277 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2278 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2282 for (i
= 0; i
< 3; i
++) {
2283 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2284 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2288 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2289 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2293 tcg_temp_free_i32(tmp2
);
2294 tcg_temp_free_i32(tmp
);
2296 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2297 wrd
= (insn
>> 12) & 0xf;
2298 rd0
= (insn
>> 16) & 0xf;
2299 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2300 switch ((insn
>> 22) & 3) {
2302 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2305 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2308 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2313 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2314 gen_op_iwmmxt_set_mup();
2316 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2317 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2319 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2320 tmp2
= tcg_temp_new_i32();
2321 tcg_gen_mov_i32(tmp2
, tmp
);
2322 switch ((insn
>> 22) & 3) {
2324 for (i
= 0; i
< 7; i
++) {
2325 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2326 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2330 for (i
= 0; i
< 3; i
++) {
2331 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2332 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2336 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2337 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2341 tcg_temp_free_i32(tmp2
);
2342 tcg_temp_free_i32(tmp
);
2344 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2345 rd
= (insn
>> 12) & 0xf;
2346 rd0
= (insn
>> 16) & 0xf;
2347 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2349 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2350 tmp
= tcg_temp_new_i32();
2351 switch ((insn
>> 22) & 3) {
2353 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2356 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2359 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2362 store_reg(s
, rd
, tmp
);
2364 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2365 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2366 wrd
= (insn
>> 12) & 0xf;
2367 rd0
= (insn
>> 16) & 0xf;
2368 rd1
= (insn
>> 0) & 0xf;
2369 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2370 switch ((insn
>> 22) & 3) {
2372 if (insn
& (1 << 21))
2373 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2375 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2378 if (insn
& (1 << 21))
2379 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2381 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2384 if (insn
& (1 << 21))
2385 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2387 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2392 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2393 gen_op_iwmmxt_set_mup();
2394 gen_op_iwmmxt_set_cup();
2396 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2397 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2398 wrd
= (insn
>> 12) & 0xf;
2399 rd0
= (insn
>> 16) & 0xf;
2400 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2401 switch ((insn
>> 22) & 3) {
2403 if (insn
& (1 << 21))
2404 gen_op_iwmmxt_unpacklsb_M0();
2406 gen_op_iwmmxt_unpacklub_M0();
2409 if (insn
& (1 << 21))
2410 gen_op_iwmmxt_unpacklsw_M0();
2412 gen_op_iwmmxt_unpackluw_M0();
2415 if (insn
& (1 << 21))
2416 gen_op_iwmmxt_unpacklsl_M0();
2418 gen_op_iwmmxt_unpacklul_M0();
2423 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2424 gen_op_iwmmxt_set_mup();
2425 gen_op_iwmmxt_set_cup();
2427 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2428 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2429 wrd
= (insn
>> 12) & 0xf;
2430 rd0
= (insn
>> 16) & 0xf;
2431 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2432 switch ((insn
>> 22) & 3) {
2434 if (insn
& (1 << 21))
2435 gen_op_iwmmxt_unpackhsb_M0();
2437 gen_op_iwmmxt_unpackhub_M0();
2440 if (insn
& (1 << 21))
2441 gen_op_iwmmxt_unpackhsw_M0();
2443 gen_op_iwmmxt_unpackhuw_M0();
2446 if (insn
& (1 << 21))
2447 gen_op_iwmmxt_unpackhsl_M0();
2449 gen_op_iwmmxt_unpackhul_M0();
2454 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2455 gen_op_iwmmxt_set_mup();
2456 gen_op_iwmmxt_set_cup();
2458 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2459 case 0x214: case 0x614: case 0xa14: case 0xe14:
2460 if (((insn
>> 22) & 3) == 0)
2462 wrd
= (insn
>> 12) & 0xf;
2463 rd0
= (insn
>> 16) & 0xf;
2464 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2465 tmp
= tcg_temp_new_i32();
2466 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2467 tcg_temp_free_i32(tmp
);
2470 switch ((insn
>> 22) & 3) {
2472 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2475 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2478 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2481 tcg_temp_free_i32(tmp
);
2482 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2483 gen_op_iwmmxt_set_mup();
2484 gen_op_iwmmxt_set_cup();
2486 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2487 case 0x014: case 0x414: case 0x814: case 0xc14:
2488 if (((insn
>> 22) & 3) == 0)
2490 wrd
= (insn
>> 12) & 0xf;
2491 rd0
= (insn
>> 16) & 0xf;
2492 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2493 tmp
= tcg_temp_new_i32();
2494 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2495 tcg_temp_free_i32(tmp
);
2498 switch ((insn
>> 22) & 3) {
2500 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2503 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2506 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2509 tcg_temp_free_i32(tmp
);
2510 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2511 gen_op_iwmmxt_set_mup();
2512 gen_op_iwmmxt_set_cup();
2514 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2515 case 0x114: case 0x514: case 0x914: case 0xd14:
2516 if (((insn
>> 22) & 3) == 0)
2518 wrd
= (insn
>> 12) & 0xf;
2519 rd0
= (insn
>> 16) & 0xf;
2520 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2521 tmp
= tcg_temp_new_i32();
2522 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2523 tcg_temp_free_i32(tmp
);
2526 switch ((insn
>> 22) & 3) {
2528 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2531 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2534 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2537 tcg_temp_free_i32(tmp
);
2538 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2539 gen_op_iwmmxt_set_mup();
2540 gen_op_iwmmxt_set_cup();
2542 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2543 case 0x314: case 0x714: case 0xb14: case 0xf14:
2544 if (((insn
>> 22) & 3) == 0)
2546 wrd
= (insn
>> 12) & 0xf;
2547 rd0
= (insn
>> 16) & 0xf;
2548 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2549 tmp
= tcg_temp_new_i32();
2550 switch ((insn
>> 22) & 3) {
2552 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2553 tcg_temp_free_i32(tmp
);
2556 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2559 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2560 tcg_temp_free_i32(tmp
);
2563 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2566 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2567 tcg_temp_free_i32(tmp
);
2570 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2573 tcg_temp_free_i32(tmp
);
2574 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2575 gen_op_iwmmxt_set_mup();
2576 gen_op_iwmmxt_set_cup();
2578 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2579 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2580 wrd
= (insn
>> 12) & 0xf;
2581 rd0
= (insn
>> 16) & 0xf;
2582 rd1
= (insn
>> 0) & 0xf;
2583 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2584 switch ((insn
>> 22) & 3) {
2586 if (insn
& (1 << 21))
2587 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2589 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2592 if (insn
& (1 << 21))
2593 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2595 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2598 if (insn
& (1 << 21))
2599 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2601 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2606 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2607 gen_op_iwmmxt_set_mup();
2609 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2610 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2611 wrd
= (insn
>> 12) & 0xf;
2612 rd0
= (insn
>> 16) & 0xf;
2613 rd1
= (insn
>> 0) & 0xf;
2614 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2615 switch ((insn
>> 22) & 3) {
2617 if (insn
& (1 << 21))
2618 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2620 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2623 if (insn
& (1 << 21))
2624 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2626 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2629 if (insn
& (1 << 21))
2630 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2632 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2637 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2638 gen_op_iwmmxt_set_mup();
2640 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2641 case 0x402: case 0x502: case 0x602: case 0x702:
2642 wrd
= (insn
>> 12) & 0xf;
2643 rd0
= (insn
>> 16) & 0xf;
2644 rd1
= (insn
>> 0) & 0xf;
2645 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2646 tmp
= tcg_const_i32((insn
>> 20) & 3);
2647 iwmmxt_load_reg(cpu_V1
, rd1
);
2648 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2649 tcg_temp_free_i32(tmp
);
2650 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2651 gen_op_iwmmxt_set_mup();
2653 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2654 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2655 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2656 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2657 wrd
= (insn
>> 12) & 0xf;
2658 rd0
= (insn
>> 16) & 0xf;
2659 rd1
= (insn
>> 0) & 0xf;
2660 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2661 switch ((insn
>> 20) & 0xf) {
2663 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2666 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2669 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2672 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2675 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2678 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2681 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2684 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2687 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2692 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2693 gen_op_iwmmxt_set_mup();
2694 gen_op_iwmmxt_set_cup();
2696 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2697 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2698 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2699 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2700 wrd
= (insn
>> 12) & 0xf;
2701 rd0
= (insn
>> 16) & 0xf;
2702 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2703 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2704 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2705 tcg_temp_free_i32(tmp
);
2706 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2707 gen_op_iwmmxt_set_mup();
2708 gen_op_iwmmxt_set_cup();
2710 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2711 case 0x418: case 0x518: case 0x618: case 0x718:
2712 case 0x818: case 0x918: case 0xa18: case 0xb18:
2713 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2714 wrd
= (insn
>> 12) & 0xf;
2715 rd0
= (insn
>> 16) & 0xf;
2716 rd1
= (insn
>> 0) & 0xf;
2717 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2718 switch ((insn
>> 20) & 0xf) {
2720 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2723 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2726 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2729 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2732 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2735 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2738 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2741 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2744 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2749 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2750 gen_op_iwmmxt_set_mup();
2751 gen_op_iwmmxt_set_cup();
2753 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2754 case 0x408: case 0x508: case 0x608: case 0x708:
2755 case 0x808: case 0x908: case 0xa08: case 0xb08:
2756 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2757 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2759 wrd
= (insn
>> 12) & 0xf;
2760 rd0
= (insn
>> 16) & 0xf;
2761 rd1
= (insn
>> 0) & 0xf;
2762 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2763 switch ((insn
>> 22) & 3) {
2765 if (insn
& (1 << 21))
2766 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2768 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2771 if (insn
& (1 << 21))
2772 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2774 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2777 if (insn
& (1 << 21))
2778 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2780 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2783 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2784 gen_op_iwmmxt_set_mup();
2785 gen_op_iwmmxt_set_cup();
2787 case 0x201: case 0x203: case 0x205: case 0x207:
2788 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2789 case 0x211: case 0x213: case 0x215: case 0x217:
2790 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2791 wrd
= (insn
>> 5) & 0xf;
2792 rd0
= (insn
>> 12) & 0xf;
2793 rd1
= (insn
>> 0) & 0xf;
2794 if (rd0
== 0xf || rd1
== 0xf)
2796 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2797 tmp
= load_reg(s
, rd0
);
2798 tmp2
= load_reg(s
, rd1
);
2799 switch ((insn
>> 16) & 0xf) {
2800 case 0x0: /* TMIA */
2801 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2803 case 0x8: /* TMIAPH */
2804 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2806 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2807 if (insn
& (1 << 16))
2808 tcg_gen_shri_i32(tmp
, tmp
, 16);
2809 if (insn
& (1 << 17))
2810 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2811 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2814 tcg_temp_free_i32(tmp2
);
2815 tcg_temp_free_i32(tmp
);
2818 tcg_temp_free_i32(tmp2
);
2819 tcg_temp_free_i32(tmp
);
2820 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2821 gen_op_iwmmxt_set_mup();
2830 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2831 (ie. an undefined instruction). */
2832 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2834 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2837 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2838 /* Multiply with Internal Accumulate Format */
2839 rd0
= (insn
>> 12) & 0xf;
2841 acc
= (insn
>> 5) & 7;
2846 tmp
= load_reg(s
, rd0
);
2847 tmp2
= load_reg(s
, rd1
);
2848 switch ((insn
>> 16) & 0xf) {
2850 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2852 case 0x8: /* MIAPH */
2853 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2855 case 0xc: /* MIABB */
2856 case 0xd: /* MIABT */
2857 case 0xe: /* MIATB */
2858 case 0xf: /* MIATT */
2859 if (insn
& (1 << 16))
2860 tcg_gen_shri_i32(tmp
, tmp
, 16);
2861 if (insn
& (1 << 17))
2862 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2863 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2868 tcg_temp_free_i32(tmp2
);
2869 tcg_temp_free_i32(tmp
);
2871 gen_op_iwmmxt_movq_wRn_M0(acc
);
2875 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2876 /* Internal Accumulator Access Format */
2877 rdhi
= (insn
>> 16) & 0xf;
2878 rdlo
= (insn
>> 12) & 0xf;
2884 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2885 iwmmxt_load_reg(cpu_V0
, acc
);
2886 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2887 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2888 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2889 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2891 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2892 iwmmxt_store_reg(cpu_V0
, acc
);
2900 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2901 #define VFP_SREG(insn, bigbit, smallbit) \
2902 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2903 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2904 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2905 reg = (((insn) >> (bigbit)) & 0x0f) \
2906 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2908 if (insn & (1 << (smallbit))) \
2910 reg = ((insn) >> (bigbit)) & 0x0f; \
2913 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2914 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2915 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2916 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2917 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2918 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2920 /* Move between integer and VFP cores. */
2921 static TCGv_i32
gen_vfp_mrs(void)
2923 TCGv_i32 tmp
= tcg_temp_new_i32();
2924 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2928 static void gen_vfp_msr(TCGv_i32 tmp
)
2930 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2931 tcg_temp_free_i32(tmp
);
2934 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2936 TCGv_i32 tmp
= tcg_temp_new_i32();
2938 tcg_gen_shri_i32(var
, var
, shift
);
2939 tcg_gen_ext8u_i32(var
, var
);
2940 tcg_gen_shli_i32(tmp
, var
, 8);
2941 tcg_gen_or_i32(var
, var
, tmp
);
2942 tcg_gen_shli_i32(tmp
, var
, 16);
2943 tcg_gen_or_i32(var
, var
, tmp
);
2944 tcg_temp_free_i32(tmp
);
2947 static void gen_neon_dup_low16(TCGv_i32 var
)
2949 TCGv_i32 tmp
= tcg_temp_new_i32();
2950 tcg_gen_ext16u_i32(var
, var
);
2951 tcg_gen_shli_i32(tmp
, var
, 16);
2952 tcg_gen_or_i32(var
, var
, tmp
);
2953 tcg_temp_free_i32(tmp
);
2956 static void gen_neon_dup_high16(TCGv_i32 var
)
2958 TCGv_i32 tmp
= tcg_temp_new_i32();
2959 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2960 tcg_gen_shri_i32(tmp
, var
, 16);
2961 tcg_gen_or_i32(var
, var
, tmp
);
2962 tcg_temp_free_i32(tmp
);
2965 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2967 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2968 TCGv_i32 tmp
= tcg_temp_new_i32();
2971 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2972 gen_neon_dup_u8(tmp
, 0);
2975 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2976 gen_neon_dup_low16(tmp
);
2979 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2981 default: /* Avoid compiler warnings. */
2987 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2990 uint32_t cc
= extract32(insn
, 20, 2);
2993 TCGv_i64 frn
, frm
, dest
;
2994 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2996 zero
= tcg_const_i64(0);
2998 frn
= tcg_temp_new_i64();
2999 frm
= tcg_temp_new_i64();
3000 dest
= tcg_temp_new_i64();
3002 zf
= tcg_temp_new_i64();
3003 nf
= tcg_temp_new_i64();
3004 vf
= tcg_temp_new_i64();
3006 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
3007 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
3008 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
3010 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3011 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3014 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
3018 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
3021 case 2: /* ge: N == V -> N ^ V == 0 */
3022 tmp
= tcg_temp_new_i64();
3023 tcg_gen_xor_i64(tmp
, vf
, nf
);
3024 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
3026 tcg_temp_free_i64(tmp
);
3028 case 3: /* gt: !Z && N == V */
3029 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
3031 tmp
= tcg_temp_new_i64();
3032 tcg_gen_xor_i64(tmp
, vf
, nf
);
3033 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
3035 tcg_temp_free_i64(tmp
);
3038 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3039 tcg_temp_free_i64(frn
);
3040 tcg_temp_free_i64(frm
);
3041 tcg_temp_free_i64(dest
);
3043 tcg_temp_free_i64(zf
);
3044 tcg_temp_free_i64(nf
);
3045 tcg_temp_free_i64(vf
);
3047 tcg_temp_free_i64(zero
);
3049 TCGv_i32 frn
, frm
, dest
;
3052 zero
= tcg_const_i32(0);
3054 frn
= tcg_temp_new_i32();
3055 frm
= tcg_temp_new_i32();
3056 dest
= tcg_temp_new_i32();
3057 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3058 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3061 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
3065 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
3068 case 2: /* ge: N == V -> N ^ V == 0 */
3069 tmp
= tcg_temp_new_i32();
3070 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3071 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3073 tcg_temp_free_i32(tmp
);
3075 case 3: /* gt: !Z && N == V */
3076 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
3078 tmp
= tcg_temp_new_i32();
3079 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3080 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3082 tcg_temp_free_i32(tmp
);
3085 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3086 tcg_temp_free_i32(frn
);
3087 tcg_temp_free_i32(frm
);
3088 tcg_temp_free_i32(dest
);
3090 tcg_temp_free_i32(zero
);
3096 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
3097 uint32_t rm
, uint32_t dp
)
3099 uint32_t vmin
= extract32(insn
, 6, 1);
3100 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3103 TCGv_i64 frn
, frm
, dest
;
3105 frn
= tcg_temp_new_i64();
3106 frm
= tcg_temp_new_i64();
3107 dest
= tcg_temp_new_i64();
3109 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3110 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3112 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
3114 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
3116 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3117 tcg_temp_free_i64(frn
);
3118 tcg_temp_free_i64(frm
);
3119 tcg_temp_free_i64(dest
);
3121 TCGv_i32 frn
, frm
, dest
;
3123 frn
= tcg_temp_new_i32();
3124 frm
= tcg_temp_new_i32();
3125 dest
= tcg_temp_new_i32();
3127 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3128 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3130 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
3132 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
3134 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3135 tcg_temp_free_i32(frn
);
3136 tcg_temp_free_i32(frm
);
3137 tcg_temp_free_i32(dest
);
3140 tcg_temp_free_ptr(fpst
);
3144 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3147 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3150 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3151 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3156 tcg_op
= tcg_temp_new_i64();
3157 tcg_res
= tcg_temp_new_i64();
3158 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3159 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
3160 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3161 tcg_temp_free_i64(tcg_op
);
3162 tcg_temp_free_i64(tcg_res
);
3166 tcg_op
= tcg_temp_new_i32();
3167 tcg_res
= tcg_temp_new_i32();
3168 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3169 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
3170 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3171 tcg_temp_free_i32(tcg_op
);
3172 tcg_temp_free_i32(tcg_res
);
3175 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3176 tcg_temp_free_i32(tcg_rmode
);
3178 tcg_temp_free_ptr(fpst
);
3182 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3185 bool is_signed
= extract32(insn
, 7, 1);
3186 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3187 TCGv_i32 tcg_rmode
, tcg_shift
;
3189 tcg_shift
= tcg_const_i32(0);
3191 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3192 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3195 TCGv_i64 tcg_double
, tcg_res
;
3197 /* Rd is encoded as a single precision register even when the source
3198 * is double precision.
3200 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3201 tcg_double
= tcg_temp_new_i64();
3202 tcg_res
= tcg_temp_new_i64();
3203 tcg_tmp
= tcg_temp_new_i32();
3204 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3206 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3208 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3210 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3211 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3212 tcg_temp_free_i32(tcg_tmp
);
3213 tcg_temp_free_i64(tcg_res
);
3214 tcg_temp_free_i64(tcg_double
);
3216 TCGv_i32 tcg_single
, tcg_res
;
3217 tcg_single
= tcg_temp_new_i32();
3218 tcg_res
= tcg_temp_new_i32();
3219 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3221 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3223 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3225 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3226 tcg_temp_free_i32(tcg_res
);
3227 tcg_temp_free_i32(tcg_single
);
3230 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3231 tcg_temp_free_i32(tcg_rmode
);
3233 tcg_temp_free_i32(tcg_shift
);
3235 tcg_temp_free_ptr(fpst
);
3240 /* Table for converting the most common AArch32 encoding of
3241 * rounding mode to arm_fprounding order (which matches the
3242 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3244 static const uint8_t fp_decode_rm
[] = {
3251 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3253 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3255 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3260 VFP_DREG_D(rd
, insn
);
3261 VFP_DREG_N(rn
, insn
);
3262 VFP_DREG_M(rm
, insn
);
3264 rd
= VFP_SREG_D(insn
);
3265 rn
= VFP_SREG_N(insn
);
3266 rm
= VFP_SREG_M(insn
);
3269 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3270 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3271 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3272 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3273 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3274 /* VRINTA, VRINTN, VRINTP, VRINTM */
3275 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3276 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3277 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3278 /* VCVTA, VCVTN, VCVTP, VCVTM */
3279 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3280 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3285 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3286 (ie. an undefined instruction). */
3287 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3289 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3295 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3299 /* FIXME: this access check should not take precedence over UNDEF
3300 * for invalid encodings; we will generate incorrect syndrome information
3301 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3303 if (s
->fp_excp_el
) {
3304 gen_exception_insn(s
, 4, EXCP_UDEF
,
3305 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3309 if (!s
->vfp_enabled
) {
3310 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3311 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3313 rn
= (insn
>> 16) & 0xf;
3314 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3315 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3320 if (extract32(insn
, 28, 4) == 0xf) {
3321 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3322 * only used in v8 and above.
3324 return disas_vfp_v8_insn(s
, insn
);
3327 dp
= ((insn
& 0xf00) == 0xb00);
3328 switch ((insn
>> 24) & 0xf) {
3330 if (insn
& (1 << 4)) {
3331 /* single register transfer */
3332 rd
= (insn
>> 12) & 0xf;
3337 VFP_DREG_N(rn
, insn
);
3340 if (insn
& 0x00c00060
3341 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3345 pass
= (insn
>> 21) & 1;
3346 if (insn
& (1 << 22)) {
3348 offset
= ((insn
>> 5) & 3) * 8;
3349 } else if (insn
& (1 << 5)) {
3351 offset
= (insn
& (1 << 6)) ? 16 : 0;
3356 if (insn
& ARM_CP_RW_BIT
) {
3358 tmp
= neon_load_reg(rn
, pass
);
3362 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3363 if (insn
& (1 << 23))
3369 if (insn
& (1 << 23)) {
3371 tcg_gen_shri_i32(tmp
, tmp
, 16);
3377 tcg_gen_sari_i32(tmp
, tmp
, 16);
3386 store_reg(s
, rd
, tmp
);
3389 tmp
= load_reg(s
, rd
);
3390 if (insn
& (1 << 23)) {
3393 gen_neon_dup_u8(tmp
, 0);
3394 } else if (size
== 1) {
3395 gen_neon_dup_low16(tmp
);
3397 for (n
= 0; n
<= pass
* 2; n
++) {
3398 tmp2
= tcg_temp_new_i32();
3399 tcg_gen_mov_i32(tmp2
, tmp
);
3400 neon_store_reg(rn
, n
, tmp2
);
3402 neon_store_reg(rn
, n
, tmp
);
3407 tmp2
= neon_load_reg(rn
, pass
);
3408 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3409 tcg_temp_free_i32(tmp2
);
3412 tmp2
= neon_load_reg(rn
, pass
);
3413 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3414 tcg_temp_free_i32(tmp2
);
3419 neon_store_reg(rn
, pass
, tmp
);
3423 if ((insn
& 0x6f) != 0x00)
3425 rn
= VFP_SREG_N(insn
);
3426 if (insn
& ARM_CP_RW_BIT
) {
3428 if (insn
& (1 << 21)) {
3429 /* system register */
3434 /* VFP2 allows access to FSID from userspace.
3435 VFP3 restricts all id registers to privileged
3438 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3441 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3446 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3448 case ARM_VFP_FPINST
:
3449 case ARM_VFP_FPINST2
:
3450 /* Not present in VFP3. */
3452 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3455 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3459 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3460 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3462 tmp
= tcg_temp_new_i32();
3463 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3467 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3474 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3477 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3483 gen_mov_F0_vreg(0, rn
);
3484 tmp
= gen_vfp_mrs();
3487 /* Set the 4 flag bits in the CPSR. */
3489 tcg_temp_free_i32(tmp
);
3491 store_reg(s
, rd
, tmp
);
3495 if (insn
& (1 << 21)) {
3497 /* system register */
3502 /* Writes are ignored. */
3505 tmp
= load_reg(s
, rd
);
3506 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3507 tcg_temp_free_i32(tmp
);
3513 /* TODO: VFP subarchitecture support.
3514 * For now, keep the EN bit only */
3515 tmp
= load_reg(s
, rd
);
3516 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3517 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3520 case ARM_VFP_FPINST
:
3521 case ARM_VFP_FPINST2
:
3525 tmp
= load_reg(s
, rd
);
3526 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3532 tmp
= load_reg(s
, rd
);
3534 gen_mov_vreg_F0(0, rn
);
3539 /* data processing */
3540 /* The opcode is in bits 23, 21, 20 and 6. */
3541 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3545 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3547 /* rn is register number */
3548 VFP_DREG_N(rn
, insn
);
3551 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3552 ((rn
& 0x1e) == 0x6))) {
3553 /* Integer or single/half precision destination. */
3554 rd
= VFP_SREG_D(insn
);
3556 VFP_DREG_D(rd
, insn
);
3559 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3560 ((rn
& 0x1e) == 0x4))) {
3561 /* VCVT from int or half precision is always from S reg
3562 * regardless of dp bit. VCVT with immediate frac_bits
3563 * has same format as SREG_M.
3565 rm
= VFP_SREG_M(insn
);
3567 VFP_DREG_M(rm
, insn
);
3570 rn
= VFP_SREG_N(insn
);
3571 if (op
== 15 && rn
== 15) {
3572 /* Double precision destination. */
3573 VFP_DREG_D(rd
, insn
);
3575 rd
= VFP_SREG_D(insn
);
3577 /* NB that we implicitly rely on the encoding for the frac_bits
3578 * in VCVT of fixed to float being the same as that of an SREG_M
3580 rm
= VFP_SREG_M(insn
);
3583 veclen
= s
->vec_len
;
3584 if (op
== 15 && rn
> 3)
3587 /* Shut up compiler warnings. */
3598 /* Figure out what type of vector operation this is. */
3599 if ((rd
& bank_mask
) == 0) {
3604 delta_d
= (s
->vec_stride
>> 1) + 1;
3606 delta_d
= s
->vec_stride
+ 1;
3608 if ((rm
& bank_mask
) == 0) {
3609 /* mixed scalar/vector */
3618 /* Load the initial operands. */
3623 /* Integer source */
3624 gen_mov_F0_vreg(0, rm
);
3629 gen_mov_F0_vreg(dp
, rd
);
3630 gen_mov_F1_vreg(dp
, rm
);
3634 /* Compare with zero */
3635 gen_mov_F0_vreg(dp
, rd
);
3646 /* Source and destination the same. */
3647 gen_mov_F0_vreg(dp
, rd
);
3653 /* VCVTB, VCVTT: only present with the halfprec extension
3654 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3655 * (we choose to UNDEF)
3657 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3658 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3661 if (!extract32(rn
, 1, 1)) {
3662 /* Half precision source. */
3663 gen_mov_F0_vreg(0, rm
);
3666 /* Otherwise fall through */
3668 /* One source operand. */
3669 gen_mov_F0_vreg(dp
, rm
);
3673 /* Two source operands. */
3674 gen_mov_F0_vreg(dp
, rn
);
3675 gen_mov_F1_vreg(dp
, rm
);
3679 /* Perform the calculation. */
3681 case 0: /* VMLA: fd + (fn * fm) */
3682 /* Note that order of inputs to the add matters for NaNs */
3684 gen_mov_F0_vreg(dp
, rd
);
3687 case 1: /* VMLS: fd + -(fn * fm) */
3690 gen_mov_F0_vreg(dp
, rd
);
3693 case 2: /* VNMLS: -fd + (fn * fm) */
3694 /* Note that it isn't valid to replace (-A + B) with (B - A)
3695 * or similar plausible looking simplifications
3696 * because this will give wrong results for NaNs.
3699 gen_mov_F0_vreg(dp
, rd
);
3703 case 3: /* VNMLA: -fd + -(fn * fm) */
3706 gen_mov_F0_vreg(dp
, rd
);
3710 case 4: /* mul: fn * fm */
3713 case 5: /* nmul: -(fn * fm) */
3717 case 6: /* add: fn + fm */
3720 case 7: /* sub: fn - fm */
3723 case 8: /* div: fn / fm */
3726 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3727 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3728 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3729 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3730 /* These are fused multiply-add, and must be done as one
3731 * floating point operation with no rounding between the
3732 * multiplication and addition steps.
3733 * NB that doing the negations here as separate steps is
3734 * correct : an input NaN should come out with its sign bit
3735 * flipped if it is a negated-input.
3737 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3745 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3747 frd
= tcg_temp_new_i64();
3748 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3751 gen_helper_vfp_negd(frd
, frd
);
3753 fpst
= get_fpstatus_ptr(0);
3754 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3755 cpu_F1d
, frd
, fpst
);
3756 tcg_temp_free_ptr(fpst
);
3757 tcg_temp_free_i64(frd
);
3763 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3765 frd
= tcg_temp_new_i32();
3766 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3768 gen_helper_vfp_negs(frd
, frd
);
3770 fpst
= get_fpstatus_ptr(0);
3771 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3772 cpu_F1s
, frd
, fpst
);
3773 tcg_temp_free_ptr(fpst
);
3774 tcg_temp_free_i32(frd
);
3777 case 14: /* fconst */
3778 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3782 n
= (insn
<< 12) & 0x80000000;
3783 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3790 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3797 tcg_gen_movi_i32(cpu_F0s
, n
);
3800 case 15: /* extension space */
3814 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3815 tmp
= gen_vfp_mrs();
3816 tcg_gen_ext16u_i32(tmp
, tmp
);
3818 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3821 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3824 tcg_temp_free_i32(tmp
);
3826 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3827 tmp
= gen_vfp_mrs();
3828 tcg_gen_shri_i32(tmp
, tmp
, 16);
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 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3839 tmp
= tcg_temp_new_i32();
3841 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3844 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3847 gen_mov_F0_vreg(0, rd
);
3848 tmp2
= gen_vfp_mrs();
3849 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3850 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3851 tcg_temp_free_i32(tmp2
);
3854 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3855 tmp
= tcg_temp_new_i32();
3857 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3860 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3863 tcg_gen_shli_i32(tmp
, tmp
, 16);
3864 gen_mov_F0_vreg(0, rd
);
3865 tmp2
= gen_vfp_mrs();
3866 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3867 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3868 tcg_temp_free_i32(tmp2
);
3880 case 11: /* cmpez */
3884 case 12: /* vrintr */
3886 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3888 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3890 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3892 tcg_temp_free_ptr(fpst
);
3895 case 13: /* vrintz */
3897 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3899 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3900 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3902 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3904 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3906 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, fpst
);
3907 tcg_temp_free_i32(tcg_rmode
);
3908 tcg_temp_free_ptr(fpst
);
3911 case 14: /* vrintx */
3913 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3915 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3917 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3919 tcg_temp_free_ptr(fpst
);
3922 case 15: /* single<->double conversion */
3924 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3926 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3928 case 16: /* fuito */
3929 gen_vfp_uito(dp
, 0);
3931 case 17: /* fsito */
3932 gen_vfp_sito(dp
, 0);
3934 case 20: /* fshto */
3935 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3938 gen_vfp_shto(dp
, 16 - rm
, 0);
3940 case 21: /* fslto */
3941 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3944 gen_vfp_slto(dp
, 32 - rm
, 0);
3946 case 22: /* fuhto */
3947 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3950 gen_vfp_uhto(dp
, 16 - rm
, 0);
3952 case 23: /* fulto */
3953 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3956 gen_vfp_ulto(dp
, 32 - rm
, 0);
3958 case 24: /* ftoui */
3959 gen_vfp_toui(dp
, 0);
3961 case 25: /* ftouiz */
3962 gen_vfp_touiz(dp
, 0);
3964 case 26: /* ftosi */
3965 gen_vfp_tosi(dp
, 0);
3967 case 27: /* ftosiz */
3968 gen_vfp_tosiz(dp
, 0);
3970 case 28: /* ftosh */
3971 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3974 gen_vfp_tosh(dp
, 16 - rm
, 0);
3976 case 29: /* ftosl */
3977 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3980 gen_vfp_tosl(dp
, 32 - rm
, 0);
3982 case 30: /* ftouh */
3983 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3986 gen_vfp_touh(dp
, 16 - rm
, 0);
3988 case 31: /* ftoul */
3989 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3992 gen_vfp_toul(dp
, 32 - rm
, 0);
3994 default: /* undefined */
3998 default: /* undefined */
4002 /* Write back the result. */
4003 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
4004 /* Comparison, do nothing. */
4005 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
4006 (rn
& 0x1e) == 0x6)) {
4007 /* VCVT double to int: always integer result.
4008 * VCVT double to half precision is always a single
4011 gen_mov_vreg_F0(0, rd
);
4012 } else if (op
== 15 && rn
== 15) {
4014 gen_mov_vreg_F0(!dp
, rd
);
4016 gen_mov_vreg_F0(dp
, rd
);
4019 /* break out of the loop if we have finished */
4023 if (op
== 15 && delta_m
== 0) {
4024 /* single source one-many */
4026 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
4028 gen_mov_vreg_F0(dp
, rd
);
4032 /* Setup the next operands. */
4034 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
4038 /* One source operand. */
4039 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
4041 gen_mov_F0_vreg(dp
, rm
);
4043 /* Two source operands. */
4044 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
4046 gen_mov_F0_vreg(dp
, rn
);
4048 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
4050 gen_mov_F1_vreg(dp
, rm
);
4058 if ((insn
& 0x03e00000) == 0x00400000) {
4059 /* two-register transfer */
4060 rn
= (insn
>> 16) & 0xf;
4061 rd
= (insn
>> 12) & 0xf;
4063 VFP_DREG_M(rm
, insn
);
4065 rm
= VFP_SREG_M(insn
);
4068 if (insn
& ARM_CP_RW_BIT
) {
4071 gen_mov_F0_vreg(0, rm
* 2);
4072 tmp
= gen_vfp_mrs();
4073 store_reg(s
, rd
, tmp
);
4074 gen_mov_F0_vreg(0, rm
* 2 + 1);
4075 tmp
= gen_vfp_mrs();
4076 store_reg(s
, rn
, tmp
);
4078 gen_mov_F0_vreg(0, rm
);
4079 tmp
= gen_vfp_mrs();
4080 store_reg(s
, rd
, tmp
);
4081 gen_mov_F0_vreg(0, rm
+ 1);
4082 tmp
= gen_vfp_mrs();
4083 store_reg(s
, rn
, tmp
);
4088 tmp
= load_reg(s
, rd
);
4090 gen_mov_vreg_F0(0, rm
* 2);
4091 tmp
= load_reg(s
, rn
);
4093 gen_mov_vreg_F0(0, rm
* 2 + 1);
4095 tmp
= load_reg(s
, rd
);
4097 gen_mov_vreg_F0(0, rm
);
4098 tmp
= load_reg(s
, rn
);
4100 gen_mov_vreg_F0(0, rm
+ 1);
4105 rn
= (insn
>> 16) & 0xf;
4107 VFP_DREG_D(rd
, insn
);
4109 rd
= VFP_SREG_D(insn
);
4110 if ((insn
& 0x01200000) == 0x01000000) {
4111 /* Single load/store */
4112 offset
= (insn
& 0xff) << 2;
4113 if ((insn
& (1 << 23)) == 0)
4115 if (s
->thumb
&& rn
== 15) {
4116 /* This is actually UNPREDICTABLE */
4117 addr
= tcg_temp_new_i32();
4118 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4120 addr
= load_reg(s
, rn
);
4122 tcg_gen_addi_i32(addr
, addr
, offset
);
4123 if (insn
& (1 << 20)) {
4124 gen_vfp_ld(s
, dp
, addr
);
4125 gen_mov_vreg_F0(dp
, rd
);
4127 gen_mov_F0_vreg(dp
, rd
);
4128 gen_vfp_st(s
, dp
, addr
);
4130 tcg_temp_free_i32(addr
);
4132 /* load/store multiple */
4133 int w
= insn
& (1 << 21);
4135 n
= (insn
>> 1) & 0x7f;
4139 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
4140 /* P == U , W == 1 => UNDEF */
4143 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
4144 /* UNPREDICTABLE cases for bad immediates: we choose to
4145 * UNDEF to avoid generating huge numbers of TCG ops
4149 if (rn
== 15 && w
) {
4150 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4154 if (s
->thumb
&& rn
== 15) {
4155 /* This is actually UNPREDICTABLE */
4156 addr
= tcg_temp_new_i32();
4157 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4159 addr
= load_reg(s
, rn
);
4161 if (insn
& (1 << 24)) /* pre-decrement */
4162 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4168 for (i
= 0; i
< n
; i
++) {
4169 if (insn
& ARM_CP_RW_BIT
) {
4171 gen_vfp_ld(s
, dp
, addr
);
4172 gen_mov_vreg_F0(dp
, rd
+ i
);
4175 gen_mov_F0_vreg(dp
, rd
+ i
);
4176 gen_vfp_st(s
, dp
, addr
);
4178 tcg_gen_addi_i32(addr
, addr
, offset
);
4182 if (insn
& (1 << 24))
4183 offset
= -offset
* n
;
4184 else if (dp
&& (insn
& 1))
4190 tcg_gen_addi_i32(addr
, addr
, offset
);
4191 store_reg(s
, rn
, addr
);
4193 tcg_temp_free_i32(addr
);
4199 /* Should never happen. */
4205 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4207 #ifndef CONFIG_USER_ONLY
4208 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4209 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4215 static void gen_goto_ptr(void)
4217 tcg_gen_lookup_and_goto_ptr();
4220 /* This will end the TB but doesn't guarantee we'll return to
4221 * cpu_loop_exec. Any live exit_requests will be processed as we
4222 * enter the next TB.
4224 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4226 if (use_goto_tb(s
, dest
)) {
4228 gen_set_pc_im(s
, dest
);
4229 tcg_gen_exit_tb((uintptr_t)s
->base
.tb
+ n
);
4231 gen_set_pc_im(s
, dest
);
4234 s
->base
.is_jmp
= DISAS_NORETURN
;
4237 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4239 if (unlikely(is_singlestepping(s
))) {
4240 /* An indirect jump so that we still trigger the debug exception. */
4245 gen_goto_tb(s
, 0, dest
);
4249 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4252 tcg_gen_sari_i32(t0
, t0
, 16);
4256 tcg_gen_sari_i32(t1
, t1
, 16);
4259 tcg_gen_mul_i32(t0
, t0
, t1
);
4262 /* Return the mask of PSR bits set by a MSR instruction. */
4263 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4268 if (flags
& (1 << 0))
4270 if (flags
& (1 << 1))
4272 if (flags
& (1 << 2))
4274 if (flags
& (1 << 3))
4277 /* Mask out undefined bits. */
4278 mask
&= ~CPSR_RESERVED
;
4279 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4282 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4283 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4285 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4286 mask
&= ~(CPSR_E
| CPSR_GE
);
4288 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4291 /* Mask out execution state and reserved bits. */
4293 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4295 /* Mask out privileged bits. */
4301 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4302 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4306 /* ??? This is also undefined in system mode. */
4310 tmp
= load_cpu_field(spsr
);
4311 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4312 tcg_gen_andi_i32(t0
, t0
, mask
);
4313 tcg_gen_or_i32(tmp
, tmp
, t0
);
4314 store_cpu_field(tmp
, spsr
);
4316 gen_set_cpsr(t0
, mask
);
4318 tcg_temp_free_i32(t0
);
4323 /* Returns nonzero if access to the PSR is not permitted. */
4324 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4327 tmp
= tcg_temp_new_i32();
4328 tcg_gen_movi_i32(tmp
, val
);
4329 return gen_set_psr(s
, mask
, spsr
, tmp
);
4332 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4333 int *tgtmode
, int *regno
)
4335 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4336 * the target mode and register number, and identify the various
4337 * unpredictable cases.
4338 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4339 * + executed in user mode
4340 * + using R15 as the src/dest register
4341 * + accessing an unimplemented register
4342 * + accessing a register that's inaccessible at current PL/security state*
4343 * + accessing a register that you could access with a different insn
4344 * We choose to UNDEF in all these cases.
4345 * Since we don't know which of the various AArch32 modes we are in
4346 * we have to defer some checks to runtime.
4347 * Accesses to Monitor mode registers from Secure EL1 (which implies
4348 * that EL3 is AArch64) must trap to EL3.
4350 * If the access checks fail this function will emit code to take
4351 * an exception and return false. Otherwise it will return true,
4352 * and set *tgtmode and *regno appropriately.
4354 int exc_target
= default_exception_el(s
);
4356 /* These instructions are present only in ARMv8, or in ARMv7 with the
4357 * Virtualization Extensions.
4359 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4360 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4364 if (IS_USER(s
) || rn
== 15) {
4368 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4369 * of registers into (r, sysm).
4372 /* SPSRs for other modes */
4374 case 0xe: /* SPSR_fiq */
4375 *tgtmode
= ARM_CPU_MODE_FIQ
;
4377 case 0x10: /* SPSR_irq */
4378 *tgtmode
= ARM_CPU_MODE_IRQ
;
4380 case 0x12: /* SPSR_svc */
4381 *tgtmode
= ARM_CPU_MODE_SVC
;
4383 case 0x14: /* SPSR_abt */
4384 *tgtmode
= ARM_CPU_MODE_ABT
;
4386 case 0x16: /* SPSR_und */
4387 *tgtmode
= ARM_CPU_MODE_UND
;
4389 case 0x1c: /* SPSR_mon */
4390 *tgtmode
= ARM_CPU_MODE_MON
;
4392 case 0x1e: /* SPSR_hyp */
4393 *tgtmode
= ARM_CPU_MODE_HYP
;
4395 default: /* unallocated */
4398 /* We arbitrarily assign SPSR a register number of 16. */
4401 /* general purpose registers for other modes */
4403 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4404 *tgtmode
= ARM_CPU_MODE_USR
;
4407 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4408 *tgtmode
= ARM_CPU_MODE_FIQ
;
4411 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4412 *tgtmode
= ARM_CPU_MODE_IRQ
;
4413 *regno
= sysm
& 1 ? 13 : 14;
4415 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4416 *tgtmode
= ARM_CPU_MODE_SVC
;
4417 *regno
= sysm
& 1 ? 13 : 14;
4419 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4420 *tgtmode
= ARM_CPU_MODE_ABT
;
4421 *regno
= sysm
& 1 ? 13 : 14;
4423 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4424 *tgtmode
= ARM_CPU_MODE_UND
;
4425 *regno
= sysm
& 1 ? 13 : 14;
4427 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4428 *tgtmode
= ARM_CPU_MODE_MON
;
4429 *regno
= sysm
& 1 ? 13 : 14;
4431 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4432 *tgtmode
= ARM_CPU_MODE_HYP
;
4433 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4434 *regno
= sysm
& 1 ? 13 : 17;
4436 default: /* unallocated */
4441 /* Catch the 'accessing inaccessible register' cases we can detect
4442 * at translate time.
4445 case ARM_CPU_MODE_MON
:
4446 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4449 if (s
->current_el
== 1) {
4450 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4451 * then accesses to Mon registers trap to EL3
4457 case ARM_CPU_MODE_HYP
:
4458 /* Note that we can forbid accesses from EL2 here because they
4459 * must be from Hyp mode itself
4461 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4472 /* If we get here then some access check did not pass */
4473 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4477 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4479 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4480 int tgtmode
= 0, regno
= 0;
4482 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4486 /* Sync state because msr_banked() can raise exceptions */
4487 gen_set_condexec(s
);
4488 gen_set_pc_im(s
, s
->pc
- 4);
4489 tcg_reg
= load_reg(s
, rn
);
4490 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4491 tcg_regno
= tcg_const_i32(regno
);
4492 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4493 tcg_temp_free_i32(tcg_tgtmode
);
4494 tcg_temp_free_i32(tcg_regno
);
4495 tcg_temp_free_i32(tcg_reg
);
4496 s
->base
.is_jmp
= DISAS_UPDATE
;
4499 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4501 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4502 int tgtmode
= 0, regno
= 0;
4504 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4508 /* Sync state because mrs_banked() can raise exceptions */
4509 gen_set_condexec(s
);
4510 gen_set_pc_im(s
, s
->pc
- 4);
4511 tcg_reg
= tcg_temp_new_i32();
4512 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4513 tcg_regno
= tcg_const_i32(regno
);
4514 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4515 tcg_temp_free_i32(tcg_tgtmode
);
4516 tcg_temp_free_i32(tcg_regno
);
4517 store_reg(s
, rn
, tcg_reg
);
4518 s
->base
.is_jmp
= DISAS_UPDATE
;
4521 /* Store value to PC as for an exception return (ie don't
4522 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4523 * will do the masking based on the new value of the Thumb bit.
4525 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4527 tcg_gen_mov_i32(cpu_R
[15], pc
);
4528 tcg_temp_free_i32(pc
);
4531 /* Generate a v6 exception return. Marks both values as dead. */
4532 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4534 store_pc_exc_ret(s
, pc
);
4535 /* The cpsr_write_eret helper will mask the low bits of PC
4536 * appropriately depending on the new Thumb bit, so it must
4537 * be called after storing the new PC.
4539 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4540 tcg_temp_free_i32(cpsr
);
4541 /* Must exit loop to check un-masked IRQs */
4542 s
->base
.is_jmp
= DISAS_EXIT
;
4545 /* Generate an old-style exception return. Marks pc as dead. */
4546 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4548 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4552 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4553 * only call the helper when running single threaded TCG code to ensure
4554 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4555 * just skip this instruction. Currently the SEV/SEVL instructions
4556 * which are *one* of many ways to wake the CPU from WFE are not
4557 * implemented so we can't sleep like WFI does.
4559 static void gen_nop_hint(DisasContext
*s
, int val
)
4562 /* When running in MTTCG we don't generate jumps to the yield and
4563 * WFE helpers as it won't affect the scheduling of other vCPUs.
4564 * If we wanted to more completely model WFE/SEV so we don't busy
4565 * spin unnecessarily we would need to do something more involved.
4568 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4569 gen_set_pc_im(s
, s
->pc
);
4570 s
->base
.is_jmp
= DISAS_YIELD
;
4574 gen_set_pc_im(s
, s
->pc
);
4575 s
->base
.is_jmp
= DISAS_WFI
;
4578 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4579 gen_set_pc_im(s
, s
->pc
);
4580 s
->base
.is_jmp
= DISAS_WFE
;
4585 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4591 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4593 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4596 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4597 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4598 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4603 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4606 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4607 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4608 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4613 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4614 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4615 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4616 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4617 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4619 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4620 switch ((size << 1) | u) { \
4622 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4625 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4628 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4631 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4634 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4637 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4639 default: return 1; \
4642 #define GEN_NEON_INTEGER_OP(name) do { \
4643 switch ((size << 1) | u) { \
4645 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4648 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4651 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4654 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4657 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4660 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4662 default: return 1; \
4665 static TCGv_i32
neon_load_scratch(int scratch
)
4667 TCGv_i32 tmp
= tcg_temp_new_i32();
4668 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4672 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4674 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4675 tcg_temp_free_i32(var
);
4678 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4682 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4684 gen_neon_dup_high16(tmp
);
4686 gen_neon_dup_low16(tmp
);
4689 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4694 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4698 if (!q
&& size
== 2) {
4701 pd
= vfp_reg_ptr(true, rd
);
4702 pm
= vfp_reg_ptr(true, rm
);
4706 gen_helper_neon_qunzip8(pd
, pm
);
4709 gen_helper_neon_qunzip16(pd
, pm
);
4712 gen_helper_neon_qunzip32(pd
, pm
);
4720 gen_helper_neon_unzip8(pd
, pm
);
4723 gen_helper_neon_unzip16(pd
, pm
);
4729 tcg_temp_free_ptr(pd
);
4730 tcg_temp_free_ptr(pm
);
4734 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4738 if (!q
&& size
== 2) {
4741 pd
= vfp_reg_ptr(true, rd
);
4742 pm
= vfp_reg_ptr(true, rm
);
4746 gen_helper_neon_qzip8(pd
, pm
);
4749 gen_helper_neon_qzip16(pd
, pm
);
4752 gen_helper_neon_qzip32(pd
, pm
);
4760 gen_helper_neon_zip8(pd
, pm
);
4763 gen_helper_neon_zip16(pd
, pm
);
4769 tcg_temp_free_ptr(pd
);
4770 tcg_temp_free_ptr(pm
);
4774 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4778 rd
= tcg_temp_new_i32();
4779 tmp
= tcg_temp_new_i32();
4781 tcg_gen_shli_i32(rd
, t0
, 8);
4782 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4783 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4784 tcg_gen_or_i32(rd
, rd
, tmp
);
4786 tcg_gen_shri_i32(t1
, t1
, 8);
4787 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4788 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4789 tcg_gen_or_i32(t1
, t1
, tmp
);
4790 tcg_gen_mov_i32(t0
, rd
);
4792 tcg_temp_free_i32(tmp
);
4793 tcg_temp_free_i32(rd
);
4796 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4800 rd
= tcg_temp_new_i32();
4801 tmp
= tcg_temp_new_i32();
4803 tcg_gen_shli_i32(rd
, t0
, 16);
4804 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4805 tcg_gen_or_i32(rd
, rd
, tmp
);
4806 tcg_gen_shri_i32(t1
, t1
, 16);
4807 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4808 tcg_gen_or_i32(t1
, t1
, tmp
);
4809 tcg_gen_mov_i32(t0
, rd
);
4811 tcg_temp_free_i32(tmp
);
4812 tcg_temp_free_i32(rd
);
4820 } neon_ls_element_type
[11] = {
4834 /* Translate a NEON load/store element instruction. Return nonzero if the
4835 instruction is invalid. */
4836 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4855 /* FIXME: this access check should not take precedence over UNDEF
4856 * for invalid encodings; we will generate incorrect syndrome information
4857 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4859 if (s
->fp_excp_el
) {
4860 gen_exception_insn(s
, 4, EXCP_UDEF
,
4861 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4865 if (!s
->vfp_enabled
)
4867 VFP_DREG_D(rd
, insn
);
4868 rn
= (insn
>> 16) & 0xf;
4870 load
= (insn
& (1 << 21)) != 0;
4871 if ((insn
& (1 << 23)) == 0) {
4872 /* Load store all elements. */
4873 op
= (insn
>> 8) & 0xf;
4874 size
= (insn
>> 6) & 3;
4877 /* Catch UNDEF cases for bad values of align field */
4880 if (((insn
>> 5) & 1) == 1) {
4885 if (((insn
>> 4) & 3) == 3) {
4892 nregs
= neon_ls_element_type
[op
].nregs
;
4893 interleave
= neon_ls_element_type
[op
].interleave
;
4894 spacing
= neon_ls_element_type
[op
].spacing
;
4895 if (size
== 3 && (interleave
| spacing
) != 1)
4897 addr
= tcg_temp_new_i32();
4898 load_reg_var(s
, addr
, rn
);
4899 stride
= (1 << size
) * interleave
;
4900 for (reg
= 0; reg
< nregs
; reg
++) {
4901 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4902 load_reg_var(s
, addr
, rn
);
4903 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4904 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4905 load_reg_var(s
, addr
, rn
);
4906 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4909 tmp64
= tcg_temp_new_i64();
4911 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4912 neon_store_reg64(tmp64
, rd
);
4914 neon_load_reg64(tmp64
, rd
);
4915 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4917 tcg_temp_free_i64(tmp64
);
4918 tcg_gen_addi_i32(addr
, addr
, stride
);
4920 for (pass
= 0; pass
< 2; pass
++) {
4923 tmp
= tcg_temp_new_i32();
4924 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4925 neon_store_reg(rd
, pass
, tmp
);
4927 tmp
= neon_load_reg(rd
, pass
);
4928 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4929 tcg_temp_free_i32(tmp
);
4931 tcg_gen_addi_i32(addr
, addr
, stride
);
4932 } else if (size
== 1) {
4934 tmp
= tcg_temp_new_i32();
4935 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4936 tcg_gen_addi_i32(addr
, addr
, stride
);
4937 tmp2
= tcg_temp_new_i32();
4938 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4939 tcg_gen_addi_i32(addr
, addr
, stride
);
4940 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4941 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4942 tcg_temp_free_i32(tmp2
);
4943 neon_store_reg(rd
, pass
, tmp
);
4945 tmp
= neon_load_reg(rd
, pass
);
4946 tmp2
= tcg_temp_new_i32();
4947 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4948 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4949 tcg_temp_free_i32(tmp
);
4950 tcg_gen_addi_i32(addr
, addr
, stride
);
4951 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4952 tcg_temp_free_i32(tmp2
);
4953 tcg_gen_addi_i32(addr
, addr
, stride
);
4955 } else /* size == 0 */ {
4958 for (n
= 0; n
< 4; n
++) {
4959 tmp
= tcg_temp_new_i32();
4960 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4961 tcg_gen_addi_i32(addr
, addr
, stride
);
4965 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4966 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4967 tcg_temp_free_i32(tmp
);
4970 neon_store_reg(rd
, pass
, tmp2
);
4972 tmp2
= neon_load_reg(rd
, pass
);
4973 for (n
= 0; n
< 4; n
++) {
4974 tmp
= tcg_temp_new_i32();
4976 tcg_gen_mov_i32(tmp
, tmp2
);
4978 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4980 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4981 tcg_temp_free_i32(tmp
);
4982 tcg_gen_addi_i32(addr
, addr
, stride
);
4984 tcg_temp_free_i32(tmp2
);
4991 tcg_temp_free_i32(addr
);
4994 size
= (insn
>> 10) & 3;
4996 /* Load single element to all lanes. */
4997 int a
= (insn
>> 4) & 1;
5001 size
= (insn
>> 6) & 3;
5002 nregs
= ((insn
>> 8) & 3) + 1;
5005 if (nregs
!= 4 || a
== 0) {
5008 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5011 if (nregs
== 1 && a
== 1 && size
== 0) {
5014 if (nregs
== 3 && a
== 1) {
5017 addr
= tcg_temp_new_i32();
5018 load_reg_var(s
, addr
, rn
);
5020 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5021 tmp
= gen_load_and_replicate(s
, addr
, size
);
5022 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
5023 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
5024 if (insn
& (1 << 5)) {
5025 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
5026 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
5028 tcg_temp_free_i32(tmp
);
5030 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5031 stride
= (insn
& (1 << 5)) ? 2 : 1;
5032 for (reg
= 0; reg
< nregs
; reg
++) {
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 tcg_temp_free_i32(tmp
);
5037 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5041 tcg_temp_free_i32(addr
);
5042 stride
= (1 << size
) * nregs
;
5044 /* Single element. */
5045 int idx
= (insn
>> 4) & 0xf;
5046 pass
= (insn
>> 7) & 1;
5049 shift
= ((insn
>> 5) & 3) * 8;
5053 shift
= ((insn
>> 6) & 1) * 16;
5054 stride
= (insn
& (1 << 5)) ? 2 : 1;
5058 stride
= (insn
& (1 << 6)) ? 2 : 1;
5063 nregs
= ((insn
>> 8) & 3) + 1;
5064 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5067 if (((idx
& (1 << size
)) != 0) ||
5068 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
5073 if ((idx
& 1) != 0) {
5078 if (size
== 2 && (idx
& 2) != 0) {
5083 if ((size
== 2) && ((idx
& 3) == 3)) {
5090 if ((rd
+ stride
* (nregs
- 1)) > 31) {
5091 /* Attempts to write off the end of the register file
5092 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5093 * the neon_load_reg() would write off the end of the array.
5097 addr
= tcg_temp_new_i32();
5098 load_reg_var(s
, addr
, rn
);
5099 for (reg
= 0; reg
< nregs
; reg
++) {
5101 tmp
= tcg_temp_new_i32();
5104 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
5107 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
5110 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
5112 default: /* Avoid compiler warnings. */
5116 tmp2
= neon_load_reg(rd
, pass
);
5117 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
5118 shift
, size
? 16 : 8);
5119 tcg_temp_free_i32(tmp2
);
5121 neon_store_reg(rd
, pass
, tmp
);
5122 } else { /* Store */
5123 tmp
= neon_load_reg(rd
, pass
);
5125 tcg_gen_shri_i32(tmp
, tmp
, shift
);
5128 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
5131 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
5134 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5137 tcg_temp_free_i32(tmp
);
5140 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5142 tcg_temp_free_i32(addr
);
5143 stride
= nregs
* (1 << size
);
5149 base
= load_reg(s
, rn
);
5151 tcg_gen_addi_i32(base
, base
, stride
);
5154 index
= load_reg(s
, rm
);
5155 tcg_gen_add_i32(base
, base
, index
);
5156 tcg_temp_free_i32(index
);
5158 store_reg(s
, rn
, base
);
5163 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5164 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
5166 tcg_gen_and_i32(t
, t
, c
);
5167 tcg_gen_andc_i32(f
, f
, c
);
5168 tcg_gen_or_i32(dest
, t
, f
);
5171 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5174 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
5175 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
5176 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
5181 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5184 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
5185 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
5186 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5191 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5194 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5195 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5196 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5201 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5204 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5205 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5206 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5211 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5217 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5218 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5223 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5224 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5231 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5232 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5237 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5238 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5245 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5249 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5250 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5251 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5256 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5257 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5258 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5262 tcg_temp_free_i32(src
);
5265 static inline void gen_neon_addl(int size
)
5268 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5269 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5270 case 2: tcg_gen_add_i64(CPU_V001
); break;
5275 static inline void gen_neon_subl(int size
)
5278 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5279 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5280 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5285 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5288 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5289 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5291 tcg_gen_neg_i64(var
, var
);
5297 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5300 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5301 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5306 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5311 switch ((size
<< 1) | u
) {
5312 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5313 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5314 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5315 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5317 tmp
= gen_muls_i64_i32(a
, b
);
5318 tcg_gen_mov_i64(dest
, tmp
);
5319 tcg_temp_free_i64(tmp
);
5322 tmp
= gen_mulu_i64_i32(a
, b
);
5323 tcg_gen_mov_i64(dest
, tmp
);
5324 tcg_temp_free_i64(tmp
);
5329 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5330 Don't forget to clean them now. */
5332 tcg_temp_free_i32(a
);
5333 tcg_temp_free_i32(b
);
5337 static void gen_neon_narrow_op(int op
, int u
, int size
,
5338 TCGv_i32 dest
, TCGv_i64 src
)
5342 gen_neon_unarrow_sats(size
, dest
, src
);
5344 gen_neon_narrow(size
, dest
, src
);
5348 gen_neon_narrow_satu(size
, dest
, src
);
5350 gen_neon_narrow_sats(size
, dest
, src
);
5355 /* Symbolic constants for op fields for Neon 3-register same-length.
5356 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5359 #define NEON_3R_VHADD 0
5360 #define NEON_3R_VQADD 1
5361 #define NEON_3R_VRHADD 2
5362 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5363 #define NEON_3R_VHSUB 4
5364 #define NEON_3R_VQSUB 5
5365 #define NEON_3R_VCGT 6
5366 #define NEON_3R_VCGE 7
5367 #define NEON_3R_VSHL 8
5368 #define NEON_3R_VQSHL 9
5369 #define NEON_3R_VRSHL 10
5370 #define NEON_3R_VQRSHL 11
5371 #define NEON_3R_VMAX 12
5372 #define NEON_3R_VMIN 13
5373 #define NEON_3R_VABD 14
5374 #define NEON_3R_VABA 15
5375 #define NEON_3R_VADD_VSUB 16
5376 #define NEON_3R_VTST_VCEQ 17
5377 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5378 #define NEON_3R_VMUL 19
5379 #define NEON_3R_VPMAX 20
5380 #define NEON_3R_VPMIN 21
5381 #define NEON_3R_VQDMULH_VQRDMULH 22
5382 #define NEON_3R_VPADD_VQRDMLAH 23
5383 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5384 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5385 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5386 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5387 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5388 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5389 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5390 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5392 static const uint8_t neon_3r_sizes
[] = {
5393 [NEON_3R_VHADD
] = 0x7,
5394 [NEON_3R_VQADD
] = 0xf,
5395 [NEON_3R_VRHADD
] = 0x7,
5396 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5397 [NEON_3R_VHSUB
] = 0x7,
5398 [NEON_3R_VQSUB
] = 0xf,
5399 [NEON_3R_VCGT
] = 0x7,
5400 [NEON_3R_VCGE
] = 0x7,
5401 [NEON_3R_VSHL
] = 0xf,
5402 [NEON_3R_VQSHL
] = 0xf,
5403 [NEON_3R_VRSHL
] = 0xf,
5404 [NEON_3R_VQRSHL
] = 0xf,
5405 [NEON_3R_VMAX
] = 0x7,
5406 [NEON_3R_VMIN
] = 0x7,
5407 [NEON_3R_VABD
] = 0x7,
5408 [NEON_3R_VABA
] = 0x7,
5409 [NEON_3R_VADD_VSUB
] = 0xf,
5410 [NEON_3R_VTST_VCEQ
] = 0x7,
5411 [NEON_3R_VML
] = 0x7,
5412 [NEON_3R_VMUL
] = 0x7,
5413 [NEON_3R_VPMAX
] = 0x7,
5414 [NEON_3R_VPMIN
] = 0x7,
5415 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5416 [NEON_3R_VPADD_VQRDMLAH
] = 0x7,
5417 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5418 [NEON_3R_VFM_VQRDMLSH
] = 0x7, /* For VFM, size bit 1 encodes op */
5419 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5420 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5421 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5422 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5423 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5424 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5427 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5428 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5431 #define NEON_2RM_VREV64 0
5432 #define NEON_2RM_VREV32 1
5433 #define NEON_2RM_VREV16 2
5434 #define NEON_2RM_VPADDL 4
5435 #define NEON_2RM_VPADDL_U 5
5436 #define NEON_2RM_AESE 6 /* Includes AESD */
5437 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5438 #define NEON_2RM_VCLS 8
5439 #define NEON_2RM_VCLZ 9
5440 #define NEON_2RM_VCNT 10
5441 #define NEON_2RM_VMVN 11
5442 #define NEON_2RM_VPADAL 12
5443 #define NEON_2RM_VPADAL_U 13
5444 #define NEON_2RM_VQABS 14
5445 #define NEON_2RM_VQNEG 15
5446 #define NEON_2RM_VCGT0 16
5447 #define NEON_2RM_VCGE0 17
5448 #define NEON_2RM_VCEQ0 18
5449 #define NEON_2RM_VCLE0 19
5450 #define NEON_2RM_VCLT0 20
5451 #define NEON_2RM_SHA1H 21
5452 #define NEON_2RM_VABS 22
5453 #define NEON_2RM_VNEG 23
5454 #define NEON_2RM_VCGT0_F 24
5455 #define NEON_2RM_VCGE0_F 25
5456 #define NEON_2RM_VCEQ0_F 26
5457 #define NEON_2RM_VCLE0_F 27
5458 #define NEON_2RM_VCLT0_F 28
5459 #define NEON_2RM_VABS_F 30
5460 #define NEON_2RM_VNEG_F 31
5461 #define NEON_2RM_VSWP 32
5462 #define NEON_2RM_VTRN 33
5463 #define NEON_2RM_VUZP 34
5464 #define NEON_2RM_VZIP 35
5465 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5466 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5467 #define NEON_2RM_VSHLL 38
5468 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5469 #define NEON_2RM_VRINTN 40
5470 #define NEON_2RM_VRINTX 41
5471 #define NEON_2RM_VRINTA 42
5472 #define NEON_2RM_VRINTZ 43
5473 #define NEON_2RM_VCVT_F16_F32 44
5474 #define NEON_2RM_VRINTM 45
5475 #define NEON_2RM_VCVT_F32_F16 46
5476 #define NEON_2RM_VRINTP 47
5477 #define NEON_2RM_VCVTAU 48
5478 #define NEON_2RM_VCVTAS 49
5479 #define NEON_2RM_VCVTNU 50
5480 #define NEON_2RM_VCVTNS 51
5481 #define NEON_2RM_VCVTPU 52
5482 #define NEON_2RM_VCVTPS 53
5483 #define NEON_2RM_VCVTMU 54
5484 #define NEON_2RM_VCVTMS 55
5485 #define NEON_2RM_VRECPE 56
5486 #define NEON_2RM_VRSQRTE 57
5487 #define NEON_2RM_VRECPE_F 58
5488 #define NEON_2RM_VRSQRTE_F 59
5489 #define NEON_2RM_VCVT_FS 60
5490 #define NEON_2RM_VCVT_FU 61
5491 #define NEON_2RM_VCVT_SF 62
5492 #define NEON_2RM_VCVT_UF 63
5494 static int neon_2rm_is_float_op(int op
)
5496 /* Return true if this neon 2reg-misc op is float-to-float */
5497 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5498 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5499 op
== NEON_2RM_VRINTM
||
5500 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5501 op
>= NEON_2RM_VRECPE_F
);
5504 static bool neon_2rm_is_v8_op(int op
)
5506 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5508 case NEON_2RM_VRINTN
:
5509 case NEON_2RM_VRINTA
:
5510 case NEON_2RM_VRINTM
:
5511 case NEON_2RM_VRINTP
:
5512 case NEON_2RM_VRINTZ
:
5513 case NEON_2RM_VRINTX
:
5514 case NEON_2RM_VCVTAU
:
5515 case NEON_2RM_VCVTAS
:
5516 case NEON_2RM_VCVTNU
:
5517 case NEON_2RM_VCVTNS
:
5518 case NEON_2RM_VCVTPU
:
5519 case NEON_2RM_VCVTPS
:
5520 case NEON_2RM_VCVTMU
:
5521 case NEON_2RM_VCVTMS
:
5528 /* Each entry in this array has bit n set if the insn allows
5529 * size value n (otherwise it will UNDEF). Since unallocated
5530 * op values will have no bits set they always UNDEF.
5532 static const uint8_t neon_2rm_sizes
[] = {
5533 [NEON_2RM_VREV64
] = 0x7,
5534 [NEON_2RM_VREV32
] = 0x3,
5535 [NEON_2RM_VREV16
] = 0x1,
5536 [NEON_2RM_VPADDL
] = 0x7,
5537 [NEON_2RM_VPADDL_U
] = 0x7,
5538 [NEON_2RM_AESE
] = 0x1,
5539 [NEON_2RM_AESMC
] = 0x1,
5540 [NEON_2RM_VCLS
] = 0x7,
5541 [NEON_2RM_VCLZ
] = 0x7,
5542 [NEON_2RM_VCNT
] = 0x1,
5543 [NEON_2RM_VMVN
] = 0x1,
5544 [NEON_2RM_VPADAL
] = 0x7,
5545 [NEON_2RM_VPADAL_U
] = 0x7,
5546 [NEON_2RM_VQABS
] = 0x7,
5547 [NEON_2RM_VQNEG
] = 0x7,
5548 [NEON_2RM_VCGT0
] = 0x7,
5549 [NEON_2RM_VCGE0
] = 0x7,
5550 [NEON_2RM_VCEQ0
] = 0x7,
5551 [NEON_2RM_VCLE0
] = 0x7,
5552 [NEON_2RM_VCLT0
] = 0x7,
5553 [NEON_2RM_SHA1H
] = 0x4,
5554 [NEON_2RM_VABS
] = 0x7,
5555 [NEON_2RM_VNEG
] = 0x7,
5556 [NEON_2RM_VCGT0_F
] = 0x4,
5557 [NEON_2RM_VCGE0_F
] = 0x4,
5558 [NEON_2RM_VCEQ0_F
] = 0x4,
5559 [NEON_2RM_VCLE0_F
] = 0x4,
5560 [NEON_2RM_VCLT0_F
] = 0x4,
5561 [NEON_2RM_VABS_F
] = 0x4,
5562 [NEON_2RM_VNEG_F
] = 0x4,
5563 [NEON_2RM_VSWP
] = 0x1,
5564 [NEON_2RM_VTRN
] = 0x7,
5565 [NEON_2RM_VUZP
] = 0x7,
5566 [NEON_2RM_VZIP
] = 0x7,
5567 [NEON_2RM_VMOVN
] = 0x7,
5568 [NEON_2RM_VQMOVN
] = 0x7,
5569 [NEON_2RM_VSHLL
] = 0x7,
5570 [NEON_2RM_SHA1SU1
] = 0x4,
5571 [NEON_2RM_VRINTN
] = 0x4,
5572 [NEON_2RM_VRINTX
] = 0x4,
5573 [NEON_2RM_VRINTA
] = 0x4,
5574 [NEON_2RM_VRINTZ
] = 0x4,
5575 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5576 [NEON_2RM_VRINTM
] = 0x4,
5577 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5578 [NEON_2RM_VRINTP
] = 0x4,
5579 [NEON_2RM_VCVTAU
] = 0x4,
5580 [NEON_2RM_VCVTAS
] = 0x4,
5581 [NEON_2RM_VCVTNU
] = 0x4,
5582 [NEON_2RM_VCVTNS
] = 0x4,
5583 [NEON_2RM_VCVTPU
] = 0x4,
5584 [NEON_2RM_VCVTPS
] = 0x4,
5585 [NEON_2RM_VCVTMU
] = 0x4,
5586 [NEON_2RM_VCVTMS
] = 0x4,
5587 [NEON_2RM_VRECPE
] = 0x4,
5588 [NEON_2RM_VRSQRTE
] = 0x4,
5589 [NEON_2RM_VRECPE_F
] = 0x4,
5590 [NEON_2RM_VRSQRTE_F
] = 0x4,
5591 [NEON_2RM_VCVT_FS
] = 0x4,
5592 [NEON_2RM_VCVT_FU
] = 0x4,
5593 [NEON_2RM_VCVT_SF
] = 0x4,
5594 [NEON_2RM_VCVT_UF
] = 0x4,
5598 /* Expand v8.1 simd helper. */
5599 static int do_v81_helper(DisasContext
*s
, gen_helper_gvec_3_ptr
*fn
,
5600 int q
, int rd
, int rn
, int rm
)
5602 if (arm_dc_feature(s
, ARM_FEATURE_V8_RDM
)) {
5603 int opr_sz
= (1 + q
) * 8;
5604 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
5605 vfp_reg_offset(1, rn
),
5606 vfp_reg_offset(1, rm
), cpu_env
,
5607 opr_sz
, opr_sz
, 0, fn
);
5613 /* Translate a NEON data processing instruction. Return nonzero if the
5614 instruction is invalid.
5615 We process data in a mixture of 32-bit and 64-bit chunks.
5616 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5618 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5630 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5631 TCGv_ptr ptr1
, ptr2
, ptr3
;
5634 /* FIXME: this access check should not take precedence over UNDEF
5635 * for invalid encodings; we will generate incorrect syndrome information
5636 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5638 if (s
->fp_excp_el
) {
5639 gen_exception_insn(s
, 4, EXCP_UDEF
,
5640 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5644 if (!s
->vfp_enabled
)
5646 q
= (insn
& (1 << 6)) != 0;
5647 u
= (insn
>> 24) & 1;
5648 VFP_DREG_D(rd
, insn
);
5649 VFP_DREG_N(rn
, insn
);
5650 VFP_DREG_M(rm
, insn
);
5651 size
= (insn
>> 20) & 3;
5652 if ((insn
& (1 << 23)) == 0) {
5653 /* Three register same length. */
5654 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5655 /* Catch invalid op and bad size combinations: UNDEF */
5656 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5659 /* All insns of this form UNDEF for either this condition or the
5660 * superset of cases "Q==1"; we catch the latter later.
5662 if (q
&& ((rd
| rn
| rm
) & 1)) {
5667 /* The SHA-1/SHA-256 3-register instructions require special
5668 * treatment here, as their size field is overloaded as an
5669 * op type selector, and they all consume their input in a
5675 if (!u
) { /* SHA-1 */
5676 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5679 ptr1
= vfp_reg_ptr(true, rd
);
5680 ptr2
= vfp_reg_ptr(true, rn
);
5681 ptr3
= vfp_reg_ptr(true, rm
);
5682 tmp4
= tcg_const_i32(size
);
5683 gen_helper_crypto_sha1_3reg(ptr1
, ptr2
, ptr3
, tmp4
);
5684 tcg_temp_free_i32(tmp4
);
5685 } else { /* SHA-256 */
5686 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5689 ptr1
= vfp_reg_ptr(true, rd
);
5690 ptr2
= vfp_reg_ptr(true, rn
);
5691 ptr3
= vfp_reg_ptr(true, rm
);
5694 gen_helper_crypto_sha256h(ptr1
, ptr2
, ptr3
);
5697 gen_helper_crypto_sha256h2(ptr1
, ptr2
, ptr3
);
5700 gen_helper_crypto_sha256su1(ptr1
, ptr2
, ptr3
);
5704 tcg_temp_free_ptr(ptr1
);
5705 tcg_temp_free_ptr(ptr2
);
5706 tcg_temp_free_ptr(ptr3
);
5709 case NEON_3R_VPADD_VQRDMLAH
:
5716 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s16
,
5719 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s32
,
5724 case NEON_3R_VFM_VQRDMLSH
:
5735 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s16
,
5738 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s32
,
5743 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5744 /* 64-bit element instructions. */
5745 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5746 neon_load_reg64(cpu_V0
, rn
+ pass
);
5747 neon_load_reg64(cpu_V1
, rm
+ pass
);
5751 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5754 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5760 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5763 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5769 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5771 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5776 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5779 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5785 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5787 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5790 case NEON_3R_VQRSHL
:
5792 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5795 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5799 case NEON_3R_VADD_VSUB
:
5801 tcg_gen_sub_i64(CPU_V001
);
5803 tcg_gen_add_i64(CPU_V001
);
5809 neon_store_reg64(cpu_V0
, rd
+ pass
);
5818 case NEON_3R_VQRSHL
:
5821 /* Shift instruction operands are reversed. */
5827 case NEON_3R_VPADD_VQRDMLAH
:
5832 case NEON_3R_FLOAT_ARITH
:
5833 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5835 case NEON_3R_FLOAT_MINMAX
:
5836 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5838 case NEON_3R_FLOAT_CMP
:
5840 /* no encoding for U=0 C=1x */
5844 case NEON_3R_FLOAT_ACMP
:
5849 case NEON_3R_FLOAT_MISC
:
5850 /* VMAXNM/VMINNM in ARMv8 */
5851 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5856 if (u
&& (size
!= 0)) {
5857 /* UNDEF on invalid size for polynomial subcase */
5861 case NEON_3R_VFM_VQRDMLSH
:
5862 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
5870 if (pairwise
&& q
) {
5871 /* All the pairwise insns UNDEF if Q is set */
5875 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5880 tmp
= neon_load_reg(rn
, 0);
5881 tmp2
= neon_load_reg(rn
, 1);
5883 tmp
= neon_load_reg(rm
, 0);
5884 tmp2
= neon_load_reg(rm
, 1);
5888 tmp
= neon_load_reg(rn
, pass
);
5889 tmp2
= neon_load_reg(rm
, pass
);
5893 GEN_NEON_INTEGER_OP(hadd
);
5896 GEN_NEON_INTEGER_OP_ENV(qadd
);
5898 case NEON_3R_VRHADD
:
5899 GEN_NEON_INTEGER_OP(rhadd
);
5901 case NEON_3R_LOGIC
: /* Logic ops. */
5902 switch ((u
<< 2) | size
) {
5904 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5907 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5910 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5913 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5916 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5919 tmp3
= neon_load_reg(rd
, pass
);
5920 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5921 tcg_temp_free_i32(tmp3
);
5924 tmp3
= neon_load_reg(rd
, pass
);
5925 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5926 tcg_temp_free_i32(tmp3
);
5929 tmp3
= neon_load_reg(rd
, pass
);
5930 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5931 tcg_temp_free_i32(tmp3
);
5936 GEN_NEON_INTEGER_OP(hsub
);
5939 GEN_NEON_INTEGER_OP_ENV(qsub
);
5942 GEN_NEON_INTEGER_OP(cgt
);
5945 GEN_NEON_INTEGER_OP(cge
);
5948 GEN_NEON_INTEGER_OP(shl
);
5951 GEN_NEON_INTEGER_OP_ENV(qshl
);
5954 GEN_NEON_INTEGER_OP(rshl
);
5956 case NEON_3R_VQRSHL
:
5957 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5960 GEN_NEON_INTEGER_OP(max
);
5963 GEN_NEON_INTEGER_OP(min
);
5966 GEN_NEON_INTEGER_OP(abd
);
5969 GEN_NEON_INTEGER_OP(abd
);
5970 tcg_temp_free_i32(tmp2
);
5971 tmp2
= neon_load_reg(rd
, pass
);
5972 gen_neon_add(size
, tmp
, tmp2
);
5974 case NEON_3R_VADD_VSUB
:
5975 if (!u
) { /* VADD */
5976 gen_neon_add(size
, tmp
, tmp2
);
5979 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5980 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5981 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5986 case NEON_3R_VTST_VCEQ
:
5987 if (!u
) { /* VTST */
5989 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5990 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5991 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5996 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5997 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5998 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6003 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
6005 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6006 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6007 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6010 tcg_temp_free_i32(tmp2
);
6011 tmp2
= neon_load_reg(rd
, pass
);
6013 gen_neon_rsb(size
, tmp
, tmp2
);
6015 gen_neon_add(size
, tmp
, tmp2
);
6019 if (u
) { /* polynomial */
6020 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
6021 } else { /* Integer */
6023 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6024 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6025 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6031 GEN_NEON_INTEGER_OP(pmax
);
6034 GEN_NEON_INTEGER_OP(pmin
);
6036 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
6037 if (!u
) { /* VQDMULH */
6040 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6043 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6047 } else { /* VQRDMULH */
6050 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6053 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6059 case NEON_3R_VPADD_VQRDMLAH
:
6061 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
6062 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
6063 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
6067 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
6069 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6070 switch ((u
<< 2) | size
) {
6073 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6076 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
6079 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
6084 tcg_temp_free_ptr(fpstatus
);
6087 case NEON_3R_FLOAT_MULTIPLY
:
6089 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6090 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6092 tcg_temp_free_i32(tmp2
);
6093 tmp2
= neon_load_reg(rd
, pass
);
6095 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6097 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6100 tcg_temp_free_ptr(fpstatus
);
6103 case NEON_3R_FLOAT_CMP
:
6105 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6107 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6110 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6112 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6115 tcg_temp_free_ptr(fpstatus
);
6118 case NEON_3R_FLOAT_ACMP
:
6120 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6122 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6124 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6126 tcg_temp_free_ptr(fpstatus
);
6129 case NEON_3R_FLOAT_MINMAX
:
6131 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6133 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6135 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6137 tcg_temp_free_ptr(fpstatus
);
6140 case NEON_3R_FLOAT_MISC
:
6143 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6145 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6147 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6149 tcg_temp_free_ptr(fpstatus
);
6152 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6154 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6158 case NEON_3R_VFM_VQRDMLSH
:
6160 /* VFMA, VFMS: fused multiply-add */
6161 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6162 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6165 gen_helper_vfp_negs(tmp
, tmp
);
6167 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6168 tcg_temp_free_i32(tmp3
);
6169 tcg_temp_free_ptr(fpstatus
);
6175 tcg_temp_free_i32(tmp2
);
6177 /* Save the result. For elementwise operations we can put it
6178 straight into the destination register. For pairwise operations
6179 we have to be careful to avoid clobbering the source operands. */
6180 if (pairwise
&& rd
== rm
) {
6181 neon_store_scratch(pass
, tmp
);
6183 neon_store_reg(rd
, pass
, tmp
);
6187 if (pairwise
&& rd
== rm
) {
6188 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6189 tmp
= neon_load_scratch(pass
);
6190 neon_store_reg(rd
, pass
, tmp
);
6193 /* End of 3 register same size operations. */
6194 } else if (insn
& (1 << 4)) {
6195 if ((insn
& 0x00380080) != 0) {
6196 /* Two registers and shift. */
6197 op
= (insn
>> 8) & 0xf;
6198 if (insn
& (1 << 7)) {
6206 while ((insn
& (1 << (size
+ 19))) == 0)
6209 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6210 /* To avoid excessive duplication of ops we implement shift
6211 by immediate using the variable shift operations. */
6213 /* Shift by immediate:
6214 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6215 if (q
&& ((rd
| rm
) & 1)) {
6218 if (!u
&& (op
== 4 || op
== 6)) {
6221 /* Right shifts are encoded as N - shift, where N is the
6222 element size in bits. */
6224 shift
= shift
- (1 << (size
+ 3));
6232 imm
= (uint8_t) shift
;
6237 imm
= (uint16_t) shift
;
6248 for (pass
= 0; pass
< count
; pass
++) {
6250 neon_load_reg64(cpu_V0
, rm
+ pass
);
6251 tcg_gen_movi_i64(cpu_V1
, imm
);
6256 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6258 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6263 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6265 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6268 case 5: /* VSHL, VSLI */
6269 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6271 case 6: /* VQSHLU */
6272 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6277 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6280 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6285 if (op
== 1 || op
== 3) {
6287 neon_load_reg64(cpu_V1
, rd
+ pass
);
6288 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6289 } else if (op
== 4 || (op
== 5 && u
)) {
6291 neon_load_reg64(cpu_V1
, rd
+ pass
);
6293 if (shift
< -63 || shift
> 63) {
6297 mask
= 0xffffffffffffffffull
>> -shift
;
6299 mask
= 0xffffffffffffffffull
<< shift
;
6302 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6303 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6305 neon_store_reg64(cpu_V0
, rd
+ pass
);
6306 } else { /* size < 3 */
6307 /* Operands in T0 and T1. */
6308 tmp
= neon_load_reg(rm
, pass
);
6309 tmp2
= tcg_temp_new_i32();
6310 tcg_gen_movi_i32(tmp2
, imm
);
6314 GEN_NEON_INTEGER_OP(shl
);
6318 GEN_NEON_INTEGER_OP(rshl
);
6321 case 5: /* VSHL, VSLI */
6323 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6324 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6325 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6329 case 6: /* VQSHLU */
6332 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6336 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6340 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6348 GEN_NEON_INTEGER_OP_ENV(qshl
);
6351 tcg_temp_free_i32(tmp2
);
6353 if (op
== 1 || op
== 3) {
6355 tmp2
= neon_load_reg(rd
, pass
);
6356 gen_neon_add(size
, tmp
, tmp2
);
6357 tcg_temp_free_i32(tmp2
);
6358 } else if (op
== 4 || (op
== 5 && u
)) {
6363 mask
= 0xff >> -shift
;
6365 mask
= (uint8_t)(0xff << shift
);
6371 mask
= 0xffff >> -shift
;
6373 mask
= (uint16_t)(0xffff << shift
);
6377 if (shift
< -31 || shift
> 31) {
6381 mask
= 0xffffffffu
>> -shift
;
6383 mask
= 0xffffffffu
<< shift
;
6389 tmp2
= neon_load_reg(rd
, pass
);
6390 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6391 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6392 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6393 tcg_temp_free_i32(tmp2
);
6395 neon_store_reg(rd
, pass
, tmp
);
6398 } else if (op
< 10) {
6399 /* Shift by immediate and narrow:
6400 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6401 int input_unsigned
= (op
== 8) ? !u
: u
;
6405 shift
= shift
- (1 << (size
+ 3));
6408 tmp64
= tcg_const_i64(shift
);
6409 neon_load_reg64(cpu_V0
, rm
);
6410 neon_load_reg64(cpu_V1
, rm
+ 1);
6411 for (pass
= 0; pass
< 2; pass
++) {
6419 if (input_unsigned
) {
6420 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6422 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6425 if (input_unsigned
) {
6426 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6428 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6431 tmp
= tcg_temp_new_i32();
6432 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6433 neon_store_reg(rd
, pass
, tmp
);
6435 tcg_temp_free_i64(tmp64
);
6438 imm
= (uint16_t)shift
;
6442 imm
= (uint32_t)shift
;
6444 tmp2
= tcg_const_i32(imm
);
6445 tmp4
= neon_load_reg(rm
+ 1, 0);
6446 tmp5
= neon_load_reg(rm
+ 1, 1);
6447 for (pass
= 0; pass
< 2; pass
++) {
6449 tmp
= neon_load_reg(rm
, 0);
6453 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6456 tmp3
= neon_load_reg(rm
, 1);
6460 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6462 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6463 tcg_temp_free_i32(tmp
);
6464 tcg_temp_free_i32(tmp3
);
6465 tmp
= tcg_temp_new_i32();
6466 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6467 neon_store_reg(rd
, pass
, tmp
);
6469 tcg_temp_free_i32(tmp2
);
6471 } else if (op
== 10) {
6473 if (q
|| (rd
& 1)) {
6476 tmp
= neon_load_reg(rm
, 0);
6477 tmp2
= neon_load_reg(rm
, 1);
6478 for (pass
= 0; pass
< 2; pass
++) {
6482 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6485 /* The shift is less than the width of the source
6486 type, so we can just shift the whole register. */
6487 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6488 /* Widen the result of shift: we need to clear
6489 * the potential overflow bits resulting from
6490 * left bits of the narrow input appearing as
6491 * right bits of left the neighbour narrow
6493 if (size
< 2 || !u
) {
6496 imm
= (0xffu
>> (8 - shift
));
6498 } else if (size
== 1) {
6499 imm
= 0xffff >> (16 - shift
);
6502 imm
= 0xffffffff >> (32 - shift
);
6505 imm64
= imm
| (((uint64_t)imm
) << 32);
6509 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6512 neon_store_reg64(cpu_V0
, rd
+ pass
);
6514 } else if (op
>= 14) {
6515 /* VCVT fixed-point. */
6516 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6519 /* We have already masked out the must-be-1 top bit of imm6,
6520 * hence this 32-shift where the ARM ARM has 64-imm6.
6523 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6524 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6527 gen_vfp_ulto(0, shift
, 1);
6529 gen_vfp_slto(0, shift
, 1);
6532 gen_vfp_toul(0, shift
, 1);
6534 gen_vfp_tosl(0, shift
, 1);
6536 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6541 } else { /* (insn & 0x00380080) == 0 */
6543 if (q
&& (rd
& 1)) {
6547 op
= (insn
>> 8) & 0xf;
6548 /* One register and immediate. */
6549 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6550 invert
= (insn
& (1 << 5)) != 0;
6551 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6552 * We choose to not special-case this and will behave as if a
6553 * valid constant encoding of 0 had been given.
6572 imm
= (imm
<< 8) | (imm
<< 24);
6575 imm
= (imm
<< 8) | 0xff;
6578 imm
= (imm
<< 16) | 0xffff;
6581 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6589 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6590 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6596 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6597 if (op
& 1 && op
< 12) {
6598 tmp
= neon_load_reg(rd
, pass
);
6600 /* The immediate value has already been inverted, so
6602 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6604 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6608 tmp
= tcg_temp_new_i32();
6609 if (op
== 14 && invert
) {
6613 for (n
= 0; n
< 4; n
++) {
6614 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6615 val
|= 0xff << (n
* 8);
6617 tcg_gen_movi_i32(tmp
, val
);
6619 tcg_gen_movi_i32(tmp
, imm
);
6622 neon_store_reg(rd
, pass
, tmp
);
6625 } else { /* (insn & 0x00800010 == 0x00800000) */
6627 op
= (insn
>> 8) & 0xf;
6628 if ((insn
& (1 << 6)) == 0) {
6629 /* Three registers of different lengths. */
6633 /* undefreq: bit 0 : UNDEF if size == 0
6634 * bit 1 : UNDEF if size == 1
6635 * bit 2 : UNDEF if size == 2
6636 * bit 3 : UNDEF if U == 1
6637 * Note that [2:0] set implies 'always UNDEF'
6640 /* prewiden, src1_wide, src2_wide, undefreq */
6641 static const int neon_3reg_wide
[16][4] = {
6642 {1, 0, 0, 0}, /* VADDL */
6643 {1, 1, 0, 0}, /* VADDW */
6644 {1, 0, 0, 0}, /* VSUBL */
6645 {1, 1, 0, 0}, /* VSUBW */
6646 {0, 1, 1, 0}, /* VADDHN */
6647 {0, 0, 0, 0}, /* VABAL */
6648 {0, 1, 1, 0}, /* VSUBHN */
6649 {0, 0, 0, 0}, /* VABDL */
6650 {0, 0, 0, 0}, /* VMLAL */
6651 {0, 0, 0, 9}, /* VQDMLAL */
6652 {0, 0, 0, 0}, /* VMLSL */
6653 {0, 0, 0, 9}, /* VQDMLSL */
6654 {0, 0, 0, 0}, /* Integer VMULL */
6655 {0, 0, 0, 1}, /* VQDMULL */
6656 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6657 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6660 prewiden
= neon_3reg_wide
[op
][0];
6661 src1_wide
= neon_3reg_wide
[op
][1];
6662 src2_wide
= neon_3reg_wide
[op
][2];
6663 undefreq
= neon_3reg_wide
[op
][3];
6665 if ((undefreq
& (1 << size
)) ||
6666 ((undefreq
& 8) && u
)) {
6669 if ((src1_wide
&& (rn
& 1)) ||
6670 (src2_wide
&& (rm
& 1)) ||
6671 (!src2_wide
&& (rd
& 1))) {
6675 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6676 * outside the loop below as it only performs a single pass.
6678 if (op
== 14 && size
== 2) {
6679 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6681 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6684 tcg_rn
= tcg_temp_new_i64();
6685 tcg_rm
= tcg_temp_new_i64();
6686 tcg_rd
= tcg_temp_new_i64();
6687 neon_load_reg64(tcg_rn
, rn
);
6688 neon_load_reg64(tcg_rm
, rm
);
6689 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6690 neon_store_reg64(tcg_rd
, rd
);
6691 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6692 neon_store_reg64(tcg_rd
, rd
+ 1);
6693 tcg_temp_free_i64(tcg_rn
);
6694 tcg_temp_free_i64(tcg_rm
);
6695 tcg_temp_free_i64(tcg_rd
);
6699 /* Avoid overlapping operands. Wide source operands are
6700 always aligned so will never overlap with wide
6701 destinations in problematic ways. */
6702 if (rd
== rm
&& !src2_wide
) {
6703 tmp
= neon_load_reg(rm
, 1);
6704 neon_store_scratch(2, tmp
);
6705 } else if (rd
== rn
&& !src1_wide
) {
6706 tmp
= neon_load_reg(rn
, 1);
6707 neon_store_scratch(2, tmp
);
6710 for (pass
= 0; pass
< 2; pass
++) {
6712 neon_load_reg64(cpu_V0
, rn
+ pass
);
6715 if (pass
== 1 && rd
== rn
) {
6716 tmp
= neon_load_scratch(2);
6718 tmp
= neon_load_reg(rn
, pass
);
6721 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6725 neon_load_reg64(cpu_V1
, rm
+ pass
);
6728 if (pass
== 1 && rd
== rm
) {
6729 tmp2
= neon_load_scratch(2);
6731 tmp2
= neon_load_reg(rm
, pass
);
6734 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6738 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6739 gen_neon_addl(size
);
6741 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6742 gen_neon_subl(size
);
6744 case 5: case 7: /* VABAL, VABDL */
6745 switch ((size
<< 1) | u
) {
6747 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6750 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6753 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6756 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6759 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6762 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6766 tcg_temp_free_i32(tmp2
);
6767 tcg_temp_free_i32(tmp
);
6769 case 8: case 9: case 10: case 11: case 12: case 13:
6770 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6771 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6773 case 14: /* Polynomial VMULL */
6774 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6775 tcg_temp_free_i32(tmp2
);
6776 tcg_temp_free_i32(tmp
);
6778 default: /* 15 is RESERVED: caught earlier */
6783 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6784 neon_store_reg64(cpu_V0
, rd
+ pass
);
6785 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6787 neon_load_reg64(cpu_V1
, rd
+ pass
);
6789 case 10: /* VMLSL */
6790 gen_neon_negl(cpu_V0
, size
);
6792 case 5: case 8: /* VABAL, VMLAL */
6793 gen_neon_addl(size
);
6795 case 9: case 11: /* VQDMLAL, VQDMLSL */
6796 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6798 gen_neon_negl(cpu_V0
, size
);
6800 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6805 neon_store_reg64(cpu_V0
, rd
+ pass
);
6806 } else if (op
== 4 || op
== 6) {
6807 /* Narrowing operation. */
6808 tmp
= tcg_temp_new_i32();
6812 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6815 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6818 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6819 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6826 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6829 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6832 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6833 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6834 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6842 neon_store_reg(rd
, 0, tmp3
);
6843 neon_store_reg(rd
, 1, tmp
);
6846 /* Write back the result. */
6847 neon_store_reg64(cpu_V0
, rd
+ pass
);
6851 /* Two registers and a scalar. NB that for ops of this form
6852 * the ARM ARM labels bit 24 as Q, but it is in our variable
6859 case 1: /* Float VMLA scalar */
6860 case 5: /* Floating point VMLS scalar */
6861 case 9: /* Floating point VMUL scalar */
6866 case 0: /* Integer VMLA scalar */
6867 case 4: /* Integer VMLS scalar */
6868 case 8: /* Integer VMUL scalar */
6869 case 12: /* VQDMULH scalar */
6870 case 13: /* VQRDMULH scalar */
6871 if (u
&& ((rd
| rn
) & 1)) {
6874 tmp
= neon_get_scalar(size
, rm
);
6875 neon_store_scratch(0, tmp
);
6876 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6877 tmp
= neon_load_scratch(0);
6878 tmp2
= neon_load_reg(rn
, pass
);
6881 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6883 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6885 } else if (op
== 13) {
6887 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6889 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6891 } else if (op
& 1) {
6892 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6893 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6894 tcg_temp_free_ptr(fpstatus
);
6897 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6898 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6899 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6903 tcg_temp_free_i32(tmp2
);
6906 tmp2
= neon_load_reg(rd
, pass
);
6909 gen_neon_add(size
, tmp
, tmp2
);
6913 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6914 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6915 tcg_temp_free_ptr(fpstatus
);
6919 gen_neon_rsb(size
, tmp
, tmp2
);
6923 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6924 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6925 tcg_temp_free_ptr(fpstatus
);
6931 tcg_temp_free_i32(tmp2
);
6933 neon_store_reg(rd
, pass
, tmp
);
6936 case 3: /* VQDMLAL scalar */
6937 case 7: /* VQDMLSL scalar */
6938 case 11: /* VQDMULL scalar */
6943 case 2: /* VMLAL sclar */
6944 case 6: /* VMLSL scalar */
6945 case 10: /* VMULL scalar */
6949 tmp2
= neon_get_scalar(size
, rm
);
6950 /* We need a copy of tmp2 because gen_neon_mull
6951 * deletes it during pass 0. */
6952 tmp4
= tcg_temp_new_i32();
6953 tcg_gen_mov_i32(tmp4
, tmp2
);
6954 tmp3
= neon_load_reg(rn
, 1);
6956 for (pass
= 0; pass
< 2; pass
++) {
6958 tmp
= neon_load_reg(rn
, 0);
6963 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6965 neon_load_reg64(cpu_V1
, rd
+ pass
);
6969 gen_neon_negl(cpu_V0
, size
);
6972 gen_neon_addl(size
);
6975 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6977 gen_neon_negl(cpu_V0
, size
);
6979 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6985 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6990 neon_store_reg64(cpu_V0
, rd
+ pass
);
6993 case 14: /* VQRDMLAH scalar */
6994 case 15: /* VQRDMLSH scalar */
6996 NeonGenThreeOpEnvFn
*fn
;
6998 if (!arm_dc_feature(s
, ARM_FEATURE_V8_RDM
)) {
7001 if (u
&& ((rd
| rn
) & 1)) {
7006 fn
= gen_helper_neon_qrdmlah_s16
;
7008 fn
= gen_helper_neon_qrdmlah_s32
;
7012 fn
= gen_helper_neon_qrdmlsh_s16
;
7014 fn
= gen_helper_neon_qrdmlsh_s32
;
7018 tmp2
= neon_get_scalar(size
, rm
);
7019 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
7020 tmp
= neon_load_reg(rn
, pass
);
7021 tmp3
= neon_load_reg(rd
, pass
);
7022 fn(tmp
, cpu_env
, tmp
, tmp2
, tmp3
);
7023 tcg_temp_free_i32(tmp3
);
7024 neon_store_reg(rd
, pass
, tmp
);
7026 tcg_temp_free_i32(tmp2
);
7030 g_assert_not_reached();
7033 } else { /* size == 3 */
7036 imm
= (insn
>> 8) & 0xf;
7041 if (q
&& ((rd
| rn
| rm
) & 1)) {
7046 neon_load_reg64(cpu_V0
, rn
);
7048 neon_load_reg64(cpu_V1
, rn
+ 1);
7050 } else if (imm
== 8) {
7051 neon_load_reg64(cpu_V0
, rn
+ 1);
7053 neon_load_reg64(cpu_V1
, rm
);
7056 tmp64
= tcg_temp_new_i64();
7058 neon_load_reg64(cpu_V0
, rn
);
7059 neon_load_reg64(tmp64
, rn
+ 1);
7061 neon_load_reg64(cpu_V0
, rn
+ 1);
7062 neon_load_reg64(tmp64
, rm
);
7064 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
7065 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
7066 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7068 neon_load_reg64(cpu_V1
, rm
);
7070 neon_load_reg64(cpu_V1
, rm
+ 1);
7073 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7074 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
7075 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
7076 tcg_temp_free_i64(tmp64
);
7079 neon_load_reg64(cpu_V0
, rn
);
7080 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
7081 neon_load_reg64(cpu_V1
, rm
);
7082 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
7083 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
7085 neon_store_reg64(cpu_V0
, rd
);
7087 neon_store_reg64(cpu_V1
, rd
+ 1);
7089 } else if ((insn
& (1 << 11)) == 0) {
7090 /* Two register misc. */
7091 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
7092 size
= (insn
>> 18) & 3;
7093 /* UNDEF for unknown op values and bad op-size combinations */
7094 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
7097 if (neon_2rm_is_v8_op(op
) &&
7098 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7101 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
7102 q
&& ((rm
| rd
) & 1)) {
7106 case NEON_2RM_VREV64
:
7107 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
7108 tmp
= neon_load_reg(rm
, pass
* 2);
7109 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
7111 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7112 case 1: gen_swap_half(tmp
); break;
7113 case 2: /* no-op */ break;
7116 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
7118 neon_store_reg(rd
, pass
* 2, tmp2
);
7121 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
7122 case 1: gen_swap_half(tmp2
); break;
7125 neon_store_reg(rd
, pass
* 2, tmp2
);
7129 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
7130 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
7131 for (pass
= 0; pass
< q
+ 1; pass
++) {
7132 tmp
= neon_load_reg(rm
, pass
* 2);
7133 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
7134 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
7135 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
7137 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
7138 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
7139 case 2: tcg_gen_add_i64(CPU_V001
); break;
7142 if (op
>= NEON_2RM_VPADAL
) {
7144 neon_load_reg64(cpu_V1
, rd
+ pass
);
7145 gen_neon_addl(size
);
7147 neon_store_reg64(cpu_V0
, rd
+ pass
);
7153 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7154 tmp
= neon_load_reg(rm
, n
);
7155 tmp2
= neon_load_reg(rd
, n
+ 1);
7156 neon_store_reg(rm
, n
, tmp2
);
7157 neon_store_reg(rd
, n
+ 1, tmp
);
7164 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7169 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7173 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7174 /* also VQMOVUN; op field and mnemonics don't line up */
7179 for (pass
= 0; pass
< 2; pass
++) {
7180 neon_load_reg64(cpu_V0
, rm
+ pass
);
7181 tmp
= tcg_temp_new_i32();
7182 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7187 neon_store_reg(rd
, 0, tmp2
);
7188 neon_store_reg(rd
, 1, tmp
);
7192 case NEON_2RM_VSHLL
:
7193 if (q
|| (rd
& 1)) {
7196 tmp
= neon_load_reg(rm
, 0);
7197 tmp2
= neon_load_reg(rm
, 1);
7198 for (pass
= 0; pass
< 2; pass
++) {
7201 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7202 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7203 neon_store_reg64(cpu_V0
, rd
+ pass
);
7206 case NEON_2RM_VCVT_F16_F32
:
7207 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7211 tmp
= tcg_temp_new_i32();
7212 tmp2
= tcg_temp_new_i32();
7213 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7214 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7215 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7216 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7217 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7218 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7219 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7220 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7221 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7222 neon_store_reg(rd
, 0, tmp2
);
7223 tmp2
= tcg_temp_new_i32();
7224 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7225 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7226 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7227 neon_store_reg(rd
, 1, tmp2
);
7228 tcg_temp_free_i32(tmp
);
7230 case NEON_2RM_VCVT_F32_F16
:
7231 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7235 tmp3
= tcg_temp_new_i32();
7236 tmp
= neon_load_reg(rm
, 0);
7237 tmp2
= neon_load_reg(rm
, 1);
7238 tcg_gen_ext16u_i32(tmp3
, tmp
);
7239 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7240 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7241 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7242 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7243 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7244 tcg_temp_free_i32(tmp
);
7245 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7246 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7247 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7248 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7249 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7250 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7251 tcg_temp_free_i32(tmp2
);
7252 tcg_temp_free_i32(tmp3
);
7254 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7255 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
7256 || ((rm
| rd
) & 1)) {
7259 ptr1
= vfp_reg_ptr(true, rd
);
7260 ptr2
= vfp_reg_ptr(true, rm
);
7262 /* Bit 6 is the lowest opcode bit; it distinguishes between
7263 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7265 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7267 if (op
== NEON_2RM_AESE
) {
7268 gen_helper_crypto_aese(ptr1
, ptr2
, tmp3
);
7270 gen_helper_crypto_aesmc(ptr1
, ptr2
, tmp3
);
7272 tcg_temp_free_ptr(ptr1
);
7273 tcg_temp_free_ptr(ptr2
);
7274 tcg_temp_free_i32(tmp3
);
7276 case NEON_2RM_SHA1H
:
7277 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7278 || ((rm
| rd
) & 1)) {
7281 ptr1
= vfp_reg_ptr(true, rd
);
7282 ptr2
= vfp_reg_ptr(true, rm
);
7284 gen_helper_crypto_sha1h(ptr1
, ptr2
);
7286 tcg_temp_free_ptr(ptr1
);
7287 tcg_temp_free_ptr(ptr2
);
7289 case NEON_2RM_SHA1SU1
:
7290 if ((rm
| rd
) & 1) {
7293 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7295 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7298 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7301 ptr1
= vfp_reg_ptr(true, rd
);
7302 ptr2
= vfp_reg_ptr(true, rm
);
7304 gen_helper_crypto_sha256su0(ptr1
, ptr2
);
7306 gen_helper_crypto_sha1su1(ptr1
, ptr2
);
7308 tcg_temp_free_ptr(ptr1
);
7309 tcg_temp_free_ptr(ptr2
);
7313 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7314 if (neon_2rm_is_float_op(op
)) {
7315 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7316 neon_reg_offset(rm
, pass
));
7319 tmp
= neon_load_reg(rm
, pass
);
7322 case NEON_2RM_VREV32
:
7324 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7325 case 1: gen_swap_half(tmp
); break;
7329 case NEON_2RM_VREV16
:
7334 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7335 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7336 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7342 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7343 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7344 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7349 gen_helper_neon_cnt_u8(tmp
, tmp
);
7352 tcg_gen_not_i32(tmp
, tmp
);
7354 case NEON_2RM_VQABS
:
7357 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7360 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7363 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7368 case NEON_2RM_VQNEG
:
7371 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7374 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7377 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7382 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7383 tmp2
= tcg_const_i32(0);
7385 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7386 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7387 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7390 tcg_temp_free_i32(tmp2
);
7391 if (op
== NEON_2RM_VCLE0
) {
7392 tcg_gen_not_i32(tmp
, tmp
);
7395 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7396 tmp2
= tcg_const_i32(0);
7398 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7399 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7400 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7403 tcg_temp_free_i32(tmp2
);
7404 if (op
== NEON_2RM_VCLT0
) {
7405 tcg_gen_not_i32(tmp
, tmp
);
7408 case NEON_2RM_VCEQ0
:
7409 tmp2
= tcg_const_i32(0);
7411 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7412 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7413 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7416 tcg_temp_free_i32(tmp2
);
7420 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7421 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7422 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7427 tmp2
= tcg_const_i32(0);
7428 gen_neon_rsb(size
, tmp
, tmp2
);
7429 tcg_temp_free_i32(tmp2
);
7431 case NEON_2RM_VCGT0_F
:
7433 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7434 tmp2
= tcg_const_i32(0);
7435 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7436 tcg_temp_free_i32(tmp2
);
7437 tcg_temp_free_ptr(fpstatus
);
7440 case NEON_2RM_VCGE0_F
:
7442 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7443 tmp2
= tcg_const_i32(0);
7444 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7445 tcg_temp_free_i32(tmp2
);
7446 tcg_temp_free_ptr(fpstatus
);
7449 case NEON_2RM_VCEQ0_F
:
7451 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7452 tmp2
= tcg_const_i32(0);
7453 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7454 tcg_temp_free_i32(tmp2
);
7455 tcg_temp_free_ptr(fpstatus
);
7458 case NEON_2RM_VCLE0_F
:
7460 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7461 tmp2
= tcg_const_i32(0);
7462 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7463 tcg_temp_free_i32(tmp2
);
7464 tcg_temp_free_ptr(fpstatus
);
7467 case NEON_2RM_VCLT0_F
:
7469 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7470 tmp2
= tcg_const_i32(0);
7471 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7472 tcg_temp_free_i32(tmp2
);
7473 tcg_temp_free_ptr(fpstatus
);
7476 case NEON_2RM_VABS_F
:
7479 case NEON_2RM_VNEG_F
:
7483 tmp2
= neon_load_reg(rd
, pass
);
7484 neon_store_reg(rm
, pass
, tmp2
);
7487 tmp2
= neon_load_reg(rd
, pass
);
7489 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7490 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7493 neon_store_reg(rm
, pass
, tmp2
);
7495 case NEON_2RM_VRINTN
:
7496 case NEON_2RM_VRINTA
:
7497 case NEON_2RM_VRINTM
:
7498 case NEON_2RM_VRINTP
:
7499 case NEON_2RM_VRINTZ
:
7502 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7505 if (op
== NEON_2RM_VRINTZ
) {
7506 rmode
= FPROUNDING_ZERO
;
7508 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7511 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7512 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7514 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7515 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7517 tcg_temp_free_ptr(fpstatus
);
7518 tcg_temp_free_i32(tcg_rmode
);
7521 case NEON_2RM_VRINTX
:
7523 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7524 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7525 tcg_temp_free_ptr(fpstatus
);
7528 case NEON_2RM_VCVTAU
:
7529 case NEON_2RM_VCVTAS
:
7530 case NEON_2RM_VCVTNU
:
7531 case NEON_2RM_VCVTNS
:
7532 case NEON_2RM_VCVTPU
:
7533 case NEON_2RM_VCVTPS
:
7534 case NEON_2RM_VCVTMU
:
7535 case NEON_2RM_VCVTMS
:
7537 bool is_signed
= !extract32(insn
, 7, 1);
7538 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7539 TCGv_i32 tcg_rmode
, tcg_shift
;
7540 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7542 tcg_shift
= tcg_const_i32(0);
7543 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7544 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7548 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7551 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7555 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7557 tcg_temp_free_i32(tcg_rmode
);
7558 tcg_temp_free_i32(tcg_shift
);
7559 tcg_temp_free_ptr(fpst
);
7562 case NEON_2RM_VRECPE
:
7564 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7565 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7566 tcg_temp_free_ptr(fpstatus
);
7569 case NEON_2RM_VRSQRTE
:
7571 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7572 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7573 tcg_temp_free_ptr(fpstatus
);
7576 case NEON_2RM_VRECPE_F
:
7578 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7579 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7580 tcg_temp_free_ptr(fpstatus
);
7583 case NEON_2RM_VRSQRTE_F
:
7585 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7586 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7587 tcg_temp_free_ptr(fpstatus
);
7590 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7593 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7596 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7597 gen_vfp_tosiz(0, 1);
7599 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7600 gen_vfp_touiz(0, 1);
7603 /* Reserved op values were caught by the
7604 * neon_2rm_sizes[] check earlier.
7608 if (neon_2rm_is_float_op(op
)) {
7609 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7610 neon_reg_offset(rd
, pass
));
7612 neon_store_reg(rd
, pass
, tmp
);
7617 } else if ((insn
& (1 << 10)) == 0) {
7619 int n
= ((insn
>> 8) & 3) + 1;
7620 if ((rn
+ n
) > 32) {
7621 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7622 * helper function running off the end of the register file.
7627 if (insn
& (1 << 6)) {
7628 tmp
= neon_load_reg(rd
, 0);
7630 tmp
= tcg_temp_new_i32();
7631 tcg_gen_movi_i32(tmp
, 0);
7633 tmp2
= neon_load_reg(rm
, 0);
7634 ptr1
= vfp_reg_ptr(true, rn
);
7635 tmp5
= tcg_const_i32(n
);
7636 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, ptr1
, tmp5
);
7637 tcg_temp_free_i32(tmp
);
7638 if (insn
& (1 << 6)) {
7639 tmp
= neon_load_reg(rd
, 1);
7641 tmp
= tcg_temp_new_i32();
7642 tcg_gen_movi_i32(tmp
, 0);
7644 tmp3
= neon_load_reg(rm
, 1);
7645 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, ptr1
, tmp5
);
7646 tcg_temp_free_i32(tmp5
);
7647 tcg_temp_free_ptr(ptr1
);
7648 neon_store_reg(rd
, 0, tmp2
);
7649 neon_store_reg(rd
, 1, tmp3
);
7650 tcg_temp_free_i32(tmp
);
7651 } else if ((insn
& 0x380) == 0) {
7653 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7656 if (insn
& (1 << 19)) {
7657 tmp
= neon_load_reg(rm
, 1);
7659 tmp
= neon_load_reg(rm
, 0);
7661 if (insn
& (1 << 16)) {
7662 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7663 } else if (insn
& (1 << 17)) {
7664 if ((insn
>> 18) & 1)
7665 gen_neon_dup_high16(tmp
);
7667 gen_neon_dup_low16(tmp
);
7669 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7670 tmp2
= tcg_temp_new_i32();
7671 tcg_gen_mov_i32(tmp2
, tmp
);
7672 neon_store_reg(rd
, pass
, tmp2
);
7674 tcg_temp_free_i32(tmp
);
7683 /* Advanced SIMD three registers of the same length extension.
7684 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7685 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7686 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7687 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7689 static int disas_neon_insn_3same_ext(DisasContext
*s
, uint32_t insn
)
7691 gen_helper_gvec_3_ptr
*fn_gvec_ptr
;
7692 int rd
, rn
, rm
, rot
, size
, opr_sz
;
7696 q
= extract32(insn
, 6, 1);
7697 VFP_DREG_D(rd
, insn
);
7698 VFP_DREG_N(rn
, insn
);
7699 VFP_DREG_M(rm
, insn
);
7700 if ((rd
| rn
| rm
) & q
) {
7704 if ((insn
& 0xfe200f10) == 0xfc200800) {
7705 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7706 size
= extract32(insn
, 20, 1);
7707 rot
= extract32(insn
, 23, 2);
7708 if (!arm_dc_feature(s
, ARM_FEATURE_V8_FCMA
)
7709 || (!size
&& !arm_dc_feature(s
, ARM_FEATURE_V8_FP16
))) {
7712 fn_gvec_ptr
= size
? gen_helper_gvec_fcmlas
: gen_helper_gvec_fcmlah
;
7713 } else if ((insn
& 0xfea00f10) == 0xfc800800) {
7714 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7715 size
= extract32(insn
, 20, 1);
7716 rot
= extract32(insn
, 24, 1);
7717 if (!arm_dc_feature(s
, ARM_FEATURE_V8_FCMA
)
7718 || (!size
&& !arm_dc_feature(s
, ARM_FEATURE_V8_FP16
))) {
7721 fn_gvec_ptr
= size
? gen_helper_gvec_fcadds
: gen_helper_gvec_fcaddh
;
7726 if (s
->fp_excp_el
) {
7727 gen_exception_insn(s
, 4, EXCP_UDEF
,
7728 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
7731 if (!s
->vfp_enabled
) {
7735 opr_sz
= (1 + q
) * 8;
7736 fpst
= get_fpstatus_ptr(1);
7737 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
7738 vfp_reg_offset(1, rn
),
7739 vfp_reg_offset(1, rm
), fpst
,
7740 opr_sz
, opr_sz
, rot
, fn_gvec_ptr
);
7741 tcg_temp_free_ptr(fpst
);
7745 /* Advanced SIMD two registers and a scalar extension.
7746 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7747 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7748 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7749 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7753 static int disas_neon_insn_2reg_scalar_ext(DisasContext
*s
, uint32_t insn
)
7755 int rd
, rn
, rm
, rot
, size
, opr_sz
;
7759 q
= extract32(insn
, 6, 1);
7760 VFP_DREG_D(rd
, insn
);
7761 VFP_DREG_N(rn
, insn
);
7762 VFP_DREG_M(rm
, insn
);
7763 if ((rd
| rn
) & q
) {
7767 if ((insn
& 0xff000f10) == 0xfe000800) {
7768 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7769 rot
= extract32(insn
, 20, 2);
7770 size
= extract32(insn
, 23, 1);
7771 if (!arm_dc_feature(s
, ARM_FEATURE_V8_FCMA
)
7772 || (!size
&& !arm_dc_feature(s
, ARM_FEATURE_V8_FP16
))) {
7779 if (s
->fp_excp_el
) {
7780 gen_exception_insn(s
, 4, EXCP_UDEF
,
7781 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
7784 if (!s
->vfp_enabled
) {
7788 opr_sz
= (1 + q
) * 8;
7789 fpst
= get_fpstatus_ptr(1);
7790 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
7791 vfp_reg_offset(1, rn
),
7792 vfp_reg_offset(1, rm
), fpst
,
7793 opr_sz
, opr_sz
, rot
,
7794 size
? gen_helper_gvec_fcmlas_idx
7795 : gen_helper_gvec_fcmlah_idx
);
7796 tcg_temp_free_ptr(fpst
);
7800 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7802 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7803 const ARMCPRegInfo
*ri
;
7805 cpnum
= (insn
>> 8) & 0xf;
7807 /* First check for coprocessor space used for XScale/iwMMXt insns */
7808 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7809 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7812 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7813 return disas_iwmmxt_insn(s
, insn
);
7814 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7815 return disas_dsp_insn(s
, insn
);
7820 /* Otherwise treat as a generic register access */
7821 is64
= (insn
& (1 << 25)) == 0;
7822 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7830 opc1
= (insn
>> 4) & 0xf;
7832 rt2
= (insn
>> 16) & 0xf;
7834 crn
= (insn
>> 16) & 0xf;
7835 opc1
= (insn
>> 21) & 7;
7836 opc2
= (insn
>> 5) & 7;
7839 isread
= (insn
>> 20) & 1;
7840 rt
= (insn
>> 12) & 0xf;
7842 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7843 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7845 /* Check access permissions */
7846 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7851 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7852 /* Emit code to perform further access permissions checks at
7853 * runtime; this may result in an exception.
7854 * Note that on XScale all cp0..c13 registers do an access check
7855 * call in order to handle c15_cpar.
7858 TCGv_i32 tcg_syn
, tcg_isread
;
7861 /* Note that since we are an implementation which takes an
7862 * exception on a trapped conditional instruction only if the
7863 * instruction passes its condition code check, we can take
7864 * advantage of the clause in the ARM ARM that allows us to set
7865 * the COND field in the instruction to 0xE in all cases.
7866 * We could fish the actual condition out of the insn (ARM)
7867 * or the condexec bits (Thumb) but it isn't necessary.
7872 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7875 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7881 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7884 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7889 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7890 * so this can only happen if this is an ARMv7 or earlier CPU,
7891 * in which case the syndrome information won't actually be
7894 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7895 syndrome
= syn_uncategorized();
7899 gen_set_condexec(s
);
7900 gen_set_pc_im(s
, s
->pc
- 4);
7901 tmpptr
= tcg_const_ptr(ri
);
7902 tcg_syn
= tcg_const_i32(syndrome
);
7903 tcg_isread
= tcg_const_i32(isread
);
7904 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7906 tcg_temp_free_ptr(tmpptr
);
7907 tcg_temp_free_i32(tcg_syn
);
7908 tcg_temp_free_i32(tcg_isread
);
7911 /* Handle special cases first */
7912 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7919 gen_set_pc_im(s
, s
->pc
);
7920 s
->base
.is_jmp
= DISAS_WFI
;
7926 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7935 if (ri
->type
& ARM_CP_CONST
) {
7936 tmp64
= tcg_const_i64(ri
->resetvalue
);
7937 } else if (ri
->readfn
) {
7939 tmp64
= tcg_temp_new_i64();
7940 tmpptr
= tcg_const_ptr(ri
);
7941 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7942 tcg_temp_free_ptr(tmpptr
);
7944 tmp64
= tcg_temp_new_i64();
7945 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7947 tmp
= tcg_temp_new_i32();
7948 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7949 store_reg(s
, rt
, tmp
);
7950 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7951 tmp
= tcg_temp_new_i32();
7952 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7953 tcg_temp_free_i64(tmp64
);
7954 store_reg(s
, rt2
, tmp
);
7957 if (ri
->type
& ARM_CP_CONST
) {
7958 tmp
= tcg_const_i32(ri
->resetvalue
);
7959 } else if (ri
->readfn
) {
7961 tmp
= tcg_temp_new_i32();
7962 tmpptr
= tcg_const_ptr(ri
);
7963 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7964 tcg_temp_free_ptr(tmpptr
);
7966 tmp
= load_cpu_offset(ri
->fieldoffset
);
7969 /* Destination register of r15 for 32 bit loads sets
7970 * the condition codes from the high 4 bits of the value
7973 tcg_temp_free_i32(tmp
);
7975 store_reg(s
, rt
, tmp
);
7980 if (ri
->type
& ARM_CP_CONST
) {
7981 /* If not forbidden by access permissions, treat as WI */
7986 TCGv_i32 tmplo
, tmphi
;
7987 TCGv_i64 tmp64
= tcg_temp_new_i64();
7988 tmplo
= load_reg(s
, rt
);
7989 tmphi
= load_reg(s
, rt2
);
7990 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7991 tcg_temp_free_i32(tmplo
);
7992 tcg_temp_free_i32(tmphi
);
7994 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7995 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7996 tcg_temp_free_ptr(tmpptr
);
7998 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
8000 tcg_temp_free_i64(tmp64
);
8005 tmp
= load_reg(s
, rt
);
8006 tmpptr
= tcg_const_ptr(ri
);
8007 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
8008 tcg_temp_free_ptr(tmpptr
);
8009 tcg_temp_free_i32(tmp
);
8011 TCGv_i32 tmp
= load_reg(s
, rt
);
8012 store_cpu_offset(tmp
, ri
->fieldoffset
);
8017 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
8018 /* I/O operations must end the TB here (whether read or write) */
8021 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
8022 /* We default to ending the TB on a coprocessor register write,
8023 * but allow this to be suppressed by the register definition
8024 * (usually only necessary to work around guest bugs).
8032 /* Unknown register; this might be a guest error or a QEMU
8033 * unimplemented feature.
8036 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8037 "64 bit system register cp:%d opc1: %d crm:%d "
8039 isread
? "read" : "write", cpnum
, opc1
, crm
,
8040 s
->ns
? "non-secure" : "secure");
8042 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
8043 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8045 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
8046 s
->ns
? "non-secure" : "secure");
8053 /* Store a 64-bit value to a register pair. Clobbers val. */
8054 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
8057 tmp
= tcg_temp_new_i32();
8058 tcg_gen_extrl_i64_i32(tmp
, val
);
8059 store_reg(s
, rlow
, tmp
);
8060 tmp
= tcg_temp_new_i32();
8061 tcg_gen_shri_i64(val
, val
, 32);
8062 tcg_gen_extrl_i64_i32(tmp
, val
);
8063 store_reg(s
, rhigh
, tmp
);
8066 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8067 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
8072 /* Load value and extend to 64 bits. */
8073 tmp
= tcg_temp_new_i64();
8074 tmp2
= load_reg(s
, rlow
);
8075 tcg_gen_extu_i32_i64(tmp
, tmp2
);
8076 tcg_temp_free_i32(tmp2
);
8077 tcg_gen_add_i64(val
, val
, tmp
);
8078 tcg_temp_free_i64(tmp
);
8081 /* load and add a 64-bit value from a register pair. */
8082 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
8088 /* Load 64-bit value rd:rn. */
8089 tmpl
= load_reg(s
, rlow
);
8090 tmph
= load_reg(s
, rhigh
);
8091 tmp
= tcg_temp_new_i64();
8092 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
8093 tcg_temp_free_i32(tmpl
);
8094 tcg_temp_free_i32(tmph
);
8095 tcg_gen_add_i64(val
, val
, tmp
);
8096 tcg_temp_free_i64(tmp
);
8099 /* Set N and Z flags from hi|lo. */
8100 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
8102 tcg_gen_mov_i32(cpu_NF
, hi
);
8103 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
8106 /* Load/Store exclusive instructions are implemented by remembering
8107 the value/address loaded, and seeing if these are the same
8108 when the store is performed. This should be sufficient to implement
8109 the architecturally mandated semantics, and avoids having to monitor
8110 regular stores. The compare vs the remembered value is done during
8111 the cmpxchg operation, but we must compare the addresses manually. */
8112 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
8113 TCGv_i32 addr
, int size
)
8115 TCGv_i32 tmp
= tcg_temp_new_i32();
8116 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8121 TCGv_i32 tmp2
= tcg_temp_new_i32();
8122 TCGv_i64 t64
= tcg_temp_new_i64();
8124 /* For AArch32, architecturally the 32-bit word at the lowest
8125 * address is always Rt and the one at addr+4 is Rt2, even if
8126 * the CPU is big-endian. That means we don't want to do a
8127 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8128 * for an architecturally 64-bit access, but instead do a
8129 * 64-bit access using MO_BE if appropriate and then split
8131 * This only makes a difference for BE32 user-mode, where
8132 * frob64() must not flip the two halves of the 64-bit data
8133 * but this code must treat BE32 user-mode like BE32 system.
8135 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
8137 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
8138 tcg_temp_free(taddr
);
8139 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
8140 if (s
->be_data
== MO_BE
) {
8141 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
8143 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
8145 tcg_temp_free_i64(t64
);
8147 store_reg(s
, rt2
, tmp2
);
8149 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
8150 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
8153 store_reg(s
, rt
, tmp
);
8154 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
8157 static void gen_clrex(DisasContext
*s
)
8159 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8162 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
8163 TCGv_i32 addr
, int size
)
8165 TCGv_i32 t0
, t1
, t2
;
8168 TCGLabel
*done_label
;
8169 TCGLabel
*fail_label
;
8170 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8172 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8178 fail_label
= gen_new_label();
8179 done_label
= gen_new_label();
8180 extaddr
= tcg_temp_new_i64();
8181 tcg_gen_extu_i32_i64(extaddr
, addr
);
8182 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
8183 tcg_temp_free_i64(extaddr
);
8185 taddr
= gen_aa32_addr(s
, addr
, opc
);
8186 t0
= tcg_temp_new_i32();
8187 t1
= load_reg(s
, rt
);
8189 TCGv_i64 o64
= tcg_temp_new_i64();
8190 TCGv_i64 n64
= tcg_temp_new_i64();
8192 t2
= load_reg(s
, rt2
);
8193 /* For AArch32, architecturally the 32-bit word at the lowest
8194 * address is always Rt and the one at addr+4 is Rt2, even if
8195 * the CPU is big-endian. Since we're going to treat this as a
8196 * single 64-bit BE store, we need to put the two halves in the
8197 * opposite order for BE to LE, so that they end up in the right
8199 * We don't want gen_aa32_frob64() because that does the wrong
8200 * thing for BE32 usermode.
8202 if (s
->be_data
== MO_BE
) {
8203 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
8205 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
8207 tcg_temp_free_i32(t2
);
8209 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
8210 get_mem_index(s
), opc
);
8211 tcg_temp_free_i64(n64
);
8213 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
8214 tcg_gen_extrl_i64_i32(t0
, o64
);
8216 tcg_temp_free_i64(o64
);
8218 t2
= tcg_temp_new_i32();
8219 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
8220 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
8221 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
8222 tcg_temp_free_i32(t2
);
8224 tcg_temp_free_i32(t1
);
8225 tcg_temp_free(taddr
);
8226 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
8227 tcg_temp_free_i32(t0
);
8228 tcg_gen_br(done_label
);
8230 gen_set_label(fail_label
);
8231 tcg_gen_movi_i32(cpu_R
[rd
], 1);
8232 gen_set_label(done_label
);
8233 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8239 * @mode: mode field from insn (which stack to store to)
8240 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8241 * @writeback: true if writeback bit set
8243 * Generate code for the SRS (Store Return State) insn.
8245 static void gen_srs(DisasContext
*s
,
8246 uint32_t mode
, uint32_t amode
, bool writeback
)
8253 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8254 * and specified mode is monitor mode
8255 * - UNDEFINED in Hyp mode
8256 * - UNPREDICTABLE in User or System mode
8257 * - UNPREDICTABLE if the specified mode is:
8258 * -- not implemented
8259 * -- not a valid mode number
8260 * -- a mode that's at a higher exception level
8261 * -- Monitor, if we are Non-secure
8262 * For the UNPREDICTABLE cases we choose to UNDEF.
8264 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
8265 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
8269 if (s
->current_el
== 0 || s
->current_el
== 2) {
8274 case ARM_CPU_MODE_USR
:
8275 case ARM_CPU_MODE_FIQ
:
8276 case ARM_CPU_MODE_IRQ
:
8277 case ARM_CPU_MODE_SVC
:
8278 case ARM_CPU_MODE_ABT
:
8279 case ARM_CPU_MODE_UND
:
8280 case ARM_CPU_MODE_SYS
:
8282 case ARM_CPU_MODE_HYP
:
8283 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
8287 case ARM_CPU_MODE_MON
:
8288 /* No need to check specifically for "are we non-secure" because
8289 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8290 * so if this isn't EL3 then we must be non-secure.
8292 if (s
->current_el
!= 3) {
8301 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8302 default_exception_el(s
));
8306 addr
= tcg_temp_new_i32();
8307 tmp
= tcg_const_i32(mode
);
8308 /* get_r13_banked() will raise an exception if called from System mode */
8309 gen_set_condexec(s
);
8310 gen_set_pc_im(s
, s
->pc
- 4);
8311 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8312 tcg_temp_free_i32(tmp
);
8329 tcg_gen_addi_i32(addr
, addr
, offset
);
8330 tmp
= load_reg(s
, 14);
8331 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8332 tcg_temp_free_i32(tmp
);
8333 tmp
= load_cpu_field(spsr
);
8334 tcg_gen_addi_i32(addr
, addr
, 4);
8335 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8336 tcg_temp_free_i32(tmp
);
8354 tcg_gen_addi_i32(addr
, addr
, offset
);
8355 tmp
= tcg_const_i32(mode
);
8356 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8357 tcg_temp_free_i32(tmp
);
8359 tcg_temp_free_i32(addr
);
8360 s
->base
.is_jmp
= DISAS_UPDATE
;
8363 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8365 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8372 /* M variants do not implement ARM mode; this must raise the INVSTATE
8373 * UsageFault exception.
8375 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8376 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8377 default_exception_el(s
));
8382 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8383 * choose to UNDEF. In ARMv5 and above the space is used
8384 * for miscellaneous unconditional instructions.
8388 /* Unconditional instructions. */
8389 if (((insn
>> 25) & 7) == 1) {
8390 /* NEON Data processing. */
8391 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8395 if (disas_neon_data_insn(s
, insn
)) {
8400 if ((insn
& 0x0f100000) == 0x04000000) {
8401 /* NEON load/store. */
8402 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8406 if (disas_neon_ls_insn(s
, insn
)) {
8411 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8413 if (disas_vfp_insn(s
, insn
)) {
8418 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8419 ((insn
& 0x0f30f010) == 0x0710f000)) {
8420 if ((insn
& (1 << 22)) == 0) {
8422 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8426 /* Otherwise PLD; v5TE+ */
8430 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8431 ((insn
& 0x0f70f010) == 0x0650f000)) {
8433 return; /* PLI; V7 */
8435 if (((insn
& 0x0f700000) == 0x04100000) ||
8436 ((insn
& 0x0f700010) == 0x06100000)) {
8437 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8440 return; /* v7MP: Unallocated memory hint: must NOP */
8443 if ((insn
& 0x0ffffdff) == 0x01010000) {
8446 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8447 gen_helper_setend(cpu_env
);
8448 s
->base
.is_jmp
= DISAS_UPDATE
;
8451 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8452 switch ((insn
>> 4) & 0xf) {
8460 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8463 /* We need to break the TB after this insn to execute
8464 * self-modifying code correctly and also to take
8465 * any pending interrupts immediately.
8467 gen_goto_tb(s
, 0, s
->pc
& ~1);
8472 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8475 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8477 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8483 rn
= (insn
>> 16) & 0xf;
8484 addr
= load_reg(s
, rn
);
8485 i
= (insn
>> 23) & 3;
8487 case 0: offset
= -4; break; /* DA */
8488 case 1: offset
= 0; break; /* IA */
8489 case 2: offset
= -8; break; /* DB */
8490 case 3: offset
= 4; break; /* IB */
8494 tcg_gen_addi_i32(addr
, addr
, offset
);
8495 /* Load PC into tmp and CPSR into tmp2. */
8496 tmp
= tcg_temp_new_i32();
8497 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8498 tcg_gen_addi_i32(addr
, addr
, 4);
8499 tmp2
= tcg_temp_new_i32();
8500 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8501 if (insn
& (1 << 21)) {
8502 /* Base writeback. */
8504 case 0: offset
= -8; break;
8505 case 1: offset
= 4; break;
8506 case 2: offset
= -4; break;
8507 case 3: offset
= 0; break;
8511 tcg_gen_addi_i32(addr
, addr
, offset
);
8512 store_reg(s
, rn
, addr
);
8514 tcg_temp_free_i32(addr
);
8516 gen_rfe(s
, tmp
, tmp2
);
8518 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8519 /* branch link and change to thumb (blx <offset>) */
8522 val
= (uint32_t)s
->pc
;
8523 tmp
= tcg_temp_new_i32();
8524 tcg_gen_movi_i32(tmp
, val
);
8525 store_reg(s
, 14, tmp
);
8526 /* Sign-extend the 24-bit offset */
8527 offset
= (((int32_t)insn
) << 8) >> 8;
8528 /* offset * 4 + bit24 * 2 + (thumb bit) */
8529 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8530 /* pipeline offset */
8532 /* protected by ARCH(5); above, near the start of uncond block */
8535 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8536 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8537 /* iWMMXt register transfer. */
8538 if (extract32(s
->c15_cpar
, 1, 1)) {
8539 if (!disas_iwmmxt_insn(s
, insn
)) {
8544 } else if ((insn
& 0x0e000a00) == 0x0c000800
8545 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8546 if (disas_neon_insn_3same_ext(s
, insn
)) {
8550 } else if ((insn
& 0x0f000a00) == 0x0e000800
8551 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8552 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
8556 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8557 /* Coprocessor double register transfer. */
8559 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8560 /* Additional coprocessor register transfer. */
8561 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8564 /* cps (privileged) */
8568 if (insn
& (1 << 19)) {
8569 if (insn
& (1 << 8))
8571 if (insn
& (1 << 7))
8573 if (insn
& (1 << 6))
8575 if (insn
& (1 << 18))
8578 if (insn
& (1 << 17)) {
8580 val
|= (insn
& 0x1f);
8583 gen_set_psr_im(s
, mask
, 0, val
);
8590 /* if not always execute, we generate a conditional jump to
8592 s
->condlabel
= gen_new_label();
8593 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8596 if ((insn
& 0x0f900000) == 0x03000000) {
8597 if ((insn
& (1 << 21)) == 0) {
8599 rd
= (insn
>> 12) & 0xf;
8600 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8601 if ((insn
& (1 << 22)) == 0) {
8603 tmp
= tcg_temp_new_i32();
8604 tcg_gen_movi_i32(tmp
, val
);
8607 tmp
= load_reg(s
, rd
);
8608 tcg_gen_ext16u_i32(tmp
, tmp
);
8609 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8611 store_reg(s
, rd
, tmp
);
8613 if (((insn
>> 12) & 0xf) != 0xf)
8615 if (((insn
>> 16) & 0xf) == 0) {
8616 gen_nop_hint(s
, insn
& 0xff);
8618 /* CPSR = immediate */
8620 shift
= ((insn
>> 8) & 0xf) * 2;
8622 val
= (val
>> shift
) | (val
<< (32 - shift
));
8623 i
= ((insn
& (1 << 22)) != 0);
8624 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8630 } else if ((insn
& 0x0f900000) == 0x01000000
8631 && (insn
& 0x00000090) != 0x00000090) {
8632 /* miscellaneous instructions */
8633 op1
= (insn
>> 21) & 3;
8634 sh
= (insn
>> 4) & 0xf;
8637 case 0x0: /* MSR, MRS */
8638 if (insn
& (1 << 9)) {
8639 /* MSR (banked) and MRS (banked) */
8640 int sysm
= extract32(insn
, 16, 4) |
8641 (extract32(insn
, 8, 1) << 4);
8642 int r
= extract32(insn
, 22, 1);
8646 gen_msr_banked(s
, r
, sysm
, rm
);
8649 int rd
= extract32(insn
, 12, 4);
8651 gen_mrs_banked(s
, r
, sysm
, rd
);
8656 /* MSR, MRS (for PSRs) */
8659 tmp
= load_reg(s
, rm
);
8660 i
= ((op1
& 2) != 0);
8661 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8665 rd
= (insn
>> 12) & 0xf;
8669 tmp
= load_cpu_field(spsr
);
8671 tmp
= tcg_temp_new_i32();
8672 gen_helper_cpsr_read(tmp
, cpu_env
);
8674 store_reg(s
, rd
, tmp
);
8679 /* branch/exchange thumb (bx). */
8681 tmp
= load_reg(s
, rm
);
8683 } else if (op1
== 3) {
8686 rd
= (insn
>> 12) & 0xf;
8687 tmp
= load_reg(s
, rm
);
8688 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8689 store_reg(s
, rd
, tmp
);
8697 /* Trivial implementation equivalent to bx. */
8698 tmp
= load_reg(s
, rm
);
8709 /* branch link/exchange thumb (blx) */
8710 tmp
= load_reg(s
, rm
);
8711 tmp2
= tcg_temp_new_i32();
8712 tcg_gen_movi_i32(tmp2
, s
->pc
);
8713 store_reg(s
, 14, tmp2
);
8719 uint32_t c
= extract32(insn
, 8, 4);
8721 /* Check this CPU supports ARMv8 CRC instructions.
8722 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8723 * Bits 8, 10 and 11 should be zero.
8725 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8730 rn
= extract32(insn
, 16, 4);
8731 rd
= extract32(insn
, 12, 4);
8733 tmp
= load_reg(s
, rn
);
8734 tmp2
= load_reg(s
, rm
);
8736 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8737 } else if (op1
== 1) {
8738 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8740 tmp3
= tcg_const_i32(1 << op1
);
8742 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8744 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8746 tcg_temp_free_i32(tmp2
);
8747 tcg_temp_free_i32(tmp3
);
8748 store_reg(s
, rd
, tmp
);
8751 case 0x5: /* saturating add/subtract */
8753 rd
= (insn
>> 12) & 0xf;
8754 rn
= (insn
>> 16) & 0xf;
8755 tmp
= load_reg(s
, rm
);
8756 tmp2
= load_reg(s
, rn
);
8758 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8760 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8762 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8763 tcg_temp_free_i32(tmp2
);
8764 store_reg(s
, rd
, tmp
);
8768 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8777 gen_exception_insn(s
, 4, EXCP_BKPT
,
8778 syn_aa32_bkpt(imm16
, false),
8779 default_exception_el(s
));
8782 /* Hypervisor call (v7) */
8790 /* Secure monitor call (v6+) */
8798 g_assert_not_reached();
8802 case 0x8: /* signed multiply */
8807 rs
= (insn
>> 8) & 0xf;
8808 rn
= (insn
>> 12) & 0xf;
8809 rd
= (insn
>> 16) & 0xf;
8811 /* (32 * 16) >> 16 */
8812 tmp
= load_reg(s
, rm
);
8813 tmp2
= load_reg(s
, rs
);
8815 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8818 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8819 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8820 tmp
= tcg_temp_new_i32();
8821 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8822 tcg_temp_free_i64(tmp64
);
8823 if ((sh
& 2) == 0) {
8824 tmp2
= load_reg(s
, rn
);
8825 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8826 tcg_temp_free_i32(tmp2
);
8828 store_reg(s
, rd
, tmp
);
8831 tmp
= load_reg(s
, rm
);
8832 tmp2
= load_reg(s
, rs
);
8833 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8834 tcg_temp_free_i32(tmp2
);
8836 tmp64
= tcg_temp_new_i64();
8837 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8838 tcg_temp_free_i32(tmp
);
8839 gen_addq(s
, tmp64
, rn
, rd
);
8840 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8841 tcg_temp_free_i64(tmp64
);
8844 tmp2
= load_reg(s
, rn
);
8845 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8846 tcg_temp_free_i32(tmp2
);
8848 store_reg(s
, rd
, tmp
);
8855 } else if (((insn
& 0x0e000000) == 0 &&
8856 (insn
& 0x00000090) != 0x90) ||
8857 ((insn
& 0x0e000000) == (1 << 25))) {
8858 int set_cc
, logic_cc
, shiftop
;
8860 op1
= (insn
>> 21) & 0xf;
8861 set_cc
= (insn
>> 20) & 1;
8862 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8864 /* data processing instruction */
8865 if (insn
& (1 << 25)) {
8866 /* immediate operand */
8868 shift
= ((insn
>> 8) & 0xf) * 2;
8870 val
= (val
>> shift
) | (val
<< (32 - shift
));
8872 tmp2
= tcg_temp_new_i32();
8873 tcg_gen_movi_i32(tmp2
, val
);
8874 if (logic_cc
&& shift
) {
8875 gen_set_CF_bit31(tmp2
);
8880 tmp2
= load_reg(s
, rm
);
8881 shiftop
= (insn
>> 5) & 3;
8882 if (!(insn
& (1 << 4))) {
8883 shift
= (insn
>> 7) & 0x1f;
8884 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8886 rs
= (insn
>> 8) & 0xf;
8887 tmp
= load_reg(s
, rs
);
8888 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8891 if (op1
!= 0x0f && op1
!= 0x0d) {
8892 rn
= (insn
>> 16) & 0xf;
8893 tmp
= load_reg(s
, rn
);
8897 rd
= (insn
>> 12) & 0xf;
8900 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8904 store_reg_bx(s
, rd
, tmp
);
8907 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8911 store_reg_bx(s
, rd
, tmp
);
8914 if (set_cc
&& rd
== 15) {
8915 /* SUBS r15, ... is used for exception return. */
8919 gen_sub_CC(tmp
, tmp
, tmp2
);
8920 gen_exception_return(s
, tmp
);
8923 gen_sub_CC(tmp
, tmp
, tmp2
);
8925 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8927 store_reg_bx(s
, rd
, tmp
);
8932 gen_sub_CC(tmp
, tmp2
, tmp
);
8934 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8936 store_reg_bx(s
, rd
, tmp
);
8940 gen_add_CC(tmp
, tmp
, tmp2
);
8942 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8944 store_reg_bx(s
, rd
, tmp
);
8948 gen_adc_CC(tmp
, tmp
, tmp2
);
8950 gen_add_carry(tmp
, tmp
, tmp2
);
8952 store_reg_bx(s
, rd
, tmp
);
8956 gen_sbc_CC(tmp
, tmp
, tmp2
);
8958 gen_sub_carry(tmp
, tmp
, tmp2
);
8960 store_reg_bx(s
, rd
, tmp
);
8964 gen_sbc_CC(tmp
, tmp2
, tmp
);
8966 gen_sub_carry(tmp
, tmp2
, tmp
);
8968 store_reg_bx(s
, rd
, tmp
);
8972 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8975 tcg_temp_free_i32(tmp
);
8979 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8982 tcg_temp_free_i32(tmp
);
8986 gen_sub_CC(tmp
, tmp
, tmp2
);
8988 tcg_temp_free_i32(tmp
);
8992 gen_add_CC(tmp
, tmp
, tmp2
);
8994 tcg_temp_free_i32(tmp
);
8997 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9001 store_reg_bx(s
, rd
, tmp
);
9004 if (logic_cc
&& rd
== 15) {
9005 /* MOVS r15, ... is used for exception return. */
9009 gen_exception_return(s
, tmp2
);
9014 store_reg_bx(s
, rd
, tmp2
);
9018 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9022 store_reg_bx(s
, rd
, tmp
);
9026 tcg_gen_not_i32(tmp2
, tmp2
);
9030 store_reg_bx(s
, rd
, tmp2
);
9033 if (op1
!= 0x0f && op1
!= 0x0d) {
9034 tcg_temp_free_i32(tmp2
);
9037 /* other instructions */
9038 op1
= (insn
>> 24) & 0xf;
9042 /* multiplies, extra load/stores */
9043 sh
= (insn
>> 5) & 3;
9046 rd
= (insn
>> 16) & 0xf;
9047 rn
= (insn
>> 12) & 0xf;
9048 rs
= (insn
>> 8) & 0xf;
9050 op1
= (insn
>> 20) & 0xf;
9052 case 0: case 1: case 2: case 3: case 6:
9054 tmp
= load_reg(s
, rs
);
9055 tmp2
= load_reg(s
, rm
);
9056 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9057 tcg_temp_free_i32(tmp2
);
9058 if (insn
& (1 << 22)) {
9059 /* Subtract (mls) */
9061 tmp2
= load_reg(s
, rn
);
9062 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9063 tcg_temp_free_i32(tmp2
);
9064 } else if (insn
& (1 << 21)) {
9066 tmp2
= load_reg(s
, rn
);
9067 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9068 tcg_temp_free_i32(tmp2
);
9070 if (insn
& (1 << 20))
9072 store_reg(s
, rd
, tmp
);
9075 /* 64 bit mul double accumulate (UMAAL) */
9077 tmp
= load_reg(s
, rs
);
9078 tmp2
= load_reg(s
, rm
);
9079 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9080 gen_addq_lo(s
, tmp64
, rn
);
9081 gen_addq_lo(s
, tmp64
, rd
);
9082 gen_storeq_reg(s
, rn
, rd
, tmp64
);
9083 tcg_temp_free_i64(tmp64
);
9085 case 8: case 9: case 10: case 11:
9086 case 12: case 13: case 14: case 15:
9087 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9088 tmp
= load_reg(s
, rs
);
9089 tmp2
= load_reg(s
, rm
);
9090 if (insn
& (1 << 22)) {
9091 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
9093 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
9095 if (insn
& (1 << 21)) { /* mult accumulate */
9096 TCGv_i32 al
= load_reg(s
, rn
);
9097 TCGv_i32 ah
= load_reg(s
, rd
);
9098 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
9099 tcg_temp_free_i32(al
);
9100 tcg_temp_free_i32(ah
);
9102 if (insn
& (1 << 20)) {
9103 gen_logicq_cc(tmp
, tmp2
);
9105 store_reg(s
, rn
, tmp
);
9106 store_reg(s
, rd
, tmp2
);
9112 rn
= (insn
>> 16) & 0xf;
9113 rd
= (insn
>> 12) & 0xf;
9114 if (insn
& (1 << 23)) {
9115 /* load/store exclusive */
9116 int op2
= (insn
>> 8) & 3;
9117 op1
= (insn
>> 21) & 0x3;
9120 case 0: /* lda/stl */
9126 case 1: /* reserved */
9128 case 2: /* ldaex/stlex */
9131 case 3: /* ldrex/strex */
9140 addr
= tcg_temp_local_new_i32();
9141 load_reg_var(s
, addr
, rn
);
9143 /* Since the emulation does not have barriers,
9144 the acquire/release semantics need no special
9147 if (insn
& (1 << 20)) {
9148 tmp
= tcg_temp_new_i32();
9151 gen_aa32_ld32u_iss(s
, tmp
, addr
,
9156 gen_aa32_ld8u_iss(s
, tmp
, addr
,
9161 gen_aa32_ld16u_iss(s
, tmp
, addr
,
9168 store_reg(s
, rd
, tmp
);
9171 tmp
= load_reg(s
, rm
);
9174 gen_aa32_st32_iss(s
, tmp
, addr
,
9179 gen_aa32_st8_iss(s
, tmp
, addr
,
9184 gen_aa32_st16_iss(s
, tmp
, addr
,
9191 tcg_temp_free_i32(tmp
);
9193 } else if (insn
& (1 << 20)) {
9196 gen_load_exclusive(s
, rd
, 15, addr
, 2);
9198 case 1: /* ldrexd */
9199 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
9201 case 2: /* ldrexb */
9202 gen_load_exclusive(s
, rd
, 15, addr
, 0);
9204 case 3: /* ldrexh */
9205 gen_load_exclusive(s
, rd
, 15, addr
, 1);
9214 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
9216 case 1: /* strexd */
9217 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
9219 case 2: /* strexb */
9220 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
9222 case 3: /* strexh */
9223 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
9229 tcg_temp_free_i32(addr
);
9232 TCGMemOp opc
= s
->be_data
;
9234 /* SWP instruction */
9237 if (insn
& (1 << 22)) {
9240 opc
|= MO_UL
| MO_ALIGN
;
9243 addr
= load_reg(s
, rn
);
9244 taddr
= gen_aa32_addr(s
, addr
, opc
);
9245 tcg_temp_free_i32(addr
);
9247 tmp
= load_reg(s
, rm
);
9248 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
9249 get_mem_index(s
), opc
);
9250 tcg_temp_free(taddr
);
9251 store_reg(s
, rd
, tmp
);
9256 bool load
= insn
& (1 << 20);
9257 bool wbit
= insn
& (1 << 21);
9258 bool pbit
= insn
& (1 << 24);
9259 bool doubleword
= false;
9262 /* Misc load/store */
9263 rn
= (insn
>> 16) & 0xf;
9264 rd
= (insn
>> 12) & 0xf;
9266 /* ISS not valid if writeback */
9267 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
9269 if (!load
&& (sh
& 2)) {
9273 /* UNPREDICTABLE; we choose to UNDEF */
9276 load
= (sh
& 1) == 0;
9280 addr
= load_reg(s
, rn
);
9282 gen_add_datah_offset(s
, insn
, 0, addr
);
9289 tmp
= load_reg(s
, rd
);
9290 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9291 tcg_temp_free_i32(tmp
);
9292 tcg_gen_addi_i32(addr
, addr
, 4);
9293 tmp
= load_reg(s
, rd
+ 1);
9294 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9295 tcg_temp_free_i32(tmp
);
9298 tmp
= tcg_temp_new_i32();
9299 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9300 store_reg(s
, rd
, tmp
);
9301 tcg_gen_addi_i32(addr
, addr
, 4);
9302 tmp
= tcg_temp_new_i32();
9303 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9306 address_offset
= -4;
9309 tmp
= tcg_temp_new_i32();
9312 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9316 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9321 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9327 tmp
= load_reg(s
, rd
);
9328 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9329 tcg_temp_free_i32(tmp
);
9331 /* Perform base writeback before the loaded value to
9332 ensure correct behavior with overlapping index registers.
9333 ldrd with base writeback is undefined if the
9334 destination and index registers overlap. */
9336 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9337 store_reg(s
, rn
, addr
);
9340 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9341 store_reg(s
, rn
, addr
);
9343 tcg_temp_free_i32(addr
);
9346 /* Complete the load. */
9347 store_reg(s
, rd
, tmp
);
9356 if (insn
& (1 << 4)) {
9358 /* Armv6 Media instructions. */
9360 rn
= (insn
>> 16) & 0xf;
9361 rd
= (insn
>> 12) & 0xf;
9362 rs
= (insn
>> 8) & 0xf;
9363 switch ((insn
>> 23) & 3) {
9364 case 0: /* Parallel add/subtract. */
9365 op1
= (insn
>> 20) & 7;
9366 tmp
= load_reg(s
, rn
);
9367 tmp2
= load_reg(s
, rm
);
9368 sh
= (insn
>> 5) & 7;
9369 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9371 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9372 tcg_temp_free_i32(tmp2
);
9373 store_reg(s
, rd
, tmp
);
9376 if ((insn
& 0x00700020) == 0) {
9377 /* Halfword pack. */
9378 tmp
= load_reg(s
, rn
);
9379 tmp2
= load_reg(s
, rm
);
9380 shift
= (insn
>> 7) & 0x1f;
9381 if (insn
& (1 << 6)) {
9385 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9386 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9387 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9391 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9392 tcg_gen_ext16u_i32(tmp
, tmp
);
9393 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9395 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9396 tcg_temp_free_i32(tmp2
);
9397 store_reg(s
, rd
, tmp
);
9398 } else if ((insn
& 0x00200020) == 0x00200000) {
9400 tmp
= load_reg(s
, rm
);
9401 shift
= (insn
>> 7) & 0x1f;
9402 if (insn
& (1 << 6)) {
9405 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9407 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9409 sh
= (insn
>> 16) & 0x1f;
9410 tmp2
= tcg_const_i32(sh
);
9411 if (insn
& (1 << 22))
9412 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9414 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9415 tcg_temp_free_i32(tmp2
);
9416 store_reg(s
, rd
, tmp
);
9417 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9419 tmp
= load_reg(s
, rm
);
9420 sh
= (insn
>> 16) & 0x1f;
9421 tmp2
= tcg_const_i32(sh
);
9422 if (insn
& (1 << 22))
9423 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9425 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9426 tcg_temp_free_i32(tmp2
);
9427 store_reg(s
, rd
, tmp
);
9428 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9430 tmp
= load_reg(s
, rn
);
9431 tmp2
= load_reg(s
, rm
);
9432 tmp3
= tcg_temp_new_i32();
9433 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9434 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9435 tcg_temp_free_i32(tmp3
);
9436 tcg_temp_free_i32(tmp2
);
9437 store_reg(s
, rd
, tmp
);
9438 } else if ((insn
& 0x000003e0) == 0x00000060) {
9439 tmp
= load_reg(s
, rm
);
9440 shift
= (insn
>> 10) & 3;
9441 /* ??? In many cases it's not necessary to do a
9442 rotate, a shift is sufficient. */
9444 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9445 op1
= (insn
>> 20) & 7;
9447 case 0: gen_sxtb16(tmp
); break;
9448 case 2: gen_sxtb(tmp
); break;
9449 case 3: gen_sxth(tmp
); break;
9450 case 4: gen_uxtb16(tmp
); break;
9451 case 6: gen_uxtb(tmp
); break;
9452 case 7: gen_uxth(tmp
); break;
9453 default: goto illegal_op
;
9456 tmp2
= load_reg(s
, rn
);
9457 if ((op1
& 3) == 0) {
9458 gen_add16(tmp
, tmp2
);
9460 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9461 tcg_temp_free_i32(tmp2
);
9464 store_reg(s
, rd
, tmp
);
9465 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9467 tmp
= load_reg(s
, rm
);
9468 if (insn
& (1 << 22)) {
9469 if (insn
& (1 << 7)) {
9473 gen_helper_rbit(tmp
, tmp
);
9476 if (insn
& (1 << 7))
9479 tcg_gen_bswap32_i32(tmp
, tmp
);
9481 store_reg(s
, rd
, tmp
);
9486 case 2: /* Multiplies (Type 3). */
9487 switch ((insn
>> 20) & 0x7) {
9489 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9490 /* op2 not 00x or 11x : UNDEF */
9493 /* Signed multiply most significant [accumulate].
9494 (SMMUL, SMMLA, SMMLS) */
9495 tmp
= load_reg(s
, rm
);
9496 tmp2
= load_reg(s
, rs
);
9497 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9500 tmp
= load_reg(s
, rd
);
9501 if (insn
& (1 << 6)) {
9502 tmp64
= gen_subq_msw(tmp64
, tmp
);
9504 tmp64
= gen_addq_msw(tmp64
, tmp
);
9507 if (insn
& (1 << 5)) {
9508 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9510 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9511 tmp
= tcg_temp_new_i32();
9512 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9513 tcg_temp_free_i64(tmp64
);
9514 store_reg(s
, rn
, tmp
);
9518 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9519 if (insn
& (1 << 7)) {
9522 tmp
= load_reg(s
, rm
);
9523 tmp2
= load_reg(s
, rs
);
9524 if (insn
& (1 << 5))
9525 gen_swap_half(tmp2
);
9526 gen_smul_dual(tmp
, tmp2
);
9527 if (insn
& (1 << 22)) {
9528 /* smlald, smlsld */
9531 tmp64
= tcg_temp_new_i64();
9532 tmp64_2
= tcg_temp_new_i64();
9533 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9534 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9535 tcg_temp_free_i32(tmp
);
9536 tcg_temp_free_i32(tmp2
);
9537 if (insn
& (1 << 6)) {
9538 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9540 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9542 tcg_temp_free_i64(tmp64_2
);
9543 gen_addq(s
, tmp64
, rd
, rn
);
9544 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9545 tcg_temp_free_i64(tmp64
);
9547 /* smuad, smusd, smlad, smlsd */
9548 if (insn
& (1 << 6)) {
9549 /* This subtraction cannot overflow. */
9550 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9552 /* This addition cannot overflow 32 bits;
9553 * however it may overflow considered as a
9554 * signed operation, in which case we must set
9557 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9559 tcg_temp_free_i32(tmp2
);
9562 tmp2
= load_reg(s
, rd
);
9563 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9564 tcg_temp_free_i32(tmp2
);
9566 store_reg(s
, rn
, tmp
);
9572 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9575 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9578 tmp
= load_reg(s
, rm
);
9579 tmp2
= load_reg(s
, rs
);
9580 if (insn
& (1 << 21)) {
9581 gen_helper_udiv(tmp
, tmp
, tmp2
);
9583 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9585 tcg_temp_free_i32(tmp2
);
9586 store_reg(s
, rn
, tmp
);
9593 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9595 case 0: /* Unsigned sum of absolute differences. */
9597 tmp
= load_reg(s
, rm
);
9598 tmp2
= load_reg(s
, rs
);
9599 gen_helper_usad8(tmp
, tmp
, tmp2
);
9600 tcg_temp_free_i32(tmp2
);
9602 tmp2
= load_reg(s
, rd
);
9603 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9604 tcg_temp_free_i32(tmp2
);
9606 store_reg(s
, rn
, tmp
);
9608 case 0x20: case 0x24: case 0x28: case 0x2c:
9609 /* Bitfield insert/clear. */
9611 shift
= (insn
>> 7) & 0x1f;
9612 i
= (insn
>> 16) & 0x1f;
9614 /* UNPREDICTABLE; we choose to UNDEF */
9619 tmp
= tcg_temp_new_i32();
9620 tcg_gen_movi_i32(tmp
, 0);
9622 tmp
= load_reg(s
, rm
);
9625 tmp2
= load_reg(s
, rd
);
9626 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9627 tcg_temp_free_i32(tmp2
);
9629 store_reg(s
, rd
, tmp
);
9631 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9632 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9634 tmp
= load_reg(s
, rm
);
9635 shift
= (insn
>> 7) & 0x1f;
9636 i
= ((insn
>> 16) & 0x1f) + 1;
9641 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9643 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9646 store_reg(s
, rd
, tmp
);
9656 /* Check for undefined extension instructions
9657 * per the ARM Bible IE:
9658 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9660 sh
= (0xf << 20) | (0xf << 4);
9661 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9665 /* load/store byte/word */
9666 rn
= (insn
>> 16) & 0xf;
9667 rd
= (insn
>> 12) & 0xf;
9668 tmp2
= load_reg(s
, rn
);
9669 if ((insn
& 0x01200000) == 0x00200000) {
9671 i
= get_a32_user_mem_index(s
);
9673 i
= get_mem_index(s
);
9675 if (insn
& (1 << 24))
9676 gen_add_data_offset(s
, insn
, tmp2
);
9677 if (insn
& (1 << 20)) {
9679 tmp
= tcg_temp_new_i32();
9680 if (insn
& (1 << 22)) {
9681 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9683 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9687 tmp
= load_reg(s
, rd
);
9688 if (insn
& (1 << 22)) {
9689 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9691 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9693 tcg_temp_free_i32(tmp
);
9695 if (!(insn
& (1 << 24))) {
9696 gen_add_data_offset(s
, insn
, tmp2
);
9697 store_reg(s
, rn
, tmp2
);
9698 } else if (insn
& (1 << 21)) {
9699 store_reg(s
, rn
, tmp2
);
9701 tcg_temp_free_i32(tmp2
);
9703 if (insn
& (1 << 20)) {
9704 /* Complete the load. */
9705 store_reg_from_load(s
, rd
, tmp
);
9711 int j
, n
, loaded_base
;
9712 bool exc_return
= false;
9713 bool is_load
= extract32(insn
, 20, 1);
9715 TCGv_i32 loaded_var
;
9716 /* load/store multiple words */
9717 /* XXX: store correct base if write back */
9718 if (insn
& (1 << 22)) {
9719 /* LDM (user), LDM (exception return) and STM (user) */
9721 goto illegal_op
; /* only usable in supervisor mode */
9723 if (is_load
&& extract32(insn
, 15, 1)) {
9729 rn
= (insn
>> 16) & 0xf;
9730 addr
= load_reg(s
, rn
);
9732 /* compute total size */
9737 if (insn
& (1 << i
))
9740 /* XXX: test invalid n == 0 case ? */
9741 if (insn
& (1 << 23)) {
9742 if (insn
& (1 << 24)) {
9744 tcg_gen_addi_i32(addr
, addr
, 4);
9746 /* post increment */
9749 if (insn
& (1 << 24)) {
9751 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9753 /* post decrement */
9755 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9760 if (insn
& (1 << i
)) {
9763 tmp
= tcg_temp_new_i32();
9764 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9766 tmp2
= tcg_const_i32(i
);
9767 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9768 tcg_temp_free_i32(tmp2
);
9769 tcg_temp_free_i32(tmp
);
9770 } else if (i
== rn
) {
9773 } else if (rn
== 15 && exc_return
) {
9774 store_pc_exc_ret(s
, tmp
);
9776 store_reg_from_load(s
, i
, tmp
);
9781 /* special case: r15 = PC + 8 */
9782 val
= (long)s
->pc
+ 4;
9783 tmp
= tcg_temp_new_i32();
9784 tcg_gen_movi_i32(tmp
, val
);
9786 tmp
= tcg_temp_new_i32();
9787 tmp2
= tcg_const_i32(i
);
9788 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9789 tcg_temp_free_i32(tmp2
);
9791 tmp
= load_reg(s
, i
);
9793 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9794 tcg_temp_free_i32(tmp
);
9797 /* no need to add after the last transfer */
9799 tcg_gen_addi_i32(addr
, addr
, 4);
9802 if (insn
& (1 << 21)) {
9804 if (insn
& (1 << 23)) {
9805 if (insn
& (1 << 24)) {
9808 /* post increment */
9809 tcg_gen_addi_i32(addr
, addr
, 4);
9812 if (insn
& (1 << 24)) {
9815 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9817 /* post decrement */
9818 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9821 store_reg(s
, rn
, addr
);
9823 tcg_temp_free_i32(addr
);
9826 store_reg(s
, rn
, loaded_var
);
9829 /* Restore CPSR from SPSR. */
9830 tmp
= load_cpu_field(spsr
);
9831 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9832 tcg_temp_free_i32(tmp
);
9833 /* Must exit loop to check un-masked IRQs */
9834 s
->base
.is_jmp
= DISAS_EXIT
;
9843 /* branch (and link) */
9844 val
= (int32_t)s
->pc
;
9845 if (insn
& (1 << 24)) {
9846 tmp
= tcg_temp_new_i32();
9847 tcg_gen_movi_i32(tmp
, val
);
9848 store_reg(s
, 14, tmp
);
9850 offset
= sextract32(insn
<< 2, 0, 26);
9858 if (((insn
>> 8) & 0xe) == 10) {
9860 if (disas_vfp_insn(s
, insn
)) {
9863 } else if (disas_coproc_insn(s
, insn
)) {
9870 gen_set_pc_im(s
, s
->pc
);
9871 s
->svc_imm
= extract32(insn
, 0, 24);
9872 s
->base
.is_jmp
= DISAS_SWI
;
9876 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9877 default_exception_el(s
));
9883 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t insn
)
9885 /* Return true if this is a 16 bit instruction. We must be precise
9886 * about this (matching the decode). We assume that s->pc still
9887 * points to the first 16 bits of the insn.
9889 if ((insn
>> 11) < 0x1d) {
9890 /* Definitely a 16-bit instruction */
9894 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9895 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9896 * end up actually treating this as two 16-bit insns, though,
9897 * if it's half of a bl/blx pair that might span a page boundary.
9899 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
9900 /* Thumb2 cores (including all M profile ones) always treat
9901 * 32-bit insns as 32-bit.
9906 if ((insn
>> 11) == 0x1e && (s
->pc
< s
->next_page_start
- 3)) {
9907 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9908 * is not on the next page; we merge this into a 32-bit
9913 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9914 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9915 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9916 * -- handle as single 16 bit insn
9921 /* Return true if this is a Thumb-2 logical op. */
9923 thumb2_logic_op(int op
)
9928 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9929 then set condition code flags based on the result of the operation.
9930 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9931 to the high bit of T1.
9932 Returns zero if the opcode is valid. */
9935 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9936 TCGv_i32 t0
, TCGv_i32 t1
)
9943 tcg_gen_and_i32(t0
, t0
, t1
);
9947 tcg_gen_andc_i32(t0
, t0
, t1
);
9951 tcg_gen_or_i32(t0
, t0
, t1
);
9955 tcg_gen_orc_i32(t0
, t0
, t1
);
9959 tcg_gen_xor_i32(t0
, t0
, t1
);
9964 gen_add_CC(t0
, t0
, t1
);
9966 tcg_gen_add_i32(t0
, t0
, t1
);
9970 gen_adc_CC(t0
, t0
, t1
);
9976 gen_sbc_CC(t0
, t0
, t1
);
9978 gen_sub_carry(t0
, t0
, t1
);
9983 gen_sub_CC(t0
, t0
, t1
);
9985 tcg_gen_sub_i32(t0
, t0
, t1
);
9989 gen_sub_CC(t0
, t1
, t0
);
9991 tcg_gen_sub_i32(t0
, t1
, t0
);
9993 default: /* 5, 6, 7, 9, 12, 15. */
9999 gen_set_CF_bit31(t1
);
10004 /* Translate a 32-bit thumb instruction. */
10005 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
10007 uint32_t imm
, shift
, offset
;
10008 uint32_t rd
, rn
, rm
, rs
;
10019 /* The only 32 bit insn that's allowed for Thumb1 is the combined
10020 * BL/BLX prefix and suffix.
10022 if ((insn
& 0xf800e800) != 0xf000e800) {
10026 rn
= (insn
>> 16) & 0xf;
10027 rs
= (insn
>> 12) & 0xf;
10028 rd
= (insn
>> 8) & 0xf;
10030 switch ((insn
>> 25) & 0xf) {
10031 case 0: case 1: case 2: case 3:
10032 /* 16-bit instructions. Should never happen. */
10035 if (insn
& (1 << 22)) {
10036 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10037 * - load/store doubleword, load/store exclusive, ldacq/strel,
10038 * table branch, TT.
10040 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_M
) &&
10041 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10042 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10044 * The bulk of the behaviour for this instruction is implemented
10045 * in v7m_handle_execute_nsc(), which deals with the insn when
10046 * it is executed by a CPU in non-secure state from memory
10047 * which is Secure & NonSecure-Callable.
10048 * Here we only need to handle the remaining cases:
10049 * * in NS memory (including the "security extension not
10050 * implemented" case) : NOP
10051 * * in S memory but CPU already secure (clear IT bits)
10052 * We know that the attribute for the memory this insn is
10053 * in must match the current CPU state, because otherwise
10054 * get_phys_addr_pmsav8 would have generated an exception.
10056 if (s
->v8m_secure
) {
10057 /* Like the IT insn, we don't need to generate any code */
10058 s
->condexec_cond
= 0;
10059 s
->condexec_mask
= 0;
10061 } else if (insn
& 0x01200000) {
10062 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10063 * - load/store dual (post-indexed)
10064 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10065 * - load/store dual (literal and immediate)
10066 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10067 * - load/store dual (pre-indexed)
10070 if (insn
& (1 << 21)) {
10071 /* UNPREDICTABLE */
10074 addr
= tcg_temp_new_i32();
10075 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
10077 addr
= load_reg(s
, rn
);
10079 offset
= (insn
& 0xff) * 4;
10080 if ((insn
& (1 << 23)) == 0)
10082 if (insn
& (1 << 24)) {
10083 tcg_gen_addi_i32(addr
, addr
, offset
);
10086 if (insn
& (1 << 20)) {
10088 tmp
= tcg_temp_new_i32();
10089 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10090 store_reg(s
, rs
, tmp
);
10091 tcg_gen_addi_i32(addr
, addr
, 4);
10092 tmp
= tcg_temp_new_i32();
10093 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10094 store_reg(s
, rd
, tmp
);
10097 tmp
= load_reg(s
, rs
);
10098 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10099 tcg_temp_free_i32(tmp
);
10100 tcg_gen_addi_i32(addr
, addr
, 4);
10101 tmp
= load_reg(s
, rd
);
10102 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10103 tcg_temp_free_i32(tmp
);
10105 if (insn
& (1 << 21)) {
10106 /* Base writeback. */
10107 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
10108 store_reg(s
, rn
, addr
);
10110 tcg_temp_free_i32(addr
);
10112 } else if ((insn
& (1 << 23)) == 0) {
10113 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10114 * - load/store exclusive word
10118 if (!(insn
& (1 << 20)) &&
10119 arm_dc_feature(s
, ARM_FEATURE_M
) &&
10120 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10121 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10124 bool alt
= insn
& (1 << 7);
10125 TCGv_i32 addr
, op
, ttresp
;
10127 if ((insn
& 0x3f) || rd
== 13 || rd
== 15 || rn
== 15) {
10128 /* we UNDEF for these UNPREDICTABLE cases */
10132 if (alt
&& !s
->v8m_secure
) {
10136 addr
= load_reg(s
, rn
);
10137 op
= tcg_const_i32(extract32(insn
, 6, 2));
10138 ttresp
= tcg_temp_new_i32();
10139 gen_helper_v7m_tt(ttresp
, cpu_env
, addr
, op
);
10140 tcg_temp_free_i32(addr
);
10141 tcg_temp_free_i32(op
);
10142 store_reg(s
, rd
, ttresp
);
10147 addr
= tcg_temp_local_new_i32();
10148 load_reg_var(s
, addr
, rn
);
10149 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
10150 if (insn
& (1 << 20)) {
10151 gen_load_exclusive(s
, rs
, 15, addr
, 2);
10153 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
10155 tcg_temp_free_i32(addr
);
10156 } else if ((insn
& (7 << 5)) == 0) {
10157 /* Table Branch. */
10159 addr
= tcg_temp_new_i32();
10160 tcg_gen_movi_i32(addr
, s
->pc
);
10162 addr
= load_reg(s
, rn
);
10164 tmp
= load_reg(s
, rm
);
10165 tcg_gen_add_i32(addr
, addr
, tmp
);
10166 if (insn
& (1 << 4)) {
10168 tcg_gen_add_i32(addr
, addr
, tmp
);
10169 tcg_temp_free_i32(tmp
);
10170 tmp
= tcg_temp_new_i32();
10171 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
10173 tcg_temp_free_i32(tmp
);
10174 tmp
= tcg_temp_new_i32();
10175 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
10177 tcg_temp_free_i32(addr
);
10178 tcg_gen_shli_i32(tmp
, tmp
, 1);
10179 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
10180 store_reg(s
, 15, tmp
);
10182 int op2
= (insn
>> 6) & 0x3;
10183 op
= (insn
>> 4) & 0x3;
10188 /* Load/store exclusive byte/halfword/doubleword */
10195 /* Load-acquire/store-release */
10201 /* Load-acquire/store-release exclusive */
10205 addr
= tcg_temp_local_new_i32();
10206 load_reg_var(s
, addr
, rn
);
10208 if (insn
& (1 << 20)) {
10209 tmp
= tcg_temp_new_i32();
10212 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
10216 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
10220 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
10226 store_reg(s
, rs
, tmp
);
10228 tmp
= load_reg(s
, rs
);
10231 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
10235 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
10239 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
10245 tcg_temp_free_i32(tmp
);
10247 } else if (insn
& (1 << 20)) {
10248 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
10250 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
10252 tcg_temp_free_i32(addr
);
10255 /* Load/store multiple, RFE, SRS. */
10256 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
10257 /* RFE, SRS: not available in user mode or on M profile */
10258 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10261 if (insn
& (1 << 20)) {
10263 addr
= load_reg(s
, rn
);
10264 if ((insn
& (1 << 24)) == 0)
10265 tcg_gen_addi_i32(addr
, addr
, -8);
10266 /* Load PC into tmp and CPSR into tmp2. */
10267 tmp
= tcg_temp_new_i32();
10268 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10269 tcg_gen_addi_i32(addr
, addr
, 4);
10270 tmp2
= tcg_temp_new_i32();
10271 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
10272 if (insn
& (1 << 21)) {
10273 /* Base writeback. */
10274 if (insn
& (1 << 24)) {
10275 tcg_gen_addi_i32(addr
, addr
, 4);
10277 tcg_gen_addi_i32(addr
, addr
, -4);
10279 store_reg(s
, rn
, addr
);
10281 tcg_temp_free_i32(addr
);
10283 gen_rfe(s
, tmp
, tmp2
);
10286 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
10290 int i
, loaded_base
= 0;
10291 TCGv_i32 loaded_var
;
10292 /* Load/store multiple. */
10293 addr
= load_reg(s
, rn
);
10295 for (i
= 0; i
< 16; i
++) {
10296 if (insn
& (1 << i
))
10299 if (insn
& (1 << 24)) {
10300 tcg_gen_addi_i32(addr
, addr
, -offset
);
10304 for (i
= 0; i
< 16; i
++) {
10305 if ((insn
& (1 << i
)) == 0)
10307 if (insn
& (1 << 20)) {
10309 tmp
= tcg_temp_new_i32();
10310 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10312 gen_bx_excret(s
, tmp
);
10313 } else if (i
== rn
) {
10317 store_reg(s
, i
, tmp
);
10321 tmp
= load_reg(s
, i
);
10322 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10323 tcg_temp_free_i32(tmp
);
10325 tcg_gen_addi_i32(addr
, addr
, 4);
10328 store_reg(s
, rn
, loaded_var
);
10330 if (insn
& (1 << 21)) {
10331 /* Base register writeback. */
10332 if (insn
& (1 << 24)) {
10333 tcg_gen_addi_i32(addr
, addr
, -offset
);
10335 /* Fault if writeback register is in register list. */
10336 if (insn
& (1 << rn
))
10338 store_reg(s
, rn
, addr
);
10340 tcg_temp_free_i32(addr
);
10347 op
= (insn
>> 21) & 0xf;
10349 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10352 /* Halfword pack. */
10353 tmp
= load_reg(s
, rn
);
10354 tmp2
= load_reg(s
, rm
);
10355 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
10356 if (insn
& (1 << 5)) {
10360 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
10361 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
10362 tcg_gen_ext16u_i32(tmp2
, tmp2
);
10366 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10367 tcg_gen_ext16u_i32(tmp
, tmp
);
10368 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10370 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10371 tcg_temp_free_i32(tmp2
);
10372 store_reg(s
, rd
, tmp
);
10374 /* Data processing register constant shift. */
10376 tmp
= tcg_temp_new_i32();
10377 tcg_gen_movi_i32(tmp
, 0);
10379 tmp
= load_reg(s
, rn
);
10381 tmp2
= load_reg(s
, rm
);
10383 shiftop
= (insn
>> 4) & 3;
10384 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10385 conds
= (insn
& (1 << 20)) != 0;
10386 logic_cc
= (conds
&& thumb2_logic_op(op
));
10387 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10388 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10390 tcg_temp_free_i32(tmp2
);
10392 store_reg(s
, rd
, tmp
);
10394 tcg_temp_free_i32(tmp
);
10398 case 13: /* Misc data processing. */
10399 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10400 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10403 case 0: /* Register controlled shift. */
10404 tmp
= load_reg(s
, rn
);
10405 tmp2
= load_reg(s
, rm
);
10406 if ((insn
& 0x70) != 0)
10408 op
= (insn
>> 21) & 3;
10409 logic_cc
= (insn
& (1 << 20)) != 0;
10410 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10413 store_reg(s
, rd
, tmp
);
10415 case 1: /* Sign/zero extend. */
10416 op
= (insn
>> 20) & 7;
10418 case 0: /* SXTAH, SXTH */
10419 case 1: /* UXTAH, UXTH */
10420 case 4: /* SXTAB, SXTB */
10421 case 5: /* UXTAB, UXTB */
10423 case 2: /* SXTAB16, SXTB16 */
10424 case 3: /* UXTAB16, UXTB16 */
10425 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10433 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10437 tmp
= load_reg(s
, rm
);
10438 shift
= (insn
>> 4) & 3;
10439 /* ??? In many cases it's not necessary to do a
10440 rotate, a shift is sufficient. */
10442 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10443 op
= (insn
>> 20) & 7;
10445 case 0: gen_sxth(tmp
); break;
10446 case 1: gen_uxth(tmp
); break;
10447 case 2: gen_sxtb16(tmp
); break;
10448 case 3: gen_uxtb16(tmp
); break;
10449 case 4: gen_sxtb(tmp
); break;
10450 case 5: gen_uxtb(tmp
); break;
10452 g_assert_not_reached();
10455 tmp2
= load_reg(s
, rn
);
10456 if ((op
>> 1) == 1) {
10457 gen_add16(tmp
, tmp2
);
10459 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10460 tcg_temp_free_i32(tmp2
);
10463 store_reg(s
, rd
, tmp
);
10465 case 2: /* SIMD add/subtract. */
10466 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10469 op
= (insn
>> 20) & 7;
10470 shift
= (insn
>> 4) & 7;
10471 if ((op
& 3) == 3 || (shift
& 3) == 3)
10473 tmp
= load_reg(s
, rn
);
10474 tmp2
= load_reg(s
, rm
);
10475 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10476 tcg_temp_free_i32(tmp2
);
10477 store_reg(s
, rd
, tmp
);
10479 case 3: /* Other data processing. */
10480 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10482 /* Saturating add/subtract. */
10483 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10486 tmp
= load_reg(s
, rn
);
10487 tmp2
= load_reg(s
, rm
);
10489 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10491 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10493 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10494 tcg_temp_free_i32(tmp2
);
10497 case 0x0a: /* rbit */
10498 case 0x08: /* rev */
10499 case 0x09: /* rev16 */
10500 case 0x0b: /* revsh */
10501 case 0x18: /* clz */
10503 case 0x10: /* sel */
10504 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10508 case 0x20: /* crc32/crc32c */
10514 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10521 tmp
= load_reg(s
, rn
);
10523 case 0x0a: /* rbit */
10524 gen_helper_rbit(tmp
, tmp
);
10526 case 0x08: /* rev */
10527 tcg_gen_bswap32_i32(tmp
, tmp
);
10529 case 0x09: /* rev16 */
10532 case 0x0b: /* revsh */
10535 case 0x10: /* sel */
10536 tmp2
= load_reg(s
, rm
);
10537 tmp3
= tcg_temp_new_i32();
10538 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10539 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10540 tcg_temp_free_i32(tmp3
);
10541 tcg_temp_free_i32(tmp2
);
10543 case 0x18: /* clz */
10544 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10554 uint32_t sz
= op
& 0x3;
10555 uint32_t c
= op
& 0x8;
10557 tmp2
= load_reg(s
, rm
);
10559 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10560 } else if (sz
== 1) {
10561 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10563 tmp3
= tcg_const_i32(1 << sz
);
10565 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10567 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10569 tcg_temp_free_i32(tmp2
);
10570 tcg_temp_free_i32(tmp3
);
10574 g_assert_not_reached();
10577 store_reg(s
, rd
, tmp
);
10579 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10580 switch ((insn
>> 20) & 7) {
10581 case 0: /* 32 x 32 -> 32 */
10582 case 7: /* Unsigned sum of absolute differences. */
10584 case 1: /* 16 x 16 -> 32 */
10585 case 2: /* Dual multiply add. */
10586 case 3: /* 32 * 16 -> 32msb */
10587 case 4: /* Dual multiply subtract. */
10588 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10589 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10594 op
= (insn
>> 4) & 0xf;
10595 tmp
= load_reg(s
, rn
);
10596 tmp2
= load_reg(s
, rm
);
10597 switch ((insn
>> 20) & 7) {
10598 case 0: /* 32 x 32 -> 32 */
10599 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10600 tcg_temp_free_i32(tmp2
);
10602 tmp2
= load_reg(s
, rs
);
10604 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10606 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10607 tcg_temp_free_i32(tmp2
);
10610 case 1: /* 16 x 16 -> 32 */
10611 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10612 tcg_temp_free_i32(tmp2
);
10614 tmp2
= load_reg(s
, rs
);
10615 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10616 tcg_temp_free_i32(tmp2
);
10619 case 2: /* Dual multiply add. */
10620 case 4: /* Dual multiply subtract. */
10622 gen_swap_half(tmp2
);
10623 gen_smul_dual(tmp
, tmp2
);
10624 if (insn
& (1 << 22)) {
10625 /* This subtraction cannot overflow. */
10626 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10628 /* This addition cannot overflow 32 bits;
10629 * however it may overflow considered as a signed
10630 * operation, in which case we must set the Q flag.
10632 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10634 tcg_temp_free_i32(tmp2
);
10637 tmp2
= load_reg(s
, rs
);
10638 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10639 tcg_temp_free_i32(tmp2
);
10642 case 3: /* 32 * 16 -> 32msb */
10644 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10647 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10648 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10649 tmp
= tcg_temp_new_i32();
10650 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10651 tcg_temp_free_i64(tmp64
);
10654 tmp2
= load_reg(s
, rs
);
10655 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10656 tcg_temp_free_i32(tmp2
);
10659 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10660 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10662 tmp
= load_reg(s
, rs
);
10663 if (insn
& (1 << 20)) {
10664 tmp64
= gen_addq_msw(tmp64
, tmp
);
10666 tmp64
= gen_subq_msw(tmp64
, tmp
);
10669 if (insn
& (1 << 4)) {
10670 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10672 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10673 tmp
= tcg_temp_new_i32();
10674 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10675 tcg_temp_free_i64(tmp64
);
10677 case 7: /* Unsigned sum of absolute differences. */
10678 gen_helper_usad8(tmp
, tmp
, tmp2
);
10679 tcg_temp_free_i32(tmp2
);
10681 tmp2
= load_reg(s
, rs
);
10682 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10683 tcg_temp_free_i32(tmp2
);
10687 store_reg(s
, rd
, tmp
);
10689 case 6: case 7: /* 64-bit multiply, Divide. */
10690 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10691 tmp
= load_reg(s
, rn
);
10692 tmp2
= load_reg(s
, rm
);
10693 if ((op
& 0x50) == 0x10) {
10695 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10699 gen_helper_udiv(tmp
, tmp
, tmp2
);
10701 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10702 tcg_temp_free_i32(tmp2
);
10703 store_reg(s
, rd
, tmp
);
10704 } else if ((op
& 0xe) == 0xc) {
10705 /* Dual multiply accumulate long. */
10706 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10707 tcg_temp_free_i32(tmp
);
10708 tcg_temp_free_i32(tmp2
);
10712 gen_swap_half(tmp2
);
10713 gen_smul_dual(tmp
, tmp2
);
10715 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10717 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10719 tcg_temp_free_i32(tmp2
);
10721 tmp64
= tcg_temp_new_i64();
10722 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10723 tcg_temp_free_i32(tmp
);
10724 gen_addq(s
, tmp64
, rs
, rd
);
10725 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10726 tcg_temp_free_i64(tmp64
);
10729 /* Unsigned 64-bit multiply */
10730 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10734 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10735 tcg_temp_free_i32(tmp2
);
10736 tcg_temp_free_i32(tmp
);
10739 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10740 tcg_temp_free_i32(tmp2
);
10741 tmp64
= tcg_temp_new_i64();
10742 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10743 tcg_temp_free_i32(tmp
);
10745 /* Signed 64-bit multiply */
10746 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10751 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10752 tcg_temp_free_i64(tmp64
);
10755 gen_addq_lo(s
, tmp64
, rs
);
10756 gen_addq_lo(s
, tmp64
, rd
);
10757 } else if (op
& 0x40) {
10758 /* 64-bit accumulate. */
10759 gen_addq(s
, tmp64
, rs
, rd
);
10761 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10762 tcg_temp_free_i64(tmp64
);
10767 case 6: case 7: case 14: case 15:
10769 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10770 /* We don't currently implement M profile FP support,
10771 * so this entire space should give a NOCP fault.
10773 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10774 default_exception_el(s
));
10777 if ((insn
& 0xfe000a00) == 0xfc000800
10778 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10779 /* The Thumb2 and ARM encodings are identical. */
10780 if (disas_neon_insn_3same_ext(s
, insn
)) {
10783 } else if ((insn
& 0xff000a00) == 0xfe000800
10784 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10785 /* The Thumb2 and ARM encodings are identical. */
10786 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
10789 } else if (((insn
>> 24) & 3) == 3) {
10790 /* Translate into the equivalent ARM encoding. */
10791 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10792 if (disas_neon_data_insn(s
, insn
)) {
10795 } else if (((insn
>> 8) & 0xe) == 10) {
10796 if (disas_vfp_insn(s
, insn
)) {
10800 if (insn
& (1 << 28))
10802 if (disas_coproc_insn(s
, insn
)) {
10807 case 8: case 9: case 10: case 11:
10808 if (insn
& (1 << 15)) {
10809 /* Branches, misc control. */
10810 if (insn
& 0x5000) {
10811 /* Unconditional branch. */
10812 /* signextend(hw1[10:0]) -> offset[:12]. */
10813 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10814 /* hw1[10:0] -> offset[11:1]. */
10815 offset
|= (insn
& 0x7ff) << 1;
10816 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10817 offset[24:22] already have the same value because of the
10818 sign extension above. */
10819 offset
^= ((~insn
) & (1 << 13)) << 10;
10820 offset
^= ((~insn
) & (1 << 11)) << 11;
10822 if (insn
& (1 << 14)) {
10823 /* Branch and link. */
10824 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10828 if (insn
& (1 << 12)) {
10830 gen_jmp(s
, offset
);
10833 offset
&= ~(uint32_t)2;
10834 /* thumb2 bx, no need to check */
10835 gen_bx_im(s
, offset
);
10837 } else if (((insn
>> 23) & 7) == 7) {
10839 if (insn
& (1 << 13))
10842 if (insn
& (1 << 26)) {
10843 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10846 if (!(insn
& (1 << 20))) {
10847 /* Hypervisor call (v7) */
10848 int imm16
= extract32(insn
, 16, 4) << 12
10849 | extract32(insn
, 0, 12);
10856 /* Secure monitor call (v6+) */
10864 op
= (insn
>> 20) & 7;
10866 case 0: /* msr cpsr. */
10867 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10868 tmp
= load_reg(s
, rn
);
10869 /* the constant is the mask and SYSm fields */
10870 addr
= tcg_const_i32(insn
& 0xfff);
10871 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10872 tcg_temp_free_i32(addr
);
10873 tcg_temp_free_i32(tmp
);
10878 case 1: /* msr spsr. */
10879 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10883 if (extract32(insn
, 5, 1)) {
10885 int sysm
= extract32(insn
, 8, 4) |
10886 (extract32(insn
, 4, 1) << 4);
10889 gen_msr_banked(s
, r
, sysm
, rm
);
10893 /* MSR (for PSRs) */
10894 tmp
= load_reg(s
, rn
);
10896 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10900 case 2: /* cps, nop-hint. */
10901 if (((insn
>> 8) & 7) == 0) {
10902 gen_nop_hint(s
, insn
& 0xff);
10904 /* Implemented as NOP in user mode. */
10909 if (insn
& (1 << 10)) {
10910 if (insn
& (1 << 7))
10912 if (insn
& (1 << 6))
10914 if (insn
& (1 << 5))
10916 if (insn
& (1 << 9))
10917 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10919 if (insn
& (1 << 8)) {
10921 imm
|= (insn
& 0x1f);
10924 gen_set_psr_im(s
, offset
, 0, imm
);
10927 case 3: /* Special control operations. */
10929 op
= (insn
>> 4) & 0xf;
10931 case 2: /* clrex */
10936 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10939 /* We need to break the TB after this insn
10940 * to execute self-modifying code correctly
10941 * and also to take any pending interrupts
10944 gen_goto_tb(s
, 0, s
->pc
& ~1);
10951 /* Trivial implementation equivalent to bx.
10952 * This instruction doesn't exist at all for M-profile.
10954 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10957 tmp
= load_reg(s
, rn
);
10960 case 5: /* Exception return. */
10964 if (rn
!= 14 || rd
!= 15) {
10967 tmp
= load_reg(s
, rn
);
10968 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10969 gen_exception_return(s
, tmp
);
10972 if (extract32(insn
, 5, 1) &&
10973 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10975 int sysm
= extract32(insn
, 16, 4) |
10976 (extract32(insn
, 4, 1) << 4);
10978 gen_mrs_banked(s
, 0, sysm
, rd
);
10982 if (extract32(insn
, 16, 4) != 0xf) {
10985 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10986 extract32(insn
, 0, 8) != 0) {
10991 tmp
= tcg_temp_new_i32();
10992 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10993 addr
= tcg_const_i32(insn
& 0xff);
10994 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10995 tcg_temp_free_i32(addr
);
10997 gen_helper_cpsr_read(tmp
, cpu_env
);
10999 store_reg(s
, rd
, tmp
);
11002 if (extract32(insn
, 5, 1) &&
11003 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11005 int sysm
= extract32(insn
, 16, 4) |
11006 (extract32(insn
, 4, 1) << 4);
11008 gen_mrs_banked(s
, 1, sysm
, rd
);
11013 /* Not accessible in user mode. */
11014 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
11018 if (extract32(insn
, 16, 4) != 0xf ||
11019 extract32(insn
, 0, 8) != 0) {
11023 tmp
= load_cpu_field(spsr
);
11024 store_reg(s
, rd
, tmp
);
11029 /* Conditional branch. */
11030 op
= (insn
>> 22) & 0xf;
11031 /* Generate a conditional jump to next instruction. */
11032 s
->condlabel
= gen_new_label();
11033 arm_gen_test_cc(op
^ 1, s
->condlabel
);
11036 /* offset[11:1] = insn[10:0] */
11037 offset
= (insn
& 0x7ff) << 1;
11038 /* offset[17:12] = insn[21:16]. */
11039 offset
|= (insn
& 0x003f0000) >> 4;
11040 /* offset[31:20] = insn[26]. */
11041 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
11042 /* offset[18] = insn[13]. */
11043 offset
|= (insn
& (1 << 13)) << 5;
11044 /* offset[19] = insn[11]. */
11045 offset
|= (insn
& (1 << 11)) << 8;
11047 /* jump to the offset */
11048 gen_jmp(s
, s
->pc
+ offset
);
11051 /* Data processing immediate. */
11052 if (insn
& (1 << 25)) {
11053 if (insn
& (1 << 24)) {
11054 if (insn
& (1 << 20))
11056 /* Bitfield/Saturate. */
11057 op
= (insn
>> 21) & 7;
11059 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
11061 tmp
= tcg_temp_new_i32();
11062 tcg_gen_movi_i32(tmp
, 0);
11064 tmp
= load_reg(s
, rn
);
11067 case 2: /* Signed bitfield extract. */
11069 if (shift
+ imm
> 32)
11072 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
11075 case 6: /* Unsigned bitfield extract. */
11077 if (shift
+ imm
> 32)
11080 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
11083 case 3: /* Bitfield insert/clear. */
11086 imm
= imm
+ 1 - shift
;
11088 tmp2
= load_reg(s
, rd
);
11089 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
11090 tcg_temp_free_i32(tmp2
);
11095 default: /* Saturate. */
11098 tcg_gen_sari_i32(tmp
, tmp
, shift
);
11100 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11102 tmp2
= tcg_const_i32(imm
);
11105 if ((op
& 1) && shift
== 0) {
11106 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11107 tcg_temp_free_i32(tmp
);
11108 tcg_temp_free_i32(tmp2
);
11111 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
11113 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
11117 if ((op
& 1) && shift
== 0) {
11118 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11119 tcg_temp_free_i32(tmp
);
11120 tcg_temp_free_i32(tmp2
);
11123 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
11125 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
11128 tcg_temp_free_i32(tmp2
);
11131 store_reg(s
, rd
, tmp
);
11133 imm
= ((insn
& 0x04000000) >> 15)
11134 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
11135 if (insn
& (1 << 22)) {
11136 /* 16-bit immediate. */
11137 imm
|= (insn
>> 4) & 0xf000;
11138 if (insn
& (1 << 23)) {
11140 tmp
= load_reg(s
, rd
);
11141 tcg_gen_ext16u_i32(tmp
, tmp
);
11142 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
11145 tmp
= tcg_temp_new_i32();
11146 tcg_gen_movi_i32(tmp
, imm
);
11149 /* Add/sub 12-bit immediate. */
11151 offset
= s
->pc
& ~(uint32_t)3;
11152 if (insn
& (1 << 23))
11156 tmp
= tcg_temp_new_i32();
11157 tcg_gen_movi_i32(tmp
, offset
);
11159 tmp
= load_reg(s
, rn
);
11160 if (insn
& (1 << 23))
11161 tcg_gen_subi_i32(tmp
, tmp
, imm
);
11163 tcg_gen_addi_i32(tmp
, tmp
, imm
);
11166 store_reg(s
, rd
, tmp
);
11169 int shifter_out
= 0;
11170 /* modified 12-bit immediate. */
11171 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
11172 imm
= (insn
& 0xff);
11175 /* Nothing to do. */
11177 case 1: /* 00XY00XY */
11180 case 2: /* XY00XY00 */
11184 case 3: /* XYXYXYXY */
11188 default: /* Rotated constant. */
11189 shift
= (shift
<< 1) | (imm
>> 7);
11191 imm
= imm
<< (32 - shift
);
11195 tmp2
= tcg_temp_new_i32();
11196 tcg_gen_movi_i32(tmp2
, imm
);
11197 rn
= (insn
>> 16) & 0xf;
11199 tmp
= tcg_temp_new_i32();
11200 tcg_gen_movi_i32(tmp
, 0);
11202 tmp
= load_reg(s
, rn
);
11204 op
= (insn
>> 21) & 0xf;
11205 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
11206 shifter_out
, tmp
, tmp2
))
11208 tcg_temp_free_i32(tmp2
);
11209 rd
= (insn
>> 8) & 0xf;
11211 store_reg(s
, rd
, tmp
);
11213 tcg_temp_free_i32(tmp
);
11218 case 12: /* Load/store single data item. */
11225 if ((insn
& 0x01100000) == 0x01000000) {
11226 if (disas_neon_ls_insn(s
, insn
)) {
11231 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
11233 if (!(insn
& (1 << 20))) {
11237 /* Byte or halfword load space with dest == r15 : memory hints.
11238 * Catch them early so we don't emit pointless addressing code.
11239 * This space is a mix of:
11240 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11241 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11243 * unallocated hints, which must be treated as NOPs
11244 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11245 * which is easiest for the decoding logic
11246 * Some space which must UNDEF
11248 int op1
= (insn
>> 23) & 3;
11249 int op2
= (insn
>> 6) & 0x3f;
11254 /* UNPREDICTABLE, unallocated hint or
11255 * PLD/PLDW/PLI (literal)
11260 return; /* PLD/PLDW/PLI or unallocated hint */
11262 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
11263 return; /* PLD/PLDW/PLI or unallocated hint */
11265 /* UNDEF space, or an UNPREDICTABLE */
11269 memidx
= get_mem_index(s
);
11271 addr
= tcg_temp_new_i32();
11273 /* s->pc has already been incremented by 4. */
11274 imm
= s
->pc
& 0xfffffffc;
11275 if (insn
& (1 << 23))
11276 imm
+= insn
& 0xfff;
11278 imm
-= insn
& 0xfff;
11279 tcg_gen_movi_i32(addr
, imm
);
11281 addr
= load_reg(s
, rn
);
11282 if (insn
& (1 << 23)) {
11283 /* Positive offset. */
11284 imm
= insn
& 0xfff;
11285 tcg_gen_addi_i32(addr
, addr
, imm
);
11288 switch ((insn
>> 8) & 0xf) {
11289 case 0x0: /* Shifted Register. */
11290 shift
= (insn
>> 4) & 0xf;
11292 tcg_temp_free_i32(addr
);
11295 tmp
= load_reg(s
, rm
);
11297 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11298 tcg_gen_add_i32(addr
, addr
, tmp
);
11299 tcg_temp_free_i32(tmp
);
11301 case 0xc: /* Negative offset. */
11302 tcg_gen_addi_i32(addr
, addr
, -imm
);
11304 case 0xe: /* User privilege. */
11305 tcg_gen_addi_i32(addr
, addr
, imm
);
11306 memidx
= get_a32_user_mem_index(s
);
11308 case 0x9: /* Post-decrement. */
11310 /* Fall through. */
11311 case 0xb: /* Post-increment. */
11315 case 0xd: /* Pre-decrement. */
11317 /* Fall through. */
11318 case 0xf: /* Pre-increment. */
11319 tcg_gen_addi_i32(addr
, addr
, imm
);
11323 tcg_temp_free_i32(addr
);
11329 issinfo
= writeback
? ISSInvalid
: rs
;
11331 if (insn
& (1 << 20)) {
11333 tmp
= tcg_temp_new_i32();
11336 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11339 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11342 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11345 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11348 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11351 tcg_temp_free_i32(tmp
);
11352 tcg_temp_free_i32(addr
);
11356 gen_bx_excret(s
, tmp
);
11358 store_reg(s
, rs
, tmp
);
11362 tmp
= load_reg(s
, rs
);
11365 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
11368 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
11371 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
11374 tcg_temp_free_i32(tmp
);
11375 tcg_temp_free_i32(addr
);
11378 tcg_temp_free_i32(tmp
);
11381 tcg_gen_addi_i32(addr
, addr
, imm
);
11383 store_reg(s
, rn
, addr
);
11385 tcg_temp_free_i32(addr
);
11394 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11395 default_exception_el(s
));
11398 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
11400 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
11407 switch (insn
>> 12) {
11411 op
= (insn
>> 11) & 3;
11414 rn
= (insn
>> 3) & 7;
11415 tmp
= load_reg(s
, rn
);
11416 if (insn
& (1 << 10)) {
11418 tmp2
= tcg_temp_new_i32();
11419 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11422 rm
= (insn
>> 6) & 7;
11423 tmp2
= load_reg(s
, rm
);
11425 if (insn
& (1 << 9)) {
11426 if (s
->condexec_mask
)
11427 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11429 gen_sub_CC(tmp
, tmp
, tmp2
);
11431 if (s
->condexec_mask
)
11432 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11434 gen_add_CC(tmp
, tmp
, tmp2
);
11436 tcg_temp_free_i32(tmp2
);
11437 store_reg(s
, rd
, tmp
);
11439 /* shift immediate */
11440 rm
= (insn
>> 3) & 7;
11441 shift
= (insn
>> 6) & 0x1f;
11442 tmp
= load_reg(s
, rm
);
11443 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11444 if (!s
->condexec_mask
)
11446 store_reg(s
, rd
, tmp
);
11450 /* arithmetic large immediate */
11451 op
= (insn
>> 11) & 3;
11452 rd
= (insn
>> 8) & 0x7;
11453 if (op
== 0) { /* mov */
11454 tmp
= tcg_temp_new_i32();
11455 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11456 if (!s
->condexec_mask
)
11458 store_reg(s
, rd
, tmp
);
11460 tmp
= load_reg(s
, rd
);
11461 tmp2
= tcg_temp_new_i32();
11462 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11465 gen_sub_CC(tmp
, tmp
, tmp2
);
11466 tcg_temp_free_i32(tmp
);
11467 tcg_temp_free_i32(tmp2
);
11470 if (s
->condexec_mask
)
11471 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11473 gen_add_CC(tmp
, tmp
, tmp2
);
11474 tcg_temp_free_i32(tmp2
);
11475 store_reg(s
, rd
, tmp
);
11478 if (s
->condexec_mask
)
11479 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11481 gen_sub_CC(tmp
, tmp
, tmp2
);
11482 tcg_temp_free_i32(tmp2
);
11483 store_reg(s
, rd
, tmp
);
11489 if (insn
& (1 << 11)) {
11490 rd
= (insn
>> 8) & 7;
11491 /* load pc-relative. Bit 1 of PC is ignored. */
11492 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11493 val
&= ~(uint32_t)2;
11494 addr
= tcg_temp_new_i32();
11495 tcg_gen_movi_i32(addr
, val
);
11496 tmp
= tcg_temp_new_i32();
11497 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11499 tcg_temp_free_i32(addr
);
11500 store_reg(s
, rd
, tmp
);
11503 if (insn
& (1 << 10)) {
11504 /* 0b0100_01xx_xxxx_xxxx
11505 * - data processing extended, branch and exchange
11507 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11508 rm
= (insn
>> 3) & 0xf;
11509 op
= (insn
>> 8) & 3;
11512 tmp
= load_reg(s
, rd
);
11513 tmp2
= load_reg(s
, rm
);
11514 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11515 tcg_temp_free_i32(tmp2
);
11516 store_reg(s
, rd
, tmp
);
11519 tmp
= load_reg(s
, rd
);
11520 tmp2
= load_reg(s
, rm
);
11521 gen_sub_CC(tmp
, tmp
, tmp2
);
11522 tcg_temp_free_i32(tmp2
);
11523 tcg_temp_free_i32(tmp
);
11525 case 2: /* mov/cpy */
11526 tmp
= load_reg(s
, rm
);
11527 store_reg(s
, rd
, tmp
);
11531 /* 0b0100_0111_xxxx_xxxx
11532 * - branch [and link] exchange thumb register
11534 bool link
= insn
& (1 << 7);
11543 /* BXNS/BLXNS: only exists for v8M with the
11544 * security extensions, and always UNDEF if NonSecure.
11545 * We don't implement these in the user-only mode
11546 * either (in theory you can use them from Secure User
11547 * mode but they are too tied in to system emulation.)
11549 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
11560 tmp
= load_reg(s
, rm
);
11562 val
= (uint32_t)s
->pc
| 1;
11563 tmp2
= tcg_temp_new_i32();
11564 tcg_gen_movi_i32(tmp2
, val
);
11565 store_reg(s
, 14, tmp2
);
11568 /* Only BX works as exception-return, not BLX */
11569 gen_bx_excret(s
, tmp
);
11577 /* data processing register */
11579 rm
= (insn
>> 3) & 7;
11580 op
= (insn
>> 6) & 0xf;
11581 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11582 /* the shift/rotate ops want the operands backwards */
11591 if (op
== 9) { /* neg */
11592 tmp
= tcg_temp_new_i32();
11593 tcg_gen_movi_i32(tmp
, 0);
11594 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11595 tmp
= load_reg(s
, rd
);
11600 tmp2
= load_reg(s
, rm
);
11602 case 0x0: /* and */
11603 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11604 if (!s
->condexec_mask
)
11607 case 0x1: /* eor */
11608 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11609 if (!s
->condexec_mask
)
11612 case 0x2: /* lsl */
11613 if (s
->condexec_mask
) {
11614 gen_shl(tmp2
, tmp2
, tmp
);
11616 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11617 gen_logic_CC(tmp2
);
11620 case 0x3: /* lsr */
11621 if (s
->condexec_mask
) {
11622 gen_shr(tmp2
, tmp2
, tmp
);
11624 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11625 gen_logic_CC(tmp2
);
11628 case 0x4: /* asr */
11629 if (s
->condexec_mask
) {
11630 gen_sar(tmp2
, tmp2
, tmp
);
11632 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11633 gen_logic_CC(tmp2
);
11636 case 0x5: /* adc */
11637 if (s
->condexec_mask
) {
11638 gen_adc(tmp
, tmp2
);
11640 gen_adc_CC(tmp
, tmp
, tmp2
);
11643 case 0x6: /* sbc */
11644 if (s
->condexec_mask
) {
11645 gen_sub_carry(tmp
, tmp
, tmp2
);
11647 gen_sbc_CC(tmp
, tmp
, tmp2
);
11650 case 0x7: /* ror */
11651 if (s
->condexec_mask
) {
11652 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11653 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11655 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11656 gen_logic_CC(tmp2
);
11659 case 0x8: /* tst */
11660 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11664 case 0x9: /* neg */
11665 if (s
->condexec_mask
)
11666 tcg_gen_neg_i32(tmp
, tmp2
);
11668 gen_sub_CC(tmp
, tmp
, tmp2
);
11670 case 0xa: /* cmp */
11671 gen_sub_CC(tmp
, tmp
, tmp2
);
11674 case 0xb: /* cmn */
11675 gen_add_CC(tmp
, tmp
, tmp2
);
11678 case 0xc: /* orr */
11679 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11680 if (!s
->condexec_mask
)
11683 case 0xd: /* mul */
11684 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11685 if (!s
->condexec_mask
)
11688 case 0xe: /* bic */
11689 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11690 if (!s
->condexec_mask
)
11693 case 0xf: /* mvn */
11694 tcg_gen_not_i32(tmp2
, tmp2
);
11695 if (!s
->condexec_mask
)
11696 gen_logic_CC(tmp2
);
11703 store_reg(s
, rm
, tmp2
);
11705 tcg_temp_free_i32(tmp
);
11707 store_reg(s
, rd
, tmp
);
11708 tcg_temp_free_i32(tmp2
);
11711 tcg_temp_free_i32(tmp
);
11712 tcg_temp_free_i32(tmp2
);
11717 /* load/store register offset. */
11719 rn
= (insn
>> 3) & 7;
11720 rm
= (insn
>> 6) & 7;
11721 op
= (insn
>> 9) & 7;
11722 addr
= load_reg(s
, rn
);
11723 tmp
= load_reg(s
, rm
);
11724 tcg_gen_add_i32(addr
, addr
, tmp
);
11725 tcg_temp_free_i32(tmp
);
11727 if (op
< 3) { /* store */
11728 tmp
= load_reg(s
, rd
);
11730 tmp
= tcg_temp_new_i32();
11735 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11738 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11741 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11743 case 3: /* ldrsb */
11744 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11747 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11750 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11753 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11755 case 7: /* ldrsh */
11756 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11759 if (op
>= 3) { /* load */
11760 store_reg(s
, rd
, tmp
);
11762 tcg_temp_free_i32(tmp
);
11764 tcg_temp_free_i32(addr
);
11768 /* load/store word immediate offset */
11770 rn
= (insn
>> 3) & 7;
11771 addr
= load_reg(s
, rn
);
11772 val
= (insn
>> 4) & 0x7c;
11773 tcg_gen_addi_i32(addr
, addr
, val
);
11775 if (insn
& (1 << 11)) {
11777 tmp
= tcg_temp_new_i32();
11778 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11779 store_reg(s
, rd
, tmp
);
11782 tmp
= load_reg(s
, rd
);
11783 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11784 tcg_temp_free_i32(tmp
);
11786 tcg_temp_free_i32(addr
);
11790 /* load/store byte immediate offset */
11792 rn
= (insn
>> 3) & 7;
11793 addr
= load_reg(s
, rn
);
11794 val
= (insn
>> 6) & 0x1f;
11795 tcg_gen_addi_i32(addr
, addr
, val
);
11797 if (insn
& (1 << 11)) {
11799 tmp
= tcg_temp_new_i32();
11800 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11801 store_reg(s
, rd
, tmp
);
11804 tmp
= load_reg(s
, rd
);
11805 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11806 tcg_temp_free_i32(tmp
);
11808 tcg_temp_free_i32(addr
);
11812 /* load/store halfword immediate offset */
11814 rn
= (insn
>> 3) & 7;
11815 addr
= load_reg(s
, rn
);
11816 val
= (insn
>> 5) & 0x3e;
11817 tcg_gen_addi_i32(addr
, addr
, val
);
11819 if (insn
& (1 << 11)) {
11821 tmp
= tcg_temp_new_i32();
11822 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11823 store_reg(s
, rd
, tmp
);
11826 tmp
= load_reg(s
, rd
);
11827 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11828 tcg_temp_free_i32(tmp
);
11830 tcg_temp_free_i32(addr
);
11834 /* load/store from stack */
11835 rd
= (insn
>> 8) & 7;
11836 addr
= load_reg(s
, 13);
11837 val
= (insn
& 0xff) * 4;
11838 tcg_gen_addi_i32(addr
, addr
, val
);
11840 if (insn
& (1 << 11)) {
11842 tmp
= tcg_temp_new_i32();
11843 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11844 store_reg(s
, rd
, tmp
);
11847 tmp
= load_reg(s
, rd
);
11848 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11849 tcg_temp_free_i32(tmp
);
11851 tcg_temp_free_i32(addr
);
11855 /* add to high reg */
11856 rd
= (insn
>> 8) & 7;
11857 if (insn
& (1 << 11)) {
11859 tmp
= load_reg(s
, 13);
11861 /* PC. bit 1 is ignored. */
11862 tmp
= tcg_temp_new_i32();
11863 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11865 val
= (insn
& 0xff) * 4;
11866 tcg_gen_addi_i32(tmp
, tmp
, val
);
11867 store_reg(s
, rd
, tmp
);
11872 op
= (insn
>> 8) & 0xf;
11875 /* adjust stack pointer */
11876 tmp
= load_reg(s
, 13);
11877 val
= (insn
& 0x7f) * 4;
11878 if (insn
& (1 << 7))
11879 val
= -(int32_t)val
;
11880 tcg_gen_addi_i32(tmp
, tmp
, val
);
11881 store_reg(s
, 13, tmp
);
11884 case 2: /* sign/zero extend. */
11887 rm
= (insn
>> 3) & 7;
11888 tmp
= load_reg(s
, rm
);
11889 switch ((insn
>> 6) & 3) {
11890 case 0: gen_sxth(tmp
); break;
11891 case 1: gen_sxtb(tmp
); break;
11892 case 2: gen_uxth(tmp
); break;
11893 case 3: gen_uxtb(tmp
); break;
11895 store_reg(s
, rd
, tmp
);
11897 case 4: case 5: case 0xc: case 0xd:
11899 addr
= load_reg(s
, 13);
11900 if (insn
& (1 << 8))
11904 for (i
= 0; i
< 8; i
++) {
11905 if (insn
& (1 << i
))
11908 if ((insn
& (1 << 11)) == 0) {
11909 tcg_gen_addi_i32(addr
, addr
, -offset
);
11911 for (i
= 0; i
< 8; i
++) {
11912 if (insn
& (1 << i
)) {
11913 if (insn
& (1 << 11)) {
11915 tmp
= tcg_temp_new_i32();
11916 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11917 store_reg(s
, i
, tmp
);
11920 tmp
= load_reg(s
, i
);
11921 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11922 tcg_temp_free_i32(tmp
);
11924 /* advance to the next address. */
11925 tcg_gen_addi_i32(addr
, addr
, 4);
11929 if (insn
& (1 << 8)) {
11930 if (insn
& (1 << 11)) {
11932 tmp
= tcg_temp_new_i32();
11933 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11934 /* don't set the pc until the rest of the instruction
11938 tmp
= load_reg(s
, 14);
11939 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11940 tcg_temp_free_i32(tmp
);
11942 tcg_gen_addi_i32(addr
, addr
, 4);
11944 if ((insn
& (1 << 11)) == 0) {
11945 tcg_gen_addi_i32(addr
, addr
, -offset
);
11947 /* write back the new stack pointer */
11948 store_reg(s
, 13, addr
);
11949 /* set the new PC value */
11950 if ((insn
& 0x0900) == 0x0900) {
11951 store_reg_from_load(s
, 15, tmp
);
11955 case 1: case 3: case 9: case 11: /* czb */
11957 tmp
= load_reg(s
, rm
);
11958 s
->condlabel
= gen_new_label();
11960 if (insn
& (1 << 11))
11961 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11963 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11964 tcg_temp_free_i32(tmp
);
11965 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11966 val
= (uint32_t)s
->pc
+ 2;
11971 case 15: /* IT, nop-hint. */
11972 if ((insn
& 0xf) == 0) {
11973 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11977 s
->condexec_cond
= (insn
>> 4) & 0xe;
11978 s
->condexec_mask
= insn
& 0x1f;
11979 /* No actual code generated for this insn, just setup state. */
11982 case 0xe: /* bkpt */
11984 int imm8
= extract32(insn
, 0, 8);
11986 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11987 default_exception_el(s
));
11991 case 0xa: /* rev, and hlt */
11993 int op1
= extract32(insn
, 6, 2);
11997 int imm6
= extract32(insn
, 0, 6);
12003 /* Otherwise this is rev */
12005 rn
= (insn
>> 3) & 0x7;
12007 tmp
= load_reg(s
, rn
);
12009 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
12010 case 1: gen_rev16(tmp
); break;
12011 case 3: gen_revsh(tmp
); break;
12013 g_assert_not_reached();
12015 store_reg(s
, rd
, tmp
);
12020 switch ((insn
>> 5) & 7) {
12024 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
12025 gen_helper_setend(cpu_env
);
12026 s
->base
.is_jmp
= DISAS_UPDATE
;
12035 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
12036 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
12039 addr
= tcg_const_i32(19);
12040 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12041 tcg_temp_free_i32(addr
);
12045 addr
= tcg_const_i32(16);
12046 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
12047 tcg_temp_free_i32(addr
);
12049 tcg_temp_free_i32(tmp
);
12052 if (insn
& (1 << 4)) {
12053 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
12057 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
12072 /* load/store multiple */
12073 TCGv_i32 loaded_var
= NULL
;
12074 rn
= (insn
>> 8) & 0x7;
12075 addr
= load_reg(s
, rn
);
12076 for (i
= 0; i
< 8; i
++) {
12077 if (insn
& (1 << i
)) {
12078 if (insn
& (1 << 11)) {
12080 tmp
= tcg_temp_new_i32();
12081 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12085 store_reg(s
, i
, tmp
);
12089 tmp
= load_reg(s
, i
);
12090 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12091 tcg_temp_free_i32(tmp
);
12093 /* advance to the next address */
12094 tcg_gen_addi_i32(addr
, addr
, 4);
12097 if ((insn
& (1 << rn
)) == 0) {
12098 /* base reg not in list: base register writeback */
12099 store_reg(s
, rn
, addr
);
12101 /* base reg in list: if load, complete it now */
12102 if (insn
& (1 << 11)) {
12103 store_reg(s
, rn
, loaded_var
);
12105 tcg_temp_free_i32(addr
);
12110 /* conditional branch or swi */
12111 cond
= (insn
>> 8) & 0xf;
12117 gen_set_pc_im(s
, s
->pc
);
12118 s
->svc_imm
= extract32(insn
, 0, 8);
12119 s
->base
.is_jmp
= DISAS_SWI
;
12122 /* generate a conditional jump to next instruction */
12123 s
->condlabel
= gen_new_label();
12124 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
12127 /* jump to the offset */
12128 val
= (uint32_t)s
->pc
+ 2;
12129 offset
= ((int32_t)insn
<< 24) >> 24;
12130 val
+= offset
<< 1;
12135 if (insn
& (1 << 11)) {
12136 /* thumb_insn_is_16bit() ensures we can't get here for
12137 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12138 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12140 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12142 offset
= ((insn
& 0x7ff) << 1);
12143 tmp
= load_reg(s
, 14);
12144 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12145 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
12147 tmp2
= tcg_temp_new_i32();
12148 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12149 store_reg(s
, 14, tmp2
);
12153 /* unconditional branch */
12154 val
= (uint32_t)s
->pc
;
12155 offset
= ((int32_t)insn
<< 21) >> 21;
12156 val
+= (offset
<< 1) + 2;
12161 /* thumb_insn_is_16bit() ensures we can't get here for
12162 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12164 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12166 if (insn
& (1 << 11)) {
12167 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12168 offset
= ((insn
& 0x7ff) << 1) | 1;
12169 tmp
= load_reg(s
, 14);
12170 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12172 tmp2
= tcg_temp_new_i32();
12173 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12174 store_reg(s
, 14, tmp2
);
12177 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12178 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
12180 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
12187 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
12188 default_exception_el(s
));
12191 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
12193 /* Return true if the insn at dc->pc might cross a page boundary.
12194 * (False positives are OK, false negatives are not.)
12195 * We know this is a Thumb insn, and our caller ensures we are
12196 * only called if dc->pc is less than 4 bytes from the page
12197 * boundary, so we cross the page if the first 16 bits indicate
12198 * that this is a 32 bit insn.
12200 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
12202 return !thumb_insn_is_16bit(s
, insn
);
12205 static int arm_tr_init_disas_context(DisasContextBase
*dcbase
,
12206 CPUState
*cs
, int max_insns
)
12208 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12209 CPUARMState
*env
= cs
->env_ptr
;
12210 ARMCPU
*cpu
= arm_env_get_cpu(env
);
12212 dc
->pc
= dc
->base
.pc_first
;
12216 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12217 * there is no secure EL1, so we route exceptions to EL3.
12219 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
12220 !arm_el_is_aa64(env
, 3);
12221 dc
->thumb
= ARM_TBFLAG_THUMB(dc
->base
.tb
->flags
);
12222 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(dc
->base
.tb
->flags
);
12223 dc
->be_data
= ARM_TBFLAG_BE_DATA(dc
->base
.tb
->flags
) ? MO_BE
: MO_LE
;
12224 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) & 0xf) << 1;
12225 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) >> 4;
12226 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, ARM_TBFLAG_MMUIDX(dc
->base
.tb
->flags
));
12227 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
12228 #if !defined(CONFIG_USER_ONLY)
12229 dc
->user
= (dc
->current_el
== 0);
12231 dc
->ns
= ARM_TBFLAG_NS(dc
->base
.tb
->flags
);
12232 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(dc
->base
.tb
->flags
);
12233 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(dc
->base
.tb
->flags
);
12234 dc
->vec_len
= ARM_TBFLAG_VECLEN(dc
->base
.tb
->flags
);
12235 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(dc
->base
.tb
->flags
);
12236 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(dc
->base
.tb
->flags
);
12237 dc
->v7m_handler_mode
= ARM_TBFLAG_HANDLER(dc
->base
.tb
->flags
);
12238 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
12239 regime_is_secure(env
, dc
->mmu_idx
);
12240 dc
->cp_regs
= cpu
->cp_regs
;
12241 dc
->features
= env
->features
;
12243 /* Single step state. The code-generation logic here is:
12245 * generate code with no special handling for single-stepping (except
12246 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12247 * this happens anyway because those changes are all system register or
12249 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12250 * emit code for one insn
12251 * emit code to clear PSTATE.SS
12252 * emit code to generate software step exception for completed step
12253 * end TB (as usual for having generated an exception)
12254 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12255 * emit code to generate a software step exception
12258 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(dc
->base
.tb
->flags
);
12259 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(dc
->base
.tb
->flags
);
12260 dc
->is_ldex
= false;
12261 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
12263 dc
->next_page_start
=
12264 (dc
->base
.pc_first
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
12266 /* If architectural single step active, limit to 1. */
12267 if (is_singlestepping(dc
)) {
12271 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12272 to those left on the page. */
12274 int bound
= (dc
->next_page_start
- dc
->base
.pc_first
) / 4;
12275 max_insns
= MIN(max_insns
, bound
);
12278 cpu_F0s
= tcg_temp_new_i32();
12279 cpu_F1s
= tcg_temp_new_i32();
12280 cpu_F0d
= tcg_temp_new_i64();
12281 cpu_F1d
= tcg_temp_new_i64();
12284 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12285 cpu_M0
= tcg_temp_new_i64();
12290 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12292 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12294 /* A note on handling of the condexec (IT) bits:
12296 * We want to avoid the overhead of having to write the updated condexec
12297 * bits back to the CPUARMState for every instruction in an IT block. So:
12298 * (1) if the condexec bits are not already zero then we write
12299 * zero back into the CPUARMState now. This avoids complications trying
12300 * to do it at the end of the block. (For example if we don't do this
12301 * it's hard to identify whether we can safely skip writing condexec
12302 * at the end of the TB, which we definitely want to do for the case
12303 * where a TB doesn't do anything with the IT state at all.)
12304 * (2) if we are going to leave the TB then we call gen_set_condexec()
12305 * which will write the correct value into CPUARMState if zero is wrong.
12306 * This is done both for leaving the TB at the end, and for leaving
12307 * it because of an exception we know will happen, which is done in
12308 * gen_exception_insn(). The latter is necessary because we need to
12309 * leave the TB with the PC/IT state just prior to execution of the
12310 * instruction which caused the exception.
12311 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12312 * then the CPUARMState will be wrong and we need to reset it.
12313 * This is handled in the same way as restoration of the
12314 * PC in these situations; we save the value of the condexec bits
12315 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12316 * then uses this to restore them after an exception.
12318 * Note that there are no instructions which can read the condexec
12319 * bits, and none which can write non-static values to them, so
12320 * we don't need to care about whether CPUARMState is correct in the
12324 /* Reset the conditional execution bits immediately. This avoids
12325 complications trying to do it at the end of the block. */
12326 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
12327 TCGv_i32 tmp
= tcg_temp_new_i32();
12328 tcg_gen_movi_i32(tmp
, 0);
12329 store_cpu_field(tmp
, condexec_bits
);
12331 tcg_clear_temp_count();
12334 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12336 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12338 tcg_gen_insn_start(dc
->pc
,
12339 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
12341 dc
->insn_start
= tcg_last_op();
12344 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
12345 const CPUBreakpoint
*bp
)
12347 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12349 if (bp
->flags
& BP_CPU
) {
12350 gen_set_condexec(dc
);
12351 gen_set_pc_im(dc
, dc
->pc
);
12352 gen_helper_check_breakpoints(cpu_env
);
12353 /* End the TB early; it's likely not going to be executed */
12354 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12356 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
12357 /* The address covered by the breakpoint must be
12358 included in [tb->pc, tb->pc + tb->size) in order
12359 to for it to be properly cleared -- thus we
12360 increment the PC here so that the logic setting
12361 tb->size below does the right thing. */
12362 /* TODO: Advance PC by correct instruction length to
12363 * avoid disassembler error messages */
12365 dc
->base
.is_jmp
= DISAS_NORETURN
;
12371 static bool arm_pre_translate_insn(DisasContext
*dc
)
12373 #ifdef CONFIG_USER_ONLY
12374 /* Intercept jump to the magic kernel page. */
12375 if (dc
->pc
>= 0xffff0000) {
12376 /* We always get here via a jump, so know we are not in a
12377 conditional execution block. */
12378 gen_exception_internal(EXCP_KERNEL_TRAP
);
12379 dc
->base
.is_jmp
= DISAS_NORETURN
;
12384 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12385 /* Singlestep state is Active-pending.
12386 * If we're in this state at the start of a TB then either
12387 * a) we just took an exception to an EL which is being debugged
12388 * and this is the first insn in the exception handler
12389 * b) debug exceptions were masked and we just unmasked them
12390 * without changing EL (eg by clearing PSTATE.D)
12391 * In either case we're going to take a swstep exception in the
12392 * "did not step an insn" case, and so the syndrome ISV and EX
12393 * bits should be zero.
12395 assert(dc
->base
.num_insns
== 1);
12396 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
12397 default_exception_el(dc
));
12398 dc
->base
.is_jmp
= DISAS_NORETURN
;
12405 static void arm_post_translate_insn(DisasContext
*dc
)
12407 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12408 gen_set_label(dc
->condlabel
);
12411 dc
->base
.pc_next
= dc
->pc
;
12412 translator_loop_temp_check(&dc
->base
);
12415 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12417 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12418 CPUARMState
*env
= cpu
->env_ptr
;
12421 if (arm_pre_translate_insn(dc
)) {
12425 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12428 disas_arm_insn(dc
, insn
);
12430 arm_post_translate_insn(dc
);
12432 /* ARM is a fixed-length ISA. We performed the cross-page check
12433 in init_disas_context by adjusting max_insns. */
12436 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
12438 /* Return true if this Thumb insn is always unconditional,
12439 * even inside an IT block. This is true of only a very few
12440 * instructions: BKPT, HLT, and SG.
12442 * A larger class of instructions are UNPREDICTABLE if used
12443 * inside an IT block; we do not need to detect those here, because
12444 * what we do by default (perform the cc check and update the IT
12445 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12446 * choice for those situations.
12448 * insn is either a 16-bit or a 32-bit instruction; the two are
12449 * distinguishable because for the 16-bit case the top 16 bits
12450 * are zeroes, and that isn't a valid 32-bit encoding.
12452 if ((insn
& 0xffffff00) == 0xbe00) {
12457 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12458 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
12459 /* HLT: v8A only. This is unconditional even when it is going to
12460 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12461 * For v7 cores this was a plain old undefined encoding and so
12462 * honours its cc check. (We might be using the encoding as
12463 * a semihosting trap, but we don't change the cc check behaviour
12464 * on that account, because a debugger connected to a real v7A
12465 * core and emulating semihosting traps by catching the UNDEF
12466 * exception would also only see cases where the cc check passed.
12467 * No guest code should be trying to do a HLT semihosting trap
12468 * in an IT block anyway.
12473 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12474 arm_dc_feature(s
, ARM_FEATURE_M
)) {
12482 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12484 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12485 CPUARMState
*env
= cpu
->env_ptr
;
12489 if (arm_pre_translate_insn(dc
)) {
12493 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12494 is_16bit
= thumb_insn_is_16bit(dc
, insn
);
12497 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12499 insn
= insn
<< 16 | insn2
;
12504 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
12505 uint32_t cond
= dc
->condexec_cond
;
12507 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
12508 dc
->condlabel
= gen_new_label();
12509 arm_gen_test_cc(cond
^ 1, dc
->condlabel
);
12515 disas_thumb_insn(dc
, insn
);
12517 disas_thumb2_insn(dc
, insn
);
12520 /* Advance the Thumb condexec condition. */
12521 if (dc
->condexec_mask
) {
12522 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
12523 ((dc
->condexec_mask
>> 4) & 1));
12524 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12525 if (dc
->condexec_mask
== 0) {
12526 dc
->condexec_cond
= 0;
12530 arm_post_translate_insn(dc
);
12532 /* Thumb is a variable-length ISA. Stop translation when the next insn
12533 * will touch a new page. This ensures that prefetch aborts occur at
12536 * We want to stop the TB if the next insn starts in a new page,
12537 * or if it spans between this page and the next. This means that
12538 * if we're looking at the last halfword in the page we need to
12539 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12540 * or a 32-bit Thumb insn (which won't).
12541 * This is to avoid generating a silly TB with a single 16-bit insn
12542 * in it at the end of this page (which would execute correctly
12543 * but isn't very efficient).
12545 if (dc
->base
.is_jmp
== DISAS_NEXT
12546 && (dc
->pc
>= dc
->next_page_start
12547 || (dc
->pc
>= dc
->next_page_start
- 3
12548 && insn_crosses_page(env
, dc
)))) {
12549 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12553 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
12555 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12557 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
12558 /* FIXME: This can theoretically happen with self-modifying code. */
12559 cpu_abort(cpu
, "IO on conditional branch instruction");
12562 /* At this stage dc->condjmp will only be set when the skipped
12563 instruction was a conditional branch or trap, and the PC has
12564 already been written. */
12565 gen_set_condexec(dc
);
12566 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12567 /* Exception return branches need some special case code at the
12568 * end of the TB, which is complex enough that it has to
12569 * handle the single-step vs not and the condition-failed
12570 * insn codepath itself.
12572 gen_bx_excret_final_code(dc
);
12573 } else if (unlikely(is_singlestepping(dc
))) {
12574 /* Unconditional and "condition passed" instruction codepath. */
12575 switch (dc
->base
.is_jmp
) {
12577 gen_ss_advance(dc
);
12578 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12579 default_exception_el(dc
));
12582 gen_ss_advance(dc
);
12583 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12586 gen_ss_advance(dc
);
12587 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12590 case DISAS_TOO_MANY
:
12592 gen_set_pc_im(dc
, dc
->pc
);
12595 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12596 gen_singlestep_exception(dc
);
12598 case DISAS_NORETURN
:
12602 /* While branches must always occur at the end of an IT block,
12603 there are a few other things that can cause us to terminate
12604 the TB in the middle of an IT block:
12605 - Exception generating instructions (bkpt, swi, undefined).
12607 - Hardware watchpoints.
12608 Hardware breakpoints have already been handled and skip this code.
12610 switch(dc
->base
.is_jmp
) {
12612 case DISAS_TOO_MANY
:
12613 gen_goto_tb(dc
, 1, dc
->pc
);
12619 gen_set_pc_im(dc
, dc
->pc
);
12622 /* indicate that the hash table must be used to find the next TB */
12623 tcg_gen_exit_tb(0);
12625 case DISAS_NORETURN
:
12626 /* nothing more to generate */
12630 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
12631 !(dc
->insn
& (1U << 31))) ? 2 : 4);
12633 gen_helper_wfi(cpu_env
, tmp
);
12634 tcg_temp_free_i32(tmp
);
12635 /* The helper doesn't necessarily throw an exception, but we
12636 * must go back to the main loop to check for interrupts anyway.
12638 tcg_gen_exit_tb(0);
12642 gen_helper_wfe(cpu_env
);
12645 gen_helper_yield(cpu_env
);
12648 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12649 default_exception_el(dc
));
12652 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12655 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12661 /* "Condition failed" instruction codepath for the branch/trap insn */
12662 gen_set_label(dc
->condlabel
);
12663 gen_set_condexec(dc
);
12664 if (unlikely(is_singlestepping(dc
))) {
12665 gen_set_pc_im(dc
, dc
->pc
);
12666 gen_singlestep_exception(dc
);
12668 gen_goto_tb(dc
, 1, dc
->pc
);
12672 /* Functions above can change dc->pc, so re-align db->pc_next */
12673 dc
->base
.pc_next
= dc
->pc
;
12676 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
12678 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12680 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
12681 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
12684 static const TranslatorOps arm_translator_ops
= {
12685 .init_disas_context
= arm_tr_init_disas_context
,
12686 .tb_start
= arm_tr_tb_start
,
12687 .insn_start
= arm_tr_insn_start
,
12688 .breakpoint_check
= arm_tr_breakpoint_check
,
12689 .translate_insn
= arm_tr_translate_insn
,
12690 .tb_stop
= arm_tr_tb_stop
,
12691 .disas_log
= arm_tr_disas_log
,
12694 static const TranslatorOps thumb_translator_ops
= {
12695 .init_disas_context
= arm_tr_init_disas_context
,
12696 .tb_start
= arm_tr_tb_start
,
12697 .insn_start
= arm_tr_insn_start
,
12698 .breakpoint_check
= arm_tr_breakpoint_check
,
12699 .translate_insn
= thumb_tr_translate_insn
,
12700 .tb_stop
= arm_tr_tb_stop
,
12701 .disas_log
= arm_tr_disas_log
,
12704 /* generate intermediate code for basic block 'tb'. */
12705 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
)
12708 const TranslatorOps
*ops
= &arm_translator_ops
;
12710 if (ARM_TBFLAG_THUMB(tb
->flags
)) {
12711 ops
= &thumb_translator_ops
;
12713 #ifdef TARGET_AARCH64
12714 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
12715 ops
= &aarch64_translator_ops
;
12719 translator_loop(ops
, &dc
.base
, cpu
, tb
);
12722 static const char *cpu_mode_names
[16] = {
12723 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12724 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12727 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12730 ARMCPU
*cpu
= ARM_CPU(cs
);
12731 CPUARMState
*env
= &cpu
->env
;
12735 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12739 for(i
=0;i
<16;i
++) {
12740 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12742 cpu_fprintf(f
, "\n");
12744 cpu_fprintf(f
, " ");
12747 if (arm_feature(env
, ARM_FEATURE_M
)) {
12748 uint32_t xpsr
= xpsr_read(env
);
12750 const char *ns_status
= "";
12752 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
12753 ns_status
= env
->v7m
.secure
? "S " : "NS ";
12756 if (xpsr
& XPSR_EXCP
) {
12759 if (env
->v7m
.control
[env
->v7m
.secure
] & R_V7M_CONTROL_NPRIV_MASK
) {
12760 mode
= "unpriv-thread";
12762 mode
= "priv-thread";
12766 cpu_fprintf(f
, "XPSR=%08x %c%c%c%c %c %s%s\n",
12768 xpsr
& XPSR_N
? 'N' : '-',
12769 xpsr
& XPSR_Z
? 'Z' : '-',
12770 xpsr
& XPSR_C
? 'C' : '-',
12771 xpsr
& XPSR_V
? 'V' : '-',
12772 xpsr
& XPSR_T
? 'T' : 'A',
12776 uint32_t psr
= cpsr_read(env
);
12777 const char *ns_status
= "";
12779 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12780 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12781 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12784 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12786 psr
& CPSR_N
? 'N' : '-',
12787 psr
& CPSR_Z
? 'Z' : '-',
12788 psr
& CPSR_C
? 'C' : '-',
12789 psr
& CPSR_V
? 'V' : '-',
12790 psr
& CPSR_T
? 'T' : 'A',
12792 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12795 if (flags
& CPU_DUMP_FPU
) {
12796 int numvfpregs
= 0;
12797 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12800 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12803 for (i
= 0; i
< numvfpregs
; i
++) {
12804 uint64_t v
= *aa32_vfp_dreg(env
, i
);
12805 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12806 i
* 2, (uint32_t)v
,
12807 i
* 2 + 1, (uint32_t)(v
>> 32),
12810 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12814 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12815 target_ulong
*data
)
12819 env
->condexec_bits
= 0;
12820 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12822 env
->regs
[15] = data
[0];
12823 env
->condexec_bits
= data
[1];
12824 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;