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 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1564 TCGv_ptr ret
= tcg_temp_new_ptr();
1565 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1569 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1570 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1571 #define tcg_gen_st_f32 tcg_gen_st_i32
1572 #define tcg_gen_st_f64 tcg_gen_st_i64
1574 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1577 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1579 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1582 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1585 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1587 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1590 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1593 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1595 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1598 #define ARM_CP_RW_BIT (1 << 20)
1600 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1602 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1605 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1607 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1610 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1612 TCGv_i32 var
= tcg_temp_new_i32();
1613 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1617 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1619 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1620 tcg_temp_free_i32(var
);
1623 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1625 iwmmxt_store_reg(cpu_M0
, rn
);
1628 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1630 iwmmxt_load_reg(cpu_M0
, rn
);
1633 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1635 iwmmxt_load_reg(cpu_V1
, rn
);
1636 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1639 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1641 iwmmxt_load_reg(cpu_V1
, rn
);
1642 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1645 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1647 iwmmxt_load_reg(cpu_V1
, rn
);
1648 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1651 #define IWMMXT_OP(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_M0, cpu_V1); \
1658 #define IWMMXT_OP_ENV(name) \
1659 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1661 iwmmxt_load_reg(cpu_V1, rn); \
1662 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1665 #define IWMMXT_OP_ENV_SIZE(name) \
1666 IWMMXT_OP_ENV(name##b) \
1667 IWMMXT_OP_ENV(name##w) \
1668 IWMMXT_OP_ENV(name##l)
1670 #define IWMMXT_OP_ENV1(name) \
1671 static inline void gen_op_iwmmxt_##name##_M0(void) \
1673 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1687 IWMMXT_OP_ENV_SIZE(unpackl
)
1688 IWMMXT_OP_ENV_SIZE(unpackh
)
1690 IWMMXT_OP_ENV1(unpacklub
)
1691 IWMMXT_OP_ENV1(unpackluw
)
1692 IWMMXT_OP_ENV1(unpacklul
)
1693 IWMMXT_OP_ENV1(unpackhub
)
1694 IWMMXT_OP_ENV1(unpackhuw
)
1695 IWMMXT_OP_ENV1(unpackhul
)
1696 IWMMXT_OP_ENV1(unpacklsb
)
1697 IWMMXT_OP_ENV1(unpacklsw
)
1698 IWMMXT_OP_ENV1(unpacklsl
)
1699 IWMMXT_OP_ENV1(unpackhsb
)
1700 IWMMXT_OP_ENV1(unpackhsw
)
1701 IWMMXT_OP_ENV1(unpackhsl
)
1703 IWMMXT_OP_ENV_SIZE(cmpeq
)
1704 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1705 IWMMXT_OP_ENV_SIZE(cmpgts
)
1707 IWMMXT_OP_ENV_SIZE(mins
)
1708 IWMMXT_OP_ENV_SIZE(minu
)
1709 IWMMXT_OP_ENV_SIZE(maxs
)
1710 IWMMXT_OP_ENV_SIZE(maxu
)
1712 IWMMXT_OP_ENV_SIZE(subn
)
1713 IWMMXT_OP_ENV_SIZE(addn
)
1714 IWMMXT_OP_ENV_SIZE(subu
)
1715 IWMMXT_OP_ENV_SIZE(addu
)
1716 IWMMXT_OP_ENV_SIZE(subs
)
1717 IWMMXT_OP_ENV_SIZE(adds
)
1719 IWMMXT_OP_ENV(avgb0
)
1720 IWMMXT_OP_ENV(avgb1
)
1721 IWMMXT_OP_ENV(avgw0
)
1722 IWMMXT_OP_ENV(avgw1
)
1724 IWMMXT_OP_ENV(packuw
)
1725 IWMMXT_OP_ENV(packul
)
1726 IWMMXT_OP_ENV(packuq
)
1727 IWMMXT_OP_ENV(packsw
)
1728 IWMMXT_OP_ENV(packsl
)
1729 IWMMXT_OP_ENV(packsq
)
1731 static void gen_op_iwmmxt_set_mup(void)
1734 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1735 tcg_gen_ori_i32(tmp
, tmp
, 2);
1736 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1739 static void gen_op_iwmmxt_set_cup(void)
1742 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1743 tcg_gen_ori_i32(tmp
, tmp
, 1);
1744 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1747 static void gen_op_iwmmxt_setpsr_nz(void)
1749 TCGv_i32 tmp
= tcg_temp_new_i32();
1750 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1751 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1754 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1756 iwmmxt_load_reg(cpu_V1
, rn
);
1757 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1758 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1761 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1768 rd
= (insn
>> 16) & 0xf;
1769 tmp
= load_reg(s
, rd
);
1771 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1772 if (insn
& (1 << 24)) {
1774 if (insn
& (1 << 23))
1775 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1777 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1778 tcg_gen_mov_i32(dest
, tmp
);
1779 if (insn
& (1 << 21))
1780 store_reg(s
, rd
, tmp
);
1782 tcg_temp_free_i32(tmp
);
1783 } else if (insn
& (1 << 21)) {
1785 tcg_gen_mov_i32(dest
, tmp
);
1786 if (insn
& (1 << 23))
1787 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1789 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1790 store_reg(s
, rd
, tmp
);
1791 } else if (!(insn
& (1 << 23)))
1796 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1798 int rd
= (insn
>> 0) & 0xf;
1801 if (insn
& (1 << 8)) {
1802 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1805 tmp
= iwmmxt_load_creg(rd
);
1808 tmp
= tcg_temp_new_i32();
1809 iwmmxt_load_reg(cpu_V0
, rd
);
1810 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1812 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1813 tcg_gen_mov_i32(dest
, tmp
);
1814 tcg_temp_free_i32(tmp
);
1818 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1819 (ie. an undefined instruction). */
1820 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1823 int rdhi
, rdlo
, rd0
, rd1
, i
;
1825 TCGv_i32 tmp
, tmp2
, tmp3
;
1827 if ((insn
& 0x0e000e00) == 0x0c000000) {
1828 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1830 rdlo
= (insn
>> 12) & 0xf;
1831 rdhi
= (insn
>> 16) & 0xf;
1832 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1833 iwmmxt_load_reg(cpu_V0
, wrd
);
1834 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1835 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1836 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1837 } else { /* TMCRR */
1838 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1839 iwmmxt_store_reg(cpu_V0
, wrd
);
1840 gen_op_iwmmxt_set_mup();
1845 wrd
= (insn
>> 12) & 0xf;
1846 addr
= tcg_temp_new_i32();
1847 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1848 tcg_temp_free_i32(addr
);
1851 if (insn
& ARM_CP_RW_BIT
) {
1852 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1853 tmp
= tcg_temp_new_i32();
1854 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1855 iwmmxt_store_creg(wrd
, tmp
);
1858 if (insn
& (1 << 8)) {
1859 if (insn
& (1 << 22)) { /* WLDRD */
1860 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1862 } else { /* WLDRW wRd */
1863 tmp
= tcg_temp_new_i32();
1864 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1867 tmp
= tcg_temp_new_i32();
1868 if (insn
& (1 << 22)) { /* WLDRH */
1869 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1870 } else { /* WLDRB */
1871 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1875 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1876 tcg_temp_free_i32(tmp
);
1878 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1881 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1882 tmp
= iwmmxt_load_creg(wrd
);
1883 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1885 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1886 tmp
= tcg_temp_new_i32();
1887 if (insn
& (1 << 8)) {
1888 if (insn
& (1 << 22)) { /* WSTRD */
1889 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1890 } else { /* WSTRW wRd */
1891 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1892 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1895 if (insn
& (1 << 22)) { /* WSTRH */
1896 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1897 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1898 } else { /* WSTRB */
1899 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1900 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1904 tcg_temp_free_i32(tmp
);
1906 tcg_temp_free_i32(addr
);
1910 if ((insn
& 0x0f000000) != 0x0e000000)
1913 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1914 case 0x000: /* WOR */
1915 wrd
= (insn
>> 12) & 0xf;
1916 rd0
= (insn
>> 0) & 0xf;
1917 rd1
= (insn
>> 16) & 0xf;
1918 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1919 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1920 gen_op_iwmmxt_setpsr_nz();
1921 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1922 gen_op_iwmmxt_set_mup();
1923 gen_op_iwmmxt_set_cup();
1925 case 0x011: /* TMCR */
1928 rd
= (insn
>> 12) & 0xf;
1929 wrd
= (insn
>> 16) & 0xf;
1931 case ARM_IWMMXT_wCID
:
1932 case ARM_IWMMXT_wCASF
:
1934 case ARM_IWMMXT_wCon
:
1935 gen_op_iwmmxt_set_cup();
1937 case ARM_IWMMXT_wCSSF
:
1938 tmp
= iwmmxt_load_creg(wrd
);
1939 tmp2
= load_reg(s
, rd
);
1940 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1941 tcg_temp_free_i32(tmp2
);
1942 iwmmxt_store_creg(wrd
, tmp
);
1944 case ARM_IWMMXT_wCGR0
:
1945 case ARM_IWMMXT_wCGR1
:
1946 case ARM_IWMMXT_wCGR2
:
1947 case ARM_IWMMXT_wCGR3
:
1948 gen_op_iwmmxt_set_cup();
1949 tmp
= load_reg(s
, rd
);
1950 iwmmxt_store_creg(wrd
, tmp
);
1956 case 0x100: /* WXOR */
1957 wrd
= (insn
>> 12) & 0xf;
1958 rd0
= (insn
>> 0) & 0xf;
1959 rd1
= (insn
>> 16) & 0xf;
1960 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1961 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1962 gen_op_iwmmxt_setpsr_nz();
1963 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1964 gen_op_iwmmxt_set_mup();
1965 gen_op_iwmmxt_set_cup();
1967 case 0x111: /* TMRC */
1970 rd
= (insn
>> 12) & 0xf;
1971 wrd
= (insn
>> 16) & 0xf;
1972 tmp
= iwmmxt_load_creg(wrd
);
1973 store_reg(s
, rd
, tmp
);
1975 case 0x300: /* WANDN */
1976 wrd
= (insn
>> 12) & 0xf;
1977 rd0
= (insn
>> 0) & 0xf;
1978 rd1
= (insn
>> 16) & 0xf;
1979 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1980 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1981 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1982 gen_op_iwmmxt_setpsr_nz();
1983 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1984 gen_op_iwmmxt_set_mup();
1985 gen_op_iwmmxt_set_cup();
1987 case 0x200: /* WAND */
1988 wrd
= (insn
>> 12) & 0xf;
1989 rd0
= (insn
>> 0) & 0xf;
1990 rd1
= (insn
>> 16) & 0xf;
1991 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1992 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1993 gen_op_iwmmxt_setpsr_nz();
1994 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1995 gen_op_iwmmxt_set_mup();
1996 gen_op_iwmmxt_set_cup();
1998 case 0x810: case 0xa10: /* WMADD */
1999 wrd
= (insn
>> 12) & 0xf;
2000 rd0
= (insn
>> 0) & 0xf;
2001 rd1
= (insn
>> 16) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2003 if (insn
& (1 << 21))
2004 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
2006 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
2007 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2008 gen_op_iwmmxt_set_mup();
2010 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2011 wrd
= (insn
>> 12) & 0xf;
2012 rd0
= (insn
>> 16) & 0xf;
2013 rd1
= (insn
>> 0) & 0xf;
2014 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2015 switch ((insn
>> 22) & 3) {
2017 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
2020 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
2023 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
2028 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2029 gen_op_iwmmxt_set_mup();
2030 gen_op_iwmmxt_set_cup();
2032 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2033 wrd
= (insn
>> 12) & 0xf;
2034 rd0
= (insn
>> 16) & 0xf;
2035 rd1
= (insn
>> 0) & 0xf;
2036 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2037 switch ((insn
>> 22) & 3) {
2039 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
2042 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
2045 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
2050 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2051 gen_op_iwmmxt_set_mup();
2052 gen_op_iwmmxt_set_cup();
2054 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2055 wrd
= (insn
>> 12) & 0xf;
2056 rd0
= (insn
>> 16) & 0xf;
2057 rd1
= (insn
>> 0) & 0xf;
2058 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2059 if (insn
& (1 << 22))
2060 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2062 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2063 if (!(insn
& (1 << 20)))
2064 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2065 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2066 gen_op_iwmmxt_set_mup();
2068 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2069 wrd
= (insn
>> 12) & 0xf;
2070 rd0
= (insn
>> 16) & 0xf;
2071 rd1
= (insn
>> 0) & 0xf;
2072 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2073 if (insn
& (1 << 21)) {
2074 if (insn
& (1 << 20))
2075 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2077 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2079 if (insn
& (1 << 20))
2080 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2082 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2084 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2085 gen_op_iwmmxt_set_mup();
2087 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2088 wrd
= (insn
>> 12) & 0xf;
2089 rd0
= (insn
>> 16) & 0xf;
2090 rd1
= (insn
>> 0) & 0xf;
2091 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2092 if (insn
& (1 << 21))
2093 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2095 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2096 if (!(insn
& (1 << 20))) {
2097 iwmmxt_load_reg(cpu_V1
, wrd
);
2098 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2100 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2101 gen_op_iwmmxt_set_mup();
2103 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2104 wrd
= (insn
>> 12) & 0xf;
2105 rd0
= (insn
>> 16) & 0xf;
2106 rd1
= (insn
>> 0) & 0xf;
2107 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2108 switch ((insn
>> 22) & 3) {
2110 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2113 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2116 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2121 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2122 gen_op_iwmmxt_set_mup();
2123 gen_op_iwmmxt_set_cup();
2125 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2126 wrd
= (insn
>> 12) & 0xf;
2127 rd0
= (insn
>> 16) & 0xf;
2128 rd1
= (insn
>> 0) & 0xf;
2129 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2130 if (insn
& (1 << 22)) {
2131 if (insn
& (1 << 20))
2132 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2134 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2136 if (insn
& (1 << 20))
2137 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2139 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2141 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2142 gen_op_iwmmxt_set_mup();
2143 gen_op_iwmmxt_set_cup();
2145 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2146 wrd
= (insn
>> 12) & 0xf;
2147 rd0
= (insn
>> 16) & 0xf;
2148 rd1
= (insn
>> 0) & 0xf;
2149 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2150 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2151 tcg_gen_andi_i32(tmp
, tmp
, 7);
2152 iwmmxt_load_reg(cpu_V1
, rd1
);
2153 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2154 tcg_temp_free_i32(tmp
);
2155 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2156 gen_op_iwmmxt_set_mup();
2158 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2159 if (((insn
>> 6) & 3) == 3)
2161 rd
= (insn
>> 12) & 0xf;
2162 wrd
= (insn
>> 16) & 0xf;
2163 tmp
= load_reg(s
, rd
);
2164 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2165 switch ((insn
>> 6) & 3) {
2167 tmp2
= tcg_const_i32(0xff);
2168 tmp3
= tcg_const_i32((insn
& 7) << 3);
2171 tmp2
= tcg_const_i32(0xffff);
2172 tmp3
= tcg_const_i32((insn
& 3) << 4);
2175 tmp2
= tcg_const_i32(0xffffffff);
2176 tmp3
= tcg_const_i32((insn
& 1) << 5);
2182 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2183 tcg_temp_free_i32(tmp3
);
2184 tcg_temp_free_i32(tmp2
);
2185 tcg_temp_free_i32(tmp
);
2186 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2187 gen_op_iwmmxt_set_mup();
2189 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2190 rd
= (insn
>> 12) & 0xf;
2191 wrd
= (insn
>> 16) & 0xf;
2192 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2194 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2195 tmp
= tcg_temp_new_i32();
2196 switch ((insn
>> 22) & 3) {
2198 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2199 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2201 tcg_gen_ext8s_i32(tmp
, tmp
);
2203 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2207 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2208 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2210 tcg_gen_ext16s_i32(tmp
, tmp
);
2212 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2216 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2217 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2220 store_reg(s
, rd
, tmp
);
2222 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2223 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2225 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2226 switch ((insn
>> 22) & 3) {
2228 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2231 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2234 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2237 tcg_gen_shli_i32(tmp
, tmp
, 28);
2239 tcg_temp_free_i32(tmp
);
2241 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2242 if (((insn
>> 6) & 3) == 3)
2244 rd
= (insn
>> 12) & 0xf;
2245 wrd
= (insn
>> 16) & 0xf;
2246 tmp
= load_reg(s
, rd
);
2247 switch ((insn
>> 6) & 3) {
2249 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2252 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2255 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2258 tcg_temp_free_i32(tmp
);
2259 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2260 gen_op_iwmmxt_set_mup();
2262 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2263 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2265 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2266 tmp2
= tcg_temp_new_i32();
2267 tcg_gen_mov_i32(tmp2
, tmp
);
2268 switch ((insn
>> 22) & 3) {
2270 for (i
= 0; i
< 7; i
++) {
2271 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2272 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2276 for (i
= 0; i
< 3; i
++) {
2277 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2278 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2282 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2283 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2287 tcg_temp_free_i32(tmp2
);
2288 tcg_temp_free_i32(tmp
);
2290 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2291 wrd
= (insn
>> 12) & 0xf;
2292 rd0
= (insn
>> 16) & 0xf;
2293 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2294 switch ((insn
>> 22) & 3) {
2296 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2299 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2302 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2307 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2308 gen_op_iwmmxt_set_mup();
2310 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2311 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2313 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2314 tmp2
= tcg_temp_new_i32();
2315 tcg_gen_mov_i32(tmp2
, tmp
);
2316 switch ((insn
>> 22) & 3) {
2318 for (i
= 0; i
< 7; i
++) {
2319 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2320 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2324 for (i
= 0; i
< 3; i
++) {
2325 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2326 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2330 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2331 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2335 tcg_temp_free_i32(tmp2
);
2336 tcg_temp_free_i32(tmp
);
2338 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2339 rd
= (insn
>> 12) & 0xf;
2340 rd0
= (insn
>> 16) & 0xf;
2341 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2343 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2344 tmp
= tcg_temp_new_i32();
2345 switch ((insn
>> 22) & 3) {
2347 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2350 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2353 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2356 store_reg(s
, rd
, tmp
);
2358 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2359 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2360 wrd
= (insn
>> 12) & 0xf;
2361 rd0
= (insn
>> 16) & 0xf;
2362 rd1
= (insn
>> 0) & 0xf;
2363 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2364 switch ((insn
>> 22) & 3) {
2366 if (insn
& (1 << 21))
2367 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2369 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2372 if (insn
& (1 << 21))
2373 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2375 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2378 if (insn
& (1 << 21))
2379 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2381 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2386 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2387 gen_op_iwmmxt_set_mup();
2388 gen_op_iwmmxt_set_cup();
2390 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2391 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2392 wrd
= (insn
>> 12) & 0xf;
2393 rd0
= (insn
>> 16) & 0xf;
2394 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2395 switch ((insn
>> 22) & 3) {
2397 if (insn
& (1 << 21))
2398 gen_op_iwmmxt_unpacklsb_M0();
2400 gen_op_iwmmxt_unpacklub_M0();
2403 if (insn
& (1 << 21))
2404 gen_op_iwmmxt_unpacklsw_M0();
2406 gen_op_iwmmxt_unpackluw_M0();
2409 if (insn
& (1 << 21))
2410 gen_op_iwmmxt_unpacklsl_M0();
2412 gen_op_iwmmxt_unpacklul_M0();
2417 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2418 gen_op_iwmmxt_set_mup();
2419 gen_op_iwmmxt_set_cup();
2421 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2422 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2423 wrd
= (insn
>> 12) & 0xf;
2424 rd0
= (insn
>> 16) & 0xf;
2425 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2426 switch ((insn
>> 22) & 3) {
2428 if (insn
& (1 << 21))
2429 gen_op_iwmmxt_unpackhsb_M0();
2431 gen_op_iwmmxt_unpackhub_M0();
2434 if (insn
& (1 << 21))
2435 gen_op_iwmmxt_unpackhsw_M0();
2437 gen_op_iwmmxt_unpackhuw_M0();
2440 if (insn
& (1 << 21))
2441 gen_op_iwmmxt_unpackhsl_M0();
2443 gen_op_iwmmxt_unpackhul_M0();
2448 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2449 gen_op_iwmmxt_set_mup();
2450 gen_op_iwmmxt_set_cup();
2452 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2453 case 0x214: case 0x614: case 0xa14: case 0xe14:
2454 if (((insn
>> 22) & 3) == 0)
2456 wrd
= (insn
>> 12) & 0xf;
2457 rd0
= (insn
>> 16) & 0xf;
2458 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2459 tmp
= tcg_temp_new_i32();
2460 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2461 tcg_temp_free_i32(tmp
);
2464 switch ((insn
>> 22) & 3) {
2466 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2469 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2472 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2475 tcg_temp_free_i32(tmp
);
2476 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2477 gen_op_iwmmxt_set_mup();
2478 gen_op_iwmmxt_set_cup();
2480 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2481 case 0x014: case 0x414: case 0x814: case 0xc14:
2482 if (((insn
>> 22) & 3) == 0)
2484 wrd
= (insn
>> 12) & 0xf;
2485 rd0
= (insn
>> 16) & 0xf;
2486 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2487 tmp
= tcg_temp_new_i32();
2488 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2489 tcg_temp_free_i32(tmp
);
2492 switch ((insn
>> 22) & 3) {
2494 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2497 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2500 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2503 tcg_temp_free_i32(tmp
);
2504 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2505 gen_op_iwmmxt_set_mup();
2506 gen_op_iwmmxt_set_cup();
2508 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2509 case 0x114: case 0x514: case 0x914: case 0xd14:
2510 if (((insn
>> 22) & 3) == 0)
2512 wrd
= (insn
>> 12) & 0xf;
2513 rd0
= (insn
>> 16) & 0xf;
2514 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2515 tmp
= tcg_temp_new_i32();
2516 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2517 tcg_temp_free_i32(tmp
);
2520 switch ((insn
>> 22) & 3) {
2522 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2525 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2528 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2531 tcg_temp_free_i32(tmp
);
2532 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2533 gen_op_iwmmxt_set_mup();
2534 gen_op_iwmmxt_set_cup();
2536 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2537 case 0x314: case 0x714: case 0xb14: case 0xf14:
2538 if (((insn
>> 22) & 3) == 0)
2540 wrd
= (insn
>> 12) & 0xf;
2541 rd0
= (insn
>> 16) & 0xf;
2542 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2543 tmp
= tcg_temp_new_i32();
2544 switch ((insn
>> 22) & 3) {
2546 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2547 tcg_temp_free_i32(tmp
);
2550 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2553 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2554 tcg_temp_free_i32(tmp
);
2557 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2560 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2561 tcg_temp_free_i32(tmp
);
2564 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2567 tcg_temp_free_i32(tmp
);
2568 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2569 gen_op_iwmmxt_set_mup();
2570 gen_op_iwmmxt_set_cup();
2572 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2573 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2574 wrd
= (insn
>> 12) & 0xf;
2575 rd0
= (insn
>> 16) & 0xf;
2576 rd1
= (insn
>> 0) & 0xf;
2577 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2578 switch ((insn
>> 22) & 3) {
2580 if (insn
& (1 << 21))
2581 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2583 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2586 if (insn
& (1 << 21))
2587 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2589 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2592 if (insn
& (1 << 21))
2593 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2595 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2600 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2601 gen_op_iwmmxt_set_mup();
2603 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2604 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2605 wrd
= (insn
>> 12) & 0xf;
2606 rd0
= (insn
>> 16) & 0xf;
2607 rd1
= (insn
>> 0) & 0xf;
2608 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2609 switch ((insn
>> 22) & 3) {
2611 if (insn
& (1 << 21))
2612 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2614 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2617 if (insn
& (1 << 21))
2618 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2620 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2623 if (insn
& (1 << 21))
2624 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2626 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2631 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2632 gen_op_iwmmxt_set_mup();
2634 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2635 case 0x402: case 0x502: case 0x602: case 0x702:
2636 wrd
= (insn
>> 12) & 0xf;
2637 rd0
= (insn
>> 16) & 0xf;
2638 rd1
= (insn
>> 0) & 0xf;
2639 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2640 tmp
= tcg_const_i32((insn
>> 20) & 3);
2641 iwmmxt_load_reg(cpu_V1
, rd1
);
2642 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2643 tcg_temp_free_i32(tmp
);
2644 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2645 gen_op_iwmmxt_set_mup();
2647 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2648 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2649 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2650 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2651 wrd
= (insn
>> 12) & 0xf;
2652 rd0
= (insn
>> 16) & 0xf;
2653 rd1
= (insn
>> 0) & 0xf;
2654 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2655 switch ((insn
>> 20) & 0xf) {
2657 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2660 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2663 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2666 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2669 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2672 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2675 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2678 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2681 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2686 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2687 gen_op_iwmmxt_set_mup();
2688 gen_op_iwmmxt_set_cup();
2690 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2691 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2692 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2693 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2694 wrd
= (insn
>> 12) & 0xf;
2695 rd0
= (insn
>> 16) & 0xf;
2696 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2697 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2698 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2699 tcg_temp_free_i32(tmp
);
2700 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2701 gen_op_iwmmxt_set_mup();
2702 gen_op_iwmmxt_set_cup();
2704 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2705 case 0x418: case 0x518: case 0x618: case 0x718:
2706 case 0x818: case 0x918: case 0xa18: case 0xb18:
2707 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2708 wrd
= (insn
>> 12) & 0xf;
2709 rd0
= (insn
>> 16) & 0xf;
2710 rd1
= (insn
>> 0) & 0xf;
2711 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2712 switch ((insn
>> 20) & 0xf) {
2714 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2717 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2720 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2723 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2726 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2729 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2732 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2735 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2738 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2743 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2744 gen_op_iwmmxt_set_mup();
2745 gen_op_iwmmxt_set_cup();
2747 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2748 case 0x408: case 0x508: case 0x608: case 0x708:
2749 case 0x808: case 0x908: case 0xa08: case 0xb08:
2750 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2751 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2753 wrd
= (insn
>> 12) & 0xf;
2754 rd0
= (insn
>> 16) & 0xf;
2755 rd1
= (insn
>> 0) & 0xf;
2756 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2757 switch ((insn
>> 22) & 3) {
2759 if (insn
& (1 << 21))
2760 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2762 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2765 if (insn
& (1 << 21))
2766 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2768 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2771 if (insn
& (1 << 21))
2772 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2774 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2777 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2778 gen_op_iwmmxt_set_mup();
2779 gen_op_iwmmxt_set_cup();
2781 case 0x201: case 0x203: case 0x205: case 0x207:
2782 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2783 case 0x211: case 0x213: case 0x215: case 0x217:
2784 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2785 wrd
= (insn
>> 5) & 0xf;
2786 rd0
= (insn
>> 12) & 0xf;
2787 rd1
= (insn
>> 0) & 0xf;
2788 if (rd0
== 0xf || rd1
== 0xf)
2790 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2791 tmp
= load_reg(s
, rd0
);
2792 tmp2
= load_reg(s
, rd1
);
2793 switch ((insn
>> 16) & 0xf) {
2794 case 0x0: /* TMIA */
2795 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2797 case 0x8: /* TMIAPH */
2798 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2800 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2801 if (insn
& (1 << 16))
2802 tcg_gen_shri_i32(tmp
, tmp
, 16);
2803 if (insn
& (1 << 17))
2804 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2805 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2808 tcg_temp_free_i32(tmp2
);
2809 tcg_temp_free_i32(tmp
);
2812 tcg_temp_free_i32(tmp2
);
2813 tcg_temp_free_i32(tmp
);
2814 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2815 gen_op_iwmmxt_set_mup();
2824 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2825 (ie. an undefined instruction). */
2826 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2828 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2831 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2832 /* Multiply with Internal Accumulate Format */
2833 rd0
= (insn
>> 12) & 0xf;
2835 acc
= (insn
>> 5) & 7;
2840 tmp
= load_reg(s
, rd0
);
2841 tmp2
= load_reg(s
, rd1
);
2842 switch ((insn
>> 16) & 0xf) {
2844 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2846 case 0x8: /* MIAPH */
2847 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2849 case 0xc: /* MIABB */
2850 case 0xd: /* MIABT */
2851 case 0xe: /* MIATB */
2852 case 0xf: /* MIATT */
2853 if (insn
& (1 << 16))
2854 tcg_gen_shri_i32(tmp
, tmp
, 16);
2855 if (insn
& (1 << 17))
2856 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2857 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2862 tcg_temp_free_i32(tmp2
);
2863 tcg_temp_free_i32(tmp
);
2865 gen_op_iwmmxt_movq_wRn_M0(acc
);
2869 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2870 /* Internal Accumulator Access Format */
2871 rdhi
= (insn
>> 16) & 0xf;
2872 rdlo
= (insn
>> 12) & 0xf;
2878 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2879 iwmmxt_load_reg(cpu_V0
, acc
);
2880 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2881 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2882 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2883 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2885 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2886 iwmmxt_store_reg(cpu_V0
, acc
);
2894 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2895 #define VFP_SREG(insn, bigbit, smallbit) \
2896 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2897 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2898 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2899 reg = (((insn) >> (bigbit)) & 0x0f) \
2900 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2902 if (insn & (1 << (smallbit))) \
2904 reg = ((insn) >> (bigbit)) & 0x0f; \
2907 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2908 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2909 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2910 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2911 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2912 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2914 /* Move between integer and VFP cores. */
2915 static TCGv_i32
gen_vfp_mrs(void)
2917 TCGv_i32 tmp
= tcg_temp_new_i32();
2918 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2922 static void gen_vfp_msr(TCGv_i32 tmp
)
2924 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2925 tcg_temp_free_i32(tmp
);
2928 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2930 TCGv_i32 tmp
= tcg_temp_new_i32();
2932 tcg_gen_shri_i32(var
, var
, shift
);
2933 tcg_gen_ext8u_i32(var
, var
);
2934 tcg_gen_shli_i32(tmp
, var
, 8);
2935 tcg_gen_or_i32(var
, var
, tmp
);
2936 tcg_gen_shli_i32(tmp
, var
, 16);
2937 tcg_gen_or_i32(var
, var
, tmp
);
2938 tcg_temp_free_i32(tmp
);
2941 static void gen_neon_dup_low16(TCGv_i32 var
)
2943 TCGv_i32 tmp
= tcg_temp_new_i32();
2944 tcg_gen_ext16u_i32(var
, var
);
2945 tcg_gen_shli_i32(tmp
, var
, 16);
2946 tcg_gen_or_i32(var
, var
, tmp
);
2947 tcg_temp_free_i32(tmp
);
2950 static void gen_neon_dup_high16(TCGv_i32 var
)
2952 TCGv_i32 tmp
= tcg_temp_new_i32();
2953 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2954 tcg_gen_shri_i32(tmp
, var
, 16);
2955 tcg_gen_or_i32(var
, var
, tmp
);
2956 tcg_temp_free_i32(tmp
);
2959 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2961 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2962 TCGv_i32 tmp
= tcg_temp_new_i32();
2965 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2966 gen_neon_dup_u8(tmp
, 0);
2969 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2970 gen_neon_dup_low16(tmp
);
2973 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2975 default: /* Avoid compiler warnings. */
2981 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2984 uint32_t cc
= extract32(insn
, 20, 2);
2987 TCGv_i64 frn
, frm
, dest
;
2988 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2990 zero
= tcg_const_i64(0);
2992 frn
= tcg_temp_new_i64();
2993 frm
= tcg_temp_new_i64();
2994 dest
= tcg_temp_new_i64();
2996 zf
= tcg_temp_new_i64();
2997 nf
= tcg_temp_new_i64();
2998 vf
= tcg_temp_new_i64();
3000 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
3001 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
3002 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
3004 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3005 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3008 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
3012 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
3015 case 2: /* ge: N == V -> N ^ V == 0 */
3016 tmp
= tcg_temp_new_i64();
3017 tcg_gen_xor_i64(tmp
, vf
, nf
);
3018 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
3020 tcg_temp_free_i64(tmp
);
3022 case 3: /* gt: !Z && N == V */
3023 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
3025 tmp
= tcg_temp_new_i64();
3026 tcg_gen_xor_i64(tmp
, vf
, nf
);
3027 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
3029 tcg_temp_free_i64(tmp
);
3032 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3033 tcg_temp_free_i64(frn
);
3034 tcg_temp_free_i64(frm
);
3035 tcg_temp_free_i64(dest
);
3037 tcg_temp_free_i64(zf
);
3038 tcg_temp_free_i64(nf
);
3039 tcg_temp_free_i64(vf
);
3041 tcg_temp_free_i64(zero
);
3043 TCGv_i32 frn
, frm
, dest
;
3046 zero
= tcg_const_i32(0);
3048 frn
= tcg_temp_new_i32();
3049 frm
= tcg_temp_new_i32();
3050 dest
= tcg_temp_new_i32();
3051 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3052 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3055 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
3059 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
3062 case 2: /* ge: N == V -> N ^ V == 0 */
3063 tmp
= tcg_temp_new_i32();
3064 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3065 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3067 tcg_temp_free_i32(tmp
);
3069 case 3: /* gt: !Z && N == V */
3070 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
3072 tmp
= tcg_temp_new_i32();
3073 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3074 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3076 tcg_temp_free_i32(tmp
);
3079 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3080 tcg_temp_free_i32(frn
);
3081 tcg_temp_free_i32(frm
);
3082 tcg_temp_free_i32(dest
);
3084 tcg_temp_free_i32(zero
);
3090 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
3091 uint32_t rm
, uint32_t dp
)
3093 uint32_t vmin
= extract32(insn
, 6, 1);
3094 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3097 TCGv_i64 frn
, frm
, dest
;
3099 frn
= tcg_temp_new_i64();
3100 frm
= tcg_temp_new_i64();
3101 dest
= tcg_temp_new_i64();
3103 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3104 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3106 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
3108 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
3110 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3111 tcg_temp_free_i64(frn
);
3112 tcg_temp_free_i64(frm
);
3113 tcg_temp_free_i64(dest
);
3115 TCGv_i32 frn
, frm
, dest
;
3117 frn
= tcg_temp_new_i32();
3118 frm
= tcg_temp_new_i32();
3119 dest
= tcg_temp_new_i32();
3121 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3122 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3124 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
3126 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
3128 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3129 tcg_temp_free_i32(frn
);
3130 tcg_temp_free_i32(frm
);
3131 tcg_temp_free_i32(dest
);
3134 tcg_temp_free_ptr(fpst
);
3138 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3141 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3144 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3145 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3150 tcg_op
= tcg_temp_new_i64();
3151 tcg_res
= tcg_temp_new_i64();
3152 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3153 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
3154 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3155 tcg_temp_free_i64(tcg_op
);
3156 tcg_temp_free_i64(tcg_res
);
3160 tcg_op
= tcg_temp_new_i32();
3161 tcg_res
= tcg_temp_new_i32();
3162 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3163 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
3164 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3165 tcg_temp_free_i32(tcg_op
);
3166 tcg_temp_free_i32(tcg_res
);
3169 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3170 tcg_temp_free_i32(tcg_rmode
);
3172 tcg_temp_free_ptr(fpst
);
3176 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3179 bool is_signed
= extract32(insn
, 7, 1);
3180 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3181 TCGv_i32 tcg_rmode
, tcg_shift
;
3183 tcg_shift
= tcg_const_i32(0);
3185 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3186 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3189 TCGv_i64 tcg_double
, tcg_res
;
3191 /* Rd is encoded as a single precision register even when the source
3192 * is double precision.
3194 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3195 tcg_double
= tcg_temp_new_i64();
3196 tcg_res
= tcg_temp_new_i64();
3197 tcg_tmp
= tcg_temp_new_i32();
3198 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3200 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3202 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3204 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3205 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3206 tcg_temp_free_i32(tcg_tmp
);
3207 tcg_temp_free_i64(tcg_res
);
3208 tcg_temp_free_i64(tcg_double
);
3210 TCGv_i32 tcg_single
, tcg_res
;
3211 tcg_single
= tcg_temp_new_i32();
3212 tcg_res
= tcg_temp_new_i32();
3213 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3215 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3217 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3219 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3220 tcg_temp_free_i32(tcg_res
);
3221 tcg_temp_free_i32(tcg_single
);
3224 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3225 tcg_temp_free_i32(tcg_rmode
);
3227 tcg_temp_free_i32(tcg_shift
);
3229 tcg_temp_free_ptr(fpst
);
3234 /* Table for converting the most common AArch32 encoding of
3235 * rounding mode to arm_fprounding order (which matches the
3236 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3238 static const uint8_t fp_decode_rm
[] = {
3245 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3247 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3249 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3254 VFP_DREG_D(rd
, insn
);
3255 VFP_DREG_N(rn
, insn
);
3256 VFP_DREG_M(rm
, insn
);
3258 rd
= VFP_SREG_D(insn
);
3259 rn
= VFP_SREG_N(insn
);
3260 rm
= VFP_SREG_M(insn
);
3263 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3264 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3265 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3266 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3267 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3268 /* VRINTA, VRINTN, VRINTP, VRINTM */
3269 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3270 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3271 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3272 /* VCVTA, VCVTN, VCVTP, VCVTM */
3273 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3274 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3279 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3280 (ie. an undefined instruction). */
3281 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3283 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3289 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3293 /* FIXME: this access check should not take precedence over UNDEF
3294 * for invalid encodings; we will generate incorrect syndrome information
3295 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3297 if (s
->fp_excp_el
) {
3298 gen_exception_insn(s
, 4, EXCP_UDEF
,
3299 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3303 if (!s
->vfp_enabled
) {
3304 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3305 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3307 rn
= (insn
>> 16) & 0xf;
3308 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3309 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3314 if (extract32(insn
, 28, 4) == 0xf) {
3315 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3316 * only used in v8 and above.
3318 return disas_vfp_v8_insn(s
, insn
);
3321 dp
= ((insn
& 0xf00) == 0xb00);
3322 switch ((insn
>> 24) & 0xf) {
3324 if (insn
& (1 << 4)) {
3325 /* single register transfer */
3326 rd
= (insn
>> 12) & 0xf;
3331 VFP_DREG_N(rn
, insn
);
3334 if (insn
& 0x00c00060
3335 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3339 pass
= (insn
>> 21) & 1;
3340 if (insn
& (1 << 22)) {
3342 offset
= ((insn
>> 5) & 3) * 8;
3343 } else if (insn
& (1 << 5)) {
3345 offset
= (insn
& (1 << 6)) ? 16 : 0;
3350 if (insn
& ARM_CP_RW_BIT
) {
3352 tmp
= neon_load_reg(rn
, pass
);
3356 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3357 if (insn
& (1 << 23))
3363 if (insn
& (1 << 23)) {
3365 tcg_gen_shri_i32(tmp
, tmp
, 16);
3371 tcg_gen_sari_i32(tmp
, tmp
, 16);
3380 store_reg(s
, rd
, tmp
);
3383 tmp
= load_reg(s
, rd
);
3384 if (insn
& (1 << 23)) {
3387 gen_neon_dup_u8(tmp
, 0);
3388 } else if (size
== 1) {
3389 gen_neon_dup_low16(tmp
);
3391 for (n
= 0; n
<= pass
* 2; n
++) {
3392 tmp2
= tcg_temp_new_i32();
3393 tcg_gen_mov_i32(tmp2
, tmp
);
3394 neon_store_reg(rn
, n
, tmp2
);
3396 neon_store_reg(rn
, n
, tmp
);
3401 tmp2
= neon_load_reg(rn
, pass
);
3402 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3403 tcg_temp_free_i32(tmp2
);
3406 tmp2
= neon_load_reg(rn
, pass
);
3407 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3408 tcg_temp_free_i32(tmp2
);
3413 neon_store_reg(rn
, pass
, tmp
);
3417 if ((insn
& 0x6f) != 0x00)
3419 rn
= VFP_SREG_N(insn
);
3420 if (insn
& ARM_CP_RW_BIT
) {
3422 if (insn
& (1 << 21)) {
3423 /* system register */
3428 /* VFP2 allows access to FSID from userspace.
3429 VFP3 restricts all id registers to privileged
3432 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3435 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3440 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3442 case ARM_VFP_FPINST
:
3443 case ARM_VFP_FPINST2
:
3444 /* Not present in VFP3. */
3446 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3449 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3453 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3454 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3456 tmp
= tcg_temp_new_i32();
3457 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3461 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3468 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3471 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3477 gen_mov_F0_vreg(0, rn
);
3478 tmp
= gen_vfp_mrs();
3481 /* Set the 4 flag bits in the CPSR. */
3483 tcg_temp_free_i32(tmp
);
3485 store_reg(s
, rd
, tmp
);
3489 if (insn
& (1 << 21)) {
3491 /* system register */
3496 /* Writes are ignored. */
3499 tmp
= load_reg(s
, rd
);
3500 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3501 tcg_temp_free_i32(tmp
);
3507 /* TODO: VFP subarchitecture support.
3508 * For now, keep the EN bit only */
3509 tmp
= load_reg(s
, rd
);
3510 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3511 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3514 case ARM_VFP_FPINST
:
3515 case ARM_VFP_FPINST2
:
3519 tmp
= load_reg(s
, rd
);
3520 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3526 tmp
= load_reg(s
, rd
);
3528 gen_mov_vreg_F0(0, rn
);
3533 /* data processing */
3534 /* The opcode is in bits 23, 21, 20 and 6. */
3535 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3539 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3541 /* rn is register number */
3542 VFP_DREG_N(rn
, insn
);
3545 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3546 ((rn
& 0x1e) == 0x6))) {
3547 /* Integer or single/half precision destination. */
3548 rd
= VFP_SREG_D(insn
);
3550 VFP_DREG_D(rd
, insn
);
3553 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3554 ((rn
& 0x1e) == 0x4))) {
3555 /* VCVT from int or half precision is always from S reg
3556 * regardless of dp bit. VCVT with immediate frac_bits
3557 * has same format as SREG_M.
3559 rm
= VFP_SREG_M(insn
);
3561 VFP_DREG_M(rm
, insn
);
3564 rn
= VFP_SREG_N(insn
);
3565 if (op
== 15 && rn
== 15) {
3566 /* Double precision destination. */
3567 VFP_DREG_D(rd
, insn
);
3569 rd
= VFP_SREG_D(insn
);
3571 /* NB that we implicitly rely on the encoding for the frac_bits
3572 * in VCVT of fixed to float being the same as that of an SREG_M
3574 rm
= VFP_SREG_M(insn
);
3577 veclen
= s
->vec_len
;
3578 if (op
== 15 && rn
> 3)
3581 /* Shut up compiler warnings. */
3592 /* Figure out what type of vector operation this is. */
3593 if ((rd
& bank_mask
) == 0) {
3598 delta_d
= (s
->vec_stride
>> 1) + 1;
3600 delta_d
= s
->vec_stride
+ 1;
3602 if ((rm
& bank_mask
) == 0) {
3603 /* mixed scalar/vector */
3612 /* Load the initial operands. */
3617 /* Integer source */
3618 gen_mov_F0_vreg(0, rm
);
3623 gen_mov_F0_vreg(dp
, rd
);
3624 gen_mov_F1_vreg(dp
, rm
);
3628 /* Compare with zero */
3629 gen_mov_F0_vreg(dp
, rd
);
3640 /* Source and destination the same. */
3641 gen_mov_F0_vreg(dp
, rd
);
3647 /* VCVTB, VCVTT: only present with the halfprec extension
3648 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3649 * (we choose to UNDEF)
3651 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3652 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3655 if (!extract32(rn
, 1, 1)) {
3656 /* Half precision source. */
3657 gen_mov_F0_vreg(0, rm
);
3660 /* Otherwise fall through */
3662 /* One source operand. */
3663 gen_mov_F0_vreg(dp
, rm
);
3667 /* Two source operands. */
3668 gen_mov_F0_vreg(dp
, rn
);
3669 gen_mov_F1_vreg(dp
, rm
);
3673 /* Perform the calculation. */
3675 case 0: /* VMLA: fd + (fn * fm) */
3676 /* Note that order of inputs to the add matters for NaNs */
3678 gen_mov_F0_vreg(dp
, rd
);
3681 case 1: /* VMLS: fd + -(fn * fm) */
3684 gen_mov_F0_vreg(dp
, rd
);
3687 case 2: /* VNMLS: -fd + (fn * fm) */
3688 /* Note that it isn't valid to replace (-A + B) with (B - A)
3689 * or similar plausible looking simplifications
3690 * because this will give wrong results for NaNs.
3693 gen_mov_F0_vreg(dp
, rd
);
3697 case 3: /* VNMLA: -fd + -(fn * fm) */
3700 gen_mov_F0_vreg(dp
, rd
);
3704 case 4: /* mul: fn * fm */
3707 case 5: /* nmul: -(fn * fm) */
3711 case 6: /* add: fn + fm */
3714 case 7: /* sub: fn - fm */
3717 case 8: /* div: fn / fm */
3720 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3721 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3722 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3723 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3724 /* These are fused multiply-add, and must be done as one
3725 * floating point operation with no rounding between the
3726 * multiplication and addition steps.
3727 * NB that doing the negations here as separate steps is
3728 * correct : an input NaN should come out with its sign bit
3729 * flipped if it is a negated-input.
3731 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3739 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3741 frd
= tcg_temp_new_i64();
3742 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3745 gen_helper_vfp_negd(frd
, frd
);
3747 fpst
= get_fpstatus_ptr(0);
3748 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3749 cpu_F1d
, frd
, fpst
);
3750 tcg_temp_free_ptr(fpst
);
3751 tcg_temp_free_i64(frd
);
3757 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3759 frd
= tcg_temp_new_i32();
3760 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3762 gen_helper_vfp_negs(frd
, frd
);
3764 fpst
= get_fpstatus_ptr(0);
3765 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3766 cpu_F1s
, frd
, fpst
);
3767 tcg_temp_free_ptr(fpst
);
3768 tcg_temp_free_i32(frd
);
3771 case 14: /* fconst */
3772 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3776 n
= (insn
<< 12) & 0x80000000;
3777 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3784 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3791 tcg_gen_movi_i32(cpu_F0s
, n
);
3794 case 15: /* extension space */
3808 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3809 tmp
= gen_vfp_mrs();
3810 tcg_gen_ext16u_i32(tmp
, tmp
);
3812 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3815 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3818 tcg_temp_free_i32(tmp
);
3820 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3821 tmp
= gen_vfp_mrs();
3822 tcg_gen_shri_i32(tmp
, tmp
, 16);
3824 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3827 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3830 tcg_temp_free_i32(tmp
);
3832 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3833 tmp
= tcg_temp_new_i32();
3835 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3838 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3841 gen_mov_F0_vreg(0, rd
);
3842 tmp2
= gen_vfp_mrs();
3843 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3844 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3845 tcg_temp_free_i32(tmp2
);
3848 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3849 tmp
= tcg_temp_new_i32();
3851 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3854 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3857 tcg_gen_shli_i32(tmp
, tmp
, 16);
3858 gen_mov_F0_vreg(0, rd
);
3859 tmp2
= gen_vfp_mrs();
3860 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3861 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3862 tcg_temp_free_i32(tmp2
);
3874 case 11: /* cmpez */
3878 case 12: /* vrintr */
3880 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3882 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3884 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3886 tcg_temp_free_ptr(fpst
);
3889 case 13: /* vrintz */
3891 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3893 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3894 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3896 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3898 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3900 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3901 tcg_temp_free_i32(tcg_rmode
);
3902 tcg_temp_free_ptr(fpst
);
3905 case 14: /* vrintx */
3907 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3909 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3911 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3913 tcg_temp_free_ptr(fpst
);
3916 case 15: /* single<->double conversion */
3918 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3920 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3922 case 16: /* fuito */
3923 gen_vfp_uito(dp
, 0);
3925 case 17: /* fsito */
3926 gen_vfp_sito(dp
, 0);
3928 case 20: /* fshto */
3929 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3932 gen_vfp_shto(dp
, 16 - rm
, 0);
3934 case 21: /* fslto */
3935 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3938 gen_vfp_slto(dp
, 32 - rm
, 0);
3940 case 22: /* fuhto */
3941 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3944 gen_vfp_uhto(dp
, 16 - rm
, 0);
3946 case 23: /* fulto */
3947 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3950 gen_vfp_ulto(dp
, 32 - rm
, 0);
3952 case 24: /* ftoui */
3953 gen_vfp_toui(dp
, 0);
3955 case 25: /* ftouiz */
3956 gen_vfp_touiz(dp
, 0);
3958 case 26: /* ftosi */
3959 gen_vfp_tosi(dp
, 0);
3961 case 27: /* ftosiz */
3962 gen_vfp_tosiz(dp
, 0);
3964 case 28: /* ftosh */
3965 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3968 gen_vfp_tosh(dp
, 16 - rm
, 0);
3970 case 29: /* ftosl */
3971 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3974 gen_vfp_tosl(dp
, 32 - rm
, 0);
3976 case 30: /* ftouh */
3977 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3980 gen_vfp_touh(dp
, 16 - rm
, 0);
3982 case 31: /* ftoul */
3983 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3986 gen_vfp_toul(dp
, 32 - rm
, 0);
3988 default: /* undefined */
3992 default: /* undefined */
3996 /* Write back the result. */
3997 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3998 /* Comparison, do nothing. */
3999 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
4000 (rn
& 0x1e) == 0x6)) {
4001 /* VCVT double to int: always integer result.
4002 * VCVT double to half precision is always a single
4005 gen_mov_vreg_F0(0, rd
);
4006 } else if (op
== 15 && rn
== 15) {
4008 gen_mov_vreg_F0(!dp
, rd
);
4010 gen_mov_vreg_F0(dp
, rd
);
4013 /* break out of the loop if we have finished */
4017 if (op
== 15 && delta_m
== 0) {
4018 /* single source one-many */
4020 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
4022 gen_mov_vreg_F0(dp
, rd
);
4026 /* Setup the next operands. */
4028 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
4032 /* One source operand. */
4033 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
4035 gen_mov_F0_vreg(dp
, rm
);
4037 /* Two source operands. */
4038 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
4040 gen_mov_F0_vreg(dp
, rn
);
4042 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
4044 gen_mov_F1_vreg(dp
, rm
);
4052 if ((insn
& 0x03e00000) == 0x00400000) {
4053 /* two-register transfer */
4054 rn
= (insn
>> 16) & 0xf;
4055 rd
= (insn
>> 12) & 0xf;
4057 VFP_DREG_M(rm
, insn
);
4059 rm
= VFP_SREG_M(insn
);
4062 if (insn
& ARM_CP_RW_BIT
) {
4065 gen_mov_F0_vreg(0, rm
* 2);
4066 tmp
= gen_vfp_mrs();
4067 store_reg(s
, rd
, tmp
);
4068 gen_mov_F0_vreg(0, rm
* 2 + 1);
4069 tmp
= gen_vfp_mrs();
4070 store_reg(s
, rn
, tmp
);
4072 gen_mov_F0_vreg(0, rm
);
4073 tmp
= gen_vfp_mrs();
4074 store_reg(s
, rd
, tmp
);
4075 gen_mov_F0_vreg(0, rm
+ 1);
4076 tmp
= gen_vfp_mrs();
4077 store_reg(s
, rn
, tmp
);
4082 tmp
= load_reg(s
, rd
);
4084 gen_mov_vreg_F0(0, rm
* 2);
4085 tmp
= load_reg(s
, rn
);
4087 gen_mov_vreg_F0(0, rm
* 2 + 1);
4089 tmp
= load_reg(s
, rd
);
4091 gen_mov_vreg_F0(0, rm
);
4092 tmp
= load_reg(s
, rn
);
4094 gen_mov_vreg_F0(0, rm
+ 1);
4099 rn
= (insn
>> 16) & 0xf;
4101 VFP_DREG_D(rd
, insn
);
4103 rd
= VFP_SREG_D(insn
);
4104 if ((insn
& 0x01200000) == 0x01000000) {
4105 /* Single load/store */
4106 offset
= (insn
& 0xff) << 2;
4107 if ((insn
& (1 << 23)) == 0)
4109 if (s
->thumb
&& rn
== 15) {
4110 /* This is actually UNPREDICTABLE */
4111 addr
= tcg_temp_new_i32();
4112 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4114 addr
= load_reg(s
, rn
);
4116 tcg_gen_addi_i32(addr
, addr
, offset
);
4117 if (insn
& (1 << 20)) {
4118 gen_vfp_ld(s
, dp
, addr
);
4119 gen_mov_vreg_F0(dp
, rd
);
4121 gen_mov_F0_vreg(dp
, rd
);
4122 gen_vfp_st(s
, dp
, addr
);
4124 tcg_temp_free_i32(addr
);
4126 /* load/store multiple */
4127 int w
= insn
& (1 << 21);
4129 n
= (insn
>> 1) & 0x7f;
4133 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
4134 /* P == U , W == 1 => UNDEF */
4137 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
4138 /* UNPREDICTABLE cases for bad immediates: we choose to
4139 * UNDEF to avoid generating huge numbers of TCG ops
4143 if (rn
== 15 && w
) {
4144 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4148 if (s
->thumb
&& rn
== 15) {
4149 /* This is actually UNPREDICTABLE */
4150 addr
= tcg_temp_new_i32();
4151 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4153 addr
= load_reg(s
, rn
);
4155 if (insn
& (1 << 24)) /* pre-decrement */
4156 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4162 for (i
= 0; i
< n
; i
++) {
4163 if (insn
& ARM_CP_RW_BIT
) {
4165 gen_vfp_ld(s
, dp
, addr
);
4166 gen_mov_vreg_F0(dp
, rd
+ i
);
4169 gen_mov_F0_vreg(dp
, rd
+ i
);
4170 gen_vfp_st(s
, dp
, addr
);
4172 tcg_gen_addi_i32(addr
, addr
, offset
);
4176 if (insn
& (1 << 24))
4177 offset
= -offset
* n
;
4178 else if (dp
&& (insn
& 1))
4184 tcg_gen_addi_i32(addr
, addr
, offset
);
4185 store_reg(s
, rn
, addr
);
4187 tcg_temp_free_i32(addr
);
4193 /* Should never happen. */
4199 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4201 #ifndef CONFIG_USER_ONLY
4202 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4203 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4209 static void gen_goto_ptr(void)
4211 tcg_gen_lookup_and_goto_ptr();
4214 /* This will end the TB but doesn't guarantee we'll return to
4215 * cpu_loop_exec. Any live exit_requests will be processed as we
4216 * enter the next TB.
4218 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4220 if (use_goto_tb(s
, dest
)) {
4222 gen_set_pc_im(s
, dest
);
4223 tcg_gen_exit_tb((uintptr_t)s
->base
.tb
+ n
);
4225 gen_set_pc_im(s
, dest
);
4228 s
->base
.is_jmp
= DISAS_NORETURN
;
4231 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4233 if (unlikely(is_singlestepping(s
))) {
4234 /* An indirect jump so that we still trigger the debug exception. */
4239 gen_goto_tb(s
, 0, dest
);
4243 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4246 tcg_gen_sari_i32(t0
, t0
, 16);
4250 tcg_gen_sari_i32(t1
, t1
, 16);
4253 tcg_gen_mul_i32(t0
, t0
, t1
);
4256 /* Return the mask of PSR bits set by a MSR instruction. */
4257 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4262 if (flags
& (1 << 0))
4264 if (flags
& (1 << 1))
4266 if (flags
& (1 << 2))
4268 if (flags
& (1 << 3))
4271 /* Mask out undefined bits. */
4272 mask
&= ~CPSR_RESERVED
;
4273 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4276 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4277 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4279 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4280 mask
&= ~(CPSR_E
| CPSR_GE
);
4282 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4285 /* Mask out execution state and reserved bits. */
4287 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4289 /* Mask out privileged bits. */
4295 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4296 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4300 /* ??? This is also undefined in system mode. */
4304 tmp
= load_cpu_field(spsr
);
4305 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4306 tcg_gen_andi_i32(t0
, t0
, mask
);
4307 tcg_gen_or_i32(tmp
, tmp
, t0
);
4308 store_cpu_field(tmp
, spsr
);
4310 gen_set_cpsr(t0
, mask
);
4312 tcg_temp_free_i32(t0
);
4317 /* Returns nonzero if access to the PSR is not permitted. */
4318 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4321 tmp
= tcg_temp_new_i32();
4322 tcg_gen_movi_i32(tmp
, val
);
4323 return gen_set_psr(s
, mask
, spsr
, tmp
);
4326 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4327 int *tgtmode
, int *regno
)
4329 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4330 * the target mode and register number, and identify the various
4331 * unpredictable cases.
4332 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4333 * + executed in user mode
4334 * + using R15 as the src/dest register
4335 * + accessing an unimplemented register
4336 * + accessing a register that's inaccessible at current PL/security state*
4337 * + accessing a register that you could access with a different insn
4338 * We choose to UNDEF in all these cases.
4339 * Since we don't know which of the various AArch32 modes we are in
4340 * we have to defer some checks to runtime.
4341 * Accesses to Monitor mode registers from Secure EL1 (which implies
4342 * that EL3 is AArch64) must trap to EL3.
4344 * If the access checks fail this function will emit code to take
4345 * an exception and return false. Otherwise it will return true,
4346 * and set *tgtmode and *regno appropriately.
4348 int exc_target
= default_exception_el(s
);
4350 /* These instructions are present only in ARMv8, or in ARMv7 with the
4351 * Virtualization Extensions.
4353 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4354 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4358 if (IS_USER(s
) || rn
== 15) {
4362 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4363 * of registers into (r, sysm).
4366 /* SPSRs for other modes */
4368 case 0xe: /* SPSR_fiq */
4369 *tgtmode
= ARM_CPU_MODE_FIQ
;
4371 case 0x10: /* SPSR_irq */
4372 *tgtmode
= ARM_CPU_MODE_IRQ
;
4374 case 0x12: /* SPSR_svc */
4375 *tgtmode
= ARM_CPU_MODE_SVC
;
4377 case 0x14: /* SPSR_abt */
4378 *tgtmode
= ARM_CPU_MODE_ABT
;
4380 case 0x16: /* SPSR_und */
4381 *tgtmode
= ARM_CPU_MODE_UND
;
4383 case 0x1c: /* SPSR_mon */
4384 *tgtmode
= ARM_CPU_MODE_MON
;
4386 case 0x1e: /* SPSR_hyp */
4387 *tgtmode
= ARM_CPU_MODE_HYP
;
4389 default: /* unallocated */
4392 /* We arbitrarily assign SPSR a register number of 16. */
4395 /* general purpose registers for other modes */
4397 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4398 *tgtmode
= ARM_CPU_MODE_USR
;
4401 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4402 *tgtmode
= ARM_CPU_MODE_FIQ
;
4405 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4406 *tgtmode
= ARM_CPU_MODE_IRQ
;
4407 *regno
= sysm
& 1 ? 13 : 14;
4409 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4410 *tgtmode
= ARM_CPU_MODE_SVC
;
4411 *regno
= sysm
& 1 ? 13 : 14;
4413 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4414 *tgtmode
= ARM_CPU_MODE_ABT
;
4415 *regno
= sysm
& 1 ? 13 : 14;
4417 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4418 *tgtmode
= ARM_CPU_MODE_UND
;
4419 *regno
= sysm
& 1 ? 13 : 14;
4421 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4422 *tgtmode
= ARM_CPU_MODE_MON
;
4423 *regno
= sysm
& 1 ? 13 : 14;
4425 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4426 *tgtmode
= ARM_CPU_MODE_HYP
;
4427 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4428 *regno
= sysm
& 1 ? 13 : 17;
4430 default: /* unallocated */
4435 /* Catch the 'accessing inaccessible register' cases we can detect
4436 * at translate time.
4439 case ARM_CPU_MODE_MON
:
4440 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4443 if (s
->current_el
== 1) {
4444 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4445 * then accesses to Mon registers trap to EL3
4451 case ARM_CPU_MODE_HYP
:
4452 /* Note that we can forbid accesses from EL2 here because they
4453 * must be from Hyp mode itself
4455 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4466 /* If we get here then some access check did not pass */
4467 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4471 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4473 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4474 int tgtmode
= 0, regno
= 0;
4476 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4480 /* Sync state because msr_banked() can raise exceptions */
4481 gen_set_condexec(s
);
4482 gen_set_pc_im(s
, s
->pc
- 4);
4483 tcg_reg
= load_reg(s
, rn
);
4484 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4485 tcg_regno
= tcg_const_i32(regno
);
4486 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4487 tcg_temp_free_i32(tcg_tgtmode
);
4488 tcg_temp_free_i32(tcg_regno
);
4489 tcg_temp_free_i32(tcg_reg
);
4490 s
->base
.is_jmp
= DISAS_UPDATE
;
4493 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4495 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4496 int tgtmode
= 0, regno
= 0;
4498 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4502 /* Sync state because mrs_banked() can raise exceptions */
4503 gen_set_condexec(s
);
4504 gen_set_pc_im(s
, s
->pc
- 4);
4505 tcg_reg
= tcg_temp_new_i32();
4506 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4507 tcg_regno
= tcg_const_i32(regno
);
4508 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4509 tcg_temp_free_i32(tcg_tgtmode
);
4510 tcg_temp_free_i32(tcg_regno
);
4511 store_reg(s
, rn
, tcg_reg
);
4512 s
->base
.is_jmp
= DISAS_UPDATE
;
4515 /* Store value to PC as for an exception return (ie don't
4516 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4517 * will do the masking based on the new value of the Thumb bit.
4519 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4521 tcg_gen_mov_i32(cpu_R
[15], pc
);
4522 tcg_temp_free_i32(pc
);
4525 /* Generate a v6 exception return. Marks both values as dead. */
4526 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4528 store_pc_exc_ret(s
, pc
);
4529 /* The cpsr_write_eret helper will mask the low bits of PC
4530 * appropriately depending on the new Thumb bit, so it must
4531 * be called after storing the new PC.
4533 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4534 tcg_temp_free_i32(cpsr
);
4535 /* Must exit loop to check un-masked IRQs */
4536 s
->base
.is_jmp
= DISAS_EXIT
;
4539 /* Generate an old-style exception return. Marks pc as dead. */
4540 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4542 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4546 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4547 * only call the helper when running single threaded TCG code to ensure
4548 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4549 * just skip this instruction. Currently the SEV/SEVL instructions
4550 * which are *one* of many ways to wake the CPU from WFE are not
4551 * implemented so we can't sleep like WFI does.
4553 static void gen_nop_hint(DisasContext
*s
, int val
)
4556 /* When running in MTTCG we don't generate jumps to the yield and
4557 * WFE helpers as it won't affect the scheduling of other vCPUs.
4558 * If we wanted to more completely model WFE/SEV so we don't busy
4559 * spin unnecessarily we would need to do something more involved.
4562 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4563 gen_set_pc_im(s
, s
->pc
);
4564 s
->base
.is_jmp
= DISAS_YIELD
;
4568 gen_set_pc_im(s
, s
->pc
);
4569 s
->base
.is_jmp
= DISAS_WFI
;
4572 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4573 gen_set_pc_im(s
, s
->pc
);
4574 s
->base
.is_jmp
= DISAS_WFE
;
4579 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4585 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4587 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4590 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4591 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4592 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4597 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4600 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4601 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4602 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4607 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4608 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4609 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4610 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4611 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4613 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4614 switch ((size << 1) | u) { \
4616 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4619 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4622 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4625 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4628 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4631 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4633 default: return 1; \
4636 #define GEN_NEON_INTEGER_OP(name) do { \
4637 switch ((size << 1) | u) { \
4639 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4642 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4645 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4648 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4651 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4654 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4656 default: return 1; \
4659 static TCGv_i32
neon_load_scratch(int scratch
)
4661 TCGv_i32 tmp
= tcg_temp_new_i32();
4662 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4666 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4668 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4669 tcg_temp_free_i32(var
);
4672 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4676 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4678 gen_neon_dup_high16(tmp
);
4680 gen_neon_dup_low16(tmp
);
4683 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4688 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4691 if (!q
&& size
== 2) {
4694 tmp
= tcg_const_i32(rd
);
4695 tmp2
= tcg_const_i32(rm
);
4699 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4702 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4705 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4713 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4716 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4722 tcg_temp_free_i32(tmp
);
4723 tcg_temp_free_i32(tmp2
);
4727 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4730 if (!q
&& size
== 2) {
4733 tmp
= tcg_const_i32(rd
);
4734 tmp2
= tcg_const_i32(rm
);
4738 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4741 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4744 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4752 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4755 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4761 tcg_temp_free_i32(tmp
);
4762 tcg_temp_free_i32(tmp2
);
4766 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4770 rd
= tcg_temp_new_i32();
4771 tmp
= tcg_temp_new_i32();
4773 tcg_gen_shli_i32(rd
, t0
, 8);
4774 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4775 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4776 tcg_gen_or_i32(rd
, rd
, tmp
);
4778 tcg_gen_shri_i32(t1
, t1
, 8);
4779 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4780 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4781 tcg_gen_or_i32(t1
, t1
, tmp
);
4782 tcg_gen_mov_i32(t0
, rd
);
4784 tcg_temp_free_i32(tmp
);
4785 tcg_temp_free_i32(rd
);
4788 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4792 rd
= tcg_temp_new_i32();
4793 tmp
= tcg_temp_new_i32();
4795 tcg_gen_shli_i32(rd
, t0
, 16);
4796 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4797 tcg_gen_or_i32(rd
, rd
, tmp
);
4798 tcg_gen_shri_i32(t1
, t1
, 16);
4799 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4800 tcg_gen_or_i32(t1
, t1
, tmp
);
4801 tcg_gen_mov_i32(t0
, rd
);
4803 tcg_temp_free_i32(tmp
);
4804 tcg_temp_free_i32(rd
);
4812 } neon_ls_element_type
[11] = {
4826 /* Translate a NEON load/store element instruction. Return nonzero if the
4827 instruction is invalid. */
4828 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4847 /* FIXME: this access check should not take precedence over UNDEF
4848 * for invalid encodings; we will generate incorrect syndrome information
4849 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4851 if (s
->fp_excp_el
) {
4852 gen_exception_insn(s
, 4, EXCP_UDEF
,
4853 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4857 if (!s
->vfp_enabled
)
4859 VFP_DREG_D(rd
, insn
);
4860 rn
= (insn
>> 16) & 0xf;
4862 load
= (insn
& (1 << 21)) != 0;
4863 if ((insn
& (1 << 23)) == 0) {
4864 /* Load store all elements. */
4865 op
= (insn
>> 8) & 0xf;
4866 size
= (insn
>> 6) & 3;
4869 /* Catch UNDEF cases for bad values of align field */
4872 if (((insn
>> 5) & 1) == 1) {
4877 if (((insn
>> 4) & 3) == 3) {
4884 nregs
= neon_ls_element_type
[op
].nregs
;
4885 interleave
= neon_ls_element_type
[op
].interleave
;
4886 spacing
= neon_ls_element_type
[op
].spacing
;
4887 if (size
== 3 && (interleave
| spacing
) != 1)
4889 addr
= tcg_temp_new_i32();
4890 load_reg_var(s
, addr
, rn
);
4891 stride
= (1 << size
) * interleave
;
4892 for (reg
= 0; reg
< nregs
; reg
++) {
4893 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4894 load_reg_var(s
, addr
, rn
);
4895 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4896 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4897 load_reg_var(s
, addr
, rn
);
4898 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4901 tmp64
= tcg_temp_new_i64();
4903 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4904 neon_store_reg64(tmp64
, rd
);
4906 neon_load_reg64(tmp64
, rd
);
4907 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4909 tcg_temp_free_i64(tmp64
);
4910 tcg_gen_addi_i32(addr
, addr
, stride
);
4912 for (pass
= 0; pass
< 2; pass
++) {
4915 tmp
= tcg_temp_new_i32();
4916 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4917 neon_store_reg(rd
, pass
, tmp
);
4919 tmp
= neon_load_reg(rd
, pass
);
4920 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4921 tcg_temp_free_i32(tmp
);
4923 tcg_gen_addi_i32(addr
, addr
, stride
);
4924 } else if (size
== 1) {
4926 tmp
= tcg_temp_new_i32();
4927 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4928 tcg_gen_addi_i32(addr
, addr
, stride
);
4929 tmp2
= tcg_temp_new_i32();
4930 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4931 tcg_gen_addi_i32(addr
, addr
, stride
);
4932 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4933 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4934 tcg_temp_free_i32(tmp2
);
4935 neon_store_reg(rd
, pass
, tmp
);
4937 tmp
= neon_load_reg(rd
, pass
);
4938 tmp2
= tcg_temp_new_i32();
4939 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4940 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4941 tcg_temp_free_i32(tmp
);
4942 tcg_gen_addi_i32(addr
, addr
, stride
);
4943 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4944 tcg_temp_free_i32(tmp2
);
4945 tcg_gen_addi_i32(addr
, addr
, stride
);
4947 } else /* size == 0 */ {
4950 for (n
= 0; n
< 4; n
++) {
4951 tmp
= tcg_temp_new_i32();
4952 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4953 tcg_gen_addi_i32(addr
, addr
, stride
);
4957 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4958 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4959 tcg_temp_free_i32(tmp
);
4962 neon_store_reg(rd
, pass
, tmp2
);
4964 tmp2
= neon_load_reg(rd
, pass
);
4965 for (n
= 0; n
< 4; n
++) {
4966 tmp
= tcg_temp_new_i32();
4968 tcg_gen_mov_i32(tmp
, tmp2
);
4970 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4972 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4973 tcg_temp_free_i32(tmp
);
4974 tcg_gen_addi_i32(addr
, addr
, stride
);
4976 tcg_temp_free_i32(tmp2
);
4983 tcg_temp_free_i32(addr
);
4986 size
= (insn
>> 10) & 3;
4988 /* Load single element to all lanes. */
4989 int a
= (insn
>> 4) & 1;
4993 size
= (insn
>> 6) & 3;
4994 nregs
= ((insn
>> 8) & 3) + 1;
4997 if (nregs
!= 4 || a
== 0) {
5000 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5003 if (nregs
== 1 && a
== 1 && size
== 0) {
5006 if (nregs
== 3 && a
== 1) {
5009 addr
= tcg_temp_new_i32();
5010 load_reg_var(s
, addr
, rn
);
5012 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5013 tmp
= gen_load_and_replicate(s
, addr
, size
);
5014 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
5015 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
5016 if (insn
& (1 << 5)) {
5017 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
5018 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
5020 tcg_temp_free_i32(tmp
);
5022 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5023 stride
= (insn
& (1 << 5)) ? 2 : 1;
5024 for (reg
= 0; reg
< nregs
; reg
++) {
5025 tmp
= gen_load_and_replicate(s
, addr
, size
);
5026 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
5027 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
5028 tcg_temp_free_i32(tmp
);
5029 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5033 tcg_temp_free_i32(addr
);
5034 stride
= (1 << size
) * nregs
;
5036 /* Single element. */
5037 int idx
= (insn
>> 4) & 0xf;
5038 pass
= (insn
>> 7) & 1;
5041 shift
= ((insn
>> 5) & 3) * 8;
5045 shift
= ((insn
>> 6) & 1) * 16;
5046 stride
= (insn
& (1 << 5)) ? 2 : 1;
5050 stride
= (insn
& (1 << 6)) ? 2 : 1;
5055 nregs
= ((insn
>> 8) & 3) + 1;
5056 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5059 if (((idx
& (1 << size
)) != 0) ||
5060 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
5065 if ((idx
& 1) != 0) {
5070 if (size
== 2 && (idx
& 2) != 0) {
5075 if ((size
== 2) && ((idx
& 3) == 3)) {
5082 if ((rd
+ stride
* (nregs
- 1)) > 31) {
5083 /* Attempts to write off the end of the register file
5084 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5085 * the neon_load_reg() would write off the end of the array.
5089 addr
= tcg_temp_new_i32();
5090 load_reg_var(s
, addr
, rn
);
5091 for (reg
= 0; reg
< nregs
; reg
++) {
5093 tmp
= tcg_temp_new_i32();
5096 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
5099 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
5102 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
5104 default: /* Avoid compiler warnings. */
5108 tmp2
= neon_load_reg(rd
, pass
);
5109 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
5110 shift
, size
? 16 : 8);
5111 tcg_temp_free_i32(tmp2
);
5113 neon_store_reg(rd
, pass
, tmp
);
5114 } else { /* Store */
5115 tmp
= neon_load_reg(rd
, pass
);
5117 tcg_gen_shri_i32(tmp
, tmp
, shift
);
5120 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
5123 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
5126 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5129 tcg_temp_free_i32(tmp
);
5132 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5134 tcg_temp_free_i32(addr
);
5135 stride
= nregs
* (1 << size
);
5141 base
= load_reg(s
, rn
);
5143 tcg_gen_addi_i32(base
, base
, stride
);
5146 index
= load_reg(s
, rm
);
5147 tcg_gen_add_i32(base
, base
, index
);
5148 tcg_temp_free_i32(index
);
5150 store_reg(s
, rn
, base
);
5155 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5156 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
5158 tcg_gen_and_i32(t
, t
, c
);
5159 tcg_gen_andc_i32(f
, f
, c
);
5160 tcg_gen_or_i32(dest
, t
, f
);
5163 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5166 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
5167 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
5168 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
5173 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5176 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
5177 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
5178 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5183 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5186 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5187 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5188 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5193 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5196 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5197 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5198 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5203 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5209 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5210 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5215 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5216 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5223 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5224 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5229 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5230 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5237 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5241 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5242 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5243 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5248 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5249 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5250 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5254 tcg_temp_free_i32(src
);
5257 static inline void gen_neon_addl(int size
)
5260 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5261 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5262 case 2: tcg_gen_add_i64(CPU_V001
); break;
5267 static inline void gen_neon_subl(int size
)
5270 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5271 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5272 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5277 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5280 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5281 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5283 tcg_gen_neg_i64(var
, var
);
5289 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5292 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5293 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5298 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5303 switch ((size
<< 1) | u
) {
5304 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5305 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5306 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5307 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5309 tmp
= gen_muls_i64_i32(a
, b
);
5310 tcg_gen_mov_i64(dest
, tmp
);
5311 tcg_temp_free_i64(tmp
);
5314 tmp
= gen_mulu_i64_i32(a
, b
);
5315 tcg_gen_mov_i64(dest
, tmp
);
5316 tcg_temp_free_i64(tmp
);
5321 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5322 Don't forget to clean them now. */
5324 tcg_temp_free_i32(a
);
5325 tcg_temp_free_i32(b
);
5329 static void gen_neon_narrow_op(int op
, int u
, int size
,
5330 TCGv_i32 dest
, TCGv_i64 src
)
5334 gen_neon_unarrow_sats(size
, dest
, src
);
5336 gen_neon_narrow(size
, dest
, src
);
5340 gen_neon_narrow_satu(size
, dest
, src
);
5342 gen_neon_narrow_sats(size
, dest
, src
);
5347 /* Symbolic constants for op fields for Neon 3-register same-length.
5348 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5351 #define NEON_3R_VHADD 0
5352 #define NEON_3R_VQADD 1
5353 #define NEON_3R_VRHADD 2
5354 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5355 #define NEON_3R_VHSUB 4
5356 #define NEON_3R_VQSUB 5
5357 #define NEON_3R_VCGT 6
5358 #define NEON_3R_VCGE 7
5359 #define NEON_3R_VSHL 8
5360 #define NEON_3R_VQSHL 9
5361 #define NEON_3R_VRSHL 10
5362 #define NEON_3R_VQRSHL 11
5363 #define NEON_3R_VMAX 12
5364 #define NEON_3R_VMIN 13
5365 #define NEON_3R_VABD 14
5366 #define NEON_3R_VABA 15
5367 #define NEON_3R_VADD_VSUB 16
5368 #define NEON_3R_VTST_VCEQ 17
5369 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5370 #define NEON_3R_VMUL 19
5371 #define NEON_3R_VPMAX 20
5372 #define NEON_3R_VPMIN 21
5373 #define NEON_3R_VQDMULH_VQRDMULH 22
5374 #define NEON_3R_VPADD 23
5375 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5376 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5377 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5378 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5379 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5380 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5381 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5382 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5384 static const uint8_t neon_3r_sizes
[] = {
5385 [NEON_3R_VHADD
] = 0x7,
5386 [NEON_3R_VQADD
] = 0xf,
5387 [NEON_3R_VRHADD
] = 0x7,
5388 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5389 [NEON_3R_VHSUB
] = 0x7,
5390 [NEON_3R_VQSUB
] = 0xf,
5391 [NEON_3R_VCGT
] = 0x7,
5392 [NEON_3R_VCGE
] = 0x7,
5393 [NEON_3R_VSHL
] = 0xf,
5394 [NEON_3R_VQSHL
] = 0xf,
5395 [NEON_3R_VRSHL
] = 0xf,
5396 [NEON_3R_VQRSHL
] = 0xf,
5397 [NEON_3R_VMAX
] = 0x7,
5398 [NEON_3R_VMIN
] = 0x7,
5399 [NEON_3R_VABD
] = 0x7,
5400 [NEON_3R_VABA
] = 0x7,
5401 [NEON_3R_VADD_VSUB
] = 0xf,
5402 [NEON_3R_VTST_VCEQ
] = 0x7,
5403 [NEON_3R_VML
] = 0x7,
5404 [NEON_3R_VMUL
] = 0x7,
5405 [NEON_3R_VPMAX
] = 0x7,
5406 [NEON_3R_VPMIN
] = 0x7,
5407 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5408 [NEON_3R_VPADD
] = 0x7,
5409 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5410 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5411 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5412 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5413 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5414 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5415 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5416 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5419 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5420 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5423 #define NEON_2RM_VREV64 0
5424 #define NEON_2RM_VREV32 1
5425 #define NEON_2RM_VREV16 2
5426 #define NEON_2RM_VPADDL 4
5427 #define NEON_2RM_VPADDL_U 5
5428 #define NEON_2RM_AESE 6 /* Includes AESD */
5429 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5430 #define NEON_2RM_VCLS 8
5431 #define NEON_2RM_VCLZ 9
5432 #define NEON_2RM_VCNT 10
5433 #define NEON_2RM_VMVN 11
5434 #define NEON_2RM_VPADAL 12
5435 #define NEON_2RM_VPADAL_U 13
5436 #define NEON_2RM_VQABS 14
5437 #define NEON_2RM_VQNEG 15
5438 #define NEON_2RM_VCGT0 16
5439 #define NEON_2RM_VCGE0 17
5440 #define NEON_2RM_VCEQ0 18
5441 #define NEON_2RM_VCLE0 19
5442 #define NEON_2RM_VCLT0 20
5443 #define NEON_2RM_SHA1H 21
5444 #define NEON_2RM_VABS 22
5445 #define NEON_2RM_VNEG 23
5446 #define NEON_2RM_VCGT0_F 24
5447 #define NEON_2RM_VCGE0_F 25
5448 #define NEON_2RM_VCEQ0_F 26
5449 #define NEON_2RM_VCLE0_F 27
5450 #define NEON_2RM_VCLT0_F 28
5451 #define NEON_2RM_VABS_F 30
5452 #define NEON_2RM_VNEG_F 31
5453 #define NEON_2RM_VSWP 32
5454 #define NEON_2RM_VTRN 33
5455 #define NEON_2RM_VUZP 34
5456 #define NEON_2RM_VZIP 35
5457 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5458 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5459 #define NEON_2RM_VSHLL 38
5460 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5461 #define NEON_2RM_VRINTN 40
5462 #define NEON_2RM_VRINTX 41
5463 #define NEON_2RM_VRINTA 42
5464 #define NEON_2RM_VRINTZ 43
5465 #define NEON_2RM_VCVT_F16_F32 44
5466 #define NEON_2RM_VRINTM 45
5467 #define NEON_2RM_VCVT_F32_F16 46
5468 #define NEON_2RM_VRINTP 47
5469 #define NEON_2RM_VCVTAU 48
5470 #define NEON_2RM_VCVTAS 49
5471 #define NEON_2RM_VCVTNU 50
5472 #define NEON_2RM_VCVTNS 51
5473 #define NEON_2RM_VCVTPU 52
5474 #define NEON_2RM_VCVTPS 53
5475 #define NEON_2RM_VCVTMU 54
5476 #define NEON_2RM_VCVTMS 55
5477 #define NEON_2RM_VRECPE 56
5478 #define NEON_2RM_VRSQRTE 57
5479 #define NEON_2RM_VRECPE_F 58
5480 #define NEON_2RM_VRSQRTE_F 59
5481 #define NEON_2RM_VCVT_FS 60
5482 #define NEON_2RM_VCVT_FU 61
5483 #define NEON_2RM_VCVT_SF 62
5484 #define NEON_2RM_VCVT_UF 63
5486 static int neon_2rm_is_float_op(int op
)
5488 /* Return true if this neon 2reg-misc op is float-to-float */
5489 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5490 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5491 op
== NEON_2RM_VRINTM
||
5492 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5493 op
>= NEON_2RM_VRECPE_F
);
5496 static bool neon_2rm_is_v8_op(int op
)
5498 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5500 case NEON_2RM_VRINTN
:
5501 case NEON_2RM_VRINTA
:
5502 case NEON_2RM_VRINTM
:
5503 case NEON_2RM_VRINTP
:
5504 case NEON_2RM_VRINTZ
:
5505 case NEON_2RM_VRINTX
:
5506 case NEON_2RM_VCVTAU
:
5507 case NEON_2RM_VCVTAS
:
5508 case NEON_2RM_VCVTNU
:
5509 case NEON_2RM_VCVTNS
:
5510 case NEON_2RM_VCVTPU
:
5511 case NEON_2RM_VCVTPS
:
5512 case NEON_2RM_VCVTMU
:
5513 case NEON_2RM_VCVTMS
:
5520 /* Each entry in this array has bit n set if the insn allows
5521 * size value n (otherwise it will UNDEF). Since unallocated
5522 * op values will have no bits set they always UNDEF.
5524 static const uint8_t neon_2rm_sizes
[] = {
5525 [NEON_2RM_VREV64
] = 0x7,
5526 [NEON_2RM_VREV32
] = 0x3,
5527 [NEON_2RM_VREV16
] = 0x1,
5528 [NEON_2RM_VPADDL
] = 0x7,
5529 [NEON_2RM_VPADDL_U
] = 0x7,
5530 [NEON_2RM_AESE
] = 0x1,
5531 [NEON_2RM_AESMC
] = 0x1,
5532 [NEON_2RM_VCLS
] = 0x7,
5533 [NEON_2RM_VCLZ
] = 0x7,
5534 [NEON_2RM_VCNT
] = 0x1,
5535 [NEON_2RM_VMVN
] = 0x1,
5536 [NEON_2RM_VPADAL
] = 0x7,
5537 [NEON_2RM_VPADAL_U
] = 0x7,
5538 [NEON_2RM_VQABS
] = 0x7,
5539 [NEON_2RM_VQNEG
] = 0x7,
5540 [NEON_2RM_VCGT0
] = 0x7,
5541 [NEON_2RM_VCGE0
] = 0x7,
5542 [NEON_2RM_VCEQ0
] = 0x7,
5543 [NEON_2RM_VCLE0
] = 0x7,
5544 [NEON_2RM_VCLT0
] = 0x7,
5545 [NEON_2RM_SHA1H
] = 0x4,
5546 [NEON_2RM_VABS
] = 0x7,
5547 [NEON_2RM_VNEG
] = 0x7,
5548 [NEON_2RM_VCGT0_F
] = 0x4,
5549 [NEON_2RM_VCGE0_F
] = 0x4,
5550 [NEON_2RM_VCEQ0_F
] = 0x4,
5551 [NEON_2RM_VCLE0_F
] = 0x4,
5552 [NEON_2RM_VCLT0_F
] = 0x4,
5553 [NEON_2RM_VABS_F
] = 0x4,
5554 [NEON_2RM_VNEG_F
] = 0x4,
5555 [NEON_2RM_VSWP
] = 0x1,
5556 [NEON_2RM_VTRN
] = 0x7,
5557 [NEON_2RM_VUZP
] = 0x7,
5558 [NEON_2RM_VZIP
] = 0x7,
5559 [NEON_2RM_VMOVN
] = 0x7,
5560 [NEON_2RM_VQMOVN
] = 0x7,
5561 [NEON_2RM_VSHLL
] = 0x7,
5562 [NEON_2RM_SHA1SU1
] = 0x4,
5563 [NEON_2RM_VRINTN
] = 0x4,
5564 [NEON_2RM_VRINTX
] = 0x4,
5565 [NEON_2RM_VRINTA
] = 0x4,
5566 [NEON_2RM_VRINTZ
] = 0x4,
5567 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5568 [NEON_2RM_VRINTM
] = 0x4,
5569 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5570 [NEON_2RM_VRINTP
] = 0x4,
5571 [NEON_2RM_VCVTAU
] = 0x4,
5572 [NEON_2RM_VCVTAS
] = 0x4,
5573 [NEON_2RM_VCVTNU
] = 0x4,
5574 [NEON_2RM_VCVTNS
] = 0x4,
5575 [NEON_2RM_VCVTPU
] = 0x4,
5576 [NEON_2RM_VCVTPS
] = 0x4,
5577 [NEON_2RM_VCVTMU
] = 0x4,
5578 [NEON_2RM_VCVTMS
] = 0x4,
5579 [NEON_2RM_VRECPE
] = 0x4,
5580 [NEON_2RM_VRSQRTE
] = 0x4,
5581 [NEON_2RM_VRECPE_F
] = 0x4,
5582 [NEON_2RM_VRSQRTE_F
] = 0x4,
5583 [NEON_2RM_VCVT_FS
] = 0x4,
5584 [NEON_2RM_VCVT_FU
] = 0x4,
5585 [NEON_2RM_VCVT_SF
] = 0x4,
5586 [NEON_2RM_VCVT_UF
] = 0x4,
5589 /* Translate a NEON data processing instruction. Return nonzero if the
5590 instruction is invalid.
5591 We process data in a mixture of 32-bit and 64-bit chunks.
5592 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5594 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5606 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5607 TCGv_ptr ptr1
, ptr2
, ptr3
;
5610 /* FIXME: this access check should not take precedence over UNDEF
5611 * for invalid encodings; we will generate incorrect syndrome information
5612 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5614 if (s
->fp_excp_el
) {
5615 gen_exception_insn(s
, 4, EXCP_UDEF
,
5616 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5620 if (!s
->vfp_enabled
)
5622 q
= (insn
& (1 << 6)) != 0;
5623 u
= (insn
>> 24) & 1;
5624 VFP_DREG_D(rd
, insn
);
5625 VFP_DREG_N(rn
, insn
);
5626 VFP_DREG_M(rm
, insn
);
5627 size
= (insn
>> 20) & 3;
5628 if ((insn
& (1 << 23)) == 0) {
5629 /* Three register same length. */
5630 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5631 /* Catch invalid op and bad size combinations: UNDEF */
5632 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5635 /* All insns of this form UNDEF for either this condition or the
5636 * superset of cases "Q==1"; we catch the latter later.
5638 if (q
&& ((rd
| rn
| rm
) & 1)) {
5642 * The SHA-1/SHA-256 3-register instructions require special treatment
5643 * here, as their size field is overloaded as an op type selector, and
5644 * they all consume their input in a single pass.
5646 if (op
== NEON_3R_SHA
) {
5650 if (!u
) { /* SHA-1 */
5651 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5654 ptr1
= vfp_reg_ptr(true, rd
);
5655 ptr2
= vfp_reg_ptr(true, rn
);
5656 ptr3
= vfp_reg_ptr(true, rm
);
5657 tmp4
= tcg_const_i32(size
);
5658 gen_helper_crypto_sha1_3reg(ptr1
, ptr2
, ptr3
, tmp4
);
5659 tcg_temp_free_i32(tmp4
);
5660 } else { /* SHA-256 */
5661 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5664 ptr1
= vfp_reg_ptr(true, rd
);
5665 ptr2
= vfp_reg_ptr(true, rn
);
5666 ptr3
= vfp_reg_ptr(true, rm
);
5669 gen_helper_crypto_sha256h(ptr1
, ptr2
, ptr3
);
5672 gen_helper_crypto_sha256h2(ptr1
, ptr2
, ptr3
);
5675 gen_helper_crypto_sha256su1(ptr1
, ptr2
, ptr3
);
5679 tcg_temp_free_ptr(ptr1
);
5680 tcg_temp_free_ptr(ptr2
);
5681 tcg_temp_free_ptr(ptr3
);
5684 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5685 /* 64-bit element instructions. */
5686 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5687 neon_load_reg64(cpu_V0
, rn
+ pass
);
5688 neon_load_reg64(cpu_V1
, rm
+ pass
);
5692 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5695 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5701 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5704 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5710 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5712 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5717 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5720 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5726 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5728 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5731 case NEON_3R_VQRSHL
:
5733 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5736 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5740 case NEON_3R_VADD_VSUB
:
5742 tcg_gen_sub_i64(CPU_V001
);
5744 tcg_gen_add_i64(CPU_V001
);
5750 neon_store_reg64(cpu_V0
, rd
+ pass
);
5759 case NEON_3R_VQRSHL
:
5762 /* Shift instruction operands are reversed. */
5777 case NEON_3R_FLOAT_ARITH
:
5778 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5780 case NEON_3R_FLOAT_MINMAX
:
5781 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5783 case NEON_3R_FLOAT_CMP
:
5785 /* no encoding for U=0 C=1x */
5789 case NEON_3R_FLOAT_ACMP
:
5794 case NEON_3R_FLOAT_MISC
:
5795 /* VMAXNM/VMINNM in ARMv8 */
5796 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5801 if (u
&& (size
!= 0)) {
5802 /* UNDEF on invalid size for polynomial subcase */
5807 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5815 if (pairwise
&& q
) {
5816 /* All the pairwise insns UNDEF if Q is set */
5820 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5825 tmp
= neon_load_reg(rn
, 0);
5826 tmp2
= neon_load_reg(rn
, 1);
5828 tmp
= neon_load_reg(rm
, 0);
5829 tmp2
= neon_load_reg(rm
, 1);
5833 tmp
= neon_load_reg(rn
, pass
);
5834 tmp2
= neon_load_reg(rm
, pass
);
5838 GEN_NEON_INTEGER_OP(hadd
);
5841 GEN_NEON_INTEGER_OP_ENV(qadd
);
5843 case NEON_3R_VRHADD
:
5844 GEN_NEON_INTEGER_OP(rhadd
);
5846 case NEON_3R_LOGIC
: /* Logic ops. */
5847 switch ((u
<< 2) | size
) {
5849 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5852 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5855 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5858 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5861 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5864 tmp3
= neon_load_reg(rd
, pass
);
5865 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5866 tcg_temp_free_i32(tmp3
);
5869 tmp3
= neon_load_reg(rd
, pass
);
5870 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5871 tcg_temp_free_i32(tmp3
);
5874 tmp3
= neon_load_reg(rd
, pass
);
5875 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5876 tcg_temp_free_i32(tmp3
);
5881 GEN_NEON_INTEGER_OP(hsub
);
5884 GEN_NEON_INTEGER_OP_ENV(qsub
);
5887 GEN_NEON_INTEGER_OP(cgt
);
5890 GEN_NEON_INTEGER_OP(cge
);
5893 GEN_NEON_INTEGER_OP(shl
);
5896 GEN_NEON_INTEGER_OP_ENV(qshl
);
5899 GEN_NEON_INTEGER_OP(rshl
);
5901 case NEON_3R_VQRSHL
:
5902 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5905 GEN_NEON_INTEGER_OP(max
);
5908 GEN_NEON_INTEGER_OP(min
);
5911 GEN_NEON_INTEGER_OP(abd
);
5914 GEN_NEON_INTEGER_OP(abd
);
5915 tcg_temp_free_i32(tmp2
);
5916 tmp2
= neon_load_reg(rd
, pass
);
5917 gen_neon_add(size
, tmp
, tmp2
);
5919 case NEON_3R_VADD_VSUB
:
5920 if (!u
) { /* VADD */
5921 gen_neon_add(size
, tmp
, tmp2
);
5924 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5925 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5926 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5931 case NEON_3R_VTST_VCEQ
:
5932 if (!u
) { /* VTST */
5934 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5935 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5936 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5941 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5942 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5943 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5948 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5950 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5951 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5952 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5955 tcg_temp_free_i32(tmp2
);
5956 tmp2
= neon_load_reg(rd
, pass
);
5958 gen_neon_rsb(size
, tmp
, tmp2
);
5960 gen_neon_add(size
, tmp
, tmp2
);
5964 if (u
) { /* polynomial */
5965 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5966 } else { /* Integer */
5968 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5969 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5970 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5976 GEN_NEON_INTEGER_OP(pmax
);
5979 GEN_NEON_INTEGER_OP(pmin
);
5981 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5982 if (!u
) { /* VQDMULH */
5985 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5988 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5992 } else { /* VQRDMULH */
5995 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5998 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6006 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
6007 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
6008 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
6012 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
6014 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6015 switch ((u
<< 2) | size
) {
6018 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6021 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
6024 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
6029 tcg_temp_free_ptr(fpstatus
);
6032 case NEON_3R_FLOAT_MULTIPLY
:
6034 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6035 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6037 tcg_temp_free_i32(tmp2
);
6038 tmp2
= neon_load_reg(rd
, pass
);
6040 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6042 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6045 tcg_temp_free_ptr(fpstatus
);
6048 case NEON_3R_FLOAT_CMP
:
6050 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6052 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6055 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6057 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6060 tcg_temp_free_ptr(fpstatus
);
6063 case NEON_3R_FLOAT_ACMP
:
6065 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6067 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6069 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6071 tcg_temp_free_ptr(fpstatus
);
6074 case NEON_3R_FLOAT_MINMAX
:
6076 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6078 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6080 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6082 tcg_temp_free_ptr(fpstatus
);
6085 case NEON_3R_FLOAT_MISC
:
6088 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6090 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6092 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6094 tcg_temp_free_ptr(fpstatus
);
6097 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6099 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6105 /* VFMA, VFMS: fused multiply-add */
6106 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6107 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6110 gen_helper_vfp_negs(tmp
, tmp
);
6112 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6113 tcg_temp_free_i32(tmp3
);
6114 tcg_temp_free_ptr(fpstatus
);
6120 tcg_temp_free_i32(tmp2
);
6122 /* Save the result. For elementwise operations we can put it
6123 straight into the destination register. For pairwise operations
6124 we have to be careful to avoid clobbering the source operands. */
6125 if (pairwise
&& rd
== rm
) {
6126 neon_store_scratch(pass
, tmp
);
6128 neon_store_reg(rd
, pass
, tmp
);
6132 if (pairwise
&& rd
== rm
) {
6133 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6134 tmp
= neon_load_scratch(pass
);
6135 neon_store_reg(rd
, pass
, tmp
);
6138 /* End of 3 register same size operations. */
6139 } else if (insn
& (1 << 4)) {
6140 if ((insn
& 0x00380080) != 0) {
6141 /* Two registers and shift. */
6142 op
= (insn
>> 8) & 0xf;
6143 if (insn
& (1 << 7)) {
6151 while ((insn
& (1 << (size
+ 19))) == 0)
6154 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6155 /* To avoid excessive duplication of ops we implement shift
6156 by immediate using the variable shift operations. */
6158 /* Shift by immediate:
6159 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6160 if (q
&& ((rd
| rm
) & 1)) {
6163 if (!u
&& (op
== 4 || op
== 6)) {
6166 /* Right shifts are encoded as N - shift, where N is the
6167 element size in bits. */
6169 shift
= shift
- (1 << (size
+ 3));
6177 imm
= (uint8_t) shift
;
6182 imm
= (uint16_t) shift
;
6193 for (pass
= 0; pass
< count
; pass
++) {
6195 neon_load_reg64(cpu_V0
, rm
+ pass
);
6196 tcg_gen_movi_i64(cpu_V1
, imm
);
6201 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6203 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6208 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6210 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6213 case 5: /* VSHL, VSLI */
6214 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6216 case 6: /* VQSHLU */
6217 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6222 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6225 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6230 if (op
== 1 || op
== 3) {
6232 neon_load_reg64(cpu_V1
, rd
+ pass
);
6233 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6234 } else if (op
== 4 || (op
== 5 && u
)) {
6236 neon_load_reg64(cpu_V1
, rd
+ pass
);
6238 if (shift
< -63 || shift
> 63) {
6242 mask
= 0xffffffffffffffffull
>> -shift
;
6244 mask
= 0xffffffffffffffffull
<< shift
;
6247 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6248 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6250 neon_store_reg64(cpu_V0
, rd
+ pass
);
6251 } else { /* size < 3 */
6252 /* Operands in T0 and T1. */
6253 tmp
= neon_load_reg(rm
, pass
);
6254 tmp2
= tcg_temp_new_i32();
6255 tcg_gen_movi_i32(tmp2
, imm
);
6259 GEN_NEON_INTEGER_OP(shl
);
6263 GEN_NEON_INTEGER_OP(rshl
);
6266 case 5: /* VSHL, VSLI */
6268 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6269 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6270 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6274 case 6: /* VQSHLU */
6277 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6281 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6285 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6293 GEN_NEON_INTEGER_OP_ENV(qshl
);
6296 tcg_temp_free_i32(tmp2
);
6298 if (op
== 1 || op
== 3) {
6300 tmp2
= neon_load_reg(rd
, pass
);
6301 gen_neon_add(size
, tmp
, tmp2
);
6302 tcg_temp_free_i32(tmp2
);
6303 } else if (op
== 4 || (op
== 5 && u
)) {
6308 mask
= 0xff >> -shift
;
6310 mask
= (uint8_t)(0xff << shift
);
6316 mask
= 0xffff >> -shift
;
6318 mask
= (uint16_t)(0xffff << shift
);
6322 if (shift
< -31 || shift
> 31) {
6326 mask
= 0xffffffffu
>> -shift
;
6328 mask
= 0xffffffffu
<< shift
;
6334 tmp2
= neon_load_reg(rd
, pass
);
6335 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6336 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6337 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6338 tcg_temp_free_i32(tmp2
);
6340 neon_store_reg(rd
, pass
, tmp
);
6343 } else if (op
< 10) {
6344 /* Shift by immediate and narrow:
6345 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6346 int input_unsigned
= (op
== 8) ? !u
: u
;
6350 shift
= shift
- (1 << (size
+ 3));
6353 tmp64
= tcg_const_i64(shift
);
6354 neon_load_reg64(cpu_V0
, rm
);
6355 neon_load_reg64(cpu_V1
, rm
+ 1);
6356 for (pass
= 0; pass
< 2; pass
++) {
6364 if (input_unsigned
) {
6365 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6367 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6370 if (input_unsigned
) {
6371 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6373 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6376 tmp
= tcg_temp_new_i32();
6377 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6378 neon_store_reg(rd
, pass
, tmp
);
6380 tcg_temp_free_i64(tmp64
);
6383 imm
= (uint16_t)shift
;
6387 imm
= (uint32_t)shift
;
6389 tmp2
= tcg_const_i32(imm
);
6390 tmp4
= neon_load_reg(rm
+ 1, 0);
6391 tmp5
= neon_load_reg(rm
+ 1, 1);
6392 for (pass
= 0; pass
< 2; pass
++) {
6394 tmp
= neon_load_reg(rm
, 0);
6398 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6401 tmp3
= neon_load_reg(rm
, 1);
6405 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6407 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6408 tcg_temp_free_i32(tmp
);
6409 tcg_temp_free_i32(tmp3
);
6410 tmp
= tcg_temp_new_i32();
6411 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6412 neon_store_reg(rd
, pass
, tmp
);
6414 tcg_temp_free_i32(tmp2
);
6416 } else if (op
== 10) {
6418 if (q
|| (rd
& 1)) {
6421 tmp
= neon_load_reg(rm
, 0);
6422 tmp2
= neon_load_reg(rm
, 1);
6423 for (pass
= 0; pass
< 2; pass
++) {
6427 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6430 /* The shift is less than the width of the source
6431 type, so we can just shift the whole register. */
6432 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6433 /* Widen the result of shift: we need to clear
6434 * the potential overflow bits resulting from
6435 * left bits of the narrow input appearing as
6436 * right bits of left the neighbour narrow
6438 if (size
< 2 || !u
) {
6441 imm
= (0xffu
>> (8 - shift
));
6443 } else if (size
== 1) {
6444 imm
= 0xffff >> (16 - shift
);
6447 imm
= 0xffffffff >> (32 - shift
);
6450 imm64
= imm
| (((uint64_t)imm
) << 32);
6454 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6457 neon_store_reg64(cpu_V0
, rd
+ pass
);
6459 } else if (op
>= 14) {
6460 /* VCVT fixed-point. */
6461 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6464 /* We have already masked out the must-be-1 top bit of imm6,
6465 * hence this 32-shift where the ARM ARM has 64-imm6.
6468 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6469 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6472 gen_vfp_ulto(0, shift
, 1);
6474 gen_vfp_slto(0, shift
, 1);
6477 gen_vfp_toul(0, shift
, 1);
6479 gen_vfp_tosl(0, shift
, 1);
6481 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6486 } else { /* (insn & 0x00380080) == 0 */
6488 if (q
&& (rd
& 1)) {
6492 op
= (insn
>> 8) & 0xf;
6493 /* One register and immediate. */
6494 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6495 invert
= (insn
& (1 << 5)) != 0;
6496 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6497 * We choose to not special-case this and will behave as if a
6498 * valid constant encoding of 0 had been given.
6517 imm
= (imm
<< 8) | (imm
<< 24);
6520 imm
= (imm
<< 8) | 0xff;
6523 imm
= (imm
<< 16) | 0xffff;
6526 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6534 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6535 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6541 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6542 if (op
& 1 && op
< 12) {
6543 tmp
= neon_load_reg(rd
, pass
);
6545 /* The immediate value has already been inverted, so
6547 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6549 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6553 tmp
= tcg_temp_new_i32();
6554 if (op
== 14 && invert
) {
6558 for (n
= 0; n
< 4; n
++) {
6559 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6560 val
|= 0xff << (n
* 8);
6562 tcg_gen_movi_i32(tmp
, val
);
6564 tcg_gen_movi_i32(tmp
, imm
);
6567 neon_store_reg(rd
, pass
, tmp
);
6570 } else { /* (insn & 0x00800010 == 0x00800000) */
6572 op
= (insn
>> 8) & 0xf;
6573 if ((insn
& (1 << 6)) == 0) {
6574 /* Three registers of different lengths. */
6578 /* undefreq: bit 0 : UNDEF if size == 0
6579 * bit 1 : UNDEF if size == 1
6580 * bit 2 : UNDEF if size == 2
6581 * bit 3 : UNDEF if U == 1
6582 * Note that [2:0] set implies 'always UNDEF'
6585 /* prewiden, src1_wide, src2_wide, undefreq */
6586 static const int neon_3reg_wide
[16][4] = {
6587 {1, 0, 0, 0}, /* VADDL */
6588 {1, 1, 0, 0}, /* VADDW */
6589 {1, 0, 0, 0}, /* VSUBL */
6590 {1, 1, 0, 0}, /* VSUBW */
6591 {0, 1, 1, 0}, /* VADDHN */
6592 {0, 0, 0, 0}, /* VABAL */
6593 {0, 1, 1, 0}, /* VSUBHN */
6594 {0, 0, 0, 0}, /* VABDL */
6595 {0, 0, 0, 0}, /* VMLAL */
6596 {0, 0, 0, 9}, /* VQDMLAL */
6597 {0, 0, 0, 0}, /* VMLSL */
6598 {0, 0, 0, 9}, /* VQDMLSL */
6599 {0, 0, 0, 0}, /* Integer VMULL */
6600 {0, 0, 0, 1}, /* VQDMULL */
6601 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6602 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6605 prewiden
= neon_3reg_wide
[op
][0];
6606 src1_wide
= neon_3reg_wide
[op
][1];
6607 src2_wide
= neon_3reg_wide
[op
][2];
6608 undefreq
= neon_3reg_wide
[op
][3];
6610 if ((undefreq
& (1 << size
)) ||
6611 ((undefreq
& 8) && u
)) {
6614 if ((src1_wide
&& (rn
& 1)) ||
6615 (src2_wide
&& (rm
& 1)) ||
6616 (!src2_wide
&& (rd
& 1))) {
6620 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6621 * outside the loop below as it only performs a single pass.
6623 if (op
== 14 && size
== 2) {
6624 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6626 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6629 tcg_rn
= tcg_temp_new_i64();
6630 tcg_rm
= tcg_temp_new_i64();
6631 tcg_rd
= tcg_temp_new_i64();
6632 neon_load_reg64(tcg_rn
, rn
);
6633 neon_load_reg64(tcg_rm
, rm
);
6634 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6635 neon_store_reg64(tcg_rd
, rd
);
6636 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6637 neon_store_reg64(tcg_rd
, rd
+ 1);
6638 tcg_temp_free_i64(tcg_rn
);
6639 tcg_temp_free_i64(tcg_rm
);
6640 tcg_temp_free_i64(tcg_rd
);
6644 /* Avoid overlapping operands. Wide source operands are
6645 always aligned so will never overlap with wide
6646 destinations in problematic ways. */
6647 if (rd
== rm
&& !src2_wide
) {
6648 tmp
= neon_load_reg(rm
, 1);
6649 neon_store_scratch(2, tmp
);
6650 } else if (rd
== rn
&& !src1_wide
) {
6651 tmp
= neon_load_reg(rn
, 1);
6652 neon_store_scratch(2, tmp
);
6655 for (pass
= 0; pass
< 2; pass
++) {
6657 neon_load_reg64(cpu_V0
, rn
+ pass
);
6660 if (pass
== 1 && rd
== rn
) {
6661 tmp
= neon_load_scratch(2);
6663 tmp
= neon_load_reg(rn
, pass
);
6666 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6670 neon_load_reg64(cpu_V1
, rm
+ pass
);
6673 if (pass
== 1 && rd
== rm
) {
6674 tmp2
= neon_load_scratch(2);
6676 tmp2
= neon_load_reg(rm
, pass
);
6679 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6683 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6684 gen_neon_addl(size
);
6686 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6687 gen_neon_subl(size
);
6689 case 5: case 7: /* VABAL, VABDL */
6690 switch ((size
<< 1) | u
) {
6692 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6695 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6698 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6701 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6704 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6707 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6711 tcg_temp_free_i32(tmp2
);
6712 tcg_temp_free_i32(tmp
);
6714 case 8: case 9: case 10: case 11: case 12: case 13:
6715 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6716 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6718 case 14: /* Polynomial VMULL */
6719 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6720 tcg_temp_free_i32(tmp2
);
6721 tcg_temp_free_i32(tmp
);
6723 default: /* 15 is RESERVED: caught earlier */
6728 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6729 neon_store_reg64(cpu_V0
, rd
+ pass
);
6730 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6732 neon_load_reg64(cpu_V1
, rd
+ pass
);
6734 case 10: /* VMLSL */
6735 gen_neon_negl(cpu_V0
, size
);
6737 case 5: case 8: /* VABAL, VMLAL */
6738 gen_neon_addl(size
);
6740 case 9: case 11: /* VQDMLAL, VQDMLSL */
6741 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6743 gen_neon_negl(cpu_V0
, size
);
6745 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6750 neon_store_reg64(cpu_V0
, rd
+ pass
);
6751 } else if (op
== 4 || op
== 6) {
6752 /* Narrowing operation. */
6753 tmp
= tcg_temp_new_i32();
6757 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6760 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6763 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6764 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6771 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6774 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6777 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6778 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6779 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6787 neon_store_reg(rd
, 0, tmp3
);
6788 neon_store_reg(rd
, 1, tmp
);
6791 /* Write back the result. */
6792 neon_store_reg64(cpu_V0
, rd
+ pass
);
6796 /* Two registers and a scalar. NB that for ops of this form
6797 * the ARM ARM labels bit 24 as Q, but it is in our variable
6804 case 1: /* Float VMLA scalar */
6805 case 5: /* Floating point VMLS scalar */
6806 case 9: /* Floating point VMUL scalar */
6811 case 0: /* Integer VMLA scalar */
6812 case 4: /* Integer VMLS scalar */
6813 case 8: /* Integer VMUL scalar */
6814 case 12: /* VQDMULH scalar */
6815 case 13: /* VQRDMULH scalar */
6816 if (u
&& ((rd
| rn
) & 1)) {
6819 tmp
= neon_get_scalar(size
, rm
);
6820 neon_store_scratch(0, tmp
);
6821 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6822 tmp
= neon_load_scratch(0);
6823 tmp2
= neon_load_reg(rn
, pass
);
6826 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6828 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6830 } else if (op
== 13) {
6832 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6834 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6836 } else if (op
& 1) {
6837 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6838 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6839 tcg_temp_free_ptr(fpstatus
);
6842 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6843 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6844 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6848 tcg_temp_free_i32(tmp2
);
6851 tmp2
= neon_load_reg(rd
, pass
);
6854 gen_neon_add(size
, tmp
, tmp2
);
6858 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6859 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6860 tcg_temp_free_ptr(fpstatus
);
6864 gen_neon_rsb(size
, tmp
, tmp2
);
6868 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6869 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6870 tcg_temp_free_ptr(fpstatus
);
6876 tcg_temp_free_i32(tmp2
);
6878 neon_store_reg(rd
, pass
, tmp
);
6881 case 3: /* VQDMLAL scalar */
6882 case 7: /* VQDMLSL scalar */
6883 case 11: /* VQDMULL scalar */
6888 case 2: /* VMLAL sclar */
6889 case 6: /* VMLSL scalar */
6890 case 10: /* VMULL scalar */
6894 tmp2
= neon_get_scalar(size
, rm
);
6895 /* We need a copy of tmp2 because gen_neon_mull
6896 * deletes it during pass 0. */
6897 tmp4
= tcg_temp_new_i32();
6898 tcg_gen_mov_i32(tmp4
, tmp2
);
6899 tmp3
= neon_load_reg(rn
, 1);
6901 for (pass
= 0; pass
< 2; pass
++) {
6903 tmp
= neon_load_reg(rn
, 0);
6908 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6910 neon_load_reg64(cpu_V1
, rd
+ pass
);
6914 gen_neon_negl(cpu_V0
, size
);
6917 gen_neon_addl(size
);
6920 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6922 gen_neon_negl(cpu_V0
, size
);
6924 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6930 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6935 neon_store_reg64(cpu_V0
, rd
+ pass
);
6940 default: /* 14 and 15 are RESERVED */
6944 } else { /* size == 3 */
6947 imm
= (insn
>> 8) & 0xf;
6952 if (q
&& ((rd
| rn
| rm
) & 1)) {
6957 neon_load_reg64(cpu_V0
, rn
);
6959 neon_load_reg64(cpu_V1
, rn
+ 1);
6961 } else if (imm
== 8) {
6962 neon_load_reg64(cpu_V0
, rn
+ 1);
6964 neon_load_reg64(cpu_V1
, rm
);
6967 tmp64
= tcg_temp_new_i64();
6969 neon_load_reg64(cpu_V0
, rn
);
6970 neon_load_reg64(tmp64
, rn
+ 1);
6972 neon_load_reg64(cpu_V0
, rn
+ 1);
6973 neon_load_reg64(tmp64
, rm
);
6975 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6976 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6977 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6979 neon_load_reg64(cpu_V1
, rm
);
6981 neon_load_reg64(cpu_V1
, rm
+ 1);
6984 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6985 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6986 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6987 tcg_temp_free_i64(tmp64
);
6990 neon_load_reg64(cpu_V0
, rn
);
6991 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6992 neon_load_reg64(cpu_V1
, rm
);
6993 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6994 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6996 neon_store_reg64(cpu_V0
, rd
);
6998 neon_store_reg64(cpu_V1
, rd
+ 1);
7000 } else if ((insn
& (1 << 11)) == 0) {
7001 /* Two register misc. */
7002 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
7003 size
= (insn
>> 18) & 3;
7004 /* UNDEF for unknown op values and bad op-size combinations */
7005 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
7008 if (neon_2rm_is_v8_op(op
) &&
7009 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7012 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
7013 q
&& ((rm
| rd
) & 1)) {
7017 case NEON_2RM_VREV64
:
7018 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
7019 tmp
= neon_load_reg(rm
, pass
* 2);
7020 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
7022 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7023 case 1: gen_swap_half(tmp
); break;
7024 case 2: /* no-op */ break;
7027 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
7029 neon_store_reg(rd
, pass
* 2, tmp2
);
7032 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
7033 case 1: gen_swap_half(tmp2
); break;
7036 neon_store_reg(rd
, pass
* 2, tmp2
);
7040 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
7041 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
7042 for (pass
= 0; pass
< q
+ 1; pass
++) {
7043 tmp
= neon_load_reg(rm
, pass
* 2);
7044 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
7045 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
7046 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
7048 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
7049 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
7050 case 2: tcg_gen_add_i64(CPU_V001
); break;
7053 if (op
>= NEON_2RM_VPADAL
) {
7055 neon_load_reg64(cpu_V1
, rd
+ pass
);
7056 gen_neon_addl(size
);
7058 neon_store_reg64(cpu_V0
, rd
+ pass
);
7064 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7065 tmp
= neon_load_reg(rm
, n
);
7066 tmp2
= neon_load_reg(rd
, n
+ 1);
7067 neon_store_reg(rm
, n
, tmp2
);
7068 neon_store_reg(rd
, n
+ 1, tmp
);
7075 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7080 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7084 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7085 /* also VQMOVUN; op field and mnemonics don't line up */
7090 for (pass
= 0; pass
< 2; pass
++) {
7091 neon_load_reg64(cpu_V0
, rm
+ pass
);
7092 tmp
= tcg_temp_new_i32();
7093 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7098 neon_store_reg(rd
, 0, tmp2
);
7099 neon_store_reg(rd
, 1, tmp
);
7103 case NEON_2RM_VSHLL
:
7104 if (q
|| (rd
& 1)) {
7107 tmp
= neon_load_reg(rm
, 0);
7108 tmp2
= neon_load_reg(rm
, 1);
7109 for (pass
= 0; pass
< 2; pass
++) {
7112 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7113 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7114 neon_store_reg64(cpu_V0
, rd
+ pass
);
7117 case NEON_2RM_VCVT_F16_F32
:
7118 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7122 tmp
= tcg_temp_new_i32();
7123 tmp2
= tcg_temp_new_i32();
7124 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7125 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7126 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
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 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7131 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7132 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7133 neon_store_reg(rd
, 0, tmp2
);
7134 tmp2
= tcg_temp_new_i32();
7135 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7136 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7137 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7138 neon_store_reg(rd
, 1, tmp2
);
7139 tcg_temp_free_i32(tmp
);
7141 case NEON_2RM_VCVT_F32_F16
:
7142 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7146 tmp3
= tcg_temp_new_i32();
7147 tmp
= neon_load_reg(rm
, 0);
7148 tmp2
= neon_load_reg(rm
, 1);
7149 tcg_gen_ext16u_i32(tmp3
, tmp
);
7150 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7151 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7152 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7153 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7154 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7155 tcg_temp_free_i32(tmp
);
7156 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7157 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7158 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7159 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7160 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7161 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7162 tcg_temp_free_i32(tmp2
);
7163 tcg_temp_free_i32(tmp3
);
7165 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7166 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
7167 || ((rm
| rd
) & 1)) {
7170 ptr1
= vfp_reg_ptr(true, rd
);
7171 ptr2
= vfp_reg_ptr(true, rm
);
7173 /* Bit 6 is the lowest opcode bit; it distinguishes between
7174 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7176 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7178 if (op
== NEON_2RM_AESE
) {
7179 gen_helper_crypto_aese(ptr1
, ptr2
, tmp3
);
7181 gen_helper_crypto_aesmc(ptr1
, ptr2
, tmp3
);
7183 tcg_temp_free_ptr(ptr1
);
7184 tcg_temp_free_ptr(ptr2
);
7185 tcg_temp_free_i32(tmp3
);
7187 case NEON_2RM_SHA1H
:
7188 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7189 || ((rm
| rd
) & 1)) {
7192 ptr1
= vfp_reg_ptr(true, rd
);
7193 ptr2
= vfp_reg_ptr(true, rm
);
7195 gen_helper_crypto_sha1h(ptr1
, ptr2
);
7197 tcg_temp_free_ptr(ptr1
);
7198 tcg_temp_free_ptr(ptr2
);
7200 case NEON_2RM_SHA1SU1
:
7201 if ((rm
| rd
) & 1) {
7204 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7206 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7209 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7212 ptr1
= vfp_reg_ptr(true, rd
);
7213 ptr2
= vfp_reg_ptr(true, rm
);
7215 gen_helper_crypto_sha256su0(ptr1
, ptr2
);
7217 gen_helper_crypto_sha1su1(ptr1
, ptr2
);
7219 tcg_temp_free_ptr(ptr1
);
7220 tcg_temp_free_ptr(ptr2
);
7224 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7225 if (neon_2rm_is_float_op(op
)) {
7226 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7227 neon_reg_offset(rm
, pass
));
7230 tmp
= neon_load_reg(rm
, pass
);
7233 case NEON_2RM_VREV32
:
7235 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7236 case 1: gen_swap_half(tmp
); break;
7240 case NEON_2RM_VREV16
:
7245 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7246 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7247 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7253 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7254 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7255 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7260 gen_helper_neon_cnt_u8(tmp
, tmp
);
7263 tcg_gen_not_i32(tmp
, tmp
);
7265 case NEON_2RM_VQABS
:
7268 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7271 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7274 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7279 case NEON_2RM_VQNEG
:
7282 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7285 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7288 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7293 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7294 tmp2
= tcg_const_i32(0);
7296 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7297 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7298 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7301 tcg_temp_free_i32(tmp2
);
7302 if (op
== NEON_2RM_VCLE0
) {
7303 tcg_gen_not_i32(tmp
, tmp
);
7306 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7307 tmp2
= tcg_const_i32(0);
7309 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7310 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7311 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7314 tcg_temp_free_i32(tmp2
);
7315 if (op
== NEON_2RM_VCLT0
) {
7316 tcg_gen_not_i32(tmp
, tmp
);
7319 case NEON_2RM_VCEQ0
:
7320 tmp2
= tcg_const_i32(0);
7322 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7323 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7324 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7327 tcg_temp_free_i32(tmp2
);
7331 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7332 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7333 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7338 tmp2
= tcg_const_i32(0);
7339 gen_neon_rsb(size
, tmp
, tmp2
);
7340 tcg_temp_free_i32(tmp2
);
7342 case NEON_2RM_VCGT0_F
:
7344 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7345 tmp2
= tcg_const_i32(0);
7346 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7347 tcg_temp_free_i32(tmp2
);
7348 tcg_temp_free_ptr(fpstatus
);
7351 case NEON_2RM_VCGE0_F
:
7353 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7354 tmp2
= tcg_const_i32(0);
7355 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7356 tcg_temp_free_i32(tmp2
);
7357 tcg_temp_free_ptr(fpstatus
);
7360 case NEON_2RM_VCEQ0_F
:
7362 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7363 tmp2
= tcg_const_i32(0);
7364 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7365 tcg_temp_free_i32(tmp2
);
7366 tcg_temp_free_ptr(fpstatus
);
7369 case NEON_2RM_VCLE0_F
:
7371 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7372 tmp2
= tcg_const_i32(0);
7373 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7374 tcg_temp_free_i32(tmp2
);
7375 tcg_temp_free_ptr(fpstatus
);
7378 case NEON_2RM_VCLT0_F
:
7380 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7381 tmp2
= tcg_const_i32(0);
7382 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7383 tcg_temp_free_i32(tmp2
);
7384 tcg_temp_free_ptr(fpstatus
);
7387 case NEON_2RM_VABS_F
:
7390 case NEON_2RM_VNEG_F
:
7394 tmp2
= neon_load_reg(rd
, pass
);
7395 neon_store_reg(rm
, pass
, tmp2
);
7398 tmp2
= neon_load_reg(rd
, pass
);
7400 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7401 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7404 neon_store_reg(rm
, pass
, tmp2
);
7406 case NEON_2RM_VRINTN
:
7407 case NEON_2RM_VRINTA
:
7408 case NEON_2RM_VRINTM
:
7409 case NEON_2RM_VRINTP
:
7410 case NEON_2RM_VRINTZ
:
7413 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7416 if (op
== NEON_2RM_VRINTZ
) {
7417 rmode
= FPROUNDING_ZERO
;
7419 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7422 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7423 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7425 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7426 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7428 tcg_temp_free_ptr(fpstatus
);
7429 tcg_temp_free_i32(tcg_rmode
);
7432 case NEON_2RM_VRINTX
:
7434 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7435 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7436 tcg_temp_free_ptr(fpstatus
);
7439 case NEON_2RM_VCVTAU
:
7440 case NEON_2RM_VCVTAS
:
7441 case NEON_2RM_VCVTNU
:
7442 case NEON_2RM_VCVTNS
:
7443 case NEON_2RM_VCVTPU
:
7444 case NEON_2RM_VCVTPS
:
7445 case NEON_2RM_VCVTMU
:
7446 case NEON_2RM_VCVTMS
:
7448 bool is_signed
= !extract32(insn
, 7, 1);
7449 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7450 TCGv_i32 tcg_rmode
, tcg_shift
;
7451 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7453 tcg_shift
= tcg_const_i32(0);
7454 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7455 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7459 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7462 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7466 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7468 tcg_temp_free_i32(tcg_rmode
);
7469 tcg_temp_free_i32(tcg_shift
);
7470 tcg_temp_free_ptr(fpst
);
7473 case NEON_2RM_VRECPE
:
7475 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7476 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7477 tcg_temp_free_ptr(fpstatus
);
7480 case NEON_2RM_VRSQRTE
:
7482 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7483 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7484 tcg_temp_free_ptr(fpstatus
);
7487 case NEON_2RM_VRECPE_F
:
7489 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7490 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7491 tcg_temp_free_ptr(fpstatus
);
7494 case NEON_2RM_VRSQRTE_F
:
7496 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7497 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7498 tcg_temp_free_ptr(fpstatus
);
7501 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7504 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7507 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7508 gen_vfp_tosiz(0, 1);
7510 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7511 gen_vfp_touiz(0, 1);
7514 /* Reserved op values were caught by the
7515 * neon_2rm_sizes[] check earlier.
7519 if (neon_2rm_is_float_op(op
)) {
7520 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7521 neon_reg_offset(rd
, pass
));
7523 neon_store_reg(rd
, pass
, tmp
);
7528 } else if ((insn
& (1 << 10)) == 0) {
7530 int n
= ((insn
>> 8) & 3) + 1;
7531 if ((rn
+ n
) > 32) {
7532 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7533 * helper function running off the end of the register file.
7538 if (insn
& (1 << 6)) {
7539 tmp
= neon_load_reg(rd
, 0);
7541 tmp
= tcg_temp_new_i32();
7542 tcg_gen_movi_i32(tmp
, 0);
7544 tmp2
= neon_load_reg(rm
, 0);
7545 tmp4
= tcg_const_i32(rn
);
7546 tmp5
= tcg_const_i32(n
);
7547 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7548 tcg_temp_free_i32(tmp
);
7549 if (insn
& (1 << 6)) {
7550 tmp
= neon_load_reg(rd
, 1);
7552 tmp
= tcg_temp_new_i32();
7553 tcg_gen_movi_i32(tmp
, 0);
7555 tmp3
= neon_load_reg(rm
, 1);
7556 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7557 tcg_temp_free_i32(tmp5
);
7558 tcg_temp_free_i32(tmp4
);
7559 neon_store_reg(rd
, 0, tmp2
);
7560 neon_store_reg(rd
, 1, tmp3
);
7561 tcg_temp_free_i32(tmp
);
7562 } else if ((insn
& 0x380) == 0) {
7564 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7567 if (insn
& (1 << 19)) {
7568 tmp
= neon_load_reg(rm
, 1);
7570 tmp
= neon_load_reg(rm
, 0);
7572 if (insn
& (1 << 16)) {
7573 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7574 } else if (insn
& (1 << 17)) {
7575 if ((insn
>> 18) & 1)
7576 gen_neon_dup_high16(tmp
);
7578 gen_neon_dup_low16(tmp
);
7580 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7581 tmp2
= tcg_temp_new_i32();
7582 tcg_gen_mov_i32(tmp2
, tmp
);
7583 neon_store_reg(rd
, pass
, tmp2
);
7585 tcg_temp_free_i32(tmp
);
7594 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7596 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7597 const ARMCPRegInfo
*ri
;
7599 cpnum
= (insn
>> 8) & 0xf;
7601 /* First check for coprocessor space used for XScale/iwMMXt insns */
7602 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7603 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7606 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7607 return disas_iwmmxt_insn(s
, insn
);
7608 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7609 return disas_dsp_insn(s
, insn
);
7614 /* Otherwise treat as a generic register access */
7615 is64
= (insn
& (1 << 25)) == 0;
7616 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7624 opc1
= (insn
>> 4) & 0xf;
7626 rt2
= (insn
>> 16) & 0xf;
7628 crn
= (insn
>> 16) & 0xf;
7629 opc1
= (insn
>> 21) & 7;
7630 opc2
= (insn
>> 5) & 7;
7633 isread
= (insn
>> 20) & 1;
7634 rt
= (insn
>> 12) & 0xf;
7636 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7637 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7639 /* Check access permissions */
7640 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7645 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7646 /* Emit code to perform further access permissions checks at
7647 * runtime; this may result in an exception.
7648 * Note that on XScale all cp0..c13 registers do an access check
7649 * call in order to handle c15_cpar.
7652 TCGv_i32 tcg_syn
, tcg_isread
;
7655 /* Note that since we are an implementation which takes an
7656 * exception on a trapped conditional instruction only if the
7657 * instruction passes its condition code check, we can take
7658 * advantage of the clause in the ARM ARM that allows us to set
7659 * the COND field in the instruction to 0xE in all cases.
7660 * We could fish the actual condition out of the insn (ARM)
7661 * or the condexec bits (Thumb) but it isn't necessary.
7666 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7669 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7675 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7678 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7683 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7684 * so this can only happen if this is an ARMv7 or earlier CPU,
7685 * in which case the syndrome information won't actually be
7688 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7689 syndrome
= syn_uncategorized();
7693 gen_set_condexec(s
);
7694 gen_set_pc_im(s
, s
->pc
- 4);
7695 tmpptr
= tcg_const_ptr(ri
);
7696 tcg_syn
= tcg_const_i32(syndrome
);
7697 tcg_isread
= tcg_const_i32(isread
);
7698 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7700 tcg_temp_free_ptr(tmpptr
);
7701 tcg_temp_free_i32(tcg_syn
);
7702 tcg_temp_free_i32(tcg_isread
);
7705 /* Handle special cases first */
7706 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7713 gen_set_pc_im(s
, s
->pc
);
7714 s
->base
.is_jmp
= DISAS_WFI
;
7720 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7729 if (ri
->type
& ARM_CP_CONST
) {
7730 tmp64
= tcg_const_i64(ri
->resetvalue
);
7731 } else if (ri
->readfn
) {
7733 tmp64
= tcg_temp_new_i64();
7734 tmpptr
= tcg_const_ptr(ri
);
7735 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7736 tcg_temp_free_ptr(tmpptr
);
7738 tmp64
= tcg_temp_new_i64();
7739 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7741 tmp
= tcg_temp_new_i32();
7742 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7743 store_reg(s
, rt
, tmp
);
7744 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7745 tmp
= tcg_temp_new_i32();
7746 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7747 tcg_temp_free_i64(tmp64
);
7748 store_reg(s
, rt2
, tmp
);
7751 if (ri
->type
& ARM_CP_CONST
) {
7752 tmp
= tcg_const_i32(ri
->resetvalue
);
7753 } else if (ri
->readfn
) {
7755 tmp
= tcg_temp_new_i32();
7756 tmpptr
= tcg_const_ptr(ri
);
7757 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7758 tcg_temp_free_ptr(tmpptr
);
7760 tmp
= load_cpu_offset(ri
->fieldoffset
);
7763 /* Destination register of r15 for 32 bit loads sets
7764 * the condition codes from the high 4 bits of the value
7767 tcg_temp_free_i32(tmp
);
7769 store_reg(s
, rt
, tmp
);
7774 if (ri
->type
& ARM_CP_CONST
) {
7775 /* If not forbidden by access permissions, treat as WI */
7780 TCGv_i32 tmplo
, tmphi
;
7781 TCGv_i64 tmp64
= tcg_temp_new_i64();
7782 tmplo
= load_reg(s
, rt
);
7783 tmphi
= load_reg(s
, rt2
);
7784 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7785 tcg_temp_free_i32(tmplo
);
7786 tcg_temp_free_i32(tmphi
);
7788 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7789 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7790 tcg_temp_free_ptr(tmpptr
);
7792 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7794 tcg_temp_free_i64(tmp64
);
7799 tmp
= load_reg(s
, rt
);
7800 tmpptr
= tcg_const_ptr(ri
);
7801 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7802 tcg_temp_free_ptr(tmpptr
);
7803 tcg_temp_free_i32(tmp
);
7805 TCGv_i32 tmp
= load_reg(s
, rt
);
7806 store_cpu_offset(tmp
, ri
->fieldoffset
);
7811 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7812 /* I/O operations must end the TB here (whether read or write) */
7815 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7816 /* We default to ending the TB on a coprocessor register write,
7817 * but allow this to be suppressed by the register definition
7818 * (usually only necessary to work around guest bugs).
7826 /* Unknown register; this might be a guest error or a QEMU
7827 * unimplemented feature.
7830 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7831 "64 bit system register cp:%d opc1: %d crm:%d "
7833 isread
? "read" : "write", cpnum
, opc1
, crm
,
7834 s
->ns
? "non-secure" : "secure");
7836 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7837 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7839 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7840 s
->ns
? "non-secure" : "secure");
7847 /* Store a 64-bit value to a register pair. Clobbers val. */
7848 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7851 tmp
= tcg_temp_new_i32();
7852 tcg_gen_extrl_i64_i32(tmp
, val
);
7853 store_reg(s
, rlow
, tmp
);
7854 tmp
= tcg_temp_new_i32();
7855 tcg_gen_shri_i64(val
, val
, 32);
7856 tcg_gen_extrl_i64_i32(tmp
, val
);
7857 store_reg(s
, rhigh
, tmp
);
7860 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7861 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7866 /* Load value and extend to 64 bits. */
7867 tmp
= tcg_temp_new_i64();
7868 tmp2
= load_reg(s
, rlow
);
7869 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7870 tcg_temp_free_i32(tmp2
);
7871 tcg_gen_add_i64(val
, val
, tmp
);
7872 tcg_temp_free_i64(tmp
);
7875 /* load and add a 64-bit value from a register pair. */
7876 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7882 /* Load 64-bit value rd:rn. */
7883 tmpl
= load_reg(s
, rlow
);
7884 tmph
= load_reg(s
, rhigh
);
7885 tmp
= tcg_temp_new_i64();
7886 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7887 tcg_temp_free_i32(tmpl
);
7888 tcg_temp_free_i32(tmph
);
7889 tcg_gen_add_i64(val
, val
, tmp
);
7890 tcg_temp_free_i64(tmp
);
7893 /* Set N and Z flags from hi|lo. */
7894 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7896 tcg_gen_mov_i32(cpu_NF
, hi
);
7897 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7900 /* Load/Store exclusive instructions are implemented by remembering
7901 the value/address loaded, and seeing if these are the same
7902 when the store is performed. This should be sufficient to implement
7903 the architecturally mandated semantics, and avoids having to monitor
7904 regular stores. The compare vs the remembered value is done during
7905 the cmpxchg operation, but we must compare the addresses manually. */
7906 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7907 TCGv_i32 addr
, int size
)
7909 TCGv_i32 tmp
= tcg_temp_new_i32();
7910 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7915 TCGv_i32 tmp2
= tcg_temp_new_i32();
7916 TCGv_i64 t64
= tcg_temp_new_i64();
7918 /* For AArch32, architecturally the 32-bit word at the lowest
7919 * address is always Rt and the one at addr+4 is Rt2, even if
7920 * the CPU is big-endian. That means we don't want to do a
7921 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7922 * for an architecturally 64-bit access, but instead do a
7923 * 64-bit access using MO_BE if appropriate and then split
7925 * This only makes a difference for BE32 user-mode, where
7926 * frob64() must not flip the two halves of the 64-bit data
7927 * but this code must treat BE32 user-mode like BE32 system.
7929 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
7931 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
7932 tcg_temp_free(taddr
);
7933 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
7934 if (s
->be_data
== MO_BE
) {
7935 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
7937 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
7939 tcg_temp_free_i64(t64
);
7941 store_reg(s
, rt2
, tmp2
);
7943 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
7944 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7947 store_reg(s
, rt
, tmp
);
7948 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7951 static void gen_clrex(DisasContext
*s
)
7953 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7956 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7957 TCGv_i32 addr
, int size
)
7959 TCGv_i32 t0
, t1
, t2
;
7962 TCGLabel
*done_label
;
7963 TCGLabel
*fail_label
;
7964 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7966 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7972 fail_label
= gen_new_label();
7973 done_label
= gen_new_label();
7974 extaddr
= tcg_temp_new_i64();
7975 tcg_gen_extu_i32_i64(extaddr
, addr
);
7976 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7977 tcg_temp_free_i64(extaddr
);
7979 taddr
= gen_aa32_addr(s
, addr
, opc
);
7980 t0
= tcg_temp_new_i32();
7981 t1
= load_reg(s
, rt
);
7983 TCGv_i64 o64
= tcg_temp_new_i64();
7984 TCGv_i64 n64
= tcg_temp_new_i64();
7986 t2
= load_reg(s
, rt2
);
7987 /* For AArch32, architecturally the 32-bit word at the lowest
7988 * address is always Rt and the one at addr+4 is Rt2, even if
7989 * the CPU is big-endian. Since we're going to treat this as a
7990 * single 64-bit BE store, we need to put the two halves in the
7991 * opposite order for BE to LE, so that they end up in the right
7993 * We don't want gen_aa32_frob64() because that does the wrong
7994 * thing for BE32 usermode.
7996 if (s
->be_data
== MO_BE
) {
7997 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
7999 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
8001 tcg_temp_free_i32(t2
);
8003 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
8004 get_mem_index(s
), opc
);
8005 tcg_temp_free_i64(n64
);
8007 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
8008 tcg_gen_extrl_i64_i32(t0
, o64
);
8010 tcg_temp_free_i64(o64
);
8012 t2
= tcg_temp_new_i32();
8013 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
8014 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
8015 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
8016 tcg_temp_free_i32(t2
);
8018 tcg_temp_free_i32(t1
);
8019 tcg_temp_free(taddr
);
8020 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
8021 tcg_temp_free_i32(t0
);
8022 tcg_gen_br(done_label
);
8024 gen_set_label(fail_label
);
8025 tcg_gen_movi_i32(cpu_R
[rd
], 1);
8026 gen_set_label(done_label
);
8027 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
8033 * @mode: mode field from insn (which stack to store to)
8034 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8035 * @writeback: true if writeback bit set
8037 * Generate code for the SRS (Store Return State) insn.
8039 static void gen_srs(DisasContext
*s
,
8040 uint32_t mode
, uint32_t amode
, bool writeback
)
8047 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8048 * and specified mode is monitor mode
8049 * - UNDEFINED in Hyp mode
8050 * - UNPREDICTABLE in User or System mode
8051 * - UNPREDICTABLE if the specified mode is:
8052 * -- not implemented
8053 * -- not a valid mode number
8054 * -- a mode that's at a higher exception level
8055 * -- Monitor, if we are Non-secure
8056 * For the UNPREDICTABLE cases we choose to UNDEF.
8058 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
8059 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
8063 if (s
->current_el
== 0 || s
->current_el
== 2) {
8068 case ARM_CPU_MODE_USR
:
8069 case ARM_CPU_MODE_FIQ
:
8070 case ARM_CPU_MODE_IRQ
:
8071 case ARM_CPU_MODE_SVC
:
8072 case ARM_CPU_MODE_ABT
:
8073 case ARM_CPU_MODE_UND
:
8074 case ARM_CPU_MODE_SYS
:
8076 case ARM_CPU_MODE_HYP
:
8077 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
8081 case ARM_CPU_MODE_MON
:
8082 /* No need to check specifically for "are we non-secure" because
8083 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8084 * so if this isn't EL3 then we must be non-secure.
8086 if (s
->current_el
!= 3) {
8095 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8096 default_exception_el(s
));
8100 addr
= tcg_temp_new_i32();
8101 tmp
= tcg_const_i32(mode
);
8102 /* get_r13_banked() will raise an exception if called from System mode */
8103 gen_set_condexec(s
);
8104 gen_set_pc_im(s
, s
->pc
- 4);
8105 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8106 tcg_temp_free_i32(tmp
);
8123 tcg_gen_addi_i32(addr
, addr
, offset
);
8124 tmp
= load_reg(s
, 14);
8125 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8126 tcg_temp_free_i32(tmp
);
8127 tmp
= load_cpu_field(spsr
);
8128 tcg_gen_addi_i32(addr
, addr
, 4);
8129 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8130 tcg_temp_free_i32(tmp
);
8148 tcg_gen_addi_i32(addr
, addr
, offset
);
8149 tmp
= tcg_const_i32(mode
);
8150 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8151 tcg_temp_free_i32(tmp
);
8153 tcg_temp_free_i32(addr
);
8154 s
->base
.is_jmp
= DISAS_UPDATE
;
8157 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8159 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8166 /* M variants do not implement ARM mode; this must raise the INVSTATE
8167 * UsageFault exception.
8169 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8170 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8171 default_exception_el(s
));
8176 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8177 * choose to UNDEF. In ARMv5 and above the space is used
8178 * for miscellaneous unconditional instructions.
8182 /* Unconditional instructions. */
8183 if (((insn
>> 25) & 7) == 1) {
8184 /* NEON Data processing. */
8185 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8189 if (disas_neon_data_insn(s
, insn
)) {
8194 if ((insn
& 0x0f100000) == 0x04000000) {
8195 /* NEON load/store. */
8196 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8200 if (disas_neon_ls_insn(s
, insn
)) {
8205 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8207 if (disas_vfp_insn(s
, insn
)) {
8212 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8213 ((insn
& 0x0f30f010) == 0x0710f000)) {
8214 if ((insn
& (1 << 22)) == 0) {
8216 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8220 /* Otherwise PLD; v5TE+ */
8224 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8225 ((insn
& 0x0f70f010) == 0x0650f000)) {
8227 return; /* PLI; V7 */
8229 if (((insn
& 0x0f700000) == 0x04100000) ||
8230 ((insn
& 0x0f700010) == 0x06100000)) {
8231 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8234 return; /* v7MP: Unallocated memory hint: must NOP */
8237 if ((insn
& 0x0ffffdff) == 0x01010000) {
8240 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8241 gen_helper_setend(cpu_env
);
8242 s
->base
.is_jmp
= DISAS_UPDATE
;
8245 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8246 switch ((insn
>> 4) & 0xf) {
8254 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8257 /* We need to break the TB after this insn to execute
8258 * self-modifying code correctly and also to take
8259 * any pending interrupts immediately.
8261 gen_goto_tb(s
, 0, s
->pc
& ~1);
8266 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8269 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8271 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8277 rn
= (insn
>> 16) & 0xf;
8278 addr
= load_reg(s
, rn
);
8279 i
= (insn
>> 23) & 3;
8281 case 0: offset
= -4; break; /* DA */
8282 case 1: offset
= 0; break; /* IA */
8283 case 2: offset
= -8; break; /* DB */
8284 case 3: offset
= 4; break; /* IB */
8288 tcg_gen_addi_i32(addr
, addr
, offset
);
8289 /* Load PC into tmp and CPSR into tmp2. */
8290 tmp
= tcg_temp_new_i32();
8291 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8292 tcg_gen_addi_i32(addr
, addr
, 4);
8293 tmp2
= tcg_temp_new_i32();
8294 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8295 if (insn
& (1 << 21)) {
8296 /* Base writeback. */
8298 case 0: offset
= -8; break;
8299 case 1: offset
= 4; break;
8300 case 2: offset
= -4; break;
8301 case 3: offset
= 0; break;
8305 tcg_gen_addi_i32(addr
, addr
, offset
);
8306 store_reg(s
, rn
, addr
);
8308 tcg_temp_free_i32(addr
);
8310 gen_rfe(s
, tmp
, tmp2
);
8312 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8313 /* branch link and change to thumb (blx <offset>) */
8316 val
= (uint32_t)s
->pc
;
8317 tmp
= tcg_temp_new_i32();
8318 tcg_gen_movi_i32(tmp
, val
);
8319 store_reg(s
, 14, tmp
);
8320 /* Sign-extend the 24-bit offset */
8321 offset
= (((int32_t)insn
) << 8) >> 8;
8322 /* offset * 4 + bit24 * 2 + (thumb bit) */
8323 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8324 /* pipeline offset */
8326 /* protected by ARCH(5); above, near the start of uncond block */
8329 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8330 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8331 /* iWMMXt register transfer. */
8332 if (extract32(s
->c15_cpar
, 1, 1)) {
8333 if (!disas_iwmmxt_insn(s
, insn
)) {
8338 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8339 /* Coprocessor double register transfer. */
8341 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8342 /* Additional coprocessor register transfer. */
8343 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8346 /* cps (privileged) */
8350 if (insn
& (1 << 19)) {
8351 if (insn
& (1 << 8))
8353 if (insn
& (1 << 7))
8355 if (insn
& (1 << 6))
8357 if (insn
& (1 << 18))
8360 if (insn
& (1 << 17)) {
8362 val
|= (insn
& 0x1f);
8365 gen_set_psr_im(s
, mask
, 0, val
);
8372 /* if not always execute, we generate a conditional jump to
8374 s
->condlabel
= gen_new_label();
8375 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8378 if ((insn
& 0x0f900000) == 0x03000000) {
8379 if ((insn
& (1 << 21)) == 0) {
8381 rd
= (insn
>> 12) & 0xf;
8382 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8383 if ((insn
& (1 << 22)) == 0) {
8385 tmp
= tcg_temp_new_i32();
8386 tcg_gen_movi_i32(tmp
, val
);
8389 tmp
= load_reg(s
, rd
);
8390 tcg_gen_ext16u_i32(tmp
, tmp
);
8391 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8393 store_reg(s
, rd
, tmp
);
8395 if (((insn
>> 12) & 0xf) != 0xf)
8397 if (((insn
>> 16) & 0xf) == 0) {
8398 gen_nop_hint(s
, insn
& 0xff);
8400 /* CPSR = immediate */
8402 shift
= ((insn
>> 8) & 0xf) * 2;
8404 val
= (val
>> shift
) | (val
<< (32 - shift
));
8405 i
= ((insn
& (1 << 22)) != 0);
8406 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8412 } else if ((insn
& 0x0f900000) == 0x01000000
8413 && (insn
& 0x00000090) != 0x00000090) {
8414 /* miscellaneous instructions */
8415 op1
= (insn
>> 21) & 3;
8416 sh
= (insn
>> 4) & 0xf;
8419 case 0x0: /* MSR, MRS */
8420 if (insn
& (1 << 9)) {
8421 /* MSR (banked) and MRS (banked) */
8422 int sysm
= extract32(insn
, 16, 4) |
8423 (extract32(insn
, 8, 1) << 4);
8424 int r
= extract32(insn
, 22, 1);
8428 gen_msr_banked(s
, r
, sysm
, rm
);
8431 int rd
= extract32(insn
, 12, 4);
8433 gen_mrs_banked(s
, r
, sysm
, rd
);
8438 /* MSR, MRS (for PSRs) */
8441 tmp
= load_reg(s
, rm
);
8442 i
= ((op1
& 2) != 0);
8443 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8447 rd
= (insn
>> 12) & 0xf;
8451 tmp
= load_cpu_field(spsr
);
8453 tmp
= tcg_temp_new_i32();
8454 gen_helper_cpsr_read(tmp
, cpu_env
);
8456 store_reg(s
, rd
, tmp
);
8461 /* branch/exchange thumb (bx). */
8463 tmp
= load_reg(s
, rm
);
8465 } else if (op1
== 3) {
8468 rd
= (insn
>> 12) & 0xf;
8469 tmp
= load_reg(s
, rm
);
8470 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8471 store_reg(s
, rd
, tmp
);
8479 /* Trivial implementation equivalent to bx. */
8480 tmp
= load_reg(s
, rm
);
8491 /* branch link/exchange thumb (blx) */
8492 tmp
= load_reg(s
, rm
);
8493 tmp2
= tcg_temp_new_i32();
8494 tcg_gen_movi_i32(tmp2
, s
->pc
);
8495 store_reg(s
, 14, tmp2
);
8501 uint32_t c
= extract32(insn
, 8, 4);
8503 /* Check this CPU supports ARMv8 CRC instructions.
8504 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8505 * Bits 8, 10 and 11 should be zero.
8507 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8512 rn
= extract32(insn
, 16, 4);
8513 rd
= extract32(insn
, 12, 4);
8515 tmp
= load_reg(s
, rn
);
8516 tmp2
= load_reg(s
, rm
);
8518 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8519 } else if (op1
== 1) {
8520 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8522 tmp3
= tcg_const_i32(1 << op1
);
8524 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8526 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8528 tcg_temp_free_i32(tmp2
);
8529 tcg_temp_free_i32(tmp3
);
8530 store_reg(s
, rd
, tmp
);
8533 case 0x5: /* saturating add/subtract */
8535 rd
= (insn
>> 12) & 0xf;
8536 rn
= (insn
>> 16) & 0xf;
8537 tmp
= load_reg(s
, rm
);
8538 tmp2
= load_reg(s
, rn
);
8540 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8542 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8544 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8545 tcg_temp_free_i32(tmp2
);
8546 store_reg(s
, rd
, tmp
);
8550 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8559 gen_exception_insn(s
, 4, EXCP_BKPT
,
8560 syn_aa32_bkpt(imm16
, false),
8561 default_exception_el(s
));
8564 /* Hypervisor call (v7) */
8572 /* Secure monitor call (v6+) */
8580 g_assert_not_reached();
8584 case 0x8: /* signed multiply */
8589 rs
= (insn
>> 8) & 0xf;
8590 rn
= (insn
>> 12) & 0xf;
8591 rd
= (insn
>> 16) & 0xf;
8593 /* (32 * 16) >> 16 */
8594 tmp
= load_reg(s
, rm
);
8595 tmp2
= load_reg(s
, rs
);
8597 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8600 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8601 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8602 tmp
= tcg_temp_new_i32();
8603 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8604 tcg_temp_free_i64(tmp64
);
8605 if ((sh
& 2) == 0) {
8606 tmp2
= load_reg(s
, rn
);
8607 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8608 tcg_temp_free_i32(tmp2
);
8610 store_reg(s
, rd
, tmp
);
8613 tmp
= load_reg(s
, rm
);
8614 tmp2
= load_reg(s
, rs
);
8615 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8616 tcg_temp_free_i32(tmp2
);
8618 tmp64
= tcg_temp_new_i64();
8619 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8620 tcg_temp_free_i32(tmp
);
8621 gen_addq(s
, tmp64
, rn
, rd
);
8622 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8623 tcg_temp_free_i64(tmp64
);
8626 tmp2
= load_reg(s
, rn
);
8627 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8628 tcg_temp_free_i32(tmp2
);
8630 store_reg(s
, rd
, tmp
);
8637 } else if (((insn
& 0x0e000000) == 0 &&
8638 (insn
& 0x00000090) != 0x90) ||
8639 ((insn
& 0x0e000000) == (1 << 25))) {
8640 int set_cc
, logic_cc
, shiftop
;
8642 op1
= (insn
>> 21) & 0xf;
8643 set_cc
= (insn
>> 20) & 1;
8644 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8646 /* data processing instruction */
8647 if (insn
& (1 << 25)) {
8648 /* immediate operand */
8650 shift
= ((insn
>> 8) & 0xf) * 2;
8652 val
= (val
>> shift
) | (val
<< (32 - shift
));
8654 tmp2
= tcg_temp_new_i32();
8655 tcg_gen_movi_i32(tmp2
, val
);
8656 if (logic_cc
&& shift
) {
8657 gen_set_CF_bit31(tmp2
);
8662 tmp2
= load_reg(s
, rm
);
8663 shiftop
= (insn
>> 5) & 3;
8664 if (!(insn
& (1 << 4))) {
8665 shift
= (insn
>> 7) & 0x1f;
8666 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8668 rs
= (insn
>> 8) & 0xf;
8669 tmp
= load_reg(s
, rs
);
8670 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8673 if (op1
!= 0x0f && op1
!= 0x0d) {
8674 rn
= (insn
>> 16) & 0xf;
8675 tmp
= load_reg(s
, rn
);
8679 rd
= (insn
>> 12) & 0xf;
8682 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8686 store_reg_bx(s
, rd
, tmp
);
8689 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8693 store_reg_bx(s
, rd
, tmp
);
8696 if (set_cc
&& rd
== 15) {
8697 /* SUBS r15, ... is used for exception return. */
8701 gen_sub_CC(tmp
, tmp
, tmp2
);
8702 gen_exception_return(s
, tmp
);
8705 gen_sub_CC(tmp
, tmp
, tmp2
);
8707 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8709 store_reg_bx(s
, rd
, tmp
);
8714 gen_sub_CC(tmp
, tmp2
, tmp
);
8716 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8718 store_reg_bx(s
, rd
, tmp
);
8722 gen_add_CC(tmp
, tmp
, tmp2
);
8724 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8726 store_reg_bx(s
, rd
, tmp
);
8730 gen_adc_CC(tmp
, tmp
, tmp2
);
8732 gen_add_carry(tmp
, tmp
, tmp2
);
8734 store_reg_bx(s
, rd
, tmp
);
8738 gen_sbc_CC(tmp
, tmp
, tmp2
);
8740 gen_sub_carry(tmp
, tmp
, tmp2
);
8742 store_reg_bx(s
, rd
, tmp
);
8746 gen_sbc_CC(tmp
, tmp2
, tmp
);
8748 gen_sub_carry(tmp
, tmp2
, tmp
);
8750 store_reg_bx(s
, rd
, tmp
);
8754 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8757 tcg_temp_free_i32(tmp
);
8761 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8764 tcg_temp_free_i32(tmp
);
8768 gen_sub_CC(tmp
, tmp
, tmp2
);
8770 tcg_temp_free_i32(tmp
);
8774 gen_add_CC(tmp
, tmp
, tmp2
);
8776 tcg_temp_free_i32(tmp
);
8779 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8783 store_reg_bx(s
, rd
, tmp
);
8786 if (logic_cc
&& rd
== 15) {
8787 /* MOVS r15, ... is used for exception return. */
8791 gen_exception_return(s
, tmp2
);
8796 store_reg_bx(s
, rd
, tmp2
);
8800 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8804 store_reg_bx(s
, rd
, tmp
);
8808 tcg_gen_not_i32(tmp2
, tmp2
);
8812 store_reg_bx(s
, rd
, tmp2
);
8815 if (op1
!= 0x0f && op1
!= 0x0d) {
8816 tcg_temp_free_i32(tmp2
);
8819 /* other instructions */
8820 op1
= (insn
>> 24) & 0xf;
8824 /* multiplies, extra load/stores */
8825 sh
= (insn
>> 5) & 3;
8828 rd
= (insn
>> 16) & 0xf;
8829 rn
= (insn
>> 12) & 0xf;
8830 rs
= (insn
>> 8) & 0xf;
8832 op1
= (insn
>> 20) & 0xf;
8834 case 0: case 1: case 2: case 3: case 6:
8836 tmp
= load_reg(s
, rs
);
8837 tmp2
= load_reg(s
, rm
);
8838 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8839 tcg_temp_free_i32(tmp2
);
8840 if (insn
& (1 << 22)) {
8841 /* Subtract (mls) */
8843 tmp2
= load_reg(s
, rn
);
8844 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8845 tcg_temp_free_i32(tmp2
);
8846 } else if (insn
& (1 << 21)) {
8848 tmp2
= load_reg(s
, rn
);
8849 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8850 tcg_temp_free_i32(tmp2
);
8852 if (insn
& (1 << 20))
8854 store_reg(s
, rd
, tmp
);
8857 /* 64 bit mul double accumulate (UMAAL) */
8859 tmp
= load_reg(s
, rs
);
8860 tmp2
= load_reg(s
, rm
);
8861 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8862 gen_addq_lo(s
, tmp64
, rn
);
8863 gen_addq_lo(s
, tmp64
, rd
);
8864 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8865 tcg_temp_free_i64(tmp64
);
8867 case 8: case 9: case 10: case 11:
8868 case 12: case 13: case 14: case 15:
8869 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8870 tmp
= load_reg(s
, rs
);
8871 tmp2
= load_reg(s
, rm
);
8872 if (insn
& (1 << 22)) {
8873 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8875 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8877 if (insn
& (1 << 21)) { /* mult accumulate */
8878 TCGv_i32 al
= load_reg(s
, rn
);
8879 TCGv_i32 ah
= load_reg(s
, rd
);
8880 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8881 tcg_temp_free_i32(al
);
8882 tcg_temp_free_i32(ah
);
8884 if (insn
& (1 << 20)) {
8885 gen_logicq_cc(tmp
, tmp2
);
8887 store_reg(s
, rn
, tmp
);
8888 store_reg(s
, rd
, tmp2
);
8894 rn
= (insn
>> 16) & 0xf;
8895 rd
= (insn
>> 12) & 0xf;
8896 if (insn
& (1 << 23)) {
8897 /* load/store exclusive */
8898 int op2
= (insn
>> 8) & 3;
8899 op1
= (insn
>> 21) & 0x3;
8902 case 0: /* lda/stl */
8908 case 1: /* reserved */
8910 case 2: /* ldaex/stlex */
8913 case 3: /* ldrex/strex */
8922 addr
= tcg_temp_local_new_i32();
8923 load_reg_var(s
, addr
, rn
);
8925 /* Since the emulation does not have barriers,
8926 the acquire/release semantics need no special
8929 if (insn
& (1 << 20)) {
8930 tmp
= tcg_temp_new_i32();
8933 gen_aa32_ld32u_iss(s
, tmp
, addr
,
8938 gen_aa32_ld8u_iss(s
, tmp
, addr
,
8943 gen_aa32_ld16u_iss(s
, tmp
, addr
,
8950 store_reg(s
, rd
, tmp
);
8953 tmp
= load_reg(s
, rm
);
8956 gen_aa32_st32_iss(s
, tmp
, addr
,
8961 gen_aa32_st8_iss(s
, tmp
, addr
,
8966 gen_aa32_st16_iss(s
, tmp
, addr
,
8973 tcg_temp_free_i32(tmp
);
8975 } else if (insn
& (1 << 20)) {
8978 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8980 case 1: /* ldrexd */
8981 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8983 case 2: /* ldrexb */
8984 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8986 case 3: /* ldrexh */
8987 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8996 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8998 case 1: /* strexd */
8999 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
9001 case 2: /* strexb */
9002 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
9004 case 3: /* strexh */
9005 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
9011 tcg_temp_free_i32(addr
);
9014 TCGMemOp opc
= s
->be_data
;
9016 /* SWP instruction */
9019 if (insn
& (1 << 22)) {
9022 opc
|= MO_UL
| MO_ALIGN
;
9025 addr
= load_reg(s
, rn
);
9026 taddr
= gen_aa32_addr(s
, addr
, opc
);
9027 tcg_temp_free_i32(addr
);
9029 tmp
= load_reg(s
, rm
);
9030 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
9031 get_mem_index(s
), opc
);
9032 tcg_temp_free(taddr
);
9033 store_reg(s
, rd
, tmp
);
9038 bool load
= insn
& (1 << 20);
9039 bool wbit
= insn
& (1 << 21);
9040 bool pbit
= insn
& (1 << 24);
9041 bool doubleword
= false;
9044 /* Misc load/store */
9045 rn
= (insn
>> 16) & 0xf;
9046 rd
= (insn
>> 12) & 0xf;
9048 /* ISS not valid if writeback */
9049 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
9051 if (!load
&& (sh
& 2)) {
9055 /* UNPREDICTABLE; we choose to UNDEF */
9058 load
= (sh
& 1) == 0;
9062 addr
= load_reg(s
, rn
);
9064 gen_add_datah_offset(s
, insn
, 0, addr
);
9071 tmp
= load_reg(s
, rd
);
9072 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9073 tcg_temp_free_i32(tmp
);
9074 tcg_gen_addi_i32(addr
, addr
, 4);
9075 tmp
= load_reg(s
, rd
+ 1);
9076 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9077 tcg_temp_free_i32(tmp
);
9080 tmp
= tcg_temp_new_i32();
9081 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9082 store_reg(s
, rd
, tmp
);
9083 tcg_gen_addi_i32(addr
, addr
, 4);
9084 tmp
= tcg_temp_new_i32();
9085 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9088 address_offset
= -4;
9091 tmp
= tcg_temp_new_i32();
9094 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9098 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9103 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9109 tmp
= load_reg(s
, rd
);
9110 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9111 tcg_temp_free_i32(tmp
);
9113 /* Perform base writeback before the loaded value to
9114 ensure correct behavior with overlapping index registers.
9115 ldrd with base writeback is undefined if the
9116 destination and index registers overlap. */
9118 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9119 store_reg(s
, rn
, addr
);
9122 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9123 store_reg(s
, rn
, addr
);
9125 tcg_temp_free_i32(addr
);
9128 /* Complete the load. */
9129 store_reg(s
, rd
, tmp
);
9138 if (insn
& (1 << 4)) {
9140 /* Armv6 Media instructions. */
9142 rn
= (insn
>> 16) & 0xf;
9143 rd
= (insn
>> 12) & 0xf;
9144 rs
= (insn
>> 8) & 0xf;
9145 switch ((insn
>> 23) & 3) {
9146 case 0: /* Parallel add/subtract. */
9147 op1
= (insn
>> 20) & 7;
9148 tmp
= load_reg(s
, rn
);
9149 tmp2
= load_reg(s
, rm
);
9150 sh
= (insn
>> 5) & 7;
9151 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9153 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9154 tcg_temp_free_i32(tmp2
);
9155 store_reg(s
, rd
, tmp
);
9158 if ((insn
& 0x00700020) == 0) {
9159 /* Halfword pack. */
9160 tmp
= load_reg(s
, rn
);
9161 tmp2
= load_reg(s
, rm
);
9162 shift
= (insn
>> 7) & 0x1f;
9163 if (insn
& (1 << 6)) {
9167 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9168 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9169 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9173 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9174 tcg_gen_ext16u_i32(tmp
, tmp
);
9175 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9177 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9178 tcg_temp_free_i32(tmp2
);
9179 store_reg(s
, rd
, tmp
);
9180 } else if ((insn
& 0x00200020) == 0x00200000) {
9182 tmp
= load_reg(s
, rm
);
9183 shift
= (insn
>> 7) & 0x1f;
9184 if (insn
& (1 << 6)) {
9187 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9189 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9191 sh
= (insn
>> 16) & 0x1f;
9192 tmp2
= tcg_const_i32(sh
);
9193 if (insn
& (1 << 22))
9194 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9196 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9197 tcg_temp_free_i32(tmp2
);
9198 store_reg(s
, rd
, tmp
);
9199 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9201 tmp
= load_reg(s
, rm
);
9202 sh
= (insn
>> 16) & 0x1f;
9203 tmp2
= tcg_const_i32(sh
);
9204 if (insn
& (1 << 22))
9205 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9207 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9208 tcg_temp_free_i32(tmp2
);
9209 store_reg(s
, rd
, tmp
);
9210 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9212 tmp
= load_reg(s
, rn
);
9213 tmp2
= load_reg(s
, rm
);
9214 tmp3
= tcg_temp_new_i32();
9215 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9216 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9217 tcg_temp_free_i32(tmp3
);
9218 tcg_temp_free_i32(tmp2
);
9219 store_reg(s
, rd
, tmp
);
9220 } else if ((insn
& 0x000003e0) == 0x00000060) {
9221 tmp
= load_reg(s
, rm
);
9222 shift
= (insn
>> 10) & 3;
9223 /* ??? In many cases it's not necessary to do a
9224 rotate, a shift is sufficient. */
9226 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9227 op1
= (insn
>> 20) & 7;
9229 case 0: gen_sxtb16(tmp
); break;
9230 case 2: gen_sxtb(tmp
); break;
9231 case 3: gen_sxth(tmp
); break;
9232 case 4: gen_uxtb16(tmp
); break;
9233 case 6: gen_uxtb(tmp
); break;
9234 case 7: gen_uxth(tmp
); break;
9235 default: goto illegal_op
;
9238 tmp2
= load_reg(s
, rn
);
9239 if ((op1
& 3) == 0) {
9240 gen_add16(tmp
, tmp2
);
9242 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9243 tcg_temp_free_i32(tmp2
);
9246 store_reg(s
, rd
, tmp
);
9247 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9249 tmp
= load_reg(s
, rm
);
9250 if (insn
& (1 << 22)) {
9251 if (insn
& (1 << 7)) {
9255 gen_helper_rbit(tmp
, tmp
);
9258 if (insn
& (1 << 7))
9261 tcg_gen_bswap32_i32(tmp
, tmp
);
9263 store_reg(s
, rd
, tmp
);
9268 case 2: /* Multiplies (Type 3). */
9269 switch ((insn
>> 20) & 0x7) {
9271 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9272 /* op2 not 00x or 11x : UNDEF */
9275 /* Signed multiply most significant [accumulate].
9276 (SMMUL, SMMLA, SMMLS) */
9277 tmp
= load_reg(s
, rm
);
9278 tmp2
= load_reg(s
, rs
);
9279 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9282 tmp
= load_reg(s
, rd
);
9283 if (insn
& (1 << 6)) {
9284 tmp64
= gen_subq_msw(tmp64
, tmp
);
9286 tmp64
= gen_addq_msw(tmp64
, tmp
);
9289 if (insn
& (1 << 5)) {
9290 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9292 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9293 tmp
= tcg_temp_new_i32();
9294 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9295 tcg_temp_free_i64(tmp64
);
9296 store_reg(s
, rn
, tmp
);
9300 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9301 if (insn
& (1 << 7)) {
9304 tmp
= load_reg(s
, rm
);
9305 tmp2
= load_reg(s
, rs
);
9306 if (insn
& (1 << 5))
9307 gen_swap_half(tmp2
);
9308 gen_smul_dual(tmp
, tmp2
);
9309 if (insn
& (1 << 22)) {
9310 /* smlald, smlsld */
9313 tmp64
= tcg_temp_new_i64();
9314 tmp64_2
= tcg_temp_new_i64();
9315 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9316 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9317 tcg_temp_free_i32(tmp
);
9318 tcg_temp_free_i32(tmp2
);
9319 if (insn
& (1 << 6)) {
9320 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9322 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9324 tcg_temp_free_i64(tmp64_2
);
9325 gen_addq(s
, tmp64
, rd
, rn
);
9326 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9327 tcg_temp_free_i64(tmp64
);
9329 /* smuad, smusd, smlad, smlsd */
9330 if (insn
& (1 << 6)) {
9331 /* This subtraction cannot overflow. */
9332 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9334 /* This addition cannot overflow 32 bits;
9335 * however it may overflow considered as a
9336 * signed operation, in which case we must set
9339 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9341 tcg_temp_free_i32(tmp2
);
9344 tmp2
= load_reg(s
, rd
);
9345 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9346 tcg_temp_free_i32(tmp2
);
9348 store_reg(s
, rn
, tmp
);
9354 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9357 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9360 tmp
= load_reg(s
, rm
);
9361 tmp2
= load_reg(s
, rs
);
9362 if (insn
& (1 << 21)) {
9363 gen_helper_udiv(tmp
, tmp
, tmp2
);
9365 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9367 tcg_temp_free_i32(tmp2
);
9368 store_reg(s
, rn
, tmp
);
9375 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9377 case 0: /* Unsigned sum of absolute differences. */
9379 tmp
= load_reg(s
, rm
);
9380 tmp2
= load_reg(s
, rs
);
9381 gen_helper_usad8(tmp
, tmp
, tmp2
);
9382 tcg_temp_free_i32(tmp2
);
9384 tmp2
= load_reg(s
, rd
);
9385 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9386 tcg_temp_free_i32(tmp2
);
9388 store_reg(s
, rn
, tmp
);
9390 case 0x20: case 0x24: case 0x28: case 0x2c:
9391 /* Bitfield insert/clear. */
9393 shift
= (insn
>> 7) & 0x1f;
9394 i
= (insn
>> 16) & 0x1f;
9396 /* UNPREDICTABLE; we choose to UNDEF */
9401 tmp
= tcg_temp_new_i32();
9402 tcg_gen_movi_i32(tmp
, 0);
9404 tmp
= load_reg(s
, rm
);
9407 tmp2
= load_reg(s
, rd
);
9408 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9409 tcg_temp_free_i32(tmp2
);
9411 store_reg(s
, rd
, tmp
);
9413 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9414 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9416 tmp
= load_reg(s
, rm
);
9417 shift
= (insn
>> 7) & 0x1f;
9418 i
= ((insn
>> 16) & 0x1f) + 1;
9423 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9425 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9428 store_reg(s
, rd
, tmp
);
9438 /* Check for undefined extension instructions
9439 * per the ARM Bible IE:
9440 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9442 sh
= (0xf << 20) | (0xf << 4);
9443 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9447 /* load/store byte/word */
9448 rn
= (insn
>> 16) & 0xf;
9449 rd
= (insn
>> 12) & 0xf;
9450 tmp2
= load_reg(s
, rn
);
9451 if ((insn
& 0x01200000) == 0x00200000) {
9453 i
= get_a32_user_mem_index(s
);
9455 i
= get_mem_index(s
);
9457 if (insn
& (1 << 24))
9458 gen_add_data_offset(s
, insn
, tmp2
);
9459 if (insn
& (1 << 20)) {
9461 tmp
= tcg_temp_new_i32();
9462 if (insn
& (1 << 22)) {
9463 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9465 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9469 tmp
= load_reg(s
, rd
);
9470 if (insn
& (1 << 22)) {
9471 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9473 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9475 tcg_temp_free_i32(tmp
);
9477 if (!(insn
& (1 << 24))) {
9478 gen_add_data_offset(s
, insn
, tmp2
);
9479 store_reg(s
, rn
, tmp2
);
9480 } else if (insn
& (1 << 21)) {
9481 store_reg(s
, rn
, tmp2
);
9483 tcg_temp_free_i32(tmp2
);
9485 if (insn
& (1 << 20)) {
9486 /* Complete the load. */
9487 store_reg_from_load(s
, rd
, tmp
);
9493 int j
, n
, loaded_base
;
9494 bool exc_return
= false;
9495 bool is_load
= extract32(insn
, 20, 1);
9497 TCGv_i32 loaded_var
;
9498 /* load/store multiple words */
9499 /* XXX: store correct base if write back */
9500 if (insn
& (1 << 22)) {
9501 /* LDM (user), LDM (exception return) and STM (user) */
9503 goto illegal_op
; /* only usable in supervisor mode */
9505 if (is_load
&& extract32(insn
, 15, 1)) {
9511 rn
= (insn
>> 16) & 0xf;
9512 addr
= load_reg(s
, rn
);
9514 /* compute total size */
9519 if (insn
& (1 << i
))
9522 /* XXX: test invalid n == 0 case ? */
9523 if (insn
& (1 << 23)) {
9524 if (insn
& (1 << 24)) {
9526 tcg_gen_addi_i32(addr
, addr
, 4);
9528 /* post increment */
9531 if (insn
& (1 << 24)) {
9533 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9535 /* post decrement */
9537 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9542 if (insn
& (1 << i
)) {
9545 tmp
= tcg_temp_new_i32();
9546 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9548 tmp2
= tcg_const_i32(i
);
9549 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9550 tcg_temp_free_i32(tmp2
);
9551 tcg_temp_free_i32(tmp
);
9552 } else if (i
== rn
) {
9555 } else if (rn
== 15 && exc_return
) {
9556 store_pc_exc_ret(s
, tmp
);
9558 store_reg_from_load(s
, i
, tmp
);
9563 /* special case: r15 = PC + 8 */
9564 val
= (long)s
->pc
+ 4;
9565 tmp
= tcg_temp_new_i32();
9566 tcg_gen_movi_i32(tmp
, val
);
9568 tmp
= tcg_temp_new_i32();
9569 tmp2
= tcg_const_i32(i
);
9570 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9571 tcg_temp_free_i32(tmp2
);
9573 tmp
= load_reg(s
, i
);
9575 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9576 tcg_temp_free_i32(tmp
);
9579 /* no need to add after the last transfer */
9581 tcg_gen_addi_i32(addr
, addr
, 4);
9584 if (insn
& (1 << 21)) {
9586 if (insn
& (1 << 23)) {
9587 if (insn
& (1 << 24)) {
9590 /* post increment */
9591 tcg_gen_addi_i32(addr
, addr
, 4);
9594 if (insn
& (1 << 24)) {
9597 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9599 /* post decrement */
9600 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9603 store_reg(s
, rn
, addr
);
9605 tcg_temp_free_i32(addr
);
9608 store_reg(s
, rn
, loaded_var
);
9611 /* Restore CPSR from SPSR. */
9612 tmp
= load_cpu_field(spsr
);
9613 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9614 tcg_temp_free_i32(tmp
);
9615 /* Must exit loop to check un-masked IRQs */
9616 s
->base
.is_jmp
= DISAS_EXIT
;
9625 /* branch (and link) */
9626 val
= (int32_t)s
->pc
;
9627 if (insn
& (1 << 24)) {
9628 tmp
= tcg_temp_new_i32();
9629 tcg_gen_movi_i32(tmp
, val
);
9630 store_reg(s
, 14, tmp
);
9632 offset
= sextract32(insn
<< 2, 0, 26);
9640 if (((insn
>> 8) & 0xe) == 10) {
9642 if (disas_vfp_insn(s
, insn
)) {
9645 } else if (disas_coproc_insn(s
, insn
)) {
9652 gen_set_pc_im(s
, s
->pc
);
9653 s
->svc_imm
= extract32(insn
, 0, 24);
9654 s
->base
.is_jmp
= DISAS_SWI
;
9658 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9659 default_exception_el(s
));
9665 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t insn
)
9667 /* Return true if this is a 16 bit instruction. We must be precise
9668 * about this (matching the decode). We assume that s->pc still
9669 * points to the first 16 bits of the insn.
9671 if ((insn
>> 11) < 0x1d) {
9672 /* Definitely a 16-bit instruction */
9676 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9677 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9678 * end up actually treating this as two 16-bit insns, though,
9679 * if it's half of a bl/blx pair that might span a page boundary.
9681 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
9682 /* Thumb2 cores (including all M profile ones) always treat
9683 * 32-bit insns as 32-bit.
9688 if ((insn
>> 11) == 0x1e && (s
->pc
< s
->next_page_start
- 3)) {
9689 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9690 * is not on the next page; we merge this into a 32-bit
9695 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9696 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9697 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9698 * -- handle as single 16 bit insn
9703 /* Return true if this is a Thumb-2 logical op. */
9705 thumb2_logic_op(int op
)
9710 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9711 then set condition code flags based on the result of the operation.
9712 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9713 to the high bit of T1.
9714 Returns zero if the opcode is valid. */
9717 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9718 TCGv_i32 t0
, TCGv_i32 t1
)
9725 tcg_gen_and_i32(t0
, t0
, t1
);
9729 tcg_gen_andc_i32(t0
, t0
, t1
);
9733 tcg_gen_or_i32(t0
, t0
, t1
);
9737 tcg_gen_orc_i32(t0
, t0
, t1
);
9741 tcg_gen_xor_i32(t0
, t0
, t1
);
9746 gen_add_CC(t0
, t0
, t1
);
9748 tcg_gen_add_i32(t0
, t0
, t1
);
9752 gen_adc_CC(t0
, t0
, t1
);
9758 gen_sbc_CC(t0
, t0
, t1
);
9760 gen_sub_carry(t0
, t0
, t1
);
9765 gen_sub_CC(t0
, t0
, t1
);
9767 tcg_gen_sub_i32(t0
, t0
, t1
);
9771 gen_sub_CC(t0
, t1
, t0
);
9773 tcg_gen_sub_i32(t0
, t1
, t0
);
9775 default: /* 5, 6, 7, 9, 12, 15. */
9781 gen_set_CF_bit31(t1
);
9786 /* Translate a 32-bit thumb instruction. */
9787 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
9789 uint32_t imm
, shift
, offset
;
9790 uint32_t rd
, rn
, rm
, rs
;
9801 /* The only 32 bit insn that's allowed for Thumb1 is the combined
9802 * BL/BLX prefix and suffix.
9804 if ((insn
& 0xf800e800) != 0xf000e800) {
9808 rn
= (insn
>> 16) & 0xf;
9809 rs
= (insn
>> 12) & 0xf;
9810 rd
= (insn
>> 8) & 0xf;
9812 switch ((insn
>> 25) & 0xf) {
9813 case 0: case 1: case 2: case 3:
9814 /* 16-bit instructions. Should never happen. */
9817 if (insn
& (1 << 22)) {
9818 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9819 * - load/store doubleword, load/store exclusive, ldacq/strel,
9822 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_M
) &&
9823 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
9824 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9826 * The bulk of the behaviour for this instruction is implemented
9827 * in v7m_handle_execute_nsc(), which deals with the insn when
9828 * it is executed by a CPU in non-secure state from memory
9829 * which is Secure & NonSecure-Callable.
9830 * Here we only need to handle the remaining cases:
9831 * * in NS memory (including the "security extension not
9832 * implemented" case) : NOP
9833 * * in S memory but CPU already secure (clear IT bits)
9834 * We know that the attribute for the memory this insn is
9835 * in must match the current CPU state, because otherwise
9836 * get_phys_addr_pmsav8 would have generated an exception.
9838 if (s
->v8m_secure
) {
9839 /* Like the IT insn, we don't need to generate any code */
9840 s
->condexec_cond
= 0;
9841 s
->condexec_mask
= 0;
9843 } else if (insn
& 0x01200000) {
9844 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9845 * - load/store dual (post-indexed)
9846 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9847 * - load/store dual (literal and immediate)
9848 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9849 * - load/store dual (pre-indexed)
9852 if (insn
& (1 << 21)) {
9856 addr
= tcg_temp_new_i32();
9857 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9859 addr
= load_reg(s
, rn
);
9861 offset
= (insn
& 0xff) * 4;
9862 if ((insn
& (1 << 23)) == 0)
9864 if (insn
& (1 << 24)) {
9865 tcg_gen_addi_i32(addr
, addr
, offset
);
9868 if (insn
& (1 << 20)) {
9870 tmp
= tcg_temp_new_i32();
9871 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9872 store_reg(s
, rs
, tmp
);
9873 tcg_gen_addi_i32(addr
, addr
, 4);
9874 tmp
= tcg_temp_new_i32();
9875 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9876 store_reg(s
, rd
, tmp
);
9879 tmp
= load_reg(s
, rs
);
9880 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9881 tcg_temp_free_i32(tmp
);
9882 tcg_gen_addi_i32(addr
, addr
, 4);
9883 tmp
= load_reg(s
, rd
);
9884 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9885 tcg_temp_free_i32(tmp
);
9887 if (insn
& (1 << 21)) {
9888 /* Base writeback. */
9889 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9890 store_reg(s
, rn
, addr
);
9892 tcg_temp_free_i32(addr
);
9894 } else if ((insn
& (1 << 23)) == 0) {
9895 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9896 * - load/store exclusive word
9900 if (!(insn
& (1 << 20)) &&
9901 arm_dc_feature(s
, ARM_FEATURE_M
) &&
9902 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
9903 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
9906 bool alt
= insn
& (1 << 7);
9907 TCGv_i32 addr
, op
, ttresp
;
9909 if ((insn
& 0x3f) || rd
== 13 || rd
== 15 || rn
== 15) {
9910 /* we UNDEF for these UNPREDICTABLE cases */
9914 if (alt
&& !s
->v8m_secure
) {
9918 addr
= load_reg(s
, rn
);
9919 op
= tcg_const_i32(extract32(insn
, 6, 2));
9920 ttresp
= tcg_temp_new_i32();
9921 gen_helper_v7m_tt(ttresp
, cpu_env
, addr
, op
);
9922 tcg_temp_free_i32(addr
);
9923 tcg_temp_free_i32(op
);
9924 store_reg(s
, rd
, ttresp
);
9928 addr
= tcg_temp_local_new_i32();
9929 load_reg_var(s
, addr
, rn
);
9930 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9931 if (insn
& (1 << 20)) {
9932 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9934 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9936 tcg_temp_free_i32(addr
);
9937 } else if ((insn
& (7 << 5)) == 0) {
9940 addr
= tcg_temp_new_i32();
9941 tcg_gen_movi_i32(addr
, s
->pc
);
9943 addr
= load_reg(s
, rn
);
9945 tmp
= load_reg(s
, rm
);
9946 tcg_gen_add_i32(addr
, addr
, tmp
);
9947 if (insn
& (1 << 4)) {
9949 tcg_gen_add_i32(addr
, addr
, tmp
);
9950 tcg_temp_free_i32(tmp
);
9951 tmp
= tcg_temp_new_i32();
9952 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9954 tcg_temp_free_i32(tmp
);
9955 tmp
= tcg_temp_new_i32();
9956 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9958 tcg_temp_free_i32(addr
);
9959 tcg_gen_shli_i32(tmp
, tmp
, 1);
9960 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9961 store_reg(s
, 15, tmp
);
9963 int op2
= (insn
>> 6) & 0x3;
9964 op
= (insn
>> 4) & 0x3;
9969 /* Load/store exclusive byte/halfword/doubleword */
9976 /* Load-acquire/store-release */
9982 /* Load-acquire/store-release exclusive */
9986 addr
= tcg_temp_local_new_i32();
9987 load_reg_var(s
, addr
, rn
);
9989 if (insn
& (1 << 20)) {
9990 tmp
= tcg_temp_new_i32();
9993 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
9997 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
10001 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
10007 store_reg(s
, rs
, tmp
);
10009 tmp
= load_reg(s
, rs
);
10012 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
10016 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
10020 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
10026 tcg_temp_free_i32(tmp
);
10028 } else if (insn
& (1 << 20)) {
10029 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
10031 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
10033 tcg_temp_free_i32(addr
);
10036 /* Load/store multiple, RFE, SRS. */
10037 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
10038 /* RFE, SRS: not available in user mode or on M profile */
10039 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10042 if (insn
& (1 << 20)) {
10044 addr
= load_reg(s
, rn
);
10045 if ((insn
& (1 << 24)) == 0)
10046 tcg_gen_addi_i32(addr
, addr
, -8);
10047 /* Load PC into tmp and CPSR into tmp2. */
10048 tmp
= tcg_temp_new_i32();
10049 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10050 tcg_gen_addi_i32(addr
, addr
, 4);
10051 tmp2
= tcg_temp_new_i32();
10052 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
10053 if (insn
& (1 << 21)) {
10054 /* Base writeback. */
10055 if (insn
& (1 << 24)) {
10056 tcg_gen_addi_i32(addr
, addr
, 4);
10058 tcg_gen_addi_i32(addr
, addr
, -4);
10060 store_reg(s
, rn
, addr
);
10062 tcg_temp_free_i32(addr
);
10064 gen_rfe(s
, tmp
, tmp2
);
10067 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
10071 int i
, loaded_base
= 0;
10072 TCGv_i32 loaded_var
;
10073 /* Load/store multiple. */
10074 addr
= load_reg(s
, rn
);
10076 for (i
= 0; i
< 16; i
++) {
10077 if (insn
& (1 << i
))
10080 if (insn
& (1 << 24)) {
10081 tcg_gen_addi_i32(addr
, addr
, -offset
);
10085 for (i
= 0; i
< 16; i
++) {
10086 if ((insn
& (1 << i
)) == 0)
10088 if (insn
& (1 << 20)) {
10090 tmp
= tcg_temp_new_i32();
10091 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10093 gen_bx_excret(s
, tmp
);
10094 } else if (i
== rn
) {
10098 store_reg(s
, i
, tmp
);
10102 tmp
= load_reg(s
, i
);
10103 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10104 tcg_temp_free_i32(tmp
);
10106 tcg_gen_addi_i32(addr
, addr
, 4);
10109 store_reg(s
, rn
, loaded_var
);
10111 if (insn
& (1 << 21)) {
10112 /* Base register writeback. */
10113 if (insn
& (1 << 24)) {
10114 tcg_gen_addi_i32(addr
, addr
, -offset
);
10116 /* Fault if writeback register is in register list. */
10117 if (insn
& (1 << rn
))
10119 store_reg(s
, rn
, addr
);
10121 tcg_temp_free_i32(addr
);
10128 op
= (insn
>> 21) & 0xf;
10130 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10133 /* Halfword pack. */
10134 tmp
= load_reg(s
, rn
);
10135 tmp2
= load_reg(s
, rm
);
10136 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
10137 if (insn
& (1 << 5)) {
10141 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
10142 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
10143 tcg_gen_ext16u_i32(tmp2
, tmp2
);
10147 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10148 tcg_gen_ext16u_i32(tmp
, tmp
);
10149 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10151 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10152 tcg_temp_free_i32(tmp2
);
10153 store_reg(s
, rd
, tmp
);
10155 /* Data processing register constant shift. */
10157 tmp
= tcg_temp_new_i32();
10158 tcg_gen_movi_i32(tmp
, 0);
10160 tmp
= load_reg(s
, rn
);
10162 tmp2
= load_reg(s
, rm
);
10164 shiftop
= (insn
>> 4) & 3;
10165 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10166 conds
= (insn
& (1 << 20)) != 0;
10167 logic_cc
= (conds
&& thumb2_logic_op(op
));
10168 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10169 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10171 tcg_temp_free_i32(tmp2
);
10173 store_reg(s
, rd
, tmp
);
10175 tcg_temp_free_i32(tmp
);
10179 case 13: /* Misc data processing. */
10180 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10181 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10184 case 0: /* Register controlled shift. */
10185 tmp
= load_reg(s
, rn
);
10186 tmp2
= load_reg(s
, rm
);
10187 if ((insn
& 0x70) != 0)
10189 op
= (insn
>> 21) & 3;
10190 logic_cc
= (insn
& (1 << 20)) != 0;
10191 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10194 store_reg(s
, rd
, tmp
);
10196 case 1: /* Sign/zero extend. */
10197 op
= (insn
>> 20) & 7;
10199 case 0: /* SXTAH, SXTH */
10200 case 1: /* UXTAH, UXTH */
10201 case 4: /* SXTAB, SXTB */
10202 case 5: /* UXTAB, UXTB */
10204 case 2: /* SXTAB16, SXTB16 */
10205 case 3: /* UXTAB16, UXTB16 */
10206 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10214 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10218 tmp
= load_reg(s
, rm
);
10219 shift
= (insn
>> 4) & 3;
10220 /* ??? In many cases it's not necessary to do a
10221 rotate, a shift is sufficient. */
10223 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10224 op
= (insn
>> 20) & 7;
10226 case 0: gen_sxth(tmp
); break;
10227 case 1: gen_uxth(tmp
); break;
10228 case 2: gen_sxtb16(tmp
); break;
10229 case 3: gen_uxtb16(tmp
); break;
10230 case 4: gen_sxtb(tmp
); break;
10231 case 5: gen_uxtb(tmp
); break;
10233 g_assert_not_reached();
10236 tmp2
= load_reg(s
, rn
);
10237 if ((op
>> 1) == 1) {
10238 gen_add16(tmp
, tmp2
);
10240 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10241 tcg_temp_free_i32(tmp2
);
10244 store_reg(s
, rd
, tmp
);
10246 case 2: /* SIMD add/subtract. */
10247 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10250 op
= (insn
>> 20) & 7;
10251 shift
= (insn
>> 4) & 7;
10252 if ((op
& 3) == 3 || (shift
& 3) == 3)
10254 tmp
= load_reg(s
, rn
);
10255 tmp2
= load_reg(s
, rm
);
10256 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10257 tcg_temp_free_i32(tmp2
);
10258 store_reg(s
, rd
, tmp
);
10260 case 3: /* Other data processing. */
10261 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10263 /* Saturating add/subtract. */
10264 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10267 tmp
= load_reg(s
, rn
);
10268 tmp2
= load_reg(s
, rm
);
10270 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10272 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10274 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10275 tcg_temp_free_i32(tmp2
);
10278 case 0x0a: /* rbit */
10279 case 0x08: /* rev */
10280 case 0x09: /* rev16 */
10281 case 0x0b: /* revsh */
10282 case 0x18: /* clz */
10284 case 0x10: /* sel */
10285 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10289 case 0x20: /* crc32/crc32c */
10295 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10302 tmp
= load_reg(s
, rn
);
10304 case 0x0a: /* rbit */
10305 gen_helper_rbit(tmp
, tmp
);
10307 case 0x08: /* rev */
10308 tcg_gen_bswap32_i32(tmp
, tmp
);
10310 case 0x09: /* rev16 */
10313 case 0x0b: /* revsh */
10316 case 0x10: /* sel */
10317 tmp2
= load_reg(s
, rm
);
10318 tmp3
= tcg_temp_new_i32();
10319 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10320 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10321 tcg_temp_free_i32(tmp3
);
10322 tcg_temp_free_i32(tmp2
);
10324 case 0x18: /* clz */
10325 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10335 uint32_t sz
= op
& 0x3;
10336 uint32_t c
= op
& 0x8;
10338 tmp2
= load_reg(s
, rm
);
10340 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10341 } else if (sz
== 1) {
10342 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10344 tmp3
= tcg_const_i32(1 << sz
);
10346 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10348 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10350 tcg_temp_free_i32(tmp2
);
10351 tcg_temp_free_i32(tmp3
);
10355 g_assert_not_reached();
10358 store_reg(s
, rd
, tmp
);
10360 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10361 switch ((insn
>> 20) & 7) {
10362 case 0: /* 32 x 32 -> 32 */
10363 case 7: /* Unsigned sum of absolute differences. */
10365 case 1: /* 16 x 16 -> 32 */
10366 case 2: /* Dual multiply add. */
10367 case 3: /* 32 * 16 -> 32msb */
10368 case 4: /* Dual multiply subtract. */
10369 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10370 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10375 op
= (insn
>> 4) & 0xf;
10376 tmp
= load_reg(s
, rn
);
10377 tmp2
= load_reg(s
, rm
);
10378 switch ((insn
>> 20) & 7) {
10379 case 0: /* 32 x 32 -> 32 */
10380 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10381 tcg_temp_free_i32(tmp2
);
10383 tmp2
= load_reg(s
, rs
);
10385 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10387 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10388 tcg_temp_free_i32(tmp2
);
10391 case 1: /* 16 x 16 -> 32 */
10392 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10393 tcg_temp_free_i32(tmp2
);
10395 tmp2
= load_reg(s
, rs
);
10396 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10397 tcg_temp_free_i32(tmp2
);
10400 case 2: /* Dual multiply add. */
10401 case 4: /* Dual multiply subtract. */
10403 gen_swap_half(tmp2
);
10404 gen_smul_dual(tmp
, tmp2
);
10405 if (insn
& (1 << 22)) {
10406 /* This subtraction cannot overflow. */
10407 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10409 /* This addition cannot overflow 32 bits;
10410 * however it may overflow considered as a signed
10411 * operation, in which case we must set the Q flag.
10413 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10415 tcg_temp_free_i32(tmp2
);
10418 tmp2
= load_reg(s
, rs
);
10419 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10420 tcg_temp_free_i32(tmp2
);
10423 case 3: /* 32 * 16 -> 32msb */
10425 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10428 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10429 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10430 tmp
= tcg_temp_new_i32();
10431 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10432 tcg_temp_free_i64(tmp64
);
10435 tmp2
= load_reg(s
, rs
);
10436 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10437 tcg_temp_free_i32(tmp2
);
10440 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10441 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10443 tmp
= load_reg(s
, rs
);
10444 if (insn
& (1 << 20)) {
10445 tmp64
= gen_addq_msw(tmp64
, tmp
);
10447 tmp64
= gen_subq_msw(tmp64
, tmp
);
10450 if (insn
& (1 << 4)) {
10451 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10453 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10454 tmp
= tcg_temp_new_i32();
10455 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10456 tcg_temp_free_i64(tmp64
);
10458 case 7: /* Unsigned sum of absolute differences. */
10459 gen_helper_usad8(tmp
, tmp
, tmp2
);
10460 tcg_temp_free_i32(tmp2
);
10462 tmp2
= load_reg(s
, rs
);
10463 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10464 tcg_temp_free_i32(tmp2
);
10468 store_reg(s
, rd
, tmp
);
10470 case 6: case 7: /* 64-bit multiply, Divide. */
10471 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10472 tmp
= load_reg(s
, rn
);
10473 tmp2
= load_reg(s
, rm
);
10474 if ((op
& 0x50) == 0x10) {
10476 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10480 gen_helper_udiv(tmp
, tmp
, tmp2
);
10482 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10483 tcg_temp_free_i32(tmp2
);
10484 store_reg(s
, rd
, tmp
);
10485 } else if ((op
& 0xe) == 0xc) {
10486 /* Dual multiply accumulate long. */
10487 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10488 tcg_temp_free_i32(tmp
);
10489 tcg_temp_free_i32(tmp2
);
10493 gen_swap_half(tmp2
);
10494 gen_smul_dual(tmp
, tmp2
);
10496 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10498 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10500 tcg_temp_free_i32(tmp2
);
10502 tmp64
= tcg_temp_new_i64();
10503 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10504 tcg_temp_free_i32(tmp
);
10505 gen_addq(s
, tmp64
, rs
, rd
);
10506 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10507 tcg_temp_free_i64(tmp64
);
10510 /* Unsigned 64-bit multiply */
10511 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10515 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10516 tcg_temp_free_i32(tmp2
);
10517 tcg_temp_free_i32(tmp
);
10520 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10521 tcg_temp_free_i32(tmp2
);
10522 tmp64
= tcg_temp_new_i64();
10523 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10524 tcg_temp_free_i32(tmp
);
10526 /* Signed 64-bit multiply */
10527 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10532 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10533 tcg_temp_free_i64(tmp64
);
10536 gen_addq_lo(s
, tmp64
, rs
);
10537 gen_addq_lo(s
, tmp64
, rd
);
10538 } else if (op
& 0x40) {
10539 /* 64-bit accumulate. */
10540 gen_addq(s
, tmp64
, rs
, rd
);
10542 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10543 tcg_temp_free_i64(tmp64
);
10548 case 6: case 7: case 14: case 15:
10550 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10551 /* We don't currently implement M profile FP support,
10552 * so this entire space should give a NOCP fault.
10554 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10555 default_exception_el(s
));
10558 if (((insn
>> 24) & 3) == 3) {
10559 /* Translate into the equivalent ARM encoding. */
10560 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10561 if (disas_neon_data_insn(s
, insn
)) {
10564 } else if (((insn
>> 8) & 0xe) == 10) {
10565 if (disas_vfp_insn(s
, insn
)) {
10569 if (insn
& (1 << 28))
10571 if (disas_coproc_insn(s
, insn
)) {
10576 case 8: case 9: case 10: case 11:
10577 if (insn
& (1 << 15)) {
10578 /* Branches, misc control. */
10579 if (insn
& 0x5000) {
10580 /* Unconditional branch. */
10581 /* signextend(hw1[10:0]) -> offset[:12]. */
10582 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10583 /* hw1[10:0] -> offset[11:1]. */
10584 offset
|= (insn
& 0x7ff) << 1;
10585 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10586 offset[24:22] already have the same value because of the
10587 sign extension above. */
10588 offset
^= ((~insn
) & (1 << 13)) << 10;
10589 offset
^= ((~insn
) & (1 << 11)) << 11;
10591 if (insn
& (1 << 14)) {
10592 /* Branch and link. */
10593 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10597 if (insn
& (1 << 12)) {
10599 gen_jmp(s
, offset
);
10602 offset
&= ~(uint32_t)2;
10603 /* thumb2 bx, no need to check */
10604 gen_bx_im(s
, offset
);
10606 } else if (((insn
>> 23) & 7) == 7) {
10608 if (insn
& (1 << 13))
10611 if (insn
& (1 << 26)) {
10612 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10615 if (!(insn
& (1 << 20))) {
10616 /* Hypervisor call (v7) */
10617 int imm16
= extract32(insn
, 16, 4) << 12
10618 | extract32(insn
, 0, 12);
10625 /* Secure monitor call (v6+) */
10633 op
= (insn
>> 20) & 7;
10635 case 0: /* msr cpsr. */
10636 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10637 tmp
= load_reg(s
, rn
);
10638 /* the constant is the mask and SYSm fields */
10639 addr
= tcg_const_i32(insn
& 0xfff);
10640 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10641 tcg_temp_free_i32(addr
);
10642 tcg_temp_free_i32(tmp
);
10647 case 1: /* msr spsr. */
10648 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10652 if (extract32(insn
, 5, 1)) {
10654 int sysm
= extract32(insn
, 8, 4) |
10655 (extract32(insn
, 4, 1) << 4);
10658 gen_msr_banked(s
, r
, sysm
, rm
);
10662 /* MSR (for PSRs) */
10663 tmp
= load_reg(s
, rn
);
10665 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10669 case 2: /* cps, nop-hint. */
10670 if (((insn
>> 8) & 7) == 0) {
10671 gen_nop_hint(s
, insn
& 0xff);
10673 /* Implemented as NOP in user mode. */
10678 if (insn
& (1 << 10)) {
10679 if (insn
& (1 << 7))
10681 if (insn
& (1 << 6))
10683 if (insn
& (1 << 5))
10685 if (insn
& (1 << 9))
10686 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10688 if (insn
& (1 << 8)) {
10690 imm
|= (insn
& 0x1f);
10693 gen_set_psr_im(s
, offset
, 0, imm
);
10696 case 3: /* Special control operations. */
10698 op
= (insn
>> 4) & 0xf;
10700 case 2: /* clrex */
10705 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10708 /* We need to break the TB after this insn
10709 * to execute self-modifying code correctly
10710 * and also to take any pending interrupts
10713 gen_goto_tb(s
, 0, s
->pc
& ~1);
10720 /* Trivial implementation equivalent to bx.
10721 * This instruction doesn't exist at all for M-profile.
10723 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10726 tmp
= load_reg(s
, rn
);
10729 case 5: /* Exception return. */
10733 if (rn
!= 14 || rd
!= 15) {
10736 tmp
= load_reg(s
, rn
);
10737 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10738 gen_exception_return(s
, tmp
);
10741 if (extract32(insn
, 5, 1) &&
10742 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10744 int sysm
= extract32(insn
, 16, 4) |
10745 (extract32(insn
, 4, 1) << 4);
10747 gen_mrs_banked(s
, 0, sysm
, rd
);
10751 if (extract32(insn
, 16, 4) != 0xf) {
10754 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10755 extract32(insn
, 0, 8) != 0) {
10760 tmp
= tcg_temp_new_i32();
10761 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10762 addr
= tcg_const_i32(insn
& 0xff);
10763 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10764 tcg_temp_free_i32(addr
);
10766 gen_helper_cpsr_read(tmp
, cpu_env
);
10768 store_reg(s
, rd
, tmp
);
10771 if (extract32(insn
, 5, 1) &&
10772 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10774 int sysm
= extract32(insn
, 16, 4) |
10775 (extract32(insn
, 4, 1) << 4);
10777 gen_mrs_banked(s
, 1, sysm
, rd
);
10782 /* Not accessible in user mode. */
10783 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10787 if (extract32(insn
, 16, 4) != 0xf ||
10788 extract32(insn
, 0, 8) != 0) {
10792 tmp
= load_cpu_field(spsr
);
10793 store_reg(s
, rd
, tmp
);
10798 /* Conditional branch. */
10799 op
= (insn
>> 22) & 0xf;
10800 /* Generate a conditional jump to next instruction. */
10801 s
->condlabel
= gen_new_label();
10802 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10805 /* offset[11:1] = insn[10:0] */
10806 offset
= (insn
& 0x7ff) << 1;
10807 /* offset[17:12] = insn[21:16]. */
10808 offset
|= (insn
& 0x003f0000) >> 4;
10809 /* offset[31:20] = insn[26]. */
10810 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10811 /* offset[18] = insn[13]. */
10812 offset
|= (insn
& (1 << 13)) << 5;
10813 /* offset[19] = insn[11]. */
10814 offset
|= (insn
& (1 << 11)) << 8;
10816 /* jump to the offset */
10817 gen_jmp(s
, s
->pc
+ offset
);
10820 /* Data processing immediate. */
10821 if (insn
& (1 << 25)) {
10822 if (insn
& (1 << 24)) {
10823 if (insn
& (1 << 20))
10825 /* Bitfield/Saturate. */
10826 op
= (insn
>> 21) & 7;
10828 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10830 tmp
= tcg_temp_new_i32();
10831 tcg_gen_movi_i32(tmp
, 0);
10833 tmp
= load_reg(s
, rn
);
10836 case 2: /* Signed bitfield extract. */
10838 if (shift
+ imm
> 32)
10841 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
10844 case 6: /* Unsigned bitfield extract. */
10846 if (shift
+ imm
> 32)
10849 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
10852 case 3: /* Bitfield insert/clear. */
10855 imm
= imm
+ 1 - shift
;
10857 tmp2
= load_reg(s
, rd
);
10858 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10859 tcg_temp_free_i32(tmp2
);
10864 default: /* Saturate. */
10867 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10869 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10871 tmp2
= tcg_const_i32(imm
);
10874 if ((op
& 1) && shift
== 0) {
10875 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10876 tcg_temp_free_i32(tmp
);
10877 tcg_temp_free_i32(tmp2
);
10880 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10882 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10886 if ((op
& 1) && shift
== 0) {
10887 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10888 tcg_temp_free_i32(tmp
);
10889 tcg_temp_free_i32(tmp2
);
10892 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10894 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10897 tcg_temp_free_i32(tmp2
);
10900 store_reg(s
, rd
, tmp
);
10902 imm
= ((insn
& 0x04000000) >> 15)
10903 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10904 if (insn
& (1 << 22)) {
10905 /* 16-bit immediate. */
10906 imm
|= (insn
>> 4) & 0xf000;
10907 if (insn
& (1 << 23)) {
10909 tmp
= load_reg(s
, rd
);
10910 tcg_gen_ext16u_i32(tmp
, tmp
);
10911 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10914 tmp
= tcg_temp_new_i32();
10915 tcg_gen_movi_i32(tmp
, imm
);
10918 /* Add/sub 12-bit immediate. */
10920 offset
= s
->pc
& ~(uint32_t)3;
10921 if (insn
& (1 << 23))
10925 tmp
= tcg_temp_new_i32();
10926 tcg_gen_movi_i32(tmp
, offset
);
10928 tmp
= load_reg(s
, rn
);
10929 if (insn
& (1 << 23))
10930 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10932 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10935 store_reg(s
, rd
, tmp
);
10938 int shifter_out
= 0;
10939 /* modified 12-bit immediate. */
10940 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10941 imm
= (insn
& 0xff);
10944 /* Nothing to do. */
10946 case 1: /* 00XY00XY */
10949 case 2: /* XY00XY00 */
10953 case 3: /* XYXYXYXY */
10957 default: /* Rotated constant. */
10958 shift
= (shift
<< 1) | (imm
>> 7);
10960 imm
= imm
<< (32 - shift
);
10964 tmp2
= tcg_temp_new_i32();
10965 tcg_gen_movi_i32(tmp2
, imm
);
10966 rn
= (insn
>> 16) & 0xf;
10968 tmp
= tcg_temp_new_i32();
10969 tcg_gen_movi_i32(tmp
, 0);
10971 tmp
= load_reg(s
, rn
);
10973 op
= (insn
>> 21) & 0xf;
10974 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10975 shifter_out
, tmp
, tmp2
))
10977 tcg_temp_free_i32(tmp2
);
10978 rd
= (insn
>> 8) & 0xf;
10980 store_reg(s
, rd
, tmp
);
10982 tcg_temp_free_i32(tmp
);
10987 case 12: /* Load/store single data item. */
10994 if ((insn
& 0x01100000) == 0x01000000) {
10995 if (disas_neon_ls_insn(s
, insn
)) {
11000 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
11002 if (!(insn
& (1 << 20))) {
11006 /* Byte or halfword load space with dest == r15 : memory hints.
11007 * Catch them early so we don't emit pointless addressing code.
11008 * This space is a mix of:
11009 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11010 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11012 * unallocated hints, which must be treated as NOPs
11013 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11014 * which is easiest for the decoding logic
11015 * Some space which must UNDEF
11017 int op1
= (insn
>> 23) & 3;
11018 int op2
= (insn
>> 6) & 0x3f;
11023 /* UNPREDICTABLE, unallocated hint or
11024 * PLD/PLDW/PLI (literal)
11029 return; /* PLD/PLDW/PLI or unallocated hint */
11031 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
11032 return; /* PLD/PLDW/PLI or unallocated hint */
11034 /* UNDEF space, or an UNPREDICTABLE */
11038 memidx
= get_mem_index(s
);
11040 addr
= tcg_temp_new_i32();
11042 /* s->pc has already been incremented by 4. */
11043 imm
= s
->pc
& 0xfffffffc;
11044 if (insn
& (1 << 23))
11045 imm
+= insn
& 0xfff;
11047 imm
-= insn
& 0xfff;
11048 tcg_gen_movi_i32(addr
, imm
);
11050 addr
= load_reg(s
, rn
);
11051 if (insn
& (1 << 23)) {
11052 /* Positive offset. */
11053 imm
= insn
& 0xfff;
11054 tcg_gen_addi_i32(addr
, addr
, imm
);
11057 switch ((insn
>> 8) & 0xf) {
11058 case 0x0: /* Shifted Register. */
11059 shift
= (insn
>> 4) & 0xf;
11061 tcg_temp_free_i32(addr
);
11064 tmp
= load_reg(s
, rm
);
11066 tcg_gen_shli_i32(tmp
, tmp
, shift
);
11067 tcg_gen_add_i32(addr
, addr
, tmp
);
11068 tcg_temp_free_i32(tmp
);
11070 case 0xc: /* Negative offset. */
11071 tcg_gen_addi_i32(addr
, addr
, -imm
);
11073 case 0xe: /* User privilege. */
11074 tcg_gen_addi_i32(addr
, addr
, imm
);
11075 memidx
= get_a32_user_mem_index(s
);
11077 case 0x9: /* Post-decrement. */
11079 /* Fall through. */
11080 case 0xb: /* Post-increment. */
11084 case 0xd: /* Pre-decrement. */
11086 /* Fall through. */
11087 case 0xf: /* Pre-increment. */
11088 tcg_gen_addi_i32(addr
, addr
, imm
);
11092 tcg_temp_free_i32(addr
);
11098 issinfo
= writeback
? ISSInvalid
: rs
;
11100 if (insn
& (1 << 20)) {
11102 tmp
= tcg_temp_new_i32();
11105 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11108 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11111 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11114 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
11117 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
11120 tcg_temp_free_i32(tmp
);
11121 tcg_temp_free_i32(addr
);
11125 gen_bx_excret(s
, tmp
);
11127 store_reg(s
, rs
, tmp
);
11131 tmp
= load_reg(s
, rs
);
11134 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
11137 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
11140 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
11143 tcg_temp_free_i32(tmp
);
11144 tcg_temp_free_i32(addr
);
11147 tcg_temp_free_i32(tmp
);
11150 tcg_gen_addi_i32(addr
, addr
, imm
);
11152 store_reg(s
, rn
, addr
);
11154 tcg_temp_free_i32(addr
);
11163 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11164 default_exception_el(s
));
11167 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
11169 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
11176 switch (insn
>> 12) {
11180 op
= (insn
>> 11) & 3;
11183 rn
= (insn
>> 3) & 7;
11184 tmp
= load_reg(s
, rn
);
11185 if (insn
& (1 << 10)) {
11187 tmp2
= tcg_temp_new_i32();
11188 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11191 rm
= (insn
>> 6) & 7;
11192 tmp2
= load_reg(s
, rm
);
11194 if (insn
& (1 << 9)) {
11195 if (s
->condexec_mask
)
11196 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11198 gen_sub_CC(tmp
, tmp
, tmp2
);
11200 if (s
->condexec_mask
)
11201 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11203 gen_add_CC(tmp
, tmp
, tmp2
);
11205 tcg_temp_free_i32(tmp2
);
11206 store_reg(s
, rd
, tmp
);
11208 /* shift immediate */
11209 rm
= (insn
>> 3) & 7;
11210 shift
= (insn
>> 6) & 0x1f;
11211 tmp
= load_reg(s
, rm
);
11212 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11213 if (!s
->condexec_mask
)
11215 store_reg(s
, rd
, tmp
);
11219 /* arithmetic large immediate */
11220 op
= (insn
>> 11) & 3;
11221 rd
= (insn
>> 8) & 0x7;
11222 if (op
== 0) { /* mov */
11223 tmp
= tcg_temp_new_i32();
11224 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11225 if (!s
->condexec_mask
)
11227 store_reg(s
, rd
, tmp
);
11229 tmp
= load_reg(s
, rd
);
11230 tmp2
= tcg_temp_new_i32();
11231 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11234 gen_sub_CC(tmp
, tmp
, tmp2
);
11235 tcg_temp_free_i32(tmp
);
11236 tcg_temp_free_i32(tmp2
);
11239 if (s
->condexec_mask
)
11240 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11242 gen_add_CC(tmp
, tmp
, tmp2
);
11243 tcg_temp_free_i32(tmp2
);
11244 store_reg(s
, rd
, tmp
);
11247 if (s
->condexec_mask
)
11248 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11250 gen_sub_CC(tmp
, tmp
, tmp2
);
11251 tcg_temp_free_i32(tmp2
);
11252 store_reg(s
, rd
, tmp
);
11258 if (insn
& (1 << 11)) {
11259 rd
= (insn
>> 8) & 7;
11260 /* load pc-relative. Bit 1 of PC is ignored. */
11261 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11262 val
&= ~(uint32_t)2;
11263 addr
= tcg_temp_new_i32();
11264 tcg_gen_movi_i32(addr
, val
);
11265 tmp
= tcg_temp_new_i32();
11266 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11268 tcg_temp_free_i32(addr
);
11269 store_reg(s
, rd
, tmp
);
11272 if (insn
& (1 << 10)) {
11273 /* 0b0100_01xx_xxxx_xxxx
11274 * - data processing extended, branch and exchange
11276 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11277 rm
= (insn
>> 3) & 0xf;
11278 op
= (insn
>> 8) & 3;
11281 tmp
= load_reg(s
, rd
);
11282 tmp2
= load_reg(s
, rm
);
11283 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11284 tcg_temp_free_i32(tmp2
);
11285 store_reg(s
, rd
, tmp
);
11288 tmp
= load_reg(s
, rd
);
11289 tmp2
= load_reg(s
, rm
);
11290 gen_sub_CC(tmp
, tmp
, tmp2
);
11291 tcg_temp_free_i32(tmp2
);
11292 tcg_temp_free_i32(tmp
);
11294 case 2: /* mov/cpy */
11295 tmp
= load_reg(s
, rm
);
11296 store_reg(s
, rd
, tmp
);
11300 /* 0b0100_0111_xxxx_xxxx
11301 * - branch [and link] exchange thumb register
11303 bool link
= insn
& (1 << 7);
11312 /* BXNS/BLXNS: only exists for v8M with the
11313 * security extensions, and always UNDEF if NonSecure.
11314 * We don't implement these in the user-only mode
11315 * either (in theory you can use them from Secure User
11316 * mode but they are too tied in to system emulation.)
11318 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
11329 tmp
= load_reg(s
, rm
);
11331 val
= (uint32_t)s
->pc
| 1;
11332 tmp2
= tcg_temp_new_i32();
11333 tcg_gen_movi_i32(tmp2
, val
);
11334 store_reg(s
, 14, tmp2
);
11337 /* Only BX works as exception-return, not BLX */
11338 gen_bx_excret(s
, tmp
);
11346 /* data processing register */
11348 rm
= (insn
>> 3) & 7;
11349 op
= (insn
>> 6) & 0xf;
11350 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11351 /* the shift/rotate ops want the operands backwards */
11360 if (op
== 9) { /* neg */
11361 tmp
= tcg_temp_new_i32();
11362 tcg_gen_movi_i32(tmp
, 0);
11363 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11364 tmp
= load_reg(s
, rd
);
11369 tmp2
= load_reg(s
, rm
);
11371 case 0x0: /* and */
11372 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11373 if (!s
->condexec_mask
)
11376 case 0x1: /* eor */
11377 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11378 if (!s
->condexec_mask
)
11381 case 0x2: /* lsl */
11382 if (s
->condexec_mask
) {
11383 gen_shl(tmp2
, tmp2
, tmp
);
11385 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11386 gen_logic_CC(tmp2
);
11389 case 0x3: /* lsr */
11390 if (s
->condexec_mask
) {
11391 gen_shr(tmp2
, tmp2
, tmp
);
11393 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11394 gen_logic_CC(tmp2
);
11397 case 0x4: /* asr */
11398 if (s
->condexec_mask
) {
11399 gen_sar(tmp2
, tmp2
, tmp
);
11401 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11402 gen_logic_CC(tmp2
);
11405 case 0x5: /* adc */
11406 if (s
->condexec_mask
) {
11407 gen_adc(tmp
, tmp2
);
11409 gen_adc_CC(tmp
, tmp
, tmp2
);
11412 case 0x6: /* sbc */
11413 if (s
->condexec_mask
) {
11414 gen_sub_carry(tmp
, tmp
, tmp2
);
11416 gen_sbc_CC(tmp
, tmp
, tmp2
);
11419 case 0x7: /* ror */
11420 if (s
->condexec_mask
) {
11421 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11422 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11424 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11425 gen_logic_CC(tmp2
);
11428 case 0x8: /* tst */
11429 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11433 case 0x9: /* neg */
11434 if (s
->condexec_mask
)
11435 tcg_gen_neg_i32(tmp
, tmp2
);
11437 gen_sub_CC(tmp
, tmp
, tmp2
);
11439 case 0xa: /* cmp */
11440 gen_sub_CC(tmp
, tmp
, tmp2
);
11443 case 0xb: /* cmn */
11444 gen_add_CC(tmp
, tmp
, tmp2
);
11447 case 0xc: /* orr */
11448 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11449 if (!s
->condexec_mask
)
11452 case 0xd: /* mul */
11453 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11454 if (!s
->condexec_mask
)
11457 case 0xe: /* bic */
11458 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11459 if (!s
->condexec_mask
)
11462 case 0xf: /* mvn */
11463 tcg_gen_not_i32(tmp2
, tmp2
);
11464 if (!s
->condexec_mask
)
11465 gen_logic_CC(tmp2
);
11472 store_reg(s
, rm
, tmp2
);
11474 tcg_temp_free_i32(tmp
);
11476 store_reg(s
, rd
, tmp
);
11477 tcg_temp_free_i32(tmp2
);
11480 tcg_temp_free_i32(tmp
);
11481 tcg_temp_free_i32(tmp2
);
11486 /* load/store register offset. */
11488 rn
= (insn
>> 3) & 7;
11489 rm
= (insn
>> 6) & 7;
11490 op
= (insn
>> 9) & 7;
11491 addr
= load_reg(s
, rn
);
11492 tmp
= load_reg(s
, rm
);
11493 tcg_gen_add_i32(addr
, addr
, tmp
);
11494 tcg_temp_free_i32(tmp
);
11496 if (op
< 3) { /* store */
11497 tmp
= load_reg(s
, rd
);
11499 tmp
= tcg_temp_new_i32();
11504 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11507 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11510 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11512 case 3: /* ldrsb */
11513 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11516 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11519 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11522 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11524 case 7: /* ldrsh */
11525 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11528 if (op
>= 3) { /* load */
11529 store_reg(s
, rd
, tmp
);
11531 tcg_temp_free_i32(tmp
);
11533 tcg_temp_free_i32(addr
);
11537 /* load/store word immediate offset */
11539 rn
= (insn
>> 3) & 7;
11540 addr
= load_reg(s
, rn
);
11541 val
= (insn
>> 4) & 0x7c;
11542 tcg_gen_addi_i32(addr
, addr
, val
);
11544 if (insn
& (1 << 11)) {
11546 tmp
= tcg_temp_new_i32();
11547 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11548 store_reg(s
, rd
, tmp
);
11551 tmp
= load_reg(s
, rd
);
11552 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11553 tcg_temp_free_i32(tmp
);
11555 tcg_temp_free_i32(addr
);
11559 /* load/store byte immediate offset */
11561 rn
= (insn
>> 3) & 7;
11562 addr
= load_reg(s
, rn
);
11563 val
= (insn
>> 6) & 0x1f;
11564 tcg_gen_addi_i32(addr
, addr
, val
);
11566 if (insn
& (1 << 11)) {
11568 tmp
= tcg_temp_new_i32();
11569 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11570 store_reg(s
, rd
, tmp
);
11573 tmp
= load_reg(s
, rd
);
11574 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11575 tcg_temp_free_i32(tmp
);
11577 tcg_temp_free_i32(addr
);
11581 /* load/store halfword immediate offset */
11583 rn
= (insn
>> 3) & 7;
11584 addr
= load_reg(s
, rn
);
11585 val
= (insn
>> 5) & 0x3e;
11586 tcg_gen_addi_i32(addr
, addr
, val
);
11588 if (insn
& (1 << 11)) {
11590 tmp
= tcg_temp_new_i32();
11591 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11592 store_reg(s
, rd
, tmp
);
11595 tmp
= load_reg(s
, rd
);
11596 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11597 tcg_temp_free_i32(tmp
);
11599 tcg_temp_free_i32(addr
);
11603 /* load/store from stack */
11604 rd
= (insn
>> 8) & 7;
11605 addr
= load_reg(s
, 13);
11606 val
= (insn
& 0xff) * 4;
11607 tcg_gen_addi_i32(addr
, addr
, val
);
11609 if (insn
& (1 << 11)) {
11611 tmp
= tcg_temp_new_i32();
11612 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11613 store_reg(s
, rd
, tmp
);
11616 tmp
= load_reg(s
, rd
);
11617 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11618 tcg_temp_free_i32(tmp
);
11620 tcg_temp_free_i32(addr
);
11624 /* add to high reg */
11625 rd
= (insn
>> 8) & 7;
11626 if (insn
& (1 << 11)) {
11628 tmp
= load_reg(s
, 13);
11630 /* PC. bit 1 is ignored. */
11631 tmp
= tcg_temp_new_i32();
11632 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11634 val
= (insn
& 0xff) * 4;
11635 tcg_gen_addi_i32(tmp
, tmp
, val
);
11636 store_reg(s
, rd
, tmp
);
11641 op
= (insn
>> 8) & 0xf;
11644 /* adjust stack pointer */
11645 tmp
= load_reg(s
, 13);
11646 val
= (insn
& 0x7f) * 4;
11647 if (insn
& (1 << 7))
11648 val
= -(int32_t)val
;
11649 tcg_gen_addi_i32(tmp
, tmp
, val
);
11650 store_reg(s
, 13, tmp
);
11653 case 2: /* sign/zero extend. */
11656 rm
= (insn
>> 3) & 7;
11657 tmp
= load_reg(s
, rm
);
11658 switch ((insn
>> 6) & 3) {
11659 case 0: gen_sxth(tmp
); break;
11660 case 1: gen_sxtb(tmp
); break;
11661 case 2: gen_uxth(tmp
); break;
11662 case 3: gen_uxtb(tmp
); break;
11664 store_reg(s
, rd
, tmp
);
11666 case 4: case 5: case 0xc: case 0xd:
11668 addr
= load_reg(s
, 13);
11669 if (insn
& (1 << 8))
11673 for (i
= 0; i
< 8; i
++) {
11674 if (insn
& (1 << i
))
11677 if ((insn
& (1 << 11)) == 0) {
11678 tcg_gen_addi_i32(addr
, addr
, -offset
);
11680 for (i
= 0; i
< 8; i
++) {
11681 if (insn
& (1 << i
)) {
11682 if (insn
& (1 << 11)) {
11684 tmp
= tcg_temp_new_i32();
11685 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11686 store_reg(s
, i
, tmp
);
11689 tmp
= load_reg(s
, i
);
11690 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11691 tcg_temp_free_i32(tmp
);
11693 /* advance to the next address. */
11694 tcg_gen_addi_i32(addr
, addr
, 4);
11698 if (insn
& (1 << 8)) {
11699 if (insn
& (1 << 11)) {
11701 tmp
= tcg_temp_new_i32();
11702 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11703 /* don't set the pc until the rest of the instruction
11707 tmp
= load_reg(s
, 14);
11708 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11709 tcg_temp_free_i32(tmp
);
11711 tcg_gen_addi_i32(addr
, addr
, 4);
11713 if ((insn
& (1 << 11)) == 0) {
11714 tcg_gen_addi_i32(addr
, addr
, -offset
);
11716 /* write back the new stack pointer */
11717 store_reg(s
, 13, addr
);
11718 /* set the new PC value */
11719 if ((insn
& 0x0900) == 0x0900) {
11720 store_reg_from_load(s
, 15, tmp
);
11724 case 1: case 3: case 9: case 11: /* czb */
11726 tmp
= load_reg(s
, rm
);
11727 s
->condlabel
= gen_new_label();
11729 if (insn
& (1 << 11))
11730 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11732 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11733 tcg_temp_free_i32(tmp
);
11734 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11735 val
= (uint32_t)s
->pc
+ 2;
11740 case 15: /* IT, nop-hint. */
11741 if ((insn
& 0xf) == 0) {
11742 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11746 s
->condexec_cond
= (insn
>> 4) & 0xe;
11747 s
->condexec_mask
= insn
& 0x1f;
11748 /* No actual code generated for this insn, just setup state. */
11751 case 0xe: /* bkpt */
11753 int imm8
= extract32(insn
, 0, 8);
11755 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11756 default_exception_el(s
));
11760 case 0xa: /* rev, and hlt */
11762 int op1
= extract32(insn
, 6, 2);
11766 int imm6
= extract32(insn
, 0, 6);
11772 /* Otherwise this is rev */
11774 rn
= (insn
>> 3) & 0x7;
11776 tmp
= load_reg(s
, rn
);
11778 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11779 case 1: gen_rev16(tmp
); break;
11780 case 3: gen_revsh(tmp
); break;
11782 g_assert_not_reached();
11784 store_reg(s
, rd
, tmp
);
11789 switch ((insn
>> 5) & 7) {
11793 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11794 gen_helper_setend(cpu_env
);
11795 s
->base
.is_jmp
= DISAS_UPDATE
;
11804 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11805 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11808 addr
= tcg_const_i32(19);
11809 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11810 tcg_temp_free_i32(addr
);
11814 addr
= tcg_const_i32(16);
11815 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11816 tcg_temp_free_i32(addr
);
11818 tcg_temp_free_i32(tmp
);
11821 if (insn
& (1 << 4)) {
11822 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11826 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11841 /* load/store multiple */
11842 TCGv_i32 loaded_var
= NULL
;
11843 rn
= (insn
>> 8) & 0x7;
11844 addr
= load_reg(s
, rn
);
11845 for (i
= 0; i
< 8; i
++) {
11846 if (insn
& (1 << i
)) {
11847 if (insn
& (1 << 11)) {
11849 tmp
= tcg_temp_new_i32();
11850 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11854 store_reg(s
, i
, tmp
);
11858 tmp
= load_reg(s
, i
);
11859 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11860 tcg_temp_free_i32(tmp
);
11862 /* advance to the next address */
11863 tcg_gen_addi_i32(addr
, addr
, 4);
11866 if ((insn
& (1 << rn
)) == 0) {
11867 /* base reg not in list: base register writeback */
11868 store_reg(s
, rn
, addr
);
11870 /* base reg in list: if load, complete it now */
11871 if (insn
& (1 << 11)) {
11872 store_reg(s
, rn
, loaded_var
);
11874 tcg_temp_free_i32(addr
);
11879 /* conditional branch or swi */
11880 cond
= (insn
>> 8) & 0xf;
11886 gen_set_pc_im(s
, s
->pc
);
11887 s
->svc_imm
= extract32(insn
, 0, 8);
11888 s
->base
.is_jmp
= DISAS_SWI
;
11891 /* generate a conditional jump to next instruction */
11892 s
->condlabel
= gen_new_label();
11893 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11896 /* jump to the offset */
11897 val
= (uint32_t)s
->pc
+ 2;
11898 offset
= ((int32_t)insn
<< 24) >> 24;
11899 val
+= offset
<< 1;
11904 if (insn
& (1 << 11)) {
11905 /* thumb_insn_is_16bit() ensures we can't get here for
11906 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11907 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11909 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11911 offset
= ((insn
& 0x7ff) << 1);
11912 tmp
= load_reg(s
, 14);
11913 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11914 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
11916 tmp2
= tcg_temp_new_i32();
11917 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
11918 store_reg(s
, 14, tmp2
);
11922 /* unconditional branch */
11923 val
= (uint32_t)s
->pc
;
11924 offset
= ((int32_t)insn
<< 21) >> 21;
11925 val
+= (offset
<< 1) + 2;
11930 /* thumb_insn_is_16bit() ensures we can't get here for
11931 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11933 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11935 if (insn
& (1 << 11)) {
11936 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11937 offset
= ((insn
& 0x7ff) << 1) | 1;
11938 tmp
= load_reg(s
, 14);
11939 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11941 tmp2
= tcg_temp_new_i32();
11942 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
11943 store_reg(s
, 14, tmp2
);
11946 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11947 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
11949 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
11956 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11957 default_exception_el(s
));
11960 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11962 /* Return true if the insn at dc->pc might cross a page boundary.
11963 * (False positives are OK, false negatives are not.)
11964 * We know this is a Thumb insn, and our caller ensures we are
11965 * only called if dc->pc is less than 4 bytes from the page
11966 * boundary, so we cross the page if the first 16 bits indicate
11967 * that this is a 32 bit insn.
11969 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11971 return !thumb_insn_is_16bit(s
, insn
);
11974 static int arm_tr_init_disas_context(DisasContextBase
*dcbase
,
11975 CPUState
*cs
, int max_insns
)
11977 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11978 CPUARMState
*env
= cs
->env_ptr
;
11979 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11981 dc
->pc
= dc
->base
.pc_first
;
11985 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11986 * there is no secure EL1, so we route exceptions to EL3.
11988 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11989 !arm_el_is_aa64(env
, 3);
11990 dc
->thumb
= ARM_TBFLAG_THUMB(dc
->base
.tb
->flags
);
11991 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(dc
->base
.tb
->flags
);
11992 dc
->be_data
= ARM_TBFLAG_BE_DATA(dc
->base
.tb
->flags
) ? MO_BE
: MO_LE
;
11993 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) & 0xf) << 1;
11994 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) >> 4;
11995 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, ARM_TBFLAG_MMUIDX(dc
->base
.tb
->flags
));
11996 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11997 #if !defined(CONFIG_USER_ONLY)
11998 dc
->user
= (dc
->current_el
== 0);
12000 dc
->ns
= ARM_TBFLAG_NS(dc
->base
.tb
->flags
);
12001 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(dc
->base
.tb
->flags
);
12002 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(dc
->base
.tb
->flags
);
12003 dc
->vec_len
= ARM_TBFLAG_VECLEN(dc
->base
.tb
->flags
);
12004 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(dc
->base
.tb
->flags
);
12005 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(dc
->base
.tb
->flags
);
12006 dc
->v7m_handler_mode
= ARM_TBFLAG_HANDLER(dc
->base
.tb
->flags
);
12007 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
12008 regime_is_secure(env
, dc
->mmu_idx
);
12009 dc
->cp_regs
= cpu
->cp_regs
;
12010 dc
->features
= env
->features
;
12012 /* Single step state. The code-generation logic here is:
12014 * generate code with no special handling for single-stepping (except
12015 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12016 * this happens anyway because those changes are all system register or
12018 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12019 * emit code for one insn
12020 * emit code to clear PSTATE.SS
12021 * emit code to generate software step exception for completed step
12022 * end TB (as usual for having generated an exception)
12023 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12024 * emit code to generate a software step exception
12027 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(dc
->base
.tb
->flags
);
12028 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(dc
->base
.tb
->flags
);
12029 dc
->is_ldex
= false;
12030 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
12032 dc
->next_page_start
=
12033 (dc
->base
.pc_first
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
12035 /* If architectural single step active, limit to 1. */
12036 if (is_singlestepping(dc
)) {
12040 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12041 to those left on the page. */
12043 int bound
= (dc
->next_page_start
- dc
->base
.pc_first
) / 4;
12044 max_insns
= MIN(max_insns
, bound
);
12047 cpu_F0s
= tcg_temp_new_i32();
12048 cpu_F1s
= tcg_temp_new_i32();
12049 cpu_F0d
= tcg_temp_new_i64();
12050 cpu_F1d
= tcg_temp_new_i64();
12053 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12054 cpu_M0
= tcg_temp_new_i64();
12059 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12061 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12063 /* A note on handling of the condexec (IT) bits:
12065 * We want to avoid the overhead of having to write the updated condexec
12066 * bits back to the CPUARMState for every instruction in an IT block. So:
12067 * (1) if the condexec bits are not already zero then we write
12068 * zero back into the CPUARMState now. This avoids complications trying
12069 * to do it at the end of the block. (For example if we don't do this
12070 * it's hard to identify whether we can safely skip writing condexec
12071 * at the end of the TB, which we definitely want to do for the case
12072 * where a TB doesn't do anything with the IT state at all.)
12073 * (2) if we are going to leave the TB then we call gen_set_condexec()
12074 * which will write the correct value into CPUARMState if zero is wrong.
12075 * This is done both for leaving the TB at the end, and for leaving
12076 * it because of an exception we know will happen, which is done in
12077 * gen_exception_insn(). The latter is necessary because we need to
12078 * leave the TB with the PC/IT state just prior to execution of the
12079 * instruction which caused the exception.
12080 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12081 * then the CPUARMState will be wrong and we need to reset it.
12082 * This is handled in the same way as restoration of the
12083 * PC in these situations; we save the value of the condexec bits
12084 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12085 * then uses this to restore them after an exception.
12087 * Note that there are no instructions which can read the condexec
12088 * bits, and none which can write non-static values to them, so
12089 * we don't need to care about whether CPUARMState is correct in the
12093 /* Reset the conditional execution bits immediately. This avoids
12094 complications trying to do it at the end of the block. */
12095 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
12096 TCGv_i32 tmp
= tcg_temp_new_i32();
12097 tcg_gen_movi_i32(tmp
, 0);
12098 store_cpu_field(tmp
, condexec_bits
);
12100 tcg_clear_temp_count();
12103 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
12105 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12107 tcg_gen_insn_start(dc
->pc
,
12108 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
12110 dc
->insn_start
= tcg_last_op();
12113 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
12114 const CPUBreakpoint
*bp
)
12116 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12118 if (bp
->flags
& BP_CPU
) {
12119 gen_set_condexec(dc
);
12120 gen_set_pc_im(dc
, dc
->pc
);
12121 gen_helper_check_breakpoints(cpu_env
);
12122 /* End the TB early; it's likely not going to be executed */
12123 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12125 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
12126 /* The address covered by the breakpoint must be
12127 included in [tb->pc, tb->pc + tb->size) in order
12128 to for it to be properly cleared -- thus we
12129 increment the PC here so that the logic setting
12130 tb->size below does the right thing. */
12131 /* TODO: Advance PC by correct instruction length to
12132 * avoid disassembler error messages */
12134 dc
->base
.is_jmp
= DISAS_NORETURN
;
12140 static bool arm_pre_translate_insn(DisasContext
*dc
)
12142 #ifdef CONFIG_USER_ONLY
12143 /* Intercept jump to the magic kernel page. */
12144 if (dc
->pc
>= 0xffff0000) {
12145 /* We always get here via a jump, so know we are not in a
12146 conditional execution block. */
12147 gen_exception_internal(EXCP_KERNEL_TRAP
);
12148 dc
->base
.is_jmp
= DISAS_NORETURN
;
12153 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12154 /* Singlestep state is Active-pending.
12155 * If we're in this state at the start of a TB then either
12156 * a) we just took an exception to an EL which is being debugged
12157 * and this is the first insn in the exception handler
12158 * b) debug exceptions were masked and we just unmasked them
12159 * without changing EL (eg by clearing PSTATE.D)
12160 * In either case we're going to take a swstep exception in the
12161 * "did not step an insn" case, and so the syndrome ISV and EX
12162 * bits should be zero.
12164 assert(dc
->base
.num_insns
== 1);
12165 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
12166 default_exception_el(dc
));
12167 dc
->base
.is_jmp
= DISAS_NORETURN
;
12174 static void arm_post_translate_insn(DisasContext
*dc
)
12176 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12177 gen_set_label(dc
->condlabel
);
12180 dc
->base
.pc_next
= dc
->pc
;
12181 translator_loop_temp_check(&dc
->base
);
12184 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12186 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12187 CPUARMState
*env
= cpu
->env_ptr
;
12190 if (arm_pre_translate_insn(dc
)) {
12194 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12197 disas_arm_insn(dc
, insn
);
12199 arm_post_translate_insn(dc
);
12201 /* ARM is a fixed-length ISA. We performed the cross-page check
12202 in init_disas_context by adjusting max_insns. */
12205 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
12207 /* Return true if this Thumb insn is always unconditional,
12208 * even inside an IT block. This is true of only a very few
12209 * instructions: BKPT, HLT, and SG.
12211 * A larger class of instructions are UNPREDICTABLE if used
12212 * inside an IT block; we do not need to detect those here, because
12213 * what we do by default (perform the cc check and update the IT
12214 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12215 * choice for those situations.
12217 * insn is either a 16-bit or a 32-bit instruction; the two are
12218 * distinguishable because for the 16-bit case the top 16 bits
12219 * are zeroes, and that isn't a valid 32-bit encoding.
12221 if ((insn
& 0xffffff00) == 0xbe00) {
12226 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12227 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
12228 /* HLT: v8A only. This is unconditional even when it is going to
12229 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12230 * For v7 cores this was a plain old undefined encoding and so
12231 * honours its cc check. (We might be using the encoding as
12232 * a semihosting trap, but we don't change the cc check behaviour
12233 * on that account, because a debugger connected to a real v7A
12234 * core and emulating semihosting traps by catching the UNDEF
12235 * exception would also only see cases where the cc check passed.
12236 * No guest code should be trying to do a HLT semihosting trap
12237 * in an IT block anyway.
12242 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12243 arm_dc_feature(s
, ARM_FEATURE_M
)) {
12251 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12253 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12254 CPUARMState
*env
= cpu
->env_ptr
;
12258 if (arm_pre_translate_insn(dc
)) {
12262 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12263 is_16bit
= thumb_insn_is_16bit(dc
, insn
);
12266 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12268 insn
= insn
<< 16 | insn2
;
12273 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
12274 uint32_t cond
= dc
->condexec_cond
;
12276 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
12277 dc
->condlabel
= gen_new_label();
12278 arm_gen_test_cc(cond
^ 1, dc
->condlabel
);
12284 disas_thumb_insn(dc
, insn
);
12286 disas_thumb2_insn(dc
, insn
);
12289 /* Advance the Thumb condexec condition. */
12290 if (dc
->condexec_mask
) {
12291 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
12292 ((dc
->condexec_mask
>> 4) & 1));
12293 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12294 if (dc
->condexec_mask
== 0) {
12295 dc
->condexec_cond
= 0;
12299 arm_post_translate_insn(dc
);
12301 /* Thumb is a variable-length ISA. Stop translation when the next insn
12302 * will touch a new page. This ensures that prefetch aborts occur at
12305 * We want to stop the TB if the next insn starts in a new page,
12306 * or if it spans between this page and the next. This means that
12307 * if we're looking at the last halfword in the page we need to
12308 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12309 * or a 32-bit Thumb insn (which won't).
12310 * This is to avoid generating a silly TB with a single 16-bit insn
12311 * in it at the end of this page (which would execute correctly
12312 * but isn't very efficient).
12314 if (dc
->base
.is_jmp
== DISAS_NEXT
12315 && (dc
->pc
>= dc
->next_page_start
12316 || (dc
->pc
>= dc
->next_page_start
- 3
12317 && insn_crosses_page(env
, dc
)))) {
12318 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12322 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
12324 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12326 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
12327 /* FIXME: This can theoretically happen with self-modifying code. */
12328 cpu_abort(cpu
, "IO on conditional branch instruction");
12331 /* At this stage dc->condjmp will only be set when the skipped
12332 instruction was a conditional branch or trap, and the PC has
12333 already been written. */
12334 gen_set_condexec(dc
);
12335 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12336 /* Exception return branches need some special case code at the
12337 * end of the TB, which is complex enough that it has to
12338 * handle the single-step vs not and the condition-failed
12339 * insn codepath itself.
12341 gen_bx_excret_final_code(dc
);
12342 } else if (unlikely(is_singlestepping(dc
))) {
12343 /* Unconditional and "condition passed" instruction codepath. */
12344 switch (dc
->base
.is_jmp
) {
12346 gen_ss_advance(dc
);
12347 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12348 default_exception_el(dc
));
12351 gen_ss_advance(dc
);
12352 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12355 gen_ss_advance(dc
);
12356 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12359 case DISAS_TOO_MANY
:
12361 gen_set_pc_im(dc
, dc
->pc
);
12364 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12365 gen_singlestep_exception(dc
);
12367 case DISAS_NORETURN
:
12371 /* While branches must always occur at the end of an IT block,
12372 there are a few other things that can cause us to terminate
12373 the TB in the middle of an IT block:
12374 - Exception generating instructions (bkpt, swi, undefined).
12376 - Hardware watchpoints.
12377 Hardware breakpoints have already been handled and skip this code.
12379 switch(dc
->base
.is_jmp
) {
12381 case DISAS_TOO_MANY
:
12382 gen_goto_tb(dc
, 1, dc
->pc
);
12388 gen_set_pc_im(dc
, dc
->pc
);
12391 /* indicate that the hash table must be used to find the next TB */
12392 tcg_gen_exit_tb(0);
12394 case DISAS_NORETURN
:
12395 /* nothing more to generate */
12399 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
12400 !(dc
->insn
& (1U << 31))) ? 2 : 4);
12402 gen_helper_wfi(cpu_env
, tmp
);
12403 tcg_temp_free_i32(tmp
);
12404 /* The helper doesn't necessarily throw an exception, but we
12405 * must go back to the main loop to check for interrupts anyway.
12407 tcg_gen_exit_tb(0);
12411 gen_helper_wfe(cpu_env
);
12414 gen_helper_yield(cpu_env
);
12417 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12418 default_exception_el(dc
));
12421 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12424 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12430 /* "Condition failed" instruction codepath for the branch/trap insn */
12431 gen_set_label(dc
->condlabel
);
12432 gen_set_condexec(dc
);
12433 if (unlikely(is_singlestepping(dc
))) {
12434 gen_set_pc_im(dc
, dc
->pc
);
12435 gen_singlestep_exception(dc
);
12437 gen_goto_tb(dc
, 1, dc
->pc
);
12441 /* Functions above can change dc->pc, so re-align db->pc_next */
12442 dc
->base
.pc_next
= dc
->pc
;
12445 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
12447 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12449 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
12450 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
12453 static const TranslatorOps arm_translator_ops
= {
12454 .init_disas_context
= arm_tr_init_disas_context
,
12455 .tb_start
= arm_tr_tb_start
,
12456 .insn_start
= arm_tr_insn_start
,
12457 .breakpoint_check
= arm_tr_breakpoint_check
,
12458 .translate_insn
= arm_tr_translate_insn
,
12459 .tb_stop
= arm_tr_tb_stop
,
12460 .disas_log
= arm_tr_disas_log
,
12463 static const TranslatorOps thumb_translator_ops
= {
12464 .init_disas_context
= arm_tr_init_disas_context
,
12465 .tb_start
= arm_tr_tb_start
,
12466 .insn_start
= arm_tr_insn_start
,
12467 .breakpoint_check
= arm_tr_breakpoint_check
,
12468 .translate_insn
= thumb_tr_translate_insn
,
12469 .tb_stop
= arm_tr_tb_stop
,
12470 .disas_log
= arm_tr_disas_log
,
12473 /* generate intermediate code for basic block 'tb'. */
12474 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
)
12477 const TranslatorOps
*ops
= &arm_translator_ops
;
12479 if (ARM_TBFLAG_THUMB(tb
->flags
)) {
12480 ops
= &thumb_translator_ops
;
12482 #ifdef TARGET_AARCH64
12483 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
12484 ops
= &aarch64_translator_ops
;
12488 translator_loop(ops
, &dc
.base
, cpu
, tb
);
12491 static const char *cpu_mode_names
[16] = {
12492 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12493 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12496 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12499 ARMCPU
*cpu
= ARM_CPU(cs
);
12500 CPUARMState
*env
= &cpu
->env
;
12504 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12508 for(i
=0;i
<16;i
++) {
12509 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12511 cpu_fprintf(f
, "\n");
12513 cpu_fprintf(f
, " ");
12516 if (arm_feature(env
, ARM_FEATURE_M
)) {
12517 uint32_t xpsr
= xpsr_read(env
);
12519 const char *ns_status
= "";
12521 if (arm_feature(env
, ARM_FEATURE_M_SECURITY
)) {
12522 ns_status
= env
->v7m
.secure
? "S " : "NS ";
12525 if (xpsr
& XPSR_EXCP
) {
12528 if (env
->v7m
.control
[env
->v7m
.secure
] & R_V7M_CONTROL_NPRIV_MASK
) {
12529 mode
= "unpriv-thread";
12531 mode
= "priv-thread";
12535 cpu_fprintf(f
, "XPSR=%08x %c%c%c%c %c %s%s\n",
12537 xpsr
& XPSR_N
? 'N' : '-',
12538 xpsr
& XPSR_Z
? 'Z' : '-',
12539 xpsr
& XPSR_C
? 'C' : '-',
12540 xpsr
& XPSR_V
? 'V' : '-',
12541 xpsr
& XPSR_T
? 'T' : 'A',
12545 uint32_t psr
= cpsr_read(env
);
12546 const char *ns_status
= "";
12548 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12549 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12550 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12553 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12555 psr
& CPSR_N
? 'N' : '-',
12556 psr
& CPSR_Z
? 'Z' : '-',
12557 psr
& CPSR_C
? 'C' : '-',
12558 psr
& CPSR_V
? 'V' : '-',
12559 psr
& CPSR_T
? 'T' : 'A',
12561 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12564 if (flags
& CPU_DUMP_FPU
) {
12565 int numvfpregs
= 0;
12566 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12569 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12572 for (i
= 0; i
< numvfpregs
; i
++) {
12573 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12574 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12575 i
* 2, (uint32_t)v
,
12576 i
* 2 + 1, (uint32_t)(v
>> 32),
12579 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12583 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12584 target_ulong
*data
)
12588 env
->condexec_bits
= 0;
12589 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12591 env
->regs
[15] = data
[0];
12592 env
->condexec_bits
= data
[1];
12593 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;