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"
29 #include "qemu/bitops.h"
31 #include "exec/semihost.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
36 #include "trace-tcg.h"
40 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
41 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
42 /* currently all emulated v5 cores are also v5TE, so don't bother */
43 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
44 #define ENABLE_ARCH_5J arm_dc_feature(s, ARM_FEATURE_JAZELLE)
45 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
46 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
47 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
48 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
49 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
51 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
53 #include "translate.h"
55 #if defined(CONFIG_USER_ONLY)
58 #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 /* initialize TCG globals. */
80 void arm_translate_init(void)
84 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
85 tcg_ctx
.tcg_env
= cpu_env
;
87 for (i
= 0; i
< 16; i
++) {
88 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
89 offsetof(CPUARMState
, regs
[i
]),
92 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
93 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
94 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
95 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
97 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
98 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
99 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
100 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
102 a64_translate_init();
105 /* Flags for the disas_set_da_iss info argument:
106 * lower bits hold the Rt register number, higher bits are flags.
108 typedef enum ISSInfo
{
111 ISSInvalid
= (1 << 5),
112 ISSIsAcqRel
= (1 << 6),
113 ISSIsWrite
= (1 << 7),
114 ISSIs16Bit
= (1 << 8),
117 /* Save the syndrome information for a Data Abort */
118 static void disas_set_da_iss(DisasContext
*s
, TCGMemOp memop
, ISSInfo issinfo
)
121 int sas
= memop
& MO_SIZE
;
122 bool sse
= memop
& MO_SIGN
;
123 bool is_acqrel
= issinfo
& ISSIsAcqRel
;
124 bool is_write
= issinfo
& ISSIsWrite
;
125 bool is_16bit
= issinfo
& ISSIs16Bit
;
126 int srt
= issinfo
& ISSRegMask
;
128 if (issinfo
& ISSInvalid
) {
129 /* Some callsites want to conditionally provide ISS info,
130 * eg "only if this was not a writeback"
136 /* For AArch32, insns where the src/dest is R15 never generate
137 * ISS information. Catching that here saves checking at all
143 syn
= syn_data_abort_with_iss(0, sas
, sse
, srt
, 0, is_acqrel
,
144 0, 0, 0, is_write
, 0, is_16bit
);
145 disas_set_insn_syndrome(s
, syn
);
148 static inline int get_a32_user_mem_index(DisasContext
*s
)
150 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
152 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
153 * otherwise, access as if at PL0.
155 switch (s
->mmu_idx
) {
156 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
157 case ARMMMUIdx_S12NSE0
:
158 case ARMMMUIdx_S12NSE1
:
159 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0
);
161 case ARMMMUIdx_S1SE0
:
162 case ARMMMUIdx_S1SE1
:
163 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0
);
164 case ARMMMUIdx_MUser
:
165 case ARMMMUIdx_MPriv
:
166 case ARMMMUIdx_MNegPri
:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser
);
168 case ARMMMUIdx_MSUser
:
169 case ARMMMUIdx_MSPriv
:
170 case ARMMMUIdx_MSNegPri
:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser
);
174 g_assert_not_reached();
178 static inline TCGv_i32
load_cpu_offset(int offset
)
180 TCGv_i32 tmp
= tcg_temp_new_i32();
181 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
185 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
187 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
189 tcg_gen_st_i32(var
, cpu_env
, offset
);
190 tcg_temp_free_i32(var
);
193 #define store_cpu_field(var, name) \
194 store_cpu_offset(var, offsetof(CPUARMState, name))
196 /* Set a variable to the value of a CPU register. */
197 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
201 /* normally, since we updated PC, we need only to add one insn */
203 addr
= (long)s
->pc
+ 2;
205 addr
= (long)s
->pc
+ 4;
206 tcg_gen_movi_i32(var
, addr
);
208 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
212 /* Create a new temporary and set it to the value of a CPU register. */
213 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
215 TCGv_i32 tmp
= tcg_temp_new_i32();
216 load_reg_var(s
, tmp
, reg
);
220 /* Set a CPU register. The source must be a temporary and will be
222 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
225 /* In Thumb mode, we must ignore bit 0.
226 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
227 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
228 * We choose to ignore [1:0] in ARM mode for all architecture versions.
230 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
231 s
->base
.is_jmp
= DISAS_JUMP
;
233 tcg_gen_mov_i32(cpu_R
[reg
], var
);
234 tcg_temp_free_i32(var
);
237 /* Value extensions. */
238 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
239 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
240 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
241 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
243 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
244 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
247 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
249 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
250 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
251 tcg_temp_free_i32(tmp_mask
);
253 /* Set NZCV flags from the high 4 bits of var. */
254 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
256 static void gen_exception_internal(int excp
)
258 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
260 assert(excp_is_internal(excp
));
261 gen_helper_exception_internal(cpu_env
, tcg_excp
);
262 tcg_temp_free_i32(tcg_excp
);
265 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
267 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
268 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
269 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
271 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
274 tcg_temp_free_i32(tcg_el
);
275 tcg_temp_free_i32(tcg_syn
);
276 tcg_temp_free_i32(tcg_excp
);
279 static void gen_ss_advance(DisasContext
*s
)
281 /* If the singlestep state is Active-not-pending, advance to
286 gen_helper_clear_pstate_ss(cpu_env
);
290 static void gen_step_complete_exception(DisasContext
*s
)
292 /* We just completed step of an insn. Move from Active-not-pending
293 * to Active-pending, and then also take the swstep exception.
294 * This corresponds to making the (IMPDEF) choice to prioritize
295 * swstep exceptions over asynchronous exceptions taken to an exception
296 * level where debug is disabled. This choice has the advantage that
297 * we do not need to maintain internal state corresponding to the
298 * ISV/EX syndrome bits between completion of the step and generation
299 * of the exception, and our syndrome information is always correct.
302 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
303 default_exception_el(s
));
304 s
->base
.is_jmp
= DISAS_NORETURN
;
307 static void gen_singlestep_exception(DisasContext
*s
)
309 /* Generate the right kind of exception for singlestep, which is
310 * either the architectural singlestep or EXCP_DEBUG for QEMU's
311 * gdb singlestepping.
314 gen_step_complete_exception(s
);
316 gen_exception_internal(EXCP_DEBUG
);
320 static inline bool is_singlestepping(DisasContext
*s
)
322 /* Return true if we are singlestepping either because of
323 * architectural singlestep or QEMU gdbstub singlestep. This does
324 * not include the command line '-singlestep' mode which is rather
325 * misnamed as it only means "one instruction per TB" and doesn't
326 * affect the code we generate.
328 return s
->base
.singlestep_enabled
|| s
->ss_active
;
331 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
333 TCGv_i32 tmp1
= tcg_temp_new_i32();
334 TCGv_i32 tmp2
= tcg_temp_new_i32();
335 tcg_gen_ext16s_i32(tmp1
, a
);
336 tcg_gen_ext16s_i32(tmp2
, b
);
337 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
338 tcg_temp_free_i32(tmp2
);
339 tcg_gen_sari_i32(a
, a
, 16);
340 tcg_gen_sari_i32(b
, b
, 16);
341 tcg_gen_mul_i32(b
, b
, a
);
342 tcg_gen_mov_i32(a
, tmp1
);
343 tcg_temp_free_i32(tmp1
);
346 /* Byteswap each halfword. */
347 static void gen_rev16(TCGv_i32 var
)
349 TCGv_i32 tmp
= tcg_temp_new_i32();
350 TCGv_i32 mask
= tcg_const_i32(0x00ff00ff);
351 tcg_gen_shri_i32(tmp
, var
, 8);
352 tcg_gen_and_i32(tmp
, tmp
, mask
);
353 tcg_gen_and_i32(var
, var
, mask
);
354 tcg_gen_shli_i32(var
, var
, 8);
355 tcg_gen_or_i32(var
, var
, tmp
);
356 tcg_temp_free_i32(mask
);
357 tcg_temp_free_i32(tmp
);
360 /* Byteswap low halfword and sign extend. */
361 static void gen_revsh(TCGv_i32 var
)
363 tcg_gen_ext16u_i32(var
, var
);
364 tcg_gen_bswap16_i32(var
, var
);
365 tcg_gen_ext16s_i32(var
, var
);
368 /* Return (b << 32) + a. Mark inputs as dead */
369 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
371 TCGv_i64 tmp64
= tcg_temp_new_i64();
373 tcg_gen_extu_i32_i64(tmp64
, b
);
374 tcg_temp_free_i32(b
);
375 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
376 tcg_gen_add_i64(a
, tmp64
, a
);
378 tcg_temp_free_i64(tmp64
);
382 /* Return (b << 32) - a. Mark inputs as dead. */
383 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
385 TCGv_i64 tmp64
= tcg_temp_new_i64();
387 tcg_gen_extu_i32_i64(tmp64
, b
);
388 tcg_temp_free_i32(b
);
389 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
390 tcg_gen_sub_i64(a
, tmp64
, a
);
392 tcg_temp_free_i64(tmp64
);
396 /* 32x32->64 multiply. Marks inputs as dead. */
397 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
399 TCGv_i32 lo
= tcg_temp_new_i32();
400 TCGv_i32 hi
= tcg_temp_new_i32();
403 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
404 tcg_temp_free_i32(a
);
405 tcg_temp_free_i32(b
);
407 ret
= tcg_temp_new_i64();
408 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
409 tcg_temp_free_i32(lo
);
410 tcg_temp_free_i32(hi
);
415 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
417 TCGv_i32 lo
= tcg_temp_new_i32();
418 TCGv_i32 hi
= tcg_temp_new_i32();
421 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
422 tcg_temp_free_i32(a
);
423 tcg_temp_free_i32(b
);
425 ret
= tcg_temp_new_i64();
426 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
427 tcg_temp_free_i32(lo
);
428 tcg_temp_free_i32(hi
);
433 /* Swap low and high halfwords. */
434 static void gen_swap_half(TCGv_i32 var
)
436 TCGv_i32 tmp
= tcg_temp_new_i32();
437 tcg_gen_shri_i32(tmp
, var
, 16);
438 tcg_gen_shli_i32(var
, var
, 16);
439 tcg_gen_or_i32(var
, var
, tmp
);
440 tcg_temp_free_i32(tmp
);
443 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
444 tmp = (t0 ^ t1) & 0x8000;
447 t0 = (t0 + t1) ^ tmp;
450 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
452 TCGv_i32 tmp
= tcg_temp_new_i32();
453 tcg_gen_xor_i32(tmp
, t0
, t1
);
454 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
455 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
456 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
457 tcg_gen_add_i32(t0
, t0
, t1
);
458 tcg_gen_xor_i32(t0
, t0
, tmp
);
459 tcg_temp_free_i32(tmp
);
460 tcg_temp_free_i32(t1
);
463 /* Set CF to the top bit of var. */
464 static void gen_set_CF_bit31(TCGv_i32 var
)
466 tcg_gen_shri_i32(cpu_CF
, var
, 31);
469 /* Set N and Z flags from var. */
470 static inline void gen_logic_CC(TCGv_i32 var
)
472 tcg_gen_mov_i32(cpu_NF
, var
);
473 tcg_gen_mov_i32(cpu_ZF
, var
);
477 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
479 tcg_gen_add_i32(t0
, t0
, t1
);
480 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
483 /* dest = T0 + T1 + CF. */
484 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
486 tcg_gen_add_i32(dest
, t0
, t1
);
487 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
490 /* dest = T0 - T1 + CF - 1. */
491 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
493 tcg_gen_sub_i32(dest
, t0
, t1
);
494 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
495 tcg_gen_subi_i32(dest
, dest
, 1);
498 /* dest = T0 + T1. Compute C, N, V and Z flags */
499 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
501 TCGv_i32 tmp
= tcg_temp_new_i32();
502 tcg_gen_movi_i32(tmp
, 0);
503 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
504 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
505 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
506 tcg_gen_xor_i32(tmp
, t0
, t1
);
507 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
508 tcg_temp_free_i32(tmp
);
509 tcg_gen_mov_i32(dest
, cpu_NF
);
512 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
513 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
515 TCGv_i32 tmp
= tcg_temp_new_i32();
516 if (TCG_TARGET_HAS_add2_i32
) {
517 tcg_gen_movi_i32(tmp
, 0);
518 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
519 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
521 TCGv_i64 q0
= tcg_temp_new_i64();
522 TCGv_i64 q1
= tcg_temp_new_i64();
523 tcg_gen_extu_i32_i64(q0
, t0
);
524 tcg_gen_extu_i32_i64(q1
, t1
);
525 tcg_gen_add_i64(q0
, q0
, q1
);
526 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
527 tcg_gen_add_i64(q0
, q0
, q1
);
528 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
529 tcg_temp_free_i64(q0
);
530 tcg_temp_free_i64(q1
);
532 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
533 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
534 tcg_gen_xor_i32(tmp
, t0
, t1
);
535 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
536 tcg_temp_free_i32(tmp
);
537 tcg_gen_mov_i32(dest
, cpu_NF
);
540 /* dest = T0 - T1. Compute C, N, V and Z flags */
541 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
544 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
545 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
546 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
547 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
548 tmp
= tcg_temp_new_i32();
549 tcg_gen_xor_i32(tmp
, t0
, t1
);
550 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
551 tcg_temp_free_i32(tmp
);
552 tcg_gen_mov_i32(dest
, cpu_NF
);
555 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
556 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
558 TCGv_i32 tmp
= tcg_temp_new_i32();
559 tcg_gen_not_i32(tmp
, t1
);
560 gen_adc_CC(dest
, t0
, tmp
);
561 tcg_temp_free_i32(tmp
);
564 #define GEN_SHIFT(name) \
565 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
567 TCGv_i32 tmp1, tmp2, tmp3; \
568 tmp1 = tcg_temp_new_i32(); \
569 tcg_gen_andi_i32(tmp1, t1, 0xff); \
570 tmp2 = tcg_const_i32(0); \
571 tmp3 = tcg_const_i32(0x1f); \
572 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
573 tcg_temp_free_i32(tmp3); \
574 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
575 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
576 tcg_temp_free_i32(tmp2); \
577 tcg_temp_free_i32(tmp1); \
583 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
586 tmp1
= tcg_temp_new_i32();
587 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
588 tmp2
= tcg_const_i32(0x1f);
589 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
590 tcg_temp_free_i32(tmp2
);
591 tcg_gen_sar_i32(dest
, t0
, tmp1
);
592 tcg_temp_free_i32(tmp1
);
595 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
597 TCGv_i32 c0
= tcg_const_i32(0);
598 TCGv_i32 tmp
= tcg_temp_new_i32();
599 tcg_gen_neg_i32(tmp
, src
);
600 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
601 tcg_temp_free_i32(c0
);
602 tcg_temp_free_i32(tmp
);
605 static void shifter_out_im(TCGv_i32 var
, int shift
)
608 tcg_gen_andi_i32(cpu_CF
, var
, 1);
610 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
612 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
617 /* Shift by immediate. Includes special handling for shift == 0. */
618 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
619 int shift
, int flags
)
625 shifter_out_im(var
, 32 - shift
);
626 tcg_gen_shli_i32(var
, var
, shift
);
632 tcg_gen_shri_i32(cpu_CF
, var
, 31);
634 tcg_gen_movi_i32(var
, 0);
637 shifter_out_im(var
, shift
- 1);
638 tcg_gen_shri_i32(var
, var
, shift
);
645 shifter_out_im(var
, shift
- 1);
648 tcg_gen_sari_i32(var
, var
, shift
);
650 case 3: /* ROR/RRX */
653 shifter_out_im(var
, shift
- 1);
654 tcg_gen_rotri_i32(var
, var
, shift
); break;
656 TCGv_i32 tmp
= tcg_temp_new_i32();
657 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
659 shifter_out_im(var
, 0);
660 tcg_gen_shri_i32(var
, var
, 1);
661 tcg_gen_or_i32(var
, var
, tmp
);
662 tcg_temp_free_i32(tmp
);
667 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
668 TCGv_i32 shift
, int flags
)
672 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
673 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
674 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
675 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
680 gen_shl(var
, var
, shift
);
683 gen_shr(var
, var
, shift
);
686 gen_sar(var
, var
, shift
);
688 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
689 tcg_gen_rotr_i32(var
, var
, shift
); break;
692 tcg_temp_free_i32(shift
);
695 #define PAS_OP(pfx) \
697 case 0: gen_pas_helper(glue(pfx,add16)); break; \
698 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
699 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
700 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
701 case 4: gen_pas_helper(glue(pfx,add8)); break; \
702 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
704 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
709 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
711 tmp
= tcg_temp_new_ptr();
712 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
714 tcg_temp_free_ptr(tmp
);
717 tmp
= tcg_temp_new_ptr();
718 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
720 tcg_temp_free_ptr(tmp
);
722 #undef gen_pas_helper
723 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
736 #undef gen_pas_helper
741 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
742 #define PAS_OP(pfx) \
744 case 0: gen_pas_helper(glue(pfx,add8)); break; \
745 case 1: gen_pas_helper(glue(pfx,add16)); break; \
746 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
747 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
748 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
749 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
751 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
756 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
758 tmp
= tcg_temp_new_ptr();
759 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
761 tcg_temp_free_ptr(tmp
);
764 tmp
= tcg_temp_new_ptr();
765 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
767 tcg_temp_free_ptr(tmp
);
769 #undef gen_pas_helper
770 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
783 #undef gen_pas_helper
789 * Generate a conditional based on ARM condition code cc.
790 * This is common between ARM and Aarch64 targets.
792 void arm_test_cc(DisasCompare
*cmp
, int cc
)
823 case 8: /* hi: C && !Z */
824 case 9: /* ls: !C || Z -> !(C && !Z) */
826 value
= tcg_temp_new_i32();
828 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
829 ZF is non-zero for !Z; so AND the two subexpressions. */
830 tcg_gen_neg_i32(value
, cpu_CF
);
831 tcg_gen_and_i32(value
, value
, cpu_ZF
);
834 case 10: /* ge: N == V -> N ^ V == 0 */
835 case 11: /* lt: N != V -> N ^ V != 0 */
836 /* Since we're only interested in the sign bit, == 0 is >= 0. */
838 value
= tcg_temp_new_i32();
840 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
843 case 12: /* gt: !Z && N == V */
844 case 13: /* le: Z || N != V */
846 value
= tcg_temp_new_i32();
848 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
849 * the sign bit then AND with ZF to yield the result. */
850 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
851 tcg_gen_sari_i32(value
, value
, 31);
852 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
855 case 14: /* always */
856 case 15: /* always */
857 /* Use the ALWAYS condition, which will fold early.
858 * It doesn't matter what we use for the value. */
859 cond
= TCG_COND_ALWAYS
;
864 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
869 cond
= tcg_invert_cond(cond
);
875 cmp
->value_global
= global
;
878 void arm_free_cc(DisasCompare
*cmp
)
880 if (!cmp
->value_global
) {
881 tcg_temp_free_i32(cmp
->value
);
885 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
887 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
890 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
893 arm_test_cc(&cmp
, cc
);
894 arm_jump_cc(&cmp
, label
);
898 static const uint8_t table_logic_cc
[16] = {
917 static inline void gen_set_condexec(DisasContext
*s
)
919 if (s
->condexec_mask
) {
920 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
921 TCGv_i32 tmp
= tcg_temp_new_i32();
922 tcg_gen_movi_i32(tmp
, val
);
923 store_cpu_field(tmp
, condexec_bits
);
927 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
929 tcg_gen_movi_i32(cpu_R
[15], val
);
932 /* Set PC and Thumb state from an immediate address. */
933 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
937 s
->base
.is_jmp
= DISAS_JUMP
;
938 if (s
->thumb
!= (addr
& 1)) {
939 tmp
= tcg_temp_new_i32();
940 tcg_gen_movi_i32(tmp
, addr
& 1);
941 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
942 tcg_temp_free_i32(tmp
);
944 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
947 /* Set PC and Thumb state from var. var is marked as dead. */
948 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
950 s
->base
.is_jmp
= DISAS_JUMP
;
951 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
952 tcg_gen_andi_i32(var
, var
, 1);
953 store_cpu_field(var
, thumb
);
956 /* Set PC and Thumb state from var. var is marked as dead.
957 * For M-profile CPUs, include logic to detect exception-return
958 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
959 * and BX reg, and no others, and happens only for code in Handler mode.
961 static inline void gen_bx_excret(DisasContext
*s
, TCGv_i32 var
)
963 /* Generate the same code here as for a simple bx, but flag via
964 * s->base.is_jmp that we need to do the rest of the work later.
967 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
) ||
968 (s
->v7m_handler_mode
&& arm_dc_feature(s
, ARM_FEATURE_M
))) {
969 s
->base
.is_jmp
= DISAS_BX_EXCRET
;
973 static inline void gen_bx_excret_final_code(DisasContext
*s
)
975 /* Generate the code to finish possible exception return and end the TB */
976 TCGLabel
*excret_label
= gen_new_label();
979 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
)) {
980 /* Covers FNC_RETURN and EXC_RETURN magic */
981 min_magic
= FNC_RETURN_MIN_MAGIC
;
983 /* EXC_RETURN magic only */
984 min_magic
= EXC_RETURN_MIN_MAGIC
;
987 /* Is the new PC value in the magic range indicating exception return? */
988 tcg_gen_brcondi_i32(TCG_COND_GEU
, cpu_R
[15], min_magic
, excret_label
);
989 /* No: end the TB as we would for a DISAS_JMP */
990 if (is_singlestepping(s
)) {
991 gen_singlestep_exception(s
);
995 gen_set_label(excret_label
);
996 /* Yes: this is an exception return.
997 * At this point in runtime env->regs[15] and env->thumb will hold
998 * the exception-return magic number, which do_v7m_exception_exit()
999 * will read. Nothing else will be able to see those values because
1000 * the cpu-exec main loop guarantees that we will always go straight
1001 * from raising the exception to the exception-handling code.
1003 * gen_ss_advance(s) does nothing on M profile currently but
1004 * calling it is conceptually the right thing as we have executed
1005 * this instruction (compare SWI, HVC, SMC handling).
1008 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
1011 static inline void gen_bxns(DisasContext
*s
, int rm
)
1013 TCGv_i32 var
= load_reg(s
, rm
);
1015 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1016 * we need to sync state before calling it, but:
1017 * - we don't need to do gen_set_pc_im() because the bxns helper will
1018 * always set the PC itself
1019 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1020 * unless it's outside an IT block or the last insn in an IT block,
1021 * so we know that condexec == 0 (already set at the top of the TB)
1022 * is correct in the non-UNPREDICTABLE cases, and we can choose
1023 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1025 gen_helper_v7m_bxns(cpu_env
, var
);
1026 tcg_temp_free_i32(var
);
1027 s
->base
.is_jmp
= DISAS_EXIT
;
1030 static inline void gen_blxns(DisasContext
*s
, int rm
)
1032 TCGv_i32 var
= load_reg(s
, rm
);
1034 /* We don't need to sync condexec state, for the same reason as bxns.
1035 * We do however need to set the PC, because the blxns helper reads it.
1036 * The blxns helper may throw an exception.
1038 gen_set_pc_im(s
, s
->pc
);
1039 gen_helper_v7m_blxns(cpu_env
, var
);
1040 tcg_temp_free_i32(var
);
1041 s
->base
.is_jmp
= DISAS_EXIT
;
1044 /* Variant of store_reg which uses branch&exchange logic when storing
1045 to r15 in ARM architecture v7 and above. The source must be a temporary
1046 and will be marked as dead. */
1047 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
1049 if (reg
== 15 && ENABLE_ARCH_7
) {
1052 store_reg(s
, reg
, var
);
1056 /* Variant of store_reg which uses branch&exchange logic when storing
1057 * to r15 in ARM architecture v5T and above. This is used for storing
1058 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1059 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1060 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
1062 if (reg
== 15 && ENABLE_ARCH_5
) {
1063 gen_bx_excret(s
, var
);
1065 store_reg(s
, reg
, var
);
1069 #ifdef CONFIG_USER_ONLY
1070 #define IS_USER_ONLY 1
1072 #define IS_USER_ONLY 0
1075 /* Abstractions of "generate code to do a guest load/store for
1076 * AArch32", where a vaddr is always 32 bits (and is zero
1077 * extended if we're a 64 bit core) and data is also
1078 * 32 bits unless specifically doing a 64 bit access.
1079 * These functions work like tcg_gen_qemu_{ld,st}* except
1080 * that the address argument is TCGv_i32 rather than TCGv.
1083 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, TCGMemOp op
)
1085 TCGv addr
= tcg_temp_new();
1086 tcg_gen_extu_i32_tl(addr
, a32
);
1088 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1089 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
1090 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
1095 static void gen_aa32_ld_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1096 int index
, TCGMemOp opc
)
1098 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1099 tcg_gen_qemu_ld_i32(val
, addr
, index
, opc
);
1100 tcg_temp_free(addr
);
1103 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1104 int index
, TCGMemOp opc
)
1106 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1107 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
1108 tcg_temp_free(addr
);
1111 #define DO_GEN_LD(SUFF, OPC) \
1112 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1113 TCGv_i32 a32, int index) \
1115 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1117 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1119 TCGv_i32 a32, int index, \
1122 gen_aa32_ld##SUFF(s, val, a32, index); \
1123 disas_set_da_iss(s, OPC, issinfo); \
1126 #define DO_GEN_ST(SUFF, OPC) \
1127 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1128 TCGv_i32 a32, int index) \
1130 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1132 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1134 TCGv_i32 a32, int index, \
1137 gen_aa32_st##SUFF(s, val, a32, index); \
1138 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1141 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
1143 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1144 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1145 tcg_gen_rotri_i64(val
, val
, 32);
1149 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1150 int index
, TCGMemOp opc
)
1152 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1153 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
1154 gen_aa32_frob64(s
, val
);
1155 tcg_temp_free(addr
);
1158 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1159 TCGv_i32 a32
, int index
)
1161 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1164 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1165 int index
, TCGMemOp opc
)
1167 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1169 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1170 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1171 TCGv_i64 tmp
= tcg_temp_new_i64();
1172 tcg_gen_rotri_i64(tmp
, val
, 32);
1173 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
1174 tcg_temp_free_i64(tmp
);
1176 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
1178 tcg_temp_free(addr
);
1181 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1182 TCGv_i32 a32
, int index
)
1184 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1187 DO_GEN_LD(8s
, MO_SB
)
1188 DO_GEN_LD(8u, MO_UB
)
1189 DO_GEN_LD(16s
, MO_SW
)
1190 DO_GEN_LD(16u, MO_UW
)
1191 DO_GEN_LD(32u, MO_UL
)
1193 DO_GEN_ST(16, MO_UW
)
1194 DO_GEN_ST(32, MO_UL
)
1196 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1198 /* The pre HVC helper handles cases when HVC gets trapped
1199 * as an undefined insn by runtime configuration (ie before
1200 * the insn really executes).
1202 gen_set_pc_im(s
, s
->pc
- 4);
1203 gen_helper_pre_hvc(cpu_env
);
1204 /* Otherwise we will treat this as a real exception which
1205 * happens after execution of the insn. (The distinction matters
1206 * for the PC value reported to the exception handler and also
1207 * for single stepping.)
1210 gen_set_pc_im(s
, s
->pc
);
1211 s
->base
.is_jmp
= DISAS_HVC
;
1214 static inline void gen_smc(DisasContext
*s
)
1216 /* As with HVC, we may take an exception either before or after
1217 * the insn executes.
1221 gen_set_pc_im(s
, s
->pc
- 4);
1222 tmp
= tcg_const_i32(syn_aa32_smc());
1223 gen_helper_pre_smc(cpu_env
, tmp
);
1224 tcg_temp_free_i32(tmp
);
1225 gen_set_pc_im(s
, s
->pc
);
1226 s
->base
.is_jmp
= DISAS_SMC
;
1229 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1231 gen_set_condexec(s
);
1232 gen_set_pc_im(s
, s
->pc
- offset
);
1233 gen_exception_internal(excp
);
1234 s
->base
.is_jmp
= DISAS_NORETURN
;
1237 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1238 int syn
, uint32_t target_el
)
1240 gen_set_condexec(s
);
1241 gen_set_pc_im(s
, s
->pc
- offset
);
1242 gen_exception(excp
, syn
, target_el
);
1243 s
->base
.is_jmp
= DISAS_NORETURN
;
1246 /* Force a TB lookup after an instruction that changes the CPU state. */
1247 static inline void gen_lookup_tb(DisasContext
*s
)
1249 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1250 s
->base
.is_jmp
= DISAS_EXIT
;
1253 static inline void gen_hlt(DisasContext
*s
, int imm
)
1255 /* HLT. This has two purposes.
1256 * Architecturally, it is an external halting debug instruction.
1257 * Since QEMU doesn't implement external debug, we treat this as
1258 * it is required for halting debug disabled: it will UNDEF.
1259 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1260 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1261 * must trigger semihosting even for ARMv7 and earlier, where
1262 * HLT was an undefined encoding.
1263 * In system mode, we don't allow userspace access to
1264 * semihosting, to provide some semblance of security
1265 * (and for consistency with our 32-bit semihosting).
1267 if (semihosting_enabled() &&
1268 #ifndef CONFIG_USER_ONLY
1269 s
->current_el
!= 0 &&
1271 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1272 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1276 gen_exception_insn(s
, s
->thumb
? 2 : 4, EXCP_UDEF
, syn_uncategorized(),
1277 default_exception_el(s
));
1280 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1283 int val
, rm
, shift
, shiftop
;
1286 if (!(insn
& (1 << 25))) {
1289 if (!(insn
& (1 << 23)))
1292 tcg_gen_addi_i32(var
, var
, val
);
1294 /* shift/register */
1296 shift
= (insn
>> 7) & 0x1f;
1297 shiftop
= (insn
>> 5) & 3;
1298 offset
= load_reg(s
, rm
);
1299 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1300 if (!(insn
& (1 << 23)))
1301 tcg_gen_sub_i32(var
, var
, offset
);
1303 tcg_gen_add_i32(var
, var
, offset
);
1304 tcg_temp_free_i32(offset
);
1308 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1309 int extra
, TCGv_i32 var
)
1314 if (insn
& (1 << 22)) {
1316 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1317 if (!(insn
& (1 << 23)))
1321 tcg_gen_addi_i32(var
, var
, val
);
1325 tcg_gen_addi_i32(var
, var
, extra
);
1327 offset
= load_reg(s
, rm
);
1328 if (!(insn
& (1 << 23)))
1329 tcg_gen_sub_i32(var
, var
, offset
);
1331 tcg_gen_add_i32(var
, var
, offset
);
1332 tcg_temp_free_i32(offset
);
1336 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1338 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1341 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1343 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1345 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1349 #define VFP_OP2(name) \
1350 static inline void gen_vfp_##name(int dp) \
1352 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1354 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1356 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1358 tcg_temp_free_ptr(fpst); \
1368 static inline void gen_vfp_F1_mul(int dp
)
1370 /* Like gen_vfp_mul() but put result in F1 */
1371 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1373 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1375 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1377 tcg_temp_free_ptr(fpst
);
1380 static inline void gen_vfp_F1_neg(int dp
)
1382 /* Like gen_vfp_neg() but put result in F1 */
1384 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1386 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1390 static inline void gen_vfp_abs(int dp
)
1393 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1395 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1398 static inline void gen_vfp_neg(int dp
)
1401 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1403 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1406 static inline void gen_vfp_sqrt(int dp
)
1409 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1411 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1414 static inline void gen_vfp_cmp(int dp
)
1417 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1419 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1422 static inline void gen_vfp_cmpe(int dp
)
1425 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1427 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1430 static inline void gen_vfp_F1_ld0(int dp
)
1433 tcg_gen_movi_i64(cpu_F1d
, 0);
1435 tcg_gen_movi_i32(cpu_F1s
, 0);
1438 #define VFP_GEN_ITOF(name) \
1439 static inline void gen_vfp_##name(int dp, int neon) \
1441 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1443 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1445 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1447 tcg_temp_free_ptr(statusptr); \
1454 #define VFP_GEN_FTOI(name) \
1455 static inline void gen_vfp_##name(int dp, int neon) \
1457 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1459 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1461 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1463 tcg_temp_free_ptr(statusptr); \
1472 #define VFP_GEN_FIX(name, round) \
1473 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1475 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1476 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1478 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1481 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1484 tcg_temp_free_i32(tmp_shift); \
1485 tcg_temp_free_ptr(statusptr); \
1487 VFP_GEN_FIX(tosh
, _round_to_zero
)
1488 VFP_GEN_FIX(tosl
, _round_to_zero
)
1489 VFP_GEN_FIX(touh
, _round_to_zero
)
1490 VFP_GEN_FIX(toul
, _round_to_zero
)
1497 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1500 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1502 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1506 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1509 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1511 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1516 vfp_reg_offset (int dp
, int reg
)
1519 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1521 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1522 + offsetof(CPU_DoubleU
, l
.upper
);
1524 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1525 + offsetof(CPU_DoubleU
, l
.lower
);
1529 /* Return the offset of a 32-bit piece of a NEON register.
1530 zero is the least significant end of the register. */
1532 neon_reg_offset (int reg
, int n
)
1536 return vfp_reg_offset(0, sreg
);
1539 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1541 TCGv_i32 tmp
= tcg_temp_new_i32();
1542 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1546 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1548 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1549 tcg_temp_free_i32(var
);
1552 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1554 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1557 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1559 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1562 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1563 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1564 #define tcg_gen_st_f32 tcg_gen_st_i32
1565 #define tcg_gen_st_f64 tcg_gen_st_i64
1567 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1570 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1572 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1575 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1578 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1580 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1583 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1586 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1588 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1591 #define ARM_CP_RW_BIT (1 << 20)
1593 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1595 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1598 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1600 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1603 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1605 TCGv_i32 var
= tcg_temp_new_i32();
1606 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1610 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1612 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1613 tcg_temp_free_i32(var
);
1616 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1618 iwmmxt_store_reg(cpu_M0
, rn
);
1621 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1623 iwmmxt_load_reg(cpu_M0
, rn
);
1626 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1628 iwmmxt_load_reg(cpu_V1
, rn
);
1629 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1632 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1634 iwmmxt_load_reg(cpu_V1
, rn
);
1635 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1638 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1640 iwmmxt_load_reg(cpu_V1
, rn
);
1641 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1644 #define IWMMXT_OP(name) \
1645 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1647 iwmmxt_load_reg(cpu_V1, rn); \
1648 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1651 #define IWMMXT_OP_ENV(name) \
1652 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1654 iwmmxt_load_reg(cpu_V1, rn); \
1655 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1658 #define IWMMXT_OP_ENV_SIZE(name) \
1659 IWMMXT_OP_ENV(name##b) \
1660 IWMMXT_OP_ENV(name##w) \
1661 IWMMXT_OP_ENV(name##l)
1663 #define IWMMXT_OP_ENV1(name) \
1664 static inline void gen_op_iwmmxt_##name##_M0(void) \
1666 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1680 IWMMXT_OP_ENV_SIZE(unpackl
)
1681 IWMMXT_OP_ENV_SIZE(unpackh
)
1683 IWMMXT_OP_ENV1(unpacklub
)
1684 IWMMXT_OP_ENV1(unpackluw
)
1685 IWMMXT_OP_ENV1(unpacklul
)
1686 IWMMXT_OP_ENV1(unpackhub
)
1687 IWMMXT_OP_ENV1(unpackhuw
)
1688 IWMMXT_OP_ENV1(unpackhul
)
1689 IWMMXT_OP_ENV1(unpacklsb
)
1690 IWMMXT_OP_ENV1(unpacklsw
)
1691 IWMMXT_OP_ENV1(unpacklsl
)
1692 IWMMXT_OP_ENV1(unpackhsb
)
1693 IWMMXT_OP_ENV1(unpackhsw
)
1694 IWMMXT_OP_ENV1(unpackhsl
)
1696 IWMMXT_OP_ENV_SIZE(cmpeq
)
1697 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1698 IWMMXT_OP_ENV_SIZE(cmpgts
)
1700 IWMMXT_OP_ENV_SIZE(mins
)
1701 IWMMXT_OP_ENV_SIZE(minu
)
1702 IWMMXT_OP_ENV_SIZE(maxs
)
1703 IWMMXT_OP_ENV_SIZE(maxu
)
1705 IWMMXT_OP_ENV_SIZE(subn
)
1706 IWMMXT_OP_ENV_SIZE(addn
)
1707 IWMMXT_OP_ENV_SIZE(subu
)
1708 IWMMXT_OP_ENV_SIZE(addu
)
1709 IWMMXT_OP_ENV_SIZE(subs
)
1710 IWMMXT_OP_ENV_SIZE(adds
)
1712 IWMMXT_OP_ENV(avgb0
)
1713 IWMMXT_OP_ENV(avgb1
)
1714 IWMMXT_OP_ENV(avgw0
)
1715 IWMMXT_OP_ENV(avgw1
)
1717 IWMMXT_OP_ENV(packuw
)
1718 IWMMXT_OP_ENV(packul
)
1719 IWMMXT_OP_ENV(packuq
)
1720 IWMMXT_OP_ENV(packsw
)
1721 IWMMXT_OP_ENV(packsl
)
1722 IWMMXT_OP_ENV(packsq
)
1724 static void gen_op_iwmmxt_set_mup(void)
1727 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1728 tcg_gen_ori_i32(tmp
, tmp
, 2);
1729 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1732 static void gen_op_iwmmxt_set_cup(void)
1735 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1736 tcg_gen_ori_i32(tmp
, tmp
, 1);
1737 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1740 static void gen_op_iwmmxt_setpsr_nz(void)
1742 TCGv_i32 tmp
= tcg_temp_new_i32();
1743 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1744 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1747 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1749 iwmmxt_load_reg(cpu_V1
, rn
);
1750 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1751 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1754 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1761 rd
= (insn
>> 16) & 0xf;
1762 tmp
= load_reg(s
, rd
);
1764 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1765 if (insn
& (1 << 24)) {
1767 if (insn
& (1 << 23))
1768 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1770 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1771 tcg_gen_mov_i32(dest
, tmp
);
1772 if (insn
& (1 << 21))
1773 store_reg(s
, rd
, tmp
);
1775 tcg_temp_free_i32(tmp
);
1776 } else if (insn
& (1 << 21)) {
1778 tcg_gen_mov_i32(dest
, tmp
);
1779 if (insn
& (1 << 23))
1780 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1782 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1783 store_reg(s
, rd
, tmp
);
1784 } else if (!(insn
& (1 << 23)))
1789 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1791 int rd
= (insn
>> 0) & 0xf;
1794 if (insn
& (1 << 8)) {
1795 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1798 tmp
= iwmmxt_load_creg(rd
);
1801 tmp
= tcg_temp_new_i32();
1802 iwmmxt_load_reg(cpu_V0
, rd
);
1803 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1805 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1806 tcg_gen_mov_i32(dest
, tmp
);
1807 tcg_temp_free_i32(tmp
);
1811 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1812 (ie. an undefined instruction). */
1813 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1816 int rdhi
, rdlo
, rd0
, rd1
, i
;
1818 TCGv_i32 tmp
, tmp2
, tmp3
;
1820 if ((insn
& 0x0e000e00) == 0x0c000000) {
1821 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1823 rdlo
= (insn
>> 12) & 0xf;
1824 rdhi
= (insn
>> 16) & 0xf;
1825 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1826 iwmmxt_load_reg(cpu_V0
, wrd
);
1827 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1828 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1829 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1830 } else { /* TMCRR */
1831 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1832 iwmmxt_store_reg(cpu_V0
, wrd
);
1833 gen_op_iwmmxt_set_mup();
1838 wrd
= (insn
>> 12) & 0xf;
1839 addr
= tcg_temp_new_i32();
1840 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1841 tcg_temp_free_i32(addr
);
1844 if (insn
& ARM_CP_RW_BIT
) {
1845 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1846 tmp
= tcg_temp_new_i32();
1847 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1848 iwmmxt_store_creg(wrd
, tmp
);
1851 if (insn
& (1 << 8)) {
1852 if (insn
& (1 << 22)) { /* WLDRD */
1853 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1855 } else { /* WLDRW wRd */
1856 tmp
= tcg_temp_new_i32();
1857 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1860 tmp
= tcg_temp_new_i32();
1861 if (insn
& (1 << 22)) { /* WLDRH */
1862 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1863 } else { /* WLDRB */
1864 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1868 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1869 tcg_temp_free_i32(tmp
);
1871 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1874 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1875 tmp
= iwmmxt_load_creg(wrd
);
1876 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1878 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1879 tmp
= tcg_temp_new_i32();
1880 if (insn
& (1 << 8)) {
1881 if (insn
& (1 << 22)) { /* WSTRD */
1882 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1883 } else { /* WSTRW wRd */
1884 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1885 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1888 if (insn
& (1 << 22)) { /* WSTRH */
1889 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1890 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1891 } else { /* WSTRB */
1892 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1893 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1897 tcg_temp_free_i32(tmp
);
1899 tcg_temp_free_i32(addr
);
1903 if ((insn
& 0x0f000000) != 0x0e000000)
1906 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1907 case 0x000: /* WOR */
1908 wrd
= (insn
>> 12) & 0xf;
1909 rd0
= (insn
>> 0) & 0xf;
1910 rd1
= (insn
>> 16) & 0xf;
1911 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1912 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1913 gen_op_iwmmxt_setpsr_nz();
1914 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1915 gen_op_iwmmxt_set_mup();
1916 gen_op_iwmmxt_set_cup();
1918 case 0x011: /* TMCR */
1921 rd
= (insn
>> 12) & 0xf;
1922 wrd
= (insn
>> 16) & 0xf;
1924 case ARM_IWMMXT_wCID
:
1925 case ARM_IWMMXT_wCASF
:
1927 case ARM_IWMMXT_wCon
:
1928 gen_op_iwmmxt_set_cup();
1930 case ARM_IWMMXT_wCSSF
:
1931 tmp
= iwmmxt_load_creg(wrd
);
1932 tmp2
= load_reg(s
, rd
);
1933 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1934 tcg_temp_free_i32(tmp2
);
1935 iwmmxt_store_creg(wrd
, tmp
);
1937 case ARM_IWMMXT_wCGR0
:
1938 case ARM_IWMMXT_wCGR1
:
1939 case ARM_IWMMXT_wCGR2
:
1940 case ARM_IWMMXT_wCGR3
:
1941 gen_op_iwmmxt_set_cup();
1942 tmp
= load_reg(s
, rd
);
1943 iwmmxt_store_creg(wrd
, tmp
);
1949 case 0x100: /* WXOR */
1950 wrd
= (insn
>> 12) & 0xf;
1951 rd0
= (insn
>> 0) & 0xf;
1952 rd1
= (insn
>> 16) & 0xf;
1953 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1954 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1955 gen_op_iwmmxt_setpsr_nz();
1956 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1957 gen_op_iwmmxt_set_mup();
1958 gen_op_iwmmxt_set_cup();
1960 case 0x111: /* TMRC */
1963 rd
= (insn
>> 12) & 0xf;
1964 wrd
= (insn
>> 16) & 0xf;
1965 tmp
= iwmmxt_load_creg(wrd
);
1966 store_reg(s
, rd
, tmp
);
1968 case 0x300: /* WANDN */
1969 wrd
= (insn
>> 12) & 0xf;
1970 rd0
= (insn
>> 0) & 0xf;
1971 rd1
= (insn
>> 16) & 0xf;
1972 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1973 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1974 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1975 gen_op_iwmmxt_setpsr_nz();
1976 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1977 gen_op_iwmmxt_set_mup();
1978 gen_op_iwmmxt_set_cup();
1980 case 0x200: /* WAND */
1981 wrd
= (insn
>> 12) & 0xf;
1982 rd0
= (insn
>> 0) & 0xf;
1983 rd1
= (insn
>> 16) & 0xf;
1984 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1985 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1986 gen_op_iwmmxt_setpsr_nz();
1987 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1988 gen_op_iwmmxt_set_mup();
1989 gen_op_iwmmxt_set_cup();
1991 case 0x810: case 0xa10: /* WMADD */
1992 wrd
= (insn
>> 12) & 0xf;
1993 rd0
= (insn
>> 0) & 0xf;
1994 rd1
= (insn
>> 16) & 0xf;
1995 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1996 if (insn
& (1 << 21))
1997 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1999 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
2000 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2001 gen_op_iwmmxt_set_mup();
2003 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2004 wrd
= (insn
>> 12) & 0xf;
2005 rd0
= (insn
>> 16) & 0xf;
2006 rd1
= (insn
>> 0) & 0xf;
2007 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2008 switch ((insn
>> 22) & 3) {
2010 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
2013 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
2016 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
2021 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2022 gen_op_iwmmxt_set_mup();
2023 gen_op_iwmmxt_set_cup();
2025 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2026 wrd
= (insn
>> 12) & 0xf;
2027 rd0
= (insn
>> 16) & 0xf;
2028 rd1
= (insn
>> 0) & 0xf;
2029 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2030 switch ((insn
>> 22) & 3) {
2032 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
2035 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
2038 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
2043 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2044 gen_op_iwmmxt_set_mup();
2045 gen_op_iwmmxt_set_cup();
2047 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2048 wrd
= (insn
>> 12) & 0xf;
2049 rd0
= (insn
>> 16) & 0xf;
2050 rd1
= (insn
>> 0) & 0xf;
2051 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2052 if (insn
& (1 << 22))
2053 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2055 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2056 if (!(insn
& (1 << 20)))
2057 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2058 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2059 gen_op_iwmmxt_set_mup();
2061 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2062 wrd
= (insn
>> 12) & 0xf;
2063 rd0
= (insn
>> 16) & 0xf;
2064 rd1
= (insn
>> 0) & 0xf;
2065 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2066 if (insn
& (1 << 21)) {
2067 if (insn
& (1 << 20))
2068 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2070 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2072 if (insn
& (1 << 20))
2073 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2075 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2077 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2078 gen_op_iwmmxt_set_mup();
2080 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2081 wrd
= (insn
>> 12) & 0xf;
2082 rd0
= (insn
>> 16) & 0xf;
2083 rd1
= (insn
>> 0) & 0xf;
2084 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2085 if (insn
& (1 << 21))
2086 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2088 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2089 if (!(insn
& (1 << 20))) {
2090 iwmmxt_load_reg(cpu_V1
, wrd
);
2091 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2093 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2094 gen_op_iwmmxt_set_mup();
2096 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2097 wrd
= (insn
>> 12) & 0xf;
2098 rd0
= (insn
>> 16) & 0xf;
2099 rd1
= (insn
>> 0) & 0xf;
2100 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2101 switch ((insn
>> 22) & 3) {
2103 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2106 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2109 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2114 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2115 gen_op_iwmmxt_set_mup();
2116 gen_op_iwmmxt_set_cup();
2118 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2119 wrd
= (insn
>> 12) & 0xf;
2120 rd0
= (insn
>> 16) & 0xf;
2121 rd1
= (insn
>> 0) & 0xf;
2122 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2123 if (insn
& (1 << 22)) {
2124 if (insn
& (1 << 20))
2125 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2127 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2129 if (insn
& (1 << 20))
2130 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2132 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2134 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2135 gen_op_iwmmxt_set_mup();
2136 gen_op_iwmmxt_set_cup();
2138 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2139 wrd
= (insn
>> 12) & 0xf;
2140 rd0
= (insn
>> 16) & 0xf;
2141 rd1
= (insn
>> 0) & 0xf;
2142 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2143 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2144 tcg_gen_andi_i32(tmp
, tmp
, 7);
2145 iwmmxt_load_reg(cpu_V1
, rd1
);
2146 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2147 tcg_temp_free_i32(tmp
);
2148 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2149 gen_op_iwmmxt_set_mup();
2151 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2152 if (((insn
>> 6) & 3) == 3)
2154 rd
= (insn
>> 12) & 0xf;
2155 wrd
= (insn
>> 16) & 0xf;
2156 tmp
= load_reg(s
, rd
);
2157 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2158 switch ((insn
>> 6) & 3) {
2160 tmp2
= tcg_const_i32(0xff);
2161 tmp3
= tcg_const_i32((insn
& 7) << 3);
2164 tmp2
= tcg_const_i32(0xffff);
2165 tmp3
= tcg_const_i32((insn
& 3) << 4);
2168 tmp2
= tcg_const_i32(0xffffffff);
2169 tmp3
= tcg_const_i32((insn
& 1) << 5);
2172 TCGV_UNUSED_I32(tmp2
);
2173 TCGV_UNUSED_I32(tmp3
);
2175 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2176 tcg_temp_free_i32(tmp3
);
2177 tcg_temp_free_i32(tmp2
);
2178 tcg_temp_free_i32(tmp
);
2179 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2180 gen_op_iwmmxt_set_mup();
2182 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2183 rd
= (insn
>> 12) & 0xf;
2184 wrd
= (insn
>> 16) & 0xf;
2185 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2187 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2188 tmp
= tcg_temp_new_i32();
2189 switch ((insn
>> 22) & 3) {
2191 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2192 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2194 tcg_gen_ext8s_i32(tmp
, tmp
);
2196 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2200 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2201 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2203 tcg_gen_ext16s_i32(tmp
, tmp
);
2205 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2209 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2210 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2213 store_reg(s
, rd
, tmp
);
2215 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2216 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2218 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2219 switch ((insn
>> 22) & 3) {
2221 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2224 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2227 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2230 tcg_gen_shli_i32(tmp
, tmp
, 28);
2232 tcg_temp_free_i32(tmp
);
2234 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2235 if (((insn
>> 6) & 3) == 3)
2237 rd
= (insn
>> 12) & 0xf;
2238 wrd
= (insn
>> 16) & 0xf;
2239 tmp
= load_reg(s
, rd
);
2240 switch ((insn
>> 6) & 3) {
2242 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2245 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2248 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2251 tcg_temp_free_i32(tmp
);
2252 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2253 gen_op_iwmmxt_set_mup();
2255 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2256 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2258 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2259 tmp2
= tcg_temp_new_i32();
2260 tcg_gen_mov_i32(tmp2
, tmp
);
2261 switch ((insn
>> 22) & 3) {
2263 for (i
= 0; i
< 7; i
++) {
2264 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2265 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2269 for (i
= 0; i
< 3; i
++) {
2270 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2271 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2275 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2276 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2280 tcg_temp_free_i32(tmp2
);
2281 tcg_temp_free_i32(tmp
);
2283 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2284 wrd
= (insn
>> 12) & 0xf;
2285 rd0
= (insn
>> 16) & 0xf;
2286 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2287 switch ((insn
>> 22) & 3) {
2289 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2292 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2295 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2300 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2301 gen_op_iwmmxt_set_mup();
2303 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2304 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2306 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2307 tmp2
= tcg_temp_new_i32();
2308 tcg_gen_mov_i32(tmp2
, tmp
);
2309 switch ((insn
>> 22) & 3) {
2311 for (i
= 0; i
< 7; i
++) {
2312 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2313 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2317 for (i
= 0; i
< 3; i
++) {
2318 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2319 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2323 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2324 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2328 tcg_temp_free_i32(tmp2
);
2329 tcg_temp_free_i32(tmp
);
2331 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2332 rd
= (insn
>> 12) & 0xf;
2333 rd0
= (insn
>> 16) & 0xf;
2334 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2336 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2337 tmp
= tcg_temp_new_i32();
2338 switch ((insn
>> 22) & 3) {
2340 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2343 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2346 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2349 store_reg(s
, rd
, tmp
);
2351 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2352 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2353 wrd
= (insn
>> 12) & 0xf;
2354 rd0
= (insn
>> 16) & 0xf;
2355 rd1
= (insn
>> 0) & 0xf;
2356 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2357 switch ((insn
>> 22) & 3) {
2359 if (insn
& (1 << 21))
2360 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2362 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2365 if (insn
& (1 << 21))
2366 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2368 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2371 if (insn
& (1 << 21))
2372 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2374 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2379 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2380 gen_op_iwmmxt_set_mup();
2381 gen_op_iwmmxt_set_cup();
2383 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2384 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2385 wrd
= (insn
>> 12) & 0xf;
2386 rd0
= (insn
>> 16) & 0xf;
2387 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2388 switch ((insn
>> 22) & 3) {
2390 if (insn
& (1 << 21))
2391 gen_op_iwmmxt_unpacklsb_M0();
2393 gen_op_iwmmxt_unpacklub_M0();
2396 if (insn
& (1 << 21))
2397 gen_op_iwmmxt_unpacklsw_M0();
2399 gen_op_iwmmxt_unpackluw_M0();
2402 if (insn
& (1 << 21))
2403 gen_op_iwmmxt_unpacklsl_M0();
2405 gen_op_iwmmxt_unpacklul_M0();
2410 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2411 gen_op_iwmmxt_set_mup();
2412 gen_op_iwmmxt_set_cup();
2414 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2415 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2416 wrd
= (insn
>> 12) & 0xf;
2417 rd0
= (insn
>> 16) & 0xf;
2418 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2419 switch ((insn
>> 22) & 3) {
2421 if (insn
& (1 << 21))
2422 gen_op_iwmmxt_unpackhsb_M0();
2424 gen_op_iwmmxt_unpackhub_M0();
2427 if (insn
& (1 << 21))
2428 gen_op_iwmmxt_unpackhsw_M0();
2430 gen_op_iwmmxt_unpackhuw_M0();
2433 if (insn
& (1 << 21))
2434 gen_op_iwmmxt_unpackhsl_M0();
2436 gen_op_iwmmxt_unpackhul_M0();
2441 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2442 gen_op_iwmmxt_set_mup();
2443 gen_op_iwmmxt_set_cup();
2445 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2446 case 0x214: case 0x614: case 0xa14: case 0xe14:
2447 if (((insn
>> 22) & 3) == 0)
2449 wrd
= (insn
>> 12) & 0xf;
2450 rd0
= (insn
>> 16) & 0xf;
2451 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2452 tmp
= tcg_temp_new_i32();
2453 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2454 tcg_temp_free_i32(tmp
);
2457 switch ((insn
>> 22) & 3) {
2459 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2462 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2465 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2468 tcg_temp_free_i32(tmp
);
2469 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2470 gen_op_iwmmxt_set_mup();
2471 gen_op_iwmmxt_set_cup();
2473 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2474 case 0x014: case 0x414: case 0x814: case 0xc14:
2475 if (((insn
>> 22) & 3) == 0)
2477 wrd
= (insn
>> 12) & 0xf;
2478 rd0
= (insn
>> 16) & 0xf;
2479 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2480 tmp
= tcg_temp_new_i32();
2481 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2482 tcg_temp_free_i32(tmp
);
2485 switch ((insn
>> 22) & 3) {
2487 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2490 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2493 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2496 tcg_temp_free_i32(tmp
);
2497 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2498 gen_op_iwmmxt_set_mup();
2499 gen_op_iwmmxt_set_cup();
2501 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2502 case 0x114: case 0x514: case 0x914: case 0xd14:
2503 if (((insn
>> 22) & 3) == 0)
2505 wrd
= (insn
>> 12) & 0xf;
2506 rd0
= (insn
>> 16) & 0xf;
2507 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2508 tmp
= tcg_temp_new_i32();
2509 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2510 tcg_temp_free_i32(tmp
);
2513 switch ((insn
>> 22) & 3) {
2515 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2518 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2521 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2524 tcg_temp_free_i32(tmp
);
2525 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2526 gen_op_iwmmxt_set_mup();
2527 gen_op_iwmmxt_set_cup();
2529 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2530 case 0x314: case 0x714: case 0xb14: case 0xf14:
2531 if (((insn
>> 22) & 3) == 0)
2533 wrd
= (insn
>> 12) & 0xf;
2534 rd0
= (insn
>> 16) & 0xf;
2535 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2536 tmp
= tcg_temp_new_i32();
2537 switch ((insn
>> 22) & 3) {
2539 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2540 tcg_temp_free_i32(tmp
);
2543 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2546 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2547 tcg_temp_free_i32(tmp
);
2550 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2553 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2554 tcg_temp_free_i32(tmp
);
2557 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2560 tcg_temp_free_i32(tmp
);
2561 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2562 gen_op_iwmmxt_set_mup();
2563 gen_op_iwmmxt_set_cup();
2565 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2566 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2567 wrd
= (insn
>> 12) & 0xf;
2568 rd0
= (insn
>> 16) & 0xf;
2569 rd1
= (insn
>> 0) & 0xf;
2570 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2571 switch ((insn
>> 22) & 3) {
2573 if (insn
& (1 << 21))
2574 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2576 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2579 if (insn
& (1 << 21))
2580 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2582 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2585 if (insn
& (1 << 21))
2586 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2588 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2593 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2594 gen_op_iwmmxt_set_mup();
2596 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2597 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2598 wrd
= (insn
>> 12) & 0xf;
2599 rd0
= (insn
>> 16) & 0xf;
2600 rd1
= (insn
>> 0) & 0xf;
2601 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2602 switch ((insn
>> 22) & 3) {
2604 if (insn
& (1 << 21))
2605 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2607 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2610 if (insn
& (1 << 21))
2611 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2613 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2616 if (insn
& (1 << 21))
2617 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2619 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2624 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2625 gen_op_iwmmxt_set_mup();
2627 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2628 case 0x402: case 0x502: case 0x602: case 0x702:
2629 wrd
= (insn
>> 12) & 0xf;
2630 rd0
= (insn
>> 16) & 0xf;
2631 rd1
= (insn
>> 0) & 0xf;
2632 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2633 tmp
= tcg_const_i32((insn
>> 20) & 3);
2634 iwmmxt_load_reg(cpu_V1
, rd1
);
2635 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2636 tcg_temp_free_i32(tmp
);
2637 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2638 gen_op_iwmmxt_set_mup();
2640 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2641 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2642 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2643 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2644 wrd
= (insn
>> 12) & 0xf;
2645 rd0
= (insn
>> 16) & 0xf;
2646 rd1
= (insn
>> 0) & 0xf;
2647 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2648 switch ((insn
>> 20) & 0xf) {
2650 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2653 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2656 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2659 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2662 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2665 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2668 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2671 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2674 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2679 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2680 gen_op_iwmmxt_set_mup();
2681 gen_op_iwmmxt_set_cup();
2683 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2684 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2685 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2686 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2687 wrd
= (insn
>> 12) & 0xf;
2688 rd0
= (insn
>> 16) & 0xf;
2689 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2690 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2691 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2692 tcg_temp_free_i32(tmp
);
2693 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2694 gen_op_iwmmxt_set_mup();
2695 gen_op_iwmmxt_set_cup();
2697 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2698 case 0x418: case 0x518: case 0x618: case 0x718:
2699 case 0x818: case 0x918: case 0xa18: case 0xb18:
2700 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2701 wrd
= (insn
>> 12) & 0xf;
2702 rd0
= (insn
>> 16) & 0xf;
2703 rd1
= (insn
>> 0) & 0xf;
2704 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2705 switch ((insn
>> 20) & 0xf) {
2707 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2710 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2713 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2716 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2719 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2722 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2725 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2728 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2731 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2736 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2737 gen_op_iwmmxt_set_mup();
2738 gen_op_iwmmxt_set_cup();
2740 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2741 case 0x408: case 0x508: case 0x608: case 0x708:
2742 case 0x808: case 0x908: case 0xa08: case 0xb08:
2743 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2744 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2746 wrd
= (insn
>> 12) & 0xf;
2747 rd0
= (insn
>> 16) & 0xf;
2748 rd1
= (insn
>> 0) & 0xf;
2749 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2750 switch ((insn
>> 22) & 3) {
2752 if (insn
& (1 << 21))
2753 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2755 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2758 if (insn
& (1 << 21))
2759 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2761 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2764 if (insn
& (1 << 21))
2765 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2767 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2770 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2771 gen_op_iwmmxt_set_mup();
2772 gen_op_iwmmxt_set_cup();
2774 case 0x201: case 0x203: case 0x205: case 0x207:
2775 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2776 case 0x211: case 0x213: case 0x215: case 0x217:
2777 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2778 wrd
= (insn
>> 5) & 0xf;
2779 rd0
= (insn
>> 12) & 0xf;
2780 rd1
= (insn
>> 0) & 0xf;
2781 if (rd0
== 0xf || rd1
== 0xf)
2783 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2784 tmp
= load_reg(s
, rd0
);
2785 tmp2
= load_reg(s
, rd1
);
2786 switch ((insn
>> 16) & 0xf) {
2787 case 0x0: /* TMIA */
2788 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2790 case 0x8: /* TMIAPH */
2791 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2793 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2794 if (insn
& (1 << 16))
2795 tcg_gen_shri_i32(tmp
, tmp
, 16);
2796 if (insn
& (1 << 17))
2797 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2798 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2801 tcg_temp_free_i32(tmp2
);
2802 tcg_temp_free_i32(tmp
);
2805 tcg_temp_free_i32(tmp2
);
2806 tcg_temp_free_i32(tmp
);
2807 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2808 gen_op_iwmmxt_set_mup();
2817 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2818 (ie. an undefined instruction). */
2819 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2821 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2824 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2825 /* Multiply with Internal Accumulate Format */
2826 rd0
= (insn
>> 12) & 0xf;
2828 acc
= (insn
>> 5) & 7;
2833 tmp
= load_reg(s
, rd0
);
2834 tmp2
= load_reg(s
, rd1
);
2835 switch ((insn
>> 16) & 0xf) {
2837 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2839 case 0x8: /* MIAPH */
2840 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2842 case 0xc: /* MIABB */
2843 case 0xd: /* MIABT */
2844 case 0xe: /* MIATB */
2845 case 0xf: /* MIATT */
2846 if (insn
& (1 << 16))
2847 tcg_gen_shri_i32(tmp
, tmp
, 16);
2848 if (insn
& (1 << 17))
2849 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2850 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2855 tcg_temp_free_i32(tmp2
);
2856 tcg_temp_free_i32(tmp
);
2858 gen_op_iwmmxt_movq_wRn_M0(acc
);
2862 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2863 /* Internal Accumulator Access Format */
2864 rdhi
= (insn
>> 16) & 0xf;
2865 rdlo
= (insn
>> 12) & 0xf;
2871 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2872 iwmmxt_load_reg(cpu_V0
, acc
);
2873 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2874 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2875 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2876 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2878 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2879 iwmmxt_store_reg(cpu_V0
, acc
);
2887 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2888 #define VFP_SREG(insn, bigbit, smallbit) \
2889 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2890 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2891 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2892 reg = (((insn) >> (bigbit)) & 0x0f) \
2893 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2895 if (insn & (1 << (smallbit))) \
2897 reg = ((insn) >> (bigbit)) & 0x0f; \
2900 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2901 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2902 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2903 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2904 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2905 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2907 /* Move between integer and VFP cores. */
2908 static TCGv_i32
gen_vfp_mrs(void)
2910 TCGv_i32 tmp
= tcg_temp_new_i32();
2911 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2915 static void gen_vfp_msr(TCGv_i32 tmp
)
2917 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2918 tcg_temp_free_i32(tmp
);
2921 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2923 TCGv_i32 tmp
= tcg_temp_new_i32();
2925 tcg_gen_shri_i32(var
, var
, shift
);
2926 tcg_gen_ext8u_i32(var
, var
);
2927 tcg_gen_shli_i32(tmp
, var
, 8);
2928 tcg_gen_or_i32(var
, var
, tmp
);
2929 tcg_gen_shli_i32(tmp
, var
, 16);
2930 tcg_gen_or_i32(var
, var
, tmp
);
2931 tcg_temp_free_i32(tmp
);
2934 static void gen_neon_dup_low16(TCGv_i32 var
)
2936 TCGv_i32 tmp
= tcg_temp_new_i32();
2937 tcg_gen_ext16u_i32(var
, var
);
2938 tcg_gen_shli_i32(tmp
, var
, 16);
2939 tcg_gen_or_i32(var
, var
, tmp
);
2940 tcg_temp_free_i32(tmp
);
2943 static void gen_neon_dup_high16(TCGv_i32 var
)
2945 TCGv_i32 tmp
= tcg_temp_new_i32();
2946 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2947 tcg_gen_shri_i32(tmp
, var
, 16);
2948 tcg_gen_or_i32(var
, var
, tmp
);
2949 tcg_temp_free_i32(tmp
);
2952 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2954 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2955 TCGv_i32 tmp
= tcg_temp_new_i32();
2958 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2959 gen_neon_dup_u8(tmp
, 0);
2962 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2963 gen_neon_dup_low16(tmp
);
2966 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2968 default: /* Avoid compiler warnings. */
2974 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2977 uint32_t cc
= extract32(insn
, 20, 2);
2980 TCGv_i64 frn
, frm
, dest
;
2981 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2983 zero
= tcg_const_i64(0);
2985 frn
= tcg_temp_new_i64();
2986 frm
= tcg_temp_new_i64();
2987 dest
= tcg_temp_new_i64();
2989 zf
= tcg_temp_new_i64();
2990 nf
= tcg_temp_new_i64();
2991 vf
= tcg_temp_new_i64();
2993 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2994 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2995 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2997 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2998 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3001 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
3005 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
3008 case 2: /* ge: N == V -> N ^ V == 0 */
3009 tmp
= tcg_temp_new_i64();
3010 tcg_gen_xor_i64(tmp
, vf
, nf
);
3011 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
3013 tcg_temp_free_i64(tmp
);
3015 case 3: /* gt: !Z && N == V */
3016 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
3018 tmp
= tcg_temp_new_i64();
3019 tcg_gen_xor_i64(tmp
, vf
, nf
);
3020 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
3022 tcg_temp_free_i64(tmp
);
3025 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3026 tcg_temp_free_i64(frn
);
3027 tcg_temp_free_i64(frm
);
3028 tcg_temp_free_i64(dest
);
3030 tcg_temp_free_i64(zf
);
3031 tcg_temp_free_i64(nf
);
3032 tcg_temp_free_i64(vf
);
3034 tcg_temp_free_i64(zero
);
3036 TCGv_i32 frn
, frm
, dest
;
3039 zero
= tcg_const_i32(0);
3041 frn
= tcg_temp_new_i32();
3042 frm
= tcg_temp_new_i32();
3043 dest
= tcg_temp_new_i32();
3044 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3045 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3048 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
3052 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
3055 case 2: /* ge: N == V -> N ^ V == 0 */
3056 tmp
= tcg_temp_new_i32();
3057 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3058 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3060 tcg_temp_free_i32(tmp
);
3062 case 3: /* gt: !Z && N == V */
3063 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
3065 tmp
= tcg_temp_new_i32();
3066 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3067 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3069 tcg_temp_free_i32(tmp
);
3072 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3073 tcg_temp_free_i32(frn
);
3074 tcg_temp_free_i32(frm
);
3075 tcg_temp_free_i32(dest
);
3077 tcg_temp_free_i32(zero
);
3083 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
3084 uint32_t rm
, uint32_t dp
)
3086 uint32_t vmin
= extract32(insn
, 6, 1);
3087 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3090 TCGv_i64 frn
, frm
, dest
;
3092 frn
= tcg_temp_new_i64();
3093 frm
= tcg_temp_new_i64();
3094 dest
= tcg_temp_new_i64();
3096 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3097 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3099 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
3101 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
3103 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3104 tcg_temp_free_i64(frn
);
3105 tcg_temp_free_i64(frm
);
3106 tcg_temp_free_i64(dest
);
3108 TCGv_i32 frn
, frm
, dest
;
3110 frn
= tcg_temp_new_i32();
3111 frm
= tcg_temp_new_i32();
3112 dest
= tcg_temp_new_i32();
3114 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3115 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3117 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
3119 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
3121 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3122 tcg_temp_free_i32(frn
);
3123 tcg_temp_free_i32(frm
);
3124 tcg_temp_free_i32(dest
);
3127 tcg_temp_free_ptr(fpst
);
3131 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3134 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3137 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3138 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3143 tcg_op
= tcg_temp_new_i64();
3144 tcg_res
= tcg_temp_new_i64();
3145 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3146 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
3147 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3148 tcg_temp_free_i64(tcg_op
);
3149 tcg_temp_free_i64(tcg_res
);
3153 tcg_op
= tcg_temp_new_i32();
3154 tcg_res
= tcg_temp_new_i32();
3155 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3156 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
3157 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3158 tcg_temp_free_i32(tcg_op
);
3159 tcg_temp_free_i32(tcg_res
);
3162 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3163 tcg_temp_free_i32(tcg_rmode
);
3165 tcg_temp_free_ptr(fpst
);
3169 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3172 bool is_signed
= extract32(insn
, 7, 1);
3173 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3174 TCGv_i32 tcg_rmode
, tcg_shift
;
3176 tcg_shift
= tcg_const_i32(0);
3178 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3179 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3182 TCGv_i64 tcg_double
, tcg_res
;
3184 /* Rd is encoded as a single precision register even when the source
3185 * is double precision.
3187 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3188 tcg_double
= tcg_temp_new_i64();
3189 tcg_res
= tcg_temp_new_i64();
3190 tcg_tmp
= tcg_temp_new_i32();
3191 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3193 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3195 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3197 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3198 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3199 tcg_temp_free_i32(tcg_tmp
);
3200 tcg_temp_free_i64(tcg_res
);
3201 tcg_temp_free_i64(tcg_double
);
3203 TCGv_i32 tcg_single
, tcg_res
;
3204 tcg_single
= tcg_temp_new_i32();
3205 tcg_res
= tcg_temp_new_i32();
3206 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3208 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3210 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3212 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3213 tcg_temp_free_i32(tcg_res
);
3214 tcg_temp_free_i32(tcg_single
);
3217 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3218 tcg_temp_free_i32(tcg_rmode
);
3220 tcg_temp_free_i32(tcg_shift
);
3222 tcg_temp_free_ptr(fpst
);
3227 /* Table for converting the most common AArch32 encoding of
3228 * rounding mode to arm_fprounding order (which matches the
3229 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3231 static const uint8_t fp_decode_rm
[] = {
3238 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3240 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3242 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3247 VFP_DREG_D(rd
, insn
);
3248 VFP_DREG_N(rn
, insn
);
3249 VFP_DREG_M(rm
, insn
);
3251 rd
= VFP_SREG_D(insn
);
3252 rn
= VFP_SREG_N(insn
);
3253 rm
= VFP_SREG_M(insn
);
3256 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3257 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3258 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3259 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3260 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3261 /* VRINTA, VRINTN, VRINTP, VRINTM */
3262 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3263 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3264 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3265 /* VCVTA, VCVTN, VCVTP, VCVTM */
3266 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3267 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3272 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3273 (ie. an undefined instruction). */
3274 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3276 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3282 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3286 /* FIXME: this access check should not take precedence over UNDEF
3287 * for invalid encodings; we will generate incorrect syndrome information
3288 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3290 if (s
->fp_excp_el
) {
3291 gen_exception_insn(s
, 4, EXCP_UDEF
,
3292 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3296 if (!s
->vfp_enabled
) {
3297 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3298 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3300 rn
= (insn
>> 16) & 0xf;
3301 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3302 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3307 if (extract32(insn
, 28, 4) == 0xf) {
3308 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3309 * only used in v8 and above.
3311 return disas_vfp_v8_insn(s
, insn
);
3314 dp
= ((insn
& 0xf00) == 0xb00);
3315 switch ((insn
>> 24) & 0xf) {
3317 if (insn
& (1 << 4)) {
3318 /* single register transfer */
3319 rd
= (insn
>> 12) & 0xf;
3324 VFP_DREG_N(rn
, insn
);
3327 if (insn
& 0x00c00060
3328 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3332 pass
= (insn
>> 21) & 1;
3333 if (insn
& (1 << 22)) {
3335 offset
= ((insn
>> 5) & 3) * 8;
3336 } else if (insn
& (1 << 5)) {
3338 offset
= (insn
& (1 << 6)) ? 16 : 0;
3343 if (insn
& ARM_CP_RW_BIT
) {
3345 tmp
= neon_load_reg(rn
, pass
);
3349 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3350 if (insn
& (1 << 23))
3356 if (insn
& (1 << 23)) {
3358 tcg_gen_shri_i32(tmp
, tmp
, 16);
3364 tcg_gen_sari_i32(tmp
, tmp
, 16);
3373 store_reg(s
, rd
, tmp
);
3376 tmp
= load_reg(s
, rd
);
3377 if (insn
& (1 << 23)) {
3380 gen_neon_dup_u8(tmp
, 0);
3381 } else if (size
== 1) {
3382 gen_neon_dup_low16(tmp
);
3384 for (n
= 0; n
<= pass
* 2; n
++) {
3385 tmp2
= tcg_temp_new_i32();
3386 tcg_gen_mov_i32(tmp2
, tmp
);
3387 neon_store_reg(rn
, n
, tmp2
);
3389 neon_store_reg(rn
, n
, tmp
);
3394 tmp2
= neon_load_reg(rn
, pass
);
3395 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3396 tcg_temp_free_i32(tmp2
);
3399 tmp2
= neon_load_reg(rn
, pass
);
3400 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3401 tcg_temp_free_i32(tmp2
);
3406 neon_store_reg(rn
, pass
, tmp
);
3410 if ((insn
& 0x6f) != 0x00)
3412 rn
= VFP_SREG_N(insn
);
3413 if (insn
& ARM_CP_RW_BIT
) {
3415 if (insn
& (1 << 21)) {
3416 /* system register */
3421 /* VFP2 allows access to FSID from userspace.
3422 VFP3 restricts all id registers to privileged
3425 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3428 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3433 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3435 case ARM_VFP_FPINST
:
3436 case ARM_VFP_FPINST2
:
3437 /* Not present in VFP3. */
3439 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3442 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3446 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3447 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3449 tmp
= tcg_temp_new_i32();
3450 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3454 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3461 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3464 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3470 gen_mov_F0_vreg(0, rn
);
3471 tmp
= gen_vfp_mrs();
3474 /* Set the 4 flag bits in the CPSR. */
3476 tcg_temp_free_i32(tmp
);
3478 store_reg(s
, rd
, tmp
);
3482 if (insn
& (1 << 21)) {
3484 /* system register */
3489 /* Writes are ignored. */
3492 tmp
= load_reg(s
, rd
);
3493 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3494 tcg_temp_free_i32(tmp
);
3500 /* TODO: VFP subarchitecture support.
3501 * For now, keep the EN bit only */
3502 tmp
= load_reg(s
, rd
);
3503 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3504 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3507 case ARM_VFP_FPINST
:
3508 case ARM_VFP_FPINST2
:
3512 tmp
= load_reg(s
, rd
);
3513 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3519 tmp
= load_reg(s
, rd
);
3521 gen_mov_vreg_F0(0, rn
);
3526 /* data processing */
3527 /* The opcode is in bits 23, 21, 20 and 6. */
3528 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3532 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3534 /* rn is register number */
3535 VFP_DREG_N(rn
, insn
);
3538 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3539 ((rn
& 0x1e) == 0x6))) {
3540 /* Integer or single/half precision destination. */
3541 rd
= VFP_SREG_D(insn
);
3543 VFP_DREG_D(rd
, insn
);
3546 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3547 ((rn
& 0x1e) == 0x4))) {
3548 /* VCVT from int or half precision is always from S reg
3549 * regardless of dp bit. VCVT with immediate frac_bits
3550 * has same format as SREG_M.
3552 rm
= VFP_SREG_M(insn
);
3554 VFP_DREG_M(rm
, insn
);
3557 rn
= VFP_SREG_N(insn
);
3558 if (op
== 15 && rn
== 15) {
3559 /* Double precision destination. */
3560 VFP_DREG_D(rd
, insn
);
3562 rd
= VFP_SREG_D(insn
);
3564 /* NB that we implicitly rely on the encoding for the frac_bits
3565 * in VCVT of fixed to float being the same as that of an SREG_M
3567 rm
= VFP_SREG_M(insn
);
3570 veclen
= s
->vec_len
;
3571 if (op
== 15 && rn
> 3)
3574 /* Shut up compiler warnings. */
3585 /* Figure out what type of vector operation this is. */
3586 if ((rd
& bank_mask
) == 0) {
3591 delta_d
= (s
->vec_stride
>> 1) + 1;
3593 delta_d
= s
->vec_stride
+ 1;
3595 if ((rm
& bank_mask
) == 0) {
3596 /* mixed scalar/vector */
3605 /* Load the initial operands. */
3610 /* Integer source */
3611 gen_mov_F0_vreg(0, rm
);
3616 gen_mov_F0_vreg(dp
, rd
);
3617 gen_mov_F1_vreg(dp
, rm
);
3621 /* Compare with zero */
3622 gen_mov_F0_vreg(dp
, rd
);
3633 /* Source and destination the same. */
3634 gen_mov_F0_vreg(dp
, rd
);
3640 /* VCVTB, VCVTT: only present with the halfprec extension
3641 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3642 * (we choose to UNDEF)
3644 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3645 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3648 if (!extract32(rn
, 1, 1)) {
3649 /* Half precision source. */
3650 gen_mov_F0_vreg(0, rm
);
3653 /* Otherwise fall through */
3655 /* One source operand. */
3656 gen_mov_F0_vreg(dp
, rm
);
3660 /* Two source operands. */
3661 gen_mov_F0_vreg(dp
, rn
);
3662 gen_mov_F1_vreg(dp
, rm
);
3666 /* Perform the calculation. */
3668 case 0: /* VMLA: fd + (fn * fm) */
3669 /* Note that order of inputs to the add matters for NaNs */
3671 gen_mov_F0_vreg(dp
, rd
);
3674 case 1: /* VMLS: fd + -(fn * fm) */
3677 gen_mov_F0_vreg(dp
, rd
);
3680 case 2: /* VNMLS: -fd + (fn * fm) */
3681 /* Note that it isn't valid to replace (-A + B) with (B - A)
3682 * or similar plausible looking simplifications
3683 * because this will give wrong results for NaNs.
3686 gen_mov_F0_vreg(dp
, rd
);
3690 case 3: /* VNMLA: -fd + -(fn * fm) */
3693 gen_mov_F0_vreg(dp
, rd
);
3697 case 4: /* mul: fn * fm */
3700 case 5: /* nmul: -(fn * fm) */
3704 case 6: /* add: fn + fm */
3707 case 7: /* sub: fn - fm */
3710 case 8: /* div: fn / fm */
3713 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3714 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3715 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3716 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3717 /* These are fused multiply-add, and must be done as one
3718 * floating point operation with no rounding between the
3719 * multiplication and addition steps.
3720 * NB that doing the negations here as separate steps is
3721 * correct : an input NaN should come out with its sign bit
3722 * flipped if it is a negated-input.
3724 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3732 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3734 frd
= tcg_temp_new_i64();
3735 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3738 gen_helper_vfp_negd(frd
, frd
);
3740 fpst
= get_fpstatus_ptr(0);
3741 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3742 cpu_F1d
, frd
, fpst
);
3743 tcg_temp_free_ptr(fpst
);
3744 tcg_temp_free_i64(frd
);
3750 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3752 frd
= tcg_temp_new_i32();
3753 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3755 gen_helper_vfp_negs(frd
, frd
);
3757 fpst
= get_fpstatus_ptr(0);
3758 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3759 cpu_F1s
, frd
, fpst
);
3760 tcg_temp_free_ptr(fpst
);
3761 tcg_temp_free_i32(frd
);
3764 case 14: /* fconst */
3765 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3769 n
= (insn
<< 12) & 0x80000000;
3770 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3777 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3784 tcg_gen_movi_i32(cpu_F0s
, n
);
3787 case 15: /* extension space */
3801 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3802 tmp
= gen_vfp_mrs();
3803 tcg_gen_ext16u_i32(tmp
, tmp
);
3805 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3808 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3811 tcg_temp_free_i32(tmp
);
3813 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3814 tmp
= gen_vfp_mrs();
3815 tcg_gen_shri_i32(tmp
, tmp
, 16);
3817 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3820 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3823 tcg_temp_free_i32(tmp
);
3825 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3826 tmp
= tcg_temp_new_i32();
3828 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3831 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3834 gen_mov_F0_vreg(0, rd
);
3835 tmp2
= gen_vfp_mrs();
3836 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3837 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3838 tcg_temp_free_i32(tmp2
);
3841 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3842 tmp
= tcg_temp_new_i32();
3844 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3847 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3850 tcg_gen_shli_i32(tmp
, tmp
, 16);
3851 gen_mov_F0_vreg(0, rd
);
3852 tmp2
= gen_vfp_mrs();
3853 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3854 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3855 tcg_temp_free_i32(tmp2
);
3867 case 11: /* cmpez */
3871 case 12: /* vrintr */
3873 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3875 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3877 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3879 tcg_temp_free_ptr(fpst
);
3882 case 13: /* vrintz */
3884 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3886 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3887 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3889 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3891 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3893 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3894 tcg_temp_free_i32(tcg_rmode
);
3895 tcg_temp_free_ptr(fpst
);
3898 case 14: /* vrintx */
3900 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3902 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3904 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3906 tcg_temp_free_ptr(fpst
);
3909 case 15: /* single<->double conversion */
3911 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3913 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3915 case 16: /* fuito */
3916 gen_vfp_uito(dp
, 0);
3918 case 17: /* fsito */
3919 gen_vfp_sito(dp
, 0);
3921 case 20: /* fshto */
3922 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3925 gen_vfp_shto(dp
, 16 - rm
, 0);
3927 case 21: /* fslto */
3928 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3931 gen_vfp_slto(dp
, 32 - rm
, 0);
3933 case 22: /* fuhto */
3934 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3937 gen_vfp_uhto(dp
, 16 - rm
, 0);
3939 case 23: /* fulto */
3940 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3943 gen_vfp_ulto(dp
, 32 - rm
, 0);
3945 case 24: /* ftoui */
3946 gen_vfp_toui(dp
, 0);
3948 case 25: /* ftouiz */
3949 gen_vfp_touiz(dp
, 0);
3951 case 26: /* ftosi */
3952 gen_vfp_tosi(dp
, 0);
3954 case 27: /* ftosiz */
3955 gen_vfp_tosiz(dp
, 0);
3957 case 28: /* ftosh */
3958 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3961 gen_vfp_tosh(dp
, 16 - rm
, 0);
3963 case 29: /* ftosl */
3964 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3967 gen_vfp_tosl(dp
, 32 - rm
, 0);
3969 case 30: /* ftouh */
3970 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3973 gen_vfp_touh(dp
, 16 - rm
, 0);
3975 case 31: /* ftoul */
3976 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3979 gen_vfp_toul(dp
, 32 - rm
, 0);
3981 default: /* undefined */
3985 default: /* undefined */
3989 /* Write back the result. */
3990 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3991 /* Comparison, do nothing. */
3992 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3993 (rn
& 0x1e) == 0x6)) {
3994 /* VCVT double to int: always integer result.
3995 * VCVT double to half precision is always a single
3998 gen_mov_vreg_F0(0, rd
);
3999 } else if (op
== 15 && rn
== 15) {
4001 gen_mov_vreg_F0(!dp
, rd
);
4003 gen_mov_vreg_F0(dp
, rd
);
4006 /* break out of the loop if we have finished */
4010 if (op
== 15 && delta_m
== 0) {
4011 /* single source one-many */
4013 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
4015 gen_mov_vreg_F0(dp
, rd
);
4019 /* Setup the next operands. */
4021 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
4025 /* One source operand. */
4026 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
4028 gen_mov_F0_vreg(dp
, rm
);
4030 /* Two source operands. */
4031 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
4033 gen_mov_F0_vreg(dp
, rn
);
4035 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
4037 gen_mov_F1_vreg(dp
, rm
);
4045 if ((insn
& 0x03e00000) == 0x00400000) {
4046 /* two-register transfer */
4047 rn
= (insn
>> 16) & 0xf;
4048 rd
= (insn
>> 12) & 0xf;
4050 VFP_DREG_M(rm
, insn
);
4052 rm
= VFP_SREG_M(insn
);
4055 if (insn
& ARM_CP_RW_BIT
) {
4058 gen_mov_F0_vreg(0, rm
* 2);
4059 tmp
= gen_vfp_mrs();
4060 store_reg(s
, rd
, tmp
);
4061 gen_mov_F0_vreg(0, rm
* 2 + 1);
4062 tmp
= gen_vfp_mrs();
4063 store_reg(s
, rn
, tmp
);
4065 gen_mov_F0_vreg(0, rm
);
4066 tmp
= gen_vfp_mrs();
4067 store_reg(s
, rd
, tmp
);
4068 gen_mov_F0_vreg(0, rm
+ 1);
4069 tmp
= gen_vfp_mrs();
4070 store_reg(s
, rn
, tmp
);
4075 tmp
= load_reg(s
, rd
);
4077 gen_mov_vreg_F0(0, rm
* 2);
4078 tmp
= load_reg(s
, rn
);
4080 gen_mov_vreg_F0(0, rm
* 2 + 1);
4082 tmp
= load_reg(s
, rd
);
4084 gen_mov_vreg_F0(0, rm
);
4085 tmp
= load_reg(s
, rn
);
4087 gen_mov_vreg_F0(0, rm
+ 1);
4092 rn
= (insn
>> 16) & 0xf;
4094 VFP_DREG_D(rd
, insn
);
4096 rd
= VFP_SREG_D(insn
);
4097 if ((insn
& 0x01200000) == 0x01000000) {
4098 /* Single load/store */
4099 offset
= (insn
& 0xff) << 2;
4100 if ((insn
& (1 << 23)) == 0)
4102 if (s
->thumb
&& rn
== 15) {
4103 /* This is actually UNPREDICTABLE */
4104 addr
= tcg_temp_new_i32();
4105 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4107 addr
= load_reg(s
, rn
);
4109 tcg_gen_addi_i32(addr
, addr
, offset
);
4110 if (insn
& (1 << 20)) {
4111 gen_vfp_ld(s
, dp
, addr
);
4112 gen_mov_vreg_F0(dp
, rd
);
4114 gen_mov_F0_vreg(dp
, rd
);
4115 gen_vfp_st(s
, dp
, addr
);
4117 tcg_temp_free_i32(addr
);
4119 /* load/store multiple */
4120 int w
= insn
& (1 << 21);
4122 n
= (insn
>> 1) & 0x7f;
4126 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
4127 /* P == U , W == 1 => UNDEF */
4130 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
4131 /* UNPREDICTABLE cases for bad immediates: we choose to
4132 * UNDEF to avoid generating huge numbers of TCG ops
4136 if (rn
== 15 && w
) {
4137 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4141 if (s
->thumb
&& rn
== 15) {
4142 /* This is actually UNPREDICTABLE */
4143 addr
= tcg_temp_new_i32();
4144 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4146 addr
= load_reg(s
, rn
);
4148 if (insn
& (1 << 24)) /* pre-decrement */
4149 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4155 for (i
= 0; i
< n
; i
++) {
4156 if (insn
& ARM_CP_RW_BIT
) {
4158 gen_vfp_ld(s
, dp
, addr
);
4159 gen_mov_vreg_F0(dp
, rd
+ i
);
4162 gen_mov_F0_vreg(dp
, rd
+ i
);
4163 gen_vfp_st(s
, dp
, addr
);
4165 tcg_gen_addi_i32(addr
, addr
, offset
);
4169 if (insn
& (1 << 24))
4170 offset
= -offset
* n
;
4171 else if (dp
&& (insn
& 1))
4177 tcg_gen_addi_i32(addr
, addr
, offset
);
4178 store_reg(s
, rn
, addr
);
4180 tcg_temp_free_i32(addr
);
4186 /* Should never happen. */
4192 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4194 #ifndef CONFIG_USER_ONLY
4195 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4196 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4202 static void gen_goto_ptr(void)
4204 tcg_gen_lookup_and_goto_ptr();
4207 /* This will end the TB but doesn't guarantee we'll return to
4208 * cpu_loop_exec. Any live exit_requests will be processed as we
4209 * enter the next TB.
4211 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4213 if (use_goto_tb(s
, dest
)) {
4215 gen_set_pc_im(s
, dest
);
4216 tcg_gen_exit_tb((uintptr_t)s
->base
.tb
+ n
);
4218 gen_set_pc_im(s
, dest
);
4221 s
->base
.is_jmp
= DISAS_NORETURN
;
4224 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4226 if (unlikely(is_singlestepping(s
))) {
4227 /* An indirect jump so that we still trigger the debug exception. */
4232 gen_goto_tb(s
, 0, dest
);
4236 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4239 tcg_gen_sari_i32(t0
, t0
, 16);
4243 tcg_gen_sari_i32(t1
, t1
, 16);
4246 tcg_gen_mul_i32(t0
, t0
, t1
);
4249 /* Return the mask of PSR bits set by a MSR instruction. */
4250 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4255 if (flags
& (1 << 0))
4257 if (flags
& (1 << 1))
4259 if (flags
& (1 << 2))
4261 if (flags
& (1 << 3))
4264 /* Mask out undefined bits. */
4265 mask
&= ~CPSR_RESERVED
;
4266 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4269 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4270 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4272 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4273 mask
&= ~(CPSR_E
| CPSR_GE
);
4275 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4278 /* Mask out execution state and reserved bits. */
4280 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4282 /* Mask out privileged bits. */
4288 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4289 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4293 /* ??? This is also undefined in system mode. */
4297 tmp
= load_cpu_field(spsr
);
4298 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4299 tcg_gen_andi_i32(t0
, t0
, mask
);
4300 tcg_gen_or_i32(tmp
, tmp
, t0
);
4301 store_cpu_field(tmp
, spsr
);
4303 gen_set_cpsr(t0
, mask
);
4305 tcg_temp_free_i32(t0
);
4310 /* Returns nonzero if access to the PSR is not permitted. */
4311 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4314 tmp
= tcg_temp_new_i32();
4315 tcg_gen_movi_i32(tmp
, val
);
4316 return gen_set_psr(s
, mask
, spsr
, tmp
);
4319 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4320 int *tgtmode
, int *regno
)
4322 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4323 * the target mode and register number, and identify the various
4324 * unpredictable cases.
4325 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4326 * + executed in user mode
4327 * + using R15 as the src/dest register
4328 * + accessing an unimplemented register
4329 * + accessing a register that's inaccessible at current PL/security state*
4330 * + accessing a register that you could access with a different insn
4331 * We choose to UNDEF in all these cases.
4332 * Since we don't know which of the various AArch32 modes we are in
4333 * we have to defer some checks to runtime.
4334 * Accesses to Monitor mode registers from Secure EL1 (which implies
4335 * that EL3 is AArch64) must trap to EL3.
4337 * If the access checks fail this function will emit code to take
4338 * an exception and return false. Otherwise it will return true,
4339 * and set *tgtmode and *regno appropriately.
4341 int exc_target
= default_exception_el(s
);
4343 /* These instructions are present only in ARMv8, or in ARMv7 with the
4344 * Virtualization Extensions.
4346 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4347 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4351 if (IS_USER(s
) || rn
== 15) {
4355 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4356 * of registers into (r, sysm).
4359 /* SPSRs for other modes */
4361 case 0xe: /* SPSR_fiq */
4362 *tgtmode
= ARM_CPU_MODE_FIQ
;
4364 case 0x10: /* SPSR_irq */
4365 *tgtmode
= ARM_CPU_MODE_IRQ
;
4367 case 0x12: /* SPSR_svc */
4368 *tgtmode
= ARM_CPU_MODE_SVC
;
4370 case 0x14: /* SPSR_abt */
4371 *tgtmode
= ARM_CPU_MODE_ABT
;
4373 case 0x16: /* SPSR_und */
4374 *tgtmode
= ARM_CPU_MODE_UND
;
4376 case 0x1c: /* SPSR_mon */
4377 *tgtmode
= ARM_CPU_MODE_MON
;
4379 case 0x1e: /* SPSR_hyp */
4380 *tgtmode
= ARM_CPU_MODE_HYP
;
4382 default: /* unallocated */
4385 /* We arbitrarily assign SPSR a register number of 16. */
4388 /* general purpose registers for other modes */
4390 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4391 *tgtmode
= ARM_CPU_MODE_USR
;
4394 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4395 *tgtmode
= ARM_CPU_MODE_FIQ
;
4398 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4399 *tgtmode
= ARM_CPU_MODE_IRQ
;
4400 *regno
= sysm
& 1 ? 13 : 14;
4402 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4403 *tgtmode
= ARM_CPU_MODE_SVC
;
4404 *regno
= sysm
& 1 ? 13 : 14;
4406 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4407 *tgtmode
= ARM_CPU_MODE_ABT
;
4408 *regno
= sysm
& 1 ? 13 : 14;
4410 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4411 *tgtmode
= ARM_CPU_MODE_UND
;
4412 *regno
= sysm
& 1 ? 13 : 14;
4414 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4415 *tgtmode
= ARM_CPU_MODE_MON
;
4416 *regno
= sysm
& 1 ? 13 : 14;
4418 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4419 *tgtmode
= ARM_CPU_MODE_HYP
;
4420 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4421 *regno
= sysm
& 1 ? 13 : 17;
4423 default: /* unallocated */
4428 /* Catch the 'accessing inaccessible register' cases we can detect
4429 * at translate time.
4432 case ARM_CPU_MODE_MON
:
4433 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4436 if (s
->current_el
== 1) {
4437 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4438 * then accesses to Mon registers trap to EL3
4444 case ARM_CPU_MODE_HYP
:
4445 /* Note that we can forbid accesses from EL2 here because they
4446 * must be from Hyp mode itself
4448 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4459 /* If we get here then some access check did not pass */
4460 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4464 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4466 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4467 int tgtmode
= 0, regno
= 0;
4469 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4473 /* Sync state because msr_banked() can raise exceptions */
4474 gen_set_condexec(s
);
4475 gen_set_pc_im(s
, s
->pc
- 4);
4476 tcg_reg
= load_reg(s
, rn
);
4477 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4478 tcg_regno
= tcg_const_i32(regno
);
4479 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4480 tcg_temp_free_i32(tcg_tgtmode
);
4481 tcg_temp_free_i32(tcg_regno
);
4482 tcg_temp_free_i32(tcg_reg
);
4483 s
->base
.is_jmp
= DISAS_UPDATE
;
4486 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4488 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4489 int tgtmode
= 0, regno
= 0;
4491 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4495 /* Sync state because mrs_banked() can raise exceptions */
4496 gen_set_condexec(s
);
4497 gen_set_pc_im(s
, s
->pc
- 4);
4498 tcg_reg
= tcg_temp_new_i32();
4499 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4500 tcg_regno
= tcg_const_i32(regno
);
4501 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4502 tcg_temp_free_i32(tcg_tgtmode
);
4503 tcg_temp_free_i32(tcg_regno
);
4504 store_reg(s
, rn
, tcg_reg
);
4505 s
->base
.is_jmp
= DISAS_UPDATE
;
4508 /* Store value to PC as for an exception return (ie don't
4509 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4510 * will do the masking based on the new value of the Thumb bit.
4512 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4514 tcg_gen_mov_i32(cpu_R
[15], pc
);
4515 tcg_temp_free_i32(pc
);
4518 /* Generate a v6 exception return. Marks both values as dead. */
4519 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4521 store_pc_exc_ret(s
, pc
);
4522 /* The cpsr_write_eret helper will mask the low bits of PC
4523 * appropriately depending on the new Thumb bit, so it must
4524 * be called after storing the new PC.
4526 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4527 tcg_temp_free_i32(cpsr
);
4528 /* Must exit loop to check un-masked IRQs */
4529 s
->base
.is_jmp
= DISAS_EXIT
;
4532 /* Generate an old-style exception return. Marks pc as dead. */
4533 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4535 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4539 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4540 * only call the helper when running single threaded TCG code to ensure
4541 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4542 * just skip this instruction. Currently the SEV/SEVL instructions
4543 * which are *one* of many ways to wake the CPU from WFE are not
4544 * implemented so we can't sleep like WFI does.
4546 static void gen_nop_hint(DisasContext
*s
, int val
)
4550 if (!parallel_cpus
) {
4551 gen_set_pc_im(s
, s
->pc
);
4552 s
->base
.is_jmp
= DISAS_YIELD
;
4556 gen_set_pc_im(s
, s
->pc
);
4557 s
->base
.is_jmp
= DISAS_WFI
;
4560 if (!parallel_cpus
) {
4561 gen_set_pc_im(s
, s
->pc
);
4562 s
->base
.is_jmp
= DISAS_WFE
;
4567 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4573 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4575 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4578 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4579 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4580 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4585 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4588 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4589 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4590 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4595 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4596 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4597 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4598 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4599 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4601 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4602 switch ((size << 1) | u) { \
4604 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4607 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4610 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4613 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4616 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4619 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4621 default: return 1; \
4624 #define GEN_NEON_INTEGER_OP(name) do { \
4625 switch ((size << 1) | u) { \
4627 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4630 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4633 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4636 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4639 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4642 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4644 default: return 1; \
4647 static TCGv_i32
neon_load_scratch(int scratch
)
4649 TCGv_i32 tmp
= tcg_temp_new_i32();
4650 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4654 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4656 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4657 tcg_temp_free_i32(var
);
4660 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4664 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4666 gen_neon_dup_high16(tmp
);
4668 gen_neon_dup_low16(tmp
);
4671 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4676 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4679 if (!q
&& size
== 2) {
4682 tmp
= tcg_const_i32(rd
);
4683 tmp2
= tcg_const_i32(rm
);
4687 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4690 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4693 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4701 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4704 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4710 tcg_temp_free_i32(tmp
);
4711 tcg_temp_free_i32(tmp2
);
4715 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4718 if (!q
&& size
== 2) {
4721 tmp
= tcg_const_i32(rd
);
4722 tmp2
= tcg_const_i32(rm
);
4726 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4729 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4732 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4740 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4743 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4749 tcg_temp_free_i32(tmp
);
4750 tcg_temp_free_i32(tmp2
);
4754 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4758 rd
= tcg_temp_new_i32();
4759 tmp
= tcg_temp_new_i32();
4761 tcg_gen_shli_i32(rd
, t0
, 8);
4762 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4763 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4764 tcg_gen_or_i32(rd
, rd
, tmp
);
4766 tcg_gen_shri_i32(t1
, t1
, 8);
4767 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4768 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4769 tcg_gen_or_i32(t1
, t1
, tmp
);
4770 tcg_gen_mov_i32(t0
, rd
);
4772 tcg_temp_free_i32(tmp
);
4773 tcg_temp_free_i32(rd
);
4776 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4780 rd
= tcg_temp_new_i32();
4781 tmp
= tcg_temp_new_i32();
4783 tcg_gen_shli_i32(rd
, t0
, 16);
4784 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4785 tcg_gen_or_i32(rd
, rd
, tmp
);
4786 tcg_gen_shri_i32(t1
, t1
, 16);
4787 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4788 tcg_gen_or_i32(t1
, t1
, tmp
);
4789 tcg_gen_mov_i32(t0
, rd
);
4791 tcg_temp_free_i32(tmp
);
4792 tcg_temp_free_i32(rd
);
4800 } neon_ls_element_type
[11] = {
4814 /* Translate a NEON load/store element instruction. Return nonzero if the
4815 instruction is invalid. */
4816 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4835 /* FIXME: this access check should not take precedence over UNDEF
4836 * for invalid encodings; we will generate incorrect syndrome information
4837 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4839 if (s
->fp_excp_el
) {
4840 gen_exception_insn(s
, 4, EXCP_UDEF
,
4841 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4845 if (!s
->vfp_enabled
)
4847 VFP_DREG_D(rd
, insn
);
4848 rn
= (insn
>> 16) & 0xf;
4850 load
= (insn
& (1 << 21)) != 0;
4851 if ((insn
& (1 << 23)) == 0) {
4852 /* Load store all elements. */
4853 op
= (insn
>> 8) & 0xf;
4854 size
= (insn
>> 6) & 3;
4857 /* Catch UNDEF cases for bad values of align field */
4860 if (((insn
>> 5) & 1) == 1) {
4865 if (((insn
>> 4) & 3) == 3) {
4872 nregs
= neon_ls_element_type
[op
].nregs
;
4873 interleave
= neon_ls_element_type
[op
].interleave
;
4874 spacing
= neon_ls_element_type
[op
].spacing
;
4875 if (size
== 3 && (interleave
| spacing
) != 1)
4877 addr
= tcg_temp_new_i32();
4878 load_reg_var(s
, addr
, rn
);
4879 stride
= (1 << size
) * interleave
;
4880 for (reg
= 0; reg
< nregs
; reg
++) {
4881 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4882 load_reg_var(s
, addr
, rn
);
4883 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4884 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4885 load_reg_var(s
, addr
, rn
);
4886 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4889 tmp64
= tcg_temp_new_i64();
4891 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4892 neon_store_reg64(tmp64
, rd
);
4894 neon_load_reg64(tmp64
, rd
);
4895 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4897 tcg_temp_free_i64(tmp64
);
4898 tcg_gen_addi_i32(addr
, addr
, stride
);
4900 for (pass
= 0; pass
< 2; pass
++) {
4903 tmp
= tcg_temp_new_i32();
4904 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4905 neon_store_reg(rd
, pass
, tmp
);
4907 tmp
= neon_load_reg(rd
, pass
);
4908 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4909 tcg_temp_free_i32(tmp
);
4911 tcg_gen_addi_i32(addr
, addr
, stride
);
4912 } else if (size
== 1) {
4914 tmp
= tcg_temp_new_i32();
4915 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4916 tcg_gen_addi_i32(addr
, addr
, stride
);
4917 tmp2
= tcg_temp_new_i32();
4918 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4919 tcg_gen_addi_i32(addr
, addr
, stride
);
4920 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4921 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4922 tcg_temp_free_i32(tmp2
);
4923 neon_store_reg(rd
, pass
, tmp
);
4925 tmp
= neon_load_reg(rd
, pass
);
4926 tmp2
= tcg_temp_new_i32();
4927 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4928 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4929 tcg_temp_free_i32(tmp
);
4930 tcg_gen_addi_i32(addr
, addr
, stride
);
4931 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4932 tcg_temp_free_i32(tmp2
);
4933 tcg_gen_addi_i32(addr
, addr
, stride
);
4935 } else /* size == 0 */ {
4937 TCGV_UNUSED_I32(tmp2
);
4938 for (n
= 0; n
< 4; n
++) {
4939 tmp
= tcg_temp_new_i32();
4940 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4941 tcg_gen_addi_i32(addr
, addr
, stride
);
4945 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4946 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4947 tcg_temp_free_i32(tmp
);
4950 neon_store_reg(rd
, pass
, tmp2
);
4952 tmp2
= neon_load_reg(rd
, pass
);
4953 for (n
= 0; n
< 4; n
++) {
4954 tmp
= tcg_temp_new_i32();
4956 tcg_gen_mov_i32(tmp
, tmp2
);
4958 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4960 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4961 tcg_temp_free_i32(tmp
);
4962 tcg_gen_addi_i32(addr
, addr
, stride
);
4964 tcg_temp_free_i32(tmp2
);
4971 tcg_temp_free_i32(addr
);
4974 size
= (insn
>> 10) & 3;
4976 /* Load single element to all lanes. */
4977 int a
= (insn
>> 4) & 1;
4981 size
= (insn
>> 6) & 3;
4982 nregs
= ((insn
>> 8) & 3) + 1;
4985 if (nregs
!= 4 || a
== 0) {
4988 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4991 if (nregs
== 1 && a
== 1 && size
== 0) {
4994 if (nregs
== 3 && a
== 1) {
4997 addr
= tcg_temp_new_i32();
4998 load_reg_var(s
, addr
, rn
);
5000 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5001 tmp
= gen_load_and_replicate(s
, addr
, size
);
5002 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
5003 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
5004 if (insn
& (1 << 5)) {
5005 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
5006 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
5008 tcg_temp_free_i32(tmp
);
5010 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5011 stride
= (insn
& (1 << 5)) ? 2 : 1;
5012 for (reg
= 0; reg
< nregs
; reg
++) {
5013 tmp
= gen_load_and_replicate(s
, addr
, size
);
5014 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
5015 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
5016 tcg_temp_free_i32(tmp
);
5017 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5021 tcg_temp_free_i32(addr
);
5022 stride
= (1 << size
) * nregs
;
5024 /* Single element. */
5025 int idx
= (insn
>> 4) & 0xf;
5026 pass
= (insn
>> 7) & 1;
5029 shift
= ((insn
>> 5) & 3) * 8;
5033 shift
= ((insn
>> 6) & 1) * 16;
5034 stride
= (insn
& (1 << 5)) ? 2 : 1;
5038 stride
= (insn
& (1 << 6)) ? 2 : 1;
5043 nregs
= ((insn
>> 8) & 3) + 1;
5044 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5047 if (((idx
& (1 << size
)) != 0) ||
5048 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
5053 if ((idx
& 1) != 0) {
5058 if (size
== 2 && (idx
& 2) != 0) {
5063 if ((size
== 2) && ((idx
& 3) == 3)) {
5070 if ((rd
+ stride
* (nregs
- 1)) > 31) {
5071 /* Attempts to write off the end of the register file
5072 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5073 * the neon_load_reg() would write off the end of the array.
5077 addr
= tcg_temp_new_i32();
5078 load_reg_var(s
, addr
, rn
);
5079 for (reg
= 0; reg
< nregs
; reg
++) {
5081 tmp
= tcg_temp_new_i32();
5084 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
5087 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
5090 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
5092 default: /* Avoid compiler warnings. */
5096 tmp2
= neon_load_reg(rd
, pass
);
5097 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
5098 shift
, size
? 16 : 8);
5099 tcg_temp_free_i32(tmp2
);
5101 neon_store_reg(rd
, pass
, tmp
);
5102 } else { /* Store */
5103 tmp
= neon_load_reg(rd
, pass
);
5105 tcg_gen_shri_i32(tmp
, tmp
, shift
);
5108 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
5111 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
5114 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5117 tcg_temp_free_i32(tmp
);
5120 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5122 tcg_temp_free_i32(addr
);
5123 stride
= nregs
* (1 << size
);
5129 base
= load_reg(s
, rn
);
5131 tcg_gen_addi_i32(base
, base
, stride
);
5134 index
= load_reg(s
, rm
);
5135 tcg_gen_add_i32(base
, base
, index
);
5136 tcg_temp_free_i32(index
);
5138 store_reg(s
, rn
, base
);
5143 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5144 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
5146 tcg_gen_and_i32(t
, t
, c
);
5147 tcg_gen_andc_i32(f
, f
, c
);
5148 tcg_gen_or_i32(dest
, t
, f
);
5151 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5154 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
5155 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
5156 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
5161 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5164 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
5165 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
5166 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5171 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5174 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5175 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5176 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5181 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5184 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5185 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5186 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5191 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5197 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5198 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5203 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5204 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5211 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5212 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5217 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5218 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5225 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5229 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5230 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5231 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5236 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5237 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5238 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5242 tcg_temp_free_i32(src
);
5245 static inline void gen_neon_addl(int size
)
5248 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5249 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5250 case 2: tcg_gen_add_i64(CPU_V001
); break;
5255 static inline void gen_neon_subl(int size
)
5258 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5259 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5260 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5265 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5268 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5269 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5271 tcg_gen_neg_i64(var
, var
);
5277 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5280 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5281 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5286 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5291 switch ((size
<< 1) | u
) {
5292 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5293 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5294 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5295 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5297 tmp
= gen_muls_i64_i32(a
, b
);
5298 tcg_gen_mov_i64(dest
, tmp
);
5299 tcg_temp_free_i64(tmp
);
5302 tmp
= gen_mulu_i64_i32(a
, b
);
5303 tcg_gen_mov_i64(dest
, tmp
);
5304 tcg_temp_free_i64(tmp
);
5309 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5310 Don't forget to clean them now. */
5312 tcg_temp_free_i32(a
);
5313 tcg_temp_free_i32(b
);
5317 static void gen_neon_narrow_op(int op
, int u
, int size
,
5318 TCGv_i32 dest
, TCGv_i64 src
)
5322 gen_neon_unarrow_sats(size
, dest
, src
);
5324 gen_neon_narrow(size
, dest
, src
);
5328 gen_neon_narrow_satu(size
, dest
, src
);
5330 gen_neon_narrow_sats(size
, dest
, src
);
5335 /* Symbolic constants for op fields for Neon 3-register same-length.
5336 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5339 #define NEON_3R_VHADD 0
5340 #define NEON_3R_VQADD 1
5341 #define NEON_3R_VRHADD 2
5342 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5343 #define NEON_3R_VHSUB 4
5344 #define NEON_3R_VQSUB 5
5345 #define NEON_3R_VCGT 6
5346 #define NEON_3R_VCGE 7
5347 #define NEON_3R_VSHL 8
5348 #define NEON_3R_VQSHL 9
5349 #define NEON_3R_VRSHL 10
5350 #define NEON_3R_VQRSHL 11
5351 #define NEON_3R_VMAX 12
5352 #define NEON_3R_VMIN 13
5353 #define NEON_3R_VABD 14
5354 #define NEON_3R_VABA 15
5355 #define NEON_3R_VADD_VSUB 16
5356 #define NEON_3R_VTST_VCEQ 17
5357 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5358 #define NEON_3R_VMUL 19
5359 #define NEON_3R_VPMAX 20
5360 #define NEON_3R_VPMIN 21
5361 #define NEON_3R_VQDMULH_VQRDMULH 22
5362 #define NEON_3R_VPADD 23
5363 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5364 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5365 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5366 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5367 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5368 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5369 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5370 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5372 static const uint8_t neon_3r_sizes
[] = {
5373 [NEON_3R_VHADD
] = 0x7,
5374 [NEON_3R_VQADD
] = 0xf,
5375 [NEON_3R_VRHADD
] = 0x7,
5376 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5377 [NEON_3R_VHSUB
] = 0x7,
5378 [NEON_3R_VQSUB
] = 0xf,
5379 [NEON_3R_VCGT
] = 0x7,
5380 [NEON_3R_VCGE
] = 0x7,
5381 [NEON_3R_VSHL
] = 0xf,
5382 [NEON_3R_VQSHL
] = 0xf,
5383 [NEON_3R_VRSHL
] = 0xf,
5384 [NEON_3R_VQRSHL
] = 0xf,
5385 [NEON_3R_VMAX
] = 0x7,
5386 [NEON_3R_VMIN
] = 0x7,
5387 [NEON_3R_VABD
] = 0x7,
5388 [NEON_3R_VABA
] = 0x7,
5389 [NEON_3R_VADD_VSUB
] = 0xf,
5390 [NEON_3R_VTST_VCEQ
] = 0x7,
5391 [NEON_3R_VML
] = 0x7,
5392 [NEON_3R_VMUL
] = 0x7,
5393 [NEON_3R_VPMAX
] = 0x7,
5394 [NEON_3R_VPMIN
] = 0x7,
5395 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5396 [NEON_3R_VPADD
] = 0x7,
5397 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5398 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5399 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5400 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5401 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5402 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5403 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5404 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5407 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5408 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5411 #define NEON_2RM_VREV64 0
5412 #define NEON_2RM_VREV32 1
5413 #define NEON_2RM_VREV16 2
5414 #define NEON_2RM_VPADDL 4
5415 #define NEON_2RM_VPADDL_U 5
5416 #define NEON_2RM_AESE 6 /* Includes AESD */
5417 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5418 #define NEON_2RM_VCLS 8
5419 #define NEON_2RM_VCLZ 9
5420 #define NEON_2RM_VCNT 10
5421 #define NEON_2RM_VMVN 11
5422 #define NEON_2RM_VPADAL 12
5423 #define NEON_2RM_VPADAL_U 13
5424 #define NEON_2RM_VQABS 14
5425 #define NEON_2RM_VQNEG 15
5426 #define NEON_2RM_VCGT0 16
5427 #define NEON_2RM_VCGE0 17
5428 #define NEON_2RM_VCEQ0 18
5429 #define NEON_2RM_VCLE0 19
5430 #define NEON_2RM_VCLT0 20
5431 #define NEON_2RM_SHA1H 21
5432 #define NEON_2RM_VABS 22
5433 #define NEON_2RM_VNEG 23
5434 #define NEON_2RM_VCGT0_F 24
5435 #define NEON_2RM_VCGE0_F 25
5436 #define NEON_2RM_VCEQ0_F 26
5437 #define NEON_2RM_VCLE0_F 27
5438 #define NEON_2RM_VCLT0_F 28
5439 #define NEON_2RM_VABS_F 30
5440 #define NEON_2RM_VNEG_F 31
5441 #define NEON_2RM_VSWP 32
5442 #define NEON_2RM_VTRN 33
5443 #define NEON_2RM_VUZP 34
5444 #define NEON_2RM_VZIP 35
5445 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5446 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5447 #define NEON_2RM_VSHLL 38
5448 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5449 #define NEON_2RM_VRINTN 40
5450 #define NEON_2RM_VRINTX 41
5451 #define NEON_2RM_VRINTA 42
5452 #define NEON_2RM_VRINTZ 43
5453 #define NEON_2RM_VCVT_F16_F32 44
5454 #define NEON_2RM_VRINTM 45
5455 #define NEON_2RM_VCVT_F32_F16 46
5456 #define NEON_2RM_VRINTP 47
5457 #define NEON_2RM_VCVTAU 48
5458 #define NEON_2RM_VCVTAS 49
5459 #define NEON_2RM_VCVTNU 50
5460 #define NEON_2RM_VCVTNS 51
5461 #define NEON_2RM_VCVTPU 52
5462 #define NEON_2RM_VCVTPS 53
5463 #define NEON_2RM_VCVTMU 54
5464 #define NEON_2RM_VCVTMS 55
5465 #define NEON_2RM_VRECPE 56
5466 #define NEON_2RM_VRSQRTE 57
5467 #define NEON_2RM_VRECPE_F 58
5468 #define NEON_2RM_VRSQRTE_F 59
5469 #define NEON_2RM_VCVT_FS 60
5470 #define NEON_2RM_VCVT_FU 61
5471 #define NEON_2RM_VCVT_SF 62
5472 #define NEON_2RM_VCVT_UF 63
5474 static int neon_2rm_is_float_op(int op
)
5476 /* Return true if this neon 2reg-misc op is float-to-float */
5477 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5478 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5479 op
== NEON_2RM_VRINTM
||
5480 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5481 op
>= NEON_2RM_VRECPE_F
);
5484 static bool neon_2rm_is_v8_op(int op
)
5486 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5488 case NEON_2RM_VRINTN
:
5489 case NEON_2RM_VRINTA
:
5490 case NEON_2RM_VRINTM
:
5491 case NEON_2RM_VRINTP
:
5492 case NEON_2RM_VRINTZ
:
5493 case NEON_2RM_VRINTX
:
5494 case NEON_2RM_VCVTAU
:
5495 case NEON_2RM_VCVTAS
:
5496 case NEON_2RM_VCVTNU
:
5497 case NEON_2RM_VCVTNS
:
5498 case NEON_2RM_VCVTPU
:
5499 case NEON_2RM_VCVTPS
:
5500 case NEON_2RM_VCVTMU
:
5501 case NEON_2RM_VCVTMS
:
5508 /* Each entry in this array has bit n set if the insn allows
5509 * size value n (otherwise it will UNDEF). Since unallocated
5510 * op values will have no bits set they always UNDEF.
5512 static const uint8_t neon_2rm_sizes
[] = {
5513 [NEON_2RM_VREV64
] = 0x7,
5514 [NEON_2RM_VREV32
] = 0x3,
5515 [NEON_2RM_VREV16
] = 0x1,
5516 [NEON_2RM_VPADDL
] = 0x7,
5517 [NEON_2RM_VPADDL_U
] = 0x7,
5518 [NEON_2RM_AESE
] = 0x1,
5519 [NEON_2RM_AESMC
] = 0x1,
5520 [NEON_2RM_VCLS
] = 0x7,
5521 [NEON_2RM_VCLZ
] = 0x7,
5522 [NEON_2RM_VCNT
] = 0x1,
5523 [NEON_2RM_VMVN
] = 0x1,
5524 [NEON_2RM_VPADAL
] = 0x7,
5525 [NEON_2RM_VPADAL_U
] = 0x7,
5526 [NEON_2RM_VQABS
] = 0x7,
5527 [NEON_2RM_VQNEG
] = 0x7,
5528 [NEON_2RM_VCGT0
] = 0x7,
5529 [NEON_2RM_VCGE0
] = 0x7,
5530 [NEON_2RM_VCEQ0
] = 0x7,
5531 [NEON_2RM_VCLE0
] = 0x7,
5532 [NEON_2RM_VCLT0
] = 0x7,
5533 [NEON_2RM_SHA1H
] = 0x4,
5534 [NEON_2RM_VABS
] = 0x7,
5535 [NEON_2RM_VNEG
] = 0x7,
5536 [NEON_2RM_VCGT0_F
] = 0x4,
5537 [NEON_2RM_VCGE0_F
] = 0x4,
5538 [NEON_2RM_VCEQ0_F
] = 0x4,
5539 [NEON_2RM_VCLE0_F
] = 0x4,
5540 [NEON_2RM_VCLT0_F
] = 0x4,
5541 [NEON_2RM_VABS_F
] = 0x4,
5542 [NEON_2RM_VNEG_F
] = 0x4,
5543 [NEON_2RM_VSWP
] = 0x1,
5544 [NEON_2RM_VTRN
] = 0x7,
5545 [NEON_2RM_VUZP
] = 0x7,
5546 [NEON_2RM_VZIP
] = 0x7,
5547 [NEON_2RM_VMOVN
] = 0x7,
5548 [NEON_2RM_VQMOVN
] = 0x7,
5549 [NEON_2RM_VSHLL
] = 0x7,
5550 [NEON_2RM_SHA1SU1
] = 0x4,
5551 [NEON_2RM_VRINTN
] = 0x4,
5552 [NEON_2RM_VRINTX
] = 0x4,
5553 [NEON_2RM_VRINTA
] = 0x4,
5554 [NEON_2RM_VRINTZ
] = 0x4,
5555 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5556 [NEON_2RM_VRINTM
] = 0x4,
5557 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5558 [NEON_2RM_VRINTP
] = 0x4,
5559 [NEON_2RM_VCVTAU
] = 0x4,
5560 [NEON_2RM_VCVTAS
] = 0x4,
5561 [NEON_2RM_VCVTNU
] = 0x4,
5562 [NEON_2RM_VCVTNS
] = 0x4,
5563 [NEON_2RM_VCVTPU
] = 0x4,
5564 [NEON_2RM_VCVTPS
] = 0x4,
5565 [NEON_2RM_VCVTMU
] = 0x4,
5566 [NEON_2RM_VCVTMS
] = 0x4,
5567 [NEON_2RM_VRECPE
] = 0x4,
5568 [NEON_2RM_VRSQRTE
] = 0x4,
5569 [NEON_2RM_VRECPE_F
] = 0x4,
5570 [NEON_2RM_VRSQRTE_F
] = 0x4,
5571 [NEON_2RM_VCVT_FS
] = 0x4,
5572 [NEON_2RM_VCVT_FU
] = 0x4,
5573 [NEON_2RM_VCVT_SF
] = 0x4,
5574 [NEON_2RM_VCVT_UF
] = 0x4,
5577 /* Translate a NEON data processing instruction. Return nonzero if the
5578 instruction is invalid.
5579 We process data in a mixture of 32-bit and 64-bit chunks.
5580 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5582 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5594 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5597 /* FIXME: this access check should not take precedence over UNDEF
5598 * for invalid encodings; we will generate incorrect syndrome information
5599 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5601 if (s
->fp_excp_el
) {
5602 gen_exception_insn(s
, 4, EXCP_UDEF
,
5603 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5607 if (!s
->vfp_enabled
)
5609 q
= (insn
& (1 << 6)) != 0;
5610 u
= (insn
>> 24) & 1;
5611 VFP_DREG_D(rd
, insn
);
5612 VFP_DREG_N(rn
, insn
);
5613 VFP_DREG_M(rm
, insn
);
5614 size
= (insn
>> 20) & 3;
5615 if ((insn
& (1 << 23)) == 0) {
5616 /* Three register same length. */
5617 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5618 /* Catch invalid op and bad size combinations: UNDEF */
5619 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5622 /* All insns of this form UNDEF for either this condition or the
5623 * superset of cases "Q==1"; we catch the latter later.
5625 if (q
&& ((rd
| rn
| rm
) & 1)) {
5629 * The SHA-1/SHA-256 3-register instructions require special treatment
5630 * here, as their size field is overloaded as an op type selector, and
5631 * they all consume their input in a single pass.
5633 if (op
== NEON_3R_SHA
) {
5637 if (!u
) { /* SHA-1 */
5638 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5641 tmp
= tcg_const_i32(rd
);
5642 tmp2
= tcg_const_i32(rn
);
5643 tmp3
= tcg_const_i32(rm
);
5644 tmp4
= tcg_const_i32(size
);
5645 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5646 tcg_temp_free_i32(tmp4
);
5647 } else { /* SHA-256 */
5648 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5651 tmp
= tcg_const_i32(rd
);
5652 tmp2
= tcg_const_i32(rn
);
5653 tmp3
= tcg_const_i32(rm
);
5656 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5659 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5662 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5666 tcg_temp_free_i32(tmp
);
5667 tcg_temp_free_i32(tmp2
);
5668 tcg_temp_free_i32(tmp3
);
5671 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5672 /* 64-bit element instructions. */
5673 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5674 neon_load_reg64(cpu_V0
, rn
+ pass
);
5675 neon_load_reg64(cpu_V1
, rm
+ pass
);
5679 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5682 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5688 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5691 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5697 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5699 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5704 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5707 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5713 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5715 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5718 case NEON_3R_VQRSHL
:
5720 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5723 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5727 case NEON_3R_VADD_VSUB
:
5729 tcg_gen_sub_i64(CPU_V001
);
5731 tcg_gen_add_i64(CPU_V001
);
5737 neon_store_reg64(cpu_V0
, rd
+ pass
);
5746 case NEON_3R_VQRSHL
:
5749 /* Shift instruction operands are reversed. */
5764 case NEON_3R_FLOAT_ARITH
:
5765 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5767 case NEON_3R_FLOAT_MINMAX
:
5768 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5770 case NEON_3R_FLOAT_CMP
:
5772 /* no encoding for U=0 C=1x */
5776 case NEON_3R_FLOAT_ACMP
:
5781 case NEON_3R_FLOAT_MISC
:
5782 /* VMAXNM/VMINNM in ARMv8 */
5783 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5788 if (u
&& (size
!= 0)) {
5789 /* UNDEF on invalid size for polynomial subcase */
5794 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5802 if (pairwise
&& q
) {
5803 /* All the pairwise insns UNDEF if Q is set */
5807 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5812 tmp
= neon_load_reg(rn
, 0);
5813 tmp2
= neon_load_reg(rn
, 1);
5815 tmp
= neon_load_reg(rm
, 0);
5816 tmp2
= neon_load_reg(rm
, 1);
5820 tmp
= neon_load_reg(rn
, pass
);
5821 tmp2
= neon_load_reg(rm
, pass
);
5825 GEN_NEON_INTEGER_OP(hadd
);
5828 GEN_NEON_INTEGER_OP_ENV(qadd
);
5830 case NEON_3R_VRHADD
:
5831 GEN_NEON_INTEGER_OP(rhadd
);
5833 case NEON_3R_LOGIC
: /* Logic ops. */
5834 switch ((u
<< 2) | size
) {
5836 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5839 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5842 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5845 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5848 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5851 tmp3
= neon_load_reg(rd
, pass
);
5852 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5853 tcg_temp_free_i32(tmp3
);
5856 tmp3
= neon_load_reg(rd
, pass
);
5857 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5858 tcg_temp_free_i32(tmp3
);
5861 tmp3
= neon_load_reg(rd
, pass
);
5862 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5863 tcg_temp_free_i32(tmp3
);
5868 GEN_NEON_INTEGER_OP(hsub
);
5871 GEN_NEON_INTEGER_OP_ENV(qsub
);
5874 GEN_NEON_INTEGER_OP(cgt
);
5877 GEN_NEON_INTEGER_OP(cge
);
5880 GEN_NEON_INTEGER_OP(shl
);
5883 GEN_NEON_INTEGER_OP_ENV(qshl
);
5886 GEN_NEON_INTEGER_OP(rshl
);
5888 case NEON_3R_VQRSHL
:
5889 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5892 GEN_NEON_INTEGER_OP(max
);
5895 GEN_NEON_INTEGER_OP(min
);
5898 GEN_NEON_INTEGER_OP(abd
);
5901 GEN_NEON_INTEGER_OP(abd
);
5902 tcg_temp_free_i32(tmp2
);
5903 tmp2
= neon_load_reg(rd
, pass
);
5904 gen_neon_add(size
, tmp
, tmp2
);
5906 case NEON_3R_VADD_VSUB
:
5907 if (!u
) { /* VADD */
5908 gen_neon_add(size
, tmp
, tmp2
);
5911 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5912 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5913 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5918 case NEON_3R_VTST_VCEQ
:
5919 if (!u
) { /* VTST */
5921 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5922 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5923 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5928 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5929 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5930 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5935 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5937 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5938 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5939 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5942 tcg_temp_free_i32(tmp2
);
5943 tmp2
= neon_load_reg(rd
, pass
);
5945 gen_neon_rsb(size
, tmp
, tmp2
);
5947 gen_neon_add(size
, tmp
, tmp2
);
5951 if (u
) { /* polynomial */
5952 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5953 } else { /* Integer */
5955 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5956 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5957 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5963 GEN_NEON_INTEGER_OP(pmax
);
5966 GEN_NEON_INTEGER_OP(pmin
);
5968 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5969 if (!u
) { /* VQDMULH */
5972 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5975 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5979 } else { /* VQRDMULH */
5982 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5985 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5993 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5994 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5995 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5999 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
6001 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6002 switch ((u
<< 2) | size
) {
6005 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6008 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
6011 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
6016 tcg_temp_free_ptr(fpstatus
);
6019 case NEON_3R_FLOAT_MULTIPLY
:
6021 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6022 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6024 tcg_temp_free_i32(tmp2
);
6025 tmp2
= neon_load_reg(rd
, pass
);
6027 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6029 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6032 tcg_temp_free_ptr(fpstatus
);
6035 case NEON_3R_FLOAT_CMP
:
6037 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6039 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6042 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6044 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6047 tcg_temp_free_ptr(fpstatus
);
6050 case NEON_3R_FLOAT_ACMP
:
6052 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6054 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6056 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6058 tcg_temp_free_ptr(fpstatus
);
6061 case NEON_3R_FLOAT_MINMAX
:
6063 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6065 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6067 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6069 tcg_temp_free_ptr(fpstatus
);
6072 case NEON_3R_FLOAT_MISC
:
6075 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6077 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6079 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6081 tcg_temp_free_ptr(fpstatus
);
6084 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6086 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6092 /* VFMA, VFMS: fused multiply-add */
6093 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6094 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6097 gen_helper_vfp_negs(tmp
, tmp
);
6099 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6100 tcg_temp_free_i32(tmp3
);
6101 tcg_temp_free_ptr(fpstatus
);
6107 tcg_temp_free_i32(tmp2
);
6109 /* Save the result. For elementwise operations we can put it
6110 straight into the destination register. For pairwise operations
6111 we have to be careful to avoid clobbering the source operands. */
6112 if (pairwise
&& rd
== rm
) {
6113 neon_store_scratch(pass
, tmp
);
6115 neon_store_reg(rd
, pass
, tmp
);
6119 if (pairwise
&& rd
== rm
) {
6120 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6121 tmp
= neon_load_scratch(pass
);
6122 neon_store_reg(rd
, pass
, tmp
);
6125 /* End of 3 register same size operations. */
6126 } else if (insn
& (1 << 4)) {
6127 if ((insn
& 0x00380080) != 0) {
6128 /* Two registers and shift. */
6129 op
= (insn
>> 8) & 0xf;
6130 if (insn
& (1 << 7)) {
6138 while ((insn
& (1 << (size
+ 19))) == 0)
6141 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6142 /* To avoid excessive duplication of ops we implement shift
6143 by immediate using the variable shift operations. */
6145 /* Shift by immediate:
6146 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6147 if (q
&& ((rd
| rm
) & 1)) {
6150 if (!u
&& (op
== 4 || op
== 6)) {
6153 /* Right shifts are encoded as N - shift, where N is the
6154 element size in bits. */
6156 shift
= shift
- (1 << (size
+ 3));
6164 imm
= (uint8_t) shift
;
6169 imm
= (uint16_t) shift
;
6180 for (pass
= 0; pass
< count
; pass
++) {
6182 neon_load_reg64(cpu_V0
, rm
+ pass
);
6183 tcg_gen_movi_i64(cpu_V1
, imm
);
6188 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6190 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6195 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6197 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6200 case 5: /* VSHL, VSLI */
6201 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6203 case 6: /* VQSHLU */
6204 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6209 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6212 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6217 if (op
== 1 || op
== 3) {
6219 neon_load_reg64(cpu_V1
, rd
+ pass
);
6220 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6221 } else if (op
== 4 || (op
== 5 && u
)) {
6223 neon_load_reg64(cpu_V1
, rd
+ pass
);
6225 if (shift
< -63 || shift
> 63) {
6229 mask
= 0xffffffffffffffffull
>> -shift
;
6231 mask
= 0xffffffffffffffffull
<< shift
;
6234 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6235 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6237 neon_store_reg64(cpu_V0
, rd
+ pass
);
6238 } else { /* size < 3 */
6239 /* Operands in T0 and T1. */
6240 tmp
= neon_load_reg(rm
, pass
);
6241 tmp2
= tcg_temp_new_i32();
6242 tcg_gen_movi_i32(tmp2
, imm
);
6246 GEN_NEON_INTEGER_OP(shl
);
6250 GEN_NEON_INTEGER_OP(rshl
);
6253 case 5: /* VSHL, VSLI */
6255 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6256 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6257 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6261 case 6: /* VQSHLU */
6264 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6268 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6272 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6280 GEN_NEON_INTEGER_OP_ENV(qshl
);
6283 tcg_temp_free_i32(tmp2
);
6285 if (op
== 1 || op
== 3) {
6287 tmp2
= neon_load_reg(rd
, pass
);
6288 gen_neon_add(size
, tmp
, tmp2
);
6289 tcg_temp_free_i32(tmp2
);
6290 } else if (op
== 4 || (op
== 5 && u
)) {
6295 mask
= 0xff >> -shift
;
6297 mask
= (uint8_t)(0xff << shift
);
6303 mask
= 0xffff >> -shift
;
6305 mask
= (uint16_t)(0xffff << shift
);
6309 if (shift
< -31 || shift
> 31) {
6313 mask
= 0xffffffffu
>> -shift
;
6315 mask
= 0xffffffffu
<< shift
;
6321 tmp2
= neon_load_reg(rd
, pass
);
6322 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6323 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6324 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6325 tcg_temp_free_i32(tmp2
);
6327 neon_store_reg(rd
, pass
, tmp
);
6330 } else if (op
< 10) {
6331 /* Shift by immediate and narrow:
6332 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6333 int input_unsigned
= (op
== 8) ? !u
: u
;
6337 shift
= shift
- (1 << (size
+ 3));
6340 tmp64
= tcg_const_i64(shift
);
6341 neon_load_reg64(cpu_V0
, rm
);
6342 neon_load_reg64(cpu_V1
, rm
+ 1);
6343 for (pass
= 0; pass
< 2; pass
++) {
6351 if (input_unsigned
) {
6352 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6354 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6357 if (input_unsigned
) {
6358 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6360 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6363 tmp
= tcg_temp_new_i32();
6364 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6365 neon_store_reg(rd
, pass
, tmp
);
6367 tcg_temp_free_i64(tmp64
);
6370 imm
= (uint16_t)shift
;
6374 imm
= (uint32_t)shift
;
6376 tmp2
= tcg_const_i32(imm
);
6377 tmp4
= neon_load_reg(rm
+ 1, 0);
6378 tmp5
= neon_load_reg(rm
+ 1, 1);
6379 for (pass
= 0; pass
< 2; pass
++) {
6381 tmp
= neon_load_reg(rm
, 0);
6385 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6388 tmp3
= neon_load_reg(rm
, 1);
6392 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6394 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6395 tcg_temp_free_i32(tmp
);
6396 tcg_temp_free_i32(tmp3
);
6397 tmp
= tcg_temp_new_i32();
6398 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6399 neon_store_reg(rd
, pass
, tmp
);
6401 tcg_temp_free_i32(tmp2
);
6403 } else if (op
== 10) {
6405 if (q
|| (rd
& 1)) {
6408 tmp
= neon_load_reg(rm
, 0);
6409 tmp2
= neon_load_reg(rm
, 1);
6410 for (pass
= 0; pass
< 2; pass
++) {
6414 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6417 /* The shift is less than the width of the source
6418 type, so we can just shift the whole register. */
6419 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6420 /* Widen the result of shift: we need to clear
6421 * the potential overflow bits resulting from
6422 * left bits of the narrow input appearing as
6423 * right bits of left the neighbour narrow
6425 if (size
< 2 || !u
) {
6428 imm
= (0xffu
>> (8 - shift
));
6430 } else if (size
== 1) {
6431 imm
= 0xffff >> (16 - shift
);
6434 imm
= 0xffffffff >> (32 - shift
);
6437 imm64
= imm
| (((uint64_t)imm
) << 32);
6441 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6444 neon_store_reg64(cpu_V0
, rd
+ pass
);
6446 } else if (op
>= 14) {
6447 /* VCVT fixed-point. */
6448 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6451 /* We have already masked out the must-be-1 top bit of imm6,
6452 * hence this 32-shift where the ARM ARM has 64-imm6.
6455 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6456 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6459 gen_vfp_ulto(0, shift
, 1);
6461 gen_vfp_slto(0, shift
, 1);
6464 gen_vfp_toul(0, shift
, 1);
6466 gen_vfp_tosl(0, shift
, 1);
6468 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6473 } else { /* (insn & 0x00380080) == 0 */
6475 if (q
&& (rd
& 1)) {
6479 op
= (insn
>> 8) & 0xf;
6480 /* One register and immediate. */
6481 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6482 invert
= (insn
& (1 << 5)) != 0;
6483 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6484 * We choose to not special-case this and will behave as if a
6485 * valid constant encoding of 0 had been given.
6504 imm
= (imm
<< 8) | (imm
<< 24);
6507 imm
= (imm
<< 8) | 0xff;
6510 imm
= (imm
<< 16) | 0xffff;
6513 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6521 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6522 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6528 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6529 if (op
& 1 && op
< 12) {
6530 tmp
= neon_load_reg(rd
, pass
);
6532 /* The immediate value has already been inverted, so
6534 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6536 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6540 tmp
= tcg_temp_new_i32();
6541 if (op
== 14 && invert
) {
6545 for (n
= 0; n
< 4; n
++) {
6546 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6547 val
|= 0xff << (n
* 8);
6549 tcg_gen_movi_i32(tmp
, val
);
6551 tcg_gen_movi_i32(tmp
, imm
);
6554 neon_store_reg(rd
, pass
, tmp
);
6557 } else { /* (insn & 0x00800010 == 0x00800000) */
6559 op
= (insn
>> 8) & 0xf;
6560 if ((insn
& (1 << 6)) == 0) {
6561 /* Three registers of different lengths. */
6565 /* undefreq: bit 0 : UNDEF if size == 0
6566 * bit 1 : UNDEF if size == 1
6567 * bit 2 : UNDEF if size == 2
6568 * bit 3 : UNDEF if U == 1
6569 * Note that [2:0] set implies 'always UNDEF'
6572 /* prewiden, src1_wide, src2_wide, undefreq */
6573 static const int neon_3reg_wide
[16][4] = {
6574 {1, 0, 0, 0}, /* VADDL */
6575 {1, 1, 0, 0}, /* VADDW */
6576 {1, 0, 0, 0}, /* VSUBL */
6577 {1, 1, 0, 0}, /* VSUBW */
6578 {0, 1, 1, 0}, /* VADDHN */
6579 {0, 0, 0, 0}, /* VABAL */
6580 {0, 1, 1, 0}, /* VSUBHN */
6581 {0, 0, 0, 0}, /* VABDL */
6582 {0, 0, 0, 0}, /* VMLAL */
6583 {0, 0, 0, 9}, /* VQDMLAL */
6584 {0, 0, 0, 0}, /* VMLSL */
6585 {0, 0, 0, 9}, /* VQDMLSL */
6586 {0, 0, 0, 0}, /* Integer VMULL */
6587 {0, 0, 0, 1}, /* VQDMULL */
6588 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6589 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6592 prewiden
= neon_3reg_wide
[op
][0];
6593 src1_wide
= neon_3reg_wide
[op
][1];
6594 src2_wide
= neon_3reg_wide
[op
][2];
6595 undefreq
= neon_3reg_wide
[op
][3];
6597 if ((undefreq
& (1 << size
)) ||
6598 ((undefreq
& 8) && u
)) {
6601 if ((src1_wide
&& (rn
& 1)) ||
6602 (src2_wide
&& (rm
& 1)) ||
6603 (!src2_wide
&& (rd
& 1))) {
6607 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6608 * outside the loop below as it only performs a single pass.
6610 if (op
== 14 && size
== 2) {
6611 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6613 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6616 tcg_rn
= tcg_temp_new_i64();
6617 tcg_rm
= tcg_temp_new_i64();
6618 tcg_rd
= tcg_temp_new_i64();
6619 neon_load_reg64(tcg_rn
, rn
);
6620 neon_load_reg64(tcg_rm
, rm
);
6621 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6622 neon_store_reg64(tcg_rd
, rd
);
6623 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6624 neon_store_reg64(tcg_rd
, rd
+ 1);
6625 tcg_temp_free_i64(tcg_rn
);
6626 tcg_temp_free_i64(tcg_rm
);
6627 tcg_temp_free_i64(tcg_rd
);
6631 /* Avoid overlapping operands. Wide source operands are
6632 always aligned so will never overlap with wide
6633 destinations in problematic ways. */
6634 if (rd
== rm
&& !src2_wide
) {
6635 tmp
= neon_load_reg(rm
, 1);
6636 neon_store_scratch(2, tmp
);
6637 } else if (rd
== rn
&& !src1_wide
) {
6638 tmp
= neon_load_reg(rn
, 1);
6639 neon_store_scratch(2, tmp
);
6641 TCGV_UNUSED_I32(tmp3
);
6642 for (pass
= 0; pass
< 2; pass
++) {
6644 neon_load_reg64(cpu_V0
, rn
+ pass
);
6645 TCGV_UNUSED_I32(tmp
);
6647 if (pass
== 1 && rd
== rn
) {
6648 tmp
= neon_load_scratch(2);
6650 tmp
= neon_load_reg(rn
, pass
);
6653 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6657 neon_load_reg64(cpu_V1
, rm
+ pass
);
6658 TCGV_UNUSED_I32(tmp2
);
6660 if (pass
== 1 && rd
== rm
) {
6661 tmp2
= neon_load_scratch(2);
6663 tmp2
= neon_load_reg(rm
, pass
);
6666 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6670 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6671 gen_neon_addl(size
);
6673 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6674 gen_neon_subl(size
);
6676 case 5: case 7: /* VABAL, VABDL */
6677 switch ((size
<< 1) | u
) {
6679 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6682 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6685 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6688 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6691 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6694 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6698 tcg_temp_free_i32(tmp2
);
6699 tcg_temp_free_i32(tmp
);
6701 case 8: case 9: case 10: case 11: case 12: case 13:
6702 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6703 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6705 case 14: /* Polynomial VMULL */
6706 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6707 tcg_temp_free_i32(tmp2
);
6708 tcg_temp_free_i32(tmp
);
6710 default: /* 15 is RESERVED: caught earlier */
6715 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6716 neon_store_reg64(cpu_V0
, rd
+ pass
);
6717 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6719 neon_load_reg64(cpu_V1
, rd
+ pass
);
6721 case 10: /* VMLSL */
6722 gen_neon_negl(cpu_V0
, size
);
6724 case 5: case 8: /* VABAL, VMLAL */
6725 gen_neon_addl(size
);
6727 case 9: case 11: /* VQDMLAL, VQDMLSL */
6728 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6730 gen_neon_negl(cpu_V0
, size
);
6732 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6737 neon_store_reg64(cpu_V0
, rd
+ pass
);
6738 } else if (op
== 4 || op
== 6) {
6739 /* Narrowing operation. */
6740 tmp
= tcg_temp_new_i32();
6744 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6747 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6750 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6751 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6758 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6761 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6764 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6765 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6766 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6774 neon_store_reg(rd
, 0, tmp3
);
6775 neon_store_reg(rd
, 1, tmp
);
6778 /* Write back the result. */
6779 neon_store_reg64(cpu_V0
, rd
+ pass
);
6783 /* Two registers and a scalar. NB that for ops of this form
6784 * the ARM ARM labels bit 24 as Q, but it is in our variable
6791 case 1: /* Float VMLA scalar */
6792 case 5: /* Floating point VMLS scalar */
6793 case 9: /* Floating point VMUL scalar */
6798 case 0: /* Integer VMLA scalar */
6799 case 4: /* Integer VMLS scalar */
6800 case 8: /* Integer VMUL scalar */
6801 case 12: /* VQDMULH scalar */
6802 case 13: /* VQRDMULH scalar */
6803 if (u
&& ((rd
| rn
) & 1)) {
6806 tmp
= neon_get_scalar(size
, rm
);
6807 neon_store_scratch(0, tmp
);
6808 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6809 tmp
= neon_load_scratch(0);
6810 tmp2
= neon_load_reg(rn
, pass
);
6813 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6815 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6817 } else if (op
== 13) {
6819 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6821 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6823 } else if (op
& 1) {
6824 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6825 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6826 tcg_temp_free_ptr(fpstatus
);
6829 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6830 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6831 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6835 tcg_temp_free_i32(tmp2
);
6838 tmp2
= neon_load_reg(rd
, pass
);
6841 gen_neon_add(size
, tmp
, tmp2
);
6845 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6846 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6847 tcg_temp_free_ptr(fpstatus
);
6851 gen_neon_rsb(size
, tmp
, tmp2
);
6855 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6856 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6857 tcg_temp_free_ptr(fpstatus
);
6863 tcg_temp_free_i32(tmp2
);
6865 neon_store_reg(rd
, pass
, tmp
);
6868 case 3: /* VQDMLAL scalar */
6869 case 7: /* VQDMLSL scalar */
6870 case 11: /* VQDMULL scalar */
6875 case 2: /* VMLAL sclar */
6876 case 6: /* VMLSL scalar */
6877 case 10: /* VMULL scalar */
6881 tmp2
= neon_get_scalar(size
, rm
);
6882 /* We need a copy of tmp2 because gen_neon_mull
6883 * deletes it during pass 0. */
6884 tmp4
= tcg_temp_new_i32();
6885 tcg_gen_mov_i32(tmp4
, tmp2
);
6886 tmp3
= neon_load_reg(rn
, 1);
6888 for (pass
= 0; pass
< 2; pass
++) {
6890 tmp
= neon_load_reg(rn
, 0);
6895 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6897 neon_load_reg64(cpu_V1
, rd
+ pass
);
6901 gen_neon_negl(cpu_V0
, size
);
6904 gen_neon_addl(size
);
6907 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6909 gen_neon_negl(cpu_V0
, size
);
6911 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6917 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6922 neon_store_reg64(cpu_V0
, rd
+ pass
);
6927 default: /* 14 and 15 are RESERVED */
6931 } else { /* size == 3 */
6934 imm
= (insn
>> 8) & 0xf;
6939 if (q
&& ((rd
| rn
| rm
) & 1)) {
6944 neon_load_reg64(cpu_V0
, rn
);
6946 neon_load_reg64(cpu_V1
, rn
+ 1);
6948 } else if (imm
== 8) {
6949 neon_load_reg64(cpu_V0
, rn
+ 1);
6951 neon_load_reg64(cpu_V1
, rm
);
6954 tmp64
= tcg_temp_new_i64();
6956 neon_load_reg64(cpu_V0
, rn
);
6957 neon_load_reg64(tmp64
, rn
+ 1);
6959 neon_load_reg64(cpu_V0
, rn
+ 1);
6960 neon_load_reg64(tmp64
, rm
);
6962 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6963 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6964 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6966 neon_load_reg64(cpu_V1
, rm
);
6968 neon_load_reg64(cpu_V1
, rm
+ 1);
6971 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6972 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6973 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6974 tcg_temp_free_i64(tmp64
);
6977 neon_load_reg64(cpu_V0
, rn
);
6978 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6979 neon_load_reg64(cpu_V1
, rm
);
6980 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6981 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6983 neon_store_reg64(cpu_V0
, rd
);
6985 neon_store_reg64(cpu_V1
, rd
+ 1);
6987 } else if ((insn
& (1 << 11)) == 0) {
6988 /* Two register misc. */
6989 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6990 size
= (insn
>> 18) & 3;
6991 /* UNDEF for unknown op values and bad op-size combinations */
6992 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6995 if (neon_2rm_is_v8_op(op
) &&
6996 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6999 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
7000 q
&& ((rm
| rd
) & 1)) {
7004 case NEON_2RM_VREV64
:
7005 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
7006 tmp
= neon_load_reg(rm
, pass
* 2);
7007 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
7009 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7010 case 1: gen_swap_half(tmp
); break;
7011 case 2: /* no-op */ break;
7014 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
7016 neon_store_reg(rd
, pass
* 2, tmp2
);
7019 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
7020 case 1: gen_swap_half(tmp2
); break;
7023 neon_store_reg(rd
, pass
* 2, tmp2
);
7027 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
7028 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
7029 for (pass
= 0; pass
< q
+ 1; pass
++) {
7030 tmp
= neon_load_reg(rm
, pass
* 2);
7031 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
7032 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
7033 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
7035 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
7036 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
7037 case 2: tcg_gen_add_i64(CPU_V001
); break;
7040 if (op
>= NEON_2RM_VPADAL
) {
7042 neon_load_reg64(cpu_V1
, rd
+ pass
);
7043 gen_neon_addl(size
);
7045 neon_store_reg64(cpu_V0
, rd
+ pass
);
7051 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7052 tmp
= neon_load_reg(rm
, n
);
7053 tmp2
= neon_load_reg(rd
, n
+ 1);
7054 neon_store_reg(rm
, n
, tmp2
);
7055 neon_store_reg(rd
, n
+ 1, tmp
);
7062 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7067 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7071 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7072 /* also VQMOVUN; op field and mnemonics don't line up */
7076 TCGV_UNUSED_I32(tmp2
);
7077 for (pass
= 0; pass
< 2; pass
++) {
7078 neon_load_reg64(cpu_V0
, rm
+ pass
);
7079 tmp
= tcg_temp_new_i32();
7080 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7085 neon_store_reg(rd
, 0, tmp2
);
7086 neon_store_reg(rd
, 1, tmp
);
7090 case NEON_2RM_VSHLL
:
7091 if (q
|| (rd
& 1)) {
7094 tmp
= neon_load_reg(rm
, 0);
7095 tmp2
= neon_load_reg(rm
, 1);
7096 for (pass
= 0; pass
< 2; pass
++) {
7099 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7100 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7101 neon_store_reg64(cpu_V0
, rd
+ pass
);
7104 case NEON_2RM_VCVT_F16_F32
:
7105 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7109 tmp
= tcg_temp_new_i32();
7110 tmp2
= tcg_temp_new_i32();
7111 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7112 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7113 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7114 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7115 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7116 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7117 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7118 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7119 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7120 neon_store_reg(rd
, 0, tmp2
);
7121 tmp2
= tcg_temp_new_i32();
7122 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7123 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7124 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7125 neon_store_reg(rd
, 1, tmp2
);
7126 tcg_temp_free_i32(tmp
);
7128 case NEON_2RM_VCVT_F32_F16
:
7129 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7133 tmp3
= tcg_temp_new_i32();
7134 tmp
= neon_load_reg(rm
, 0);
7135 tmp2
= neon_load_reg(rm
, 1);
7136 tcg_gen_ext16u_i32(tmp3
, tmp
);
7137 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7138 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7139 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7140 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7141 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7142 tcg_temp_free_i32(tmp
);
7143 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7144 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7145 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7146 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7147 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7148 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7149 tcg_temp_free_i32(tmp2
);
7150 tcg_temp_free_i32(tmp3
);
7152 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7153 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
7154 || ((rm
| rd
) & 1)) {
7157 tmp
= tcg_const_i32(rd
);
7158 tmp2
= tcg_const_i32(rm
);
7160 /* Bit 6 is the lowest opcode bit; it distinguishes between
7161 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7163 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7165 if (op
== NEON_2RM_AESE
) {
7166 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
7168 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
7170 tcg_temp_free_i32(tmp
);
7171 tcg_temp_free_i32(tmp2
);
7172 tcg_temp_free_i32(tmp3
);
7174 case NEON_2RM_SHA1H
:
7175 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7176 || ((rm
| rd
) & 1)) {
7179 tmp
= tcg_const_i32(rd
);
7180 tmp2
= tcg_const_i32(rm
);
7182 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
7184 tcg_temp_free_i32(tmp
);
7185 tcg_temp_free_i32(tmp2
);
7187 case NEON_2RM_SHA1SU1
:
7188 if ((rm
| rd
) & 1) {
7191 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7193 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7196 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7199 tmp
= tcg_const_i32(rd
);
7200 tmp2
= tcg_const_i32(rm
);
7202 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
7204 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7206 tcg_temp_free_i32(tmp
);
7207 tcg_temp_free_i32(tmp2
);
7211 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7212 if (neon_2rm_is_float_op(op
)) {
7213 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7214 neon_reg_offset(rm
, pass
));
7215 TCGV_UNUSED_I32(tmp
);
7217 tmp
= neon_load_reg(rm
, pass
);
7220 case NEON_2RM_VREV32
:
7222 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7223 case 1: gen_swap_half(tmp
); break;
7227 case NEON_2RM_VREV16
:
7232 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7233 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7234 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7240 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7241 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7242 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7247 gen_helper_neon_cnt_u8(tmp
, tmp
);
7250 tcg_gen_not_i32(tmp
, tmp
);
7252 case NEON_2RM_VQABS
:
7255 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7258 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7261 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7266 case NEON_2RM_VQNEG
:
7269 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7272 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7275 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7280 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7281 tmp2
= tcg_const_i32(0);
7283 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7284 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7285 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7288 tcg_temp_free_i32(tmp2
);
7289 if (op
== NEON_2RM_VCLE0
) {
7290 tcg_gen_not_i32(tmp
, tmp
);
7293 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7294 tmp2
= tcg_const_i32(0);
7296 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7297 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7298 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7301 tcg_temp_free_i32(tmp2
);
7302 if (op
== NEON_2RM_VCLT0
) {
7303 tcg_gen_not_i32(tmp
, tmp
);
7306 case NEON_2RM_VCEQ0
:
7307 tmp2
= tcg_const_i32(0);
7309 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7310 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7311 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7314 tcg_temp_free_i32(tmp2
);
7318 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7319 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7320 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7325 tmp2
= tcg_const_i32(0);
7326 gen_neon_rsb(size
, tmp
, tmp2
);
7327 tcg_temp_free_i32(tmp2
);
7329 case NEON_2RM_VCGT0_F
:
7331 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7332 tmp2
= tcg_const_i32(0);
7333 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7334 tcg_temp_free_i32(tmp2
);
7335 tcg_temp_free_ptr(fpstatus
);
7338 case NEON_2RM_VCGE0_F
:
7340 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7341 tmp2
= tcg_const_i32(0);
7342 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7343 tcg_temp_free_i32(tmp2
);
7344 tcg_temp_free_ptr(fpstatus
);
7347 case NEON_2RM_VCEQ0_F
:
7349 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7350 tmp2
= tcg_const_i32(0);
7351 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7352 tcg_temp_free_i32(tmp2
);
7353 tcg_temp_free_ptr(fpstatus
);
7356 case NEON_2RM_VCLE0_F
:
7358 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7359 tmp2
= tcg_const_i32(0);
7360 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7361 tcg_temp_free_i32(tmp2
);
7362 tcg_temp_free_ptr(fpstatus
);
7365 case NEON_2RM_VCLT0_F
:
7367 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7368 tmp2
= tcg_const_i32(0);
7369 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7370 tcg_temp_free_i32(tmp2
);
7371 tcg_temp_free_ptr(fpstatus
);
7374 case NEON_2RM_VABS_F
:
7377 case NEON_2RM_VNEG_F
:
7381 tmp2
= neon_load_reg(rd
, pass
);
7382 neon_store_reg(rm
, pass
, tmp2
);
7385 tmp2
= neon_load_reg(rd
, pass
);
7387 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7388 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7391 neon_store_reg(rm
, pass
, tmp2
);
7393 case NEON_2RM_VRINTN
:
7394 case NEON_2RM_VRINTA
:
7395 case NEON_2RM_VRINTM
:
7396 case NEON_2RM_VRINTP
:
7397 case NEON_2RM_VRINTZ
:
7400 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7403 if (op
== NEON_2RM_VRINTZ
) {
7404 rmode
= FPROUNDING_ZERO
;
7406 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7409 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7410 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7412 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7413 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7415 tcg_temp_free_ptr(fpstatus
);
7416 tcg_temp_free_i32(tcg_rmode
);
7419 case NEON_2RM_VRINTX
:
7421 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7422 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7423 tcg_temp_free_ptr(fpstatus
);
7426 case NEON_2RM_VCVTAU
:
7427 case NEON_2RM_VCVTAS
:
7428 case NEON_2RM_VCVTNU
:
7429 case NEON_2RM_VCVTNS
:
7430 case NEON_2RM_VCVTPU
:
7431 case NEON_2RM_VCVTPS
:
7432 case NEON_2RM_VCVTMU
:
7433 case NEON_2RM_VCVTMS
:
7435 bool is_signed
= !extract32(insn
, 7, 1);
7436 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7437 TCGv_i32 tcg_rmode
, tcg_shift
;
7438 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7440 tcg_shift
= tcg_const_i32(0);
7441 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7442 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7446 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7449 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7453 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7455 tcg_temp_free_i32(tcg_rmode
);
7456 tcg_temp_free_i32(tcg_shift
);
7457 tcg_temp_free_ptr(fpst
);
7460 case NEON_2RM_VRECPE
:
7462 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7463 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7464 tcg_temp_free_ptr(fpstatus
);
7467 case NEON_2RM_VRSQRTE
:
7469 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7470 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7471 tcg_temp_free_ptr(fpstatus
);
7474 case NEON_2RM_VRECPE_F
:
7476 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7477 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7478 tcg_temp_free_ptr(fpstatus
);
7481 case NEON_2RM_VRSQRTE_F
:
7483 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7484 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7485 tcg_temp_free_ptr(fpstatus
);
7488 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7491 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7494 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7495 gen_vfp_tosiz(0, 1);
7497 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7498 gen_vfp_touiz(0, 1);
7501 /* Reserved op values were caught by the
7502 * neon_2rm_sizes[] check earlier.
7506 if (neon_2rm_is_float_op(op
)) {
7507 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7508 neon_reg_offset(rd
, pass
));
7510 neon_store_reg(rd
, pass
, tmp
);
7515 } else if ((insn
& (1 << 10)) == 0) {
7517 int n
= ((insn
>> 8) & 3) + 1;
7518 if ((rn
+ n
) > 32) {
7519 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7520 * helper function running off the end of the register file.
7525 if (insn
& (1 << 6)) {
7526 tmp
= neon_load_reg(rd
, 0);
7528 tmp
= tcg_temp_new_i32();
7529 tcg_gen_movi_i32(tmp
, 0);
7531 tmp2
= neon_load_reg(rm
, 0);
7532 tmp4
= tcg_const_i32(rn
);
7533 tmp5
= tcg_const_i32(n
);
7534 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7535 tcg_temp_free_i32(tmp
);
7536 if (insn
& (1 << 6)) {
7537 tmp
= neon_load_reg(rd
, 1);
7539 tmp
= tcg_temp_new_i32();
7540 tcg_gen_movi_i32(tmp
, 0);
7542 tmp3
= neon_load_reg(rm
, 1);
7543 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7544 tcg_temp_free_i32(tmp5
);
7545 tcg_temp_free_i32(tmp4
);
7546 neon_store_reg(rd
, 0, tmp2
);
7547 neon_store_reg(rd
, 1, tmp3
);
7548 tcg_temp_free_i32(tmp
);
7549 } else if ((insn
& 0x380) == 0) {
7551 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7554 if (insn
& (1 << 19)) {
7555 tmp
= neon_load_reg(rm
, 1);
7557 tmp
= neon_load_reg(rm
, 0);
7559 if (insn
& (1 << 16)) {
7560 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7561 } else if (insn
& (1 << 17)) {
7562 if ((insn
>> 18) & 1)
7563 gen_neon_dup_high16(tmp
);
7565 gen_neon_dup_low16(tmp
);
7567 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7568 tmp2
= tcg_temp_new_i32();
7569 tcg_gen_mov_i32(tmp2
, tmp
);
7570 neon_store_reg(rd
, pass
, tmp2
);
7572 tcg_temp_free_i32(tmp
);
7581 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7583 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7584 const ARMCPRegInfo
*ri
;
7586 cpnum
= (insn
>> 8) & 0xf;
7588 /* First check for coprocessor space used for XScale/iwMMXt insns */
7589 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7590 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7593 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7594 return disas_iwmmxt_insn(s
, insn
);
7595 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7596 return disas_dsp_insn(s
, insn
);
7601 /* Otherwise treat as a generic register access */
7602 is64
= (insn
& (1 << 25)) == 0;
7603 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7611 opc1
= (insn
>> 4) & 0xf;
7613 rt2
= (insn
>> 16) & 0xf;
7615 crn
= (insn
>> 16) & 0xf;
7616 opc1
= (insn
>> 21) & 7;
7617 opc2
= (insn
>> 5) & 7;
7620 isread
= (insn
>> 20) & 1;
7621 rt
= (insn
>> 12) & 0xf;
7623 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7624 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7626 /* Check access permissions */
7627 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7632 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7633 /* Emit code to perform further access permissions checks at
7634 * runtime; this may result in an exception.
7635 * Note that on XScale all cp0..c13 registers do an access check
7636 * call in order to handle c15_cpar.
7639 TCGv_i32 tcg_syn
, tcg_isread
;
7642 /* Note that since we are an implementation which takes an
7643 * exception on a trapped conditional instruction only if the
7644 * instruction passes its condition code check, we can take
7645 * advantage of the clause in the ARM ARM that allows us to set
7646 * the COND field in the instruction to 0xE in all cases.
7647 * We could fish the actual condition out of the insn (ARM)
7648 * or the condexec bits (Thumb) but it isn't necessary.
7653 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7656 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7662 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7665 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7670 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7671 * so this can only happen if this is an ARMv7 or earlier CPU,
7672 * in which case the syndrome information won't actually be
7675 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7676 syndrome
= syn_uncategorized();
7680 gen_set_condexec(s
);
7681 gen_set_pc_im(s
, s
->pc
- 4);
7682 tmpptr
= tcg_const_ptr(ri
);
7683 tcg_syn
= tcg_const_i32(syndrome
);
7684 tcg_isread
= tcg_const_i32(isread
);
7685 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7687 tcg_temp_free_ptr(tmpptr
);
7688 tcg_temp_free_i32(tcg_syn
);
7689 tcg_temp_free_i32(tcg_isread
);
7692 /* Handle special cases first */
7693 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7700 gen_set_pc_im(s
, s
->pc
);
7701 s
->base
.is_jmp
= DISAS_WFI
;
7707 if ((s
->base
.tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7716 if (ri
->type
& ARM_CP_CONST
) {
7717 tmp64
= tcg_const_i64(ri
->resetvalue
);
7718 } else if (ri
->readfn
) {
7720 tmp64
= tcg_temp_new_i64();
7721 tmpptr
= tcg_const_ptr(ri
);
7722 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7723 tcg_temp_free_ptr(tmpptr
);
7725 tmp64
= tcg_temp_new_i64();
7726 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7728 tmp
= tcg_temp_new_i32();
7729 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7730 store_reg(s
, rt
, tmp
);
7731 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7732 tmp
= tcg_temp_new_i32();
7733 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7734 tcg_temp_free_i64(tmp64
);
7735 store_reg(s
, rt2
, tmp
);
7738 if (ri
->type
& ARM_CP_CONST
) {
7739 tmp
= tcg_const_i32(ri
->resetvalue
);
7740 } else if (ri
->readfn
) {
7742 tmp
= tcg_temp_new_i32();
7743 tmpptr
= tcg_const_ptr(ri
);
7744 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7745 tcg_temp_free_ptr(tmpptr
);
7747 tmp
= load_cpu_offset(ri
->fieldoffset
);
7750 /* Destination register of r15 for 32 bit loads sets
7751 * the condition codes from the high 4 bits of the value
7754 tcg_temp_free_i32(tmp
);
7756 store_reg(s
, rt
, tmp
);
7761 if (ri
->type
& ARM_CP_CONST
) {
7762 /* If not forbidden by access permissions, treat as WI */
7767 TCGv_i32 tmplo
, tmphi
;
7768 TCGv_i64 tmp64
= tcg_temp_new_i64();
7769 tmplo
= load_reg(s
, rt
);
7770 tmphi
= load_reg(s
, rt2
);
7771 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7772 tcg_temp_free_i32(tmplo
);
7773 tcg_temp_free_i32(tmphi
);
7775 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7776 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7777 tcg_temp_free_ptr(tmpptr
);
7779 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7781 tcg_temp_free_i64(tmp64
);
7786 tmp
= load_reg(s
, rt
);
7787 tmpptr
= tcg_const_ptr(ri
);
7788 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7789 tcg_temp_free_ptr(tmpptr
);
7790 tcg_temp_free_i32(tmp
);
7792 TCGv_i32 tmp
= load_reg(s
, rt
);
7793 store_cpu_offset(tmp
, ri
->fieldoffset
);
7798 if ((s
->base
.tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7799 /* I/O operations must end the TB here (whether read or write) */
7802 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7803 /* We default to ending the TB on a coprocessor register write,
7804 * but allow this to be suppressed by the register definition
7805 * (usually only necessary to work around guest bugs).
7813 /* Unknown register; this might be a guest error or a QEMU
7814 * unimplemented feature.
7817 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7818 "64 bit system register cp:%d opc1: %d crm:%d "
7820 isread
? "read" : "write", cpnum
, opc1
, crm
,
7821 s
->ns
? "non-secure" : "secure");
7823 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7824 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7826 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7827 s
->ns
? "non-secure" : "secure");
7834 /* Store a 64-bit value to a register pair. Clobbers val. */
7835 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7838 tmp
= tcg_temp_new_i32();
7839 tcg_gen_extrl_i64_i32(tmp
, val
);
7840 store_reg(s
, rlow
, tmp
);
7841 tmp
= tcg_temp_new_i32();
7842 tcg_gen_shri_i64(val
, val
, 32);
7843 tcg_gen_extrl_i64_i32(tmp
, val
);
7844 store_reg(s
, rhigh
, tmp
);
7847 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7848 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7853 /* Load value and extend to 64 bits. */
7854 tmp
= tcg_temp_new_i64();
7855 tmp2
= load_reg(s
, rlow
);
7856 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7857 tcg_temp_free_i32(tmp2
);
7858 tcg_gen_add_i64(val
, val
, tmp
);
7859 tcg_temp_free_i64(tmp
);
7862 /* load and add a 64-bit value from a register pair. */
7863 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7869 /* Load 64-bit value rd:rn. */
7870 tmpl
= load_reg(s
, rlow
);
7871 tmph
= load_reg(s
, rhigh
);
7872 tmp
= tcg_temp_new_i64();
7873 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7874 tcg_temp_free_i32(tmpl
);
7875 tcg_temp_free_i32(tmph
);
7876 tcg_gen_add_i64(val
, val
, tmp
);
7877 tcg_temp_free_i64(tmp
);
7880 /* Set N and Z flags from hi|lo. */
7881 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7883 tcg_gen_mov_i32(cpu_NF
, hi
);
7884 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7887 /* Load/Store exclusive instructions are implemented by remembering
7888 the value/address loaded, and seeing if these are the same
7889 when the store is performed. This should be sufficient to implement
7890 the architecturally mandated semantics, and avoids having to monitor
7891 regular stores. The compare vs the remembered value is done during
7892 the cmpxchg operation, but we must compare the addresses manually. */
7893 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7894 TCGv_i32 addr
, int size
)
7896 TCGv_i32 tmp
= tcg_temp_new_i32();
7897 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7902 TCGv_i32 tmp2
= tcg_temp_new_i32();
7903 TCGv_i64 t64
= tcg_temp_new_i64();
7905 gen_aa32_ld_i64(s
, t64
, addr
, get_mem_index(s
), opc
);
7906 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
7907 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
7908 tcg_temp_free_i64(t64
);
7910 store_reg(s
, rt2
, tmp2
);
7912 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
7913 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7916 store_reg(s
, rt
, tmp
);
7917 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7920 static void gen_clrex(DisasContext
*s
)
7922 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7925 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7926 TCGv_i32 addr
, int size
)
7928 TCGv_i32 t0
, t1
, t2
;
7931 TCGLabel
*done_label
;
7932 TCGLabel
*fail_label
;
7933 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7935 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7941 fail_label
= gen_new_label();
7942 done_label
= gen_new_label();
7943 extaddr
= tcg_temp_new_i64();
7944 tcg_gen_extu_i32_i64(extaddr
, addr
);
7945 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7946 tcg_temp_free_i64(extaddr
);
7948 taddr
= gen_aa32_addr(s
, addr
, opc
);
7949 t0
= tcg_temp_new_i32();
7950 t1
= load_reg(s
, rt
);
7952 TCGv_i64 o64
= tcg_temp_new_i64();
7953 TCGv_i64 n64
= tcg_temp_new_i64();
7955 t2
= load_reg(s
, rt2
);
7956 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
7957 tcg_temp_free_i32(t2
);
7958 gen_aa32_frob64(s
, n64
);
7960 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
7961 get_mem_index(s
), opc
);
7962 tcg_temp_free_i64(n64
);
7964 gen_aa32_frob64(s
, o64
);
7965 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
7966 tcg_gen_extrl_i64_i32(t0
, o64
);
7968 tcg_temp_free_i64(o64
);
7970 t2
= tcg_temp_new_i32();
7971 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
7972 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
7973 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
7974 tcg_temp_free_i32(t2
);
7976 tcg_temp_free_i32(t1
);
7977 tcg_temp_free(taddr
);
7978 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
7979 tcg_temp_free_i32(t0
);
7980 tcg_gen_br(done_label
);
7982 gen_set_label(fail_label
);
7983 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7984 gen_set_label(done_label
);
7985 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7991 * @mode: mode field from insn (which stack to store to)
7992 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7993 * @writeback: true if writeback bit set
7995 * Generate code for the SRS (Store Return State) insn.
7997 static void gen_srs(DisasContext
*s
,
7998 uint32_t mode
, uint32_t amode
, bool writeback
)
8005 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8006 * and specified mode is monitor mode
8007 * - UNDEFINED in Hyp mode
8008 * - UNPREDICTABLE in User or System mode
8009 * - UNPREDICTABLE if the specified mode is:
8010 * -- not implemented
8011 * -- not a valid mode number
8012 * -- a mode that's at a higher exception level
8013 * -- Monitor, if we are Non-secure
8014 * For the UNPREDICTABLE cases we choose to UNDEF.
8016 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
8017 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
8021 if (s
->current_el
== 0 || s
->current_el
== 2) {
8026 case ARM_CPU_MODE_USR
:
8027 case ARM_CPU_MODE_FIQ
:
8028 case ARM_CPU_MODE_IRQ
:
8029 case ARM_CPU_MODE_SVC
:
8030 case ARM_CPU_MODE_ABT
:
8031 case ARM_CPU_MODE_UND
:
8032 case ARM_CPU_MODE_SYS
:
8034 case ARM_CPU_MODE_HYP
:
8035 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
8039 case ARM_CPU_MODE_MON
:
8040 /* No need to check specifically for "are we non-secure" because
8041 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8042 * so if this isn't EL3 then we must be non-secure.
8044 if (s
->current_el
!= 3) {
8053 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8054 default_exception_el(s
));
8058 addr
= tcg_temp_new_i32();
8059 tmp
= tcg_const_i32(mode
);
8060 /* get_r13_banked() will raise an exception if called from System mode */
8061 gen_set_condexec(s
);
8062 gen_set_pc_im(s
, s
->pc
- 4);
8063 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8064 tcg_temp_free_i32(tmp
);
8081 tcg_gen_addi_i32(addr
, addr
, offset
);
8082 tmp
= load_reg(s
, 14);
8083 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8084 tcg_temp_free_i32(tmp
);
8085 tmp
= load_cpu_field(spsr
);
8086 tcg_gen_addi_i32(addr
, addr
, 4);
8087 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8088 tcg_temp_free_i32(tmp
);
8106 tcg_gen_addi_i32(addr
, addr
, offset
);
8107 tmp
= tcg_const_i32(mode
);
8108 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8109 tcg_temp_free_i32(tmp
);
8111 tcg_temp_free_i32(addr
);
8112 s
->base
.is_jmp
= DISAS_UPDATE
;
8115 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8117 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8124 /* M variants do not implement ARM mode; this must raise the INVSTATE
8125 * UsageFault exception.
8127 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8128 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8129 default_exception_el(s
));
8134 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8135 * choose to UNDEF. In ARMv5 and above the space is used
8136 * for miscellaneous unconditional instructions.
8140 /* Unconditional instructions. */
8141 if (((insn
>> 25) & 7) == 1) {
8142 /* NEON Data processing. */
8143 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8147 if (disas_neon_data_insn(s
, insn
)) {
8152 if ((insn
& 0x0f100000) == 0x04000000) {
8153 /* NEON load/store. */
8154 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8158 if (disas_neon_ls_insn(s
, insn
)) {
8163 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8165 if (disas_vfp_insn(s
, insn
)) {
8170 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8171 ((insn
& 0x0f30f010) == 0x0710f000)) {
8172 if ((insn
& (1 << 22)) == 0) {
8174 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8178 /* Otherwise PLD; v5TE+ */
8182 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8183 ((insn
& 0x0f70f010) == 0x0650f000)) {
8185 return; /* PLI; V7 */
8187 if (((insn
& 0x0f700000) == 0x04100000) ||
8188 ((insn
& 0x0f700010) == 0x06100000)) {
8189 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8192 return; /* v7MP: Unallocated memory hint: must NOP */
8195 if ((insn
& 0x0ffffdff) == 0x01010000) {
8198 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8199 gen_helper_setend(cpu_env
);
8200 s
->base
.is_jmp
= DISAS_UPDATE
;
8203 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8204 switch ((insn
>> 4) & 0xf) {
8212 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8215 /* We need to break the TB after this insn to execute
8216 * self-modifying code correctly and also to take
8217 * any pending interrupts immediately.
8219 gen_goto_tb(s
, 0, s
->pc
& ~1);
8224 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8227 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8229 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8235 rn
= (insn
>> 16) & 0xf;
8236 addr
= load_reg(s
, rn
);
8237 i
= (insn
>> 23) & 3;
8239 case 0: offset
= -4; break; /* DA */
8240 case 1: offset
= 0; break; /* IA */
8241 case 2: offset
= -8; break; /* DB */
8242 case 3: offset
= 4; break; /* IB */
8246 tcg_gen_addi_i32(addr
, addr
, offset
);
8247 /* Load PC into tmp and CPSR into tmp2. */
8248 tmp
= tcg_temp_new_i32();
8249 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8250 tcg_gen_addi_i32(addr
, addr
, 4);
8251 tmp2
= tcg_temp_new_i32();
8252 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8253 if (insn
& (1 << 21)) {
8254 /* Base writeback. */
8256 case 0: offset
= -8; break;
8257 case 1: offset
= 4; break;
8258 case 2: offset
= -4; break;
8259 case 3: offset
= 0; break;
8263 tcg_gen_addi_i32(addr
, addr
, offset
);
8264 store_reg(s
, rn
, addr
);
8266 tcg_temp_free_i32(addr
);
8268 gen_rfe(s
, tmp
, tmp2
);
8270 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8271 /* branch link and change to thumb (blx <offset>) */
8274 val
= (uint32_t)s
->pc
;
8275 tmp
= tcg_temp_new_i32();
8276 tcg_gen_movi_i32(tmp
, val
);
8277 store_reg(s
, 14, tmp
);
8278 /* Sign-extend the 24-bit offset */
8279 offset
= (((int32_t)insn
) << 8) >> 8;
8280 /* offset * 4 + bit24 * 2 + (thumb bit) */
8281 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8282 /* pipeline offset */
8284 /* protected by ARCH(5); above, near the start of uncond block */
8287 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8288 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8289 /* iWMMXt register transfer. */
8290 if (extract32(s
->c15_cpar
, 1, 1)) {
8291 if (!disas_iwmmxt_insn(s
, insn
)) {
8296 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8297 /* Coprocessor double register transfer. */
8299 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8300 /* Additional coprocessor register transfer. */
8301 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8304 /* cps (privileged) */
8308 if (insn
& (1 << 19)) {
8309 if (insn
& (1 << 8))
8311 if (insn
& (1 << 7))
8313 if (insn
& (1 << 6))
8315 if (insn
& (1 << 18))
8318 if (insn
& (1 << 17)) {
8320 val
|= (insn
& 0x1f);
8323 gen_set_psr_im(s
, mask
, 0, val
);
8330 /* if not always execute, we generate a conditional jump to
8332 s
->condlabel
= gen_new_label();
8333 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8336 if ((insn
& 0x0f900000) == 0x03000000) {
8337 if ((insn
& (1 << 21)) == 0) {
8339 rd
= (insn
>> 12) & 0xf;
8340 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8341 if ((insn
& (1 << 22)) == 0) {
8343 tmp
= tcg_temp_new_i32();
8344 tcg_gen_movi_i32(tmp
, val
);
8347 tmp
= load_reg(s
, rd
);
8348 tcg_gen_ext16u_i32(tmp
, tmp
);
8349 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8351 store_reg(s
, rd
, tmp
);
8353 if (((insn
>> 12) & 0xf) != 0xf)
8355 if (((insn
>> 16) & 0xf) == 0) {
8356 gen_nop_hint(s
, insn
& 0xff);
8358 /* CPSR = immediate */
8360 shift
= ((insn
>> 8) & 0xf) * 2;
8362 val
= (val
>> shift
) | (val
<< (32 - shift
));
8363 i
= ((insn
& (1 << 22)) != 0);
8364 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8370 } else if ((insn
& 0x0f900000) == 0x01000000
8371 && (insn
& 0x00000090) != 0x00000090) {
8372 /* miscellaneous instructions */
8373 op1
= (insn
>> 21) & 3;
8374 sh
= (insn
>> 4) & 0xf;
8377 case 0x0: /* MSR, MRS */
8378 if (insn
& (1 << 9)) {
8379 /* MSR (banked) and MRS (banked) */
8380 int sysm
= extract32(insn
, 16, 4) |
8381 (extract32(insn
, 8, 1) << 4);
8382 int r
= extract32(insn
, 22, 1);
8386 gen_msr_banked(s
, r
, sysm
, rm
);
8389 int rd
= extract32(insn
, 12, 4);
8391 gen_mrs_banked(s
, r
, sysm
, rd
);
8396 /* MSR, MRS (for PSRs) */
8399 tmp
= load_reg(s
, rm
);
8400 i
= ((op1
& 2) != 0);
8401 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8405 rd
= (insn
>> 12) & 0xf;
8409 tmp
= load_cpu_field(spsr
);
8411 tmp
= tcg_temp_new_i32();
8412 gen_helper_cpsr_read(tmp
, cpu_env
);
8414 store_reg(s
, rd
, tmp
);
8419 /* branch/exchange thumb (bx). */
8421 tmp
= load_reg(s
, rm
);
8423 } else if (op1
== 3) {
8426 rd
= (insn
>> 12) & 0xf;
8427 tmp
= load_reg(s
, rm
);
8428 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8429 store_reg(s
, rd
, tmp
);
8437 /* Trivial implementation equivalent to bx. */
8438 tmp
= load_reg(s
, rm
);
8449 /* branch link/exchange thumb (blx) */
8450 tmp
= load_reg(s
, rm
);
8451 tmp2
= tcg_temp_new_i32();
8452 tcg_gen_movi_i32(tmp2
, s
->pc
);
8453 store_reg(s
, 14, tmp2
);
8459 uint32_t c
= extract32(insn
, 8, 4);
8461 /* Check this CPU supports ARMv8 CRC instructions.
8462 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8463 * Bits 8, 10 and 11 should be zero.
8465 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8470 rn
= extract32(insn
, 16, 4);
8471 rd
= extract32(insn
, 12, 4);
8473 tmp
= load_reg(s
, rn
);
8474 tmp2
= load_reg(s
, rm
);
8476 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8477 } else if (op1
== 1) {
8478 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8480 tmp3
= tcg_const_i32(1 << op1
);
8482 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8484 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8486 tcg_temp_free_i32(tmp2
);
8487 tcg_temp_free_i32(tmp3
);
8488 store_reg(s
, rd
, tmp
);
8491 case 0x5: /* saturating add/subtract */
8493 rd
= (insn
>> 12) & 0xf;
8494 rn
= (insn
>> 16) & 0xf;
8495 tmp
= load_reg(s
, rm
);
8496 tmp2
= load_reg(s
, rn
);
8498 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8500 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8502 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8503 tcg_temp_free_i32(tmp2
);
8504 store_reg(s
, rd
, tmp
);
8508 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8517 gen_exception_insn(s
, 4, EXCP_BKPT
,
8518 syn_aa32_bkpt(imm16
, false),
8519 default_exception_el(s
));
8522 /* Hypervisor call (v7) */
8530 /* Secure monitor call (v6+) */
8538 g_assert_not_reached();
8542 case 0x8: /* signed multiply */
8547 rs
= (insn
>> 8) & 0xf;
8548 rn
= (insn
>> 12) & 0xf;
8549 rd
= (insn
>> 16) & 0xf;
8551 /* (32 * 16) >> 16 */
8552 tmp
= load_reg(s
, rm
);
8553 tmp2
= load_reg(s
, rs
);
8555 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8558 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8559 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8560 tmp
= tcg_temp_new_i32();
8561 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8562 tcg_temp_free_i64(tmp64
);
8563 if ((sh
& 2) == 0) {
8564 tmp2
= load_reg(s
, rn
);
8565 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8566 tcg_temp_free_i32(tmp2
);
8568 store_reg(s
, rd
, tmp
);
8571 tmp
= load_reg(s
, rm
);
8572 tmp2
= load_reg(s
, rs
);
8573 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8574 tcg_temp_free_i32(tmp2
);
8576 tmp64
= tcg_temp_new_i64();
8577 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8578 tcg_temp_free_i32(tmp
);
8579 gen_addq(s
, tmp64
, rn
, rd
);
8580 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8581 tcg_temp_free_i64(tmp64
);
8584 tmp2
= load_reg(s
, rn
);
8585 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8586 tcg_temp_free_i32(tmp2
);
8588 store_reg(s
, rd
, tmp
);
8595 } else if (((insn
& 0x0e000000) == 0 &&
8596 (insn
& 0x00000090) != 0x90) ||
8597 ((insn
& 0x0e000000) == (1 << 25))) {
8598 int set_cc
, logic_cc
, shiftop
;
8600 op1
= (insn
>> 21) & 0xf;
8601 set_cc
= (insn
>> 20) & 1;
8602 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8604 /* data processing instruction */
8605 if (insn
& (1 << 25)) {
8606 /* immediate operand */
8608 shift
= ((insn
>> 8) & 0xf) * 2;
8610 val
= (val
>> shift
) | (val
<< (32 - shift
));
8612 tmp2
= tcg_temp_new_i32();
8613 tcg_gen_movi_i32(tmp2
, val
);
8614 if (logic_cc
&& shift
) {
8615 gen_set_CF_bit31(tmp2
);
8620 tmp2
= load_reg(s
, rm
);
8621 shiftop
= (insn
>> 5) & 3;
8622 if (!(insn
& (1 << 4))) {
8623 shift
= (insn
>> 7) & 0x1f;
8624 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8626 rs
= (insn
>> 8) & 0xf;
8627 tmp
= load_reg(s
, rs
);
8628 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8631 if (op1
!= 0x0f && op1
!= 0x0d) {
8632 rn
= (insn
>> 16) & 0xf;
8633 tmp
= load_reg(s
, rn
);
8635 TCGV_UNUSED_I32(tmp
);
8637 rd
= (insn
>> 12) & 0xf;
8640 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8644 store_reg_bx(s
, rd
, tmp
);
8647 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8651 store_reg_bx(s
, rd
, tmp
);
8654 if (set_cc
&& rd
== 15) {
8655 /* SUBS r15, ... is used for exception return. */
8659 gen_sub_CC(tmp
, tmp
, tmp2
);
8660 gen_exception_return(s
, tmp
);
8663 gen_sub_CC(tmp
, tmp
, tmp2
);
8665 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8667 store_reg_bx(s
, rd
, tmp
);
8672 gen_sub_CC(tmp
, tmp2
, tmp
);
8674 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8676 store_reg_bx(s
, rd
, tmp
);
8680 gen_add_CC(tmp
, tmp
, tmp2
);
8682 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8684 store_reg_bx(s
, rd
, tmp
);
8688 gen_adc_CC(tmp
, tmp
, tmp2
);
8690 gen_add_carry(tmp
, tmp
, tmp2
);
8692 store_reg_bx(s
, rd
, tmp
);
8696 gen_sbc_CC(tmp
, tmp
, tmp2
);
8698 gen_sub_carry(tmp
, tmp
, tmp2
);
8700 store_reg_bx(s
, rd
, tmp
);
8704 gen_sbc_CC(tmp
, tmp2
, tmp
);
8706 gen_sub_carry(tmp
, tmp2
, tmp
);
8708 store_reg_bx(s
, rd
, tmp
);
8712 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8715 tcg_temp_free_i32(tmp
);
8719 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8722 tcg_temp_free_i32(tmp
);
8726 gen_sub_CC(tmp
, tmp
, tmp2
);
8728 tcg_temp_free_i32(tmp
);
8732 gen_add_CC(tmp
, tmp
, tmp2
);
8734 tcg_temp_free_i32(tmp
);
8737 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8741 store_reg_bx(s
, rd
, tmp
);
8744 if (logic_cc
&& rd
== 15) {
8745 /* MOVS r15, ... is used for exception return. */
8749 gen_exception_return(s
, tmp2
);
8754 store_reg_bx(s
, rd
, tmp2
);
8758 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8762 store_reg_bx(s
, rd
, tmp
);
8766 tcg_gen_not_i32(tmp2
, tmp2
);
8770 store_reg_bx(s
, rd
, tmp2
);
8773 if (op1
!= 0x0f && op1
!= 0x0d) {
8774 tcg_temp_free_i32(tmp2
);
8777 /* other instructions */
8778 op1
= (insn
>> 24) & 0xf;
8782 /* multiplies, extra load/stores */
8783 sh
= (insn
>> 5) & 3;
8786 rd
= (insn
>> 16) & 0xf;
8787 rn
= (insn
>> 12) & 0xf;
8788 rs
= (insn
>> 8) & 0xf;
8790 op1
= (insn
>> 20) & 0xf;
8792 case 0: case 1: case 2: case 3: case 6:
8794 tmp
= load_reg(s
, rs
);
8795 tmp2
= load_reg(s
, rm
);
8796 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8797 tcg_temp_free_i32(tmp2
);
8798 if (insn
& (1 << 22)) {
8799 /* Subtract (mls) */
8801 tmp2
= load_reg(s
, rn
);
8802 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8803 tcg_temp_free_i32(tmp2
);
8804 } else if (insn
& (1 << 21)) {
8806 tmp2
= load_reg(s
, rn
);
8807 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8808 tcg_temp_free_i32(tmp2
);
8810 if (insn
& (1 << 20))
8812 store_reg(s
, rd
, tmp
);
8815 /* 64 bit mul double accumulate (UMAAL) */
8817 tmp
= load_reg(s
, rs
);
8818 tmp2
= load_reg(s
, rm
);
8819 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8820 gen_addq_lo(s
, tmp64
, rn
);
8821 gen_addq_lo(s
, tmp64
, rd
);
8822 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8823 tcg_temp_free_i64(tmp64
);
8825 case 8: case 9: case 10: case 11:
8826 case 12: case 13: case 14: case 15:
8827 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8828 tmp
= load_reg(s
, rs
);
8829 tmp2
= load_reg(s
, rm
);
8830 if (insn
& (1 << 22)) {
8831 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8833 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8835 if (insn
& (1 << 21)) { /* mult accumulate */
8836 TCGv_i32 al
= load_reg(s
, rn
);
8837 TCGv_i32 ah
= load_reg(s
, rd
);
8838 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8839 tcg_temp_free_i32(al
);
8840 tcg_temp_free_i32(ah
);
8842 if (insn
& (1 << 20)) {
8843 gen_logicq_cc(tmp
, tmp2
);
8845 store_reg(s
, rn
, tmp
);
8846 store_reg(s
, rd
, tmp2
);
8852 rn
= (insn
>> 16) & 0xf;
8853 rd
= (insn
>> 12) & 0xf;
8854 if (insn
& (1 << 23)) {
8855 /* load/store exclusive */
8856 int op2
= (insn
>> 8) & 3;
8857 op1
= (insn
>> 21) & 0x3;
8860 case 0: /* lda/stl */
8866 case 1: /* reserved */
8868 case 2: /* ldaex/stlex */
8871 case 3: /* ldrex/strex */
8880 addr
= tcg_temp_local_new_i32();
8881 load_reg_var(s
, addr
, rn
);
8883 /* Since the emulation does not have barriers,
8884 the acquire/release semantics need no special
8887 if (insn
& (1 << 20)) {
8888 tmp
= tcg_temp_new_i32();
8891 gen_aa32_ld32u_iss(s
, tmp
, addr
,
8896 gen_aa32_ld8u_iss(s
, tmp
, addr
,
8901 gen_aa32_ld16u_iss(s
, tmp
, addr
,
8908 store_reg(s
, rd
, tmp
);
8911 tmp
= load_reg(s
, rm
);
8914 gen_aa32_st32_iss(s
, tmp
, addr
,
8919 gen_aa32_st8_iss(s
, tmp
, addr
,
8924 gen_aa32_st16_iss(s
, tmp
, addr
,
8931 tcg_temp_free_i32(tmp
);
8933 } else if (insn
& (1 << 20)) {
8936 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8938 case 1: /* ldrexd */
8939 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8941 case 2: /* ldrexb */
8942 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8944 case 3: /* ldrexh */
8945 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8954 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8956 case 1: /* strexd */
8957 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8959 case 2: /* strexb */
8960 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8962 case 3: /* strexh */
8963 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8969 tcg_temp_free_i32(addr
);
8972 TCGMemOp opc
= s
->be_data
;
8974 /* SWP instruction */
8977 if (insn
& (1 << 22)) {
8980 opc
|= MO_UL
| MO_ALIGN
;
8983 addr
= load_reg(s
, rn
);
8984 taddr
= gen_aa32_addr(s
, addr
, opc
);
8985 tcg_temp_free_i32(addr
);
8987 tmp
= load_reg(s
, rm
);
8988 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
8989 get_mem_index(s
), opc
);
8990 tcg_temp_free(taddr
);
8991 store_reg(s
, rd
, tmp
);
8996 bool load
= insn
& (1 << 20);
8997 bool wbit
= insn
& (1 << 21);
8998 bool pbit
= insn
& (1 << 24);
8999 bool doubleword
= false;
9002 /* Misc load/store */
9003 rn
= (insn
>> 16) & 0xf;
9004 rd
= (insn
>> 12) & 0xf;
9006 /* ISS not valid if writeback */
9007 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
9009 if (!load
&& (sh
& 2)) {
9013 /* UNPREDICTABLE; we choose to UNDEF */
9016 load
= (sh
& 1) == 0;
9020 addr
= load_reg(s
, rn
);
9022 gen_add_datah_offset(s
, insn
, 0, addr
);
9029 tmp
= load_reg(s
, rd
);
9030 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9031 tcg_temp_free_i32(tmp
);
9032 tcg_gen_addi_i32(addr
, addr
, 4);
9033 tmp
= load_reg(s
, rd
+ 1);
9034 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9035 tcg_temp_free_i32(tmp
);
9038 tmp
= tcg_temp_new_i32();
9039 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9040 store_reg(s
, rd
, tmp
);
9041 tcg_gen_addi_i32(addr
, addr
, 4);
9042 tmp
= tcg_temp_new_i32();
9043 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9046 address_offset
= -4;
9049 tmp
= tcg_temp_new_i32();
9052 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9056 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9061 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9067 tmp
= load_reg(s
, rd
);
9068 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9069 tcg_temp_free_i32(tmp
);
9071 /* Perform base writeback before the loaded value to
9072 ensure correct behavior with overlapping index registers.
9073 ldrd with base writeback is undefined if the
9074 destination and index registers overlap. */
9076 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9077 store_reg(s
, rn
, addr
);
9080 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9081 store_reg(s
, rn
, addr
);
9083 tcg_temp_free_i32(addr
);
9086 /* Complete the load. */
9087 store_reg(s
, rd
, tmp
);
9096 if (insn
& (1 << 4)) {
9098 /* Armv6 Media instructions. */
9100 rn
= (insn
>> 16) & 0xf;
9101 rd
= (insn
>> 12) & 0xf;
9102 rs
= (insn
>> 8) & 0xf;
9103 switch ((insn
>> 23) & 3) {
9104 case 0: /* Parallel add/subtract. */
9105 op1
= (insn
>> 20) & 7;
9106 tmp
= load_reg(s
, rn
);
9107 tmp2
= load_reg(s
, rm
);
9108 sh
= (insn
>> 5) & 7;
9109 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9111 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9112 tcg_temp_free_i32(tmp2
);
9113 store_reg(s
, rd
, tmp
);
9116 if ((insn
& 0x00700020) == 0) {
9117 /* Halfword pack. */
9118 tmp
= load_reg(s
, rn
);
9119 tmp2
= load_reg(s
, rm
);
9120 shift
= (insn
>> 7) & 0x1f;
9121 if (insn
& (1 << 6)) {
9125 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9126 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9127 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9131 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9132 tcg_gen_ext16u_i32(tmp
, tmp
);
9133 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9135 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9136 tcg_temp_free_i32(tmp2
);
9137 store_reg(s
, rd
, tmp
);
9138 } else if ((insn
& 0x00200020) == 0x00200000) {
9140 tmp
= load_reg(s
, rm
);
9141 shift
= (insn
>> 7) & 0x1f;
9142 if (insn
& (1 << 6)) {
9145 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9147 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9149 sh
= (insn
>> 16) & 0x1f;
9150 tmp2
= tcg_const_i32(sh
);
9151 if (insn
& (1 << 22))
9152 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9154 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9155 tcg_temp_free_i32(tmp2
);
9156 store_reg(s
, rd
, tmp
);
9157 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9159 tmp
= load_reg(s
, rm
);
9160 sh
= (insn
>> 16) & 0x1f;
9161 tmp2
= tcg_const_i32(sh
);
9162 if (insn
& (1 << 22))
9163 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9165 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9166 tcg_temp_free_i32(tmp2
);
9167 store_reg(s
, rd
, tmp
);
9168 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9170 tmp
= load_reg(s
, rn
);
9171 tmp2
= load_reg(s
, rm
);
9172 tmp3
= tcg_temp_new_i32();
9173 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9174 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9175 tcg_temp_free_i32(tmp3
);
9176 tcg_temp_free_i32(tmp2
);
9177 store_reg(s
, rd
, tmp
);
9178 } else if ((insn
& 0x000003e0) == 0x00000060) {
9179 tmp
= load_reg(s
, rm
);
9180 shift
= (insn
>> 10) & 3;
9181 /* ??? In many cases it's not necessary to do a
9182 rotate, a shift is sufficient. */
9184 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9185 op1
= (insn
>> 20) & 7;
9187 case 0: gen_sxtb16(tmp
); break;
9188 case 2: gen_sxtb(tmp
); break;
9189 case 3: gen_sxth(tmp
); break;
9190 case 4: gen_uxtb16(tmp
); break;
9191 case 6: gen_uxtb(tmp
); break;
9192 case 7: gen_uxth(tmp
); break;
9193 default: goto illegal_op
;
9196 tmp2
= load_reg(s
, rn
);
9197 if ((op1
& 3) == 0) {
9198 gen_add16(tmp
, tmp2
);
9200 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9201 tcg_temp_free_i32(tmp2
);
9204 store_reg(s
, rd
, tmp
);
9205 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9207 tmp
= load_reg(s
, rm
);
9208 if (insn
& (1 << 22)) {
9209 if (insn
& (1 << 7)) {
9213 gen_helper_rbit(tmp
, tmp
);
9216 if (insn
& (1 << 7))
9219 tcg_gen_bswap32_i32(tmp
, tmp
);
9221 store_reg(s
, rd
, tmp
);
9226 case 2: /* Multiplies (Type 3). */
9227 switch ((insn
>> 20) & 0x7) {
9229 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9230 /* op2 not 00x or 11x : UNDEF */
9233 /* Signed multiply most significant [accumulate].
9234 (SMMUL, SMMLA, SMMLS) */
9235 tmp
= load_reg(s
, rm
);
9236 tmp2
= load_reg(s
, rs
);
9237 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9240 tmp
= load_reg(s
, rd
);
9241 if (insn
& (1 << 6)) {
9242 tmp64
= gen_subq_msw(tmp64
, tmp
);
9244 tmp64
= gen_addq_msw(tmp64
, tmp
);
9247 if (insn
& (1 << 5)) {
9248 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9250 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9251 tmp
= tcg_temp_new_i32();
9252 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9253 tcg_temp_free_i64(tmp64
);
9254 store_reg(s
, rn
, tmp
);
9258 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9259 if (insn
& (1 << 7)) {
9262 tmp
= load_reg(s
, rm
);
9263 tmp2
= load_reg(s
, rs
);
9264 if (insn
& (1 << 5))
9265 gen_swap_half(tmp2
);
9266 gen_smul_dual(tmp
, tmp2
);
9267 if (insn
& (1 << 22)) {
9268 /* smlald, smlsld */
9271 tmp64
= tcg_temp_new_i64();
9272 tmp64_2
= tcg_temp_new_i64();
9273 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9274 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9275 tcg_temp_free_i32(tmp
);
9276 tcg_temp_free_i32(tmp2
);
9277 if (insn
& (1 << 6)) {
9278 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9280 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9282 tcg_temp_free_i64(tmp64_2
);
9283 gen_addq(s
, tmp64
, rd
, rn
);
9284 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9285 tcg_temp_free_i64(tmp64
);
9287 /* smuad, smusd, smlad, smlsd */
9288 if (insn
& (1 << 6)) {
9289 /* This subtraction cannot overflow. */
9290 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9292 /* This addition cannot overflow 32 bits;
9293 * however it may overflow considered as a
9294 * signed operation, in which case we must set
9297 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9299 tcg_temp_free_i32(tmp2
);
9302 tmp2
= load_reg(s
, rd
);
9303 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9304 tcg_temp_free_i32(tmp2
);
9306 store_reg(s
, rn
, tmp
);
9312 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9315 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9318 tmp
= load_reg(s
, rm
);
9319 tmp2
= load_reg(s
, rs
);
9320 if (insn
& (1 << 21)) {
9321 gen_helper_udiv(tmp
, tmp
, tmp2
);
9323 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9325 tcg_temp_free_i32(tmp2
);
9326 store_reg(s
, rn
, tmp
);
9333 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9335 case 0: /* Unsigned sum of absolute differences. */
9337 tmp
= load_reg(s
, rm
);
9338 tmp2
= load_reg(s
, rs
);
9339 gen_helper_usad8(tmp
, tmp
, tmp2
);
9340 tcg_temp_free_i32(tmp2
);
9342 tmp2
= load_reg(s
, rd
);
9343 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9344 tcg_temp_free_i32(tmp2
);
9346 store_reg(s
, rn
, tmp
);
9348 case 0x20: case 0x24: case 0x28: case 0x2c:
9349 /* Bitfield insert/clear. */
9351 shift
= (insn
>> 7) & 0x1f;
9352 i
= (insn
>> 16) & 0x1f;
9354 /* UNPREDICTABLE; we choose to UNDEF */
9359 tmp
= tcg_temp_new_i32();
9360 tcg_gen_movi_i32(tmp
, 0);
9362 tmp
= load_reg(s
, rm
);
9365 tmp2
= load_reg(s
, rd
);
9366 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9367 tcg_temp_free_i32(tmp2
);
9369 store_reg(s
, rd
, tmp
);
9371 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9372 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9374 tmp
= load_reg(s
, rm
);
9375 shift
= (insn
>> 7) & 0x1f;
9376 i
= ((insn
>> 16) & 0x1f) + 1;
9381 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9383 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9386 store_reg(s
, rd
, tmp
);
9396 /* Check for undefined extension instructions
9397 * per the ARM Bible IE:
9398 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9400 sh
= (0xf << 20) | (0xf << 4);
9401 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9405 /* load/store byte/word */
9406 rn
= (insn
>> 16) & 0xf;
9407 rd
= (insn
>> 12) & 0xf;
9408 tmp2
= load_reg(s
, rn
);
9409 if ((insn
& 0x01200000) == 0x00200000) {
9411 i
= get_a32_user_mem_index(s
);
9413 i
= get_mem_index(s
);
9415 if (insn
& (1 << 24))
9416 gen_add_data_offset(s
, insn
, tmp2
);
9417 if (insn
& (1 << 20)) {
9419 tmp
= tcg_temp_new_i32();
9420 if (insn
& (1 << 22)) {
9421 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9423 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9427 tmp
= load_reg(s
, rd
);
9428 if (insn
& (1 << 22)) {
9429 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9431 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9433 tcg_temp_free_i32(tmp
);
9435 if (!(insn
& (1 << 24))) {
9436 gen_add_data_offset(s
, insn
, tmp2
);
9437 store_reg(s
, rn
, tmp2
);
9438 } else if (insn
& (1 << 21)) {
9439 store_reg(s
, rn
, tmp2
);
9441 tcg_temp_free_i32(tmp2
);
9443 if (insn
& (1 << 20)) {
9444 /* Complete the load. */
9445 store_reg_from_load(s
, rd
, tmp
);
9451 int j
, n
, loaded_base
;
9452 bool exc_return
= false;
9453 bool is_load
= extract32(insn
, 20, 1);
9455 TCGv_i32 loaded_var
;
9456 /* load/store multiple words */
9457 /* XXX: store correct base if write back */
9458 if (insn
& (1 << 22)) {
9459 /* LDM (user), LDM (exception return) and STM (user) */
9461 goto illegal_op
; /* only usable in supervisor mode */
9463 if (is_load
&& extract32(insn
, 15, 1)) {
9469 rn
= (insn
>> 16) & 0xf;
9470 addr
= load_reg(s
, rn
);
9472 /* compute total size */
9474 TCGV_UNUSED_I32(loaded_var
);
9477 if (insn
& (1 << i
))
9480 /* XXX: test invalid n == 0 case ? */
9481 if (insn
& (1 << 23)) {
9482 if (insn
& (1 << 24)) {
9484 tcg_gen_addi_i32(addr
, addr
, 4);
9486 /* post increment */
9489 if (insn
& (1 << 24)) {
9491 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9493 /* post decrement */
9495 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9500 if (insn
& (1 << i
)) {
9503 tmp
= tcg_temp_new_i32();
9504 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9506 tmp2
= tcg_const_i32(i
);
9507 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9508 tcg_temp_free_i32(tmp2
);
9509 tcg_temp_free_i32(tmp
);
9510 } else if (i
== rn
) {
9513 } else if (rn
== 15 && exc_return
) {
9514 store_pc_exc_ret(s
, tmp
);
9516 store_reg_from_load(s
, i
, tmp
);
9521 /* special case: r15 = PC + 8 */
9522 val
= (long)s
->pc
+ 4;
9523 tmp
= tcg_temp_new_i32();
9524 tcg_gen_movi_i32(tmp
, val
);
9526 tmp
= tcg_temp_new_i32();
9527 tmp2
= tcg_const_i32(i
);
9528 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9529 tcg_temp_free_i32(tmp2
);
9531 tmp
= load_reg(s
, i
);
9533 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9534 tcg_temp_free_i32(tmp
);
9537 /* no need to add after the last transfer */
9539 tcg_gen_addi_i32(addr
, addr
, 4);
9542 if (insn
& (1 << 21)) {
9544 if (insn
& (1 << 23)) {
9545 if (insn
& (1 << 24)) {
9548 /* post increment */
9549 tcg_gen_addi_i32(addr
, addr
, 4);
9552 if (insn
& (1 << 24)) {
9555 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9557 /* post decrement */
9558 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9561 store_reg(s
, rn
, addr
);
9563 tcg_temp_free_i32(addr
);
9566 store_reg(s
, rn
, loaded_var
);
9569 /* Restore CPSR from SPSR. */
9570 tmp
= load_cpu_field(spsr
);
9571 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9572 tcg_temp_free_i32(tmp
);
9573 /* Must exit loop to check un-masked IRQs */
9574 s
->base
.is_jmp
= DISAS_EXIT
;
9583 /* branch (and link) */
9584 val
= (int32_t)s
->pc
;
9585 if (insn
& (1 << 24)) {
9586 tmp
= tcg_temp_new_i32();
9587 tcg_gen_movi_i32(tmp
, val
);
9588 store_reg(s
, 14, tmp
);
9590 offset
= sextract32(insn
<< 2, 0, 26);
9598 if (((insn
>> 8) & 0xe) == 10) {
9600 if (disas_vfp_insn(s
, insn
)) {
9603 } else if (disas_coproc_insn(s
, insn
)) {
9610 gen_set_pc_im(s
, s
->pc
);
9611 s
->svc_imm
= extract32(insn
, 0, 24);
9612 s
->base
.is_jmp
= DISAS_SWI
;
9616 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9617 default_exception_el(s
));
9623 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t insn
)
9625 /* Return true if this is a 16 bit instruction. We must be precise
9626 * about this (matching the decode). We assume that s->pc still
9627 * points to the first 16 bits of the insn.
9629 if ((insn
>> 11) < 0x1d) {
9630 /* Definitely a 16-bit instruction */
9634 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9635 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9636 * end up actually treating this as two 16-bit insns, though,
9637 * if it's half of a bl/blx pair that might span a page boundary.
9639 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
9640 /* Thumb2 cores (including all M profile ones) always treat
9641 * 32-bit insns as 32-bit.
9646 if ((insn
>> 11) == 0x1e && (s
->pc
< s
->next_page_start
- 3)) {
9647 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9648 * is not on the next page; we merge this into a 32-bit
9653 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9654 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9655 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9656 * -- handle as single 16 bit insn
9661 /* Return true if this is a Thumb-2 logical op. */
9663 thumb2_logic_op(int op
)
9668 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9669 then set condition code flags based on the result of the operation.
9670 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9671 to the high bit of T1.
9672 Returns zero if the opcode is valid. */
9675 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9676 TCGv_i32 t0
, TCGv_i32 t1
)
9683 tcg_gen_and_i32(t0
, t0
, t1
);
9687 tcg_gen_andc_i32(t0
, t0
, t1
);
9691 tcg_gen_or_i32(t0
, t0
, t1
);
9695 tcg_gen_orc_i32(t0
, t0
, t1
);
9699 tcg_gen_xor_i32(t0
, t0
, t1
);
9704 gen_add_CC(t0
, t0
, t1
);
9706 tcg_gen_add_i32(t0
, t0
, t1
);
9710 gen_adc_CC(t0
, t0
, t1
);
9716 gen_sbc_CC(t0
, t0
, t1
);
9718 gen_sub_carry(t0
, t0
, t1
);
9723 gen_sub_CC(t0
, t0
, t1
);
9725 tcg_gen_sub_i32(t0
, t0
, t1
);
9729 gen_sub_CC(t0
, t1
, t0
);
9731 tcg_gen_sub_i32(t0
, t1
, t0
);
9733 default: /* 5, 6, 7, 9, 12, 15. */
9739 gen_set_CF_bit31(t1
);
9744 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9746 static int disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
9748 uint32_t imm
, shift
, offset
;
9749 uint32_t rd
, rn
, rm
, rs
;
9760 /* The only 32 bit insn that's allowed for Thumb1 is the combined
9761 * BL/BLX prefix and suffix.
9763 if ((insn
& 0xf800e800) != 0xf000e800) {
9767 rn
= (insn
>> 16) & 0xf;
9768 rs
= (insn
>> 12) & 0xf;
9769 rd
= (insn
>> 8) & 0xf;
9771 switch ((insn
>> 25) & 0xf) {
9772 case 0: case 1: case 2: case 3:
9773 /* 16-bit instructions. Should never happen. */
9776 if (insn
& (1 << 22)) {
9777 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9778 * - load/store doubleword, load/store exclusive, ldacq/strel,
9781 if (insn
& 0x01200000) {
9782 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9783 * - load/store dual (post-indexed)
9784 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9785 * - load/store dual (literal and immediate)
9786 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9787 * - load/store dual (pre-indexed)
9790 if (insn
& (1 << 21)) {
9794 addr
= tcg_temp_new_i32();
9795 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9797 addr
= load_reg(s
, rn
);
9799 offset
= (insn
& 0xff) * 4;
9800 if ((insn
& (1 << 23)) == 0)
9802 if (insn
& (1 << 24)) {
9803 tcg_gen_addi_i32(addr
, addr
, offset
);
9806 if (insn
& (1 << 20)) {
9808 tmp
= tcg_temp_new_i32();
9809 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9810 store_reg(s
, rs
, tmp
);
9811 tcg_gen_addi_i32(addr
, addr
, 4);
9812 tmp
= tcg_temp_new_i32();
9813 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9814 store_reg(s
, rd
, tmp
);
9817 tmp
= load_reg(s
, rs
);
9818 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9819 tcg_temp_free_i32(tmp
);
9820 tcg_gen_addi_i32(addr
, addr
, 4);
9821 tmp
= load_reg(s
, rd
);
9822 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9823 tcg_temp_free_i32(tmp
);
9825 if (insn
& (1 << 21)) {
9826 /* Base writeback. */
9827 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9828 store_reg(s
, rn
, addr
);
9830 tcg_temp_free_i32(addr
);
9832 } else if ((insn
& (1 << 23)) == 0) {
9833 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9834 * - load/store exclusive word
9839 addr
= tcg_temp_local_new_i32();
9840 load_reg_var(s
, addr
, rn
);
9841 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9842 if (insn
& (1 << 20)) {
9843 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9845 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9847 tcg_temp_free_i32(addr
);
9848 } else if ((insn
& (7 << 5)) == 0) {
9851 addr
= tcg_temp_new_i32();
9852 tcg_gen_movi_i32(addr
, s
->pc
);
9854 addr
= load_reg(s
, rn
);
9856 tmp
= load_reg(s
, rm
);
9857 tcg_gen_add_i32(addr
, addr
, tmp
);
9858 if (insn
& (1 << 4)) {
9860 tcg_gen_add_i32(addr
, addr
, tmp
);
9861 tcg_temp_free_i32(tmp
);
9862 tmp
= tcg_temp_new_i32();
9863 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9865 tcg_temp_free_i32(tmp
);
9866 tmp
= tcg_temp_new_i32();
9867 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9869 tcg_temp_free_i32(addr
);
9870 tcg_gen_shli_i32(tmp
, tmp
, 1);
9871 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9872 store_reg(s
, 15, tmp
);
9874 int op2
= (insn
>> 6) & 0x3;
9875 op
= (insn
>> 4) & 0x3;
9880 /* Load/store exclusive byte/halfword/doubleword */
9887 /* Load-acquire/store-release */
9893 /* Load-acquire/store-release exclusive */
9897 addr
= tcg_temp_local_new_i32();
9898 load_reg_var(s
, addr
, rn
);
9900 if (insn
& (1 << 20)) {
9901 tmp
= tcg_temp_new_i32();
9904 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
9908 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9912 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
9918 store_reg(s
, rs
, tmp
);
9920 tmp
= load_reg(s
, rs
);
9923 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
9927 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
9931 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
9937 tcg_temp_free_i32(tmp
);
9939 } else if (insn
& (1 << 20)) {
9940 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9942 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9944 tcg_temp_free_i32(addr
);
9947 /* Load/store multiple, RFE, SRS. */
9948 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9949 /* RFE, SRS: not available in user mode or on M profile */
9950 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9953 if (insn
& (1 << 20)) {
9955 addr
= load_reg(s
, rn
);
9956 if ((insn
& (1 << 24)) == 0)
9957 tcg_gen_addi_i32(addr
, addr
, -8);
9958 /* Load PC into tmp and CPSR into tmp2. */
9959 tmp
= tcg_temp_new_i32();
9960 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9961 tcg_gen_addi_i32(addr
, addr
, 4);
9962 tmp2
= tcg_temp_new_i32();
9963 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9964 if (insn
& (1 << 21)) {
9965 /* Base writeback. */
9966 if (insn
& (1 << 24)) {
9967 tcg_gen_addi_i32(addr
, addr
, 4);
9969 tcg_gen_addi_i32(addr
, addr
, -4);
9971 store_reg(s
, rn
, addr
);
9973 tcg_temp_free_i32(addr
);
9975 gen_rfe(s
, tmp
, tmp2
);
9978 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9982 int i
, loaded_base
= 0;
9983 TCGv_i32 loaded_var
;
9984 /* Load/store multiple. */
9985 addr
= load_reg(s
, rn
);
9987 for (i
= 0; i
< 16; i
++) {
9988 if (insn
& (1 << i
))
9991 if (insn
& (1 << 24)) {
9992 tcg_gen_addi_i32(addr
, addr
, -offset
);
9995 TCGV_UNUSED_I32(loaded_var
);
9996 for (i
= 0; i
< 16; i
++) {
9997 if ((insn
& (1 << i
)) == 0)
9999 if (insn
& (1 << 20)) {
10001 tmp
= tcg_temp_new_i32();
10002 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10004 gen_bx_excret(s
, tmp
);
10005 } else if (i
== rn
) {
10009 store_reg(s
, i
, tmp
);
10013 tmp
= load_reg(s
, i
);
10014 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10015 tcg_temp_free_i32(tmp
);
10017 tcg_gen_addi_i32(addr
, addr
, 4);
10020 store_reg(s
, rn
, loaded_var
);
10022 if (insn
& (1 << 21)) {
10023 /* Base register writeback. */
10024 if (insn
& (1 << 24)) {
10025 tcg_gen_addi_i32(addr
, addr
, -offset
);
10027 /* Fault if writeback register is in register list. */
10028 if (insn
& (1 << rn
))
10030 store_reg(s
, rn
, addr
);
10032 tcg_temp_free_i32(addr
);
10039 op
= (insn
>> 21) & 0xf;
10041 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10044 /* Halfword pack. */
10045 tmp
= load_reg(s
, rn
);
10046 tmp2
= load_reg(s
, rm
);
10047 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
10048 if (insn
& (1 << 5)) {
10052 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
10053 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
10054 tcg_gen_ext16u_i32(tmp2
, tmp2
);
10058 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10059 tcg_gen_ext16u_i32(tmp
, tmp
);
10060 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10062 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10063 tcg_temp_free_i32(tmp2
);
10064 store_reg(s
, rd
, tmp
);
10066 /* Data processing register constant shift. */
10068 tmp
= tcg_temp_new_i32();
10069 tcg_gen_movi_i32(tmp
, 0);
10071 tmp
= load_reg(s
, rn
);
10073 tmp2
= load_reg(s
, rm
);
10075 shiftop
= (insn
>> 4) & 3;
10076 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10077 conds
= (insn
& (1 << 20)) != 0;
10078 logic_cc
= (conds
&& thumb2_logic_op(op
));
10079 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10080 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10082 tcg_temp_free_i32(tmp2
);
10084 store_reg(s
, rd
, tmp
);
10086 tcg_temp_free_i32(tmp
);
10090 case 13: /* Misc data processing. */
10091 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10092 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10095 case 0: /* Register controlled shift. */
10096 tmp
= load_reg(s
, rn
);
10097 tmp2
= load_reg(s
, rm
);
10098 if ((insn
& 0x70) != 0)
10100 op
= (insn
>> 21) & 3;
10101 logic_cc
= (insn
& (1 << 20)) != 0;
10102 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10105 store_reg(s
, rd
, tmp
);
10107 case 1: /* Sign/zero extend. */
10108 op
= (insn
>> 20) & 7;
10110 case 0: /* SXTAH, SXTH */
10111 case 1: /* UXTAH, UXTH */
10112 case 4: /* SXTAB, SXTB */
10113 case 5: /* UXTAB, UXTB */
10115 case 2: /* SXTAB16, SXTB16 */
10116 case 3: /* UXTAB16, UXTB16 */
10117 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10125 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10129 tmp
= load_reg(s
, rm
);
10130 shift
= (insn
>> 4) & 3;
10131 /* ??? In many cases it's not necessary to do a
10132 rotate, a shift is sufficient. */
10134 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10135 op
= (insn
>> 20) & 7;
10137 case 0: gen_sxth(tmp
); break;
10138 case 1: gen_uxth(tmp
); break;
10139 case 2: gen_sxtb16(tmp
); break;
10140 case 3: gen_uxtb16(tmp
); break;
10141 case 4: gen_sxtb(tmp
); break;
10142 case 5: gen_uxtb(tmp
); break;
10144 g_assert_not_reached();
10147 tmp2
= load_reg(s
, rn
);
10148 if ((op
>> 1) == 1) {
10149 gen_add16(tmp
, tmp2
);
10151 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10152 tcg_temp_free_i32(tmp2
);
10155 store_reg(s
, rd
, tmp
);
10157 case 2: /* SIMD add/subtract. */
10158 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10161 op
= (insn
>> 20) & 7;
10162 shift
= (insn
>> 4) & 7;
10163 if ((op
& 3) == 3 || (shift
& 3) == 3)
10165 tmp
= load_reg(s
, rn
);
10166 tmp2
= load_reg(s
, rm
);
10167 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10168 tcg_temp_free_i32(tmp2
);
10169 store_reg(s
, rd
, tmp
);
10171 case 3: /* Other data processing. */
10172 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10174 /* Saturating add/subtract. */
10175 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10178 tmp
= load_reg(s
, rn
);
10179 tmp2
= load_reg(s
, rm
);
10181 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10183 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10185 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10186 tcg_temp_free_i32(tmp2
);
10189 case 0x0a: /* rbit */
10190 case 0x08: /* rev */
10191 case 0x09: /* rev16 */
10192 case 0x0b: /* revsh */
10193 case 0x18: /* clz */
10195 case 0x10: /* sel */
10196 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10200 case 0x20: /* crc32/crc32c */
10206 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10213 tmp
= load_reg(s
, rn
);
10215 case 0x0a: /* rbit */
10216 gen_helper_rbit(tmp
, tmp
);
10218 case 0x08: /* rev */
10219 tcg_gen_bswap32_i32(tmp
, tmp
);
10221 case 0x09: /* rev16 */
10224 case 0x0b: /* revsh */
10227 case 0x10: /* sel */
10228 tmp2
= load_reg(s
, rm
);
10229 tmp3
= tcg_temp_new_i32();
10230 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10231 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10232 tcg_temp_free_i32(tmp3
);
10233 tcg_temp_free_i32(tmp2
);
10235 case 0x18: /* clz */
10236 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10246 uint32_t sz
= op
& 0x3;
10247 uint32_t c
= op
& 0x8;
10249 tmp2
= load_reg(s
, rm
);
10251 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10252 } else if (sz
== 1) {
10253 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10255 tmp3
= tcg_const_i32(1 << sz
);
10257 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10259 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10261 tcg_temp_free_i32(tmp2
);
10262 tcg_temp_free_i32(tmp3
);
10266 g_assert_not_reached();
10269 store_reg(s
, rd
, tmp
);
10271 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10272 switch ((insn
>> 20) & 7) {
10273 case 0: /* 32 x 32 -> 32 */
10274 case 7: /* Unsigned sum of absolute differences. */
10276 case 1: /* 16 x 16 -> 32 */
10277 case 2: /* Dual multiply add. */
10278 case 3: /* 32 * 16 -> 32msb */
10279 case 4: /* Dual multiply subtract. */
10280 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10281 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10286 op
= (insn
>> 4) & 0xf;
10287 tmp
= load_reg(s
, rn
);
10288 tmp2
= load_reg(s
, rm
);
10289 switch ((insn
>> 20) & 7) {
10290 case 0: /* 32 x 32 -> 32 */
10291 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10292 tcg_temp_free_i32(tmp2
);
10294 tmp2
= load_reg(s
, rs
);
10296 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10298 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10299 tcg_temp_free_i32(tmp2
);
10302 case 1: /* 16 x 16 -> 32 */
10303 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10304 tcg_temp_free_i32(tmp2
);
10306 tmp2
= load_reg(s
, rs
);
10307 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10308 tcg_temp_free_i32(tmp2
);
10311 case 2: /* Dual multiply add. */
10312 case 4: /* Dual multiply subtract. */
10314 gen_swap_half(tmp2
);
10315 gen_smul_dual(tmp
, tmp2
);
10316 if (insn
& (1 << 22)) {
10317 /* This subtraction cannot overflow. */
10318 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10320 /* This addition cannot overflow 32 bits;
10321 * however it may overflow considered as a signed
10322 * operation, in which case we must set the Q flag.
10324 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10326 tcg_temp_free_i32(tmp2
);
10329 tmp2
= load_reg(s
, rs
);
10330 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10331 tcg_temp_free_i32(tmp2
);
10334 case 3: /* 32 * 16 -> 32msb */
10336 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10339 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10340 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10341 tmp
= tcg_temp_new_i32();
10342 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10343 tcg_temp_free_i64(tmp64
);
10346 tmp2
= load_reg(s
, rs
);
10347 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10348 tcg_temp_free_i32(tmp2
);
10351 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10352 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10354 tmp
= load_reg(s
, rs
);
10355 if (insn
& (1 << 20)) {
10356 tmp64
= gen_addq_msw(tmp64
, tmp
);
10358 tmp64
= gen_subq_msw(tmp64
, tmp
);
10361 if (insn
& (1 << 4)) {
10362 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10364 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10365 tmp
= tcg_temp_new_i32();
10366 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10367 tcg_temp_free_i64(tmp64
);
10369 case 7: /* Unsigned sum of absolute differences. */
10370 gen_helper_usad8(tmp
, tmp
, tmp2
);
10371 tcg_temp_free_i32(tmp2
);
10373 tmp2
= load_reg(s
, rs
);
10374 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10375 tcg_temp_free_i32(tmp2
);
10379 store_reg(s
, rd
, tmp
);
10381 case 6: case 7: /* 64-bit multiply, Divide. */
10382 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10383 tmp
= load_reg(s
, rn
);
10384 tmp2
= load_reg(s
, rm
);
10385 if ((op
& 0x50) == 0x10) {
10387 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10391 gen_helper_udiv(tmp
, tmp
, tmp2
);
10393 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10394 tcg_temp_free_i32(tmp2
);
10395 store_reg(s
, rd
, tmp
);
10396 } else if ((op
& 0xe) == 0xc) {
10397 /* Dual multiply accumulate long. */
10398 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10399 tcg_temp_free_i32(tmp
);
10400 tcg_temp_free_i32(tmp2
);
10404 gen_swap_half(tmp2
);
10405 gen_smul_dual(tmp
, tmp2
);
10407 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10409 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10411 tcg_temp_free_i32(tmp2
);
10413 tmp64
= tcg_temp_new_i64();
10414 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10415 tcg_temp_free_i32(tmp
);
10416 gen_addq(s
, tmp64
, rs
, rd
);
10417 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10418 tcg_temp_free_i64(tmp64
);
10421 /* Unsigned 64-bit multiply */
10422 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10426 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10427 tcg_temp_free_i32(tmp2
);
10428 tcg_temp_free_i32(tmp
);
10431 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10432 tcg_temp_free_i32(tmp2
);
10433 tmp64
= tcg_temp_new_i64();
10434 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10435 tcg_temp_free_i32(tmp
);
10437 /* Signed 64-bit multiply */
10438 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10443 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10444 tcg_temp_free_i64(tmp64
);
10447 gen_addq_lo(s
, tmp64
, rs
);
10448 gen_addq_lo(s
, tmp64
, rd
);
10449 } else if (op
& 0x40) {
10450 /* 64-bit accumulate. */
10451 gen_addq(s
, tmp64
, rs
, rd
);
10453 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10454 tcg_temp_free_i64(tmp64
);
10459 case 6: case 7: case 14: case 15:
10461 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10462 /* We don't currently implement M profile FP support,
10463 * so this entire space should give a NOCP fault.
10465 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10466 default_exception_el(s
));
10469 if (((insn
>> 24) & 3) == 3) {
10470 /* Translate into the equivalent ARM encoding. */
10471 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10472 if (disas_neon_data_insn(s
, insn
)) {
10475 } else if (((insn
>> 8) & 0xe) == 10) {
10476 if (disas_vfp_insn(s
, insn
)) {
10480 if (insn
& (1 << 28))
10482 if (disas_coproc_insn(s
, insn
)) {
10487 case 8: case 9: case 10: case 11:
10488 if (insn
& (1 << 15)) {
10489 /* Branches, misc control. */
10490 if (insn
& 0x5000) {
10491 /* Unconditional branch. */
10492 /* signextend(hw1[10:0]) -> offset[:12]. */
10493 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10494 /* hw1[10:0] -> offset[11:1]. */
10495 offset
|= (insn
& 0x7ff) << 1;
10496 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10497 offset[24:22] already have the same value because of the
10498 sign extension above. */
10499 offset
^= ((~insn
) & (1 << 13)) << 10;
10500 offset
^= ((~insn
) & (1 << 11)) << 11;
10502 if (insn
& (1 << 14)) {
10503 /* Branch and link. */
10504 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10508 if (insn
& (1 << 12)) {
10510 gen_jmp(s
, offset
);
10513 offset
&= ~(uint32_t)2;
10514 /* thumb2 bx, no need to check */
10515 gen_bx_im(s
, offset
);
10517 } else if (((insn
>> 23) & 7) == 7) {
10519 if (insn
& (1 << 13))
10522 if (insn
& (1 << 26)) {
10523 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10526 if (!(insn
& (1 << 20))) {
10527 /* Hypervisor call (v7) */
10528 int imm16
= extract32(insn
, 16, 4) << 12
10529 | extract32(insn
, 0, 12);
10536 /* Secure monitor call (v6+) */
10544 op
= (insn
>> 20) & 7;
10546 case 0: /* msr cpsr. */
10547 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10548 tmp
= load_reg(s
, rn
);
10549 /* the constant is the mask and SYSm fields */
10550 addr
= tcg_const_i32(insn
& 0xfff);
10551 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10552 tcg_temp_free_i32(addr
);
10553 tcg_temp_free_i32(tmp
);
10558 case 1: /* msr spsr. */
10559 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10563 if (extract32(insn
, 5, 1)) {
10565 int sysm
= extract32(insn
, 8, 4) |
10566 (extract32(insn
, 4, 1) << 4);
10569 gen_msr_banked(s
, r
, sysm
, rm
);
10573 /* MSR (for PSRs) */
10574 tmp
= load_reg(s
, rn
);
10576 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10580 case 2: /* cps, nop-hint. */
10581 if (((insn
>> 8) & 7) == 0) {
10582 gen_nop_hint(s
, insn
& 0xff);
10584 /* Implemented as NOP in user mode. */
10589 if (insn
& (1 << 10)) {
10590 if (insn
& (1 << 7))
10592 if (insn
& (1 << 6))
10594 if (insn
& (1 << 5))
10596 if (insn
& (1 << 9))
10597 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10599 if (insn
& (1 << 8)) {
10601 imm
|= (insn
& 0x1f);
10604 gen_set_psr_im(s
, offset
, 0, imm
);
10607 case 3: /* Special control operations. */
10609 op
= (insn
>> 4) & 0xf;
10611 case 2: /* clrex */
10616 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10619 /* We need to break the TB after this insn
10620 * to execute self-modifying code correctly
10621 * and also to take any pending interrupts
10624 gen_goto_tb(s
, 0, s
->pc
& ~1);
10631 /* Trivial implementation equivalent to bx.
10632 * This instruction doesn't exist at all for M-profile.
10634 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10637 tmp
= load_reg(s
, rn
);
10640 case 5: /* Exception return. */
10644 if (rn
!= 14 || rd
!= 15) {
10647 tmp
= load_reg(s
, rn
);
10648 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10649 gen_exception_return(s
, tmp
);
10652 if (extract32(insn
, 5, 1) &&
10653 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10655 int sysm
= extract32(insn
, 16, 4) |
10656 (extract32(insn
, 4, 1) << 4);
10658 gen_mrs_banked(s
, 0, sysm
, rd
);
10662 if (extract32(insn
, 16, 4) != 0xf) {
10665 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10666 extract32(insn
, 0, 8) != 0) {
10671 tmp
= tcg_temp_new_i32();
10672 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10673 addr
= tcg_const_i32(insn
& 0xff);
10674 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10675 tcg_temp_free_i32(addr
);
10677 gen_helper_cpsr_read(tmp
, cpu_env
);
10679 store_reg(s
, rd
, tmp
);
10682 if (extract32(insn
, 5, 1) &&
10683 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10685 int sysm
= extract32(insn
, 16, 4) |
10686 (extract32(insn
, 4, 1) << 4);
10688 gen_mrs_banked(s
, 1, sysm
, rd
);
10693 /* Not accessible in user mode. */
10694 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10698 if (extract32(insn
, 16, 4) != 0xf ||
10699 extract32(insn
, 0, 8) != 0) {
10703 tmp
= load_cpu_field(spsr
);
10704 store_reg(s
, rd
, tmp
);
10709 /* Conditional branch. */
10710 op
= (insn
>> 22) & 0xf;
10711 /* Generate a conditional jump to next instruction. */
10712 s
->condlabel
= gen_new_label();
10713 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10716 /* offset[11:1] = insn[10:0] */
10717 offset
= (insn
& 0x7ff) << 1;
10718 /* offset[17:12] = insn[21:16]. */
10719 offset
|= (insn
& 0x003f0000) >> 4;
10720 /* offset[31:20] = insn[26]. */
10721 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10722 /* offset[18] = insn[13]. */
10723 offset
|= (insn
& (1 << 13)) << 5;
10724 /* offset[19] = insn[11]. */
10725 offset
|= (insn
& (1 << 11)) << 8;
10727 /* jump to the offset */
10728 gen_jmp(s
, s
->pc
+ offset
);
10731 /* Data processing immediate. */
10732 if (insn
& (1 << 25)) {
10733 if (insn
& (1 << 24)) {
10734 if (insn
& (1 << 20))
10736 /* Bitfield/Saturate. */
10737 op
= (insn
>> 21) & 7;
10739 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10741 tmp
= tcg_temp_new_i32();
10742 tcg_gen_movi_i32(tmp
, 0);
10744 tmp
= load_reg(s
, rn
);
10747 case 2: /* Signed bitfield extract. */
10749 if (shift
+ imm
> 32)
10752 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
10755 case 6: /* Unsigned bitfield extract. */
10757 if (shift
+ imm
> 32)
10760 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
10763 case 3: /* Bitfield insert/clear. */
10766 imm
= imm
+ 1 - shift
;
10768 tmp2
= load_reg(s
, rd
);
10769 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10770 tcg_temp_free_i32(tmp2
);
10775 default: /* Saturate. */
10778 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10780 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10782 tmp2
= tcg_const_i32(imm
);
10785 if ((op
& 1) && shift
== 0) {
10786 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10787 tcg_temp_free_i32(tmp
);
10788 tcg_temp_free_i32(tmp2
);
10791 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10793 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10797 if ((op
& 1) && shift
== 0) {
10798 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10799 tcg_temp_free_i32(tmp
);
10800 tcg_temp_free_i32(tmp2
);
10803 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10805 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10808 tcg_temp_free_i32(tmp2
);
10811 store_reg(s
, rd
, tmp
);
10813 imm
= ((insn
& 0x04000000) >> 15)
10814 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10815 if (insn
& (1 << 22)) {
10816 /* 16-bit immediate. */
10817 imm
|= (insn
>> 4) & 0xf000;
10818 if (insn
& (1 << 23)) {
10820 tmp
= load_reg(s
, rd
);
10821 tcg_gen_ext16u_i32(tmp
, tmp
);
10822 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10825 tmp
= tcg_temp_new_i32();
10826 tcg_gen_movi_i32(tmp
, imm
);
10829 /* Add/sub 12-bit immediate. */
10831 offset
= s
->pc
& ~(uint32_t)3;
10832 if (insn
& (1 << 23))
10836 tmp
= tcg_temp_new_i32();
10837 tcg_gen_movi_i32(tmp
, offset
);
10839 tmp
= load_reg(s
, rn
);
10840 if (insn
& (1 << 23))
10841 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10843 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10846 store_reg(s
, rd
, tmp
);
10849 int shifter_out
= 0;
10850 /* modified 12-bit immediate. */
10851 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10852 imm
= (insn
& 0xff);
10855 /* Nothing to do. */
10857 case 1: /* 00XY00XY */
10860 case 2: /* XY00XY00 */
10864 case 3: /* XYXYXYXY */
10868 default: /* Rotated constant. */
10869 shift
= (shift
<< 1) | (imm
>> 7);
10871 imm
= imm
<< (32 - shift
);
10875 tmp2
= tcg_temp_new_i32();
10876 tcg_gen_movi_i32(tmp2
, imm
);
10877 rn
= (insn
>> 16) & 0xf;
10879 tmp
= tcg_temp_new_i32();
10880 tcg_gen_movi_i32(tmp
, 0);
10882 tmp
= load_reg(s
, rn
);
10884 op
= (insn
>> 21) & 0xf;
10885 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10886 shifter_out
, tmp
, tmp2
))
10888 tcg_temp_free_i32(tmp2
);
10889 rd
= (insn
>> 8) & 0xf;
10891 store_reg(s
, rd
, tmp
);
10893 tcg_temp_free_i32(tmp
);
10898 case 12: /* Load/store single data item. */
10905 if ((insn
& 0x01100000) == 0x01000000) {
10906 if (disas_neon_ls_insn(s
, insn
)) {
10911 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10913 if (!(insn
& (1 << 20))) {
10917 /* Byte or halfword load space with dest == r15 : memory hints.
10918 * Catch them early so we don't emit pointless addressing code.
10919 * This space is a mix of:
10920 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10921 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10923 * unallocated hints, which must be treated as NOPs
10924 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10925 * which is easiest for the decoding logic
10926 * Some space which must UNDEF
10928 int op1
= (insn
>> 23) & 3;
10929 int op2
= (insn
>> 6) & 0x3f;
10934 /* UNPREDICTABLE, unallocated hint or
10935 * PLD/PLDW/PLI (literal)
10940 return 0; /* PLD/PLDW/PLI or unallocated hint */
10942 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10943 return 0; /* PLD/PLDW/PLI or unallocated hint */
10945 /* UNDEF space, or an UNPREDICTABLE */
10949 memidx
= get_mem_index(s
);
10951 addr
= tcg_temp_new_i32();
10953 /* s->pc has already been incremented by 4. */
10954 imm
= s
->pc
& 0xfffffffc;
10955 if (insn
& (1 << 23))
10956 imm
+= insn
& 0xfff;
10958 imm
-= insn
& 0xfff;
10959 tcg_gen_movi_i32(addr
, imm
);
10961 addr
= load_reg(s
, rn
);
10962 if (insn
& (1 << 23)) {
10963 /* Positive offset. */
10964 imm
= insn
& 0xfff;
10965 tcg_gen_addi_i32(addr
, addr
, imm
);
10968 switch ((insn
>> 8) & 0xf) {
10969 case 0x0: /* Shifted Register. */
10970 shift
= (insn
>> 4) & 0xf;
10972 tcg_temp_free_i32(addr
);
10975 tmp
= load_reg(s
, rm
);
10977 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10978 tcg_gen_add_i32(addr
, addr
, tmp
);
10979 tcg_temp_free_i32(tmp
);
10981 case 0xc: /* Negative offset. */
10982 tcg_gen_addi_i32(addr
, addr
, -imm
);
10984 case 0xe: /* User privilege. */
10985 tcg_gen_addi_i32(addr
, addr
, imm
);
10986 memidx
= get_a32_user_mem_index(s
);
10988 case 0x9: /* Post-decrement. */
10990 /* Fall through. */
10991 case 0xb: /* Post-increment. */
10995 case 0xd: /* Pre-decrement. */
10997 /* Fall through. */
10998 case 0xf: /* Pre-increment. */
10999 tcg_gen_addi_i32(addr
, addr
, imm
);
11003 tcg_temp_free_i32(addr
);
11009 issinfo
= writeback
? ISSInvalid
: rs
;
11011 if (insn
& (1 << 20)) {
11013 tmp
= tcg_temp_new_i32();
11016 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11019 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11022 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11025 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11028 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11031 tcg_temp_free_i32(tmp
);
11032 tcg_temp_free_i32(addr
);
11036 gen_bx_excret(s
, tmp
);
11038 store_reg(s
, rs
, tmp
);
11042 tmp
= load_reg(s
, rs
);
11045 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
11048 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
11051 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
11054 tcg_temp_free_i32(tmp
);
11055 tcg_temp_free_i32(addr
);
11058 tcg_temp_free_i32(tmp
);
11061 tcg_gen_addi_i32(addr
, addr
, imm
);
11063 store_reg(s
, rn
, addr
);
11065 tcg_temp_free_i32(addr
);
11077 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
11079 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
11086 switch (insn
>> 12) {
11090 op
= (insn
>> 11) & 3;
11093 rn
= (insn
>> 3) & 7;
11094 tmp
= load_reg(s
, rn
);
11095 if (insn
& (1 << 10)) {
11097 tmp2
= tcg_temp_new_i32();
11098 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11101 rm
= (insn
>> 6) & 7;
11102 tmp2
= load_reg(s
, rm
);
11104 if (insn
& (1 << 9)) {
11105 if (s
->condexec_mask
)
11106 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11108 gen_sub_CC(tmp
, tmp
, tmp2
);
11110 if (s
->condexec_mask
)
11111 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11113 gen_add_CC(tmp
, tmp
, tmp2
);
11115 tcg_temp_free_i32(tmp2
);
11116 store_reg(s
, rd
, tmp
);
11118 /* shift immediate */
11119 rm
= (insn
>> 3) & 7;
11120 shift
= (insn
>> 6) & 0x1f;
11121 tmp
= load_reg(s
, rm
);
11122 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11123 if (!s
->condexec_mask
)
11125 store_reg(s
, rd
, tmp
);
11129 /* arithmetic large immediate */
11130 op
= (insn
>> 11) & 3;
11131 rd
= (insn
>> 8) & 0x7;
11132 if (op
== 0) { /* mov */
11133 tmp
= tcg_temp_new_i32();
11134 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11135 if (!s
->condexec_mask
)
11137 store_reg(s
, rd
, tmp
);
11139 tmp
= load_reg(s
, rd
);
11140 tmp2
= tcg_temp_new_i32();
11141 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11144 gen_sub_CC(tmp
, tmp
, tmp2
);
11145 tcg_temp_free_i32(tmp
);
11146 tcg_temp_free_i32(tmp2
);
11149 if (s
->condexec_mask
)
11150 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11152 gen_add_CC(tmp
, tmp
, tmp2
);
11153 tcg_temp_free_i32(tmp2
);
11154 store_reg(s
, rd
, tmp
);
11157 if (s
->condexec_mask
)
11158 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11160 gen_sub_CC(tmp
, tmp
, tmp2
);
11161 tcg_temp_free_i32(tmp2
);
11162 store_reg(s
, rd
, tmp
);
11168 if (insn
& (1 << 11)) {
11169 rd
= (insn
>> 8) & 7;
11170 /* load pc-relative. Bit 1 of PC is ignored. */
11171 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11172 val
&= ~(uint32_t)2;
11173 addr
= tcg_temp_new_i32();
11174 tcg_gen_movi_i32(addr
, val
);
11175 tmp
= tcg_temp_new_i32();
11176 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11178 tcg_temp_free_i32(addr
);
11179 store_reg(s
, rd
, tmp
);
11182 if (insn
& (1 << 10)) {
11183 /* 0b0100_01xx_xxxx_xxxx
11184 * - data processing extended, branch and exchange
11186 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11187 rm
= (insn
>> 3) & 0xf;
11188 op
= (insn
>> 8) & 3;
11191 tmp
= load_reg(s
, rd
);
11192 tmp2
= load_reg(s
, rm
);
11193 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11194 tcg_temp_free_i32(tmp2
);
11195 store_reg(s
, rd
, tmp
);
11198 tmp
= load_reg(s
, rd
);
11199 tmp2
= load_reg(s
, rm
);
11200 gen_sub_CC(tmp
, tmp
, tmp2
);
11201 tcg_temp_free_i32(tmp2
);
11202 tcg_temp_free_i32(tmp
);
11204 case 2: /* mov/cpy */
11205 tmp
= load_reg(s
, rm
);
11206 store_reg(s
, rd
, tmp
);
11210 /* 0b0100_0111_xxxx_xxxx
11211 * - branch [and link] exchange thumb register
11213 bool link
= insn
& (1 << 7);
11222 /* BXNS/BLXNS: only exists for v8M with the
11223 * security extensions, and always UNDEF if NonSecure.
11224 * We don't implement these in the user-only mode
11225 * either (in theory you can use them from Secure User
11226 * mode but they are too tied in to system emulation.)
11228 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
11239 tmp
= load_reg(s
, rm
);
11241 val
= (uint32_t)s
->pc
| 1;
11242 tmp2
= tcg_temp_new_i32();
11243 tcg_gen_movi_i32(tmp2
, val
);
11244 store_reg(s
, 14, tmp2
);
11247 /* Only BX works as exception-return, not BLX */
11248 gen_bx_excret(s
, tmp
);
11256 /* data processing register */
11258 rm
= (insn
>> 3) & 7;
11259 op
= (insn
>> 6) & 0xf;
11260 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11261 /* the shift/rotate ops want the operands backwards */
11270 if (op
== 9) { /* neg */
11271 tmp
= tcg_temp_new_i32();
11272 tcg_gen_movi_i32(tmp
, 0);
11273 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11274 tmp
= load_reg(s
, rd
);
11276 TCGV_UNUSED_I32(tmp
);
11279 tmp2
= load_reg(s
, rm
);
11281 case 0x0: /* and */
11282 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11283 if (!s
->condexec_mask
)
11286 case 0x1: /* eor */
11287 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11288 if (!s
->condexec_mask
)
11291 case 0x2: /* lsl */
11292 if (s
->condexec_mask
) {
11293 gen_shl(tmp2
, tmp2
, tmp
);
11295 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11296 gen_logic_CC(tmp2
);
11299 case 0x3: /* lsr */
11300 if (s
->condexec_mask
) {
11301 gen_shr(tmp2
, tmp2
, tmp
);
11303 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11304 gen_logic_CC(tmp2
);
11307 case 0x4: /* asr */
11308 if (s
->condexec_mask
) {
11309 gen_sar(tmp2
, tmp2
, tmp
);
11311 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11312 gen_logic_CC(tmp2
);
11315 case 0x5: /* adc */
11316 if (s
->condexec_mask
) {
11317 gen_adc(tmp
, tmp2
);
11319 gen_adc_CC(tmp
, tmp
, tmp2
);
11322 case 0x6: /* sbc */
11323 if (s
->condexec_mask
) {
11324 gen_sub_carry(tmp
, tmp
, tmp2
);
11326 gen_sbc_CC(tmp
, tmp
, tmp2
);
11329 case 0x7: /* ror */
11330 if (s
->condexec_mask
) {
11331 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11332 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11334 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11335 gen_logic_CC(tmp2
);
11338 case 0x8: /* tst */
11339 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11343 case 0x9: /* neg */
11344 if (s
->condexec_mask
)
11345 tcg_gen_neg_i32(tmp
, tmp2
);
11347 gen_sub_CC(tmp
, tmp
, tmp2
);
11349 case 0xa: /* cmp */
11350 gen_sub_CC(tmp
, tmp
, tmp2
);
11353 case 0xb: /* cmn */
11354 gen_add_CC(tmp
, tmp
, tmp2
);
11357 case 0xc: /* orr */
11358 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11359 if (!s
->condexec_mask
)
11362 case 0xd: /* mul */
11363 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11364 if (!s
->condexec_mask
)
11367 case 0xe: /* bic */
11368 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11369 if (!s
->condexec_mask
)
11372 case 0xf: /* mvn */
11373 tcg_gen_not_i32(tmp2
, tmp2
);
11374 if (!s
->condexec_mask
)
11375 gen_logic_CC(tmp2
);
11382 store_reg(s
, rm
, tmp2
);
11384 tcg_temp_free_i32(tmp
);
11386 store_reg(s
, rd
, tmp
);
11387 tcg_temp_free_i32(tmp2
);
11390 tcg_temp_free_i32(tmp
);
11391 tcg_temp_free_i32(tmp2
);
11396 /* load/store register offset. */
11398 rn
= (insn
>> 3) & 7;
11399 rm
= (insn
>> 6) & 7;
11400 op
= (insn
>> 9) & 7;
11401 addr
= load_reg(s
, rn
);
11402 tmp
= load_reg(s
, rm
);
11403 tcg_gen_add_i32(addr
, addr
, tmp
);
11404 tcg_temp_free_i32(tmp
);
11406 if (op
< 3) { /* store */
11407 tmp
= load_reg(s
, rd
);
11409 tmp
= tcg_temp_new_i32();
11414 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11417 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11420 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11422 case 3: /* ldrsb */
11423 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11426 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11429 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11432 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11434 case 7: /* ldrsh */
11435 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11438 if (op
>= 3) { /* load */
11439 store_reg(s
, rd
, tmp
);
11441 tcg_temp_free_i32(tmp
);
11443 tcg_temp_free_i32(addr
);
11447 /* load/store word immediate offset */
11449 rn
= (insn
>> 3) & 7;
11450 addr
= load_reg(s
, rn
);
11451 val
= (insn
>> 4) & 0x7c;
11452 tcg_gen_addi_i32(addr
, addr
, val
);
11454 if (insn
& (1 << 11)) {
11456 tmp
= tcg_temp_new_i32();
11457 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11458 store_reg(s
, rd
, tmp
);
11461 tmp
= load_reg(s
, rd
);
11462 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11463 tcg_temp_free_i32(tmp
);
11465 tcg_temp_free_i32(addr
);
11469 /* load/store byte immediate offset */
11471 rn
= (insn
>> 3) & 7;
11472 addr
= load_reg(s
, rn
);
11473 val
= (insn
>> 6) & 0x1f;
11474 tcg_gen_addi_i32(addr
, addr
, val
);
11476 if (insn
& (1 << 11)) {
11478 tmp
= tcg_temp_new_i32();
11479 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11480 store_reg(s
, rd
, tmp
);
11483 tmp
= load_reg(s
, rd
);
11484 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11485 tcg_temp_free_i32(tmp
);
11487 tcg_temp_free_i32(addr
);
11491 /* load/store halfword immediate offset */
11493 rn
= (insn
>> 3) & 7;
11494 addr
= load_reg(s
, rn
);
11495 val
= (insn
>> 5) & 0x3e;
11496 tcg_gen_addi_i32(addr
, addr
, val
);
11498 if (insn
& (1 << 11)) {
11500 tmp
= tcg_temp_new_i32();
11501 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11502 store_reg(s
, rd
, tmp
);
11505 tmp
= load_reg(s
, rd
);
11506 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11507 tcg_temp_free_i32(tmp
);
11509 tcg_temp_free_i32(addr
);
11513 /* load/store from stack */
11514 rd
= (insn
>> 8) & 7;
11515 addr
= load_reg(s
, 13);
11516 val
= (insn
& 0xff) * 4;
11517 tcg_gen_addi_i32(addr
, addr
, val
);
11519 if (insn
& (1 << 11)) {
11521 tmp
= tcg_temp_new_i32();
11522 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11523 store_reg(s
, rd
, tmp
);
11526 tmp
= load_reg(s
, rd
);
11527 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11528 tcg_temp_free_i32(tmp
);
11530 tcg_temp_free_i32(addr
);
11534 /* add to high reg */
11535 rd
= (insn
>> 8) & 7;
11536 if (insn
& (1 << 11)) {
11538 tmp
= load_reg(s
, 13);
11540 /* PC. bit 1 is ignored. */
11541 tmp
= tcg_temp_new_i32();
11542 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11544 val
= (insn
& 0xff) * 4;
11545 tcg_gen_addi_i32(tmp
, tmp
, val
);
11546 store_reg(s
, rd
, tmp
);
11551 op
= (insn
>> 8) & 0xf;
11554 /* adjust stack pointer */
11555 tmp
= load_reg(s
, 13);
11556 val
= (insn
& 0x7f) * 4;
11557 if (insn
& (1 << 7))
11558 val
= -(int32_t)val
;
11559 tcg_gen_addi_i32(tmp
, tmp
, val
);
11560 store_reg(s
, 13, tmp
);
11563 case 2: /* sign/zero extend. */
11566 rm
= (insn
>> 3) & 7;
11567 tmp
= load_reg(s
, rm
);
11568 switch ((insn
>> 6) & 3) {
11569 case 0: gen_sxth(tmp
); break;
11570 case 1: gen_sxtb(tmp
); break;
11571 case 2: gen_uxth(tmp
); break;
11572 case 3: gen_uxtb(tmp
); break;
11574 store_reg(s
, rd
, tmp
);
11576 case 4: case 5: case 0xc: case 0xd:
11578 addr
= load_reg(s
, 13);
11579 if (insn
& (1 << 8))
11583 for (i
= 0; i
< 8; i
++) {
11584 if (insn
& (1 << i
))
11587 if ((insn
& (1 << 11)) == 0) {
11588 tcg_gen_addi_i32(addr
, addr
, -offset
);
11590 for (i
= 0; i
< 8; i
++) {
11591 if (insn
& (1 << i
)) {
11592 if (insn
& (1 << 11)) {
11594 tmp
= tcg_temp_new_i32();
11595 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11596 store_reg(s
, i
, tmp
);
11599 tmp
= load_reg(s
, i
);
11600 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11601 tcg_temp_free_i32(tmp
);
11603 /* advance to the next address. */
11604 tcg_gen_addi_i32(addr
, addr
, 4);
11607 TCGV_UNUSED_I32(tmp
);
11608 if (insn
& (1 << 8)) {
11609 if (insn
& (1 << 11)) {
11611 tmp
= tcg_temp_new_i32();
11612 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11613 /* don't set the pc until the rest of the instruction
11617 tmp
= load_reg(s
, 14);
11618 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11619 tcg_temp_free_i32(tmp
);
11621 tcg_gen_addi_i32(addr
, addr
, 4);
11623 if ((insn
& (1 << 11)) == 0) {
11624 tcg_gen_addi_i32(addr
, addr
, -offset
);
11626 /* write back the new stack pointer */
11627 store_reg(s
, 13, addr
);
11628 /* set the new PC value */
11629 if ((insn
& 0x0900) == 0x0900) {
11630 store_reg_from_load(s
, 15, tmp
);
11634 case 1: case 3: case 9: case 11: /* czb */
11636 tmp
= load_reg(s
, rm
);
11637 s
->condlabel
= gen_new_label();
11639 if (insn
& (1 << 11))
11640 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11642 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11643 tcg_temp_free_i32(tmp
);
11644 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11645 val
= (uint32_t)s
->pc
+ 2;
11650 case 15: /* IT, nop-hint. */
11651 if ((insn
& 0xf) == 0) {
11652 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11656 s
->condexec_cond
= (insn
>> 4) & 0xe;
11657 s
->condexec_mask
= insn
& 0x1f;
11658 /* No actual code generated for this insn, just setup state. */
11661 case 0xe: /* bkpt */
11663 int imm8
= extract32(insn
, 0, 8);
11665 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11666 default_exception_el(s
));
11670 case 0xa: /* rev, and hlt */
11672 int op1
= extract32(insn
, 6, 2);
11676 int imm6
= extract32(insn
, 0, 6);
11682 /* Otherwise this is rev */
11684 rn
= (insn
>> 3) & 0x7;
11686 tmp
= load_reg(s
, rn
);
11688 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11689 case 1: gen_rev16(tmp
); break;
11690 case 3: gen_revsh(tmp
); break;
11692 g_assert_not_reached();
11694 store_reg(s
, rd
, tmp
);
11699 switch ((insn
>> 5) & 7) {
11703 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11704 gen_helper_setend(cpu_env
);
11705 s
->base
.is_jmp
= DISAS_UPDATE
;
11714 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11715 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11718 addr
= tcg_const_i32(19);
11719 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11720 tcg_temp_free_i32(addr
);
11724 addr
= tcg_const_i32(16);
11725 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11726 tcg_temp_free_i32(addr
);
11728 tcg_temp_free_i32(tmp
);
11731 if (insn
& (1 << 4)) {
11732 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11736 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11751 /* load/store multiple */
11752 TCGv_i32 loaded_var
;
11753 TCGV_UNUSED_I32(loaded_var
);
11754 rn
= (insn
>> 8) & 0x7;
11755 addr
= load_reg(s
, rn
);
11756 for (i
= 0; i
< 8; i
++) {
11757 if (insn
& (1 << i
)) {
11758 if (insn
& (1 << 11)) {
11760 tmp
= tcg_temp_new_i32();
11761 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11765 store_reg(s
, i
, tmp
);
11769 tmp
= load_reg(s
, i
);
11770 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11771 tcg_temp_free_i32(tmp
);
11773 /* advance to the next address */
11774 tcg_gen_addi_i32(addr
, addr
, 4);
11777 if ((insn
& (1 << rn
)) == 0) {
11778 /* base reg not in list: base register writeback */
11779 store_reg(s
, rn
, addr
);
11781 /* base reg in list: if load, complete it now */
11782 if (insn
& (1 << 11)) {
11783 store_reg(s
, rn
, loaded_var
);
11785 tcg_temp_free_i32(addr
);
11790 /* conditional branch or swi */
11791 cond
= (insn
>> 8) & 0xf;
11797 gen_set_pc_im(s
, s
->pc
);
11798 s
->svc_imm
= extract32(insn
, 0, 8);
11799 s
->base
.is_jmp
= DISAS_SWI
;
11802 /* generate a conditional jump to next instruction */
11803 s
->condlabel
= gen_new_label();
11804 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11807 /* jump to the offset */
11808 val
= (uint32_t)s
->pc
+ 2;
11809 offset
= ((int32_t)insn
<< 24) >> 24;
11810 val
+= offset
<< 1;
11815 if (insn
& (1 << 11)) {
11816 /* thumb_insn_is_16bit() ensures we can't get here for
11817 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11818 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11820 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11822 offset
= ((insn
& 0x7ff) << 1);
11823 tmp
= load_reg(s
, 14);
11824 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11825 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
11827 tmp2
= tcg_temp_new_i32();
11828 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
11829 store_reg(s
, 14, tmp2
);
11833 /* unconditional branch */
11834 val
= (uint32_t)s
->pc
;
11835 offset
= ((int32_t)insn
<< 21) >> 21;
11836 val
+= (offset
<< 1) + 2;
11841 /* thumb_insn_is_16bit() ensures we can't get here for
11842 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11844 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11846 if (insn
& (1 << 11)) {
11847 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11848 offset
= ((insn
& 0x7ff) << 1) | 1;
11849 tmp
= load_reg(s
, 14);
11850 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11852 tmp2
= tcg_temp_new_i32();
11853 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
11854 store_reg(s
, 14, tmp2
);
11857 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11858 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
11860 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
11867 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11868 default_exception_el(s
));
11871 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11873 /* Return true if the insn at dc->pc might cross a page boundary.
11874 * (False positives are OK, false negatives are not.)
11875 * We know this is a Thumb insn, and our caller ensures we are
11876 * only called if dc->pc is less than 4 bytes from the page
11877 * boundary, so we cross the page if the first 16 bits indicate
11878 * that this is a 32 bit insn.
11880 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11882 return !thumb_insn_is_16bit(s
, insn
);
11885 static int arm_tr_init_disas_context(DisasContextBase
*dcbase
,
11886 CPUState
*cs
, int max_insns
)
11888 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11889 CPUARMState
*env
= cs
->env_ptr
;
11890 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11892 dc
->pc
= dc
->base
.pc_first
;
11896 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11897 * there is no secure EL1, so we route exceptions to EL3.
11899 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11900 !arm_el_is_aa64(env
, 3);
11901 dc
->thumb
= ARM_TBFLAG_THUMB(dc
->base
.tb
->flags
);
11902 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(dc
->base
.tb
->flags
);
11903 dc
->be_data
= ARM_TBFLAG_BE_DATA(dc
->base
.tb
->flags
) ? MO_BE
: MO_LE
;
11904 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) & 0xf) << 1;
11905 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) >> 4;
11906 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, ARM_TBFLAG_MMUIDX(dc
->base
.tb
->flags
));
11907 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11908 #if !defined(CONFIG_USER_ONLY)
11909 dc
->user
= (dc
->current_el
== 0);
11911 dc
->ns
= ARM_TBFLAG_NS(dc
->base
.tb
->flags
);
11912 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(dc
->base
.tb
->flags
);
11913 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(dc
->base
.tb
->flags
);
11914 dc
->vec_len
= ARM_TBFLAG_VECLEN(dc
->base
.tb
->flags
);
11915 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(dc
->base
.tb
->flags
);
11916 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(dc
->base
.tb
->flags
);
11917 dc
->v7m_handler_mode
= ARM_TBFLAG_HANDLER(dc
->base
.tb
->flags
);
11918 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
11919 regime_is_secure(env
, dc
->mmu_idx
);
11920 dc
->cp_regs
= cpu
->cp_regs
;
11921 dc
->features
= env
->features
;
11923 /* Single step state. The code-generation logic here is:
11925 * generate code with no special handling for single-stepping (except
11926 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11927 * this happens anyway because those changes are all system register or
11929 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11930 * emit code for one insn
11931 * emit code to clear PSTATE.SS
11932 * emit code to generate software step exception for completed step
11933 * end TB (as usual for having generated an exception)
11934 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11935 * emit code to generate a software step exception
11938 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(dc
->base
.tb
->flags
);
11939 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(dc
->base
.tb
->flags
);
11940 dc
->is_ldex
= false;
11941 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11943 dc
->next_page_start
=
11944 (dc
->base
.pc_first
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11946 /* If architectural single step active, limit to 1. */
11947 if (is_singlestepping(dc
)) {
11951 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11952 to those left on the page. */
11954 int bound
= (dc
->next_page_start
- dc
->base
.pc_first
) / 4;
11955 max_insns
= MIN(max_insns
, bound
);
11958 cpu_F0s
= tcg_temp_new_i32();
11959 cpu_F1s
= tcg_temp_new_i32();
11960 cpu_F0d
= tcg_temp_new_i64();
11961 cpu_F1d
= tcg_temp_new_i64();
11964 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11965 cpu_M0
= tcg_temp_new_i64();
11970 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
11972 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11974 /* A note on handling of the condexec (IT) bits:
11976 * We want to avoid the overhead of having to write the updated condexec
11977 * bits back to the CPUARMState for every instruction in an IT block. So:
11978 * (1) if the condexec bits are not already zero then we write
11979 * zero back into the CPUARMState now. This avoids complications trying
11980 * to do it at the end of the block. (For example if we don't do this
11981 * it's hard to identify whether we can safely skip writing condexec
11982 * at the end of the TB, which we definitely want to do for the case
11983 * where a TB doesn't do anything with the IT state at all.)
11984 * (2) if we are going to leave the TB then we call gen_set_condexec()
11985 * which will write the correct value into CPUARMState if zero is wrong.
11986 * This is done both for leaving the TB at the end, and for leaving
11987 * it because of an exception we know will happen, which is done in
11988 * gen_exception_insn(). The latter is necessary because we need to
11989 * leave the TB with the PC/IT state just prior to execution of the
11990 * instruction which caused the exception.
11991 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11992 * then the CPUARMState will be wrong and we need to reset it.
11993 * This is handled in the same way as restoration of the
11994 * PC in these situations; we save the value of the condexec bits
11995 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11996 * then uses this to restore them after an exception.
11998 * Note that there are no instructions which can read the condexec
11999 * bits, and none which can write non-static values to them, so
12000 * we don't need to care about whether CPUARMState is correct in the
12004 /* Reset the conditional execution bits immediately. This avoids
12005 complications trying to do it at the end of the block. */
12006 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
12007 TCGv_i32 tmp
= tcg_temp_new_i32();
12008 tcg_gen_movi_i32(tmp
, 0);
12009 store_cpu_field(tmp
, condexec_bits
);
12011 tcg_clear_temp_count();
12014 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12016 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12018 dc
->insn_start_idx
= tcg_op_buf_count();
12019 tcg_gen_insn_start(dc
->pc
,
12020 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
12024 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
12025 const CPUBreakpoint
*bp
)
12027 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12029 if (bp
->flags
& BP_CPU
) {
12030 gen_set_condexec(dc
);
12031 gen_set_pc_im(dc
, dc
->pc
);
12032 gen_helper_check_breakpoints(cpu_env
);
12033 /* End the TB early; it's likely not going to be executed */
12034 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12036 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
12037 /* The address covered by the breakpoint must be
12038 included in [tb->pc, tb->pc + tb->size) in order
12039 to for it to be properly cleared -- thus we
12040 increment the PC here so that the logic setting
12041 tb->size below does the right thing. */
12042 /* TODO: Advance PC by correct instruction length to
12043 * avoid disassembler error messages */
12045 dc
->base
.is_jmp
= DISAS_NORETURN
;
12051 static bool arm_pre_translate_insn(DisasContext
*dc
)
12053 #ifdef CONFIG_USER_ONLY
12054 /* Intercept jump to the magic kernel page. */
12055 if (dc
->pc
>= 0xffff0000) {
12056 /* We always get here via a jump, so know we are not in a
12057 conditional execution block. */
12058 gen_exception_internal(EXCP_KERNEL_TRAP
);
12059 dc
->base
.is_jmp
= DISAS_NORETURN
;
12064 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12065 /* Singlestep state is Active-pending.
12066 * If we're in this state at the start of a TB then either
12067 * a) we just took an exception to an EL which is being debugged
12068 * and this is the first insn in the exception handler
12069 * b) debug exceptions were masked and we just unmasked them
12070 * without changing EL (eg by clearing PSTATE.D)
12071 * In either case we're going to take a swstep exception in the
12072 * "did not step an insn" case, and so the syndrome ISV and EX
12073 * bits should be zero.
12075 assert(dc
->base
.num_insns
== 1);
12076 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
12077 default_exception_el(dc
));
12078 dc
->base
.is_jmp
= DISAS_NORETURN
;
12085 static void arm_post_translate_insn(DisasContext
*dc
)
12087 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12088 gen_set_label(dc
->condlabel
);
12091 dc
->base
.pc_next
= dc
->pc
;
12092 translator_loop_temp_check(&dc
->base
);
12095 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12097 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12098 CPUARMState
*env
= cpu
->env_ptr
;
12101 if (arm_pre_translate_insn(dc
)) {
12105 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12107 disas_arm_insn(dc
, insn
);
12109 arm_post_translate_insn(dc
);
12111 /* ARM is a fixed-length ISA. We performed the cross-page check
12112 in init_disas_context by adjusting max_insns. */
12115 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12117 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12118 CPUARMState
*env
= cpu
->env_ptr
;
12122 if (arm_pre_translate_insn(dc
)) {
12126 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12127 is_16bit
= thumb_insn_is_16bit(dc
, insn
);
12130 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12132 insn
= insn
<< 16 | insn2
;
12136 if (dc
->condexec_mask
) {
12137 uint32_t cond
= dc
->condexec_cond
;
12139 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
12140 dc
->condlabel
= gen_new_label();
12141 arm_gen_test_cc(cond
^ 1, dc
->condlabel
);
12147 disas_thumb_insn(dc
, insn
);
12149 disas_thumb2_insn(dc
, insn
);
12152 /* Advance the Thumb condexec condition. */
12153 if (dc
->condexec_mask
) {
12154 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
12155 ((dc
->condexec_mask
>> 4) & 1));
12156 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12157 if (dc
->condexec_mask
== 0) {
12158 dc
->condexec_cond
= 0;
12162 arm_post_translate_insn(dc
);
12164 /* Thumb is a variable-length ISA. Stop translation when the next insn
12165 * will touch a new page. This ensures that prefetch aborts occur at
12168 * We want to stop the TB if the next insn starts in a new page,
12169 * or if it spans between this page and the next. This means that
12170 * if we're looking at the last halfword in the page we need to
12171 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12172 * or a 32-bit Thumb insn (which won't).
12173 * This is to avoid generating a silly TB with a single 16-bit insn
12174 * in it at the end of this page (which would execute correctly
12175 * but isn't very efficient).
12177 if (dc
->base
.is_jmp
== DISAS_NEXT
12178 && (dc
->pc
>= dc
->next_page_start
12179 || (dc
->pc
>= dc
->next_page_start
- 3
12180 && insn_crosses_page(env
, dc
)))) {
12181 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12185 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
12187 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12189 if (dc
->base
.tb
->cflags
& CF_LAST_IO
&& dc
->condjmp
) {
12190 /* FIXME: This can theoretically happen with self-modifying code. */
12191 cpu_abort(cpu
, "IO on conditional branch instruction");
12194 /* At this stage dc->condjmp will only be set when the skipped
12195 instruction was a conditional branch or trap, and the PC has
12196 already been written. */
12197 gen_set_condexec(dc
);
12198 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12199 /* Exception return branches need some special case code at the
12200 * end of the TB, which is complex enough that it has to
12201 * handle the single-step vs not and the condition-failed
12202 * insn codepath itself.
12204 gen_bx_excret_final_code(dc
);
12205 } else if (unlikely(is_singlestepping(dc
))) {
12206 /* Unconditional and "condition passed" instruction codepath. */
12207 switch (dc
->base
.is_jmp
) {
12209 gen_ss_advance(dc
);
12210 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12211 default_exception_el(dc
));
12214 gen_ss_advance(dc
);
12215 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12218 gen_ss_advance(dc
);
12219 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12222 case DISAS_TOO_MANY
:
12224 gen_set_pc_im(dc
, dc
->pc
);
12227 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12228 gen_singlestep_exception(dc
);
12230 case DISAS_NORETURN
:
12234 /* While branches must always occur at the end of an IT block,
12235 there are a few other things that can cause us to terminate
12236 the TB in the middle of an IT block:
12237 - Exception generating instructions (bkpt, swi, undefined).
12239 - Hardware watchpoints.
12240 Hardware breakpoints have already been handled and skip this code.
12242 switch(dc
->base
.is_jmp
) {
12244 case DISAS_TOO_MANY
:
12245 gen_goto_tb(dc
, 1, dc
->pc
);
12251 gen_set_pc_im(dc
, dc
->pc
);
12254 /* indicate that the hash table must be used to find the next TB */
12255 tcg_gen_exit_tb(0);
12257 case DISAS_NORETURN
:
12258 /* nothing more to generate */
12261 gen_helper_wfi(cpu_env
);
12262 /* The helper doesn't necessarily throw an exception, but we
12263 * must go back to the main loop to check for interrupts anyway.
12265 tcg_gen_exit_tb(0);
12268 gen_helper_wfe(cpu_env
);
12271 gen_helper_yield(cpu_env
);
12274 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12275 default_exception_el(dc
));
12278 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12281 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12287 /* "Condition failed" instruction codepath for the branch/trap insn */
12288 gen_set_label(dc
->condlabel
);
12289 gen_set_condexec(dc
);
12290 if (unlikely(is_singlestepping(dc
))) {
12291 gen_set_pc_im(dc
, dc
->pc
);
12292 gen_singlestep_exception(dc
);
12294 gen_goto_tb(dc
, 1, dc
->pc
);
12298 /* Functions above can change dc->pc, so re-align db->pc_next */
12299 dc
->base
.pc_next
= dc
->pc
;
12302 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
12304 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12306 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
12307 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
,
12308 dc
->thumb
| (dc
->sctlr_b
<< 1));
12311 static const TranslatorOps arm_translator_ops
= {
12312 .init_disas_context
= arm_tr_init_disas_context
,
12313 .tb_start
= arm_tr_tb_start
,
12314 .insn_start
= arm_tr_insn_start
,
12315 .breakpoint_check
= arm_tr_breakpoint_check
,
12316 .translate_insn
= arm_tr_translate_insn
,
12317 .tb_stop
= arm_tr_tb_stop
,
12318 .disas_log
= arm_tr_disas_log
,
12321 static const TranslatorOps thumb_translator_ops
= {
12322 .init_disas_context
= arm_tr_init_disas_context
,
12323 .tb_start
= arm_tr_tb_start
,
12324 .insn_start
= arm_tr_insn_start
,
12325 .breakpoint_check
= arm_tr_breakpoint_check
,
12326 .translate_insn
= thumb_tr_translate_insn
,
12327 .tb_stop
= arm_tr_tb_stop
,
12328 .disas_log
= arm_tr_disas_log
,
12331 /* generate intermediate code for basic block 'tb'. */
12332 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
)
12335 const TranslatorOps
*ops
= &arm_translator_ops
;
12337 if (ARM_TBFLAG_THUMB(tb
->flags
)) {
12338 ops
= &thumb_translator_ops
;
12340 #ifdef TARGET_AARCH64
12341 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
12342 ops
= &aarch64_translator_ops
;
12346 translator_loop(ops
, &dc
.base
, cpu
, tb
);
12349 static const char *cpu_mode_names
[16] = {
12350 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12351 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12354 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12357 ARMCPU
*cpu
= ARM_CPU(cs
);
12358 CPUARMState
*env
= &cpu
->env
;
12362 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12366 for(i
=0;i
<16;i
++) {
12367 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12369 cpu_fprintf(f
, "\n");
12371 cpu_fprintf(f
, " ");
12374 if (arm_feature(env
, ARM_FEATURE_M
)) {
12375 uint32_t xpsr
= xpsr_read(env
);
12377 const char *ns_status
= "";
12379 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
12380 ns_status
= env
->v7m
.secure
? "S " : "NS ";
12383 if (xpsr
& XPSR_EXCP
) {
12386 if (env
->v7m
.control
[env
->v7m
.secure
] & R_V7M_CONTROL_NPRIV_MASK
) {
12387 mode
= "unpriv-thread";
12389 mode
= "priv-thread";
12393 cpu_fprintf(f
, "XPSR=%08x %c%c%c%c %c %s%s\n",
12395 xpsr
& XPSR_N
? 'N' : '-',
12396 xpsr
& XPSR_Z
? 'Z' : '-',
12397 xpsr
& XPSR_C
? 'C' : '-',
12398 xpsr
& XPSR_V
? 'V' : '-',
12399 xpsr
& XPSR_T
? 'T' : 'A',
12403 uint32_t psr
= cpsr_read(env
);
12404 const char *ns_status
= "";
12406 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12407 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12408 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12411 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12413 psr
& CPSR_N
? 'N' : '-',
12414 psr
& CPSR_Z
? 'Z' : '-',
12415 psr
& CPSR_C
? 'C' : '-',
12416 psr
& CPSR_V
? 'V' : '-',
12417 psr
& CPSR_T
? 'T' : 'A',
12419 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12422 if (flags
& CPU_DUMP_FPU
) {
12423 int numvfpregs
= 0;
12424 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12427 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12430 for (i
= 0; i
< numvfpregs
; i
++) {
12431 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12432 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12433 i
* 2, (uint32_t)v
,
12434 i
* 2 + 1, (uint32_t)(v
>> 32),
12437 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12441 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12442 target_ulong
*data
)
12446 env
->condexec_bits
= 0;
12447 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12449 env
->regs
[15] = data
[0];
12450 env
->condexec_bits
= data
[1];
12451 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;