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)
61 /* We reuse the same 64-bit temporaries for efficiency. */
62 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
63 static TCGv_i32 cpu_R
[16];
64 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
65 TCGv_i64 cpu_exclusive_addr
;
66 TCGv_i64 cpu_exclusive_val
;
68 /* FIXME: These should be removed. */
69 static TCGv_i32 cpu_F0s
, cpu_F1s
;
70 static TCGv_i64 cpu_F0d
, cpu_F1d
;
72 #include "exec/gen-icount.h"
74 static const char *regnames
[] =
75 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
76 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
78 /* initialize TCG globals. */
79 void arm_translate_init(void)
83 for (i
= 0; i
< 16; i
++) {
84 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
85 offsetof(CPUARMState
, regs
[i
]),
88 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
89 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
90 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
91 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
93 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
94 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
95 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
96 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
101 /* Flags for the disas_set_da_iss info argument:
102 * lower bits hold the Rt register number, higher bits are flags.
104 typedef enum ISSInfo
{
107 ISSInvalid
= (1 << 5),
108 ISSIsAcqRel
= (1 << 6),
109 ISSIsWrite
= (1 << 7),
110 ISSIs16Bit
= (1 << 8),
113 /* Save the syndrome information for a Data Abort */
114 static void disas_set_da_iss(DisasContext
*s
, TCGMemOp memop
, ISSInfo issinfo
)
117 int sas
= memop
& MO_SIZE
;
118 bool sse
= memop
& MO_SIGN
;
119 bool is_acqrel
= issinfo
& ISSIsAcqRel
;
120 bool is_write
= issinfo
& ISSIsWrite
;
121 bool is_16bit
= issinfo
& ISSIs16Bit
;
122 int srt
= issinfo
& ISSRegMask
;
124 if (issinfo
& ISSInvalid
) {
125 /* Some callsites want to conditionally provide ISS info,
126 * eg "only if this was not a writeback"
132 /* For AArch32, insns where the src/dest is R15 never generate
133 * ISS information. Catching that here saves checking at all
139 syn
= syn_data_abort_with_iss(0, sas
, sse
, srt
, 0, is_acqrel
,
140 0, 0, 0, is_write
, 0, is_16bit
);
141 disas_set_insn_syndrome(s
, syn
);
144 static inline int get_a32_user_mem_index(DisasContext
*s
)
146 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
148 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
149 * otherwise, access as if at PL0.
151 switch (s
->mmu_idx
) {
152 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
153 case ARMMMUIdx_S12NSE0
:
154 case ARMMMUIdx_S12NSE1
:
155 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0
);
157 case ARMMMUIdx_S1SE0
:
158 case ARMMMUIdx_S1SE1
:
159 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0
);
160 case ARMMMUIdx_MUser
:
161 case ARMMMUIdx_MPriv
:
162 return arm_to_core_mmu_idx(ARMMMUIdx_MUser
);
163 case ARMMMUIdx_MUserNegPri
:
164 case ARMMMUIdx_MPrivNegPri
:
165 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri
);
166 case ARMMMUIdx_MSUser
:
167 case ARMMMUIdx_MSPriv
:
168 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser
);
169 case ARMMMUIdx_MSUserNegPri
:
170 case ARMMMUIdx_MSPrivNegPri
:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri
);
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);
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
)
4549 /* When running in MTTCG we don't generate jumps to the yield and
4550 * WFE helpers as it won't affect the scheduling of other vCPUs.
4551 * If we wanted to more completely model WFE/SEV so we don't busy
4552 * spin unnecessarily we would need to do something more involved.
4555 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4556 gen_set_pc_im(s
, s
->pc
);
4557 s
->base
.is_jmp
= DISAS_YIELD
;
4561 gen_set_pc_im(s
, s
->pc
);
4562 s
->base
.is_jmp
= DISAS_WFI
;
4565 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4566 gen_set_pc_im(s
, s
->pc
);
4567 s
->base
.is_jmp
= DISAS_WFE
;
4572 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4578 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4580 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4583 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4584 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4585 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4590 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4593 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4594 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4595 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4600 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4601 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4602 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4603 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4604 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4606 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4607 switch ((size << 1) | u) { \
4609 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4612 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4615 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4618 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4621 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4624 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4626 default: return 1; \
4629 #define GEN_NEON_INTEGER_OP(name) do { \
4630 switch ((size << 1) | u) { \
4632 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4635 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4638 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4641 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4644 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4647 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4649 default: return 1; \
4652 static TCGv_i32
neon_load_scratch(int scratch
)
4654 TCGv_i32 tmp
= tcg_temp_new_i32();
4655 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4659 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4661 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4662 tcg_temp_free_i32(var
);
4665 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4669 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4671 gen_neon_dup_high16(tmp
);
4673 gen_neon_dup_low16(tmp
);
4676 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4681 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4684 if (!q
&& size
== 2) {
4687 tmp
= tcg_const_i32(rd
);
4688 tmp2
= tcg_const_i32(rm
);
4692 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4695 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4698 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4706 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4709 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4715 tcg_temp_free_i32(tmp
);
4716 tcg_temp_free_i32(tmp2
);
4720 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4723 if (!q
&& size
== 2) {
4726 tmp
= tcg_const_i32(rd
);
4727 tmp2
= tcg_const_i32(rm
);
4731 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4734 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4737 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4745 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4748 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4754 tcg_temp_free_i32(tmp
);
4755 tcg_temp_free_i32(tmp2
);
4759 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4763 rd
= tcg_temp_new_i32();
4764 tmp
= tcg_temp_new_i32();
4766 tcg_gen_shli_i32(rd
, t0
, 8);
4767 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4768 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4769 tcg_gen_or_i32(rd
, rd
, tmp
);
4771 tcg_gen_shri_i32(t1
, t1
, 8);
4772 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4773 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4774 tcg_gen_or_i32(t1
, t1
, tmp
);
4775 tcg_gen_mov_i32(t0
, rd
);
4777 tcg_temp_free_i32(tmp
);
4778 tcg_temp_free_i32(rd
);
4781 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4785 rd
= tcg_temp_new_i32();
4786 tmp
= tcg_temp_new_i32();
4788 tcg_gen_shli_i32(rd
, t0
, 16);
4789 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4790 tcg_gen_or_i32(rd
, rd
, tmp
);
4791 tcg_gen_shri_i32(t1
, t1
, 16);
4792 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4793 tcg_gen_or_i32(t1
, t1
, tmp
);
4794 tcg_gen_mov_i32(t0
, rd
);
4796 tcg_temp_free_i32(tmp
);
4797 tcg_temp_free_i32(rd
);
4805 } neon_ls_element_type
[11] = {
4819 /* Translate a NEON load/store element instruction. Return nonzero if the
4820 instruction is invalid. */
4821 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4840 /* FIXME: this access check should not take precedence over UNDEF
4841 * for invalid encodings; we will generate incorrect syndrome information
4842 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4844 if (s
->fp_excp_el
) {
4845 gen_exception_insn(s
, 4, EXCP_UDEF
,
4846 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4850 if (!s
->vfp_enabled
)
4852 VFP_DREG_D(rd
, insn
);
4853 rn
= (insn
>> 16) & 0xf;
4855 load
= (insn
& (1 << 21)) != 0;
4856 if ((insn
& (1 << 23)) == 0) {
4857 /* Load store all elements. */
4858 op
= (insn
>> 8) & 0xf;
4859 size
= (insn
>> 6) & 3;
4862 /* Catch UNDEF cases for bad values of align field */
4865 if (((insn
>> 5) & 1) == 1) {
4870 if (((insn
>> 4) & 3) == 3) {
4877 nregs
= neon_ls_element_type
[op
].nregs
;
4878 interleave
= neon_ls_element_type
[op
].interleave
;
4879 spacing
= neon_ls_element_type
[op
].spacing
;
4880 if (size
== 3 && (interleave
| spacing
) != 1)
4882 addr
= tcg_temp_new_i32();
4883 load_reg_var(s
, addr
, rn
);
4884 stride
= (1 << size
) * interleave
;
4885 for (reg
= 0; reg
< nregs
; reg
++) {
4886 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4887 load_reg_var(s
, addr
, rn
);
4888 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4889 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4890 load_reg_var(s
, addr
, rn
);
4891 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4894 tmp64
= tcg_temp_new_i64();
4896 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4897 neon_store_reg64(tmp64
, rd
);
4899 neon_load_reg64(tmp64
, rd
);
4900 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4902 tcg_temp_free_i64(tmp64
);
4903 tcg_gen_addi_i32(addr
, addr
, stride
);
4905 for (pass
= 0; pass
< 2; pass
++) {
4908 tmp
= tcg_temp_new_i32();
4909 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4910 neon_store_reg(rd
, pass
, tmp
);
4912 tmp
= neon_load_reg(rd
, pass
);
4913 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4914 tcg_temp_free_i32(tmp
);
4916 tcg_gen_addi_i32(addr
, addr
, stride
);
4917 } else if (size
== 1) {
4919 tmp
= tcg_temp_new_i32();
4920 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4921 tcg_gen_addi_i32(addr
, addr
, stride
);
4922 tmp2
= tcg_temp_new_i32();
4923 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4924 tcg_gen_addi_i32(addr
, addr
, stride
);
4925 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4926 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4927 tcg_temp_free_i32(tmp2
);
4928 neon_store_reg(rd
, pass
, tmp
);
4930 tmp
= neon_load_reg(rd
, pass
);
4931 tmp2
= tcg_temp_new_i32();
4932 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4933 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4934 tcg_temp_free_i32(tmp
);
4935 tcg_gen_addi_i32(addr
, addr
, stride
);
4936 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4937 tcg_temp_free_i32(tmp2
);
4938 tcg_gen_addi_i32(addr
, addr
, stride
);
4940 } else /* size == 0 */ {
4943 for (n
= 0; n
< 4; n
++) {
4944 tmp
= tcg_temp_new_i32();
4945 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4946 tcg_gen_addi_i32(addr
, addr
, stride
);
4950 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4951 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4952 tcg_temp_free_i32(tmp
);
4955 neon_store_reg(rd
, pass
, tmp2
);
4957 tmp2
= neon_load_reg(rd
, pass
);
4958 for (n
= 0; n
< 4; n
++) {
4959 tmp
= tcg_temp_new_i32();
4961 tcg_gen_mov_i32(tmp
, tmp2
);
4963 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4965 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4966 tcg_temp_free_i32(tmp
);
4967 tcg_gen_addi_i32(addr
, addr
, stride
);
4969 tcg_temp_free_i32(tmp2
);
4976 tcg_temp_free_i32(addr
);
4979 size
= (insn
>> 10) & 3;
4981 /* Load single element to all lanes. */
4982 int a
= (insn
>> 4) & 1;
4986 size
= (insn
>> 6) & 3;
4987 nregs
= ((insn
>> 8) & 3) + 1;
4990 if (nregs
!= 4 || a
== 0) {
4993 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4996 if (nregs
== 1 && a
== 1 && size
== 0) {
4999 if (nregs
== 3 && a
== 1) {
5002 addr
= tcg_temp_new_i32();
5003 load_reg_var(s
, addr
, rn
);
5005 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5006 tmp
= gen_load_and_replicate(s
, addr
, size
);
5007 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
5008 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
5009 if (insn
& (1 << 5)) {
5010 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
5011 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
5013 tcg_temp_free_i32(tmp
);
5015 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5016 stride
= (insn
& (1 << 5)) ? 2 : 1;
5017 for (reg
= 0; reg
< nregs
; reg
++) {
5018 tmp
= gen_load_and_replicate(s
, addr
, size
);
5019 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
5020 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
5021 tcg_temp_free_i32(tmp
);
5022 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5026 tcg_temp_free_i32(addr
);
5027 stride
= (1 << size
) * nregs
;
5029 /* Single element. */
5030 int idx
= (insn
>> 4) & 0xf;
5031 pass
= (insn
>> 7) & 1;
5034 shift
= ((insn
>> 5) & 3) * 8;
5038 shift
= ((insn
>> 6) & 1) * 16;
5039 stride
= (insn
& (1 << 5)) ? 2 : 1;
5043 stride
= (insn
& (1 << 6)) ? 2 : 1;
5048 nregs
= ((insn
>> 8) & 3) + 1;
5049 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5052 if (((idx
& (1 << size
)) != 0) ||
5053 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
5058 if ((idx
& 1) != 0) {
5063 if (size
== 2 && (idx
& 2) != 0) {
5068 if ((size
== 2) && ((idx
& 3) == 3)) {
5075 if ((rd
+ stride
* (nregs
- 1)) > 31) {
5076 /* Attempts to write off the end of the register file
5077 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5078 * the neon_load_reg() would write off the end of the array.
5082 addr
= tcg_temp_new_i32();
5083 load_reg_var(s
, addr
, rn
);
5084 for (reg
= 0; reg
< nregs
; reg
++) {
5086 tmp
= tcg_temp_new_i32();
5089 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
5092 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
5095 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
5097 default: /* Avoid compiler warnings. */
5101 tmp2
= neon_load_reg(rd
, pass
);
5102 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
5103 shift
, size
? 16 : 8);
5104 tcg_temp_free_i32(tmp2
);
5106 neon_store_reg(rd
, pass
, tmp
);
5107 } else { /* Store */
5108 tmp
= neon_load_reg(rd
, pass
);
5110 tcg_gen_shri_i32(tmp
, tmp
, shift
);
5113 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
5116 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
5119 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5122 tcg_temp_free_i32(tmp
);
5125 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5127 tcg_temp_free_i32(addr
);
5128 stride
= nregs
* (1 << size
);
5134 base
= load_reg(s
, rn
);
5136 tcg_gen_addi_i32(base
, base
, stride
);
5139 index
= load_reg(s
, rm
);
5140 tcg_gen_add_i32(base
, base
, index
);
5141 tcg_temp_free_i32(index
);
5143 store_reg(s
, rn
, base
);
5148 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5149 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
5151 tcg_gen_and_i32(t
, t
, c
);
5152 tcg_gen_andc_i32(f
, f
, c
);
5153 tcg_gen_or_i32(dest
, t
, f
);
5156 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5159 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
5160 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
5161 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
5166 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5169 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
5170 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
5171 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5176 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5179 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5180 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5181 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5186 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5189 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5190 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5191 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5196 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5202 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5203 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5208 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5209 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5216 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5217 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5222 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5223 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5230 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5234 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5235 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5236 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5241 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5242 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5243 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5247 tcg_temp_free_i32(src
);
5250 static inline void gen_neon_addl(int size
)
5253 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5254 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5255 case 2: tcg_gen_add_i64(CPU_V001
); break;
5260 static inline void gen_neon_subl(int size
)
5263 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5264 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5265 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5270 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5273 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5274 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5276 tcg_gen_neg_i64(var
, var
);
5282 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5285 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5286 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5291 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5296 switch ((size
<< 1) | u
) {
5297 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5298 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5299 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5300 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5302 tmp
= gen_muls_i64_i32(a
, b
);
5303 tcg_gen_mov_i64(dest
, tmp
);
5304 tcg_temp_free_i64(tmp
);
5307 tmp
= gen_mulu_i64_i32(a
, b
);
5308 tcg_gen_mov_i64(dest
, tmp
);
5309 tcg_temp_free_i64(tmp
);
5314 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5315 Don't forget to clean them now. */
5317 tcg_temp_free_i32(a
);
5318 tcg_temp_free_i32(b
);
5322 static void gen_neon_narrow_op(int op
, int u
, int size
,
5323 TCGv_i32 dest
, TCGv_i64 src
)
5327 gen_neon_unarrow_sats(size
, dest
, src
);
5329 gen_neon_narrow(size
, dest
, src
);
5333 gen_neon_narrow_satu(size
, dest
, src
);
5335 gen_neon_narrow_sats(size
, dest
, src
);
5340 /* Symbolic constants for op fields for Neon 3-register same-length.
5341 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5344 #define NEON_3R_VHADD 0
5345 #define NEON_3R_VQADD 1
5346 #define NEON_3R_VRHADD 2
5347 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5348 #define NEON_3R_VHSUB 4
5349 #define NEON_3R_VQSUB 5
5350 #define NEON_3R_VCGT 6
5351 #define NEON_3R_VCGE 7
5352 #define NEON_3R_VSHL 8
5353 #define NEON_3R_VQSHL 9
5354 #define NEON_3R_VRSHL 10
5355 #define NEON_3R_VQRSHL 11
5356 #define NEON_3R_VMAX 12
5357 #define NEON_3R_VMIN 13
5358 #define NEON_3R_VABD 14
5359 #define NEON_3R_VABA 15
5360 #define NEON_3R_VADD_VSUB 16
5361 #define NEON_3R_VTST_VCEQ 17
5362 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5363 #define NEON_3R_VMUL 19
5364 #define NEON_3R_VPMAX 20
5365 #define NEON_3R_VPMIN 21
5366 #define NEON_3R_VQDMULH_VQRDMULH 22
5367 #define NEON_3R_VPADD 23
5368 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5369 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5370 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5371 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5372 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5373 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5374 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5375 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5377 static const uint8_t neon_3r_sizes
[] = {
5378 [NEON_3R_VHADD
] = 0x7,
5379 [NEON_3R_VQADD
] = 0xf,
5380 [NEON_3R_VRHADD
] = 0x7,
5381 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5382 [NEON_3R_VHSUB
] = 0x7,
5383 [NEON_3R_VQSUB
] = 0xf,
5384 [NEON_3R_VCGT
] = 0x7,
5385 [NEON_3R_VCGE
] = 0x7,
5386 [NEON_3R_VSHL
] = 0xf,
5387 [NEON_3R_VQSHL
] = 0xf,
5388 [NEON_3R_VRSHL
] = 0xf,
5389 [NEON_3R_VQRSHL
] = 0xf,
5390 [NEON_3R_VMAX
] = 0x7,
5391 [NEON_3R_VMIN
] = 0x7,
5392 [NEON_3R_VABD
] = 0x7,
5393 [NEON_3R_VABA
] = 0x7,
5394 [NEON_3R_VADD_VSUB
] = 0xf,
5395 [NEON_3R_VTST_VCEQ
] = 0x7,
5396 [NEON_3R_VML
] = 0x7,
5397 [NEON_3R_VMUL
] = 0x7,
5398 [NEON_3R_VPMAX
] = 0x7,
5399 [NEON_3R_VPMIN
] = 0x7,
5400 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5401 [NEON_3R_VPADD
] = 0x7,
5402 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5403 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5404 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5405 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5406 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5407 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5408 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5409 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5412 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5413 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5416 #define NEON_2RM_VREV64 0
5417 #define NEON_2RM_VREV32 1
5418 #define NEON_2RM_VREV16 2
5419 #define NEON_2RM_VPADDL 4
5420 #define NEON_2RM_VPADDL_U 5
5421 #define NEON_2RM_AESE 6 /* Includes AESD */
5422 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5423 #define NEON_2RM_VCLS 8
5424 #define NEON_2RM_VCLZ 9
5425 #define NEON_2RM_VCNT 10
5426 #define NEON_2RM_VMVN 11
5427 #define NEON_2RM_VPADAL 12
5428 #define NEON_2RM_VPADAL_U 13
5429 #define NEON_2RM_VQABS 14
5430 #define NEON_2RM_VQNEG 15
5431 #define NEON_2RM_VCGT0 16
5432 #define NEON_2RM_VCGE0 17
5433 #define NEON_2RM_VCEQ0 18
5434 #define NEON_2RM_VCLE0 19
5435 #define NEON_2RM_VCLT0 20
5436 #define NEON_2RM_SHA1H 21
5437 #define NEON_2RM_VABS 22
5438 #define NEON_2RM_VNEG 23
5439 #define NEON_2RM_VCGT0_F 24
5440 #define NEON_2RM_VCGE0_F 25
5441 #define NEON_2RM_VCEQ0_F 26
5442 #define NEON_2RM_VCLE0_F 27
5443 #define NEON_2RM_VCLT0_F 28
5444 #define NEON_2RM_VABS_F 30
5445 #define NEON_2RM_VNEG_F 31
5446 #define NEON_2RM_VSWP 32
5447 #define NEON_2RM_VTRN 33
5448 #define NEON_2RM_VUZP 34
5449 #define NEON_2RM_VZIP 35
5450 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5451 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5452 #define NEON_2RM_VSHLL 38
5453 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5454 #define NEON_2RM_VRINTN 40
5455 #define NEON_2RM_VRINTX 41
5456 #define NEON_2RM_VRINTA 42
5457 #define NEON_2RM_VRINTZ 43
5458 #define NEON_2RM_VCVT_F16_F32 44
5459 #define NEON_2RM_VRINTM 45
5460 #define NEON_2RM_VCVT_F32_F16 46
5461 #define NEON_2RM_VRINTP 47
5462 #define NEON_2RM_VCVTAU 48
5463 #define NEON_2RM_VCVTAS 49
5464 #define NEON_2RM_VCVTNU 50
5465 #define NEON_2RM_VCVTNS 51
5466 #define NEON_2RM_VCVTPU 52
5467 #define NEON_2RM_VCVTPS 53
5468 #define NEON_2RM_VCVTMU 54
5469 #define NEON_2RM_VCVTMS 55
5470 #define NEON_2RM_VRECPE 56
5471 #define NEON_2RM_VRSQRTE 57
5472 #define NEON_2RM_VRECPE_F 58
5473 #define NEON_2RM_VRSQRTE_F 59
5474 #define NEON_2RM_VCVT_FS 60
5475 #define NEON_2RM_VCVT_FU 61
5476 #define NEON_2RM_VCVT_SF 62
5477 #define NEON_2RM_VCVT_UF 63
5479 static int neon_2rm_is_float_op(int op
)
5481 /* Return true if this neon 2reg-misc op is float-to-float */
5482 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5483 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5484 op
== NEON_2RM_VRINTM
||
5485 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5486 op
>= NEON_2RM_VRECPE_F
);
5489 static bool neon_2rm_is_v8_op(int op
)
5491 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5493 case NEON_2RM_VRINTN
:
5494 case NEON_2RM_VRINTA
:
5495 case NEON_2RM_VRINTM
:
5496 case NEON_2RM_VRINTP
:
5497 case NEON_2RM_VRINTZ
:
5498 case NEON_2RM_VRINTX
:
5499 case NEON_2RM_VCVTAU
:
5500 case NEON_2RM_VCVTAS
:
5501 case NEON_2RM_VCVTNU
:
5502 case NEON_2RM_VCVTNS
:
5503 case NEON_2RM_VCVTPU
:
5504 case NEON_2RM_VCVTPS
:
5505 case NEON_2RM_VCVTMU
:
5506 case NEON_2RM_VCVTMS
:
5513 /* Each entry in this array has bit n set if the insn allows
5514 * size value n (otherwise it will UNDEF). Since unallocated
5515 * op values will have no bits set they always UNDEF.
5517 static const uint8_t neon_2rm_sizes
[] = {
5518 [NEON_2RM_VREV64
] = 0x7,
5519 [NEON_2RM_VREV32
] = 0x3,
5520 [NEON_2RM_VREV16
] = 0x1,
5521 [NEON_2RM_VPADDL
] = 0x7,
5522 [NEON_2RM_VPADDL_U
] = 0x7,
5523 [NEON_2RM_AESE
] = 0x1,
5524 [NEON_2RM_AESMC
] = 0x1,
5525 [NEON_2RM_VCLS
] = 0x7,
5526 [NEON_2RM_VCLZ
] = 0x7,
5527 [NEON_2RM_VCNT
] = 0x1,
5528 [NEON_2RM_VMVN
] = 0x1,
5529 [NEON_2RM_VPADAL
] = 0x7,
5530 [NEON_2RM_VPADAL_U
] = 0x7,
5531 [NEON_2RM_VQABS
] = 0x7,
5532 [NEON_2RM_VQNEG
] = 0x7,
5533 [NEON_2RM_VCGT0
] = 0x7,
5534 [NEON_2RM_VCGE0
] = 0x7,
5535 [NEON_2RM_VCEQ0
] = 0x7,
5536 [NEON_2RM_VCLE0
] = 0x7,
5537 [NEON_2RM_VCLT0
] = 0x7,
5538 [NEON_2RM_SHA1H
] = 0x4,
5539 [NEON_2RM_VABS
] = 0x7,
5540 [NEON_2RM_VNEG
] = 0x7,
5541 [NEON_2RM_VCGT0_F
] = 0x4,
5542 [NEON_2RM_VCGE0_F
] = 0x4,
5543 [NEON_2RM_VCEQ0_F
] = 0x4,
5544 [NEON_2RM_VCLE0_F
] = 0x4,
5545 [NEON_2RM_VCLT0_F
] = 0x4,
5546 [NEON_2RM_VABS_F
] = 0x4,
5547 [NEON_2RM_VNEG_F
] = 0x4,
5548 [NEON_2RM_VSWP
] = 0x1,
5549 [NEON_2RM_VTRN
] = 0x7,
5550 [NEON_2RM_VUZP
] = 0x7,
5551 [NEON_2RM_VZIP
] = 0x7,
5552 [NEON_2RM_VMOVN
] = 0x7,
5553 [NEON_2RM_VQMOVN
] = 0x7,
5554 [NEON_2RM_VSHLL
] = 0x7,
5555 [NEON_2RM_SHA1SU1
] = 0x4,
5556 [NEON_2RM_VRINTN
] = 0x4,
5557 [NEON_2RM_VRINTX
] = 0x4,
5558 [NEON_2RM_VRINTA
] = 0x4,
5559 [NEON_2RM_VRINTZ
] = 0x4,
5560 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5561 [NEON_2RM_VRINTM
] = 0x4,
5562 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5563 [NEON_2RM_VRINTP
] = 0x4,
5564 [NEON_2RM_VCVTAU
] = 0x4,
5565 [NEON_2RM_VCVTAS
] = 0x4,
5566 [NEON_2RM_VCVTNU
] = 0x4,
5567 [NEON_2RM_VCVTNS
] = 0x4,
5568 [NEON_2RM_VCVTPU
] = 0x4,
5569 [NEON_2RM_VCVTPS
] = 0x4,
5570 [NEON_2RM_VCVTMU
] = 0x4,
5571 [NEON_2RM_VCVTMS
] = 0x4,
5572 [NEON_2RM_VRECPE
] = 0x4,
5573 [NEON_2RM_VRSQRTE
] = 0x4,
5574 [NEON_2RM_VRECPE_F
] = 0x4,
5575 [NEON_2RM_VRSQRTE_F
] = 0x4,
5576 [NEON_2RM_VCVT_FS
] = 0x4,
5577 [NEON_2RM_VCVT_FU
] = 0x4,
5578 [NEON_2RM_VCVT_SF
] = 0x4,
5579 [NEON_2RM_VCVT_UF
] = 0x4,
5582 /* Translate a NEON data processing instruction. Return nonzero if the
5583 instruction is invalid.
5584 We process data in a mixture of 32-bit and 64-bit chunks.
5585 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5587 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5599 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5602 /* FIXME: this access check should not take precedence over UNDEF
5603 * for invalid encodings; we will generate incorrect syndrome information
5604 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5606 if (s
->fp_excp_el
) {
5607 gen_exception_insn(s
, 4, EXCP_UDEF
,
5608 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5612 if (!s
->vfp_enabled
)
5614 q
= (insn
& (1 << 6)) != 0;
5615 u
= (insn
>> 24) & 1;
5616 VFP_DREG_D(rd
, insn
);
5617 VFP_DREG_N(rn
, insn
);
5618 VFP_DREG_M(rm
, insn
);
5619 size
= (insn
>> 20) & 3;
5620 if ((insn
& (1 << 23)) == 0) {
5621 /* Three register same length. */
5622 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5623 /* Catch invalid op and bad size combinations: UNDEF */
5624 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5627 /* All insns of this form UNDEF for either this condition or the
5628 * superset of cases "Q==1"; we catch the latter later.
5630 if (q
&& ((rd
| rn
| rm
) & 1)) {
5634 * The SHA-1/SHA-256 3-register instructions require special treatment
5635 * here, as their size field is overloaded as an op type selector, and
5636 * they all consume their input in a single pass.
5638 if (op
== NEON_3R_SHA
) {
5642 if (!u
) { /* SHA-1 */
5643 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5646 tmp
= tcg_const_i32(rd
);
5647 tmp2
= tcg_const_i32(rn
);
5648 tmp3
= tcg_const_i32(rm
);
5649 tmp4
= tcg_const_i32(size
);
5650 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5651 tcg_temp_free_i32(tmp4
);
5652 } else { /* SHA-256 */
5653 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5656 tmp
= tcg_const_i32(rd
);
5657 tmp2
= tcg_const_i32(rn
);
5658 tmp3
= tcg_const_i32(rm
);
5661 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5664 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5667 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5671 tcg_temp_free_i32(tmp
);
5672 tcg_temp_free_i32(tmp2
);
5673 tcg_temp_free_i32(tmp3
);
5676 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5677 /* 64-bit element instructions. */
5678 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5679 neon_load_reg64(cpu_V0
, rn
+ pass
);
5680 neon_load_reg64(cpu_V1
, rm
+ pass
);
5684 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5687 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5693 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5696 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5702 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5704 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5709 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5712 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5718 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5720 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5723 case NEON_3R_VQRSHL
:
5725 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5728 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5732 case NEON_3R_VADD_VSUB
:
5734 tcg_gen_sub_i64(CPU_V001
);
5736 tcg_gen_add_i64(CPU_V001
);
5742 neon_store_reg64(cpu_V0
, rd
+ pass
);
5751 case NEON_3R_VQRSHL
:
5754 /* Shift instruction operands are reversed. */
5769 case NEON_3R_FLOAT_ARITH
:
5770 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5772 case NEON_3R_FLOAT_MINMAX
:
5773 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5775 case NEON_3R_FLOAT_CMP
:
5777 /* no encoding for U=0 C=1x */
5781 case NEON_3R_FLOAT_ACMP
:
5786 case NEON_3R_FLOAT_MISC
:
5787 /* VMAXNM/VMINNM in ARMv8 */
5788 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5793 if (u
&& (size
!= 0)) {
5794 /* UNDEF on invalid size for polynomial subcase */
5799 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5807 if (pairwise
&& q
) {
5808 /* All the pairwise insns UNDEF if Q is set */
5812 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5817 tmp
= neon_load_reg(rn
, 0);
5818 tmp2
= neon_load_reg(rn
, 1);
5820 tmp
= neon_load_reg(rm
, 0);
5821 tmp2
= neon_load_reg(rm
, 1);
5825 tmp
= neon_load_reg(rn
, pass
);
5826 tmp2
= neon_load_reg(rm
, pass
);
5830 GEN_NEON_INTEGER_OP(hadd
);
5833 GEN_NEON_INTEGER_OP_ENV(qadd
);
5835 case NEON_3R_VRHADD
:
5836 GEN_NEON_INTEGER_OP(rhadd
);
5838 case NEON_3R_LOGIC
: /* Logic ops. */
5839 switch ((u
<< 2) | size
) {
5841 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5844 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5847 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5850 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5853 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5856 tmp3
= neon_load_reg(rd
, pass
);
5857 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5858 tcg_temp_free_i32(tmp3
);
5861 tmp3
= neon_load_reg(rd
, pass
);
5862 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5863 tcg_temp_free_i32(tmp3
);
5866 tmp3
= neon_load_reg(rd
, pass
);
5867 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5868 tcg_temp_free_i32(tmp3
);
5873 GEN_NEON_INTEGER_OP(hsub
);
5876 GEN_NEON_INTEGER_OP_ENV(qsub
);
5879 GEN_NEON_INTEGER_OP(cgt
);
5882 GEN_NEON_INTEGER_OP(cge
);
5885 GEN_NEON_INTEGER_OP(shl
);
5888 GEN_NEON_INTEGER_OP_ENV(qshl
);
5891 GEN_NEON_INTEGER_OP(rshl
);
5893 case NEON_3R_VQRSHL
:
5894 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5897 GEN_NEON_INTEGER_OP(max
);
5900 GEN_NEON_INTEGER_OP(min
);
5903 GEN_NEON_INTEGER_OP(abd
);
5906 GEN_NEON_INTEGER_OP(abd
);
5907 tcg_temp_free_i32(tmp2
);
5908 tmp2
= neon_load_reg(rd
, pass
);
5909 gen_neon_add(size
, tmp
, tmp2
);
5911 case NEON_3R_VADD_VSUB
:
5912 if (!u
) { /* VADD */
5913 gen_neon_add(size
, tmp
, tmp2
);
5916 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5917 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5918 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5923 case NEON_3R_VTST_VCEQ
:
5924 if (!u
) { /* VTST */
5926 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5927 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5928 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5933 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5934 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5935 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5940 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5942 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5943 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5944 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5947 tcg_temp_free_i32(tmp2
);
5948 tmp2
= neon_load_reg(rd
, pass
);
5950 gen_neon_rsb(size
, tmp
, tmp2
);
5952 gen_neon_add(size
, tmp
, tmp2
);
5956 if (u
) { /* polynomial */
5957 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5958 } else { /* Integer */
5960 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5961 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5962 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5968 GEN_NEON_INTEGER_OP(pmax
);
5971 GEN_NEON_INTEGER_OP(pmin
);
5973 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5974 if (!u
) { /* VQDMULH */
5977 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5980 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5984 } else { /* VQRDMULH */
5987 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5990 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5998 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5999 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
6000 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
6004 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
6006 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6007 switch ((u
<< 2) | size
) {
6010 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6013 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
6016 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
6021 tcg_temp_free_ptr(fpstatus
);
6024 case NEON_3R_FLOAT_MULTIPLY
:
6026 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6027 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6029 tcg_temp_free_i32(tmp2
);
6030 tmp2
= neon_load_reg(rd
, pass
);
6032 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6034 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6037 tcg_temp_free_ptr(fpstatus
);
6040 case NEON_3R_FLOAT_CMP
:
6042 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6044 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6047 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6049 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6052 tcg_temp_free_ptr(fpstatus
);
6055 case NEON_3R_FLOAT_ACMP
:
6057 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6059 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6061 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6063 tcg_temp_free_ptr(fpstatus
);
6066 case NEON_3R_FLOAT_MINMAX
:
6068 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6070 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6072 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6074 tcg_temp_free_ptr(fpstatus
);
6077 case NEON_3R_FLOAT_MISC
:
6080 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6082 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6084 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6086 tcg_temp_free_ptr(fpstatus
);
6089 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6091 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6097 /* VFMA, VFMS: fused multiply-add */
6098 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6099 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6102 gen_helper_vfp_negs(tmp
, tmp
);
6104 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6105 tcg_temp_free_i32(tmp3
);
6106 tcg_temp_free_ptr(fpstatus
);
6112 tcg_temp_free_i32(tmp2
);
6114 /* Save the result. For elementwise operations we can put it
6115 straight into the destination register. For pairwise operations
6116 we have to be careful to avoid clobbering the source operands. */
6117 if (pairwise
&& rd
== rm
) {
6118 neon_store_scratch(pass
, tmp
);
6120 neon_store_reg(rd
, pass
, tmp
);
6124 if (pairwise
&& rd
== rm
) {
6125 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6126 tmp
= neon_load_scratch(pass
);
6127 neon_store_reg(rd
, pass
, tmp
);
6130 /* End of 3 register same size operations. */
6131 } else if (insn
& (1 << 4)) {
6132 if ((insn
& 0x00380080) != 0) {
6133 /* Two registers and shift. */
6134 op
= (insn
>> 8) & 0xf;
6135 if (insn
& (1 << 7)) {
6143 while ((insn
& (1 << (size
+ 19))) == 0)
6146 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6147 /* To avoid excessive duplication of ops we implement shift
6148 by immediate using the variable shift operations. */
6150 /* Shift by immediate:
6151 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6152 if (q
&& ((rd
| rm
) & 1)) {
6155 if (!u
&& (op
== 4 || op
== 6)) {
6158 /* Right shifts are encoded as N - shift, where N is the
6159 element size in bits. */
6161 shift
= shift
- (1 << (size
+ 3));
6169 imm
= (uint8_t) shift
;
6174 imm
= (uint16_t) shift
;
6185 for (pass
= 0; pass
< count
; pass
++) {
6187 neon_load_reg64(cpu_V0
, rm
+ pass
);
6188 tcg_gen_movi_i64(cpu_V1
, imm
);
6193 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6195 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6200 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6202 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6205 case 5: /* VSHL, VSLI */
6206 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6208 case 6: /* VQSHLU */
6209 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6214 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6217 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6222 if (op
== 1 || op
== 3) {
6224 neon_load_reg64(cpu_V1
, rd
+ pass
);
6225 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6226 } else if (op
== 4 || (op
== 5 && u
)) {
6228 neon_load_reg64(cpu_V1
, rd
+ pass
);
6230 if (shift
< -63 || shift
> 63) {
6234 mask
= 0xffffffffffffffffull
>> -shift
;
6236 mask
= 0xffffffffffffffffull
<< shift
;
6239 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6240 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6242 neon_store_reg64(cpu_V0
, rd
+ pass
);
6243 } else { /* size < 3 */
6244 /* Operands in T0 and T1. */
6245 tmp
= neon_load_reg(rm
, pass
);
6246 tmp2
= tcg_temp_new_i32();
6247 tcg_gen_movi_i32(tmp2
, imm
);
6251 GEN_NEON_INTEGER_OP(shl
);
6255 GEN_NEON_INTEGER_OP(rshl
);
6258 case 5: /* VSHL, VSLI */
6260 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6261 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6262 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6266 case 6: /* VQSHLU */
6269 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6273 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6277 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6285 GEN_NEON_INTEGER_OP_ENV(qshl
);
6288 tcg_temp_free_i32(tmp2
);
6290 if (op
== 1 || op
== 3) {
6292 tmp2
= neon_load_reg(rd
, pass
);
6293 gen_neon_add(size
, tmp
, tmp2
);
6294 tcg_temp_free_i32(tmp2
);
6295 } else if (op
== 4 || (op
== 5 && u
)) {
6300 mask
= 0xff >> -shift
;
6302 mask
= (uint8_t)(0xff << shift
);
6308 mask
= 0xffff >> -shift
;
6310 mask
= (uint16_t)(0xffff << shift
);
6314 if (shift
< -31 || shift
> 31) {
6318 mask
= 0xffffffffu
>> -shift
;
6320 mask
= 0xffffffffu
<< shift
;
6326 tmp2
= neon_load_reg(rd
, pass
);
6327 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6328 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6329 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6330 tcg_temp_free_i32(tmp2
);
6332 neon_store_reg(rd
, pass
, tmp
);
6335 } else if (op
< 10) {
6336 /* Shift by immediate and narrow:
6337 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6338 int input_unsigned
= (op
== 8) ? !u
: u
;
6342 shift
= shift
- (1 << (size
+ 3));
6345 tmp64
= tcg_const_i64(shift
);
6346 neon_load_reg64(cpu_V0
, rm
);
6347 neon_load_reg64(cpu_V1
, rm
+ 1);
6348 for (pass
= 0; pass
< 2; pass
++) {
6356 if (input_unsigned
) {
6357 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6359 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6362 if (input_unsigned
) {
6363 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6365 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6368 tmp
= tcg_temp_new_i32();
6369 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6370 neon_store_reg(rd
, pass
, tmp
);
6372 tcg_temp_free_i64(tmp64
);
6375 imm
= (uint16_t)shift
;
6379 imm
= (uint32_t)shift
;
6381 tmp2
= tcg_const_i32(imm
);
6382 tmp4
= neon_load_reg(rm
+ 1, 0);
6383 tmp5
= neon_load_reg(rm
+ 1, 1);
6384 for (pass
= 0; pass
< 2; pass
++) {
6386 tmp
= neon_load_reg(rm
, 0);
6390 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6393 tmp3
= neon_load_reg(rm
, 1);
6397 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6399 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6400 tcg_temp_free_i32(tmp
);
6401 tcg_temp_free_i32(tmp3
);
6402 tmp
= tcg_temp_new_i32();
6403 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6404 neon_store_reg(rd
, pass
, tmp
);
6406 tcg_temp_free_i32(tmp2
);
6408 } else if (op
== 10) {
6410 if (q
|| (rd
& 1)) {
6413 tmp
= neon_load_reg(rm
, 0);
6414 tmp2
= neon_load_reg(rm
, 1);
6415 for (pass
= 0; pass
< 2; pass
++) {
6419 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6422 /* The shift is less than the width of the source
6423 type, so we can just shift the whole register. */
6424 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6425 /* Widen the result of shift: we need to clear
6426 * the potential overflow bits resulting from
6427 * left bits of the narrow input appearing as
6428 * right bits of left the neighbour narrow
6430 if (size
< 2 || !u
) {
6433 imm
= (0xffu
>> (8 - shift
));
6435 } else if (size
== 1) {
6436 imm
= 0xffff >> (16 - shift
);
6439 imm
= 0xffffffff >> (32 - shift
);
6442 imm64
= imm
| (((uint64_t)imm
) << 32);
6446 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6449 neon_store_reg64(cpu_V0
, rd
+ pass
);
6451 } else if (op
>= 14) {
6452 /* VCVT fixed-point. */
6453 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6456 /* We have already masked out the must-be-1 top bit of imm6,
6457 * hence this 32-shift where the ARM ARM has 64-imm6.
6460 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6461 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6464 gen_vfp_ulto(0, shift
, 1);
6466 gen_vfp_slto(0, shift
, 1);
6469 gen_vfp_toul(0, shift
, 1);
6471 gen_vfp_tosl(0, shift
, 1);
6473 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6478 } else { /* (insn & 0x00380080) == 0 */
6480 if (q
&& (rd
& 1)) {
6484 op
= (insn
>> 8) & 0xf;
6485 /* One register and immediate. */
6486 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6487 invert
= (insn
& (1 << 5)) != 0;
6488 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6489 * We choose to not special-case this and will behave as if a
6490 * valid constant encoding of 0 had been given.
6509 imm
= (imm
<< 8) | (imm
<< 24);
6512 imm
= (imm
<< 8) | 0xff;
6515 imm
= (imm
<< 16) | 0xffff;
6518 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6526 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6527 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6533 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6534 if (op
& 1 && op
< 12) {
6535 tmp
= neon_load_reg(rd
, pass
);
6537 /* The immediate value has already been inverted, so
6539 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6541 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6545 tmp
= tcg_temp_new_i32();
6546 if (op
== 14 && invert
) {
6550 for (n
= 0; n
< 4; n
++) {
6551 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6552 val
|= 0xff << (n
* 8);
6554 tcg_gen_movi_i32(tmp
, val
);
6556 tcg_gen_movi_i32(tmp
, imm
);
6559 neon_store_reg(rd
, pass
, tmp
);
6562 } else { /* (insn & 0x00800010 == 0x00800000) */
6564 op
= (insn
>> 8) & 0xf;
6565 if ((insn
& (1 << 6)) == 0) {
6566 /* Three registers of different lengths. */
6570 /* undefreq: bit 0 : UNDEF if size == 0
6571 * bit 1 : UNDEF if size == 1
6572 * bit 2 : UNDEF if size == 2
6573 * bit 3 : UNDEF if U == 1
6574 * Note that [2:0] set implies 'always UNDEF'
6577 /* prewiden, src1_wide, src2_wide, undefreq */
6578 static const int neon_3reg_wide
[16][4] = {
6579 {1, 0, 0, 0}, /* VADDL */
6580 {1, 1, 0, 0}, /* VADDW */
6581 {1, 0, 0, 0}, /* VSUBL */
6582 {1, 1, 0, 0}, /* VSUBW */
6583 {0, 1, 1, 0}, /* VADDHN */
6584 {0, 0, 0, 0}, /* VABAL */
6585 {0, 1, 1, 0}, /* VSUBHN */
6586 {0, 0, 0, 0}, /* VABDL */
6587 {0, 0, 0, 0}, /* VMLAL */
6588 {0, 0, 0, 9}, /* VQDMLAL */
6589 {0, 0, 0, 0}, /* VMLSL */
6590 {0, 0, 0, 9}, /* VQDMLSL */
6591 {0, 0, 0, 0}, /* Integer VMULL */
6592 {0, 0, 0, 1}, /* VQDMULL */
6593 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6594 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6597 prewiden
= neon_3reg_wide
[op
][0];
6598 src1_wide
= neon_3reg_wide
[op
][1];
6599 src2_wide
= neon_3reg_wide
[op
][2];
6600 undefreq
= neon_3reg_wide
[op
][3];
6602 if ((undefreq
& (1 << size
)) ||
6603 ((undefreq
& 8) && u
)) {
6606 if ((src1_wide
&& (rn
& 1)) ||
6607 (src2_wide
&& (rm
& 1)) ||
6608 (!src2_wide
&& (rd
& 1))) {
6612 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6613 * outside the loop below as it only performs a single pass.
6615 if (op
== 14 && size
== 2) {
6616 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6618 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6621 tcg_rn
= tcg_temp_new_i64();
6622 tcg_rm
= tcg_temp_new_i64();
6623 tcg_rd
= tcg_temp_new_i64();
6624 neon_load_reg64(tcg_rn
, rn
);
6625 neon_load_reg64(tcg_rm
, rm
);
6626 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6627 neon_store_reg64(tcg_rd
, rd
);
6628 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6629 neon_store_reg64(tcg_rd
, rd
+ 1);
6630 tcg_temp_free_i64(tcg_rn
);
6631 tcg_temp_free_i64(tcg_rm
);
6632 tcg_temp_free_i64(tcg_rd
);
6636 /* Avoid overlapping operands. Wide source operands are
6637 always aligned so will never overlap with wide
6638 destinations in problematic ways. */
6639 if (rd
== rm
&& !src2_wide
) {
6640 tmp
= neon_load_reg(rm
, 1);
6641 neon_store_scratch(2, tmp
);
6642 } else if (rd
== rn
&& !src1_wide
) {
6643 tmp
= neon_load_reg(rn
, 1);
6644 neon_store_scratch(2, tmp
);
6647 for (pass
= 0; pass
< 2; pass
++) {
6649 neon_load_reg64(cpu_V0
, rn
+ pass
);
6652 if (pass
== 1 && rd
== rn
) {
6653 tmp
= neon_load_scratch(2);
6655 tmp
= neon_load_reg(rn
, pass
);
6658 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6662 neon_load_reg64(cpu_V1
, rm
+ pass
);
6665 if (pass
== 1 && rd
== rm
) {
6666 tmp2
= neon_load_scratch(2);
6668 tmp2
= neon_load_reg(rm
, pass
);
6671 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6675 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6676 gen_neon_addl(size
);
6678 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6679 gen_neon_subl(size
);
6681 case 5: case 7: /* VABAL, VABDL */
6682 switch ((size
<< 1) | u
) {
6684 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6687 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6690 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6693 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6696 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6699 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6703 tcg_temp_free_i32(tmp2
);
6704 tcg_temp_free_i32(tmp
);
6706 case 8: case 9: case 10: case 11: case 12: case 13:
6707 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6708 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6710 case 14: /* Polynomial VMULL */
6711 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6712 tcg_temp_free_i32(tmp2
);
6713 tcg_temp_free_i32(tmp
);
6715 default: /* 15 is RESERVED: caught earlier */
6720 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6721 neon_store_reg64(cpu_V0
, rd
+ pass
);
6722 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6724 neon_load_reg64(cpu_V1
, rd
+ pass
);
6726 case 10: /* VMLSL */
6727 gen_neon_negl(cpu_V0
, size
);
6729 case 5: case 8: /* VABAL, VMLAL */
6730 gen_neon_addl(size
);
6732 case 9: case 11: /* VQDMLAL, VQDMLSL */
6733 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6735 gen_neon_negl(cpu_V0
, size
);
6737 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6742 neon_store_reg64(cpu_V0
, rd
+ pass
);
6743 } else if (op
== 4 || op
== 6) {
6744 /* Narrowing operation. */
6745 tmp
= tcg_temp_new_i32();
6749 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6752 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6755 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6756 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6763 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6766 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6769 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6770 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6771 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6779 neon_store_reg(rd
, 0, tmp3
);
6780 neon_store_reg(rd
, 1, tmp
);
6783 /* Write back the result. */
6784 neon_store_reg64(cpu_V0
, rd
+ pass
);
6788 /* Two registers and a scalar. NB that for ops of this form
6789 * the ARM ARM labels bit 24 as Q, but it is in our variable
6796 case 1: /* Float VMLA scalar */
6797 case 5: /* Floating point VMLS scalar */
6798 case 9: /* Floating point VMUL scalar */
6803 case 0: /* Integer VMLA scalar */
6804 case 4: /* Integer VMLS scalar */
6805 case 8: /* Integer VMUL scalar */
6806 case 12: /* VQDMULH scalar */
6807 case 13: /* VQRDMULH scalar */
6808 if (u
&& ((rd
| rn
) & 1)) {
6811 tmp
= neon_get_scalar(size
, rm
);
6812 neon_store_scratch(0, tmp
);
6813 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6814 tmp
= neon_load_scratch(0);
6815 tmp2
= neon_load_reg(rn
, pass
);
6818 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6820 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6822 } else if (op
== 13) {
6824 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6826 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6828 } else if (op
& 1) {
6829 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6830 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6831 tcg_temp_free_ptr(fpstatus
);
6834 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6835 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6836 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6840 tcg_temp_free_i32(tmp2
);
6843 tmp2
= neon_load_reg(rd
, pass
);
6846 gen_neon_add(size
, tmp
, tmp2
);
6850 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6851 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6852 tcg_temp_free_ptr(fpstatus
);
6856 gen_neon_rsb(size
, tmp
, tmp2
);
6860 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6861 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6862 tcg_temp_free_ptr(fpstatus
);
6868 tcg_temp_free_i32(tmp2
);
6870 neon_store_reg(rd
, pass
, tmp
);
6873 case 3: /* VQDMLAL scalar */
6874 case 7: /* VQDMLSL scalar */
6875 case 11: /* VQDMULL scalar */
6880 case 2: /* VMLAL sclar */
6881 case 6: /* VMLSL scalar */
6882 case 10: /* VMULL scalar */
6886 tmp2
= neon_get_scalar(size
, rm
);
6887 /* We need a copy of tmp2 because gen_neon_mull
6888 * deletes it during pass 0. */
6889 tmp4
= tcg_temp_new_i32();
6890 tcg_gen_mov_i32(tmp4
, tmp2
);
6891 tmp3
= neon_load_reg(rn
, 1);
6893 for (pass
= 0; pass
< 2; pass
++) {
6895 tmp
= neon_load_reg(rn
, 0);
6900 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6902 neon_load_reg64(cpu_V1
, rd
+ pass
);
6906 gen_neon_negl(cpu_V0
, size
);
6909 gen_neon_addl(size
);
6912 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6914 gen_neon_negl(cpu_V0
, size
);
6916 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6922 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6927 neon_store_reg64(cpu_V0
, rd
+ pass
);
6932 default: /* 14 and 15 are RESERVED */
6936 } else { /* size == 3 */
6939 imm
= (insn
>> 8) & 0xf;
6944 if (q
&& ((rd
| rn
| rm
) & 1)) {
6949 neon_load_reg64(cpu_V0
, rn
);
6951 neon_load_reg64(cpu_V1
, rn
+ 1);
6953 } else if (imm
== 8) {
6954 neon_load_reg64(cpu_V0
, rn
+ 1);
6956 neon_load_reg64(cpu_V1
, rm
);
6959 tmp64
= tcg_temp_new_i64();
6961 neon_load_reg64(cpu_V0
, rn
);
6962 neon_load_reg64(tmp64
, rn
+ 1);
6964 neon_load_reg64(cpu_V0
, rn
+ 1);
6965 neon_load_reg64(tmp64
, rm
);
6967 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6968 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6969 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6971 neon_load_reg64(cpu_V1
, rm
);
6973 neon_load_reg64(cpu_V1
, rm
+ 1);
6976 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6977 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6978 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6979 tcg_temp_free_i64(tmp64
);
6982 neon_load_reg64(cpu_V0
, rn
);
6983 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6984 neon_load_reg64(cpu_V1
, rm
);
6985 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6986 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6988 neon_store_reg64(cpu_V0
, rd
);
6990 neon_store_reg64(cpu_V1
, rd
+ 1);
6992 } else if ((insn
& (1 << 11)) == 0) {
6993 /* Two register misc. */
6994 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6995 size
= (insn
>> 18) & 3;
6996 /* UNDEF for unknown op values and bad op-size combinations */
6997 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
7000 if (neon_2rm_is_v8_op(op
) &&
7001 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7004 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
7005 q
&& ((rm
| rd
) & 1)) {
7009 case NEON_2RM_VREV64
:
7010 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
7011 tmp
= neon_load_reg(rm
, pass
* 2);
7012 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
7014 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7015 case 1: gen_swap_half(tmp
); break;
7016 case 2: /* no-op */ break;
7019 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
7021 neon_store_reg(rd
, pass
* 2, tmp2
);
7024 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
7025 case 1: gen_swap_half(tmp2
); break;
7028 neon_store_reg(rd
, pass
* 2, tmp2
);
7032 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
7033 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
7034 for (pass
= 0; pass
< q
+ 1; pass
++) {
7035 tmp
= neon_load_reg(rm
, pass
* 2);
7036 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
7037 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
7038 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
7040 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
7041 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
7042 case 2: tcg_gen_add_i64(CPU_V001
); break;
7045 if (op
>= NEON_2RM_VPADAL
) {
7047 neon_load_reg64(cpu_V1
, rd
+ pass
);
7048 gen_neon_addl(size
);
7050 neon_store_reg64(cpu_V0
, rd
+ pass
);
7056 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7057 tmp
= neon_load_reg(rm
, n
);
7058 tmp2
= neon_load_reg(rd
, n
+ 1);
7059 neon_store_reg(rm
, n
, tmp2
);
7060 neon_store_reg(rd
, n
+ 1, tmp
);
7067 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7072 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7076 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7077 /* also VQMOVUN; op field and mnemonics don't line up */
7082 for (pass
= 0; pass
< 2; pass
++) {
7083 neon_load_reg64(cpu_V0
, rm
+ pass
);
7084 tmp
= tcg_temp_new_i32();
7085 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7090 neon_store_reg(rd
, 0, tmp2
);
7091 neon_store_reg(rd
, 1, tmp
);
7095 case NEON_2RM_VSHLL
:
7096 if (q
|| (rd
& 1)) {
7099 tmp
= neon_load_reg(rm
, 0);
7100 tmp2
= neon_load_reg(rm
, 1);
7101 for (pass
= 0; pass
< 2; pass
++) {
7104 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7105 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7106 neon_store_reg64(cpu_V0
, rd
+ pass
);
7109 case NEON_2RM_VCVT_F16_F32
:
7110 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7114 tmp
= tcg_temp_new_i32();
7115 tmp2
= tcg_temp_new_i32();
7116 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7117 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7118 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7119 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7120 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7121 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7122 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7123 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7124 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7125 neon_store_reg(rd
, 0, tmp2
);
7126 tmp2
= tcg_temp_new_i32();
7127 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7128 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7129 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7130 neon_store_reg(rd
, 1, tmp2
);
7131 tcg_temp_free_i32(tmp
);
7133 case NEON_2RM_VCVT_F32_F16
:
7134 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7138 tmp3
= tcg_temp_new_i32();
7139 tmp
= neon_load_reg(rm
, 0);
7140 tmp2
= neon_load_reg(rm
, 1);
7141 tcg_gen_ext16u_i32(tmp3
, tmp
);
7142 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7143 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7144 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7145 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7146 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7147 tcg_temp_free_i32(tmp
);
7148 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7149 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7150 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7151 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7152 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7153 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7154 tcg_temp_free_i32(tmp2
);
7155 tcg_temp_free_i32(tmp3
);
7157 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7158 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
7159 || ((rm
| rd
) & 1)) {
7162 tmp
= tcg_const_i32(rd
);
7163 tmp2
= tcg_const_i32(rm
);
7165 /* Bit 6 is the lowest opcode bit; it distinguishes between
7166 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7168 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7170 if (op
== NEON_2RM_AESE
) {
7171 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
7173 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
7175 tcg_temp_free_i32(tmp
);
7176 tcg_temp_free_i32(tmp2
);
7177 tcg_temp_free_i32(tmp3
);
7179 case NEON_2RM_SHA1H
:
7180 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7181 || ((rm
| rd
) & 1)) {
7184 tmp
= tcg_const_i32(rd
);
7185 tmp2
= tcg_const_i32(rm
);
7187 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
7189 tcg_temp_free_i32(tmp
);
7190 tcg_temp_free_i32(tmp2
);
7192 case NEON_2RM_SHA1SU1
:
7193 if ((rm
| rd
) & 1) {
7196 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7198 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7201 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7204 tmp
= tcg_const_i32(rd
);
7205 tmp2
= tcg_const_i32(rm
);
7207 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
7209 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7211 tcg_temp_free_i32(tmp
);
7212 tcg_temp_free_i32(tmp2
);
7216 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7217 if (neon_2rm_is_float_op(op
)) {
7218 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7219 neon_reg_offset(rm
, pass
));
7222 tmp
= neon_load_reg(rm
, pass
);
7225 case NEON_2RM_VREV32
:
7227 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7228 case 1: gen_swap_half(tmp
); break;
7232 case NEON_2RM_VREV16
:
7237 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7238 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7239 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7245 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7246 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7247 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7252 gen_helper_neon_cnt_u8(tmp
, tmp
);
7255 tcg_gen_not_i32(tmp
, tmp
);
7257 case NEON_2RM_VQABS
:
7260 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7263 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7266 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7271 case NEON_2RM_VQNEG
:
7274 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7277 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7280 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7285 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7286 tmp2
= tcg_const_i32(0);
7288 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7289 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7290 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7293 tcg_temp_free_i32(tmp2
);
7294 if (op
== NEON_2RM_VCLE0
) {
7295 tcg_gen_not_i32(tmp
, tmp
);
7298 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7299 tmp2
= tcg_const_i32(0);
7301 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7302 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7303 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7306 tcg_temp_free_i32(tmp2
);
7307 if (op
== NEON_2RM_VCLT0
) {
7308 tcg_gen_not_i32(tmp
, tmp
);
7311 case NEON_2RM_VCEQ0
:
7312 tmp2
= tcg_const_i32(0);
7314 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7315 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7316 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7319 tcg_temp_free_i32(tmp2
);
7323 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7324 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7325 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7330 tmp2
= tcg_const_i32(0);
7331 gen_neon_rsb(size
, tmp
, tmp2
);
7332 tcg_temp_free_i32(tmp2
);
7334 case NEON_2RM_VCGT0_F
:
7336 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7337 tmp2
= tcg_const_i32(0);
7338 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7339 tcg_temp_free_i32(tmp2
);
7340 tcg_temp_free_ptr(fpstatus
);
7343 case NEON_2RM_VCGE0_F
:
7345 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7346 tmp2
= tcg_const_i32(0);
7347 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7348 tcg_temp_free_i32(tmp2
);
7349 tcg_temp_free_ptr(fpstatus
);
7352 case NEON_2RM_VCEQ0_F
:
7354 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7355 tmp2
= tcg_const_i32(0);
7356 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7357 tcg_temp_free_i32(tmp2
);
7358 tcg_temp_free_ptr(fpstatus
);
7361 case NEON_2RM_VCLE0_F
:
7363 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7364 tmp2
= tcg_const_i32(0);
7365 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7366 tcg_temp_free_i32(tmp2
);
7367 tcg_temp_free_ptr(fpstatus
);
7370 case NEON_2RM_VCLT0_F
:
7372 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7373 tmp2
= tcg_const_i32(0);
7374 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7375 tcg_temp_free_i32(tmp2
);
7376 tcg_temp_free_ptr(fpstatus
);
7379 case NEON_2RM_VABS_F
:
7382 case NEON_2RM_VNEG_F
:
7386 tmp2
= neon_load_reg(rd
, pass
);
7387 neon_store_reg(rm
, pass
, tmp2
);
7390 tmp2
= neon_load_reg(rd
, pass
);
7392 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7393 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7396 neon_store_reg(rm
, pass
, tmp2
);
7398 case NEON_2RM_VRINTN
:
7399 case NEON_2RM_VRINTA
:
7400 case NEON_2RM_VRINTM
:
7401 case NEON_2RM_VRINTP
:
7402 case NEON_2RM_VRINTZ
:
7405 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7408 if (op
== NEON_2RM_VRINTZ
) {
7409 rmode
= FPROUNDING_ZERO
;
7411 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7414 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7415 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7417 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7418 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7420 tcg_temp_free_ptr(fpstatus
);
7421 tcg_temp_free_i32(tcg_rmode
);
7424 case NEON_2RM_VRINTX
:
7426 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7427 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7428 tcg_temp_free_ptr(fpstatus
);
7431 case NEON_2RM_VCVTAU
:
7432 case NEON_2RM_VCVTAS
:
7433 case NEON_2RM_VCVTNU
:
7434 case NEON_2RM_VCVTNS
:
7435 case NEON_2RM_VCVTPU
:
7436 case NEON_2RM_VCVTPS
:
7437 case NEON_2RM_VCVTMU
:
7438 case NEON_2RM_VCVTMS
:
7440 bool is_signed
= !extract32(insn
, 7, 1);
7441 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7442 TCGv_i32 tcg_rmode
, tcg_shift
;
7443 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7445 tcg_shift
= tcg_const_i32(0);
7446 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7447 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7451 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7454 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7458 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7460 tcg_temp_free_i32(tcg_rmode
);
7461 tcg_temp_free_i32(tcg_shift
);
7462 tcg_temp_free_ptr(fpst
);
7465 case NEON_2RM_VRECPE
:
7467 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7468 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7469 tcg_temp_free_ptr(fpstatus
);
7472 case NEON_2RM_VRSQRTE
:
7474 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7475 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7476 tcg_temp_free_ptr(fpstatus
);
7479 case NEON_2RM_VRECPE_F
:
7481 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7482 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7483 tcg_temp_free_ptr(fpstatus
);
7486 case NEON_2RM_VRSQRTE_F
:
7488 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7489 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7490 tcg_temp_free_ptr(fpstatus
);
7493 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7496 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7499 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7500 gen_vfp_tosiz(0, 1);
7502 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7503 gen_vfp_touiz(0, 1);
7506 /* Reserved op values were caught by the
7507 * neon_2rm_sizes[] check earlier.
7511 if (neon_2rm_is_float_op(op
)) {
7512 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7513 neon_reg_offset(rd
, pass
));
7515 neon_store_reg(rd
, pass
, tmp
);
7520 } else if ((insn
& (1 << 10)) == 0) {
7522 int n
= ((insn
>> 8) & 3) + 1;
7523 if ((rn
+ n
) > 32) {
7524 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7525 * helper function running off the end of the register file.
7530 if (insn
& (1 << 6)) {
7531 tmp
= neon_load_reg(rd
, 0);
7533 tmp
= tcg_temp_new_i32();
7534 tcg_gen_movi_i32(tmp
, 0);
7536 tmp2
= neon_load_reg(rm
, 0);
7537 tmp4
= tcg_const_i32(rn
);
7538 tmp5
= tcg_const_i32(n
);
7539 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7540 tcg_temp_free_i32(tmp
);
7541 if (insn
& (1 << 6)) {
7542 tmp
= neon_load_reg(rd
, 1);
7544 tmp
= tcg_temp_new_i32();
7545 tcg_gen_movi_i32(tmp
, 0);
7547 tmp3
= neon_load_reg(rm
, 1);
7548 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7549 tcg_temp_free_i32(tmp5
);
7550 tcg_temp_free_i32(tmp4
);
7551 neon_store_reg(rd
, 0, tmp2
);
7552 neon_store_reg(rd
, 1, tmp3
);
7553 tcg_temp_free_i32(tmp
);
7554 } else if ((insn
& 0x380) == 0) {
7556 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7559 if (insn
& (1 << 19)) {
7560 tmp
= neon_load_reg(rm
, 1);
7562 tmp
= neon_load_reg(rm
, 0);
7564 if (insn
& (1 << 16)) {
7565 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7566 } else if (insn
& (1 << 17)) {
7567 if ((insn
>> 18) & 1)
7568 gen_neon_dup_high16(tmp
);
7570 gen_neon_dup_low16(tmp
);
7572 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7573 tmp2
= tcg_temp_new_i32();
7574 tcg_gen_mov_i32(tmp2
, tmp
);
7575 neon_store_reg(rd
, pass
, tmp2
);
7577 tcg_temp_free_i32(tmp
);
7586 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7588 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7589 const ARMCPRegInfo
*ri
;
7591 cpnum
= (insn
>> 8) & 0xf;
7593 /* First check for coprocessor space used for XScale/iwMMXt insns */
7594 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7595 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7598 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7599 return disas_iwmmxt_insn(s
, insn
);
7600 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7601 return disas_dsp_insn(s
, insn
);
7606 /* Otherwise treat as a generic register access */
7607 is64
= (insn
& (1 << 25)) == 0;
7608 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7616 opc1
= (insn
>> 4) & 0xf;
7618 rt2
= (insn
>> 16) & 0xf;
7620 crn
= (insn
>> 16) & 0xf;
7621 opc1
= (insn
>> 21) & 7;
7622 opc2
= (insn
>> 5) & 7;
7625 isread
= (insn
>> 20) & 1;
7626 rt
= (insn
>> 12) & 0xf;
7628 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7629 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7631 /* Check access permissions */
7632 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7637 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7638 /* Emit code to perform further access permissions checks at
7639 * runtime; this may result in an exception.
7640 * Note that on XScale all cp0..c13 registers do an access check
7641 * call in order to handle c15_cpar.
7644 TCGv_i32 tcg_syn
, tcg_isread
;
7647 /* Note that since we are an implementation which takes an
7648 * exception on a trapped conditional instruction only if the
7649 * instruction passes its condition code check, we can take
7650 * advantage of the clause in the ARM ARM that allows us to set
7651 * the COND field in the instruction to 0xE in all cases.
7652 * We could fish the actual condition out of the insn (ARM)
7653 * or the condexec bits (Thumb) but it isn't necessary.
7658 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7661 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7667 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7670 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7675 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7676 * so this can only happen if this is an ARMv7 or earlier CPU,
7677 * in which case the syndrome information won't actually be
7680 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7681 syndrome
= syn_uncategorized();
7685 gen_set_condexec(s
);
7686 gen_set_pc_im(s
, s
->pc
- 4);
7687 tmpptr
= tcg_const_ptr(ri
);
7688 tcg_syn
= tcg_const_i32(syndrome
);
7689 tcg_isread
= tcg_const_i32(isread
);
7690 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7692 tcg_temp_free_ptr(tmpptr
);
7693 tcg_temp_free_i32(tcg_syn
);
7694 tcg_temp_free_i32(tcg_isread
);
7697 /* Handle special cases first */
7698 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7705 gen_set_pc_im(s
, s
->pc
);
7706 s
->base
.is_jmp
= DISAS_WFI
;
7712 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7721 if (ri
->type
& ARM_CP_CONST
) {
7722 tmp64
= tcg_const_i64(ri
->resetvalue
);
7723 } else if (ri
->readfn
) {
7725 tmp64
= tcg_temp_new_i64();
7726 tmpptr
= tcg_const_ptr(ri
);
7727 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7728 tcg_temp_free_ptr(tmpptr
);
7730 tmp64
= tcg_temp_new_i64();
7731 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7733 tmp
= tcg_temp_new_i32();
7734 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7735 store_reg(s
, rt
, tmp
);
7736 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7737 tmp
= tcg_temp_new_i32();
7738 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7739 tcg_temp_free_i64(tmp64
);
7740 store_reg(s
, rt2
, tmp
);
7743 if (ri
->type
& ARM_CP_CONST
) {
7744 tmp
= tcg_const_i32(ri
->resetvalue
);
7745 } else if (ri
->readfn
) {
7747 tmp
= tcg_temp_new_i32();
7748 tmpptr
= tcg_const_ptr(ri
);
7749 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7750 tcg_temp_free_ptr(tmpptr
);
7752 tmp
= load_cpu_offset(ri
->fieldoffset
);
7755 /* Destination register of r15 for 32 bit loads sets
7756 * the condition codes from the high 4 bits of the value
7759 tcg_temp_free_i32(tmp
);
7761 store_reg(s
, rt
, tmp
);
7766 if (ri
->type
& ARM_CP_CONST
) {
7767 /* If not forbidden by access permissions, treat as WI */
7772 TCGv_i32 tmplo
, tmphi
;
7773 TCGv_i64 tmp64
= tcg_temp_new_i64();
7774 tmplo
= load_reg(s
, rt
);
7775 tmphi
= load_reg(s
, rt2
);
7776 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7777 tcg_temp_free_i32(tmplo
);
7778 tcg_temp_free_i32(tmphi
);
7780 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7781 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7782 tcg_temp_free_ptr(tmpptr
);
7784 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7786 tcg_temp_free_i64(tmp64
);
7791 tmp
= load_reg(s
, rt
);
7792 tmpptr
= tcg_const_ptr(ri
);
7793 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7794 tcg_temp_free_ptr(tmpptr
);
7795 tcg_temp_free_i32(tmp
);
7797 TCGv_i32 tmp
= load_reg(s
, rt
);
7798 store_cpu_offset(tmp
, ri
->fieldoffset
);
7803 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7804 /* I/O operations must end the TB here (whether read or write) */
7807 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7808 /* We default to ending the TB on a coprocessor register write,
7809 * but allow this to be suppressed by the register definition
7810 * (usually only necessary to work around guest bugs).
7818 /* Unknown register; this might be a guest error or a QEMU
7819 * unimplemented feature.
7822 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7823 "64 bit system register cp:%d opc1: %d crm:%d "
7825 isread
? "read" : "write", cpnum
, opc1
, crm
,
7826 s
->ns
? "non-secure" : "secure");
7828 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7829 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7831 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7832 s
->ns
? "non-secure" : "secure");
7839 /* Store a 64-bit value to a register pair. Clobbers val. */
7840 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7843 tmp
= tcg_temp_new_i32();
7844 tcg_gen_extrl_i64_i32(tmp
, val
);
7845 store_reg(s
, rlow
, tmp
);
7846 tmp
= tcg_temp_new_i32();
7847 tcg_gen_shri_i64(val
, val
, 32);
7848 tcg_gen_extrl_i64_i32(tmp
, val
);
7849 store_reg(s
, rhigh
, tmp
);
7852 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7853 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7858 /* Load value and extend to 64 bits. */
7859 tmp
= tcg_temp_new_i64();
7860 tmp2
= load_reg(s
, rlow
);
7861 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7862 tcg_temp_free_i32(tmp2
);
7863 tcg_gen_add_i64(val
, val
, tmp
);
7864 tcg_temp_free_i64(tmp
);
7867 /* load and add a 64-bit value from a register pair. */
7868 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7874 /* Load 64-bit value rd:rn. */
7875 tmpl
= load_reg(s
, rlow
);
7876 tmph
= load_reg(s
, rhigh
);
7877 tmp
= tcg_temp_new_i64();
7878 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7879 tcg_temp_free_i32(tmpl
);
7880 tcg_temp_free_i32(tmph
);
7881 tcg_gen_add_i64(val
, val
, tmp
);
7882 tcg_temp_free_i64(tmp
);
7885 /* Set N and Z flags from hi|lo. */
7886 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7888 tcg_gen_mov_i32(cpu_NF
, hi
);
7889 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7892 /* Load/Store exclusive instructions are implemented by remembering
7893 the value/address loaded, and seeing if these are the same
7894 when the store is performed. This should be sufficient to implement
7895 the architecturally mandated semantics, and avoids having to monitor
7896 regular stores. The compare vs the remembered value is done during
7897 the cmpxchg operation, but we must compare the addresses manually. */
7898 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7899 TCGv_i32 addr
, int size
)
7901 TCGv_i32 tmp
= tcg_temp_new_i32();
7902 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7907 TCGv_i32 tmp2
= tcg_temp_new_i32();
7908 TCGv_i64 t64
= tcg_temp_new_i64();
7910 /* For AArch32, architecturally the 32-bit word at the lowest
7911 * address is always Rt and the one at addr+4 is Rt2, even if
7912 * the CPU is big-endian. That means we don't want to do a
7913 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7914 * for an architecturally 64-bit access, but instead do a
7915 * 64-bit access using MO_BE if appropriate and then split
7917 * This only makes a difference for BE32 user-mode, where
7918 * frob64() must not flip the two halves of the 64-bit data
7919 * but this code must treat BE32 user-mode like BE32 system.
7921 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
7923 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
7924 tcg_temp_free(taddr
);
7925 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
7926 if (s
->be_data
== MO_BE
) {
7927 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
7929 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
7931 tcg_temp_free_i64(t64
);
7933 store_reg(s
, rt2
, tmp2
);
7935 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
7936 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7939 store_reg(s
, rt
, tmp
);
7940 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7943 static void gen_clrex(DisasContext
*s
)
7945 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7948 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7949 TCGv_i32 addr
, int size
)
7951 TCGv_i32 t0
, t1
, t2
;
7954 TCGLabel
*done_label
;
7955 TCGLabel
*fail_label
;
7956 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7958 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7964 fail_label
= gen_new_label();
7965 done_label
= gen_new_label();
7966 extaddr
= tcg_temp_new_i64();
7967 tcg_gen_extu_i32_i64(extaddr
, addr
);
7968 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7969 tcg_temp_free_i64(extaddr
);
7971 taddr
= gen_aa32_addr(s
, addr
, opc
);
7972 t0
= tcg_temp_new_i32();
7973 t1
= load_reg(s
, rt
);
7975 TCGv_i64 o64
= tcg_temp_new_i64();
7976 TCGv_i64 n64
= tcg_temp_new_i64();
7978 t2
= load_reg(s
, rt2
);
7979 /* For AArch32, architecturally the 32-bit word at the lowest
7980 * address is always Rt and the one at addr+4 is Rt2, even if
7981 * the CPU is big-endian. Since we're going to treat this as a
7982 * single 64-bit BE store, we need to put the two halves in the
7983 * opposite order for BE to LE, so that they end up in the right
7985 * We don't want gen_aa32_frob64() because that does the wrong
7986 * thing for BE32 usermode.
7988 if (s
->be_data
== MO_BE
) {
7989 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
7991 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
7993 tcg_temp_free_i32(t2
);
7995 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
7996 get_mem_index(s
), opc
);
7997 tcg_temp_free_i64(n64
);
7999 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
8000 tcg_gen_extrl_i64_i32(t0
, o64
);
8002 tcg_temp_free_i64(o64
);
8004 t2
= tcg_temp_new_i32();
8005 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
8006 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
8007 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
8008 tcg_temp_free_i32(t2
);
8010 tcg_temp_free_i32(t1
);
8011 tcg_temp_free(taddr
);
8012 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
8013 tcg_temp_free_i32(t0
);
8014 tcg_gen_br(done_label
);
8016 gen_set_label(fail_label
);
8017 tcg_gen_movi_i32(cpu_R
[rd
], 1);
8018 gen_set_label(done_label
);
8019 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8025 * @mode: mode field from insn (which stack to store to)
8026 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8027 * @writeback: true if writeback bit set
8029 * Generate code for the SRS (Store Return State) insn.
8031 static void gen_srs(DisasContext
*s
,
8032 uint32_t mode
, uint32_t amode
, bool writeback
)
8039 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8040 * and specified mode is monitor mode
8041 * - UNDEFINED in Hyp mode
8042 * - UNPREDICTABLE in User or System mode
8043 * - UNPREDICTABLE if the specified mode is:
8044 * -- not implemented
8045 * -- not a valid mode number
8046 * -- a mode that's at a higher exception level
8047 * -- Monitor, if we are Non-secure
8048 * For the UNPREDICTABLE cases we choose to UNDEF.
8050 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
8051 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
8055 if (s
->current_el
== 0 || s
->current_el
== 2) {
8060 case ARM_CPU_MODE_USR
:
8061 case ARM_CPU_MODE_FIQ
:
8062 case ARM_CPU_MODE_IRQ
:
8063 case ARM_CPU_MODE_SVC
:
8064 case ARM_CPU_MODE_ABT
:
8065 case ARM_CPU_MODE_UND
:
8066 case ARM_CPU_MODE_SYS
:
8068 case ARM_CPU_MODE_HYP
:
8069 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
8073 case ARM_CPU_MODE_MON
:
8074 /* No need to check specifically for "are we non-secure" because
8075 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8076 * so if this isn't EL3 then we must be non-secure.
8078 if (s
->current_el
!= 3) {
8087 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8088 default_exception_el(s
));
8092 addr
= tcg_temp_new_i32();
8093 tmp
= tcg_const_i32(mode
);
8094 /* get_r13_banked() will raise an exception if called from System mode */
8095 gen_set_condexec(s
);
8096 gen_set_pc_im(s
, s
->pc
- 4);
8097 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8098 tcg_temp_free_i32(tmp
);
8115 tcg_gen_addi_i32(addr
, addr
, offset
);
8116 tmp
= load_reg(s
, 14);
8117 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8118 tcg_temp_free_i32(tmp
);
8119 tmp
= load_cpu_field(spsr
);
8120 tcg_gen_addi_i32(addr
, addr
, 4);
8121 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8122 tcg_temp_free_i32(tmp
);
8140 tcg_gen_addi_i32(addr
, addr
, offset
);
8141 tmp
= tcg_const_i32(mode
);
8142 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8143 tcg_temp_free_i32(tmp
);
8145 tcg_temp_free_i32(addr
);
8146 s
->base
.is_jmp
= DISAS_UPDATE
;
8149 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8151 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8158 /* M variants do not implement ARM mode; this must raise the INVSTATE
8159 * UsageFault exception.
8161 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8162 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8163 default_exception_el(s
));
8168 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8169 * choose to UNDEF. In ARMv5 and above the space is used
8170 * for miscellaneous unconditional instructions.
8174 /* Unconditional instructions. */
8175 if (((insn
>> 25) & 7) == 1) {
8176 /* NEON Data processing. */
8177 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8181 if (disas_neon_data_insn(s
, insn
)) {
8186 if ((insn
& 0x0f100000) == 0x04000000) {
8187 /* NEON load/store. */
8188 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8192 if (disas_neon_ls_insn(s
, insn
)) {
8197 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8199 if (disas_vfp_insn(s
, insn
)) {
8204 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8205 ((insn
& 0x0f30f010) == 0x0710f000)) {
8206 if ((insn
& (1 << 22)) == 0) {
8208 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8212 /* Otherwise PLD; v5TE+ */
8216 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8217 ((insn
& 0x0f70f010) == 0x0650f000)) {
8219 return; /* PLI; V7 */
8221 if (((insn
& 0x0f700000) == 0x04100000) ||
8222 ((insn
& 0x0f700010) == 0x06100000)) {
8223 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8226 return; /* v7MP: Unallocated memory hint: must NOP */
8229 if ((insn
& 0x0ffffdff) == 0x01010000) {
8232 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8233 gen_helper_setend(cpu_env
);
8234 s
->base
.is_jmp
= DISAS_UPDATE
;
8237 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8238 switch ((insn
>> 4) & 0xf) {
8246 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8249 /* We need to break the TB after this insn to execute
8250 * self-modifying code correctly and also to take
8251 * any pending interrupts immediately.
8253 gen_goto_tb(s
, 0, s
->pc
& ~1);
8258 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8261 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8263 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8269 rn
= (insn
>> 16) & 0xf;
8270 addr
= load_reg(s
, rn
);
8271 i
= (insn
>> 23) & 3;
8273 case 0: offset
= -4; break; /* DA */
8274 case 1: offset
= 0; break; /* IA */
8275 case 2: offset
= -8; break; /* DB */
8276 case 3: offset
= 4; break; /* IB */
8280 tcg_gen_addi_i32(addr
, addr
, offset
);
8281 /* Load PC into tmp and CPSR into tmp2. */
8282 tmp
= tcg_temp_new_i32();
8283 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8284 tcg_gen_addi_i32(addr
, addr
, 4);
8285 tmp2
= tcg_temp_new_i32();
8286 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8287 if (insn
& (1 << 21)) {
8288 /* Base writeback. */
8290 case 0: offset
= -8; break;
8291 case 1: offset
= 4; break;
8292 case 2: offset
= -4; break;
8293 case 3: offset
= 0; break;
8297 tcg_gen_addi_i32(addr
, addr
, offset
);
8298 store_reg(s
, rn
, addr
);
8300 tcg_temp_free_i32(addr
);
8302 gen_rfe(s
, tmp
, tmp2
);
8304 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8305 /* branch link and change to thumb (blx <offset>) */
8308 val
= (uint32_t)s
->pc
;
8309 tmp
= tcg_temp_new_i32();
8310 tcg_gen_movi_i32(tmp
, val
);
8311 store_reg(s
, 14, tmp
);
8312 /* Sign-extend the 24-bit offset */
8313 offset
= (((int32_t)insn
) << 8) >> 8;
8314 /* offset * 4 + bit24 * 2 + (thumb bit) */
8315 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8316 /* pipeline offset */
8318 /* protected by ARCH(5); above, near the start of uncond block */
8321 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8322 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8323 /* iWMMXt register transfer. */
8324 if (extract32(s
->c15_cpar
, 1, 1)) {
8325 if (!disas_iwmmxt_insn(s
, insn
)) {
8330 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8331 /* Coprocessor double register transfer. */
8333 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8334 /* Additional coprocessor register transfer. */
8335 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8338 /* cps (privileged) */
8342 if (insn
& (1 << 19)) {
8343 if (insn
& (1 << 8))
8345 if (insn
& (1 << 7))
8347 if (insn
& (1 << 6))
8349 if (insn
& (1 << 18))
8352 if (insn
& (1 << 17)) {
8354 val
|= (insn
& 0x1f);
8357 gen_set_psr_im(s
, mask
, 0, val
);
8364 /* if not always execute, we generate a conditional jump to
8366 s
->condlabel
= gen_new_label();
8367 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8370 if ((insn
& 0x0f900000) == 0x03000000) {
8371 if ((insn
& (1 << 21)) == 0) {
8373 rd
= (insn
>> 12) & 0xf;
8374 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8375 if ((insn
& (1 << 22)) == 0) {
8377 tmp
= tcg_temp_new_i32();
8378 tcg_gen_movi_i32(tmp
, val
);
8381 tmp
= load_reg(s
, rd
);
8382 tcg_gen_ext16u_i32(tmp
, tmp
);
8383 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8385 store_reg(s
, rd
, tmp
);
8387 if (((insn
>> 12) & 0xf) != 0xf)
8389 if (((insn
>> 16) & 0xf) == 0) {
8390 gen_nop_hint(s
, insn
& 0xff);
8392 /* CPSR = immediate */
8394 shift
= ((insn
>> 8) & 0xf) * 2;
8396 val
= (val
>> shift
) | (val
<< (32 - shift
));
8397 i
= ((insn
& (1 << 22)) != 0);
8398 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8404 } else if ((insn
& 0x0f900000) == 0x01000000
8405 && (insn
& 0x00000090) != 0x00000090) {
8406 /* miscellaneous instructions */
8407 op1
= (insn
>> 21) & 3;
8408 sh
= (insn
>> 4) & 0xf;
8411 case 0x0: /* MSR, MRS */
8412 if (insn
& (1 << 9)) {
8413 /* MSR (banked) and MRS (banked) */
8414 int sysm
= extract32(insn
, 16, 4) |
8415 (extract32(insn
, 8, 1) << 4);
8416 int r
= extract32(insn
, 22, 1);
8420 gen_msr_banked(s
, r
, sysm
, rm
);
8423 int rd
= extract32(insn
, 12, 4);
8425 gen_mrs_banked(s
, r
, sysm
, rd
);
8430 /* MSR, MRS (for PSRs) */
8433 tmp
= load_reg(s
, rm
);
8434 i
= ((op1
& 2) != 0);
8435 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8439 rd
= (insn
>> 12) & 0xf;
8443 tmp
= load_cpu_field(spsr
);
8445 tmp
= tcg_temp_new_i32();
8446 gen_helper_cpsr_read(tmp
, cpu_env
);
8448 store_reg(s
, rd
, tmp
);
8453 /* branch/exchange thumb (bx). */
8455 tmp
= load_reg(s
, rm
);
8457 } else if (op1
== 3) {
8460 rd
= (insn
>> 12) & 0xf;
8461 tmp
= load_reg(s
, rm
);
8462 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8463 store_reg(s
, rd
, tmp
);
8471 /* Trivial implementation equivalent to bx. */
8472 tmp
= load_reg(s
, rm
);
8483 /* branch link/exchange thumb (blx) */
8484 tmp
= load_reg(s
, rm
);
8485 tmp2
= tcg_temp_new_i32();
8486 tcg_gen_movi_i32(tmp2
, s
->pc
);
8487 store_reg(s
, 14, tmp2
);
8493 uint32_t c
= extract32(insn
, 8, 4);
8495 /* Check this CPU supports ARMv8 CRC instructions.
8496 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8497 * Bits 8, 10 and 11 should be zero.
8499 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8504 rn
= extract32(insn
, 16, 4);
8505 rd
= extract32(insn
, 12, 4);
8507 tmp
= load_reg(s
, rn
);
8508 tmp2
= load_reg(s
, rm
);
8510 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8511 } else if (op1
== 1) {
8512 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8514 tmp3
= tcg_const_i32(1 << op1
);
8516 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8518 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8520 tcg_temp_free_i32(tmp2
);
8521 tcg_temp_free_i32(tmp3
);
8522 store_reg(s
, rd
, tmp
);
8525 case 0x5: /* saturating add/subtract */
8527 rd
= (insn
>> 12) & 0xf;
8528 rn
= (insn
>> 16) & 0xf;
8529 tmp
= load_reg(s
, rm
);
8530 tmp2
= load_reg(s
, rn
);
8532 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8534 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8536 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8537 tcg_temp_free_i32(tmp2
);
8538 store_reg(s
, rd
, tmp
);
8542 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8551 gen_exception_insn(s
, 4, EXCP_BKPT
,
8552 syn_aa32_bkpt(imm16
, false),
8553 default_exception_el(s
));
8556 /* Hypervisor call (v7) */
8564 /* Secure monitor call (v6+) */
8572 g_assert_not_reached();
8576 case 0x8: /* signed multiply */
8581 rs
= (insn
>> 8) & 0xf;
8582 rn
= (insn
>> 12) & 0xf;
8583 rd
= (insn
>> 16) & 0xf;
8585 /* (32 * 16) >> 16 */
8586 tmp
= load_reg(s
, rm
);
8587 tmp2
= load_reg(s
, rs
);
8589 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8592 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8593 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8594 tmp
= tcg_temp_new_i32();
8595 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8596 tcg_temp_free_i64(tmp64
);
8597 if ((sh
& 2) == 0) {
8598 tmp2
= load_reg(s
, rn
);
8599 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8600 tcg_temp_free_i32(tmp2
);
8602 store_reg(s
, rd
, tmp
);
8605 tmp
= load_reg(s
, rm
);
8606 tmp2
= load_reg(s
, rs
);
8607 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8608 tcg_temp_free_i32(tmp2
);
8610 tmp64
= tcg_temp_new_i64();
8611 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8612 tcg_temp_free_i32(tmp
);
8613 gen_addq(s
, tmp64
, rn
, rd
);
8614 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8615 tcg_temp_free_i64(tmp64
);
8618 tmp2
= load_reg(s
, rn
);
8619 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8620 tcg_temp_free_i32(tmp2
);
8622 store_reg(s
, rd
, tmp
);
8629 } else if (((insn
& 0x0e000000) == 0 &&
8630 (insn
& 0x00000090) != 0x90) ||
8631 ((insn
& 0x0e000000) == (1 << 25))) {
8632 int set_cc
, logic_cc
, shiftop
;
8634 op1
= (insn
>> 21) & 0xf;
8635 set_cc
= (insn
>> 20) & 1;
8636 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8638 /* data processing instruction */
8639 if (insn
& (1 << 25)) {
8640 /* immediate operand */
8642 shift
= ((insn
>> 8) & 0xf) * 2;
8644 val
= (val
>> shift
) | (val
<< (32 - shift
));
8646 tmp2
= tcg_temp_new_i32();
8647 tcg_gen_movi_i32(tmp2
, val
);
8648 if (logic_cc
&& shift
) {
8649 gen_set_CF_bit31(tmp2
);
8654 tmp2
= load_reg(s
, rm
);
8655 shiftop
= (insn
>> 5) & 3;
8656 if (!(insn
& (1 << 4))) {
8657 shift
= (insn
>> 7) & 0x1f;
8658 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8660 rs
= (insn
>> 8) & 0xf;
8661 tmp
= load_reg(s
, rs
);
8662 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8665 if (op1
!= 0x0f && op1
!= 0x0d) {
8666 rn
= (insn
>> 16) & 0xf;
8667 tmp
= load_reg(s
, rn
);
8671 rd
= (insn
>> 12) & 0xf;
8674 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8678 store_reg_bx(s
, rd
, tmp
);
8681 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8685 store_reg_bx(s
, rd
, tmp
);
8688 if (set_cc
&& rd
== 15) {
8689 /* SUBS r15, ... is used for exception return. */
8693 gen_sub_CC(tmp
, tmp
, tmp2
);
8694 gen_exception_return(s
, tmp
);
8697 gen_sub_CC(tmp
, tmp
, tmp2
);
8699 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8701 store_reg_bx(s
, rd
, tmp
);
8706 gen_sub_CC(tmp
, tmp2
, tmp
);
8708 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8710 store_reg_bx(s
, rd
, tmp
);
8714 gen_add_CC(tmp
, tmp
, tmp2
);
8716 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8718 store_reg_bx(s
, rd
, tmp
);
8722 gen_adc_CC(tmp
, tmp
, tmp2
);
8724 gen_add_carry(tmp
, tmp
, tmp2
);
8726 store_reg_bx(s
, rd
, tmp
);
8730 gen_sbc_CC(tmp
, tmp
, tmp2
);
8732 gen_sub_carry(tmp
, tmp
, tmp2
);
8734 store_reg_bx(s
, rd
, tmp
);
8738 gen_sbc_CC(tmp
, tmp2
, tmp
);
8740 gen_sub_carry(tmp
, tmp2
, tmp
);
8742 store_reg_bx(s
, rd
, tmp
);
8746 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8749 tcg_temp_free_i32(tmp
);
8753 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8756 tcg_temp_free_i32(tmp
);
8760 gen_sub_CC(tmp
, tmp
, tmp2
);
8762 tcg_temp_free_i32(tmp
);
8766 gen_add_CC(tmp
, tmp
, tmp2
);
8768 tcg_temp_free_i32(tmp
);
8771 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8775 store_reg_bx(s
, rd
, tmp
);
8778 if (logic_cc
&& rd
== 15) {
8779 /* MOVS r15, ... is used for exception return. */
8783 gen_exception_return(s
, tmp2
);
8788 store_reg_bx(s
, rd
, tmp2
);
8792 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8796 store_reg_bx(s
, rd
, tmp
);
8800 tcg_gen_not_i32(tmp2
, tmp2
);
8804 store_reg_bx(s
, rd
, tmp2
);
8807 if (op1
!= 0x0f && op1
!= 0x0d) {
8808 tcg_temp_free_i32(tmp2
);
8811 /* other instructions */
8812 op1
= (insn
>> 24) & 0xf;
8816 /* multiplies, extra load/stores */
8817 sh
= (insn
>> 5) & 3;
8820 rd
= (insn
>> 16) & 0xf;
8821 rn
= (insn
>> 12) & 0xf;
8822 rs
= (insn
>> 8) & 0xf;
8824 op1
= (insn
>> 20) & 0xf;
8826 case 0: case 1: case 2: case 3: case 6:
8828 tmp
= load_reg(s
, rs
);
8829 tmp2
= load_reg(s
, rm
);
8830 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8831 tcg_temp_free_i32(tmp2
);
8832 if (insn
& (1 << 22)) {
8833 /* Subtract (mls) */
8835 tmp2
= load_reg(s
, rn
);
8836 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8837 tcg_temp_free_i32(tmp2
);
8838 } else if (insn
& (1 << 21)) {
8840 tmp2
= load_reg(s
, rn
);
8841 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8842 tcg_temp_free_i32(tmp2
);
8844 if (insn
& (1 << 20))
8846 store_reg(s
, rd
, tmp
);
8849 /* 64 bit mul double accumulate (UMAAL) */
8851 tmp
= load_reg(s
, rs
);
8852 tmp2
= load_reg(s
, rm
);
8853 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8854 gen_addq_lo(s
, tmp64
, rn
);
8855 gen_addq_lo(s
, tmp64
, rd
);
8856 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8857 tcg_temp_free_i64(tmp64
);
8859 case 8: case 9: case 10: case 11:
8860 case 12: case 13: case 14: case 15:
8861 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8862 tmp
= load_reg(s
, rs
);
8863 tmp2
= load_reg(s
, rm
);
8864 if (insn
& (1 << 22)) {
8865 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8867 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8869 if (insn
& (1 << 21)) { /* mult accumulate */
8870 TCGv_i32 al
= load_reg(s
, rn
);
8871 TCGv_i32 ah
= load_reg(s
, rd
);
8872 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8873 tcg_temp_free_i32(al
);
8874 tcg_temp_free_i32(ah
);
8876 if (insn
& (1 << 20)) {
8877 gen_logicq_cc(tmp
, tmp2
);
8879 store_reg(s
, rn
, tmp
);
8880 store_reg(s
, rd
, tmp2
);
8886 rn
= (insn
>> 16) & 0xf;
8887 rd
= (insn
>> 12) & 0xf;
8888 if (insn
& (1 << 23)) {
8889 /* load/store exclusive */
8890 int op2
= (insn
>> 8) & 3;
8891 op1
= (insn
>> 21) & 0x3;
8894 case 0: /* lda/stl */
8900 case 1: /* reserved */
8902 case 2: /* ldaex/stlex */
8905 case 3: /* ldrex/strex */
8914 addr
= tcg_temp_local_new_i32();
8915 load_reg_var(s
, addr
, rn
);
8917 /* Since the emulation does not have barriers,
8918 the acquire/release semantics need no special
8921 if (insn
& (1 << 20)) {
8922 tmp
= tcg_temp_new_i32();
8925 gen_aa32_ld32u_iss(s
, tmp
, addr
,
8930 gen_aa32_ld8u_iss(s
, tmp
, addr
,
8935 gen_aa32_ld16u_iss(s
, tmp
, addr
,
8942 store_reg(s
, rd
, tmp
);
8945 tmp
= load_reg(s
, rm
);
8948 gen_aa32_st32_iss(s
, tmp
, addr
,
8953 gen_aa32_st8_iss(s
, tmp
, addr
,
8958 gen_aa32_st16_iss(s
, tmp
, addr
,
8965 tcg_temp_free_i32(tmp
);
8967 } else if (insn
& (1 << 20)) {
8970 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8972 case 1: /* ldrexd */
8973 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8975 case 2: /* ldrexb */
8976 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8978 case 3: /* ldrexh */
8979 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8988 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8990 case 1: /* strexd */
8991 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8993 case 2: /* strexb */
8994 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8996 case 3: /* strexh */
8997 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
9003 tcg_temp_free_i32(addr
);
9006 TCGMemOp opc
= s
->be_data
;
9008 /* SWP instruction */
9011 if (insn
& (1 << 22)) {
9014 opc
|= MO_UL
| MO_ALIGN
;
9017 addr
= load_reg(s
, rn
);
9018 taddr
= gen_aa32_addr(s
, addr
, opc
);
9019 tcg_temp_free_i32(addr
);
9021 tmp
= load_reg(s
, rm
);
9022 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
9023 get_mem_index(s
), opc
);
9024 tcg_temp_free(taddr
);
9025 store_reg(s
, rd
, tmp
);
9030 bool load
= insn
& (1 << 20);
9031 bool wbit
= insn
& (1 << 21);
9032 bool pbit
= insn
& (1 << 24);
9033 bool doubleword
= false;
9036 /* Misc load/store */
9037 rn
= (insn
>> 16) & 0xf;
9038 rd
= (insn
>> 12) & 0xf;
9040 /* ISS not valid if writeback */
9041 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
9043 if (!load
&& (sh
& 2)) {
9047 /* UNPREDICTABLE; we choose to UNDEF */
9050 load
= (sh
& 1) == 0;
9054 addr
= load_reg(s
, rn
);
9056 gen_add_datah_offset(s
, insn
, 0, addr
);
9063 tmp
= load_reg(s
, rd
);
9064 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9065 tcg_temp_free_i32(tmp
);
9066 tcg_gen_addi_i32(addr
, addr
, 4);
9067 tmp
= load_reg(s
, rd
+ 1);
9068 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9069 tcg_temp_free_i32(tmp
);
9072 tmp
= tcg_temp_new_i32();
9073 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9074 store_reg(s
, rd
, tmp
);
9075 tcg_gen_addi_i32(addr
, addr
, 4);
9076 tmp
= tcg_temp_new_i32();
9077 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9080 address_offset
= -4;
9083 tmp
= tcg_temp_new_i32();
9086 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9090 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9095 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9101 tmp
= load_reg(s
, rd
);
9102 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9103 tcg_temp_free_i32(tmp
);
9105 /* Perform base writeback before the loaded value to
9106 ensure correct behavior with overlapping index registers.
9107 ldrd with base writeback is undefined if the
9108 destination and index registers overlap. */
9110 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9111 store_reg(s
, rn
, addr
);
9114 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9115 store_reg(s
, rn
, addr
);
9117 tcg_temp_free_i32(addr
);
9120 /* Complete the load. */
9121 store_reg(s
, rd
, tmp
);
9130 if (insn
& (1 << 4)) {
9132 /* Armv6 Media instructions. */
9134 rn
= (insn
>> 16) & 0xf;
9135 rd
= (insn
>> 12) & 0xf;
9136 rs
= (insn
>> 8) & 0xf;
9137 switch ((insn
>> 23) & 3) {
9138 case 0: /* Parallel add/subtract. */
9139 op1
= (insn
>> 20) & 7;
9140 tmp
= load_reg(s
, rn
);
9141 tmp2
= load_reg(s
, rm
);
9142 sh
= (insn
>> 5) & 7;
9143 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9145 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9146 tcg_temp_free_i32(tmp2
);
9147 store_reg(s
, rd
, tmp
);
9150 if ((insn
& 0x00700020) == 0) {
9151 /* Halfword pack. */
9152 tmp
= load_reg(s
, rn
);
9153 tmp2
= load_reg(s
, rm
);
9154 shift
= (insn
>> 7) & 0x1f;
9155 if (insn
& (1 << 6)) {
9159 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9160 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9161 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9165 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9166 tcg_gen_ext16u_i32(tmp
, tmp
);
9167 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9169 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9170 tcg_temp_free_i32(tmp2
);
9171 store_reg(s
, rd
, tmp
);
9172 } else if ((insn
& 0x00200020) == 0x00200000) {
9174 tmp
= load_reg(s
, rm
);
9175 shift
= (insn
>> 7) & 0x1f;
9176 if (insn
& (1 << 6)) {
9179 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9181 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9183 sh
= (insn
>> 16) & 0x1f;
9184 tmp2
= tcg_const_i32(sh
);
9185 if (insn
& (1 << 22))
9186 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9188 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9189 tcg_temp_free_i32(tmp2
);
9190 store_reg(s
, rd
, tmp
);
9191 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9193 tmp
= load_reg(s
, rm
);
9194 sh
= (insn
>> 16) & 0x1f;
9195 tmp2
= tcg_const_i32(sh
);
9196 if (insn
& (1 << 22))
9197 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9199 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9200 tcg_temp_free_i32(tmp2
);
9201 store_reg(s
, rd
, tmp
);
9202 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9204 tmp
= load_reg(s
, rn
);
9205 tmp2
= load_reg(s
, rm
);
9206 tmp3
= tcg_temp_new_i32();
9207 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9208 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9209 tcg_temp_free_i32(tmp3
);
9210 tcg_temp_free_i32(tmp2
);
9211 store_reg(s
, rd
, tmp
);
9212 } else if ((insn
& 0x000003e0) == 0x00000060) {
9213 tmp
= load_reg(s
, rm
);
9214 shift
= (insn
>> 10) & 3;
9215 /* ??? In many cases it's not necessary to do a
9216 rotate, a shift is sufficient. */
9218 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9219 op1
= (insn
>> 20) & 7;
9221 case 0: gen_sxtb16(tmp
); break;
9222 case 2: gen_sxtb(tmp
); break;
9223 case 3: gen_sxth(tmp
); break;
9224 case 4: gen_uxtb16(tmp
); break;
9225 case 6: gen_uxtb(tmp
); break;
9226 case 7: gen_uxth(tmp
); break;
9227 default: goto illegal_op
;
9230 tmp2
= load_reg(s
, rn
);
9231 if ((op1
& 3) == 0) {
9232 gen_add16(tmp
, tmp2
);
9234 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9235 tcg_temp_free_i32(tmp2
);
9238 store_reg(s
, rd
, tmp
);
9239 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9241 tmp
= load_reg(s
, rm
);
9242 if (insn
& (1 << 22)) {
9243 if (insn
& (1 << 7)) {
9247 gen_helper_rbit(tmp
, tmp
);
9250 if (insn
& (1 << 7))
9253 tcg_gen_bswap32_i32(tmp
, tmp
);
9255 store_reg(s
, rd
, tmp
);
9260 case 2: /* Multiplies (Type 3). */
9261 switch ((insn
>> 20) & 0x7) {
9263 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9264 /* op2 not 00x or 11x : UNDEF */
9267 /* Signed multiply most significant [accumulate].
9268 (SMMUL, SMMLA, SMMLS) */
9269 tmp
= load_reg(s
, rm
);
9270 tmp2
= load_reg(s
, rs
);
9271 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9274 tmp
= load_reg(s
, rd
);
9275 if (insn
& (1 << 6)) {
9276 tmp64
= gen_subq_msw(tmp64
, tmp
);
9278 tmp64
= gen_addq_msw(tmp64
, tmp
);
9281 if (insn
& (1 << 5)) {
9282 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9284 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9285 tmp
= tcg_temp_new_i32();
9286 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9287 tcg_temp_free_i64(tmp64
);
9288 store_reg(s
, rn
, tmp
);
9292 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9293 if (insn
& (1 << 7)) {
9296 tmp
= load_reg(s
, rm
);
9297 tmp2
= load_reg(s
, rs
);
9298 if (insn
& (1 << 5))
9299 gen_swap_half(tmp2
);
9300 gen_smul_dual(tmp
, tmp2
);
9301 if (insn
& (1 << 22)) {
9302 /* smlald, smlsld */
9305 tmp64
= tcg_temp_new_i64();
9306 tmp64_2
= tcg_temp_new_i64();
9307 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9308 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9309 tcg_temp_free_i32(tmp
);
9310 tcg_temp_free_i32(tmp2
);
9311 if (insn
& (1 << 6)) {
9312 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9314 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9316 tcg_temp_free_i64(tmp64_2
);
9317 gen_addq(s
, tmp64
, rd
, rn
);
9318 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9319 tcg_temp_free_i64(tmp64
);
9321 /* smuad, smusd, smlad, smlsd */
9322 if (insn
& (1 << 6)) {
9323 /* This subtraction cannot overflow. */
9324 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9326 /* This addition cannot overflow 32 bits;
9327 * however it may overflow considered as a
9328 * signed operation, in which case we must set
9331 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9333 tcg_temp_free_i32(tmp2
);
9336 tmp2
= load_reg(s
, rd
);
9337 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9338 tcg_temp_free_i32(tmp2
);
9340 store_reg(s
, rn
, tmp
);
9346 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9349 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9352 tmp
= load_reg(s
, rm
);
9353 tmp2
= load_reg(s
, rs
);
9354 if (insn
& (1 << 21)) {
9355 gen_helper_udiv(tmp
, tmp
, tmp2
);
9357 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9359 tcg_temp_free_i32(tmp2
);
9360 store_reg(s
, rn
, tmp
);
9367 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9369 case 0: /* Unsigned sum of absolute differences. */
9371 tmp
= load_reg(s
, rm
);
9372 tmp2
= load_reg(s
, rs
);
9373 gen_helper_usad8(tmp
, tmp
, tmp2
);
9374 tcg_temp_free_i32(tmp2
);
9376 tmp2
= load_reg(s
, rd
);
9377 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9378 tcg_temp_free_i32(tmp2
);
9380 store_reg(s
, rn
, tmp
);
9382 case 0x20: case 0x24: case 0x28: case 0x2c:
9383 /* Bitfield insert/clear. */
9385 shift
= (insn
>> 7) & 0x1f;
9386 i
= (insn
>> 16) & 0x1f;
9388 /* UNPREDICTABLE; we choose to UNDEF */
9393 tmp
= tcg_temp_new_i32();
9394 tcg_gen_movi_i32(tmp
, 0);
9396 tmp
= load_reg(s
, rm
);
9399 tmp2
= load_reg(s
, rd
);
9400 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9401 tcg_temp_free_i32(tmp2
);
9403 store_reg(s
, rd
, tmp
);
9405 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9406 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9408 tmp
= load_reg(s
, rm
);
9409 shift
= (insn
>> 7) & 0x1f;
9410 i
= ((insn
>> 16) & 0x1f) + 1;
9415 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9417 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9420 store_reg(s
, rd
, tmp
);
9430 /* Check for undefined extension instructions
9431 * per the ARM Bible IE:
9432 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9434 sh
= (0xf << 20) | (0xf << 4);
9435 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9439 /* load/store byte/word */
9440 rn
= (insn
>> 16) & 0xf;
9441 rd
= (insn
>> 12) & 0xf;
9442 tmp2
= load_reg(s
, rn
);
9443 if ((insn
& 0x01200000) == 0x00200000) {
9445 i
= get_a32_user_mem_index(s
);
9447 i
= get_mem_index(s
);
9449 if (insn
& (1 << 24))
9450 gen_add_data_offset(s
, insn
, tmp2
);
9451 if (insn
& (1 << 20)) {
9453 tmp
= tcg_temp_new_i32();
9454 if (insn
& (1 << 22)) {
9455 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9457 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9461 tmp
= load_reg(s
, rd
);
9462 if (insn
& (1 << 22)) {
9463 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9465 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9467 tcg_temp_free_i32(tmp
);
9469 if (!(insn
& (1 << 24))) {
9470 gen_add_data_offset(s
, insn
, tmp2
);
9471 store_reg(s
, rn
, tmp2
);
9472 } else if (insn
& (1 << 21)) {
9473 store_reg(s
, rn
, tmp2
);
9475 tcg_temp_free_i32(tmp2
);
9477 if (insn
& (1 << 20)) {
9478 /* Complete the load. */
9479 store_reg_from_load(s
, rd
, tmp
);
9485 int j
, n
, loaded_base
;
9486 bool exc_return
= false;
9487 bool is_load
= extract32(insn
, 20, 1);
9489 TCGv_i32 loaded_var
;
9490 /* load/store multiple words */
9491 /* XXX: store correct base if write back */
9492 if (insn
& (1 << 22)) {
9493 /* LDM (user), LDM (exception return) and STM (user) */
9495 goto illegal_op
; /* only usable in supervisor mode */
9497 if (is_load
&& extract32(insn
, 15, 1)) {
9503 rn
= (insn
>> 16) & 0xf;
9504 addr
= load_reg(s
, rn
);
9506 /* compute total size */
9511 if (insn
& (1 << i
))
9514 /* XXX: test invalid n == 0 case ? */
9515 if (insn
& (1 << 23)) {
9516 if (insn
& (1 << 24)) {
9518 tcg_gen_addi_i32(addr
, addr
, 4);
9520 /* post increment */
9523 if (insn
& (1 << 24)) {
9525 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9527 /* post decrement */
9529 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9534 if (insn
& (1 << i
)) {
9537 tmp
= tcg_temp_new_i32();
9538 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9540 tmp2
= tcg_const_i32(i
);
9541 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9542 tcg_temp_free_i32(tmp2
);
9543 tcg_temp_free_i32(tmp
);
9544 } else if (i
== rn
) {
9547 } else if (rn
== 15 && exc_return
) {
9548 store_pc_exc_ret(s
, tmp
);
9550 store_reg_from_load(s
, i
, tmp
);
9555 /* special case: r15 = PC + 8 */
9556 val
= (long)s
->pc
+ 4;
9557 tmp
= tcg_temp_new_i32();
9558 tcg_gen_movi_i32(tmp
, val
);
9560 tmp
= tcg_temp_new_i32();
9561 tmp2
= tcg_const_i32(i
);
9562 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9563 tcg_temp_free_i32(tmp2
);
9565 tmp
= load_reg(s
, i
);
9567 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9568 tcg_temp_free_i32(tmp
);
9571 /* no need to add after the last transfer */
9573 tcg_gen_addi_i32(addr
, addr
, 4);
9576 if (insn
& (1 << 21)) {
9578 if (insn
& (1 << 23)) {
9579 if (insn
& (1 << 24)) {
9582 /* post increment */
9583 tcg_gen_addi_i32(addr
, addr
, 4);
9586 if (insn
& (1 << 24)) {
9589 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9591 /* post decrement */
9592 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9595 store_reg(s
, rn
, addr
);
9597 tcg_temp_free_i32(addr
);
9600 store_reg(s
, rn
, loaded_var
);
9603 /* Restore CPSR from SPSR. */
9604 tmp
= load_cpu_field(spsr
);
9605 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9606 tcg_temp_free_i32(tmp
);
9607 /* Must exit loop to check un-masked IRQs */
9608 s
->base
.is_jmp
= DISAS_EXIT
;
9617 /* branch (and link) */
9618 val
= (int32_t)s
->pc
;
9619 if (insn
& (1 << 24)) {
9620 tmp
= tcg_temp_new_i32();
9621 tcg_gen_movi_i32(tmp
, val
);
9622 store_reg(s
, 14, tmp
);
9624 offset
= sextract32(insn
<< 2, 0, 26);
9632 if (((insn
>> 8) & 0xe) == 10) {
9634 if (disas_vfp_insn(s
, insn
)) {
9637 } else if (disas_coproc_insn(s
, insn
)) {
9644 gen_set_pc_im(s
, s
->pc
);
9645 s
->svc_imm
= extract32(insn
, 0, 24);
9646 s
->base
.is_jmp
= DISAS_SWI
;
9650 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9651 default_exception_el(s
));
9657 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t insn
)
9659 /* Return true if this is a 16 bit instruction. We must be precise
9660 * about this (matching the decode). We assume that s->pc still
9661 * points to the first 16 bits of the insn.
9663 if ((insn
>> 11) < 0x1d) {
9664 /* Definitely a 16-bit instruction */
9668 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9669 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9670 * end up actually treating this as two 16-bit insns, though,
9671 * if it's half of a bl/blx pair that might span a page boundary.
9673 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
9674 /* Thumb2 cores (including all M profile ones) always treat
9675 * 32-bit insns as 32-bit.
9680 if ((insn
>> 11) == 0x1e && (s
->pc
< s
->next_page_start
- 3)) {
9681 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9682 * is not on the next page; we merge this into a 32-bit
9687 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9688 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9689 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9690 * -- handle as single 16 bit insn
9695 /* Return true if this is a Thumb-2 logical op. */
9697 thumb2_logic_op(int op
)
9702 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9703 then set condition code flags based on the result of the operation.
9704 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9705 to the high bit of T1.
9706 Returns zero if the opcode is valid. */
9709 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9710 TCGv_i32 t0
, TCGv_i32 t1
)
9717 tcg_gen_and_i32(t0
, t0
, t1
);
9721 tcg_gen_andc_i32(t0
, t0
, t1
);
9725 tcg_gen_or_i32(t0
, t0
, t1
);
9729 tcg_gen_orc_i32(t0
, t0
, t1
);
9733 tcg_gen_xor_i32(t0
, t0
, t1
);
9738 gen_add_CC(t0
, t0
, t1
);
9740 tcg_gen_add_i32(t0
, t0
, t1
);
9744 gen_adc_CC(t0
, t0
, t1
);
9750 gen_sbc_CC(t0
, t0
, t1
);
9752 gen_sub_carry(t0
, t0
, t1
);
9757 gen_sub_CC(t0
, t0
, t1
);
9759 tcg_gen_sub_i32(t0
, t0
, t1
);
9763 gen_sub_CC(t0
, t1
, t0
);
9765 tcg_gen_sub_i32(t0
, t1
, t0
);
9767 default: /* 5, 6, 7, 9, 12, 15. */
9773 gen_set_CF_bit31(t1
);
9778 /* Translate a 32-bit thumb instruction. */
9779 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
9781 uint32_t imm
, shift
, offset
;
9782 uint32_t rd
, rn
, rm
, rs
;
9793 /* The only 32 bit insn that's allowed for Thumb1 is the combined
9794 * BL/BLX prefix and suffix.
9796 if ((insn
& 0xf800e800) != 0xf000e800) {
9800 rn
= (insn
>> 16) & 0xf;
9801 rs
= (insn
>> 12) & 0xf;
9802 rd
= (insn
>> 8) & 0xf;
9804 switch ((insn
>> 25) & 0xf) {
9805 case 0: case 1: case 2: case 3:
9806 /* 16-bit instructions. Should never happen. */
9809 if (insn
& (1 << 22)) {
9810 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9811 * - load/store doubleword, load/store exclusive, ldacq/strel,
9814 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_M
) &&
9815 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
9816 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9818 * The bulk of the behaviour for this instruction is implemented
9819 * in v7m_handle_execute_nsc(), which deals with the insn when
9820 * it is executed by a CPU in non-secure state from memory
9821 * which is Secure & NonSecure-Callable.
9822 * Here we only need to handle the remaining cases:
9823 * * in NS memory (including the "security extension not
9824 * implemented" case) : NOP
9825 * * in S memory but CPU already secure (clear IT bits)
9826 * We know that the attribute for the memory this insn is
9827 * in must match the current CPU state, because otherwise
9828 * get_phys_addr_pmsav8 would have generated an exception.
9830 if (s
->v8m_secure
) {
9831 /* Like the IT insn, we don't need to generate any code */
9832 s
->condexec_cond
= 0;
9833 s
->condexec_mask
= 0;
9835 } else if (insn
& 0x01200000) {
9836 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9837 * - load/store dual (post-indexed)
9838 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9839 * - load/store dual (literal and immediate)
9840 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9841 * - load/store dual (pre-indexed)
9844 if (insn
& (1 << 21)) {
9848 addr
= tcg_temp_new_i32();
9849 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9851 addr
= load_reg(s
, rn
);
9853 offset
= (insn
& 0xff) * 4;
9854 if ((insn
& (1 << 23)) == 0)
9856 if (insn
& (1 << 24)) {
9857 tcg_gen_addi_i32(addr
, addr
, offset
);
9860 if (insn
& (1 << 20)) {
9862 tmp
= tcg_temp_new_i32();
9863 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9864 store_reg(s
, rs
, tmp
);
9865 tcg_gen_addi_i32(addr
, addr
, 4);
9866 tmp
= tcg_temp_new_i32();
9867 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9868 store_reg(s
, rd
, tmp
);
9871 tmp
= load_reg(s
, rs
);
9872 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9873 tcg_temp_free_i32(tmp
);
9874 tcg_gen_addi_i32(addr
, addr
, 4);
9875 tmp
= load_reg(s
, rd
);
9876 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9877 tcg_temp_free_i32(tmp
);
9879 if (insn
& (1 << 21)) {
9880 /* Base writeback. */
9881 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9882 store_reg(s
, rn
, addr
);
9884 tcg_temp_free_i32(addr
);
9886 } else if ((insn
& (1 << 23)) == 0) {
9887 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9888 * - load/store exclusive word
9892 if (!(insn
& (1 << 20)) &&
9893 arm_dc_feature(s
, ARM_FEATURE_M
) &&
9894 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
9895 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
9898 bool alt
= insn
& (1 << 7);
9899 TCGv_i32 addr
, op
, ttresp
;
9901 if ((insn
& 0x3f) || rd
== 13 || rd
== 15 || rn
== 15) {
9902 /* we UNDEF for these UNPREDICTABLE cases */
9906 if (alt
&& !s
->v8m_secure
) {
9910 addr
= load_reg(s
, rn
);
9911 op
= tcg_const_i32(extract32(insn
, 6, 2));
9912 ttresp
= tcg_temp_new_i32();
9913 gen_helper_v7m_tt(ttresp
, cpu_env
, addr
, op
);
9914 tcg_temp_free_i32(addr
);
9915 tcg_temp_free_i32(op
);
9916 store_reg(s
, rd
, ttresp
);
9920 addr
= tcg_temp_local_new_i32();
9921 load_reg_var(s
, addr
, rn
);
9922 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9923 if (insn
& (1 << 20)) {
9924 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9926 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9928 tcg_temp_free_i32(addr
);
9929 } else if ((insn
& (7 << 5)) == 0) {
9932 addr
= tcg_temp_new_i32();
9933 tcg_gen_movi_i32(addr
, s
->pc
);
9935 addr
= load_reg(s
, rn
);
9937 tmp
= load_reg(s
, rm
);
9938 tcg_gen_add_i32(addr
, addr
, tmp
);
9939 if (insn
& (1 << 4)) {
9941 tcg_gen_add_i32(addr
, addr
, tmp
);
9942 tcg_temp_free_i32(tmp
);
9943 tmp
= tcg_temp_new_i32();
9944 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9946 tcg_temp_free_i32(tmp
);
9947 tmp
= tcg_temp_new_i32();
9948 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9950 tcg_temp_free_i32(addr
);
9951 tcg_gen_shli_i32(tmp
, tmp
, 1);
9952 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9953 store_reg(s
, 15, tmp
);
9955 int op2
= (insn
>> 6) & 0x3;
9956 op
= (insn
>> 4) & 0x3;
9961 /* Load/store exclusive byte/halfword/doubleword */
9968 /* Load-acquire/store-release */
9974 /* Load-acquire/store-release exclusive */
9978 addr
= tcg_temp_local_new_i32();
9979 load_reg_var(s
, addr
, rn
);
9981 if (insn
& (1 << 20)) {
9982 tmp
= tcg_temp_new_i32();
9985 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
9989 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9993 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
9999 store_reg(s
, rs
, tmp
);
10001 tmp
= load_reg(s
, rs
);
10004 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
10008 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
10012 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
10018 tcg_temp_free_i32(tmp
);
10020 } else if (insn
& (1 << 20)) {
10021 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
10023 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
10025 tcg_temp_free_i32(addr
);
10028 /* Load/store multiple, RFE, SRS. */
10029 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
10030 /* RFE, SRS: not available in user mode or on M profile */
10031 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10034 if (insn
& (1 << 20)) {
10036 addr
= load_reg(s
, rn
);
10037 if ((insn
& (1 << 24)) == 0)
10038 tcg_gen_addi_i32(addr
, addr
, -8);
10039 /* Load PC into tmp and CPSR into tmp2. */
10040 tmp
= tcg_temp_new_i32();
10041 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10042 tcg_gen_addi_i32(addr
, addr
, 4);
10043 tmp2
= tcg_temp_new_i32();
10044 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
10045 if (insn
& (1 << 21)) {
10046 /* Base writeback. */
10047 if (insn
& (1 << 24)) {
10048 tcg_gen_addi_i32(addr
, addr
, 4);
10050 tcg_gen_addi_i32(addr
, addr
, -4);
10052 store_reg(s
, rn
, addr
);
10054 tcg_temp_free_i32(addr
);
10056 gen_rfe(s
, tmp
, tmp2
);
10059 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
10063 int i
, loaded_base
= 0;
10064 TCGv_i32 loaded_var
;
10065 /* Load/store multiple. */
10066 addr
= load_reg(s
, rn
);
10068 for (i
= 0; i
< 16; i
++) {
10069 if (insn
& (1 << i
))
10072 if (insn
& (1 << 24)) {
10073 tcg_gen_addi_i32(addr
, addr
, -offset
);
10077 for (i
= 0; i
< 16; i
++) {
10078 if ((insn
& (1 << i
)) == 0)
10080 if (insn
& (1 << 20)) {
10082 tmp
= tcg_temp_new_i32();
10083 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10085 gen_bx_excret(s
, tmp
);
10086 } else if (i
== rn
) {
10090 store_reg(s
, i
, tmp
);
10094 tmp
= load_reg(s
, i
);
10095 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10096 tcg_temp_free_i32(tmp
);
10098 tcg_gen_addi_i32(addr
, addr
, 4);
10101 store_reg(s
, rn
, loaded_var
);
10103 if (insn
& (1 << 21)) {
10104 /* Base register writeback. */
10105 if (insn
& (1 << 24)) {
10106 tcg_gen_addi_i32(addr
, addr
, -offset
);
10108 /* Fault if writeback register is in register list. */
10109 if (insn
& (1 << rn
))
10111 store_reg(s
, rn
, addr
);
10113 tcg_temp_free_i32(addr
);
10120 op
= (insn
>> 21) & 0xf;
10122 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10125 /* Halfword pack. */
10126 tmp
= load_reg(s
, rn
);
10127 tmp2
= load_reg(s
, rm
);
10128 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
10129 if (insn
& (1 << 5)) {
10133 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
10134 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
10135 tcg_gen_ext16u_i32(tmp2
, tmp2
);
10139 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10140 tcg_gen_ext16u_i32(tmp
, tmp
);
10141 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10143 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10144 tcg_temp_free_i32(tmp2
);
10145 store_reg(s
, rd
, tmp
);
10147 /* Data processing register constant shift. */
10149 tmp
= tcg_temp_new_i32();
10150 tcg_gen_movi_i32(tmp
, 0);
10152 tmp
= load_reg(s
, rn
);
10154 tmp2
= load_reg(s
, rm
);
10156 shiftop
= (insn
>> 4) & 3;
10157 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10158 conds
= (insn
& (1 << 20)) != 0;
10159 logic_cc
= (conds
&& thumb2_logic_op(op
));
10160 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10161 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10163 tcg_temp_free_i32(tmp2
);
10165 store_reg(s
, rd
, tmp
);
10167 tcg_temp_free_i32(tmp
);
10171 case 13: /* Misc data processing. */
10172 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10173 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10176 case 0: /* Register controlled shift. */
10177 tmp
= load_reg(s
, rn
);
10178 tmp2
= load_reg(s
, rm
);
10179 if ((insn
& 0x70) != 0)
10181 op
= (insn
>> 21) & 3;
10182 logic_cc
= (insn
& (1 << 20)) != 0;
10183 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10186 store_reg(s
, rd
, tmp
);
10188 case 1: /* Sign/zero extend. */
10189 op
= (insn
>> 20) & 7;
10191 case 0: /* SXTAH, SXTH */
10192 case 1: /* UXTAH, UXTH */
10193 case 4: /* SXTAB, SXTB */
10194 case 5: /* UXTAB, UXTB */
10196 case 2: /* SXTAB16, SXTB16 */
10197 case 3: /* UXTAB16, UXTB16 */
10198 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10206 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10210 tmp
= load_reg(s
, rm
);
10211 shift
= (insn
>> 4) & 3;
10212 /* ??? In many cases it's not necessary to do a
10213 rotate, a shift is sufficient. */
10215 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10216 op
= (insn
>> 20) & 7;
10218 case 0: gen_sxth(tmp
); break;
10219 case 1: gen_uxth(tmp
); break;
10220 case 2: gen_sxtb16(tmp
); break;
10221 case 3: gen_uxtb16(tmp
); break;
10222 case 4: gen_sxtb(tmp
); break;
10223 case 5: gen_uxtb(tmp
); break;
10225 g_assert_not_reached();
10228 tmp2
= load_reg(s
, rn
);
10229 if ((op
>> 1) == 1) {
10230 gen_add16(tmp
, tmp2
);
10232 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10233 tcg_temp_free_i32(tmp2
);
10236 store_reg(s
, rd
, tmp
);
10238 case 2: /* SIMD add/subtract. */
10239 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10242 op
= (insn
>> 20) & 7;
10243 shift
= (insn
>> 4) & 7;
10244 if ((op
& 3) == 3 || (shift
& 3) == 3)
10246 tmp
= load_reg(s
, rn
);
10247 tmp2
= load_reg(s
, rm
);
10248 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10249 tcg_temp_free_i32(tmp2
);
10250 store_reg(s
, rd
, tmp
);
10252 case 3: /* Other data processing. */
10253 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10255 /* Saturating add/subtract. */
10256 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10259 tmp
= load_reg(s
, rn
);
10260 tmp2
= load_reg(s
, rm
);
10262 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10264 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10266 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10267 tcg_temp_free_i32(tmp2
);
10270 case 0x0a: /* rbit */
10271 case 0x08: /* rev */
10272 case 0x09: /* rev16 */
10273 case 0x0b: /* revsh */
10274 case 0x18: /* clz */
10276 case 0x10: /* sel */
10277 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10281 case 0x20: /* crc32/crc32c */
10287 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10294 tmp
= load_reg(s
, rn
);
10296 case 0x0a: /* rbit */
10297 gen_helper_rbit(tmp
, tmp
);
10299 case 0x08: /* rev */
10300 tcg_gen_bswap32_i32(tmp
, tmp
);
10302 case 0x09: /* rev16 */
10305 case 0x0b: /* revsh */
10308 case 0x10: /* sel */
10309 tmp2
= load_reg(s
, rm
);
10310 tmp3
= tcg_temp_new_i32();
10311 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10312 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10313 tcg_temp_free_i32(tmp3
);
10314 tcg_temp_free_i32(tmp2
);
10316 case 0x18: /* clz */
10317 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10327 uint32_t sz
= op
& 0x3;
10328 uint32_t c
= op
& 0x8;
10330 tmp2
= load_reg(s
, rm
);
10332 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10333 } else if (sz
== 1) {
10334 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10336 tmp3
= tcg_const_i32(1 << sz
);
10338 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10340 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10342 tcg_temp_free_i32(tmp2
);
10343 tcg_temp_free_i32(tmp3
);
10347 g_assert_not_reached();
10350 store_reg(s
, rd
, tmp
);
10352 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10353 switch ((insn
>> 20) & 7) {
10354 case 0: /* 32 x 32 -> 32 */
10355 case 7: /* Unsigned sum of absolute differences. */
10357 case 1: /* 16 x 16 -> 32 */
10358 case 2: /* Dual multiply add. */
10359 case 3: /* 32 * 16 -> 32msb */
10360 case 4: /* Dual multiply subtract. */
10361 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10362 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10367 op
= (insn
>> 4) & 0xf;
10368 tmp
= load_reg(s
, rn
);
10369 tmp2
= load_reg(s
, rm
);
10370 switch ((insn
>> 20) & 7) {
10371 case 0: /* 32 x 32 -> 32 */
10372 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10373 tcg_temp_free_i32(tmp2
);
10375 tmp2
= load_reg(s
, rs
);
10377 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10379 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10380 tcg_temp_free_i32(tmp2
);
10383 case 1: /* 16 x 16 -> 32 */
10384 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10385 tcg_temp_free_i32(tmp2
);
10387 tmp2
= load_reg(s
, rs
);
10388 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10389 tcg_temp_free_i32(tmp2
);
10392 case 2: /* Dual multiply add. */
10393 case 4: /* Dual multiply subtract. */
10395 gen_swap_half(tmp2
);
10396 gen_smul_dual(tmp
, tmp2
);
10397 if (insn
& (1 << 22)) {
10398 /* This subtraction cannot overflow. */
10399 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10401 /* This addition cannot overflow 32 bits;
10402 * however it may overflow considered as a signed
10403 * operation, in which case we must set the Q flag.
10405 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10407 tcg_temp_free_i32(tmp2
);
10410 tmp2
= load_reg(s
, rs
);
10411 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10412 tcg_temp_free_i32(tmp2
);
10415 case 3: /* 32 * 16 -> 32msb */
10417 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10420 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10421 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10422 tmp
= tcg_temp_new_i32();
10423 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10424 tcg_temp_free_i64(tmp64
);
10427 tmp2
= load_reg(s
, rs
);
10428 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10429 tcg_temp_free_i32(tmp2
);
10432 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10433 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10435 tmp
= load_reg(s
, rs
);
10436 if (insn
& (1 << 20)) {
10437 tmp64
= gen_addq_msw(tmp64
, tmp
);
10439 tmp64
= gen_subq_msw(tmp64
, tmp
);
10442 if (insn
& (1 << 4)) {
10443 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10445 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10446 tmp
= tcg_temp_new_i32();
10447 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10448 tcg_temp_free_i64(tmp64
);
10450 case 7: /* Unsigned sum of absolute differences. */
10451 gen_helper_usad8(tmp
, tmp
, tmp2
);
10452 tcg_temp_free_i32(tmp2
);
10454 tmp2
= load_reg(s
, rs
);
10455 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10456 tcg_temp_free_i32(tmp2
);
10460 store_reg(s
, rd
, tmp
);
10462 case 6: case 7: /* 64-bit multiply, Divide. */
10463 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10464 tmp
= load_reg(s
, rn
);
10465 tmp2
= load_reg(s
, rm
);
10466 if ((op
& 0x50) == 0x10) {
10468 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10472 gen_helper_udiv(tmp
, tmp
, tmp2
);
10474 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10475 tcg_temp_free_i32(tmp2
);
10476 store_reg(s
, rd
, tmp
);
10477 } else if ((op
& 0xe) == 0xc) {
10478 /* Dual multiply accumulate long. */
10479 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10480 tcg_temp_free_i32(tmp
);
10481 tcg_temp_free_i32(tmp2
);
10485 gen_swap_half(tmp2
);
10486 gen_smul_dual(tmp
, tmp2
);
10488 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10490 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10492 tcg_temp_free_i32(tmp2
);
10494 tmp64
= tcg_temp_new_i64();
10495 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10496 tcg_temp_free_i32(tmp
);
10497 gen_addq(s
, tmp64
, rs
, rd
);
10498 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10499 tcg_temp_free_i64(tmp64
);
10502 /* Unsigned 64-bit multiply */
10503 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10507 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10508 tcg_temp_free_i32(tmp2
);
10509 tcg_temp_free_i32(tmp
);
10512 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10513 tcg_temp_free_i32(tmp2
);
10514 tmp64
= tcg_temp_new_i64();
10515 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10516 tcg_temp_free_i32(tmp
);
10518 /* Signed 64-bit multiply */
10519 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10524 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10525 tcg_temp_free_i64(tmp64
);
10528 gen_addq_lo(s
, tmp64
, rs
);
10529 gen_addq_lo(s
, tmp64
, rd
);
10530 } else if (op
& 0x40) {
10531 /* 64-bit accumulate. */
10532 gen_addq(s
, tmp64
, rs
, rd
);
10534 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10535 tcg_temp_free_i64(tmp64
);
10540 case 6: case 7: case 14: case 15:
10542 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10543 /* We don't currently implement M profile FP support,
10544 * so this entire space should give a NOCP fault.
10546 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10547 default_exception_el(s
));
10550 if (((insn
>> 24) & 3) == 3) {
10551 /* Translate into the equivalent ARM encoding. */
10552 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10553 if (disas_neon_data_insn(s
, insn
)) {
10556 } else if (((insn
>> 8) & 0xe) == 10) {
10557 if (disas_vfp_insn(s
, insn
)) {
10561 if (insn
& (1 << 28))
10563 if (disas_coproc_insn(s
, insn
)) {
10568 case 8: case 9: case 10: case 11:
10569 if (insn
& (1 << 15)) {
10570 /* Branches, misc control. */
10571 if (insn
& 0x5000) {
10572 /* Unconditional branch. */
10573 /* signextend(hw1[10:0]) -> offset[:12]. */
10574 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10575 /* hw1[10:0] -> offset[11:1]. */
10576 offset
|= (insn
& 0x7ff) << 1;
10577 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10578 offset[24:22] already have the same value because of the
10579 sign extension above. */
10580 offset
^= ((~insn
) & (1 << 13)) << 10;
10581 offset
^= ((~insn
) & (1 << 11)) << 11;
10583 if (insn
& (1 << 14)) {
10584 /* Branch and link. */
10585 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10589 if (insn
& (1 << 12)) {
10591 gen_jmp(s
, offset
);
10594 offset
&= ~(uint32_t)2;
10595 /* thumb2 bx, no need to check */
10596 gen_bx_im(s
, offset
);
10598 } else if (((insn
>> 23) & 7) == 7) {
10600 if (insn
& (1 << 13))
10603 if (insn
& (1 << 26)) {
10604 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10607 if (!(insn
& (1 << 20))) {
10608 /* Hypervisor call (v7) */
10609 int imm16
= extract32(insn
, 16, 4) << 12
10610 | extract32(insn
, 0, 12);
10617 /* Secure monitor call (v6+) */
10625 op
= (insn
>> 20) & 7;
10627 case 0: /* msr cpsr. */
10628 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10629 tmp
= load_reg(s
, rn
);
10630 /* the constant is the mask and SYSm fields */
10631 addr
= tcg_const_i32(insn
& 0xfff);
10632 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10633 tcg_temp_free_i32(addr
);
10634 tcg_temp_free_i32(tmp
);
10639 case 1: /* msr spsr. */
10640 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10644 if (extract32(insn
, 5, 1)) {
10646 int sysm
= extract32(insn
, 8, 4) |
10647 (extract32(insn
, 4, 1) << 4);
10650 gen_msr_banked(s
, r
, sysm
, rm
);
10654 /* MSR (for PSRs) */
10655 tmp
= load_reg(s
, rn
);
10657 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10661 case 2: /* cps, nop-hint. */
10662 if (((insn
>> 8) & 7) == 0) {
10663 gen_nop_hint(s
, insn
& 0xff);
10665 /* Implemented as NOP in user mode. */
10670 if (insn
& (1 << 10)) {
10671 if (insn
& (1 << 7))
10673 if (insn
& (1 << 6))
10675 if (insn
& (1 << 5))
10677 if (insn
& (1 << 9))
10678 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10680 if (insn
& (1 << 8)) {
10682 imm
|= (insn
& 0x1f);
10685 gen_set_psr_im(s
, offset
, 0, imm
);
10688 case 3: /* Special control operations. */
10690 op
= (insn
>> 4) & 0xf;
10692 case 2: /* clrex */
10697 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10700 /* We need to break the TB after this insn
10701 * to execute self-modifying code correctly
10702 * and also to take any pending interrupts
10705 gen_goto_tb(s
, 0, s
->pc
& ~1);
10712 /* Trivial implementation equivalent to bx.
10713 * This instruction doesn't exist at all for M-profile.
10715 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10718 tmp
= load_reg(s
, rn
);
10721 case 5: /* Exception return. */
10725 if (rn
!= 14 || rd
!= 15) {
10728 tmp
= load_reg(s
, rn
);
10729 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10730 gen_exception_return(s
, tmp
);
10733 if (extract32(insn
, 5, 1) &&
10734 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10736 int sysm
= extract32(insn
, 16, 4) |
10737 (extract32(insn
, 4, 1) << 4);
10739 gen_mrs_banked(s
, 0, sysm
, rd
);
10743 if (extract32(insn
, 16, 4) != 0xf) {
10746 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10747 extract32(insn
, 0, 8) != 0) {
10752 tmp
= tcg_temp_new_i32();
10753 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10754 addr
= tcg_const_i32(insn
& 0xff);
10755 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10756 tcg_temp_free_i32(addr
);
10758 gen_helper_cpsr_read(tmp
, cpu_env
);
10760 store_reg(s
, rd
, tmp
);
10763 if (extract32(insn
, 5, 1) &&
10764 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10766 int sysm
= extract32(insn
, 16, 4) |
10767 (extract32(insn
, 4, 1) << 4);
10769 gen_mrs_banked(s
, 1, sysm
, rd
);
10774 /* Not accessible in user mode. */
10775 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10779 if (extract32(insn
, 16, 4) != 0xf ||
10780 extract32(insn
, 0, 8) != 0) {
10784 tmp
= load_cpu_field(spsr
);
10785 store_reg(s
, rd
, tmp
);
10790 /* Conditional branch. */
10791 op
= (insn
>> 22) & 0xf;
10792 /* Generate a conditional jump to next instruction. */
10793 s
->condlabel
= gen_new_label();
10794 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10797 /* offset[11:1] = insn[10:0] */
10798 offset
= (insn
& 0x7ff) << 1;
10799 /* offset[17:12] = insn[21:16]. */
10800 offset
|= (insn
& 0x003f0000) >> 4;
10801 /* offset[31:20] = insn[26]. */
10802 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10803 /* offset[18] = insn[13]. */
10804 offset
|= (insn
& (1 << 13)) << 5;
10805 /* offset[19] = insn[11]. */
10806 offset
|= (insn
& (1 << 11)) << 8;
10808 /* jump to the offset */
10809 gen_jmp(s
, s
->pc
+ offset
);
10812 /* Data processing immediate. */
10813 if (insn
& (1 << 25)) {
10814 if (insn
& (1 << 24)) {
10815 if (insn
& (1 << 20))
10817 /* Bitfield/Saturate. */
10818 op
= (insn
>> 21) & 7;
10820 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10822 tmp
= tcg_temp_new_i32();
10823 tcg_gen_movi_i32(tmp
, 0);
10825 tmp
= load_reg(s
, rn
);
10828 case 2: /* Signed bitfield extract. */
10830 if (shift
+ imm
> 32)
10833 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
10836 case 6: /* Unsigned bitfield extract. */
10838 if (shift
+ imm
> 32)
10841 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
10844 case 3: /* Bitfield insert/clear. */
10847 imm
= imm
+ 1 - shift
;
10849 tmp2
= load_reg(s
, rd
);
10850 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10851 tcg_temp_free_i32(tmp2
);
10856 default: /* Saturate. */
10859 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10861 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10863 tmp2
= tcg_const_i32(imm
);
10866 if ((op
& 1) && shift
== 0) {
10867 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10868 tcg_temp_free_i32(tmp
);
10869 tcg_temp_free_i32(tmp2
);
10872 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10874 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10878 if ((op
& 1) && shift
== 0) {
10879 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10880 tcg_temp_free_i32(tmp
);
10881 tcg_temp_free_i32(tmp2
);
10884 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10886 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10889 tcg_temp_free_i32(tmp2
);
10892 store_reg(s
, rd
, tmp
);
10894 imm
= ((insn
& 0x04000000) >> 15)
10895 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10896 if (insn
& (1 << 22)) {
10897 /* 16-bit immediate. */
10898 imm
|= (insn
>> 4) & 0xf000;
10899 if (insn
& (1 << 23)) {
10901 tmp
= load_reg(s
, rd
);
10902 tcg_gen_ext16u_i32(tmp
, tmp
);
10903 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10906 tmp
= tcg_temp_new_i32();
10907 tcg_gen_movi_i32(tmp
, imm
);
10910 /* Add/sub 12-bit immediate. */
10912 offset
= s
->pc
& ~(uint32_t)3;
10913 if (insn
& (1 << 23))
10917 tmp
= tcg_temp_new_i32();
10918 tcg_gen_movi_i32(tmp
, offset
);
10920 tmp
= load_reg(s
, rn
);
10921 if (insn
& (1 << 23))
10922 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10924 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10927 store_reg(s
, rd
, tmp
);
10930 int shifter_out
= 0;
10931 /* modified 12-bit immediate. */
10932 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10933 imm
= (insn
& 0xff);
10936 /* Nothing to do. */
10938 case 1: /* 00XY00XY */
10941 case 2: /* XY00XY00 */
10945 case 3: /* XYXYXYXY */
10949 default: /* Rotated constant. */
10950 shift
= (shift
<< 1) | (imm
>> 7);
10952 imm
= imm
<< (32 - shift
);
10956 tmp2
= tcg_temp_new_i32();
10957 tcg_gen_movi_i32(tmp2
, imm
);
10958 rn
= (insn
>> 16) & 0xf;
10960 tmp
= tcg_temp_new_i32();
10961 tcg_gen_movi_i32(tmp
, 0);
10963 tmp
= load_reg(s
, rn
);
10965 op
= (insn
>> 21) & 0xf;
10966 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10967 shifter_out
, tmp
, tmp2
))
10969 tcg_temp_free_i32(tmp2
);
10970 rd
= (insn
>> 8) & 0xf;
10972 store_reg(s
, rd
, tmp
);
10974 tcg_temp_free_i32(tmp
);
10979 case 12: /* Load/store single data item. */
10986 if ((insn
& 0x01100000) == 0x01000000) {
10987 if (disas_neon_ls_insn(s
, insn
)) {
10992 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10994 if (!(insn
& (1 << 20))) {
10998 /* Byte or halfword load space with dest == r15 : memory hints.
10999 * Catch them early so we don't emit pointless addressing code.
11000 * This space is a mix of:
11001 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11002 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11004 * unallocated hints, which must be treated as NOPs
11005 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11006 * which is easiest for the decoding logic
11007 * Some space which must UNDEF
11009 int op1
= (insn
>> 23) & 3;
11010 int op2
= (insn
>> 6) & 0x3f;
11015 /* UNPREDICTABLE, unallocated hint or
11016 * PLD/PLDW/PLI (literal)
11021 return; /* PLD/PLDW/PLI or unallocated hint */
11023 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
11024 return; /* PLD/PLDW/PLI or unallocated hint */
11026 /* UNDEF space, or an UNPREDICTABLE */
11030 memidx
= get_mem_index(s
);
11032 addr
= tcg_temp_new_i32();
11034 /* s->pc has already been incremented by 4. */
11035 imm
= s
->pc
& 0xfffffffc;
11036 if (insn
& (1 << 23))
11037 imm
+= insn
& 0xfff;
11039 imm
-= insn
& 0xfff;
11040 tcg_gen_movi_i32(addr
, imm
);
11042 addr
= load_reg(s
, rn
);
11043 if (insn
& (1 << 23)) {
11044 /* Positive offset. */
11045 imm
= insn
& 0xfff;
11046 tcg_gen_addi_i32(addr
, addr
, imm
);
11049 switch ((insn
>> 8) & 0xf) {
11050 case 0x0: /* Shifted Register. */
11051 shift
= (insn
>> 4) & 0xf;
11053 tcg_temp_free_i32(addr
);
11056 tmp
= load_reg(s
, rm
);
11058 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11059 tcg_gen_add_i32(addr
, addr
, tmp
);
11060 tcg_temp_free_i32(tmp
);
11062 case 0xc: /* Negative offset. */
11063 tcg_gen_addi_i32(addr
, addr
, -imm
);
11065 case 0xe: /* User privilege. */
11066 tcg_gen_addi_i32(addr
, addr
, imm
);
11067 memidx
= get_a32_user_mem_index(s
);
11069 case 0x9: /* Post-decrement. */
11071 /* Fall through. */
11072 case 0xb: /* Post-increment. */
11076 case 0xd: /* Pre-decrement. */
11078 /* Fall through. */
11079 case 0xf: /* Pre-increment. */
11080 tcg_gen_addi_i32(addr
, addr
, imm
);
11084 tcg_temp_free_i32(addr
);
11090 issinfo
= writeback
? ISSInvalid
: rs
;
11092 if (insn
& (1 << 20)) {
11094 tmp
= tcg_temp_new_i32();
11097 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11100 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11103 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11106 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11109 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11112 tcg_temp_free_i32(tmp
);
11113 tcg_temp_free_i32(addr
);
11117 gen_bx_excret(s
, tmp
);
11119 store_reg(s
, rs
, tmp
);
11123 tmp
= load_reg(s
, rs
);
11126 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
11129 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
11132 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
11135 tcg_temp_free_i32(tmp
);
11136 tcg_temp_free_i32(addr
);
11139 tcg_temp_free_i32(tmp
);
11142 tcg_gen_addi_i32(addr
, addr
, imm
);
11144 store_reg(s
, rn
, addr
);
11146 tcg_temp_free_i32(addr
);
11155 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11156 default_exception_el(s
));
11159 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
11161 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
11168 switch (insn
>> 12) {
11172 op
= (insn
>> 11) & 3;
11175 rn
= (insn
>> 3) & 7;
11176 tmp
= load_reg(s
, rn
);
11177 if (insn
& (1 << 10)) {
11179 tmp2
= tcg_temp_new_i32();
11180 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11183 rm
= (insn
>> 6) & 7;
11184 tmp2
= load_reg(s
, rm
);
11186 if (insn
& (1 << 9)) {
11187 if (s
->condexec_mask
)
11188 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11190 gen_sub_CC(tmp
, tmp
, tmp2
);
11192 if (s
->condexec_mask
)
11193 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11195 gen_add_CC(tmp
, tmp
, tmp2
);
11197 tcg_temp_free_i32(tmp2
);
11198 store_reg(s
, rd
, tmp
);
11200 /* shift immediate */
11201 rm
= (insn
>> 3) & 7;
11202 shift
= (insn
>> 6) & 0x1f;
11203 tmp
= load_reg(s
, rm
);
11204 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11205 if (!s
->condexec_mask
)
11207 store_reg(s
, rd
, tmp
);
11211 /* arithmetic large immediate */
11212 op
= (insn
>> 11) & 3;
11213 rd
= (insn
>> 8) & 0x7;
11214 if (op
== 0) { /* mov */
11215 tmp
= tcg_temp_new_i32();
11216 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11217 if (!s
->condexec_mask
)
11219 store_reg(s
, rd
, tmp
);
11221 tmp
= load_reg(s
, rd
);
11222 tmp2
= tcg_temp_new_i32();
11223 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11226 gen_sub_CC(tmp
, tmp
, tmp2
);
11227 tcg_temp_free_i32(tmp
);
11228 tcg_temp_free_i32(tmp2
);
11231 if (s
->condexec_mask
)
11232 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11234 gen_add_CC(tmp
, tmp
, tmp2
);
11235 tcg_temp_free_i32(tmp2
);
11236 store_reg(s
, rd
, tmp
);
11239 if (s
->condexec_mask
)
11240 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11242 gen_sub_CC(tmp
, tmp
, tmp2
);
11243 tcg_temp_free_i32(tmp2
);
11244 store_reg(s
, rd
, tmp
);
11250 if (insn
& (1 << 11)) {
11251 rd
= (insn
>> 8) & 7;
11252 /* load pc-relative. Bit 1 of PC is ignored. */
11253 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11254 val
&= ~(uint32_t)2;
11255 addr
= tcg_temp_new_i32();
11256 tcg_gen_movi_i32(addr
, val
);
11257 tmp
= tcg_temp_new_i32();
11258 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11260 tcg_temp_free_i32(addr
);
11261 store_reg(s
, rd
, tmp
);
11264 if (insn
& (1 << 10)) {
11265 /* 0b0100_01xx_xxxx_xxxx
11266 * - data processing extended, branch and exchange
11268 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11269 rm
= (insn
>> 3) & 0xf;
11270 op
= (insn
>> 8) & 3;
11273 tmp
= load_reg(s
, rd
);
11274 tmp2
= load_reg(s
, rm
);
11275 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11276 tcg_temp_free_i32(tmp2
);
11277 store_reg(s
, rd
, tmp
);
11280 tmp
= load_reg(s
, rd
);
11281 tmp2
= load_reg(s
, rm
);
11282 gen_sub_CC(tmp
, tmp
, tmp2
);
11283 tcg_temp_free_i32(tmp2
);
11284 tcg_temp_free_i32(tmp
);
11286 case 2: /* mov/cpy */
11287 tmp
= load_reg(s
, rm
);
11288 store_reg(s
, rd
, tmp
);
11292 /* 0b0100_0111_xxxx_xxxx
11293 * - branch [and link] exchange thumb register
11295 bool link
= insn
& (1 << 7);
11304 /* BXNS/BLXNS: only exists for v8M with the
11305 * security extensions, and always UNDEF if NonSecure.
11306 * We don't implement these in the user-only mode
11307 * either (in theory you can use them from Secure User
11308 * mode but they are too tied in to system emulation.)
11310 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
11321 tmp
= load_reg(s
, rm
);
11323 val
= (uint32_t)s
->pc
| 1;
11324 tmp2
= tcg_temp_new_i32();
11325 tcg_gen_movi_i32(tmp2
, val
);
11326 store_reg(s
, 14, tmp2
);
11329 /* Only BX works as exception-return, not BLX */
11330 gen_bx_excret(s
, tmp
);
11338 /* data processing register */
11340 rm
= (insn
>> 3) & 7;
11341 op
= (insn
>> 6) & 0xf;
11342 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11343 /* the shift/rotate ops want the operands backwards */
11352 if (op
== 9) { /* neg */
11353 tmp
= tcg_temp_new_i32();
11354 tcg_gen_movi_i32(tmp
, 0);
11355 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11356 tmp
= load_reg(s
, rd
);
11361 tmp2
= load_reg(s
, rm
);
11363 case 0x0: /* and */
11364 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11365 if (!s
->condexec_mask
)
11368 case 0x1: /* eor */
11369 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11370 if (!s
->condexec_mask
)
11373 case 0x2: /* lsl */
11374 if (s
->condexec_mask
) {
11375 gen_shl(tmp2
, tmp2
, tmp
);
11377 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11378 gen_logic_CC(tmp2
);
11381 case 0x3: /* lsr */
11382 if (s
->condexec_mask
) {
11383 gen_shr(tmp2
, tmp2
, tmp
);
11385 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11386 gen_logic_CC(tmp2
);
11389 case 0x4: /* asr */
11390 if (s
->condexec_mask
) {
11391 gen_sar(tmp2
, tmp2
, tmp
);
11393 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11394 gen_logic_CC(tmp2
);
11397 case 0x5: /* adc */
11398 if (s
->condexec_mask
) {
11399 gen_adc(tmp
, tmp2
);
11401 gen_adc_CC(tmp
, tmp
, tmp2
);
11404 case 0x6: /* sbc */
11405 if (s
->condexec_mask
) {
11406 gen_sub_carry(tmp
, tmp
, tmp2
);
11408 gen_sbc_CC(tmp
, tmp
, tmp2
);
11411 case 0x7: /* ror */
11412 if (s
->condexec_mask
) {
11413 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11414 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11416 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11417 gen_logic_CC(tmp2
);
11420 case 0x8: /* tst */
11421 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11425 case 0x9: /* neg */
11426 if (s
->condexec_mask
)
11427 tcg_gen_neg_i32(tmp
, tmp2
);
11429 gen_sub_CC(tmp
, tmp
, tmp2
);
11431 case 0xa: /* cmp */
11432 gen_sub_CC(tmp
, tmp
, tmp2
);
11435 case 0xb: /* cmn */
11436 gen_add_CC(tmp
, tmp
, tmp2
);
11439 case 0xc: /* orr */
11440 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11441 if (!s
->condexec_mask
)
11444 case 0xd: /* mul */
11445 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11446 if (!s
->condexec_mask
)
11449 case 0xe: /* bic */
11450 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11451 if (!s
->condexec_mask
)
11454 case 0xf: /* mvn */
11455 tcg_gen_not_i32(tmp2
, tmp2
);
11456 if (!s
->condexec_mask
)
11457 gen_logic_CC(tmp2
);
11464 store_reg(s
, rm
, tmp2
);
11466 tcg_temp_free_i32(tmp
);
11468 store_reg(s
, rd
, tmp
);
11469 tcg_temp_free_i32(tmp2
);
11472 tcg_temp_free_i32(tmp
);
11473 tcg_temp_free_i32(tmp2
);
11478 /* load/store register offset. */
11480 rn
= (insn
>> 3) & 7;
11481 rm
= (insn
>> 6) & 7;
11482 op
= (insn
>> 9) & 7;
11483 addr
= load_reg(s
, rn
);
11484 tmp
= load_reg(s
, rm
);
11485 tcg_gen_add_i32(addr
, addr
, tmp
);
11486 tcg_temp_free_i32(tmp
);
11488 if (op
< 3) { /* store */
11489 tmp
= load_reg(s
, rd
);
11491 tmp
= tcg_temp_new_i32();
11496 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11499 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11502 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11504 case 3: /* ldrsb */
11505 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11508 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11511 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11514 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11516 case 7: /* ldrsh */
11517 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11520 if (op
>= 3) { /* load */
11521 store_reg(s
, rd
, tmp
);
11523 tcg_temp_free_i32(tmp
);
11525 tcg_temp_free_i32(addr
);
11529 /* load/store word immediate offset */
11531 rn
= (insn
>> 3) & 7;
11532 addr
= load_reg(s
, rn
);
11533 val
= (insn
>> 4) & 0x7c;
11534 tcg_gen_addi_i32(addr
, addr
, val
);
11536 if (insn
& (1 << 11)) {
11538 tmp
= tcg_temp_new_i32();
11539 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11540 store_reg(s
, rd
, tmp
);
11543 tmp
= load_reg(s
, rd
);
11544 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11545 tcg_temp_free_i32(tmp
);
11547 tcg_temp_free_i32(addr
);
11551 /* load/store byte immediate offset */
11553 rn
= (insn
>> 3) & 7;
11554 addr
= load_reg(s
, rn
);
11555 val
= (insn
>> 6) & 0x1f;
11556 tcg_gen_addi_i32(addr
, addr
, val
);
11558 if (insn
& (1 << 11)) {
11560 tmp
= tcg_temp_new_i32();
11561 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11562 store_reg(s
, rd
, tmp
);
11565 tmp
= load_reg(s
, rd
);
11566 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11567 tcg_temp_free_i32(tmp
);
11569 tcg_temp_free_i32(addr
);
11573 /* load/store halfword immediate offset */
11575 rn
= (insn
>> 3) & 7;
11576 addr
= load_reg(s
, rn
);
11577 val
= (insn
>> 5) & 0x3e;
11578 tcg_gen_addi_i32(addr
, addr
, val
);
11580 if (insn
& (1 << 11)) {
11582 tmp
= tcg_temp_new_i32();
11583 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11584 store_reg(s
, rd
, tmp
);
11587 tmp
= load_reg(s
, rd
);
11588 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11589 tcg_temp_free_i32(tmp
);
11591 tcg_temp_free_i32(addr
);
11595 /* load/store from stack */
11596 rd
= (insn
>> 8) & 7;
11597 addr
= load_reg(s
, 13);
11598 val
= (insn
& 0xff) * 4;
11599 tcg_gen_addi_i32(addr
, addr
, val
);
11601 if (insn
& (1 << 11)) {
11603 tmp
= tcg_temp_new_i32();
11604 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11605 store_reg(s
, rd
, tmp
);
11608 tmp
= load_reg(s
, rd
);
11609 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11610 tcg_temp_free_i32(tmp
);
11612 tcg_temp_free_i32(addr
);
11616 /* add to high reg */
11617 rd
= (insn
>> 8) & 7;
11618 if (insn
& (1 << 11)) {
11620 tmp
= load_reg(s
, 13);
11622 /* PC. bit 1 is ignored. */
11623 tmp
= tcg_temp_new_i32();
11624 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11626 val
= (insn
& 0xff) * 4;
11627 tcg_gen_addi_i32(tmp
, tmp
, val
);
11628 store_reg(s
, rd
, tmp
);
11633 op
= (insn
>> 8) & 0xf;
11636 /* adjust stack pointer */
11637 tmp
= load_reg(s
, 13);
11638 val
= (insn
& 0x7f) * 4;
11639 if (insn
& (1 << 7))
11640 val
= -(int32_t)val
;
11641 tcg_gen_addi_i32(tmp
, tmp
, val
);
11642 store_reg(s
, 13, tmp
);
11645 case 2: /* sign/zero extend. */
11648 rm
= (insn
>> 3) & 7;
11649 tmp
= load_reg(s
, rm
);
11650 switch ((insn
>> 6) & 3) {
11651 case 0: gen_sxth(tmp
); break;
11652 case 1: gen_sxtb(tmp
); break;
11653 case 2: gen_uxth(tmp
); break;
11654 case 3: gen_uxtb(tmp
); break;
11656 store_reg(s
, rd
, tmp
);
11658 case 4: case 5: case 0xc: case 0xd:
11660 addr
= load_reg(s
, 13);
11661 if (insn
& (1 << 8))
11665 for (i
= 0; i
< 8; i
++) {
11666 if (insn
& (1 << i
))
11669 if ((insn
& (1 << 11)) == 0) {
11670 tcg_gen_addi_i32(addr
, addr
, -offset
);
11672 for (i
= 0; i
< 8; i
++) {
11673 if (insn
& (1 << i
)) {
11674 if (insn
& (1 << 11)) {
11676 tmp
= tcg_temp_new_i32();
11677 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11678 store_reg(s
, i
, tmp
);
11681 tmp
= load_reg(s
, i
);
11682 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11683 tcg_temp_free_i32(tmp
);
11685 /* advance to the next address. */
11686 tcg_gen_addi_i32(addr
, addr
, 4);
11690 if (insn
& (1 << 8)) {
11691 if (insn
& (1 << 11)) {
11693 tmp
= tcg_temp_new_i32();
11694 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11695 /* don't set the pc until the rest of the instruction
11699 tmp
= load_reg(s
, 14);
11700 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11701 tcg_temp_free_i32(tmp
);
11703 tcg_gen_addi_i32(addr
, addr
, 4);
11705 if ((insn
& (1 << 11)) == 0) {
11706 tcg_gen_addi_i32(addr
, addr
, -offset
);
11708 /* write back the new stack pointer */
11709 store_reg(s
, 13, addr
);
11710 /* set the new PC value */
11711 if ((insn
& 0x0900) == 0x0900) {
11712 store_reg_from_load(s
, 15, tmp
);
11716 case 1: case 3: case 9: case 11: /* czb */
11718 tmp
= load_reg(s
, rm
);
11719 s
->condlabel
= gen_new_label();
11721 if (insn
& (1 << 11))
11722 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11724 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11725 tcg_temp_free_i32(tmp
);
11726 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11727 val
= (uint32_t)s
->pc
+ 2;
11732 case 15: /* IT, nop-hint. */
11733 if ((insn
& 0xf) == 0) {
11734 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11738 s
->condexec_cond
= (insn
>> 4) & 0xe;
11739 s
->condexec_mask
= insn
& 0x1f;
11740 /* No actual code generated for this insn, just setup state. */
11743 case 0xe: /* bkpt */
11745 int imm8
= extract32(insn
, 0, 8);
11747 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11748 default_exception_el(s
));
11752 case 0xa: /* rev, and hlt */
11754 int op1
= extract32(insn
, 6, 2);
11758 int imm6
= extract32(insn
, 0, 6);
11764 /* Otherwise this is rev */
11766 rn
= (insn
>> 3) & 0x7;
11768 tmp
= load_reg(s
, rn
);
11770 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11771 case 1: gen_rev16(tmp
); break;
11772 case 3: gen_revsh(tmp
); break;
11774 g_assert_not_reached();
11776 store_reg(s
, rd
, tmp
);
11781 switch ((insn
>> 5) & 7) {
11785 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11786 gen_helper_setend(cpu_env
);
11787 s
->base
.is_jmp
= DISAS_UPDATE
;
11796 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11797 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11800 addr
= tcg_const_i32(19);
11801 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11802 tcg_temp_free_i32(addr
);
11806 addr
= tcg_const_i32(16);
11807 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11808 tcg_temp_free_i32(addr
);
11810 tcg_temp_free_i32(tmp
);
11813 if (insn
& (1 << 4)) {
11814 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11818 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11833 /* load/store multiple */
11834 TCGv_i32 loaded_var
= NULL
;
11835 rn
= (insn
>> 8) & 0x7;
11836 addr
= load_reg(s
, rn
);
11837 for (i
= 0; i
< 8; i
++) {
11838 if (insn
& (1 << i
)) {
11839 if (insn
& (1 << 11)) {
11841 tmp
= tcg_temp_new_i32();
11842 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11846 store_reg(s
, i
, tmp
);
11850 tmp
= load_reg(s
, i
);
11851 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11852 tcg_temp_free_i32(tmp
);
11854 /* advance to the next address */
11855 tcg_gen_addi_i32(addr
, addr
, 4);
11858 if ((insn
& (1 << rn
)) == 0) {
11859 /* base reg not in list: base register writeback */
11860 store_reg(s
, rn
, addr
);
11862 /* base reg in list: if load, complete it now */
11863 if (insn
& (1 << 11)) {
11864 store_reg(s
, rn
, loaded_var
);
11866 tcg_temp_free_i32(addr
);
11871 /* conditional branch or swi */
11872 cond
= (insn
>> 8) & 0xf;
11878 gen_set_pc_im(s
, s
->pc
);
11879 s
->svc_imm
= extract32(insn
, 0, 8);
11880 s
->base
.is_jmp
= DISAS_SWI
;
11883 /* generate a conditional jump to next instruction */
11884 s
->condlabel
= gen_new_label();
11885 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11888 /* jump to the offset */
11889 val
= (uint32_t)s
->pc
+ 2;
11890 offset
= ((int32_t)insn
<< 24) >> 24;
11891 val
+= offset
<< 1;
11896 if (insn
& (1 << 11)) {
11897 /* thumb_insn_is_16bit() ensures we can't get here for
11898 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11899 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11901 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11903 offset
= ((insn
& 0x7ff) << 1);
11904 tmp
= load_reg(s
, 14);
11905 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11906 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
11908 tmp2
= tcg_temp_new_i32();
11909 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
11910 store_reg(s
, 14, tmp2
);
11914 /* unconditional branch */
11915 val
= (uint32_t)s
->pc
;
11916 offset
= ((int32_t)insn
<< 21) >> 21;
11917 val
+= (offset
<< 1) + 2;
11922 /* thumb_insn_is_16bit() ensures we can't get here for
11923 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11925 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11927 if (insn
& (1 << 11)) {
11928 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11929 offset
= ((insn
& 0x7ff) << 1) | 1;
11930 tmp
= load_reg(s
, 14);
11931 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11933 tmp2
= tcg_temp_new_i32();
11934 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
11935 store_reg(s
, 14, tmp2
);
11938 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11939 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
11941 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
11948 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11949 default_exception_el(s
));
11952 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11954 /* Return true if the insn at dc->pc might cross a page boundary.
11955 * (False positives are OK, false negatives are not.)
11956 * We know this is a Thumb insn, and our caller ensures we are
11957 * only called if dc->pc is less than 4 bytes from the page
11958 * boundary, so we cross the page if the first 16 bits indicate
11959 * that this is a 32 bit insn.
11961 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11963 return !thumb_insn_is_16bit(s
, insn
);
11966 static int arm_tr_init_disas_context(DisasContextBase
*dcbase
,
11967 CPUState
*cs
, int max_insns
)
11969 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11970 CPUARMState
*env
= cs
->env_ptr
;
11971 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11973 dc
->pc
= dc
->base
.pc_first
;
11977 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11978 * there is no secure EL1, so we route exceptions to EL3.
11980 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11981 !arm_el_is_aa64(env
, 3);
11982 dc
->thumb
= ARM_TBFLAG_THUMB(dc
->base
.tb
->flags
);
11983 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(dc
->base
.tb
->flags
);
11984 dc
->be_data
= ARM_TBFLAG_BE_DATA(dc
->base
.tb
->flags
) ? MO_BE
: MO_LE
;
11985 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) & 0xf) << 1;
11986 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) >> 4;
11987 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, ARM_TBFLAG_MMUIDX(dc
->base
.tb
->flags
));
11988 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11989 #if !defined(CONFIG_USER_ONLY)
11990 dc
->user
= (dc
->current_el
== 0);
11992 dc
->ns
= ARM_TBFLAG_NS(dc
->base
.tb
->flags
);
11993 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(dc
->base
.tb
->flags
);
11994 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(dc
->base
.tb
->flags
);
11995 dc
->vec_len
= ARM_TBFLAG_VECLEN(dc
->base
.tb
->flags
);
11996 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(dc
->base
.tb
->flags
);
11997 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(dc
->base
.tb
->flags
);
11998 dc
->v7m_handler_mode
= ARM_TBFLAG_HANDLER(dc
->base
.tb
->flags
);
11999 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
12000 regime_is_secure(env
, dc
->mmu_idx
);
12001 dc
->cp_regs
= cpu
->cp_regs
;
12002 dc
->features
= env
->features
;
12004 /* Single step state. The code-generation logic here is:
12006 * generate code with no special handling for single-stepping (except
12007 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12008 * this happens anyway because those changes are all system register or
12010 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12011 * emit code for one insn
12012 * emit code to clear PSTATE.SS
12013 * emit code to generate software step exception for completed step
12014 * end TB (as usual for having generated an exception)
12015 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12016 * emit code to generate a software step exception
12019 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(dc
->base
.tb
->flags
);
12020 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(dc
->base
.tb
->flags
);
12021 dc
->is_ldex
= false;
12022 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
12024 dc
->next_page_start
=
12025 (dc
->base
.pc_first
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
12027 /* If architectural single step active, limit to 1. */
12028 if (is_singlestepping(dc
)) {
12032 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12033 to those left on the page. */
12035 int bound
= (dc
->next_page_start
- dc
->base
.pc_first
) / 4;
12036 max_insns
= MIN(max_insns
, bound
);
12039 cpu_F0s
= tcg_temp_new_i32();
12040 cpu_F1s
= tcg_temp_new_i32();
12041 cpu_F0d
= tcg_temp_new_i64();
12042 cpu_F1d
= tcg_temp_new_i64();
12045 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12046 cpu_M0
= tcg_temp_new_i64();
12051 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12053 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12055 /* A note on handling of the condexec (IT) bits:
12057 * We want to avoid the overhead of having to write the updated condexec
12058 * bits back to the CPUARMState for every instruction in an IT block. So:
12059 * (1) if the condexec bits are not already zero then we write
12060 * zero back into the CPUARMState now. This avoids complications trying
12061 * to do it at the end of the block. (For example if we don't do this
12062 * it's hard to identify whether we can safely skip writing condexec
12063 * at the end of the TB, which we definitely want to do for the case
12064 * where a TB doesn't do anything with the IT state at all.)
12065 * (2) if we are going to leave the TB then we call gen_set_condexec()
12066 * which will write the correct value into CPUARMState if zero is wrong.
12067 * This is done both for leaving the TB at the end, and for leaving
12068 * it because of an exception we know will happen, which is done in
12069 * gen_exception_insn(). The latter is necessary because we need to
12070 * leave the TB with the PC/IT state just prior to execution of the
12071 * instruction which caused the exception.
12072 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12073 * then the CPUARMState will be wrong and we need to reset it.
12074 * This is handled in the same way as restoration of the
12075 * PC in these situations; we save the value of the condexec bits
12076 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12077 * then uses this to restore them after an exception.
12079 * Note that there are no instructions which can read the condexec
12080 * bits, and none which can write non-static values to them, so
12081 * we don't need to care about whether CPUARMState is correct in the
12085 /* Reset the conditional execution bits immediately. This avoids
12086 complications trying to do it at the end of the block. */
12087 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
12088 TCGv_i32 tmp
= tcg_temp_new_i32();
12089 tcg_gen_movi_i32(tmp
, 0);
12090 store_cpu_field(tmp
, condexec_bits
);
12092 tcg_clear_temp_count();
12095 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12097 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12099 tcg_gen_insn_start(dc
->pc
,
12100 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
12102 dc
->insn_start
= tcg_last_op();
12105 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
12106 const CPUBreakpoint
*bp
)
12108 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12110 if (bp
->flags
& BP_CPU
) {
12111 gen_set_condexec(dc
);
12112 gen_set_pc_im(dc
, dc
->pc
);
12113 gen_helper_check_breakpoints(cpu_env
);
12114 /* End the TB early; it's likely not going to be executed */
12115 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12117 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
12118 /* The address covered by the breakpoint must be
12119 included in [tb->pc, tb->pc + tb->size) in order
12120 to for it to be properly cleared -- thus we
12121 increment the PC here so that the logic setting
12122 tb->size below does the right thing. */
12123 /* TODO: Advance PC by correct instruction length to
12124 * avoid disassembler error messages */
12126 dc
->base
.is_jmp
= DISAS_NORETURN
;
12132 static bool arm_pre_translate_insn(DisasContext
*dc
)
12134 #ifdef CONFIG_USER_ONLY
12135 /* Intercept jump to the magic kernel page. */
12136 if (dc
->pc
>= 0xffff0000) {
12137 /* We always get here via a jump, so know we are not in a
12138 conditional execution block. */
12139 gen_exception_internal(EXCP_KERNEL_TRAP
);
12140 dc
->base
.is_jmp
= DISAS_NORETURN
;
12145 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12146 /* Singlestep state is Active-pending.
12147 * If we're in this state at the start of a TB then either
12148 * a) we just took an exception to an EL which is being debugged
12149 * and this is the first insn in the exception handler
12150 * b) debug exceptions were masked and we just unmasked them
12151 * without changing EL (eg by clearing PSTATE.D)
12152 * In either case we're going to take a swstep exception in the
12153 * "did not step an insn" case, and so the syndrome ISV and EX
12154 * bits should be zero.
12156 assert(dc
->base
.num_insns
== 1);
12157 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
12158 default_exception_el(dc
));
12159 dc
->base
.is_jmp
= DISAS_NORETURN
;
12166 static void arm_post_translate_insn(DisasContext
*dc
)
12168 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12169 gen_set_label(dc
->condlabel
);
12172 dc
->base
.pc_next
= dc
->pc
;
12173 translator_loop_temp_check(&dc
->base
);
12176 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12178 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12179 CPUARMState
*env
= cpu
->env_ptr
;
12182 if (arm_pre_translate_insn(dc
)) {
12186 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12189 disas_arm_insn(dc
, insn
);
12191 arm_post_translate_insn(dc
);
12193 /* ARM is a fixed-length ISA. We performed the cross-page check
12194 in init_disas_context by adjusting max_insns. */
12197 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
12199 /* Return true if this Thumb insn is always unconditional,
12200 * even inside an IT block. This is true of only a very few
12201 * instructions: BKPT, HLT, and SG.
12203 * A larger class of instructions are UNPREDICTABLE if used
12204 * inside an IT block; we do not need to detect those here, because
12205 * what we do by default (perform the cc check and update the IT
12206 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12207 * choice for those situations.
12209 * insn is either a 16-bit or a 32-bit instruction; the two are
12210 * distinguishable because for the 16-bit case the top 16 bits
12211 * are zeroes, and that isn't a valid 32-bit encoding.
12213 if ((insn
& 0xffffff00) == 0xbe00) {
12218 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12219 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
12220 /* HLT: v8A only. This is unconditional even when it is going to
12221 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12222 * For v7 cores this was a plain old undefined encoding and so
12223 * honours its cc check. (We might be using the encoding as
12224 * a semihosting trap, but we don't change the cc check behaviour
12225 * on that account, because a debugger connected to a real v7A
12226 * core and emulating semihosting traps by catching the UNDEF
12227 * exception would also only see cases where the cc check passed.
12228 * No guest code should be trying to do a HLT semihosting trap
12229 * in an IT block anyway.
12234 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12235 arm_dc_feature(s
, ARM_FEATURE_M
)) {
12243 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12245 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12246 CPUARMState
*env
= cpu
->env_ptr
;
12250 if (arm_pre_translate_insn(dc
)) {
12254 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12255 is_16bit
= thumb_insn_is_16bit(dc
, insn
);
12258 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12260 insn
= insn
<< 16 | insn2
;
12265 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
12266 uint32_t cond
= dc
->condexec_cond
;
12268 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
12269 dc
->condlabel
= gen_new_label();
12270 arm_gen_test_cc(cond
^ 1, dc
->condlabel
);
12276 disas_thumb_insn(dc
, insn
);
12278 disas_thumb2_insn(dc
, insn
);
12281 /* Advance the Thumb condexec condition. */
12282 if (dc
->condexec_mask
) {
12283 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
12284 ((dc
->condexec_mask
>> 4) & 1));
12285 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12286 if (dc
->condexec_mask
== 0) {
12287 dc
->condexec_cond
= 0;
12291 arm_post_translate_insn(dc
);
12293 /* Thumb is a variable-length ISA. Stop translation when the next insn
12294 * will touch a new page. This ensures that prefetch aborts occur at
12297 * We want to stop the TB if the next insn starts in a new page,
12298 * or if it spans between this page and the next. This means that
12299 * if we're looking at the last halfword in the page we need to
12300 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12301 * or a 32-bit Thumb insn (which won't).
12302 * This is to avoid generating a silly TB with a single 16-bit insn
12303 * in it at the end of this page (which would execute correctly
12304 * but isn't very efficient).
12306 if (dc
->base
.is_jmp
== DISAS_NEXT
12307 && (dc
->pc
>= dc
->next_page_start
12308 || (dc
->pc
>= dc
->next_page_start
- 3
12309 && insn_crosses_page(env
, dc
)))) {
12310 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12314 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
12316 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12318 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
12319 /* FIXME: This can theoretically happen with self-modifying code. */
12320 cpu_abort(cpu
, "IO on conditional branch instruction");
12323 /* At this stage dc->condjmp will only be set when the skipped
12324 instruction was a conditional branch or trap, and the PC has
12325 already been written. */
12326 gen_set_condexec(dc
);
12327 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12328 /* Exception return branches need some special case code at the
12329 * end of the TB, which is complex enough that it has to
12330 * handle the single-step vs not and the condition-failed
12331 * insn codepath itself.
12333 gen_bx_excret_final_code(dc
);
12334 } else if (unlikely(is_singlestepping(dc
))) {
12335 /* Unconditional and "condition passed" instruction codepath. */
12336 switch (dc
->base
.is_jmp
) {
12338 gen_ss_advance(dc
);
12339 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12340 default_exception_el(dc
));
12343 gen_ss_advance(dc
);
12344 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12347 gen_ss_advance(dc
);
12348 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12351 case DISAS_TOO_MANY
:
12353 gen_set_pc_im(dc
, dc
->pc
);
12356 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12357 gen_singlestep_exception(dc
);
12359 case DISAS_NORETURN
:
12363 /* While branches must always occur at the end of an IT block,
12364 there are a few other things that can cause us to terminate
12365 the TB in the middle of an IT block:
12366 - Exception generating instructions (bkpt, swi, undefined).
12368 - Hardware watchpoints.
12369 Hardware breakpoints have already been handled and skip this code.
12371 switch(dc
->base
.is_jmp
) {
12373 case DISAS_TOO_MANY
:
12374 gen_goto_tb(dc
, 1, dc
->pc
);
12380 gen_set_pc_im(dc
, dc
->pc
);
12383 /* indicate that the hash table must be used to find the next TB */
12384 tcg_gen_exit_tb(0);
12386 case DISAS_NORETURN
:
12387 /* nothing more to generate */
12391 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
12392 !(dc
->insn
& (1U << 31))) ? 2 : 4);
12394 gen_helper_wfi(cpu_env
, tmp
);
12395 tcg_temp_free_i32(tmp
);
12396 /* The helper doesn't necessarily throw an exception, but we
12397 * must go back to the main loop to check for interrupts anyway.
12399 tcg_gen_exit_tb(0);
12403 gen_helper_wfe(cpu_env
);
12406 gen_helper_yield(cpu_env
);
12409 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12410 default_exception_el(dc
));
12413 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12416 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12422 /* "Condition failed" instruction codepath for the branch/trap insn */
12423 gen_set_label(dc
->condlabel
);
12424 gen_set_condexec(dc
);
12425 if (unlikely(is_singlestepping(dc
))) {
12426 gen_set_pc_im(dc
, dc
->pc
);
12427 gen_singlestep_exception(dc
);
12429 gen_goto_tb(dc
, 1, dc
->pc
);
12433 /* Functions above can change dc->pc, so re-align db->pc_next */
12434 dc
->base
.pc_next
= dc
->pc
;
12437 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
12439 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12441 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
12442 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
12445 static const TranslatorOps arm_translator_ops
= {
12446 .init_disas_context
= arm_tr_init_disas_context
,
12447 .tb_start
= arm_tr_tb_start
,
12448 .insn_start
= arm_tr_insn_start
,
12449 .breakpoint_check
= arm_tr_breakpoint_check
,
12450 .translate_insn
= arm_tr_translate_insn
,
12451 .tb_stop
= arm_tr_tb_stop
,
12452 .disas_log
= arm_tr_disas_log
,
12455 static const TranslatorOps thumb_translator_ops
= {
12456 .init_disas_context
= arm_tr_init_disas_context
,
12457 .tb_start
= arm_tr_tb_start
,
12458 .insn_start
= arm_tr_insn_start
,
12459 .breakpoint_check
= arm_tr_breakpoint_check
,
12460 .translate_insn
= thumb_tr_translate_insn
,
12461 .tb_stop
= arm_tr_tb_stop
,
12462 .disas_log
= arm_tr_disas_log
,
12465 /* generate intermediate code for basic block 'tb'. */
12466 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
)
12469 const TranslatorOps
*ops
= &arm_translator_ops
;
12471 if (ARM_TBFLAG_THUMB(tb
->flags
)) {
12472 ops
= &thumb_translator_ops
;
12474 #ifdef TARGET_AARCH64
12475 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
12476 ops
= &aarch64_translator_ops
;
12480 translator_loop(ops
, &dc
.base
, cpu
, tb
);
12483 static const char *cpu_mode_names
[16] = {
12484 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12485 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12488 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12491 ARMCPU
*cpu
= ARM_CPU(cs
);
12492 CPUARMState
*env
= &cpu
->env
;
12496 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12500 for(i
=0;i
<16;i
++) {
12501 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12503 cpu_fprintf(f
, "\n");
12505 cpu_fprintf(f
, " ");
12508 if (arm_feature(env
, ARM_FEATURE_M
)) {
12509 uint32_t xpsr
= xpsr_read(env
);
12511 const char *ns_status
= "";
12513 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
12514 ns_status
= env
->v7m
.secure
? "S " : "NS ";
12517 if (xpsr
& XPSR_EXCP
) {
12520 if (env
->v7m
.control
[env
->v7m
.secure
] & R_V7M_CONTROL_NPRIV_MASK
) {
12521 mode
= "unpriv-thread";
12523 mode
= "priv-thread";
12527 cpu_fprintf(f
, "XPSR=%08x %c%c%c%c %c %s%s\n",
12529 xpsr
& XPSR_N
? 'N' : '-',
12530 xpsr
& XPSR_Z
? 'Z' : '-',
12531 xpsr
& XPSR_C
? 'C' : '-',
12532 xpsr
& XPSR_V
? 'V' : '-',
12533 xpsr
& XPSR_T
? 'T' : 'A',
12537 uint32_t psr
= cpsr_read(env
);
12538 const char *ns_status
= "";
12540 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12541 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12542 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12545 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12547 psr
& CPSR_N
? 'N' : '-',
12548 psr
& CPSR_Z
? 'Z' : '-',
12549 psr
& CPSR_C
? 'C' : '-',
12550 psr
& CPSR_V
? 'V' : '-',
12551 psr
& CPSR_T
? 'T' : 'A',
12553 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12556 if (flags
& CPU_DUMP_FPU
) {
12557 int numvfpregs
= 0;
12558 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12561 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12564 for (i
= 0; i
< numvfpregs
; i
++) {
12565 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12566 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12567 i
* 2, (uint32_t)v
,
12568 i
* 2 + 1, (uint32_t)(v
>> 32),
12571 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12575 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12576 target_ulong
*data
)
12580 env
->condexec_bits
= 0;
12581 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12583 env
->regs
[15] = data
[0];
12584 env
->condexec_bits
= data
[1];
12585 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;