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 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7747 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7748 const ARMCPRegInfo
*ri
;
7750 cpnum
= (insn
>> 8) & 0xf;
7752 /* First check for coprocessor space used for XScale/iwMMXt insns */
7753 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7754 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7757 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7758 return disas_iwmmxt_insn(s
, insn
);
7759 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7760 return disas_dsp_insn(s
, insn
);
7765 /* Otherwise treat as a generic register access */
7766 is64
= (insn
& (1 << 25)) == 0;
7767 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7775 opc1
= (insn
>> 4) & 0xf;
7777 rt2
= (insn
>> 16) & 0xf;
7779 crn
= (insn
>> 16) & 0xf;
7780 opc1
= (insn
>> 21) & 7;
7781 opc2
= (insn
>> 5) & 7;
7784 isread
= (insn
>> 20) & 1;
7785 rt
= (insn
>> 12) & 0xf;
7787 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7788 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7790 /* Check access permissions */
7791 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7796 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7797 /* Emit code to perform further access permissions checks at
7798 * runtime; this may result in an exception.
7799 * Note that on XScale all cp0..c13 registers do an access check
7800 * call in order to handle c15_cpar.
7803 TCGv_i32 tcg_syn
, tcg_isread
;
7806 /* Note that since we are an implementation which takes an
7807 * exception on a trapped conditional instruction only if the
7808 * instruction passes its condition code check, we can take
7809 * advantage of the clause in the ARM ARM that allows us to set
7810 * the COND field in the instruction to 0xE in all cases.
7811 * We could fish the actual condition out of the insn (ARM)
7812 * or the condexec bits (Thumb) but it isn't necessary.
7817 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7820 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7826 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7829 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7834 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7835 * so this can only happen if this is an ARMv7 or earlier CPU,
7836 * in which case the syndrome information won't actually be
7839 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7840 syndrome
= syn_uncategorized();
7844 gen_set_condexec(s
);
7845 gen_set_pc_im(s
, s
->pc
- 4);
7846 tmpptr
= tcg_const_ptr(ri
);
7847 tcg_syn
= tcg_const_i32(syndrome
);
7848 tcg_isread
= tcg_const_i32(isread
);
7849 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7851 tcg_temp_free_ptr(tmpptr
);
7852 tcg_temp_free_i32(tcg_syn
);
7853 tcg_temp_free_i32(tcg_isread
);
7856 /* Handle special cases first */
7857 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7864 gen_set_pc_im(s
, s
->pc
);
7865 s
->base
.is_jmp
= DISAS_WFI
;
7871 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7880 if (ri
->type
& ARM_CP_CONST
) {
7881 tmp64
= tcg_const_i64(ri
->resetvalue
);
7882 } else if (ri
->readfn
) {
7884 tmp64
= tcg_temp_new_i64();
7885 tmpptr
= tcg_const_ptr(ri
);
7886 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7887 tcg_temp_free_ptr(tmpptr
);
7889 tmp64
= tcg_temp_new_i64();
7890 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7892 tmp
= tcg_temp_new_i32();
7893 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7894 store_reg(s
, rt
, tmp
);
7895 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7896 tmp
= tcg_temp_new_i32();
7897 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7898 tcg_temp_free_i64(tmp64
);
7899 store_reg(s
, rt2
, tmp
);
7902 if (ri
->type
& ARM_CP_CONST
) {
7903 tmp
= tcg_const_i32(ri
->resetvalue
);
7904 } else if (ri
->readfn
) {
7906 tmp
= tcg_temp_new_i32();
7907 tmpptr
= tcg_const_ptr(ri
);
7908 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7909 tcg_temp_free_ptr(tmpptr
);
7911 tmp
= load_cpu_offset(ri
->fieldoffset
);
7914 /* Destination register of r15 for 32 bit loads sets
7915 * the condition codes from the high 4 bits of the value
7918 tcg_temp_free_i32(tmp
);
7920 store_reg(s
, rt
, tmp
);
7925 if (ri
->type
& ARM_CP_CONST
) {
7926 /* If not forbidden by access permissions, treat as WI */
7931 TCGv_i32 tmplo
, tmphi
;
7932 TCGv_i64 tmp64
= tcg_temp_new_i64();
7933 tmplo
= load_reg(s
, rt
);
7934 tmphi
= load_reg(s
, rt2
);
7935 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7936 tcg_temp_free_i32(tmplo
);
7937 tcg_temp_free_i32(tmphi
);
7939 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7940 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7941 tcg_temp_free_ptr(tmpptr
);
7943 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7945 tcg_temp_free_i64(tmp64
);
7950 tmp
= load_reg(s
, rt
);
7951 tmpptr
= tcg_const_ptr(ri
);
7952 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7953 tcg_temp_free_ptr(tmpptr
);
7954 tcg_temp_free_i32(tmp
);
7956 TCGv_i32 tmp
= load_reg(s
, rt
);
7957 store_cpu_offset(tmp
, ri
->fieldoffset
);
7962 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7963 /* I/O operations must end the TB here (whether read or write) */
7966 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7967 /* We default to ending the TB on a coprocessor register write,
7968 * but allow this to be suppressed by the register definition
7969 * (usually only necessary to work around guest bugs).
7977 /* Unknown register; this might be a guest error or a QEMU
7978 * unimplemented feature.
7981 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7982 "64 bit system register cp:%d opc1: %d crm:%d "
7984 isread
? "read" : "write", cpnum
, opc1
, crm
,
7985 s
->ns
? "non-secure" : "secure");
7987 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7988 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7990 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7991 s
->ns
? "non-secure" : "secure");
7998 /* Store a 64-bit value to a register pair. Clobbers val. */
7999 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
8002 tmp
= tcg_temp_new_i32();
8003 tcg_gen_extrl_i64_i32(tmp
, val
);
8004 store_reg(s
, rlow
, tmp
);
8005 tmp
= tcg_temp_new_i32();
8006 tcg_gen_shri_i64(val
, val
, 32);
8007 tcg_gen_extrl_i64_i32(tmp
, val
);
8008 store_reg(s
, rhigh
, tmp
);
8011 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8012 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
8017 /* Load value and extend to 64 bits. */
8018 tmp
= tcg_temp_new_i64();
8019 tmp2
= load_reg(s
, rlow
);
8020 tcg_gen_extu_i32_i64(tmp
, tmp2
);
8021 tcg_temp_free_i32(tmp2
);
8022 tcg_gen_add_i64(val
, val
, tmp
);
8023 tcg_temp_free_i64(tmp
);
8026 /* load and add a 64-bit value from a register pair. */
8027 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
8033 /* Load 64-bit value rd:rn. */
8034 tmpl
= load_reg(s
, rlow
);
8035 tmph
= load_reg(s
, rhigh
);
8036 tmp
= tcg_temp_new_i64();
8037 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
8038 tcg_temp_free_i32(tmpl
);
8039 tcg_temp_free_i32(tmph
);
8040 tcg_gen_add_i64(val
, val
, tmp
);
8041 tcg_temp_free_i64(tmp
);
8044 /* Set N and Z flags from hi|lo. */
8045 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
8047 tcg_gen_mov_i32(cpu_NF
, hi
);
8048 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
8051 /* Load/Store exclusive instructions are implemented by remembering
8052 the value/address loaded, and seeing if these are the same
8053 when the store is performed. This should be sufficient to implement
8054 the architecturally mandated semantics, and avoids having to monitor
8055 regular stores. The compare vs the remembered value is done during
8056 the cmpxchg operation, but we must compare the addresses manually. */
8057 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
8058 TCGv_i32 addr
, int size
)
8060 TCGv_i32 tmp
= tcg_temp_new_i32();
8061 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8066 TCGv_i32 tmp2
= tcg_temp_new_i32();
8067 TCGv_i64 t64
= tcg_temp_new_i64();
8069 /* For AArch32, architecturally the 32-bit word at the lowest
8070 * address is always Rt and the one at addr+4 is Rt2, even if
8071 * the CPU is big-endian. That means we don't want to do a
8072 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8073 * for an architecturally 64-bit access, but instead do a
8074 * 64-bit access using MO_BE if appropriate and then split
8076 * This only makes a difference for BE32 user-mode, where
8077 * frob64() must not flip the two halves of the 64-bit data
8078 * but this code must treat BE32 user-mode like BE32 system.
8080 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
8082 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
8083 tcg_temp_free(taddr
);
8084 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
8085 if (s
->be_data
== MO_BE
) {
8086 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
8088 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
8090 tcg_temp_free_i64(t64
);
8092 store_reg(s
, rt2
, tmp2
);
8094 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
8095 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
8098 store_reg(s
, rt
, tmp
);
8099 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
8102 static void gen_clrex(DisasContext
*s
)
8104 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8107 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
8108 TCGv_i32 addr
, int size
)
8110 TCGv_i32 t0
, t1
, t2
;
8113 TCGLabel
*done_label
;
8114 TCGLabel
*fail_label
;
8115 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
8117 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8123 fail_label
= gen_new_label();
8124 done_label
= gen_new_label();
8125 extaddr
= tcg_temp_new_i64();
8126 tcg_gen_extu_i32_i64(extaddr
, addr
);
8127 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
8128 tcg_temp_free_i64(extaddr
);
8130 taddr
= gen_aa32_addr(s
, addr
, opc
);
8131 t0
= tcg_temp_new_i32();
8132 t1
= load_reg(s
, rt
);
8134 TCGv_i64 o64
= tcg_temp_new_i64();
8135 TCGv_i64 n64
= tcg_temp_new_i64();
8137 t2
= load_reg(s
, rt2
);
8138 /* For AArch32, architecturally the 32-bit word at the lowest
8139 * address is always Rt and the one at addr+4 is Rt2, even if
8140 * the CPU is big-endian. Since we're going to treat this as a
8141 * single 64-bit BE store, we need to put the two halves in the
8142 * opposite order for BE to LE, so that they end up in the right
8144 * We don't want gen_aa32_frob64() because that does the wrong
8145 * thing for BE32 usermode.
8147 if (s
->be_data
== MO_BE
) {
8148 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
8150 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
8152 tcg_temp_free_i32(t2
);
8154 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
8155 get_mem_index(s
), opc
);
8156 tcg_temp_free_i64(n64
);
8158 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
8159 tcg_gen_extrl_i64_i32(t0
, o64
);
8161 tcg_temp_free_i64(o64
);
8163 t2
= tcg_temp_new_i32();
8164 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
8165 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
8166 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
8167 tcg_temp_free_i32(t2
);
8169 tcg_temp_free_i32(t1
);
8170 tcg_temp_free(taddr
);
8171 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
8172 tcg_temp_free_i32(t0
);
8173 tcg_gen_br(done_label
);
8175 gen_set_label(fail_label
);
8176 tcg_gen_movi_i32(cpu_R
[rd
], 1);
8177 gen_set_label(done_label
);
8178 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8184 * @mode: mode field from insn (which stack to store to)
8185 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8186 * @writeback: true if writeback bit set
8188 * Generate code for the SRS (Store Return State) insn.
8190 static void gen_srs(DisasContext
*s
,
8191 uint32_t mode
, uint32_t amode
, bool writeback
)
8198 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8199 * and specified mode is monitor mode
8200 * - UNDEFINED in Hyp mode
8201 * - UNPREDICTABLE in User or System mode
8202 * - UNPREDICTABLE if the specified mode is:
8203 * -- not implemented
8204 * -- not a valid mode number
8205 * -- a mode that's at a higher exception level
8206 * -- Monitor, if we are Non-secure
8207 * For the UNPREDICTABLE cases we choose to UNDEF.
8209 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
8210 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
8214 if (s
->current_el
== 0 || s
->current_el
== 2) {
8219 case ARM_CPU_MODE_USR
:
8220 case ARM_CPU_MODE_FIQ
:
8221 case ARM_CPU_MODE_IRQ
:
8222 case ARM_CPU_MODE_SVC
:
8223 case ARM_CPU_MODE_ABT
:
8224 case ARM_CPU_MODE_UND
:
8225 case ARM_CPU_MODE_SYS
:
8227 case ARM_CPU_MODE_HYP
:
8228 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
8232 case ARM_CPU_MODE_MON
:
8233 /* No need to check specifically for "are we non-secure" because
8234 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8235 * so if this isn't EL3 then we must be non-secure.
8237 if (s
->current_el
!= 3) {
8246 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8247 default_exception_el(s
));
8251 addr
= tcg_temp_new_i32();
8252 tmp
= tcg_const_i32(mode
);
8253 /* get_r13_banked() will raise an exception if called from System mode */
8254 gen_set_condexec(s
);
8255 gen_set_pc_im(s
, s
->pc
- 4);
8256 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8257 tcg_temp_free_i32(tmp
);
8274 tcg_gen_addi_i32(addr
, addr
, offset
);
8275 tmp
= load_reg(s
, 14);
8276 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8277 tcg_temp_free_i32(tmp
);
8278 tmp
= load_cpu_field(spsr
);
8279 tcg_gen_addi_i32(addr
, addr
, 4);
8280 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8281 tcg_temp_free_i32(tmp
);
8299 tcg_gen_addi_i32(addr
, addr
, offset
);
8300 tmp
= tcg_const_i32(mode
);
8301 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8302 tcg_temp_free_i32(tmp
);
8304 tcg_temp_free_i32(addr
);
8305 s
->base
.is_jmp
= DISAS_UPDATE
;
8308 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8310 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8317 /* M variants do not implement ARM mode; this must raise the INVSTATE
8318 * UsageFault exception.
8320 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8321 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8322 default_exception_el(s
));
8327 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8328 * choose to UNDEF. In ARMv5 and above the space is used
8329 * for miscellaneous unconditional instructions.
8333 /* Unconditional instructions. */
8334 if (((insn
>> 25) & 7) == 1) {
8335 /* NEON Data processing. */
8336 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8340 if (disas_neon_data_insn(s
, insn
)) {
8345 if ((insn
& 0x0f100000) == 0x04000000) {
8346 /* NEON load/store. */
8347 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8351 if (disas_neon_ls_insn(s
, insn
)) {
8356 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8358 if (disas_vfp_insn(s
, insn
)) {
8363 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8364 ((insn
& 0x0f30f010) == 0x0710f000)) {
8365 if ((insn
& (1 << 22)) == 0) {
8367 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8371 /* Otherwise PLD; v5TE+ */
8375 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8376 ((insn
& 0x0f70f010) == 0x0650f000)) {
8378 return; /* PLI; V7 */
8380 if (((insn
& 0x0f700000) == 0x04100000) ||
8381 ((insn
& 0x0f700010) == 0x06100000)) {
8382 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8385 return; /* v7MP: Unallocated memory hint: must NOP */
8388 if ((insn
& 0x0ffffdff) == 0x01010000) {
8391 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8392 gen_helper_setend(cpu_env
);
8393 s
->base
.is_jmp
= DISAS_UPDATE
;
8396 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8397 switch ((insn
>> 4) & 0xf) {
8405 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8408 /* We need to break the TB after this insn to execute
8409 * self-modifying code correctly and also to take
8410 * any pending interrupts immediately.
8412 gen_goto_tb(s
, 0, s
->pc
& ~1);
8417 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8420 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8422 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8428 rn
= (insn
>> 16) & 0xf;
8429 addr
= load_reg(s
, rn
);
8430 i
= (insn
>> 23) & 3;
8432 case 0: offset
= -4; break; /* DA */
8433 case 1: offset
= 0; break; /* IA */
8434 case 2: offset
= -8; break; /* DB */
8435 case 3: offset
= 4; break; /* IB */
8439 tcg_gen_addi_i32(addr
, addr
, offset
);
8440 /* Load PC into tmp and CPSR into tmp2. */
8441 tmp
= tcg_temp_new_i32();
8442 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8443 tcg_gen_addi_i32(addr
, addr
, 4);
8444 tmp2
= tcg_temp_new_i32();
8445 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8446 if (insn
& (1 << 21)) {
8447 /* Base writeback. */
8449 case 0: offset
= -8; break;
8450 case 1: offset
= 4; break;
8451 case 2: offset
= -4; break;
8452 case 3: offset
= 0; break;
8456 tcg_gen_addi_i32(addr
, addr
, offset
);
8457 store_reg(s
, rn
, addr
);
8459 tcg_temp_free_i32(addr
);
8461 gen_rfe(s
, tmp
, tmp2
);
8463 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8464 /* branch link and change to thumb (blx <offset>) */
8467 val
= (uint32_t)s
->pc
;
8468 tmp
= tcg_temp_new_i32();
8469 tcg_gen_movi_i32(tmp
, val
);
8470 store_reg(s
, 14, tmp
);
8471 /* Sign-extend the 24-bit offset */
8472 offset
= (((int32_t)insn
) << 8) >> 8;
8473 /* offset * 4 + bit24 * 2 + (thumb bit) */
8474 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8475 /* pipeline offset */
8477 /* protected by ARCH(5); above, near the start of uncond block */
8480 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8481 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8482 /* iWMMXt register transfer. */
8483 if (extract32(s
->c15_cpar
, 1, 1)) {
8484 if (!disas_iwmmxt_insn(s
, insn
)) {
8489 } else if ((insn
& 0x0e000a00) == 0x0c000800
8490 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8491 if (disas_neon_insn_3same_ext(s
, insn
)) {
8495 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8496 /* Coprocessor double register transfer. */
8498 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8499 /* Additional coprocessor register transfer. */
8500 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8503 /* cps (privileged) */
8507 if (insn
& (1 << 19)) {
8508 if (insn
& (1 << 8))
8510 if (insn
& (1 << 7))
8512 if (insn
& (1 << 6))
8514 if (insn
& (1 << 18))
8517 if (insn
& (1 << 17)) {
8519 val
|= (insn
& 0x1f);
8522 gen_set_psr_im(s
, mask
, 0, val
);
8529 /* if not always execute, we generate a conditional jump to
8531 s
->condlabel
= gen_new_label();
8532 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8535 if ((insn
& 0x0f900000) == 0x03000000) {
8536 if ((insn
& (1 << 21)) == 0) {
8538 rd
= (insn
>> 12) & 0xf;
8539 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8540 if ((insn
& (1 << 22)) == 0) {
8542 tmp
= tcg_temp_new_i32();
8543 tcg_gen_movi_i32(tmp
, val
);
8546 tmp
= load_reg(s
, rd
);
8547 tcg_gen_ext16u_i32(tmp
, tmp
);
8548 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8550 store_reg(s
, rd
, tmp
);
8552 if (((insn
>> 12) & 0xf) != 0xf)
8554 if (((insn
>> 16) & 0xf) == 0) {
8555 gen_nop_hint(s
, insn
& 0xff);
8557 /* CPSR = immediate */
8559 shift
= ((insn
>> 8) & 0xf) * 2;
8561 val
= (val
>> shift
) | (val
<< (32 - shift
));
8562 i
= ((insn
& (1 << 22)) != 0);
8563 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8569 } else if ((insn
& 0x0f900000) == 0x01000000
8570 && (insn
& 0x00000090) != 0x00000090) {
8571 /* miscellaneous instructions */
8572 op1
= (insn
>> 21) & 3;
8573 sh
= (insn
>> 4) & 0xf;
8576 case 0x0: /* MSR, MRS */
8577 if (insn
& (1 << 9)) {
8578 /* MSR (banked) and MRS (banked) */
8579 int sysm
= extract32(insn
, 16, 4) |
8580 (extract32(insn
, 8, 1) << 4);
8581 int r
= extract32(insn
, 22, 1);
8585 gen_msr_banked(s
, r
, sysm
, rm
);
8588 int rd
= extract32(insn
, 12, 4);
8590 gen_mrs_banked(s
, r
, sysm
, rd
);
8595 /* MSR, MRS (for PSRs) */
8598 tmp
= load_reg(s
, rm
);
8599 i
= ((op1
& 2) != 0);
8600 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8604 rd
= (insn
>> 12) & 0xf;
8608 tmp
= load_cpu_field(spsr
);
8610 tmp
= tcg_temp_new_i32();
8611 gen_helper_cpsr_read(tmp
, cpu_env
);
8613 store_reg(s
, rd
, tmp
);
8618 /* branch/exchange thumb (bx). */
8620 tmp
= load_reg(s
, rm
);
8622 } else if (op1
== 3) {
8625 rd
= (insn
>> 12) & 0xf;
8626 tmp
= load_reg(s
, rm
);
8627 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8628 store_reg(s
, rd
, tmp
);
8636 /* Trivial implementation equivalent to bx. */
8637 tmp
= load_reg(s
, rm
);
8648 /* branch link/exchange thumb (blx) */
8649 tmp
= load_reg(s
, rm
);
8650 tmp2
= tcg_temp_new_i32();
8651 tcg_gen_movi_i32(tmp2
, s
->pc
);
8652 store_reg(s
, 14, tmp2
);
8658 uint32_t c
= extract32(insn
, 8, 4);
8660 /* Check this CPU supports ARMv8 CRC instructions.
8661 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8662 * Bits 8, 10 and 11 should be zero.
8664 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8669 rn
= extract32(insn
, 16, 4);
8670 rd
= extract32(insn
, 12, 4);
8672 tmp
= load_reg(s
, rn
);
8673 tmp2
= load_reg(s
, rm
);
8675 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8676 } else if (op1
== 1) {
8677 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8679 tmp3
= tcg_const_i32(1 << op1
);
8681 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8683 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8685 tcg_temp_free_i32(tmp2
);
8686 tcg_temp_free_i32(tmp3
);
8687 store_reg(s
, rd
, tmp
);
8690 case 0x5: /* saturating add/subtract */
8692 rd
= (insn
>> 12) & 0xf;
8693 rn
= (insn
>> 16) & 0xf;
8694 tmp
= load_reg(s
, rm
);
8695 tmp2
= load_reg(s
, rn
);
8697 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8699 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8701 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8702 tcg_temp_free_i32(tmp2
);
8703 store_reg(s
, rd
, tmp
);
8707 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8716 gen_exception_insn(s
, 4, EXCP_BKPT
,
8717 syn_aa32_bkpt(imm16
, false),
8718 default_exception_el(s
));
8721 /* Hypervisor call (v7) */
8729 /* Secure monitor call (v6+) */
8737 g_assert_not_reached();
8741 case 0x8: /* signed multiply */
8746 rs
= (insn
>> 8) & 0xf;
8747 rn
= (insn
>> 12) & 0xf;
8748 rd
= (insn
>> 16) & 0xf;
8750 /* (32 * 16) >> 16 */
8751 tmp
= load_reg(s
, rm
);
8752 tmp2
= load_reg(s
, rs
);
8754 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8757 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8758 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8759 tmp
= tcg_temp_new_i32();
8760 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8761 tcg_temp_free_i64(tmp64
);
8762 if ((sh
& 2) == 0) {
8763 tmp2
= load_reg(s
, rn
);
8764 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8765 tcg_temp_free_i32(tmp2
);
8767 store_reg(s
, rd
, tmp
);
8770 tmp
= load_reg(s
, rm
);
8771 tmp2
= load_reg(s
, rs
);
8772 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8773 tcg_temp_free_i32(tmp2
);
8775 tmp64
= tcg_temp_new_i64();
8776 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8777 tcg_temp_free_i32(tmp
);
8778 gen_addq(s
, tmp64
, rn
, rd
);
8779 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8780 tcg_temp_free_i64(tmp64
);
8783 tmp2
= load_reg(s
, rn
);
8784 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8785 tcg_temp_free_i32(tmp2
);
8787 store_reg(s
, rd
, tmp
);
8794 } else if (((insn
& 0x0e000000) == 0 &&
8795 (insn
& 0x00000090) != 0x90) ||
8796 ((insn
& 0x0e000000) == (1 << 25))) {
8797 int set_cc
, logic_cc
, shiftop
;
8799 op1
= (insn
>> 21) & 0xf;
8800 set_cc
= (insn
>> 20) & 1;
8801 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8803 /* data processing instruction */
8804 if (insn
& (1 << 25)) {
8805 /* immediate operand */
8807 shift
= ((insn
>> 8) & 0xf) * 2;
8809 val
= (val
>> shift
) | (val
<< (32 - shift
));
8811 tmp2
= tcg_temp_new_i32();
8812 tcg_gen_movi_i32(tmp2
, val
);
8813 if (logic_cc
&& shift
) {
8814 gen_set_CF_bit31(tmp2
);
8819 tmp2
= load_reg(s
, rm
);
8820 shiftop
= (insn
>> 5) & 3;
8821 if (!(insn
& (1 << 4))) {
8822 shift
= (insn
>> 7) & 0x1f;
8823 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8825 rs
= (insn
>> 8) & 0xf;
8826 tmp
= load_reg(s
, rs
);
8827 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8830 if (op1
!= 0x0f && op1
!= 0x0d) {
8831 rn
= (insn
>> 16) & 0xf;
8832 tmp
= load_reg(s
, rn
);
8836 rd
= (insn
>> 12) & 0xf;
8839 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8843 store_reg_bx(s
, rd
, tmp
);
8846 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8850 store_reg_bx(s
, rd
, tmp
);
8853 if (set_cc
&& rd
== 15) {
8854 /* SUBS r15, ... is used for exception return. */
8858 gen_sub_CC(tmp
, tmp
, tmp2
);
8859 gen_exception_return(s
, tmp
);
8862 gen_sub_CC(tmp
, tmp
, tmp2
);
8864 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8866 store_reg_bx(s
, rd
, tmp
);
8871 gen_sub_CC(tmp
, tmp2
, tmp
);
8873 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8875 store_reg_bx(s
, rd
, tmp
);
8879 gen_add_CC(tmp
, tmp
, tmp2
);
8881 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8883 store_reg_bx(s
, rd
, tmp
);
8887 gen_adc_CC(tmp
, tmp
, tmp2
);
8889 gen_add_carry(tmp
, tmp
, tmp2
);
8891 store_reg_bx(s
, rd
, tmp
);
8895 gen_sbc_CC(tmp
, tmp
, tmp2
);
8897 gen_sub_carry(tmp
, tmp
, tmp2
);
8899 store_reg_bx(s
, rd
, tmp
);
8903 gen_sbc_CC(tmp
, tmp2
, tmp
);
8905 gen_sub_carry(tmp
, tmp2
, tmp
);
8907 store_reg_bx(s
, rd
, tmp
);
8911 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8914 tcg_temp_free_i32(tmp
);
8918 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8921 tcg_temp_free_i32(tmp
);
8925 gen_sub_CC(tmp
, tmp
, tmp2
);
8927 tcg_temp_free_i32(tmp
);
8931 gen_add_CC(tmp
, tmp
, tmp2
);
8933 tcg_temp_free_i32(tmp
);
8936 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8940 store_reg_bx(s
, rd
, tmp
);
8943 if (logic_cc
&& rd
== 15) {
8944 /* MOVS r15, ... is used for exception return. */
8948 gen_exception_return(s
, tmp2
);
8953 store_reg_bx(s
, rd
, tmp2
);
8957 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8961 store_reg_bx(s
, rd
, tmp
);
8965 tcg_gen_not_i32(tmp2
, tmp2
);
8969 store_reg_bx(s
, rd
, tmp2
);
8972 if (op1
!= 0x0f && op1
!= 0x0d) {
8973 tcg_temp_free_i32(tmp2
);
8976 /* other instructions */
8977 op1
= (insn
>> 24) & 0xf;
8981 /* multiplies, extra load/stores */
8982 sh
= (insn
>> 5) & 3;
8985 rd
= (insn
>> 16) & 0xf;
8986 rn
= (insn
>> 12) & 0xf;
8987 rs
= (insn
>> 8) & 0xf;
8989 op1
= (insn
>> 20) & 0xf;
8991 case 0: case 1: case 2: case 3: case 6:
8993 tmp
= load_reg(s
, rs
);
8994 tmp2
= load_reg(s
, rm
);
8995 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8996 tcg_temp_free_i32(tmp2
);
8997 if (insn
& (1 << 22)) {
8998 /* Subtract (mls) */
9000 tmp2
= load_reg(s
, rn
);
9001 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9002 tcg_temp_free_i32(tmp2
);
9003 } else if (insn
& (1 << 21)) {
9005 tmp2
= load_reg(s
, rn
);
9006 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9007 tcg_temp_free_i32(tmp2
);
9009 if (insn
& (1 << 20))
9011 store_reg(s
, rd
, tmp
);
9014 /* 64 bit mul double accumulate (UMAAL) */
9016 tmp
= load_reg(s
, rs
);
9017 tmp2
= load_reg(s
, rm
);
9018 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9019 gen_addq_lo(s
, tmp64
, rn
);
9020 gen_addq_lo(s
, tmp64
, rd
);
9021 gen_storeq_reg(s
, rn
, rd
, tmp64
);
9022 tcg_temp_free_i64(tmp64
);
9024 case 8: case 9: case 10: case 11:
9025 case 12: case 13: case 14: case 15:
9026 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9027 tmp
= load_reg(s
, rs
);
9028 tmp2
= load_reg(s
, rm
);
9029 if (insn
& (1 << 22)) {
9030 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
9032 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
9034 if (insn
& (1 << 21)) { /* mult accumulate */
9035 TCGv_i32 al
= load_reg(s
, rn
);
9036 TCGv_i32 ah
= load_reg(s
, rd
);
9037 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
9038 tcg_temp_free_i32(al
);
9039 tcg_temp_free_i32(ah
);
9041 if (insn
& (1 << 20)) {
9042 gen_logicq_cc(tmp
, tmp2
);
9044 store_reg(s
, rn
, tmp
);
9045 store_reg(s
, rd
, tmp2
);
9051 rn
= (insn
>> 16) & 0xf;
9052 rd
= (insn
>> 12) & 0xf;
9053 if (insn
& (1 << 23)) {
9054 /* load/store exclusive */
9055 int op2
= (insn
>> 8) & 3;
9056 op1
= (insn
>> 21) & 0x3;
9059 case 0: /* lda/stl */
9065 case 1: /* reserved */
9067 case 2: /* ldaex/stlex */
9070 case 3: /* ldrex/strex */
9079 addr
= tcg_temp_local_new_i32();
9080 load_reg_var(s
, addr
, rn
);
9082 /* Since the emulation does not have barriers,
9083 the acquire/release semantics need no special
9086 if (insn
& (1 << 20)) {
9087 tmp
= tcg_temp_new_i32();
9090 gen_aa32_ld32u_iss(s
, tmp
, addr
,
9095 gen_aa32_ld8u_iss(s
, tmp
, addr
,
9100 gen_aa32_ld16u_iss(s
, tmp
, addr
,
9107 store_reg(s
, rd
, tmp
);
9110 tmp
= load_reg(s
, rm
);
9113 gen_aa32_st32_iss(s
, tmp
, addr
,
9118 gen_aa32_st8_iss(s
, tmp
, addr
,
9123 gen_aa32_st16_iss(s
, tmp
, addr
,
9130 tcg_temp_free_i32(tmp
);
9132 } else if (insn
& (1 << 20)) {
9135 gen_load_exclusive(s
, rd
, 15, addr
, 2);
9137 case 1: /* ldrexd */
9138 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
9140 case 2: /* ldrexb */
9141 gen_load_exclusive(s
, rd
, 15, addr
, 0);
9143 case 3: /* ldrexh */
9144 gen_load_exclusive(s
, rd
, 15, addr
, 1);
9153 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
9155 case 1: /* strexd */
9156 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
9158 case 2: /* strexb */
9159 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
9161 case 3: /* strexh */
9162 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
9168 tcg_temp_free_i32(addr
);
9171 TCGMemOp opc
= s
->be_data
;
9173 /* SWP instruction */
9176 if (insn
& (1 << 22)) {
9179 opc
|= MO_UL
| MO_ALIGN
;
9182 addr
= load_reg(s
, rn
);
9183 taddr
= gen_aa32_addr(s
, addr
, opc
);
9184 tcg_temp_free_i32(addr
);
9186 tmp
= load_reg(s
, rm
);
9187 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
9188 get_mem_index(s
), opc
);
9189 tcg_temp_free(taddr
);
9190 store_reg(s
, rd
, tmp
);
9195 bool load
= insn
& (1 << 20);
9196 bool wbit
= insn
& (1 << 21);
9197 bool pbit
= insn
& (1 << 24);
9198 bool doubleword
= false;
9201 /* Misc load/store */
9202 rn
= (insn
>> 16) & 0xf;
9203 rd
= (insn
>> 12) & 0xf;
9205 /* ISS not valid if writeback */
9206 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
9208 if (!load
&& (sh
& 2)) {
9212 /* UNPREDICTABLE; we choose to UNDEF */
9215 load
= (sh
& 1) == 0;
9219 addr
= load_reg(s
, rn
);
9221 gen_add_datah_offset(s
, insn
, 0, addr
);
9228 tmp
= load_reg(s
, rd
);
9229 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9230 tcg_temp_free_i32(tmp
);
9231 tcg_gen_addi_i32(addr
, addr
, 4);
9232 tmp
= load_reg(s
, rd
+ 1);
9233 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9234 tcg_temp_free_i32(tmp
);
9237 tmp
= tcg_temp_new_i32();
9238 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9239 store_reg(s
, rd
, tmp
);
9240 tcg_gen_addi_i32(addr
, addr
, 4);
9241 tmp
= tcg_temp_new_i32();
9242 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9245 address_offset
= -4;
9248 tmp
= tcg_temp_new_i32();
9251 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9255 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9260 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9266 tmp
= load_reg(s
, rd
);
9267 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9268 tcg_temp_free_i32(tmp
);
9270 /* Perform base writeback before the loaded value to
9271 ensure correct behavior with overlapping index registers.
9272 ldrd with base writeback is undefined if the
9273 destination and index registers overlap. */
9275 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9276 store_reg(s
, rn
, addr
);
9279 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9280 store_reg(s
, rn
, addr
);
9282 tcg_temp_free_i32(addr
);
9285 /* Complete the load. */
9286 store_reg(s
, rd
, tmp
);
9295 if (insn
& (1 << 4)) {
9297 /* Armv6 Media instructions. */
9299 rn
= (insn
>> 16) & 0xf;
9300 rd
= (insn
>> 12) & 0xf;
9301 rs
= (insn
>> 8) & 0xf;
9302 switch ((insn
>> 23) & 3) {
9303 case 0: /* Parallel add/subtract. */
9304 op1
= (insn
>> 20) & 7;
9305 tmp
= load_reg(s
, rn
);
9306 tmp2
= load_reg(s
, rm
);
9307 sh
= (insn
>> 5) & 7;
9308 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9310 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9311 tcg_temp_free_i32(tmp2
);
9312 store_reg(s
, rd
, tmp
);
9315 if ((insn
& 0x00700020) == 0) {
9316 /* Halfword pack. */
9317 tmp
= load_reg(s
, rn
);
9318 tmp2
= load_reg(s
, rm
);
9319 shift
= (insn
>> 7) & 0x1f;
9320 if (insn
& (1 << 6)) {
9324 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9325 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9326 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9330 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9331 tcg_gen_ext16u_i32(tmp
, tmp
);
9332 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9334 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9335 tcg_temp_free_i32(tmp2
);
9336 store_reg(s
, rd
, tmp
);
9337 } else if ((insn
& 0x00200020) == 0x00200000) {
9339 tmp
= load_reg(s
, rm
);
9340 shift
= (insn
>> 7) & 0x1f;
9341 if (insn
& (1 << 6)) {
9344 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9346 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9348 sh
= (insn
>> 16) & 0x1f;
9349 tmp2
= tcg_const_i32(sh
);
9350 if (insn
& (1 << 22))
9351 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9353 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9354 tcg_temp_free_i32(tmp2
);
9355 store_reg(s
, rd
, tmp
);
9356 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9358 tmp
= load_reg(s
, rm
);
9359 sh
= (insn
>> 16) & 0x1f;
9360 tmp2
= tcg_const_i32(sh
);
9361 if (insn
& (1 << 22))
9362 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9364 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9365 tcg_temp_free_i32(tmp2
);
9366 store_reg(s
, rd
, tmp
);
9367 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9369 tmp
= load_reg(s
, rn
);
9370 tmp2
= load_reg(s
, rm
);
9371 tmp3
= tcg_temp_new_i32();
9372 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9373 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9374 tcg_temp_free_i32(tmp3
);
9375 tcg_temp_free_i32(tmp2
);
9376 store_reg(s
, rd
, tmp
);
9377 } else if ((insn
& 0x000003e0) == 0x00000060) {
9378 tmp
= load_reg(s
, rm
);
9379 shift
= (insn
>> 10) & 3;
9380 /* ??? In many cases it's not necessary to do a
9381 rotate, a shift is sufficient. */
9383 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9384 op1
= (insn
>> 20) & 7;
9386 case 0: gen_sxtb16(tmp
); break;
9387 case 2: gen_sxtb(tmp
); break;
9388 case 3: gen_sxth(tmp
); break;
9389 case 4: gen_uxtb16(tmp
); break;
9390 case 6: gen_uxtb(tmp
); break;
9391 case 7: gen_uxth(tmp
); break;
9392 default: goto illegal_op
;
9395 tmp2
= load_reg(s
, rn
);
9396 if ((op1
& 3) == 0) {
9397 gen_add16(tmp
, tmp2
);
9399 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9400 tcg_temp_free_i32(tmp2
);
9403 store_reg(s
, rd
, tmp
);
9404 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9406 tmp
= load_reg(s
, rm
);
9407 if (insn
& (1 << 22)) {
9408 if (insn
& (1 << 7)) {
9412 gen_helper_rbit(tmp
, tmp
);
9415 if (insn
& (1 << 7))
9418 tcg_gen_bswap32_i32(tmp
, tmp
);
9420 store_reg(s
, rd
, tmp
);
9425 case 2: /* Multiplies (Type 3). */
9426 switch ((insn
>> 20) & 0x7) {
9428 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9429 /* op2 not 00x or 11x : UNDEF */
9432 /* Signed multiply most significant [accumulate].
9433 (SMMUL, SMMLA, SMMLS) */
9434 tmp
= load_reg(s
, rm
);
9435 tmp2
= load_reg(s
, rs
);
9436 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9439 tmp
= load_reg(s
, rd
);
9440 if (insn
& (1 << 6)) {
9441 tmp64
= gen_subq_msw(tmp64
, tmp
);
9443 tmp64
= gen_addq_msw(tmp64
, tmp
);
9446 if (insn
& (1 << 5)) {
9447 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9449 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9450 tmp
= tcg_temp_new_i32();
9451 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9452 tcg_temp_free_i64(tmp64
);
9453 store_reg(s
, rn
, tmp
);
9457 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9458 if (insn
& (1 << 7)) {
9461 tmp
= load_reg(s
, rm
);
9462 tmp2
= load_reg(s
, rs
);
9463 if (insn
& (1 << 5))
9464 gen_swap_half(tmp2
);
9465 gen_smul_dual(tmp
, tmp2
);
9466 if (insn
& (1 << 22)) {
9467 /* smlald, smlsld */
9470 tmp64
= tcg_temp_new_i64();
9471 tmp64_2
= tcg_temp_new_i64();
9472 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9473 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9474 tcg_temp_free_i32(tmp
);
9475 tcg_temp_free_i32(tmp2
);
9476 if (insn
& (1 << 6)) {
9477 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9479 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9481 tcg_temp_free_i64(tmp64_2
);
9482 gen_addq(s
, tmp64
, rd
, rn
);
9483 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9484 tcg_temp_free_i64(tmp64
);
9486 /* smuad, smusd, smlad, smlsd */
9487 if (insn
& (1 << 6)) {
9488 /* This subtraction cannot overflow. */
9489 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9491 /* This addition cannot overflow 32 bits;
9492 * however it may overflow considered as a
9493 * signed operation, in which case we must set
9496 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9498 tcg_temp_free_i32(tmp2
);
9501 tmp2
= load_reg(s
, rd
);
9502 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9503 tcg_temp_free_i32(tmp2
);
9505 store_reg(s
, rn
, tmp
);
9511 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9514 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9517 tmp
= load_reg(s
, rm
);
9518 tmp2
= load_reg(s
, rs
);
9519 if (insn
& (1 << 21)) {
9520 gen_helper_udiv(tmp
, tmp
, tmp2
);
9522 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9524 tcg_temp_free_i32(tmp2
);
9525 store_reg(s
, rn
, tmp
);
9532 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9534 case 0: /* Unsigned sum of absolute differences. */
9536 tmp
= load_reg(s
, rm
);
9537 tmp2
= load_reg(s
, rs
);
9538 gen_helper_usad8(tmp
, tmp
, tmp2
);
9539 tcg_temp_free_i32(tmp2
);
9541 tmp2
= load_reg(s
, rd
);
9542 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9543 tcg_temp_free_i32(tmp2
);
9545 store_reg(s
, rn
, tmp
);
9547 case 0x20: case 0x24: case 0x28: case 0x2c:
9548 /* Bitfield insert/clear. */
9550 shift
= (insn
>> 7) & 0x1f;
9551 i
= (insn
>> 16) & 0x1f;
9553 /* UNPREDICTABLE; we choose to UNDEF */
9558 tmp
= tcg_temp_new_i32();
9559 tcg_gen_movi_i32(tmp
, 0);
9561 tmp
= load_reg(s
, rm
);
9564 tmp2
= load_reg(s
, rd
);
9565 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9566 tcg_temp_free_i32(tmp2
);
9568 store_reg(s
, rd
, tmp
);
9570 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9571 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9573 tmp
= load_reg(s
, rm
);
9574 shift
= (insn
>> 7) & 0x1f;
9575 i
= ((insn
>> 16) & 0x1f) + 1;
9580 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9582 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9585 store_reg(s
, rd
, tmp
);
9595 /* Check for undefined extension instructions
9596 * per the ARM Bible IE:
9597 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9599 sh
= (0xf << 20) | (0xf << 4);
9600 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9604 /* load/store byte/word */
9605 rn
= (insn
>> 16) & 0xf;
9606 rd
= (insn
>> 12) & 0xf;
9607 tmp2
= load_reg(s
, rn
);
9608 if ((insn
& 0x01200000) == 0x00200000) {
9610 i
= get_a32_user_mem_index(s
);
9612 i
= get_mem_index(s
);
9614 if (insn
& (1 << 24))
9615 gen_add_data_offset(s
, insn
, tmp2
);
9616 if (insn
& (1 << 20)) {
9618 tmp
= tcg_temp_new_i32();
9619 if (insn
& (1 << 22)) {
9620 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9622 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9626 tmp
= load_reg(s
, rd
);
9627 if (insn
& (1 << 22)) {
9628 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9630 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9632 tcg_temp_free_i32(tmp
);
9634 if (!(insn
& (1 << 24))) {
9635 gen_add_data_offset(s
, insn
, tmp2
);
9636 store_reg(s
, rn
, tmp2
);
9637 } else if (insn
& (1 << 21)) {
9638 store_reg(s
, rn
, tmp2
);
9640 tcg_temp_free_i32(tmp2
);
9642 if (insn
& (1 << 20)) {
9643 /* Complete the load. */
9644 store_reg_from_load(s
, rd
, tmp
);
9650 int j
, n
, loaded_base
;
9651 bool exc_return
= false;
9652 bool is_load
= extract32(insn
, 20, 1);
9654 TCGv_i32 loaded_var
;
9655 /* load/store multiple words */
9656 /* XXX: store correct base if write back */
9657 if (insn
& (1 << 22)) {
9658 /* LDM (user), LDM (exception return) and STM (user) */
9660 goto illegal_op
; /* only usable in supervisor mode */
9662 if (is_load
&& extract32(insn
, 15, 1)) {
9668 rn
= (insn
>> 16) & 0xf;
9669 addr
= load_reg(s
, rn
);
9671 /* compute total size */
9676 if (insn
& (1 << i
))
9679 /* XXX: test invalid n == 0 case ? */
9680 if (insn
& (1 << 23)) {
9681 if (insn
& (1 << 24)) {
9683 tcg_gen_addi_i32(addr
, addr
, 4);
9685 /* post increment */
9688 if (insn
& (1 << 24)) {
9690 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9692 /* post decrement */
9694 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9699 if (insn
& (1 << i
)) {
9702 tmp
= tcg_temp_new_i32();
9703 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9705 tmp2
= tcg_const_i32(i
);
9706 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9707 tcg_temp_free_i32(tmp2
);
9708 tcg_temp_free_i32(tmp
);
9709 } else if (i
== rn
) {
9712 } else if (rn
== 15 && exc_return
) {
9713 store_pc_exc_ret(s
, tmp
);
9715 store_reg_from_load(s
, i
, tmp
);
9720 /* special case: r15 = PC + 8 */
9721 val
= (long)s
->pc
+ 4;
9722 tmp
= tcg_temp_new_i32();
9723 tcg_gen_movi_i32(tmp
, val
);
9725 tmp
= tcg_temp_new_i32();
9726 tmp2
= tcg_const_i32(i
);
9727 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9728 tcg_temp_free_i32(tmp2
);
9730 tmp
= load_reg(s
, i
);
9732 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9733 tcg_temp_free_i32(tmp
);
9736 /* no need to add after the last transfer */
9738 tcg_gen_addi_i32(addr
, addr
, 4);
9741 if (insn
& (1 << 21)) {
9743 if (insn
& (1 << 23)) {
9744 if (insn
& (1 << 24)) {
9747 /* post increment */
9748 tcg_gen_addi_i32(addr
, addr
, 4);
9751 if (insn
& (1 << 24)) {
9754 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9756 /* post decrement */
9757 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9760 store_reg(s
, rn
, addr
);
9762 tcg_temp_free_i32(addr
);
9765 store_reg(s
, rn
, loaded_var
);
9768 /* Restore CPSR from SPSR. */
9769 tmp
= load_cpu_field(spsr
);
9770 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9771 tcg_temp_free_i32(tmp
);
9772 /* Must exit loop to check un-masked IRQs */
9773 s
->base
.is_jmp
= DISAS_EXIT
;
9782 /* branch (and link) */
9783 val
= (int32_t)s
->pc
;
9784 if (insn
& (1 << 24)) {
9785 tmp
= tcg_temp_new_i32();
9786 tcg_gen_movi_i32(tmp
, val
);
9787 store_reg(s
, 14, tmp
);
9789 offset
= sextract32(insn
<< 2, 0, 26);
9797 if (((insn
>> 8) & 0xe) == 10) {
9799 if (disas_vfp_insn(s
, insn
)) {
9802 } else if (disas_coproc_insn(s
, insn
)) {
9809 gen_set_pc_im(s
, s
->pc
);
9810 s
->svc_imm
= extract32(insn
, 0, 24);
9811 s
->base
.is_jmp
= DISAS_SWI
;
9815 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9816 default_exception_el(s
));
9822 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t insn
)
9824 /* Return true if this is a 16 bit instruction. We must be precise
9825 * about this (matching the decode). We assume that s->pc still
9826 * points to the first 16 bits of the insn.
9828 if ((insn
>> 11) < 0x1d) {
9829 /* Definitely a 16-bit instruction */
9833 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9834 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9835 * end up actually treating this as two 16-bit insns, though,
9836 * if it's half of a bl/blx pair that might span a page boundary.
9838 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
9839 /* Thumb2 cores (including all M profile ones) always treat
9840 * 32-bit insns as 32-bit.
9845 if ((insn
>> 11) == 0x1e && (s
->pc
< s
->next_page_start
- 3)) {
9846 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9847 * is not on the next page; we merge this into a 32-bit
9852 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9853 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9854 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9855 * -- handle as single 16 bit insn
9860 /* Return true if this is a Thumb-2 logical op. */
9862 thumb2_logic_op(int op
)
9867 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9868 then set condition code flags based on the result of the operation.
9869 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9870 to the high bit of T1.
9871 Returns zero if the opcode is valid. */
9874 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9875 TCGv_i32 t0
, TCGv_i32 t1
)
9882 tcg_gen_and_i32(t0
, t0
, t1
);
9886 tcg_gen_andc_i32(t0
, t0
, t1
);
9890 tcg_gen_or_i32(t0
, t0
, t1
);
9894 tcg_gen_orc_i32(t0
, t0
, t1
);
9898 tcg_gen_xor_i32(t0
, t0
, t1
);
9903 gen_add_CC(t0
, t0
, t1
);
9905 tcg_gen_add_i32(t0
, t0
, t1
);
9909 gen_adc_CC(t0
, t0
, t1
);
9915 gen_sbc_CC(t0
, t0
, t1
);
9917 gen_sub_carry(t0
, t0
, t1
);
9922 gen_sub_CC(t0
, t0
, t1
);
9924 tcg_gen_sub_i32(t0
, t0
, t1
);
9928 gen_sub_CC(t0
, t1
, t0
);
9930 tcg_gen_sub_i32(t0
, t1
, t0
);
9932 default: /* 5, 6, 7, 9, 12, 15. */
9938 gen_set_CF_bit31(t1
);
9943 /* Translate a 32-bit thumb instruction. */
9944 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
9946 uint32_t imm
, shift
, offset
;
9947 uint32_t rd
, rn
, rm
, rs
;
9958 /* The only 32 bit insn that's allowed for Thumb1 is the combined
9959 * BL/BLX prefix and suffix.
9961 if ((insn
& 0xf800e800) != 0xf000e800) {
9965 rn
= (insn
>> 16) & 0xf;
9966 rs
= (insn
>> 12) & 0xf;
9967 rd
= (insn
>> 8) & 0xf;
9969 switch ((insn
>> 25) & 0xf) {
9970 case 0: case 1: case 2: case 3:
9971 /* 16-bit instructions. Should never happen. */
9974 if (insn
& (1 << 22)) {
9975 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9976 * - load/store doubleword, load/store exclusive, ldacq/strel,
9979 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_M
) &&
9980 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
9981 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9983 * The bulk of the behaviour for this instruction is implemented
9984 * in v7m_handle_execute_nsc(), which deals with the insn when
9985 * it is executed by a CPU in non-secure state from memory
9986 * which is Secure & NonSecure-Callable.
9987 * Here we only need to handle the remaining cases:
9988 * * in NS memory (including the "security extension not
9989 * implemented" case) : NOP
9990 * * in S memory but CPU already secure (clear IT bits)
9991 * We know that the attribute for the memory this insn is
9992 * in must match the current CPU state, because otherwise
9993 * get_phys_addr_pmsav8 would have generated an exception.
9995 if (s
->v8m_secure
) {
9996 /* Like the IT insn, we don't need to generate any code */
9997 s
->condexec_cond
= 0;
9998 s
->condexec_mask
= 0;
10000 } else if (insn
& 0x01200000) {
10001 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10002 * - load/store dual (post-indexed)
10003 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10004 * - load/store dual (literal and immediate)
10005 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10006 * - load/store dual (pre-indexed)
10009 if (insn
& (1 << 21)) {
10010 /* UNPREDICTABLE */
10013 addr
= tcg_temp_new_i32();
10014 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
10016 addr
= load_reg(s
, rn
);
10018 offset
= (insn
& 0xff) * 4;
10019 if ((insn
& (1 << 23)) == 0)
10021 if (insn
& (1 << 24)) {
10022 tcg_gen_addi_i32(addr
, addr
, offset
);
10025 if (insn
& (1 << 20)) {
10027 tmp
= tcg_temp_new_i32();
10028 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10029 store_reg(s
, rs
, tmp
);
10030 tcg_gen_addi_i32(addr
, addr
, 4);
10031 tmp
= tcg_temp_new_i32();
10032 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10033 store_reg(s
, rd
, tmp
);
10036 tmp
= load_reg(s
, rs
);
10037 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10038 tcg_temp_free_i32(tmp
);
10039 tcg_gen_addi_i32(addr
, addr
, 4);
10040 tmp
= load_reg(s
, rd
);
10041 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10042 tcg_temp_free_i32(tmp
);
10044 if (insn
& (1 << 21)) {
10045 /* Base writeback. */
10046 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
10047 store_reg(s
, rn
, addr
);
10049 tcg_temp_free_i32(addr
);
10051 } else if ((insn
& (1 << 23)) == 0) {
10052 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10053 * - load/store exclusive word
10057 if (!(insn
& (1 << 20)) &&
10058 arm_dc_feature(s
, ARM_FEATURE_M
) &&
10059 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10060 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10063 bool alt
= insn
& (1 << 7);
10064 TCGv_i32 addr
, op
, ttresp
;
10066 if ((insn
& 0x3f) || rd
== 13 || rd
== 15 || rn
== 15) {
10067 /* we UNDEF for these UNPREDICTABLE cases */
10071 if (alt
&& !s
->v8m_secure
) {
10075 addr
= load_reg(s
, rn
);
10076 op
= tcg_const_i32(extract32(insn
, 6, 2));
10077 ttresp
= tcg_temp_new_i32();
10078 gen_helper_v7m_tt(ttresp
, cpu_env
, addr
, op
);
10079 tcg_temp_free_i32(addr
);
10080 tcg_temp_free_i32(op
);
10081 store_reg(s
, rd
, ttresp
);
10086 addr
= tcg_temp_local_new_i32();
10087 load_reg_var(s
, addr
, rn
);
10088 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
10089 if (insn
& (1 << 20)) {
10090 gen_load_exclusive(s
, rs
, 15, addr
, 2);
10092 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
10094 tcg_temp_free_i32(addr
);
10095 } else if ((insn
& (7 << 5)) == 0) {
10096 /* Table Branch. */
10098 addr
= tcg_temp_new_i32();
10099 tcg_gen_movi_i32(addr
, s
->pc
);
10101 addr
= load_reg(s
, rn
);
10103 tmp
= load_reg(s
, rm
);
10104 tcg_gen_add_i32(addr
, addr
, tmp
);
10105 if (insn
& (1 << 4)) {
10107 tcg_gen_add_i32(addr
, addr
, tmp
);
10108 tcg_temp_free_i32(tmp
);
10109 tmp
= tcg_temp_new_i32();
10110 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
10112 tcg_temp_free_i32(tmp
);
10113 tmp
= tcg_temp_new_i32();
10114 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
10116 tcg_temp_free_i32(addr
);
10117 tcg_gen_shli_i32(tmp
, tmp
, 1);
10118 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
10119 store_reg(s
, 15, tmp
);
10121 int op2
= (insn
>> 6) & 0x3;
10122 op
= (insn
>> 4) & 0x3;
10127 /* Load/store exclusive byte/halfword/doubleword */
10134 /* Load-acquire/store-release */
10140 /* Load-acquire/store-release exclusive */
10144 addr
= tcg_temp_local_new_i32();
10145 load_reg_var(s
, addr
, rn
);
10147 if (insn
& (1 << 20)) {
10148 tmp
= tcg_temp_new_i32();
10151 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
10155 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
10159 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
10165 store_reg(s
, rs
, tmp
);
10167 tmp
= load_reg(s
, rs
);
10170 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
10174 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
10178 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
10184 tcg_temp_free_i32(tmp
);
10186 } else if (insn
& (1 << 20)) {
10187 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
10189 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
10191 tcg_temp_free_i32(addr
);
10194 /* Load/store multiple, RFE, SRS. */
10195 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
10196 /* RFE, SRS: not available in user mode or on M profile */
10197 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10200 if (insn
& (1 << 20)) {
10202 addr
= load_reg(s
, rn
);
10203 if ((insn
& (1 << 24)) == 0)
10204 tcg_gen_addi_i32(addr
, addr
, -8);
10205 /* Load PC into tmp and CPSR into tmp2. */
10206 tmp
= tcg_temp_new_i32();
10207 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10208 tcg_gen_addi_i32(addr
, addr
, 4);
10209 tmp2
= tcg_temp_new_i32();
10210 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
10211 if (insn
& (1 << 21)) {
10212 /* Base writeback. */
10213 if (insn
& (1 << 24)) {
10214 tcg_gen_addi_i32(addr
, addr
, 4);
10216 tcg_gen_addi_i32(addr
, addr
, -4);
10218 store_reg(s
, rn
, addr
);
10220 tcg_temp_free_i32(addr
);
10222 gen_rfe(s
, tmp
, tmp2
);
10225 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
10229 int i
, loaded_base
= 0;
10230 TCGv_i32 loaded_var
;
10231 /* Load/store multiple. */
10232 addr
= load_reg(s
, rn
);
10234 for (i
= 0; i
< 16; i
++) {
10235 if (insn
& (1 << i
))
10238 if (insn
& (1 << 24)) {
10239 tcg_gen_addi_i32(addr
, addr
, -offset
);
10243 for (i
= 0; i
< 16; i
++) {
10244 if ((insn
& (1 << i
)) == 0)
10246 if (insn
& (1 << 20)) {
10248 tmp
= tcg_temp_new_i32();
10249 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10251 gen_bx_excret(s
, tmp
);
10252 } else if (i
== rn
) {
10256 store_reg(s
, i
, tmp
);
10260 tmp
= load_reg(s
, i
);
10261 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10262 tcg_temp_free_i32(tmp
);
10264 tcg_gen_addi_i32(addr
, addr
, 4);
10267 store_reg(s
, rn
, loaded_var
);
10269 if (insn
& (1 << 21)) {
10270 /* Base register writeback. */
10271 if (insn
& (1 << 24)) {
10272 tcg_gen_addi_i32(addr
, addr
, -offset
);
10274 /* Fault if writeback register is in register list. */
10275 if (insn
& (1 << rn
))
10277 store_reg(s
, rn
, addr
);
10279 tcg_temp_free_i32(addr
);
10286 op
= (insn
>> 21) & 0xf;
10288 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10291 /* Halfword pack. */
10292 tmp
= load_reg(s
, rn
);
10293 tmp2
= load_reg(s
, rm
);
10294 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
10295 if (insn
& (1 << 5)) {
10299 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
10300 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
10301 tcg_gen_ext16u_i32(tmp2
, tmp2
);
10305 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10306 tcg_gen_ext16u_i32(tmp
, tmp
);
10307 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10309 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10310 tcg_temp_free_i32(tmp2
);
10311 store_reg(s
, rd
, tmp
);
10313 /* Data processing register constant shift. */
10315 tmp
= tcg_temp_new_i32();
10316 tcg_gen_movi_i32(tmp
, 0);
10318 tmp
= load_reg(s
, rn
);
10320 tmp2
= load_reg(s
, rm
);
10322 shiftop
= (insn
>> 4) & 3;
10323 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10324 conds
= (insn
& (1 << 20)) != 0;
10325 logic_cc
= (conds
&& thumb2_logic_op(op
));
10326 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10327 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10329 tcg_temp_free_i32(tmp2
);
10331 store_reg(s
, rd
, tmp
);
10333 tcg_temp_free_i32(tmp
);
10337 case 13: /* Misc data processing. */
10338 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10339 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10342 case 0: /* Register controlled shift. */
10343 tmp
= load_reg(s
, rn
);
10344 tmp2
= load_reg(s
, rm
);
10345 if ((insn
& 0x70) != 0)
10347 op
= (insn
>> 21) & 3;
10348 logic_cc
= (insn
& (1 << 20)) != 0;
10349 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10352 store_reg(s
, rd
, tmp
);
10354 case 1: /* Sign/zero extend. */
10355 op
= (insn
>> 20) & 7;
10357 case 0: /* SXTAH, SXTH */
10358 case 1: /* UXTAH, UXTH */
10359 case 4: /* SXTAB, SXTB */
10360 case 5: /* UXTAB, UXTB */
10362 case 2: /* SXTAB16, SXTB16 */
10363 case 3: /* UXTAB16, UXTB16 */
10364 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10372 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10376 tmp
= load_reg(s
, rm
);
10377 shift
= (insn
>> 4) & 3;
10378 /* ??? In many cases it's not necessary to do a
10379 rotate, a shift is sufficient. */
10381 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10382 op
= (insn
>> 20) & 7;
10384 case 0: gen_sxth(tmp
); break;
10385 case 1: gen_uxth(tmp
); break;
10386 case 2: gen_sxtb16(tmp
); break;
10387 case 3: gen_uxtb16(tmp
); break;
10388 case 4: gen_sxtb(tmp
); break;
10389 case 5: gen_uxtb(tmp
); break;
10391 g_assert_not_reached();
10394 tmp2
= load_reg(s
, rn
);
10395 if ((op
>> 1) == 1) {
10396 gen_add16(tmp
, tmp2
);
10398 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10399 tcg_temp_free_i32(tmp2
);
10402 store_reg(s
, rd
, tmp
);
10404 case 2: /* SIMD add/subtract. */
10405 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10408 op
= (insn
>> 20) & 7;
10409 shift
= (insn
>> 4) & 7;
10410 if ((op
& 3) == 3 || (shift
& 3) == 3)
10412 tmp
= load_reg(s
, rn
);
10413 tmp2
= load_reg(s
, rm
);
10414 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10415 tcg_temp_free_i32(tmp2
);
10416 store_reg(s
, rd
, tmp
);
10418 case 3: /* Other data processing. */
10419 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10421 /* Saturating add/subtract. */
10422 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10425 tmp
= load_reg(s
, rn
);
10426 tmp2
= load_reg(s
, rm
);
10428 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10430 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10432 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10433 tcg_temp_free_i32(tmp2
);
10436 case 0x0a: /* rbit */
10437 case 0x08: /* rev */
10438 case 0x09: /* rev16 */
10439 case 0x0b: /* revsh */
10440 case 0x18: /* clz */
10442 case 0x10: /* sel */
10443 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10447 case 0x20: /* crc32/crc32c */
10453 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10460 tmp
= load_reg(s
, rn
);
10462 case 0x0a: /* rbit */
10463 gen_helper_rbit(tmp
, tmp
);
10465 case 0x08: /* rev */
10466 tcg_gen_bswap32_i32(tmp
, tmp
);
10468 case 0x09: /* rev16 */
10471 case 0x0b: /* revsh */
10474 case 0x10: /* sel */
10475 tmp2
= load_reg(s
, rm
);
10476 tmp3
= tcg_temp_new_i32();
10477 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10478 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10479 tcg_temp_free_i32(tmp3
);
10480 tcg_temp_free_i32(tmp2
);
10482 case 0x18: /* clz */
10483 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10493 uint32_t sz
= op
& 0x3;
10494 uint32_t c
= op
& 0x8;
10496 tmp2
= load_reg(s
, rm
);
10498 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10499 } else if (sz
== 1) {
10500 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10502 tmp3
= tcg_const_i32(1 << sz
);
10504 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10506 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10508 tcg_temp_free_i32(tmp2
);
10509 tcg_temp_free_i32(tmp3
);
10513 g_assert_not_reached();
10516 store_reg(s
, rd
, tmp
);
10518 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10519 switch ((insn
>> 20) & 7) {
10520 case 0: /* 32 x 32 -> 32 */
10521 case 7: /* Unsigned sum of absolute differences. */
10523 case 1: /* 16 x 16 -> 32 */
10524 case 2: /* Dual multiply add. */
10525 case 3: /* 32 * 16 -> 32msb */
10526 case 4: /* Dual multiply subtract. */
10527 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10528 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10533 op
= (insn
>> 4) & 0xf;
10534 tmp
= load_reg(s
, rn
);
10535 tmp2
= load_reg(s
, rm
);
10536 switch ((insn
>> 20) & 7) {
10537 case 0: /* 32 x 32 -> 32 */
10538 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10539 tcg_temp_free_i32(tmp2
);
10541 tmp2
= load_reg(s
, rs
);
10543 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10545 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10546 tcg_temp_free_i32(tmp2
);
10549 case 1: /* 16 x 16 -> 32 */
10550 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10551 tcg_temp_free_i32(tmp2
);
10553 tmp2
= load_reg(s
, rs
);
10554 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10555 tcg_temp_free_i32(tmp2
);
10558 case 2: /* Dual multiply add. */
10559 case 4: /* Dual multiply subtract. */
10561 gen_swap_half(tmp2
);
10562 gen_smul_dual(tmp
, tmp2
);
10563 if (insn
& (1 << 22)) {
10564 /* This subtraction cannot overflow. */
10565 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10567 /* This addition cannot overflow 32 bits;
10568 * however it may overflow considered as a signed
10569 * operation, in which case we must set the Q flag.
10571 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10573 tcg_temp_free_i32(tmp2
);
10576 tmp2
= load_reg(s
, rs
);
10577 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10578 tcg_temp_free_i32(tmp2
);
10581 case 3: /* 32 * 16 -> 32msb */
10583 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10586 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10587 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10588 tmp
= tcg_temp_new_i32();
10589 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10590 tcg_temp_free_i64(tmp64
);
10593 tmp2
= load_reg(s
, rs
);
10594 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10595 tcg_temp_free_i32(tmp2
);
10598 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10599 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10601 tmp
= load_reg(s
, rs
);
10602 if (insn
& (1 << 20)) {
10603 tmp64
= gen_addq_msw(tmp64
, tmp
);
10605 tmp64
= gen_subq_msw(tmp64
, tmp
);
10608 if (insn
& (1 << 4)) {
10609 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10611 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10612 tmp
= tcg_temp_new_i32();
10613 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10614 tcg_temp_free_i64(tmp64
);
10616 case 7: /* Unsigned sum of absolute differences. */
10617 gen_helper_usad8(tmp
, tmp
, tmp2
);
10618 tcg_temp_free_i32(tmp2
);
10620 tmp2
= load_reg(s
, rs
);
10621 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10622 tcg_temp_free_i32(tmp2
);
10626 store_reg(s
, rd
, tmp
);
10628 case 6: case 7: /* 64-bit multiply, Divide. */
10629 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10630 tmp
= load_reg(s
, rn
);
10631 tmp2
= load_reg(s
, rm
);
10632 if ((op
& 0x50) == 0x10) {
10634 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10638 gen_helper_udiv(tmp
, tmp
, tmp2
);
10640 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10641 tcg_temp_free_i32(tmp2
);
10642 store_reg(s
, rd
, tmp
);
10643 } else if ((op
& 0xe) == 0xc) {
10644 /* Dual multiply accumulate long. */
10645 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10646 tcg_temp_free_i32(tmp
);
10647 tcg_temp_free_i32(tmp2
);
10651 gen_swap_half(tmp2
);
10652 gen_smul_dual(tmp
, tmp2
);
10654 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10656 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10658 tcg_temp_free_i32(tmp2
);
10660 tmp64
= tcg_temp_new_i64();
10661 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10662 tcg_temp_free_i32(tmp
);
10663 gen_addq(s
, tmp64
, rs
, rd
);
10664 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10665 tcg_temp_free_i64(tmp64
);
10668 /* Unsigned 64-bit multiply */
10669 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10673 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10674 tcg_temp_free_i32(tmp2
);
10675 tcg_temp_free_i32(tmp
);
10678 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10679 tcg_temp_free_i32(tmp2
);
10680 tmp64
= tcg_temp_new_i64();
10681 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10682 tcg_temp_free_i32(tmp
);
10684 /* Signed 64-bit multiply */
10685 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10690 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10691 tcg_temp_free_i64(tmp64
);
10694 gen_addq_lo(s
, tmp64
, rs
);
10695 gen_addq_lo(s
, tmp64
, rd
);
10696 } else if (op
& 0x40) {
10697 /* 64-bit accumulate. */
10698 gen_addq(s
, tmp64
, rs
, rd
);
10700 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10701 tcg_temp_free_i64(tmp64
);
10706 case 6: case 7: case 14: case 15:
10708 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10709 /* We don't currently implement M profile FP support,
10710 * so this entire space should give a NOCP fault.
10712 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10713 default_exception_el(s
));
10716 if (((insn
>> 24) & 3) == 3) {
10717 /* Translate into the equivalent ARM encoding. */
10718 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10719 if (disas_neon_data_insn(s
, insn
)) {
10722 } else if (((insn
>> 8) & 0xe) == 10) {
10723 if (disas_vfp_insn(s
, insn
)) {
10727 if (insn
& (1 << 28))
10729 if (disas_coproc_insn(s
, insn
)) {
10734 case 8: case 9: case 10: case 11:
10735 if (insn
& (1 << 15)) {
10736 /* Branches, misc control. */
10737 if (insn
& 0x5000) {
10738 /* Unconditional branch. */
10739 /* signextend(hw1[10:0]) -> offset[:12]. */
10740 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10741 /* hw1[10:0] -> offset[11:1]. */
10742 offset
|= (insn
& 0x7ff) << 1;
10743 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10744 offset[24:22] already have the same value because of the
10745 sign extension above. */
10746 offset
^= ((~insn
) & (1 << 13)) << 10;
10747 offset
^= ((~insn
) & (1 << 11)) << 11;
10749 if (insn
& (1 << 14)) {
10750 /* Branch and link. */
10751 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10755 if (insn
& (1 << 12)) {
10757 gen_jmp(s
, offset
);
10760 offset
&= ~(uint32_t)2;
10761 /* thumb2 bx, no need to check */
10762 gen_bx_im(s
, offset
);
10764 } else if (((insn
>> 23) & 7) == 7) {
10766 if (insn
& (1 << 13))
10769 if (insn
& (1 << 26)) {
10770 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10773 if (!(insn
& (1 << 20))) {
10774 /* Hypervisor call (v7) */
10775 int imm16
= extract32(insn
, 16, 4) << 12
10776 | extract32(insn
, 0, 12);
10783 /* Secure monitor call (v6+) */
10791 op
= (insn
>> 20) & 7;
10793 case 0: /* msr cpsr. */
10794 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10795 tmp
= load_reg(s
, rn
);
10796 /* the constant is the mask and SYSm fields */
10797 addr
= tcg_const_i32(insn
& 0xfff);
10798 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10799 tcg_temp_free_i32(addr
);
10800 tcg_temp_free_i32(tmp
);
10805 case 1: /* msr spsr. */
10806 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10810 if (extract32(insn
, 5, 1)) {
10812 int sysm
= extract32(insn
, 8, 4) |
10813 (extract32(insn
, 4, 1) << 4);
10816 gen_msr_banked(s
, r
, sysm
, rm
);
10820 /* MSR (for PSRs) */
10821 tmp
= load_reg(s
, rn
);
10823 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10827 case 2: /* cps, nop-hint. */
10828 if (((insn
>> 8) & 7) == 0) {
10829 gen_nop_hint(s
, insn
& 0xff);
10831 /* Implemented as NOP in user mode. */
10836 if (insn
& (1 << 10)) {
10837 if (insn
& (1 << 7))
10839 if (insn
& (1 << 6))
10841 if (insn
& (1 << 5))
10843 if (insn
& (1 << 9))
10844 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10846 if (insn
& (1 << 8)) {
10848 imm
|= (insn
& 0x1f);
10851 gen_set_psr_im(s
, offset
, 0, imm
);
10854 case 3: /* Special control operations. */
10856 op
= (insn
>> 4) & 0xf;
10858 case 2: /* clrex */
10863 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10866 /* We need to break the TB after this insn
10867 * to execute self-modifying code correctly
10868 * and also to take any pending interrupts
10871 gen_goto_tb(s
, 0, s
->pc
& ~1);
10878 /* Trivial implementation equivalent to bx.
10879 * This instruction doesn't exist at all for M-profile.
10881 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10884 tmp
= load_reg(s
, rn
);
10887 case 5: /* Exception return. */
10891 if (rn
!= 14 || rd
!= 15) {
10894 tmp
= load_reg(s
, rn
);
10895 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10896 gen_exception_return(s
, tmp
);
10899 if (extract32(insn
, 5, 1) &&
10900 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10902 int sysm
= extract32(insn
, 16, 4) |
10903 (extract32(insn
, 4, 1) << 4);
10905 gen_mrs_banked(s
, 0, sysm
, rd
);
10909 if (extract32(insn
, 16, 4) != 0xf) {
10912 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10913 extract32(insn
, 0, 8) != 0) {
10918 tmp
= tcg_temp_new_i32();
10919 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10920 addr
= tcg_const_i32(insn
& 0xff);
10921 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10922 tcg_temp_free_i32(addr
);
10924 gen_helper_cpsr_read(tmp
, cpu_env
);
10926 store_reg(s
, rd
, tmp
);
10929 if (extract32(insn
, 5, 1) &&
10930 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10932 int sysm
= extract32(insn
, 16, 4) |
10933 (extract32(insn
, 4, 1) << 4);
10935 gen_mrs_banked(s
, 1, sysm
, rd
);
10940 /* Not accessible in user mode. */
10941 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10945 if (extract32(insn
, 16, 4) != 0xf ||
10946 extract32(insn
, 0, 8) != 0) {
10950 tmp
= load_cpu_field(spsr
);
10951 store_reg(s
, rd
, tmp
);
10956 /* Conditional branch. */
10957 op
= (insn
>> 22) & 0xf;
10958 /* Generate a conditional jump to next instruction. */
10959 s
->condlabel
= gen_new_label();
10960 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10963 /* offset[11:1] = insn[10:0] */
10964 offset
= (insn
& 0x7ff) << 1;
10965 /* offset[17:12] = insn[21:16]. */
10966 offset
|= (insn
& 0x003f0000) >> 4;
10967 /* offset[31:20] = insn[26]. */
10968 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10969 /* offset[18] = insn[13]. */
10970 offset
|= (insn
& (1 << 13)) << 5;
10971 /* offset[19] = insn[11]. */
10972 offset
|= (insn
& (1 << 11)) << 8;
10974 /* jump to the offset */
10975 gen_jmp(s
, s
->pc
+ offset
);
10978 /* Data processing immediate. */
10979 if (insn
& (1 << 25)) {
10980 if (insn
& (1 << 24)) {
10981 if (insn
& (1 << 20))
10983 /* Bitfield/Saturate. */
10984 op
= (insn
>> 21) & 7;
10986 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10988 tmp
= tcg_temp_new_i32();
10989 tcg_gen_movi_i32(tmp
, 0);
10991 tmp
= load_reg(s
, rn
);
10994 case 2: /* Signed bitfield extract. */
10996 if (shift
+ imm
> 32)
10999 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
11002 case 6: /* Unsigned bitfield extract. */
11004 if (shift
+ imm
> 32)
11007 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
11010 case 3: /* Bitfield insert/clear. */
11013 imm
= imm
+ 1 - shift
;
11015 tmp2
= load_reg(s
, rd
);
11016 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
11017 tcg_temp_free_i32(tmp2
);
11022 default: /* Saturate. */
11025 tcg_gen_sari_i32(tmp
, tmp
, shift
);
11027 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11029 tmp2
= tcg_const_i32(imm
);
11032 if ((op
& 1) && shift
== 0) {
11033 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11034 tcg_temp_free_i32(tmp
);
11035 tcg_temp_free_i32(tmp2
);
11038 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
11040 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
11044 if ((op
& 1) && shift
== 0) {
11045 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
11046 tcg_temp_free_i32(tmp
);
11047 tcg_temp_free_i32(tmp2
);
11050 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
11052 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
11055 tcg_temp_free_i32(tmp2
);
11058 store_reg(s
, rd
, tmp
);
11060 imm
= ((insn
& 0x04000000) >> 15)
11061 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
11062 if (insn
& (1 << 22)) {
11063 /* 16-bit immediate. */
11064 imm
|= (insn
>> 4) & 0xf000;
11065 if (insn
& (1 << 23)) {
11067 tmp
= load_reg(s
, rd
);
11068 tcg_gen_ext16u_i32(tmp
, tmp
);
11069 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
11072 tmp
= tcg_temp_new_i32();
11073 tcg_gen_movi_i32(tmp
, imm
);
11076 /* Add/sub 12-bit immediate. */
11078 offset
= s
->pc
& ~(uint32_t)3;
11079 if (insn
& (1 << 23))
11083 tmp
= tcg_temp_new_i32();
11084 tcg_gen_movi_i32(tmp
, offset
);
11086 tmp
= load_reg(s
, rn
);
11087 if (insn
& (1 << 23))
11088 tcg_gen_subi_i32(tmp
, tmp
, imm
);
11090 tcg_gen_addi_i32(tmp
, tmp
, imm
);
11093 store_reg(s
, rd
, tmp
);
11096 int shifter_out
= 0;
11097 /* modified 12-bit immediate. */
11098 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
11099 imm
= (insn
& 0xff);
11102 /* Nothing to do. */
11104 case 1: /* 00XY00XY */
11107 case 2: /* XY00XY00 */
11111 case 3: /* XYXYXYXY */
11115 default: /* Rotated constant. */
11116 shift
= (shift
<< 1) | (imm
>> 7);
11118 imm
= imm
<< (32 - shift
);
11122 tmp2
= tcg_temp_new_i32();
11123 tcg_gen_movi_i32(tmp2
, imm
);
11124 rn
= (insn
>> 16) & 0xf;
11126 tmp
= tcg_temp_new_i32();
11127 tcg_gen_movi_i32(tmp
, 0);
11129 tmp
= load_reg(s
, rn
);
11131 op
= (insn
>> 21) & 0xf;
11132 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
11133 shifter_out
, tmp
, tmp2
))
11135 tcg_temp_free_i32(tmp2
);
11136 rd
= (insn
>> 8) & 0xf;
11138 store_reg(s
, rd
, tmp
);
11140 tcg_temp_free_i32(tmp
);
11145 case 12: /* Load/store single data item. */
11152 if ((insn
& 0x01100000) == 0x01000000) {
11153 if (disas_neon_ls_insn(s
, insn
)) {
11158 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
11160 if (!(insn
& (1 << 20))) {
11164 /* Byte or halfword load space with dest == r15 : memory hints.
11165 * Catch them early so we don't emit pointless addressing code.
11166 * This space is a mix of:
11167 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11168 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11170 * unallocated hints, which must be treated as NOPs
11171 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11172 * which is easiest for the decoding logic
11173 * Some space which must UNDEF
11175 int op1
= (insn
>> 23) & 3;
11176 int op2
= (insn
>> 6) & 0x3f;
11181 /* UNPREDICTABLE, unallocated hint or
11182 * PLD/PLDW/PLI (literal)
11187 return; /* PLD/PLDW/PLI or unallocated hint */
11189 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
11190 return; /* PLD/PLDW/PLI or unallocated hint */
11192 /* UNDEF space, or an UNPREDICTABLE */
11196 memidx
= get_mem_index(s
);
11198 addr
= tcg_temp_new_i32();
11200 /* s->pc has already been incremented by 4. */
11201 imm
= s
->pc
& 0xfffffffc;
11202 if (insn
& (1 << 23))
11203 imm
+= insn
& 0xfff;
11205 imm
-= insn
& 0xfff;
11206 tcg_gen_movi_i32(addr
, imm
);
11208 addr
= load_reg(s
, rn
);
11209 if (insn
& (1 << 23)) {
11210 /* Positive offset. */
11211 imm
= insn
& 0xfff;
11212 tcg_gen_addi_i32(addr
, addr
, imm
);
11215 switch ((insn
>> 8) & 0xf) {
11216 case 0x0: /* Shifted Register. */
11217 shift
= (insn
>> 4) & 0xf;
11219 tcg_temp_free_i32(addr
);
11222 tmp
= load_reg(s
, rm
);
11224 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11225 tcg_gen_add_i32(addr
, addr
, tmp
);
11226 tcg_temp_free_i32(tmp
);
11228 case 0xc: /* Negative offset. */
11229 tcg_gen_addi_i32(addr
, addr
, -imm
);
11231 case 0xe: /* User privilege. */
11232 tcg_gen_addi_i32(addr
, addr
, imm
);
11233 memidx
= get_a32_user_mem_index(s
);
11235 case 0x9: /* Post-decrement. */
11237 /* Fall through. */
11238 case 0xb: /* Post-increment. */
11242 case 0xd: /* Pre-decrement. */
11244 /* Fall through. */
11245 case 0xf: /* Pre-increment. */
11246 tcg_gen_addi_i32(addr
, addr
, imm
);
11250 tcg_temp_free_i32(addr
);
11256 issinfo
= writeback
? ISSInvalid
: rs
;
11258 if (insn
& (1 << 20)) {
11260 tmp
= tcg_temp_new_i32();
11263 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11266 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11269 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11272 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11275 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11278 tcg_temp_free_i32(tmp
);
11279 tcg_temp_free_i32(addr
);
11283 gen_bx_excret(s
, tmp
);
11285 store_reg(s
, rs
, tmp
);
11289 tmp
= load_reg(s
, rs
);
11292 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
11295 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
11298 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
11301 tcg_temp_free_i32(tmp
);
11302 tcg_temp_free_i32(addr
);
11305 tcg_temp_free_i32(tmp
);
11308 tcg_gen_addi_i32(addr
, addr
, imm
);
11310 store_reg(s
, rn
, addr
);
11312 tcg_temp_free_i32(addr
);
11321 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11322 default_exception_el(s
));
11325 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
11327 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
11334 switch (insn
>> 12) {
11338 op
= (insn
>> 11) & 3;
11341 rn
= (insn
>> 3) & 7;
11342 tmp
= load_reg(s
, rn
);
11343 if (insn
& (1 << 10)) {
11345 tmp2
= tcg_temp_new_i32();
11346 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11349 rm
= (insn
>> 6) & 7;
11350 tmp2
= load_reg(s
, rm
);
11352 if (insn
& (1 << 9)) {
11353 if (s
->condexec_mask
)
11354 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11356 gen_sub_CC(tmp
, tmp
, tmp2
);
11358 if (s
->condexec_mask
)
11359 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11361 gen_add_CC(tmp
, tmp
, tmp2
);
11363 tcg_temp_free_i32(tmp2
);
11364 store_reg(s
, rd
, tmp
);
11366 /* shift immediate */
11367 rm
= (insn
>> 3) & 7;
11368 shift
= (insn
>> 6) & 0x1f;
11369 tmp
= load_reg(s
, rm
);
11370 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11371 if (!s
->condexec_mask
)
11373 store_reg(s
, rd
, tmp
);
11377 /* arithmetic large immediate */
11378 op
= (insn
>> 11) & 3;
11379 rd
= (insn
>> 8) & 0x7;
11380 if (op
== 0) { /* mov */
11381 tmp
= tcg_temp_new_i32();
11382 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11383 if (!s
->condexec_mask
)
11385 store_reg(s
, rd
, tmp
);
11387 tmp
= load_reg(s
, rd
);
11388 tmp2
= tcg_temp_new_i32();
11389 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11392 gen_sub_CC(tmp
, tmp
, tmp2
);
11393 tcg_temp_free_i32(tmp
);
11394 tcg_temp_free_i32(tmp2
);
11397 if (s
->condexec_mask
)
11398 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11400 gen_add_CC(tmp
, tmp
, tmp2
);
11401 tcg_temp_free_i32(tmp2
);
11402 store_reg(s
, rd
, tmp
);
11405 if (s
->condexec_mask
)
11406 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11408 gen_sub_CC(tmp
, tmp
, tmp2
);
11409 tcg_temp_free_i32(tmp2
);
11410 store_reg(s
, rd
, tmp
);
11416 if (insn
& (1 << 11)) {
11417 rd
= (insn
>> 8) & 7;
11418 /* load pc-relative. Bit 1 of PC is ignored. */
11419 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11420 val
&= ~(uint32_t)2;
11421 addr
= tcg_temp_new_i32();
11422 tcg_gen_movi_i32(addr
, val
);
11423 tmp
= tcg_temp_new_i32();
11424 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11426 tcg_temp_free_i32(addr
);
11427 store_reg(s
, rd
, tmp
);
11430 if (insn
& (1 << 10)) {
11431 /* 0b0100_01xx_xxxx_xxxx
11432 * - data processing extended, branch and exchange
11434 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11435 rm
= (insn
>> 3) & 0xf;
11436 op
= (insn
>> 8) & 3;
11439 tmp
= load_reg(s
, rd
);
11440 tmp2
= load_reg(s
, rm
);
11441 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11442 tcg_temp_free_i32(tmp2
);
11443 store_reg(s
, rd
, tmp
);
11446 tmp
= load_reg(s
, rd
);
11447 tmp2
= load_reg(s
, rm
);
11448 gen_sub_CC(tmp
, tmp
, tmp2
);
11449 tcg_temp_free_i32(tmp2
);
11450 tcg_temp_free_i32(tmp
);
11452 case 2: /* mov/cpy */
11453 tmp
= load_reg(s
, rm
);
11454 store_reg(s
, rd
, tmp
);
11458 /* 0b0100_0111_xxxx_xxxx
11459 * - branch [and link] exchange thumb register
11461 bool link
= insn
& (1 << 7);
11470 /* BXNS/BLXNS: only exists for v8M with the
11471 * security extensions, and always UNDEF if NonSecure.
11472 * We don't implement these in the user-only mode
11473 * either (in theory you can use them from Secure User
11474 * mode but they are too tied in to system emulation.)
11476 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
11487 tmp
= load_reg(s
, rm
);
11489 val
= (uint32_t)s
->pc
| 1;
11490 tmp2
= tcg_temp_new_i32();
11491 tcg_gen_movi_i32(tmp2
, val
);
11492 store_reg(s
, 14, tmp2
);
11495 /* Only BX works as exception-return, not BLX */
11496 gen_bx_excret(s
, tmp
);
11504 /* data processing register */
11506 rm
= (insn
>> 3) & 7;
11507 op
= (insn
>> 6) & 0xf;
11508 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11509 /* the shift/rotate ops want the operands backwards */
11518 if (op
== 9) { /* neg */
11519 tmp
= tcg_temp_new_i32();
11520 tcg_gen_movi_i32(tmp
, 0);
11521 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11522 tmp
= load_reg(s
, rd
);
11527 tmp2
= load_reg(s
, rm
);
11529 case 0x0: /* and */
11530 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11531 if (!s
->condexec_mask
)
11534 case 0x1: /* eor */
11535 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11536 if (!s
->condexec_mask
)
11539 case 0x2: /* lsl */
11540 if (s
->condexec_mask
) {
11541 gen_shl(tmp2
, tmp2
, tmp
);
11543 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11544 gen_logic_CC(tmp2
);
11547 case 0x3: /* lsr */
11548 if (s
->condexec_mask
) {
11549 gen_shr(tmp2
, tmp2
, tmp
);
11551 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11552 gen_logic_CC(tmp2
);
11555 case 0x4: /* asr */
11556 if (s
->condexec_mask
) {
11557 gen_sar(tmp2
, tmp2
, tmp
);
11559 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11560 gen_logic_CC(tmp2
);
11563 case 0x5: /* adc */
11564 if (s
->condexec_mask
) {
11565 gen_adc(tmp
, tmp2
);
11567 gen_adc_CC(tmp
, tmp
, tmp2
);
11570 case 0x6: /* sbc */
11571 if (s
->condexec_mask
) {
11572 gen_sub_carry(tmp
, tmp
, tmp2
);
11574 gen_sbc_CC(tmp
, tmp
, tmp2
);
11577 case 0x7: /* ror */
11578 if (s
->condexec_mask
) {
11579 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11580 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11582 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11583 gen_logic_CC(tmp2
);
11586 case 0x8: /* tst */
11587 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11591 case 0x9: /* neg */
11592 if (s
->condexec_mask
)
11593 tcg_gen_neg_i32(tmp
, tmp2
);
11595 gen_sub_CC(tmp
, tmp
, tmp2
);
11597 case 0xa: /* cmp */
11598 gen_sub_CC(tmp
, tmp
, tmp2
);
11601 case 0xb: /* cmn */
11602 gen_add_CC(tmp
, tmp
, tmp2
);
11605 case 0xc: /* orr */
11606 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11607 if (!s
->condexec_mask
)
11610 case 0xd: /* mul */
11611 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11612 if (!s
->condexec_mask
)
11615 case 0xe: /* bic */
11616 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11617 if (!s
->condexec_mask
)
11620 case 0xf: /* mvn */
11621 tcg_gen_not_i32(tmp2
, tmp2
);
11622 if (!s
->condexec_mask
)
11623 gen_logic_CC(tmp2
);
11630 store_reg(s
, rm
, tmp2
);
11632 tcg_temp_free_i32(tmp
);
11634 store_reg(s
, rd
, tmp
);
11635 tcg_temp_free_i32(tmp2
);
11638 tcg_temp_free_i32(tmp
);
11639 tcg_temp_free_i32(tmp2
);
11644 /* load/store register offset. */
11646 rn
= (insn
>> 3) & 7;
11647 rm
= (insn
>> 6) & 7;
11648 op
= (insn
>> 9) & 7;
11649 addr
= load_reg(s
, rn
);
11650 tmp
= load_reg(s
, rm
);
11651 tcg_gen_add_i32(addr
, addr
, tmp
);
11652 tcg_temp_free_i32(tmp
);
11654 if (op
< 3) { /* store */
11655 tmp
= load_reg(s
, rd
);
11657 tmp
= tcg_temp_new_i32();
11662 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11665 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11668 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11670 case 3: /* ldrsb */
11671 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11674 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11677 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11680 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11682 case 7: /* ldrsh */
11683 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11686 if (op
>= 3) { /* load */
11687 store_reg(s
, rd
, tmp
);
11689 tcg_temp_free_i32(tmp
);
11691 tcg_temp_free_i32(addr
);
11695 /* load/store word immediate offset */
11697 rn
= (insn
>> 3) & 7;
11698 addr
= load_reg(s
, rn
);
11699 val
= (insn
>> 4) & 0x7c;
11700 tcg_gen_addi_i32(addr
, addr
, val
);
11702 if (insn
& (1 << 11)) {
11704 tmp
= tcg_temp_new_i32();
11705 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11706 store_reg(s
, rd
, tmp
);
11709 tmp
= load_reg(s
, rd
);
11710 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11711 tcg_temp_free_i32(tmp
);
11713 tcg_temp_free_i32(addr
);
11717 /* load/store byte immediate offset */
11719 rn
= (insn
>> 3) & 7;
11720 addr
= load_reg(s
, rn
);
11721 val
= (insn
>> 6) & 0x1f;
11722 tcg_gen_addi_i32(addr
, addr
, val
);
11724 if (insn
& (1 << 11)) {
11726 tmp
= tcg_temp_new_i32();
11727 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11728 store_reg(s
, rd
, tmp
);
11731 tmp
= load_reg(s
, rd
);
11732 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11733 tcg_temp_free_i32(tmp
);
11735 tcg_temp_free_i32(addr
);
11739 /* load/store halfword immediate offset */
11741 rn
= (insn
>> 3) & 7;
11742 addr
= load_reg(s
, rn
);
11743 val
= (insn
>> 5) & 0x3e;
11744 tcg_gen_addi_i32(addr
, addr
, val
);
11746 if (insn
& (1 << 11)) {
11748 tmp
= tcg_temp_new_i32();
11749 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11750 store_reg(s
, rd
, tmp
);
11753 tmp
= load_reg(s
, rd
);
11754 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11755 tcg_temp_free_i32(tmp
);
11757 tcg_temp_free_i32(addr
);
11761 /* load/store from stack */
11762 rd
= (insn
>> 8) & 7;
11763 addr
= load_reg(s
, 13);
11764 val
= (insn
& 0xff) * 4;
11765 tcg_gen_addi_i32(addr
, addr
, val
);
11767 if (insn
& (1 << 11)) {
11769 tmp
= tcg_temp_new_i32();
11770 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11771 store_reg(s
, rd
, tmp
);
11774 tmp
= load_reg(s
, rd
);
11775 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11776 tcg_temp_free_i32(tmp
);
11778 tcg_temp_free_i32(addr
);
11782 /* add to high reg */
11783 rd
= (insn
>> 8) & 7;
11784 if (insn
& (1 << 11)) {
11786 tmp
= load_reg(s
, 13);
11788 /* PC. bit 1 is ignored. */
11789 tmp
= tcg_temp_new_i32();
11790 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11792 val
= (insn
& 0xff) * 4;
11793 tcg_gen_addi_i32(tmp
, tmp
, val
);
11794 store_reg(s
, rd
, tmp
);
11799 op
= (insn
>> 8) & 0xf;
11802 /* adjust stack pointer */
11803 tmp
= load_reg(s
, 13);
11804 val
= (insn
& 0x7f) * 4;
11805 if (insn
& (1 << 7))
11806 val
= -(int32_t)val
;
11807 tcg_gen_addi_i32(tmp
, tmp
, val
);
11808 store_reg(s
, 13, tmp
);
11811 case 2: /* sign/zero extend. */
11814 rm
= (insn
>> 3) & 7;
11815 tmp
= load_reg(s
, rm
);
11816 switch ((insn
>> 6) & 3) {
11817 case 0: gen_sxth(tmp
); break;
11818 case 1: gen_sxtb(tmp
); break;
11819 case 2: gen_uxth(tmp
); break;
11820 case 3: gen_uxtb(tmp
); break;
11822 store_reg(s
, rd
, tmp
);
11824 case 4: case 5: case 0xc: case 0xd:
11826 addr
= load_reg(s
, 13);
11827 if (insn
& (1 << 8))
11831 for (i
= 0; i
< 8; i
++) {
11832 if (insn
& (1 << i
))
11835 if ((insn
& (1 << 11)) == 0) {
11836 tcg_gen_addi_i32(addr
, addr
, -offset
);
11838 for (i
= 0; i
< 8; i
++) {
11839 if (insn
& (1 << i
)) {
11840 if (insn
& (1 << 11)) {
11842 tmp
= tcg_temp_new_i32();
11843 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11844 store_reg(s
, i
, tmp
);
11847 tmp
= load_reg(s
, i
);
11848 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11849 tcg_temp_free_i32(tmp
);
11851 /* advance to the next address. */
11852 tcg_gen_addi_i32(addr
, addr
, 4);
11856 if (insn
& (1 << 8)) {
11857 if (insn
& (1 << 11)) {
11859 tmp
= tcg_temp_new_i32();
11860 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11861 /* don't set the pc until the rest of the instruction
11865 tmp
= load_reg(s
, 14);
11866 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11867 tcg_temp_free_i32(tmp
);
11869 tcg_gen_addi_i32(addr
, addr
, 4);
11871 if ((insn
& (1 << 11)) == 0) {
11872 tcg_gen_addi_i32(addr
, addr
, -offset
);
11874 /* write back the new stack pointer */
11875 store_reg(s
, 13, addr
);
11876 /* set the new PC value */
11877 if ((insn
& 0x0900) == 0x0900) {
11878 store_reg_from_load(s
, 15, tmp
);
11882 case 1: case 3: case 9: case 11: /* czb */
11884 tmp
= load_reg(s
, rm
);
11885 s
->condlabel
= gen_new_label();
11887 if (insn
& (1 << 11))
11888 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11890 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11891 tcg_temp_free_i32(tmp
);
11892 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11893 val
= (uint32_t)s
->pc
+ 2;
11898 case 15: /* IT, nop-hint. */
11899 if ((insn
& 0xf) == 0) {
11900 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11904 s
->condexec_cond
= (insn
>> 4) & 0xe;
11905 s
->condexec_mask
= insn
& 0x1f;
11906 /* No actual code generated for this insn, just setup state. */
11909 case 0xe: /* bkpt */
11911 int imm8
= extract32(insn
, 0, 8);
11913 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11914 default_exception_el(s
));
11918 case 0xa: /* rev, and hlt */
11920 int op1
= extract32(insn
, 6, 2);
11924 int imm6
= extract32(insn
, 0, 6);
11930 /* Otherwise this is rev */
11932 rn
= (insn
>> 3) & 0x7;
11934 tmp
= load_reg(s
, rn
);
11936 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11937 case 1: gen_rev16(tmp
); break;
11938 case 3: gen_revsh(tmp
); break;
11940 g_assert_not_reached();
11942 store_reg(s
, rd
, tmp
);
11947 switch ((insn
>> 5) & 7) {
11951 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11952 gen_helper_setend(cpu_env
);
11953 s
->base
.is_jmp
= DISAS_UPDATE
;
11962 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11963 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11966 addr
= tcg_const_i32(19);
11967 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11968 tcg_temp_free_i32(addr
);
11972 addr
= tcg_const_i32(16);
11973 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11974 tcg_temp_free_i32(addr
);
11976 tcg_temp_free_i32(tmp
);
11979 if (insn
& (1 << 4)) {
11980 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11984 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11999 /* load/store multiple */
12000 TCGv_i32 loaded_var
= NULL
;
12001 rn
= (insn
>> 8) & 0x7;
12002 addr
= load_reg(s
, rn
);
12003 for (i
= 0; i
< 8; i
++) {
12004 if (insn
& (1 << i
)) {
12005 if (insn
& (1 << 11)) {
12007 tmp
= tcg_temp_new_i32();
12008 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
12012 store_reg(s
, i
, tmp
);
12016 tmp
= load_reg(s
, i
);
12017 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
12018 tcg_temp_free_i32(tmp
);
12020 /* advance to the next address */
12021 tcg_gen_addi_i32(addr
, addr
, 4);
12024 if ((insn
& (1 << rn
)) == 0) {
12025 /* base reg not in list: base register writeback */
12026 store_reg(s
, rn
, addr
);
12028 /* base reg in list: if load, complete it now */
12029 if (insn
& (1 << 11)) {
12030 store_reg(s
, rn
, loaded_var
);
12032 tcg_temp_free_i32(addr
);
12037 /* conditional branch or swi */
12038 cond
= (insn
>> 8) & 0xf;
12044 gen_set_pc_im(s
, s
->pc
);
12045 s
->svc_imm
= extract32(insn
, 0, 8);
12046 s
->base
.is_jmp
= DISAS_SWI
;
12049 /* generate a conditional jump to next instruction */
12050 s
->condlabel
= gen_new_label();
12051 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
12054 /* jump to the offset */
12055 val
= (uint32_t)s
->pc
+ 2;
12056 offset
= ((int32_t)insn
<< 24) >> 24;
12057 val
+= offset
<< 1;
12062 if (insn
& (1 << 11)) {
12063 /* thumb_insn_is_16bit() ensures we can't get here for
12064 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12065 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12067 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12069 offset
= ((insn
& 0x7ff) << 1);
12070 tmp
= load_reg(s
, 14);
12071 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12072 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
12074 tmp2
= tcg_temp_new_i32();
12075 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12076 store_reg(s
, 14, tmp2
);
12080 /* unconditional branch */
12081 val
= (uint32_t)s
->pc
;
12082 offset
= ((int32_t)insn
<< 21) >> 21;
12083 val
+= (offset
<< 1) + 2;
12088 /* thumb_insn_is_16bit() ensures we can't get here for
12089 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12091 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
12093 if (insn
& (1 << 11)) {
12094 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12095 offset
= ((insn
& 0x7ff) << 1) | 1;
12096 tmp
= load_reg(s
, 14);
12097 tcg_gen_addi_i32(tmp
, tmp
, offset
);
12099 tmp2
= tcg_temp_new_i32();
12100 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
12101 store_reg(s
, 14, tmp2
);
12104 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12105 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
12107 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
12114 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
12115 default_exception_el(s
));
12118 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
12120 /* Return true if the insn at dc->pc might cross a page boundary.
12121 * (False positives are OK, false negatives are not.)
12122 * We know this is a Thumb insn, and our caller ensures we are
12123 * only called if dc->pc is less than 4 bytes from the page
12124 * boundary, so we cross the page if the first 16 bits indicate
12125 * that this is a 32 bit insn.
12127 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
12129 return !thumb_insn_is_16bit(s
, insn
);
12132 static int arm_tr_init_disas_context(DisasContextBase
*dcbase
,
12133 CPUState
*cs
, int max_insns
)
12135 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12136 CPUARMState
*env
= cs
->env_ptr
;
12137 ARMCPU
*cpu
= arm_env_get_cpu(env
);
12139 dc
->pc
= dc
->base
.pc_first
;
12143 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12144 * there is no secure EL1, so we route exceptions to EL3.
12146 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
12147 !arm_el_is_aa64(env
, 3);
12148 dc
->thumb
= ARM_TBFLAG_THUMB(dc
->base
.tb
->flags
);
12149 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(dc
->base
.tb
->flags
);
12150 dc
->be_data
= ARM_TBFLAG_BE_DATA(dc
->base
.tb
->flags
) ? MO_BE
: MO_LE
;
12151 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) & 0xf) << 1;
12152 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) >> 4;
12153 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, ARM_TBFLAG_MMUIDX(dc
->base
.tb
->flags
));
12154 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
12155 #if !defined(CONFIG_USER_ONLY)
12156 dc
->user
= (dc
->current_el
== 0);
12158 dc
->ns
= ARM_TBFLAG_NS(dc
->base
.tb
->flags
);
12159 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(dc
->base
.tb
->flags
);
12160 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(dc
->base
.tb
->flags
);
12161 dc
->vec_len
= ARM_TBFLAG_VECLEN(dc
->base
.tb
->flags
);
12162 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(dc
->base
.tb
->flags
);
12163 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(dc
->base
.tb
->flags
);
12164 dc
->v7m_handler_mode
= ARM_TBFLAG_HANDLER(dc
->base
.tb
->flags
);
12165 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
12166 regime_is_secure(env
, dc
->mmu_idx
);
12167 dc
->cp_regs
= cpu
->cp_regs
;
12168 dc
->features
= env
->features
;
12170 /* Single step state. The code-generation logic here is:
12172 * generate code with no special handling for single-stepping (except
12173 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12174 * this happens anyway because those changes are all system register or
12176 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12177 * emit code for one insn
12178 * emit code to clear PSTATE.SS
12179 * emit code to generate software step exception for completed step
12180 * end TB (as usual for having generated an exception)
12181 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12182 * emit code to generate a software step exception
12185 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(dc
->base
.tb
->flags
);
12186 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(dc
->base
.tb
->flags
);
12187 dc
->is_ldex
= false;
12188 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
12190 dc
->next_page_start
=
12191 (dc
->base
.pc_first
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
12193 /* If architectural single step active, limit to 1. */
12194 if (is_singlestepping(dc
)) {
12198 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12199 to those left on the page. */
12201 int bound
= (dc
->next_page_start
- dc
->base
.pc_first
) / 4;
12202 max_insns
= MIN(max_insns
, bound
);
12205 cpu_F0s
= tcg_temp_new_i32();
12206 cpu_F1s
= tcg_temp_new_i32();
12207 cpu_F0d
= tcg_temp_new_i64();
12208 cpu_F1d
= tcg_temp_new_i64();
12211 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12212 cpu_M0
= tcg_temp_new_i64();
12217 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12219 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12221 /* A note on handling of the condexec (IT) bits:
12223 * We want to avoid the overhead of having to write the updated condexec
12224 * bits back to the CPUARMState for every instruction in an IT block. So:
12225 * (1) if the condexec bits are not already zero then we write
12226 * zero back into the CPUARMState now. This avoids complications trying
12227 * to do it at the end of the block. (For example if we don't do this
12228 * it's hard to identify whether we can safely skip writing condexec
12229 * at the end of the TB, which we definitely want to do for the case
12230 * where a TB doesn't do anything with the IT state at all.)
12231 * (2) if we are going to leave the TB then we call gen_set_condexec()
12232 * which will write the correct value into CPUARMState if zero is wrong.
12233 * This is done both for leaving the TB at the end, and for leaving
12234 * it because of an exception we know will happen, which is done in
12235 * gen_exception_insn(). The latter is necessary because we need to
12236 * leave the TB with the PC/IT state just prior to execution of the
12237 * instruction which caused the exception.
12238 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12239 * then the CPUARMState will be wrong and we need to reset it.
12240 * This is handled in the same way as restoration of the
12241 * PC in these situations; we save the value of the condexec bits
12242 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12243 * then uses this to restore them after an exception.
12245 * Note that there are no instructions which can read the condexec
12246 * bits, and none which can write non-static values to them, so
12247 * we don't need to care about whether CPUARMState is correct in the
12251 /* Reset the conditional execution bits immediately. This avoids
12252 complications trying to do it at the end of the block. */
12253 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
12254 TCGv_i32 tmp
= tcg_temp_new_i32();
12255 tcg_gen_movi_i32(tmp
, 0);
12256 store_cpu_field(tmp
, condexec_bits
);
12258 tcg_clear_temp_count();
12261 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12263 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12265 tcg_gen_insn_start(dc
->pc
,
12266 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
12268 dc
->insn_start
= tcg_last_op();
12271 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
12272 const CPUBreakpoint
*bp
)
12274 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12276 if (bp
->flags
& BP_CPU
) {
12277 gen_set_condexec(dc
);
12278 gen_set_pc_im(dc
, dc
->pc
);
12279 gen_helper_check_breakpoints(cpu_env
);
12280 /* End the TB early; it's likely not going to be executed */
12281 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12283 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
12284 /* The address covered by the breakpoint must be
12285 included in [tb->pc, tb->pc + tb->size) in order
12286 to for it to be properly cleared -- thus we
12287 increment the PC here so that the logic setting
12288 tb->size below does the right thing. */
12289 /* TODO: Advance PC by correct instruction length to
12290 * avoid disassembler error messages */
12292 dc
->base
.is_jmp
= DISAS_NORETURN
;
12298 static bool arm_pre_translate_insn(DisasContext
*dc
)
12300 #ifdef CONFIG_USER_ONLY
12301 /* Intercept jump to the magic kernel page. */
12302 if (dc
->pc
>= 0xffff0000) {
12303 /* We always get here via a jump, so know we are not in a
12304 conditional execution block. */
12305 gen_exception_internal(EXCP_KERNEL_TRAP
);
12306 dc
->base
.is_jmp
= DISAS_NORETURN
;
12311 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12312 /* Singlestep state is Active-pending.
12313 * If we're in this state at the start of a TB then either
12314 * a) we just took an exception to an EL which is being debugged
12315 * and this is the first insn in the exception handler
12316 * b) debug exceptions were masked and we just unmasked them
12317 * without changing EL (eg by clearing PSTATE.D)
12318 * In either case we're going to take a swstep exception in the
12319 * "did not step an insn" case, and so the syndrome ISV and EX
12320 * bits should be zero.
12322 assert(dc
->base
.num_insns
== 1);
12323 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
12324 default_exception_el(dc
));
12325 dc
->base
.is_jmp
= DISAS_NORETURN
;
12332 static void arm_post_translate_insn(DisasContext
*dc
)
12334 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12335 gen_set_label(dc
->condlabel
);
12338 dc
->base
.pc_next
= dc
->pc
;
12339 translator_loop_temp_check(&dc
->base
);
12342 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12344 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12345 CPUARMState
*env
= cpu
->env_ptr
;
12348 if (arm_pre_translate_insn(dc
)) {
12352 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12355 disas_arm_insn(dc
, insn
);
12357 arm_post_translate_insn(dc
);
12359 /* ARM is a fixed-length ISA. We performed the cross-page check
12360 in init_disas_context by adjusting max_insns. */
12363 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
12365 /* Return true if this Thumb insn is always unconditional,
12366 * even inside an IT block. This is true of only a very few
12367 * instructions: BKPT, HLT, and SG.
12369 * A larger class of instructions are UNPREDICTABLE if used
12370 * inside an IT block; we do not need to detect those here, because
12371 * what we do by default (perform the cc check and update the IT
12372 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12373 * choice for those situations.
12375 * insn is either a 16-bit or a 32-bit instruction; the two are
12376 * distinguishable because for the 16-bit case the top 16 bits
12377 * are zeroes, and that isn't a valid 32-bit encoding.
12379 if ((insn
& 0xffffff00) == 0xbe00) {
12384 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12385 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
12386 /* HLT: v8A only. This is unconditional even when it is going to
12387 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12388 * For v7 cores this was a plain old undefined encoding and so
12389 * honours its cc check. (We might be using the encoding as
12390 * a semihosting trap, but we don't change the cc check behaviour
12391 * on that account, because a debugger connected to a real v7A
12392 * core and emulating semihosting traps by catching the UNDEF
12393 * exception would also only see cases where the cc check passed.
12394 * No guest code should be trying to do a HLT semihosting trap
12395 * in an IT block anyway.
12400 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12401 arm_dc_feature(s
, ARM_FEATURE_M
)) {
12409 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12411 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12412 CPUARMState
*env
= cpu
->env_ptr
;
12416 if (arm_pre_translate_insn(dc
)) {
12420 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12421 is_16bit
= thumb_insn_is_16bit(dc
, insn
);
12424 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12426 insn
= insn
<< 16 | insn2
;
12431 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
12432 uint32_t cond
= dc
->condexec_cond
;
12434 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
12435 dc
->condlabel
= gen_new_label();
12436 arm_gen_test_cc(cond
^ 1, dc
->condlabel
);
12442 disas_thumb_insn(dc
, insn
);
12444 disas_thumb2_insn(dc
, insn
);
12447 /* Advance the Thumb condexec condition. */
12448 if (dc
->condexec_mask
) {
12449 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
12450 ((dc
->condexec_mask
>> 4) & 1));
12451 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12452 if (dc
->condexec_mask
== 0) {
12453 dc
->condexec_cond
= 0;
12457 arm_post_translate_insn(dc
);
12459 /* Thumb is a variable-length ISA. Stop translation when the next insn
12460 * will touch a new page. This ensures that prefetch aborts occur at
12463 * We want to stop the TB if the next insn starts in a new page,
12464 * or if it spans between this page and the next. This means that
12465 * if we're looking at the last halfword in the page we need to
12466 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12467 * or a 32-bit Thumb insn (which won't).
12468 * This is to avoid generating a silly TB with a single 16-bit insn
12469 * in it at the end of this page (which would execute correctly
12470 * but isn't very efficient).
12472 if (dc
->base
.is_jmp
== DISAS_NEXT
12473 && (dc
->pc
>= dc
->next_page_start
12474 || (dc
->pc
>= dc
->next_page_start
- 3
12475 && insn_crosses_page(env
, dc
)))) {
12476 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12480 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
12482 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12484 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
12485 /* FIXME: This can theoretically happen with self-modifying code. */
12486 cpu_abort(cpu
, "IO on conditional branch instruction");
12489 /* At this stage dc->condjmp will only be set when the skipped
12490 instruction was a conditional branch or trap, and the PC has
12491 already been written. */
12492 gen_set_condexec(dc
);
12493 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12494 /* Exception return branches need some special case code at the
12495 * end of the TB, which is complex enough that it has to
12496 * handle the single-step vs not and the condition-failed
12497 * insn codepath itself.
12499 gen_bx_excret_final_code(dc
);
12500 } else if (unlikely(is_singlestepping(dc
))) {
12501 /* Unconditional and "condition passed" instruction codepath. */
12502 switch (dc
->base
.is_jmp
) {
12504 gen_ss_advance(dc
);
12505 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12506 default_exception_el(dc
));
12509 gen_ss_advance(dc
);
12510 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12513 gen_ss_advance(dc
);
12514 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12517 case DISAS_TOO_MANY
:
12519 gen_set_pc_im(dc
, dc
->pc
);
12522 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12523 gen_singlestep_exception(dc
);
12525 case DISAS_NORETURN
:
12529 /* While branches must always occur at the end of an IT block,
12530 there are a few other things that can cause us to terminate
12531 the TB in the middle of an IT block:
12532 - Exception generating instructions (bkpt, swi, undefined).
12534 - Hardware watchpoints.
12535 Hardware breakpoints have already been handled and skip this code.
12537 switch(dc
->base
.is_jmp
) {
12539 case DISAS_TOO_MANY
:
12540 gen_goto_tb(dc
, 1, dc
->pc
);
12546 gen_set_pc_im(dc
, dc
->pc
);
12549 /* indicate that the hash table must be used to find the next TB */
12550 tcg_gen_exit_tb(0);
12552 case DISAS_NORETURN
:
12553 /* nothing more to generate */
12557 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
12558 !(dc
->insn
& (1U << 31))) ? 2 : 4);
12560 gen_helper_wfi(cpu_env
, tmp
);
12561 tcg_temp_free_i32(tmp
);
12562 /* The helper doesn't necessarily throw an exception, but we
12563 * must go back to the main loop to check for interrupts anyway.
12565 tcg_gen_exit_tb(0);
12569 gen_helper_wfe(cpu_env
);
12572 gen_helper_yield(cpu_env
);
12575 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12576 default_exception_el(dc
));
12579 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12582 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12588 /* "Condition failed" instruction codepath for the branch/trap insn */
12589 gen_set_label(dc
->condlabel
);
12590 gen_set_condexec(dc
);
12591 if (unlikely(is_singlestepping(dc
))) {
12592 gen_set_pc_im(dc
, dc
->pc
);
12593 gen_singlestep_exception(dc
);
12595 gen_goto_tb(dc
, 1, dc
->pc
);
12599 /* Functions above can change dc->pc, so re-align db->pc_next */
12600 dc
->base
.pc_next
= dc
->pc
;
12603 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
12605 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12607 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
12608 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
12611 static const TranslatorOps arm_translator_ops
= {
12612 .init_disas_context
= arm_tr_init_disas_context
,
12613 .tb_start
= arm_tr_tb_start
,
12614 .insn_start
= arm_tr_insn_start
,
12615 .breakpoint_check
= arm_tr_breakpoint_check
,
12616 .translate_insn
= arm_tr_translate_insn
,
12617 .tb_stop
= arm_tr_tb_stop
,
12618 .disas_log
= arm_tr_disas_log
,
12621 static const TranslatorOps thumb_translator_ops
= {
12622 .init_disas_context
= arm_tr_init_disas_context
,
12623 .tb_start
= arm_tr_tb_start
,
12624 .insn_start
= arm_tr_insn_start
,
12625 .breakpoint_check
= arm_tr_breakpoint_check
,
12626 .translate_insn
= thumb_tr_translate_insn
,
12627 .tb_stop
= arm_tr_tb_stop
,
12628 .disas_log
= arm_tr_disas_log
,
12631 /* generate intermediate code for basic block 'tb'. */
12632 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
)
12635 const TranslatorOps
*ops
= &arm_translator_ops
;
12637 if (ARM_TBFLAG_THUMB(tb
->flags
)) {
12638 ops
= &thumb_translator_ops
;
12640 #ifdef TARGET_AARCH64
12641 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
12642 ops
= &aarch64_translator_ops
;
12646 translator_loop(ops
, &dc
.base
, cpu
, tb
);
12649 static const char *cpu_mode_names
[16] = {
12650 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12651 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12654 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12657 ARMCPU
*cpu
= ARM_CPU(cs
);
12658 CPUARMState
*env
= &cpu
->env
;
12662 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12666 for(i
=0;i
<16;i
++) {
12667 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12669 cpu_fprintf(f
, "\n");
12671 cpu_fprintf(f
, " ");
12674 if (arm_feature(env
, ARM_FEATURE_M
)) {
12675 uint32_t xpsr
= xpsr_read(env
);
12677 const char *ns_status
= "";
12679 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
12680 ns_status
= env
->v7m
.secure
? "S " : "NS ";
12683 if (xpsr
& XPSR_EXCP
) {
12686 if (env
->v7m
.control
[env
->v7m
.secure
] & R_V7M_CONTROL_NPRIV_MASK
) {
12687 mode
= "unpriv-thread";
12689 mode
= "priv-thread";
12693 cpu_fprintf(f
, "XPSR=%08x %c%c%c%c %c %s%s\n",
12695 xpsr
& XPSR_N
? 'N' : '-',
12696 xpsr
& XPSR_Z
? 'Z' : '-',
12697 xpsr
& XPSR_C
? 'C' : '-',
12698 xpsr
& XPSR_V
? 'V' : '-',
12699 xpsr
& XPSR_T
? 'T' : 'A',
12703 uint32_t psr
= cpsr_read(env
);
12704 const char *ns_status
= "";
12706 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12707 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12708 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12711 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12713 psr
& CPSR_N
? 'N' : '-',
12714 psr
& CPSR_Z
? 'Z' : '-',
12715 psr
& CPSR_C
? 'C' : '-',
12716 psr
& CPSR_V
? 'V' : '-',
12717 psr
& CPSR_T
? 'T' : 'A',
12719 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12722 if (flags
& CPU_DUMP_FPU
) {
12723 int numvfpregs
= 0;
12724 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12727 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12730 for (i
= 0; i
< numvfpregs
; i
++) {
12731 uint64_t v
= *aa32_vfp_dreg(env
, i
);
12732 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12733 i
* 2, (uint32_t)v
,
12734 i
* 2 + 1, (uint32_t)(v
>> 32),
12737 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12741 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12742 target_ulong
*data
)
12746 env
->condexec_bits
= 0;
12747 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12749 env
->regs
[15] = data
[0];
12750 env
->condexec_bits
= data
[1];
12751 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;