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 0
45 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
46 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
47 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
48 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
49 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
51 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
53 #include "translate.h"
55 #if defined(CONFIG_USER_ONLY)
58 #define IS_USER(s) (s->user)
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
64 static TCGv_i32 cpu_R
[16];
65 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
66 TCGv_i64 cpu_exclusive_addr
;
67 TCGv_i64 cpu_exclusive_val
;
69 /* FIXME: These should be removed. */
70 static TCGv_i32 cpu_F0s
, cpu_F1s
;
71 static TCGv_i64 cpu_F0d
, cpu_F1d
;
73 #include "exec/gen-icount.h"
75 static const char *regnames
[] =
76 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
79 /* initialize TCG globals. */
80 void arm_translate_init(void)
84 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
85 tcg_ctx
.tcg_env
= cpu_env
;
87 for (i
= 0; i
< 16; i
++) {
88 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
89 offsetof(CPUARMState
, regs
[i
]),
92 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
93 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
94 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
95 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
97 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
98 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
99 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
100 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
102 a64_translate_init();
105 /* Flags for the disas_set_da_iss info argument:
106 * lower bits hold the Rt register number, higher bits are flags.
108 typedef enum ISSInfo
{
111 ISSInvalid
= (1 << 5),
112 ISSIsAcqRel
= (1 << 6),
113 ISSIsWrite
= (1 << 7),
114 ISSIs16Bit
= (1 << 8),
117 /* Save the syndrome information for a Data Abort */
118 static void disas_set_da_iss(DisasContext
*s
, TCGMemOp memop
, ISSInfo issinfo
)
121 int sas
= memop
& MO_SIZE
;
122 bool sse
= memop
& MO_SIGN
;
123 bool is_acqrel
= issinfo
& ISSIsAcqRel
;
124 bool is_write
= issinfo
& ISSIsWrite
;
125 bool is_16bit
= issinfo
& ISSIs16Bit
;
126 int srt
= issinfo
& ISSRegMask
;
128 if (issinfo
& ISSInvalid
) {
129 /* Some callsites want to conditionally provide ISS info,
130 * eg "only if this was not a writeback"
136 /* For AArch32, insns where the src/dest is R15 never generate
137 * ISS information. Catching that here saves checking at all
143 syn
= syn_data_abort_with_iss(0, sas
, sse
, srt
, 0, is_acqrel
,
144 0, 0, 0, is_write
, 0, is_16bit
);
145 disas_set_insn_syndrome(s
, syn
);
148 static inline int get_a32_user_mem_index(DisasContext
*s
)
150 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
152 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
153 * otherwise, access as if at PL0.
155 switch (s
->mmu_idx
) {
156 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
157 case ARMMMUIdx_S12NSE0
:
158 case ARMMMUIdx_S12NSE1
:
159 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0
);
161 case ARMMMUIdx_S1SE0
:
162 case ARMMMUIdx_S1SE1
:
163 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0
);
164 case ARMMMUIdx_MUser
:
165 case ARMMMUIdx_MPriv
:
166 case ARMMMUIdx_MNegPri
:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser
);
170 g_assert_not_reached();
174 static inline TCGv_i32
load_cpu_offset(int offset
)
176 TCGv_i32 tmp
= tcg_temp_new_i32();
177 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
181 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
183 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
185 tcg_gen_st_i32(var
, cpu_env
, offset
);
186 tcg_temp_free_i32(var
);
189 #define store_cpu_field(var, name) \
190 store_cpu_offset(var, offsetof(CPUARMState, name))
192 /* Set a variable to the value of a CPU register. */
193 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
197 /* normally, since we updated PC, we need only to add one insn */
199 addr
= (long)s
->pc
+ 2;
201 addr
= (long)s
->pc
+ 4;
202 tcg_gen_movi_i32(var
, addr
);
204 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
208 /* Create a new temporary and set it to the value of a CPU register. */
209 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
211 TCGv_i32 tmp
= tcg_temp_new_i32();
212 load_reg_var(s
, tmp
, reg
);
216 /* Set a CPU register. The source must be a temporary and will be
218 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
221 /* In Thumb mode, we must ignore bit 0.
222 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
223 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
224 * We choose to ignore [1:0] in ARM mode for all architecture versions.
226 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
227 s
->is_jmp
= DISAS_JUMP
;
229 tcg_gen_mov_i32(cpu_R
[reg
], var
);
230 tcg_temp_free_i32(var
);
233 /* Value extensions. */
234 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
235 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
236 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
237 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
239 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
240 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
243 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
245 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
246 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
247 tcg_temp_free_i32(tmp_mask
);
249 /* Set NZCV flags from the high 4 bits of var. */
250 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
252 static void gen_exception_internal(int excp
)
254 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
256 assert(excp_is_internal(excp
));
257 gen_helper_exception_internal(cpu_env
, tcg_excp
);
258 tcg_temp_free_i32(tcg_excp
);
261 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
263 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
264 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
265 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
267 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
270 tcg_temp_free_i32(tcg_el
);
271 tcg_temp_free_i32(tcg_syn
);
272 tcg_temp_free_i32(tcg_excp
);
275 static void gen_ss_advance(DisasContext
*s
)
277 /* If the singlestep state is Active-not-pending, advance to
282 gen_helper_clear_pstate_ss(cpu_env
);
286 static void gen_step_complete_exception(DisasContext
*s
)
288 /* We just completed step of an insn. Move from Active-not-pending
289 * to Active-pending, and then also take the swstep exception.
290 * This corresponds to making the (IMPDEF) choice to prioritize
291 * swstep exceptions over asynchronous exceptions taken to an exception
292 * level where debug is disabled. This choice has the advantage that
293 * we do not need to maintain internal state corresponding to the
294 * ISV/EX syndrome bits between completion of the step and generation
295 * of the exception, and our syndrome information is always correct.
298 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
299 default_exception_el(s
));
300 s
->is_jmp
= DISAS_EXC
;
303 static void gen_singlestep_exception(DisasContext
*s
)
305 /* Generate the right kind of exception for singlestep, which is
306 * either the architectural singlestep or EXCP_DEBUG for QEMU's
307 * gdb singlestepping.
310 gen_step_complete_exception(s
);
312 gen_exception_internal(EXCP_DEBUG
);
316 static inline bool is_singlestepping(DisasContext
*s
)
318 /* Return true if we are singlestepping either because of
319 * architectural singlestep or QEMU gdbstub singlestep. This does
320 * not include the command line '-singlestep' mode which is rather
321 * misnamed as it only means "one instruction per TB" and doesn't
322 * affect the code we generate.
324 return s
->singlestep_enabled
|| s
->ss_active
;
327 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
329 TCGv_i32 tmp1
= tcg_temp_new_i32();
330 TCGv_i32 tmp2
= tcg_temp_new_i32();
331 tcg_gen_ext16s_i32(tmp1
, a
);
332 tcg_gen_ext16s_i32(tmp2
, b
);
333 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
334 tcg_temp_free_i32(tmp2
);
335 tcg_gen_sari_i32(a
, a
, 16);
336 tcg_gen_sari_i32(b
, b
, 16);
337 tcg_gen_mul_i32(b
, b
, a
);
338 tcg_gen_mov_i32(a
, tmp1
);
339 tcg_temp_free_i32(tmp1
);
342 /* Byteswap each halfword. */
343 static void gen_rev16(TCGv_i32 var
)
345 TCGv_i32 tmp
= tcg_temp_new_i32();
346 tcg_gen_shri_i32(tmp
, var
, 8);
347 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
348 tcg_gen_shli_i32(var
, var
, 8);
349 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
350 tcg_gen_or_i32(var
, var
, tmp
);
351 tcg_temp_free_i32(tmp
);
354 /* Byteswap low halfword and sign extend. */
355 static void gen_revsh(TCGv_i32 var
)
357 tcg_gen_ext16u_i32(var
, var
);
358 tcg_gen_bswap16_i32(var
, var
);
359 tcg_gen_ext16s_i32(var
, var
);
362 /* Return (b << 32) + a. Mark inputs as dead */
363 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
365 TCGv_i64 tmp64
= tcg_temp_new_i64();
367 tcg_gen_extu_i32_i64(tmp64
, b
);
368 tcg_temp_free_i32(b
);
369 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
370 tcg_gen_add_i64(a
, tmp64
, a
);
372 tcg_temp_free_i64(tmp64
);
376 /* Return (b << 32) - a. Mark inputs as dead. */
377 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
379 TCGv_i64 tmp64
= tcg_temp_new_i64();
381 tcg_gen_extu_i32_i64(tmp64
, b
);
382 tcg_temp_free_i32(b
);
383 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
384 tcg_gen_sub_i64(a
, tmp64
, a
);
386 tcg_temp_free_i64(tmp64
);
390 /* 32x32->64 multiply. Marks inputs as dead. */
391 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
393 TCGv_i32 lo
= tcg_temp_new_i32();
394 TCGv_i32 hi
= tcg_temp_new_i32();
397 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
398 tcg_temp_free_i32(a
);
399 tcg_temp_free_i32(b
);
401 ret
= tcg_temp_new_i64();
402 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
403 tcg_temp_free_i32(lo
);
404 tcg_temp_free_i32(hi
);
409 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
411 TCGv_i32 lo
= tcg_temp_new_i32();
412 TCGv_i32 hi
= tcg_temp_new_i32();
415 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
416 tcg_temp_free_i32(a
);
417 tcg_temp_free_i32(b
);
419 ret
= tcg_temp_new_i64();
420 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
421 tcg_temp_free_i32(lo
);
422 tcg_temp_free_i32(hi
);
427 /* Swap low and high halfwords. */
428 static void gen_swap_half(TCGv_i32 var
)
430 TCGv_i32 tmp
= tcg_temp_new_i32();
431 tcg_gen_shri_i32(tmp
, var
, 16);
432 tcg_gen_shli_i32(var
, var
, 16);
433 tcg_gen_or_i32(var
, var
, tmp
);
434 tcg_temp_free_i32(tmp
);
437 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
438 tmp = (t0 ^ t1) & 0x8000;
441 t0 = (t0 + t1) ^ tmp;
444 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
446 TCGv_i32 tmp
= tcg_temp_new_i32();
447 tcg_gen_xor_i32(tmp
, t0
, t1
);
448 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
449 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
450 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
451 tcg_gen_add_i32(t0
, t0
, t1
);
452 tcg_gen_xor_i32(t0
, t0
, tmp
);
453 tcg_temp_free_i32(tmp
);
454 tcg_temp_free_i32(t1
);
457 /* Set CF to the top bit of var. */
458 static void gen_set_CF_bit31(TCGv_i32 var
)
460 tcg_gen_shri_i32(cpu_CF
, var
, 31);
463 /* Set N and Z flags from var. */
464 static inline void gen_logic_CC(TCGv_i32 var
)
466 tcg_gen_mov_i32(cpu_NF
, var
);
467 tcg_gen_mov_i32(cpu_ZF
, var
);
471 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
473 tcg_gen_add_i32(t0
, t0
, t1
);
474 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
477 /* dest = T0 + T1 + CF. */
478 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
480 tcg_gen_add_i32(dest
, t0
, t1
);
481 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
484 /* dest = T0 - T1 + CF - 1. */
485 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
487 tcg_gen_sub_i32(dest
, t0
, t1
);
488 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
489 tcg_gen_subi_i32(dest
, dest
, 1);
492 /* dest = T0 + T1. Compute C, N, V and Z flags */
493 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
495 TCGv_i32 tmp
= tcg_temp_new_i32();
496 tcg_gen_movi_i32(tmp
, 0);
497 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
498 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
499 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
500 tcg_gen_xor_i32(tmp
, t0
, t1
);
501 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
502 tcg_temp_free_i32(tmp
);
503 tcg_gen_mov_i32(dest
, cpu_NF
);
506 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
507 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
509 TCGv_i32 tmp
= tcg_temp_new_i32();
510 if (TCG_TARGET_HAS_add2_i32
) {
511 tcg_gen_movi_i32(tmp
, 0);
512 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
513 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
515 TCGv_i64 q0
= tcg_temp_new_i64();
516 TCGv_i64 q1
= tcg_temp_new_i64();
517 tcg_gen_extu_i32_i64(q0
, t0
);
518 tcg_gen_extu_i32_i64(q1
, t1
);
519 tcg_gen_add_i64(q0
, q0
, q1
);
520 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
521 tcg_gen_add_i64(q0
, q0
, q1
);
522 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
523 tcg_temp_free_i64(q0
);
524 tcg_temp_free_i64(q1
);
526 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
527 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
528 tcg_gen_xor_i32(tmp
, t0
, t1
);
529 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
530 tcg_temp_free_i32(tmp
);
531 tcg_gen_mov_i32(dest
, cpu_NF
);
534 /* dest = T0 - T1. Compute C, N, V and Z flags */
535 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
538 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
539 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
540 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
541 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
542 tmp
= tcg_temp_new_i32();
543 tcg_gen_xor_i32(tmp
, t0
, t1
);
544 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
545 tcg_temp_free_i32(tmp
);
546 tcg_gen_mov_i32(dest
, cpu_NF
);
549 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
550 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
552 TCGv_i32 tmp
= tcg_temp_new_i32();
553 tcg_gen_not_i32(tmp
, t1
);
554 gen_adc_CC(dest
, t0
, tmp
);
555 tcg_temp_free_i32(tmp
);
558 #define GEN_SHIFT(name) \
559 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
561 TCGv_i32 tmp1, tmp2, tmp3; \
562 tmp1 = tcg_temp_new_i32(); \
563 tcg_gen_andi_i32(tmp1, t1, 0xff); \
564 tmp2 = tcg_const_i32(0); \
565 tmp3 = tcg_const_i32(0x1f); \
566 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
567 tcg_temp_free_i32(tmp3); \
568 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
569 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
570 tcg_temp_free_i32(tmp2); \
571 tcg_temp_free_i32(tmp1); \
577 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
580 tmp1
= tcg_temp_new_i32();
581 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
582 tmp2
= tcg_const_i32(0x1f);
583 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
584 tcg_temp_free_i32(tmp2
);
585 tcg_gen_sar_i32(dest
, t0
, tmp1
);
586 tcg_temp_free_i32(tmp1
);
589 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
591 TCGv_i32 c0
= tcg_const_i32(0);
592 TCGv_i32 tmp
= tcg_temp_new_i32();
593 tcg_gen_neg_i32(tmp
, src
);
594 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
595 tcg_temp_free_i32(c0
);
596 tcg_temp_free_i32(tmp
);
599 static void shifter_out_im(TCGv_i32 var
, int shift
)
602 tcg_gen_andi_i32(cpu_CF
, var
, 1);
604 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
606 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
611 /* Shift by immediate. Includes special handling for shift == 0. */
612 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
613 int shift
, int flags
)
619 shifter_out_im(var
, 32 - shift
);
620 tcg_gen_shli_i32(var
, var
, shift
);
626 tcg_gen_shri_i32(cpu_CF
, var
, 31);
628 tcg_gen_movi_i32(var
, 0);
631 shifter_out_im(var
, shift
- 1);
632 tcg_gen_shri_i32(var
, var
, shift
);
639 shifter_out_im(var
, shift
- 1);
642 tcg_gen_sari_i32(var
, var
, shift
);
644 case 3: /* ROR/RRX */
647 shifter_out_im(var
, shift
- 1);
648 tcg_gen_rotri_i32(var
, var
, shift
); break;
650 TCGv_i32 tmp
= tcg_temp_new_i32();
651 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
653 shifter_out_im(var
, 0);
654 tcg_gen_shri_i32(var
, var
, 1);
655 tcg_gen_or_i32(var
, var
, tmp
);
656 tcg_temp_free_i32(tmp
);
661 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
662 TCGv_i32 shift
, int flags
)
666 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
667 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
668 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
669 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
674 gen_shl(var
, var
, shift
);
677 gen_shr(var
, var
, shift
);
680 gen_sar(var
, var
, shift
);
682 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
683 tcg_gen_rotr_i32(var
, var
, shift
); break;
686 tcg_temp_free_i32(shift
);
689 #define PAS_OP(pfx) \
691 case 0: gen_pas_helper(glue(pfx,add16)); break; \
692 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
693 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
694 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
695 case 4: gen_pas_helper(glue(pfx,add8)); break; \
696 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
698 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
703 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
705 tmp
= tcg_temp_new_ptr();
706 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
708 tcg_temp_free_ptr(tmp
);
711 tmp
= tcg_temp_new_ptr();
712 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
714 tcg_temp_free_ptr(tmp
);
716 #undef gen_pas_helper
717 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
730 #undef gen_pas_helper
735 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
736 #define PAS_OP(pfx) \
738 case 0: gen_pas_helper(glue(pfx,add8)); break; \
739 case 1: gen_pas_helper(glue(pfx,add16)); break; \
740 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
741 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
742 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
743 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
745 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
750 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
752 tmp
= tcg_temp_new_ptr();
753 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
755 tcg_temp_free_ptr(tmp
);
758 tmp
= tcg_temp_new_ptr();
759 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
761 tcg_temp_free_ptr(tmp
);
763 #undef gen_pas_helper
764 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
777 #undef gen_pas_helper
783 * Generate a conditional based on ARM condition code cc.
784 * This is common between ARM and Aarch64 targets.
786 void arm_test_cc(DisasCompare
*cmp
, int cc
)
817 case 8: /* hi: C && !Z */
818 case 9: /* ls: !C || Z -> !(C && !Z) */
820 value
= tcg_temp_new_i32();
822 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
823 ZF is non-zero for !Z; so AND the two subexpressions. */
824 tcg_gen_neg_i32(value
, cpu_CF
);
825 tcg_gen_and_i32(value
, value
, cpu_ZF
);
828 case 10: /* ge: N == V -> N ^ V == 0 */
829 case 11: /* lt: N != V -> N ^ V != 0 */
830 /* Since we're only interested in the sign bit, == 0 is >= 0. */
832 value
= tcg_temp_new_i32();
834 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
837 case 12: /* gt: !Z && N == V */
838 case 13: /* le: Z || N != V */
840 value
= tcg_temp_new_i32();
842 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
843 * the sign bit then AND with ZF to yield the result. */
844 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
845 tcg_gen_sari_i32(value
, value
, 31);
846 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
849 case 14: /* always */
850 case 15: /* always */
851 /* Use the ALWAYS condition, which will fold early.
852 * It doesn't matter what we use for the value. */
853 cond
= TCG_COND_ALWAYS
;
858 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
863 cond
= tcg_invert_cond(cond
);
869 cmp
->value_global
= global
;
872 void arm_free_cc(DisasCompare
*cmp
)
874 if (!cmp
->value_global
) {
875 tcg_temp_free_i32(cmp
->value
);
879 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
881 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
884 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
887 arm_test_cc(&cmp
, cc
);
888 arm_jump_cc(&cmp
, label
);
892 static const uint8_t table_logic_cc
[16] = {
911 static inline void gen_set_condexec(DisasContext
*s
)
913 if (s
->condexec_mask
) {
914 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
915 TCGv_i32 tmp
= tcg_temp_new_i32();
916 tcg_gen_movi_i32(tmp
, val
);
917 store_cpu_field(tmp
, condexec_bits
);
921 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
923 tcg_gen_movi_i32(cpu_R
[15], val
);
926 /* Set PC and Thumb state from an immediate address. */
927 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
931 s
->is_jmp
= DISAS_JUMP
;
932 if (s
->thumb
!= (addr
& 1)) {
933 tmp
= tcg_temp_new_i32();
934 tcg_gen_movi_i32(tmp
, addr
& 1);
935 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
936 tcg_temp_free_i32(tmp
);
938 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
941 /* Set PC and Thumb state from var. var is marked as dead. */
942 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
944 s
->is_jmp
= DISAS_JUMP
;
945 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
946 tcg_gen_andi_i32(var
, var
, 1);
947 store_cpu_field(var
, thumb
);
950 /* Set PC and Thumb state from var. var is marked as dead.
951 * For M-profile CPUs, include logic to detect exception-return
952 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
953 * and BX reg, and no others, and happens only for code in Handler mode.
955 static inline void gen_bx_excret(DisasContext
*s
, TCGv_i32 var
)
957 /* Generate the same code here as for a simple bx, but flag via
958 * s->is_jmp that we need to do the rest of the work later.
961 if (s
->v7m_handler_mode
&& arm_dc_feature(s
, ARM_FEATURE_M
)) {
962 s
->is_jmp
= DISAS_BX_EXCRET
;
966 static inline void gen_bx_excret_final_code(DisasContext
*s
)
968 /* Generate the code to finish possible exception return and end the TB */
969 TCGLabel
*excret_label
= gen_new_label();
971 /* Is the new PC value in the magic range indicating exception return? */
972 tcg_gen_brcondi_i32(TCG_COND_GEU
, cpu_R
[15], 0xff000000, excret_label
);
973 /* No: end the TB as we would for a DISAS_JMP */
974 if (is_singlestepping(s
)) {
975 gen_singlestep_exception(s
);
979 gen_set_label(excret_label
);
980 /* Yes: this is an exception return.
981 * At this point in runtime env->regs[15] and env->thumb will hold
982 * the exception-return magic number, which do_v7m_exception_exit()
983 * will read. Nothing else will be able to see those values because
984 * the cpu-exec main loop guarantees that we will always go straight
985 * from raising the exception to the exception-handling code.
987 * gen_ss_advance(s) does nothing on M profile currently but
988 * calling it is conceptually the right thing as we have executed
989 * this instruction (compare SWI, HVC, SMC handling).
992 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
995 /* Variant of store_reg which uses branch&exchange logic when storing
996 to r15 in ARM architecture v7 and above. The source must be a temporary
997 and will be marked as dead. */
998 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
1000 if (reg
== 15 && ENABLE_ARCH_7
) {
1003 store_reg(s
, reg
, var
);
1007 /* Variant of store_reg which uses branch&exchange logic when storing
1008 * to r15 in ARM architecture v5T and above. This is used for storing
1009 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1010 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1011 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
1013 if (reg
== 15 && ENABLE_ARCH_5
) {
1014 gen_bx_excret(s
, var
);
1016 store_reg(s
, reg
, var
);
1020 #ifdef CONFIG_USER_ONLY
1021 #define IS_USER_ONLY 1
1023 #define IS_USER_ONLY 0
1026 /* Abstractions of "generate code to do a guest load/store for
1027 * AArch32", where a vaddr is always 32 bits (and is zero
1028 * extended if we're a 64 bit core) and data is also
1029 * 32 bits unless specifically doing a 64 bit access.
1030 * These functions work like tcg_gen_qemu_{ld,st}* except
1031 * that the address argument is TCGv_i32 rather than TCGv.
1034 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, TCGMemOp op
)
1036 TCGv addr
= tcg_temp_new();
1037 tcg_gen_extu_i32_tl(addr
, a32
);
1039 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1040 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
1041 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
1046 static void gen_aa32_ld_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1047 int index
, TCGMemOp opc
)
1049 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1050 tcg_gen_qemu_ld_i32(val
, addr
, index
, opc
);
1051 tcg_temp_free(addr
);
1054 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1055 int index
, TCGMemOp opc
)
1057 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1058 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
1059 tcg_temp_free(addr
);
1062 #define DO_GEN_LD(SUFF, OPC) \
1063 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1064 TCGv_i32 a32, int index) \
1066 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1068 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1070 TCGv_i32 a32, int index, \
1073 gen_aa32_ld##SUFF(s, val, a32, index); \
1074 disas_set_da_iss(s, OPC, issinfo); \
1077 #define DO_GEN_ST(SUFF, OPC) \
1078 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1079 TCGv_i32 a32, int index) \
1081 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1083 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1085 TCGv_i32 a32, int index, \
1088 gen_aa32_st##SUFF(s, val, a32, index); \
1089 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1092 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
1094 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1095 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1096 tcg_gen_rotri_i64(val
, val
, 32);
1100 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1101 int index
, TCGMemOp opc
)
1103 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1104 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
1105 gen_aa32_frob64(s
, val
);
1106 tcg_temp_free(addr
);
1109 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1110 TCGv_i32 a32
, int index
)
1112 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1115 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1116 int index
, TCGMemOp opc
)
1118 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1120 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1121 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1122 TCGv_i64 tmp
= tcg_temp_new_i64();
1123 tcg_gen_rotri_i64(tmp
, val
, 32);
1124 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
1125 tcg_temp_free_i64(tmp
);
1127 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
1129 tcg_temp_free(addr
);
1132 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1133 TCGv_i32 a32
, int index
)
1135 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1138 DO_GEN_LD(8s
, MO_SB
)
1139 DO_GEN_LD(8u, MO_UB
)
1140 DO_GEN_LD(16s
, MO_SW
)
1141 DO_GEN_LD(16u, MO_UW
)
1142 DO_GEN_LD(32u, MO_UL
)
1144 DO_GEN_ST(16, MO_UW
)
1145 DO_GEN_ST(32, MO_UL
)
1147 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1149 /* The pre HVC helper handles cases when HVC gets trapped
1150 * as an undefined insn by runtime configuration (ie before
1151 * the insn really executes).
1153 gen_set_pc_im(s
, s
->pc
- 4);
1154 gen_helper_pre_hvc(cpu_env
);
1155 /* Otherwise we will treat this as a real exception which
1156 * happens after execution of the insn. (The distinction matters
1157 * for the PC value reported to the exception handler and also
1158 * for single stepping.)
1161 gen_set_pc_im(s
, s
->pc
);
1162 s
->is_jmp
= DISAS_HVC
;
1165 static inline void gen_smc(DisasContext
*s
)
1167 /* As with HVC, we may take an exception either before or after
1168 * the insn executes.
1172 gen_set_pc_im(s
, s
->pc
- 4);
1173 tmp
= tcg_const_i32(syn_aa32_smc());
1174 gen_helper_pre_smc(cpu_env
, tmp
);
1175 tcg_temp_free_i32(tmp
);
1176 gen_set_pc_im(s
, s
->pc
);
1177 s
->is_jmp
= DISAS_SMC
;
1180 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1182 gen_set_condexec(s
);
1183 gen_set_pc_im(s
, s
->pc
- offset
);
1184 gen_exception_internal(excp
);
1185 s
->is_jmp
= DISAS_EXC
;
1188 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1189 int syn
, uint32_t target_el
)
1191 gen_set_condexec(s
);
1192 gen_set_pc_im(s
, s
->pc
- offset
);
1193 gen_exception(excp
, syn
, target_el
);
1194 s
->is_jmp
= DISAS_EXC
;
1197 /* Force a TB lookup after an instruction that changes the CPU state. */
1198 static inline void gen_lookup_tb(DisasContext
*s
)
1200 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1201 s
->is_jmp
= DISAS_EXIT
;
1204 static inline void gen_hlt(DisasContext
*s
, int imm
)
1206 /* HLT. This has two purposes.
1207 * Architecturally, it is an external halting debug instruction.
1208 * Since QEMU doesn't implement external debug, we treat this as
1209 * it is required for halting debug disabled: it will UNDEF.
1210 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1211 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1212 * must trigger semihosting even for ARMv7 and earlier, where
1213 * HLT was an undefined encoding.
1214 * In system mode, we don't allow userspace access to
1215 * semihosting, to provide some semblance of security
1216 * (and for consistency with our 32-bit semihosting).
1218 if (semihosting_enabled() &&
1219 #ifndef CONFIG_USER_ONLY
1220 s
->current_el
!= 0 &&
1222 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1223 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1227 gen_exception_insn(s
, s
->thumb
? 2 : 4, EXCP_UDEF
, syn_uncategorized(),
1228 default_exception_el(s
));
1231 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1234 int val
, rm
, shift
, shiftop
;
1237 if (!(insn
& (1 << 25))) {
1240 if (!(insn
& (1 << 23)))
1243 tcg_gen_addi_i32(var
, var
, val
);
1245 /* shift/register */
1247 shift
= (insn
>> 7) & 0x1f;
1248 shiftop
= (insn
>> 5) & 3;
1249 offset
= load_reg(s
, rm
);
1250 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1251 if (!(insn
& (1 << 23)))
1252 tcg_gen_sub_i32(var
, var
, offset
);
1254 tcg_gen_add_i32(var
, var
, offset
);
1255 tcg_temp_free_i32(offset
);
1259 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1260 int extra
, TCGv_i32 var
)
1265 if (insn
& (1 << 22)) {
1267 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1268 if (!(insn
& (1 << 23)))
1272 tcg_gen_addi_i32(var
, var
, val
);
1276 tcg_gen_addi_i32(var
, var
, extra
);
1278 offset
= load_reg(s
, rm
);
1279 if (!(insn
& (1 << 23)))
1280 tcg_gen_sub_i32(var
, var
, offset
);
1282 tcg_gen_add_i32(var
, var
, offset
);
1283 tcg_temp_free_i32(offset
);
1287 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1289 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1292 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1294 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1296 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1300 #define VFP_OP2(name) \
1301 static inline void gen_vfp_##name(int dp) \
1303 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1305 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1307 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1309 tcg_temp_free_ptr(fpst); \
1319 static inline void gen_vfp_F1_mul(int dp
)
1321 /* Like gen_vfp_mul() but put result in F1 */
1322 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1324 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1326 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1328 tcg_temp_free_ptr(fpst
);
1331 static inline void gen_vfp_F1_neg(int dp
)
1333 /* Like gen_vfp_neg() but put result in F1 */
1335 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1337 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1341 static inline void gen_vfp_abs(int dp
)
1344 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1346 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1349 static inline void gen_vfp_neg(int dp
)
1352 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1354 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1357 static inline void gen_vfp_sqrt(int dp
)
1360 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1362 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1365 static inline void gen_vfp_cmp(int dp
)
1368 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1370 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1373 static inline void gen_vfp_cmpe(int dp
)
1376 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1378 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1381 static inline void gen_vfp_F1_ld0(int dp
)
1384 tcg_gen_movi_i64(cpu_F1d
, 0);
1386 tcg_gen_movi_i32(cpu_F1s
, 0);
1389 #define VFP_GEN_ITOF(name) \
1390 static inline void gen_vfp_##name(int dp, int neon) \
1392 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1394 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1396 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1398 tcg_temp_free_ptr(statusptr); \
1405 #define VFP_GEN_FTOI(name) \
1406 static inline void gen_vfp_##name(int dp, int neon) \
1408 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1410 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1412 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1414 tcg_temp_free_ptr(statusptr); \
1423 #define VFP_GEN_FIX(name, round) \
1424 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1426 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1427 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1429 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1432 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1435 tcg_temp_free_i32(tmp_shift); \
1436 tcg_temp_free_ptr(statusptr); \
1438 VFP_GEN_FIX(tosh
, _round_to_zero
)
1439 VFP_GEN_FIX(tosl
, _round_to_zero
)
1440 VFP_GEN_FIX(touh
, _round_to_zero
)
1441 VFP_GEN_FIX(toul
, _round_to_zero
)
1448 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1451 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1453 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1457 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1460 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1462 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1467 vfp_reg_offset (int dp
, int reg
)
1470 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1472 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1473 + offsetof(CPU_DoubleU
, l
.upper
);
1475 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1476 + offsetof(CPU_DoubleU
, l
.lower
);
1480 /* Return the offset of a 32-bit piece of a NEON register.
1481 zero is the least significant end of the register. */
1483 neon_reg_offset (int reg
, int n
)
1487 return vfp_reg_offset(0, sreg
);
1490 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1492 TCGv_i32 tmp
= tcg_temp_new_i32();
1493 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1497 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1499 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1500 tcg_temp_free_i32(var
);
1503 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1505 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1508 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1510 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1513 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1514 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1515 #define tcg_gen_st_f32 tcg_gen_st_i32
1516 #define tcg_gen_st_f64 tcg_gen_st_i64
1518 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1521 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1523 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1526 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1529 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1531 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1534 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1537 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1539 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1542 #define ARM_CP_RW_BIT (1 << 20)
1544 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1546 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1549 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1551 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1554 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1556 TCGv_i32 var
= tcg_temp_new_i32();
1557 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1561 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1563 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1564 tcg_temp_free_i32(var
);
1567 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1569 iwmmxt_store_reg(cpu_M0
, rn
);
1572 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1574 iwmmxt_load_reg(cpu_M0
, rn
);
1577 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1579 iwmmxt_load_reg(cpu_V1
, rn
);
1580 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1583 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1585 iwmmxt_load_reg(cpu_V1
, rn
);
1586 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1589 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1591 iwmmxt_load_reg(cpu_V1
, rn
);
1592 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1595 #define IWMMXT_OP(name) \
1596 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1598 iwmmxt_load_reg(cpu_V1, rn); \
1599 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1602 #define IWMMXT_OP_ENV(name) \
1603 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1605 iwmmxt_load_reg(cpu_V1, rn); \
1606 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1609 #define IWMMXT_OP_ENV_SIZE(name) \
1610 IWMMXT_OP_ENV(name##b) \
1611 IWMMXT_OP_ENV(name##w) \
1612 IWMMXT_OP_ENV(name##l)
1614 #define IWMMXT_OP_ENV1(name) \
1615 static inline void gen_op_iwmmxt_##name##_M0(void) \
1617 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1631 IWMMXT_OP_ENV_SIZE(unpackl
)
1632 IWMMXT_OP_ENV_SIZE(unpackh
)
1634 IWMMXT_OP_ENV1(unpacklub
)
1635 IWMMXT_OP_ENV1(unpackluw
)
1636 IWMMXT_OP_ENV1(unpacklul
)
1637 IWMMXT_OP_ENV1(unpackhub
)
1638 IWMMXT_OP_ENV1(unpackhuw
)
1639 IWMMXT_OP_ENV1(unpackhul
)
1640 IWMMXT_OP_ENV1(unpacklsb
)
1641 IWMMXT_OP_ENV1(unpacklsw
)
1642 IWMMXT_OP_ENV1(unpacklsl
)
1643 IWMMXT_OP_ENV1(unpackhsb
)
1644 IWMMXT_OP_ENV1(unpackhsw
)
1645 IWMMXT_OP_ENV1(unpackhsl
)
1647 IWMMXT_OP_ENV_SIZE(cmpeq
)
1648 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1649 IWMMXT_OP_ENV_SIZE(cmpgts
)
1651 IWMMXT_OP_ENV_SIZE(mins
)
1652 IWMMXT_OP_ENV_SIZE(minu
)
1653 IWMMXT_OP_ENV_SIZE(maxs
)
1654 IWMMXT_OP_ENV_SIZE(maxu
)
1656 IWMMXT_OP_ENV_SIZE(subn
)
1657 IWMMXT_OP_ENV_SIZE(addn
)
1658 IWMMXT_OP_ENV_SIZE(subu
)
1659 IWMMXT_OP_ENV_SIZE(addu
)
1660 IWMMXT_OP_ENV_SIZE(subs
)
1661 IWMMXT_OP_ENV_SIZE(adds
)
1663 IWMMXT_OP_ENV(avgb0
)
1664 IWMMXT_OP_ENV(avgb1
)
1665 IWMMXT_OP_ENV(avgw0
)
1666 IWMMXT_OP_ENV(avgw1
)
1668 IWMMXT_OP_ENV(packuw
)
1669 IWMMXT_OP_ENV(packul
)
1670 IWMMXT_OP_ENV(packuq
)
1671 IWMMXT_OP_ENV(packsw
)
1672 IWMMXT_OP_ENV(packsl
)
1673 IWMMXT_OP_ENV(packsq
)
1675 static void gen_op_iwmmxt_set_mup(void)
1678 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1679 tcg_gen_ori_i32(tmp
, tmp
, 2);
1680 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1683 static void gen_op_iwmmxt_set_cup(void)
1686 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1687 tcg_gen_ori_i32(tmp
, tmp
, 1);
1688 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1691 static void gen_op_iwmmxt_setpsr_nz(void)
1693 TCGv_i32 tmp
= tcg_temp_new_i32();
1694 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1695 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1698 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1700 iwmmxt_load_reg(cpu_V1
, rn
);
1701 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1702 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1705 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1712 rd
= (insn
>> 16) & 0xf;
1713 tmp
= load_reg(s
, rd
);
1715 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1716 if (insn
& (1 << 24)) {
1718 if (insn
& (1 << 23))
1719 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1721 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1722 tcg_gen_mov_i32(dest
, tmp
);
1723 if (insn
& (1 << 21))
1724 store_reg(s
, rd
, tmp
);
1726 tcg_temp_free_i32(tmp
);
1727 } else if (insn
& (1 << 21)) {
1729 tcg_gen_mov_i32(dest
, tmp
);
1730 if (insn
& (1 << 23))
1731 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1733 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1734 store_reg(s
, rd
, tmp
);
1735 } else if (!(insn
& (1 << 23)))
1740 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1742 int rd
= (insn
>> 0) & 0xf;
1745 if (insn
& (1 << 8)) {
1746 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1749 tmp
= iwmmxt_load_creg(rd
);
1752 tmp
= tcg_temp_new_i32();
1753 iwmmxt_load_reg(cpu_V0
, rd
);
1754 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1756 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1757 tcg_gen_mov_i32(dest
, tmp
);
1758 tcg_temp_free_i32(tmp
);
1762 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1763 (ie. an undefined instruction). */
1764 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1767 int rdhi
, rdlo
, rd0
, rd1
, i
;
1769 TCGv_i32 tmp
, tmp2
, tmp3
;
1771 if ((insn
& 0x0e000e00) == 0x0c000000) {
1772 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1774 rdlo
= (insn
>> 12) & 0xf;
1775 rdhi
= (insn
>> 16) & 0xf;
1776 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1777 iwmmxt_load_reg(cpu_V0
, wrd
);
1778 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1779 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1780 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1781 } else { /* TMCRR */
1782 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1783 iwmmxt_store_reg(cpu_V0
, wrd
);
1784 gen_op_iwmmxt_set_mup();
1789 wrd
= (insn
>> 12) & 0xf;
1790 addr
= tcg_temp_new_i32();
1791 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1792 tcg_temp_free_i32(addr
);
1795 if (insn
& ARM_CP_RW_BIT
) {
1796 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1797 tmp
= tcg_temp_new_i32();
1798 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1799 iwmmxt_store_creg(wrd
, tmp
);
1802 if (insn
& (1 << 8)) {
1803 if (insn
& (1 << 22)) { /* WLDRD */
1804 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1806 } else { /* WLDRW wRd */
1807 tmp
= tcg_temp_new_i32();
1808 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1811 tmp
= tcg_temp_new_i32();
1812 if (insn
& (1 << 22)) { /* WLDRH */
1813 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1814 } else { /* WLDRB */
1815 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1819 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1820 tcg_temp_free_i32(tmp
);
1822 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1825 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1826 tmp
= iwmmxt_load_creg(wrd
);
1827 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1829 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1830 tmp
= tcg_temp_new_i32();
1831 if (insn
& (1 << 8)) {
1832 if (insn
& (1 << 22)) { /* WSTRD */
1833 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1834 } else { /* WSTRW wRd */
1835 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1836 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1839 if (insn
& (1 << 22)) { /* WSTRH */
1840 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1841 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1842 } else { /* WSTRB */
1843 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1844 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1848 tcg_temp_free_i32(tmp
);
1850 tcg_temp_free_i32(addr
);
1854 if ((insn
& 0x0f000000) != 0x0e000000)
1857 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1858 case 0x000: /* WOR */
1859 wrd
= (insn
>> 12) & 0xf;
1860 rd0
= (insn
>> 0) & 0xf;
1861 rd1
= (insn
>> 16) & 0xf;
1862 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1863 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1864 gen_op_iwmmxt_setpsr_nz();
1865 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1866 gen_op_iwmmxt_set_mup();
1867 gen_op_iwmmxt_set_cup();
1869 case 0x011: /* TMCR */
1872 rd
= (insn
>> 12) & 0xf;
1873 wrd
= (insn
>> 16) & 0xf;
1875 case ARM_IWMMXT_wCID
:
1876 case ARM_IWMMXT_wCASF
:
1878 case ARM_IWMMXT_wCon
:
1879 gen_op_iwmmxt_set_cup();
1881 case ARM_IWMMXT_wCSSF
:
1882 tmp
= iwmmxt_load_creg(wrd
);
1883 tmp2
= load_reg(s
, rd
);
1884 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1885 tcg_temp_free_i32(tmp2
);
1886 iwmmxt_store_creg(wrd
, tmp
);
1888 case ARM_IWMMXT_wCGR0
:
1889 case ARM_IWMMXT_wCGR1
:
1890 case ARM_IWMMXT_wCGR2
:
1891 case ARM_IWMMXT_wCGR3
:
1892 gen_op_iwmmxt_set_cup();
1893 tmp
= load_reg(s
, rd
);
1894 iwmmxt_store_creg(wrd
, tmp
);
1900 case 0x100: /* WXOR */
1901 wrd
= (insn
>> 12) & 0xf;
1902 rd0
= (insn
>> 0) & 0xf;
1903 rd1
= (insn
>> 16) & 0xf;
1904 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1905 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1906 gen_op_iwmmxt_setpsr_nz();
1907 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1908 gen_op_iwmmxt_set_mup();
1909 gen_op_iwmmxt_set_cup();
1911 case 0x111: /* TMRC */
1914 rd
= (insn
>> 12) & 0xf;
1915 wrd
= (insn
>> 16) & 0xf;
1916 tmp
= iwmmxt_load_creg(wrd
);
1917 store_reg(s
, rd
, tmp
);
1919 case 0x300: /* WANDN */
1920 wrd
= (insn
>> 12) & 0xf;
1921 rd0
= (insn
>> 0) & 0xf;
1922 rd1
= (insn
>> 16) & 0xf;
1923 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1924 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1925 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1926 gen_op_iwmmxt_setpsr_nz();
1927 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1928 gen_op_iwmmxt_set_mup();
1929 gen_op_iwmmxt_set_cup();
1931 case 0x200: /* WAND */
1932 wrd
= (insn
>> 12) & 0xf;
1933 rd0
= (insn
>> 0) & 0xf;
1934 rd1
= (insn
>> 16) & 0xf;
1935 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1936 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1937 gen_op_iwmmxt_setpsr_nz();
1938 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1939 gen_op_iwmmxt_set_mup();
1940 gen_op_iwmmxt_set_cup();
1942 case 0x810: case 0xa10: /* WMADD */
1943 wrd
= (insn
>> 12) & 0xf;
1944 rd0
= (insn
>> 0) & 0xf;
1945 rd1
= (insn
>> 16) & 0xf;
1946 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1947 if (insn
& (1 << 21))
1948 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1950 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1951 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1952 gen_op_iwmmxt_set_mup();
1954 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1955 wrd
= (insn
>> 12) & 0xf;
1956 rd0
= (insn
>> 16) & 0xf;
1957 rd1
= (insn
>> 0) & 0xf;
1958 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1959 switch ((insn
>> 22) & 3) {
1961 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1964 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1967 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1972 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1973 gen_op_iwmmxt_set_mup();
1974 gen_op_iwmmxt_set_cup();
1976 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1977 wrd
= (insn
>> 12) & 0xf;
1978 rd0
= (insn
>> 16) & 0xf;
1979 rd1
= (insn
>> 0) & 0xf;
1980 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1981 switch ((insn
>> 22) & 3) {
1983 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1986 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1989 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1994 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1995 gen_op_iwmmxt_set_mup();
1996 gen_op_iwmmxt_set_cup();
1998 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1999 wrd
= (insn
>> 12) & 0xf;
2000 rd0
= (insn
>> 16) & 0xf;
2001 rd1
= (insn
>> 0) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2003 if (insn
& (1 << 22))
2004 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2006 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2007 if (!(insn
& (1 << 20)))
2008 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2009 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2010 gen_op_iwmmxt_set_mup();
2012 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2013 wrd
= (insn
>> 12) & 0xf;
2014 rd0
= (insn
>> 16) & 0xf;
2015 rd1
= (insn
>> 0) & 0xf;
2016 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2017 if (insn
& (1 << 21)) {
2018 if (insn
& (1 << 20))
2019 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2021 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2023 if (insn
& (1 << 20))
2024 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2026 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2028 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2029 gen_op_iwmmxt_set_mup();
2031 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2032 wrd
= (insn
>> 12) & 0xf;
2033 rd0
= (insn
>> 16) & 0xf;
2034 rd1
= (insn
>> 0) & 0xf;
2035 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2036 if (insn
& (1 << 21))
2037 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2039 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2040 if (!(insn
& (1 << 20))) {
2041 iwmmxt_load_reg(cpu_V1
, wrd
);
2042 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2044 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2045 gen_op_iwmmxt_set_mup();
2047 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2048 wrd
= (insn
>> 12) & 0xf;
2049 rd0
= (insn
>> 16) & 0xf;
2050 rd1
= (insn
>> 0) & 0xf;
2051 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2052 switch ((insn
>> 22) & 3) {
2054 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2057 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2060 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2065 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2066 gen_op_iwmmxt_set_mup();
2067 gen_op_iwmmxt_set_cup();
2069 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2070 wrd
= (insn
>> 12) & 0xf;
2071 rd0
= (insn
>> 16) & 0xf;
2072 rd1
= (insn
>> 0) & 0xf;
2073 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2074 if (insn
& (1 << 22)) {
2075 if (insn
& (1 << 20))
2076 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2078 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2080 if (insn
& (1 << 20))
2081 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2083 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2085 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2086 gen_op_iwmmxt_set_mup();
2087 gen_op_iwmmxt_set_cup();
2089 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2090 wrd
= (insn
>> 12) & 0xf;
2091 rd0
= (insn
>> 16) & 0xf;
2092 rd1
= (insn
>> 0) & 0xf;
2093 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2094 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2095 tcg_gen_andi_i32(tmp
, tmp
, 7);
2096 iwmmxt_load_reg(cpu_V1
, rd1
);
2097 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2098 tcg_temp_free_i32(tmp
);
2099 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2100 gen_op_iwmmxt_set_mup();
2102 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2103 if (((insn
>> 6) & 3) == 3)
2105 rd
= (insn
>> 12) & 0xf;
2106 wrd
= (insn
>> 16) & 0xf;
2107 tmp
= load_reg(s
, rd
);
2108 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2109 switch ((insn
>> 6) & 3) {
2111 tmp2
= tcg_const_i32(0xff);
2112 tmp3
= tcg_const_i32((insn
& 7) << 3);
2115 tmp2
= tcg_const_i32(0xffff);
2116 tmp3
= tcg_const_i32((insn
& 3) << 4);
2119 tmp2
= tcg_const_i32(0xffffffff);
2120 tmp3
= tcg_const_i32((insn
& 1) << 5);
2123 TCGV_UNUSED_I32(tmp2
);
2124 TCGV_UNUSED_I32(tmp3
);
2126 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2127 tcg_temp_free_i32(tmp3
);
2128 tcg_temp_free_i32(tmp2
);
2129 tcg_temp_free_i32(tmp
);
2130 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2131 gen_op_iwmmxt_set_mup();
2133 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2134 rd
= (insn
>> 12) & 0xf;
2135 wrd
= (insn
>> 16) & 0xf;
2136 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2138 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2139 tmp
= tcg_temp_new_i32();
2140 switch ((insn
>> 22) & 3) {
2142 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2143 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2145 tcg_gen_ext8s_i32(tmp
, tmp
);
2147 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2151 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2152 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2154 tcg_gen_ext16s_i32(tmp
, tmp
);
2156 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2160 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2161 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2164 store_reg(s
, rd
, tmp
);
2166 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2167 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2169 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2170 switch ((insn
>> 22) & 3) {
2172 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2175 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2178 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2181 tcg_gen_shli_i32(tmp
, tmp
, 28);
2183 tcg_temp_free_i32(tmp
);
2185 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2186 if (((insn
>> 6) & 3) == 3)
2188 rd
= (insn
>> 12) & 0xf;
2189 wrd
= (insn
>> 16) & 0xf;
2190 tmp
= load_reg(s
, rd
);
2191 switch ((insn
>> 6) & 3) {
2193 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2196 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2199 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2202 tcg_temp_free_i32(tmp
);
2203 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2204 gen_op_iwmmxt_set_mup();
2206 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2207 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2209 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2210 tmp2
= tcg_temp_new_i32();
2211 tcg_gen_mov_i32(tmp2
, tmp
);
2212 switch ((insn
>> 22) & 3) {
2214 for (i
= 0; i
< 7; i
++) {
2215 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2216 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2220 for (i
= 0; i
< 3; i
++) {
2221 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2222 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2226 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2227 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2231 tcg_temp_free_i32(tmp2
);
2232 tcg_temp_free_i32(tmp
);
2234 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2235 wrd
= (insn
>> 12) & 0xf;
2236 rd0
= (insn
>> 16) & 0xf;
2237 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2238 switch ((insn
>> 22) & 3) {
2240 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2243 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2246 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2251 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2252 gen_op_iwmmxt_set_mup();
2254 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2255 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2257 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2258 tmp2
= tcg_temp_new_i32();
2259 tcg_gen_mov_i32(tmp2
, tmp
);
2260 switch ((insn
>> 22) & 3) {
2262 for (i
= 0; i
< 7; i
++) {
2263 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2264 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2268 for (i
= 0; i
< 3; i
++) {
2269 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2270 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2274 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2275 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2279 tcg_temp_free_i32(tmp2
);
2280 tcg_temp_free_i32(tmp
);
2282 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2283 rd
= (insn
>> 12) & 0xf;
2284 rd0
= (insn
>> 16) & 0xf;
2285 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2287 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2288 tmp
= tcg_temp_new_i32();
2289 switch ((insn
>> 22) & 3) {
2291 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2294 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2297 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2300 store_reg(s
, rd
, tmp
);
2302 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2303 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2304 wrd
= (insn
>> 12) & 0xf;
2305 rd0
= (insn
>> 16) & 0xf;
2306 rd1
= (insn
>> 0) & 0xf;
2307 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2308 switch ((insn
>> 22) & 3) {
2310 if (insn
& (1 << 21))
2311 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2313 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2316 if (insn
& (1 << 21))
2317 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2319 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2322 if (insn
& (1 << 21))
2323 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2325 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2330 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2331 gen_op_iwmmxt_set_mup();
2332 gen_op_iwmmxt_set_cup();
2334 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2335 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2336 wrd
= (insn
>> 12) & 0xf;
2337 rd0
= (insn
>> 16) & 0xf;
2338 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2339 switch ((insn
>> 22) & 3) {
2341 if (insn
& (1 << 21))
2342 gen_op_iwmmxt_unpacklsb_M0();
2344 gen_op_iwmmxt_unpacklub_M0();
2347 if (insn
& (1 << 21))
2348 gen_op_iwmmxt_unpacklsw_M0();
2350 gen_op_iwmmxt_unpackluw_M0();
2353 if (insn
& (1 << 21))
2354 gen_op_iwmmxt_unpacklsl_M0();
2356 gen_op_iwmmxt_unpacklul_M0();
2361 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2362 gen_op_iwmmxt_set_mup();
2363 gen_op_iwmmxt_set_cup();
2365 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2366 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2367 wrd
= (insn
>> 12) & 0xf;
2368 rd0
= (insn
>> 16) & 0xf;
2369 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2370 switch ((insn
>> 22) & 3) {
2372 if (insn
& (1 << 21))
2373 gen_op_iwmmxt_unpackhsb_M0();
2375 gen_op_iwmmxt_unpackhub_M0();
2378 if (insn
& (1 << 21))
2379 gen_op_iwmmxt_unpackhsw_M0();
2381 gen_op_iwmmxt_unpackhuw_M0();
2384 if (insn
& (1 << 21))
2385 gen_op_iwmmxt_unpackhsl_M0();
2387 gen_op_iwmmxt_unpackhul_M0();
2392 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2393 gen_op_iwmmxt_set_mup();
2394 gen_op_iwmmxt_set_cup();
2396 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2397 case 0x214: case 0x614: case 0xa14: case 0xe14:
2398 if (((insn
>> 22) & 3) == 0)
2400 wrd
= (insn
>> 12) & 0xf;
2401 rd0
= (insn
>> 16) & 0xf;
2402 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2403 tmp
= tcg_temp_new_i32();
2404 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2405 tcg_temp_free_i32(tmp
);
2408 switch ((insn
>> 22) & 3) {
2410 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2413 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2416 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2419 tcg_temp_free_i32(tmp
);
2420 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2421 gen_op_iwmmxt_set_mup();
2422 gen_op_iwmmxt_set_cup();
2424 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2425 case 0x014: case 0x414: case 0x814: case 0xc14:
2426 if (((insn
>> 22) & 3) == 0)
2428 wrd
= (insn
>> 12) & 0xf;
2429 rd0
= (insn
>> 16) & 0xf;
2430 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2431 tmp
= tcg_temp_new_i32();
2432 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2433 tcg_temp_free_i32(tmp
);
2436 switch ((insn
>> 22) & 3) {
2438 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2441 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2444 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2447 tcg_temp_free_i32(tmp
);
2448 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2449 gen_op_iwmmxt_set_mup();
2450 gen_op_iwmmxt_set_cup();
2452 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2453 case 0x114: case 0x514: case 0x914: case 0xd14:
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_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2469 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2472 gen_helper_iwmmxt_sllq(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 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2481 case 0x314: case 0x714: case 0xb14: case 0xf14:
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 switch ((insn
>> 22) & 3) {
2490 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2491 tcg_temp_free_i32(tmp
);
2494 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2497 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2498 tcg_temp_free_i32(tmp
);
2501 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2504 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2505 tcg_temp_free_i32(tmp
);
2508 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2511 tcg_temp_free_i32(tmp
);
2512 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2513 gen_op_iwmmxt_set_mup();
2514 gen_op_iwmmxt_set_cup();
2516 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2517 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2518 wrd
= (insn
>> 12) & 0xf;
2519 rd0
= (insn
>> 16) & 0xf;
2520 rd1
= (insn
>> 0) & 0xf;
2521 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2522 switch ((insn
>> 22) & 3) {
2524 if (insn
& (1 << 21))
2525 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2527 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2530 if (insn
& (1 << 21))
2531 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2533 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2536 if (insn
& (1 << 21))
2537 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2539 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2544 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2545 gen_op_iwmmxt_set_mup();
2547 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2548 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2549 wrd
= (insn
>> 12) & 0xf;
2550 rd0
= (insn
>> 16) & 0xf;
2551 rd1
= (insn
>> 0) & 0xf;
2552 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2553 switch ((insn
>> 22) & 3) {
2555 if (insn
& (1 << 21))
2556 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2558 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2561 if (insn
& (1 << 21))
2562 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2564 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2567 if (insn
& (1 << 21))
2568 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2570 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2575 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2576 gen_op_iwmmxt_set_mup();
2578 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2579 case 0x402: case 0x502: case 0x602: case 0x702:
2580 wrd
= (insn
>> 12) & 0xf;
2581 rd0
= (insn
>> 16) & 0xf;
2582 rd1
= (insn
>> 0) & 0xf;
2583 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2584 tmp
= tcg_const_i32((insn
>> 20) & 3);
2585 iwmmxt_load_reg(cpu_V1
, rd1
);
2586 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2587 tcg_temp_free_i32(tmp
);
2588 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2589 gen_op_iwmmxt_set_mup();
2591 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2592 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2593 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2594 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2595 wrd
= (insn
>> 12) & 0xf;
2596 rd0
= (insn
>> 16) & 0xf;
2597 rd1
= (insn
>> 0) & 0xf;
2598 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2599 switch ((insn
>> 20) & 0xf) {
2601 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2604 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2607 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2610 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2613 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2616 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2619 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2622 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2625 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2630 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2631 gen_op_iwmmxt_set_mup();
2632 gen_op_iwmmxt_set_cup();
2634 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2635 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2636 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2637 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2638 wrd
= (insn
>> 12) & 0xf;
2639 rd0
= (insn
>> 16) & 0xf;
2640 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2641 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2642 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2643 tcg_temp_free_i32(tmp
);
2644 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2645 gen_op_iwmmxt_set_mup();
2646 gen_op_iwmmxt_set_cup();
2648 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2649 case 0x418: case 0x518: case 0x618: case 0x718:
2650 case 0x818: case 0x918: case 0xa18: case 0xb18:
2651 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2652 wrd
= (insn
>> 12) & 0xf;
2653 rd0
= (insn
>> 16) & 0xf;
2654 rd1
= (insn
>> 0) & 0xf;
2655 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2656 switch ((insn
>> 20) & 0xf) {
2658 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2661 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2664 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2667 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2670 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2673 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2676 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2679 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2682 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2687 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2688 gen_op_iwmmxt_set_mup();
2689 gen_op_iwmmxt_set_cup();
2691 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2692 case 0x408: case 0x508: case 0x608: case 0x708:
2693 case 0x808: case 0x908: case 0xa08: case 0xb08:
2694 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2695 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2697 wrd
= (insn
>> 12) & 0xf;
2698 rd0
= (insn
>> 16) & 0xf;
2699 rd1
= (insn
>> 0) & 0xf;
2700 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2701 switch ((insn
>> 22) & 3) {
2703 if (insn
& (1 << 21))
2704 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2706 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2709 if (insn
& (1 << 21))
2710 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2712 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2715 if (insn
& (1 << 21))
2716 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2718 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2721 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2722 gen_op_iwmmxt_set_mup();
2723 gen_op_iwmmxt_set_cup();
2725 case 0x201: case 0x203: case 0x205: case 0x207:
2726 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2727 case 0x211: case 0x213: case 0x215: case 0x217:
2728 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2729 wrd
= (insn
>> 5) & 0xf;
2730 rd0
= (insn
>> 12) & 0xf;
2731 rd1
= (insn
>> 0) & 0xf;
2732 if (rd0
== 0xf || rd1
== 0xf)
2734 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2735 tmp
= load_reg(s
, rd0
);
2736 tmp2
= load_reg(s
, rd1
);
2737 switch ((insn
>> 16) & 0xf) {
2738 case 0x0: /* TMIA */
2739 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2741 case 0x8: /* TMIAPH */
2742 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2744 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2745 if (insn
& (1 << 16))
2746 tcg_gen_shri_i32(tmp
, tmp
, 16);
2747 if (insn
& (1 << 17))
2748 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2749 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2752 tcg_temp_free_i32(tmp2
);
2753 tcg_temp_free_i32(tmp
);
2756 tcg_temp_free_i32(tmp2
);
2757 tcg_temp_free_i32(tmp
);
2758 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2759 gen_op_iwmmxt_set_mup();
2768 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2769 (ie. an undefined instruction). */
2770 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2772 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2775 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2776 /* Multiply with Internal Accumulate Format */
2777 rd0
= (insn
>> 12) & 0xf;
2779 acc
= (insn
>> 5) & 7;
2784 tmp
= load_reg(s
, rd0
);
2785 tmp2
= load_reg(s
, rd1
);
2786 switch ((insn
>> 16) & 0xf) {
2788 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2790 case 0x8: /* MIAPH */
2791 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2793 case 0xc: /* MIABB */
2794 case 0xd: /* MIABT */
2795 case 0xe: /* MIATB */
2796 case 0xf: /* MIATT */
2797 if (insn
& (1 << 16))
2798 tcg_gen_shri_i32(tmp
, tmp
, 16);
2799 if (insn
& (1 << 17))
2800 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2801 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2806 tcg_temp_free_i32(tmp2
);
2807 tcg_temp_free_i32(tmp
);
2809 gen_op_iwmmxt_movq_wRn_M0(acc
);
2813 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2814 /* Internal Accumulator Access Format */
2815 rdhi
= (insn
>> 16) & 0xf;
2816 rdlo
= (insn
>> 12) & 0xf;
2822 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2823 iwmmxt_load_reg(cpu_V0
, acc
);
2824 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2825 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2826 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2827 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2829 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2830 iwmmxt_store_reg(cpu_V0
, acc
);
2838 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2839 #define VFP_SREG(insn, bigbit, smallbit) \
2840 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2841 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2842 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2843 reg = (((insn) >> (bigbit)) & 0x0f) \
2844 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2846 if (insn & (1 << (smallbit))) \
2848 reg = ((insn) >> (bigbit)) & 0x0f; \
2851 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2852 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2853 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2854 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2855 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2856 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2858 /* Move between integer and VFP cores. */
2859 static TCGv_i32
gen_vfp_mrs(void)
2861 TCGv_i32 tmp
= tcg_temp_new_i32();
2862 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2866 static void gen_vfp_msr(TCGv_i32 tmp
)
2868 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2869 tcg_temp_free_i32(tmp
);
2872 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2874 TCGv_i32 tmp
= tcg_temp_new_i32();
2876 tcg_gen_shri_i32(var
, var
, shift
);
2877 tcg_gen_ext8u_i32(var
, var
);
2878 tcg_gen_shli_i32(tmp
, var
, 8);
2879 tcg_gen_or_i32(var
, var
, tmp
);
2880 tcg_gen_shli_i32(tmp
, var
, 16);
2881 tcg_gen_or_i32(var
, var
, tmp
);
2882 tcg_temp_free_i32(tmp
);
2885 static void gen_neon_dup_low16(TCGv_i32 var
)
2887 TCGv_i32 tmp
= tcg_temp_new_i32();
2888 tcg_gen_ext16u_i32(var
, var
);
2889 tcg_gen_shli_i32(tmp
, var
, 16);
2890 tcg_gen_or_i32(var
, var
, tmp
);
2891 tcg_temp_free_i32(tmp
);
2894 static void gen_neon_dup_high16(TCGv_i32 var
)
2896 TCGv_i32 tmp
= tcg_temp_new_i32();
2897 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2898 tcg_gen_shri_i32(tmp
, var
, 16);
2899 tcg_gen_or_i32(var
, var
, tmp
);
2900 tcg_temp_free_i32(tmp
);
2903 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2905 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2906 TCGv_i32 tmp
= tcg_temp_new_i32();
2909 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2910 gen_neon_dup_u8(tmp
, 0);
2913 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2914 gen_neon_dup_low16(tmp
);
2917 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2919 default: /* Avoid compiler warnings. */
2925 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2928 uint32_t cc
= extract32(insn
, 20, 2);
2931 TCGv_i64 frn
, frm
, dest
;
2932 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2934 zero
= tcg_const_i64(0);
2936 frn
= tcg_temp_new_i64();
2937 frm
= tcg_temp_new_i64();
2938 dest
= tcg_temp_new_i64();
2940 zf
= tcg_temp_new_i64();
2941 nf
= tcg_temp_new_i64();
2942 vf
= tcg_temp_new_i64();
2944 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2945 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2946 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2948 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2949 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2952 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2956 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2959 case 2: /* ge: N == V -> N ^ V == 0 */
2960 tmp
= tcg_temp_new_i64();
2961 tcg_gen_xor_i64(tmp
, vf
, nf
);
2962 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2964 tcg_temp_free_i64(tmp
);
2966 case 3: /* gt: !Z && N == V */
2967 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2969 tmp
= tcg_temp_new_i64();
2970 tcg_gen_xor_i64(tmp
, vf
, nf
);
2971 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2973 tcg_temp_free_i64(tmp
);
2976 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2977 tcg_temp_free_i64(frn
);
2978 tcg_temp_free_i64(frm
);
2979 tcg_temp_free_i64(dest
);
2981 tcg_temp_free_i64(zf
);
2982 tcg_temp_free_i64(nf
);
2983 tcg_temp_free_i64(vf
);
2985 tcg_temp_free_i64(zero
);
2987 TCGv_i32 frn
, frm
, dest
;
2990 zero
= tcg_const_i32(0);
2992 frn
= tcg_temp_new_i32();
2993 frm
= tcg_temp_new_i32();
2994 dest
= tcg_temp_new_i32();
2995 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2996 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2999 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
3003 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
3006 case 2: /* ge: N == V -> N ^ V == 0 */
3007 tmp
= tcg_temp_new_i32();
3008 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3009 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3011 tcg_temp_free_i32(tmp
);
3013 case 3: /* gt: !Z && N == V */
3014 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
3016 tmp
= tcg_temp_new_i32();
3017 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3018 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3020 tcg_temp_free_i32(tmp
);
3023 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3024 tcg_temp_free_i32(frn
);
3025 tcg_temp_free_i32(frm
);
3026 tcg_temp_free_i32(dest
);
3028 tcg_temp_free_i32(zero
);
3034 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
3035 uint32_t rm
, uint32_t dp
)
3037 uint32_t vmin
= extract32(insn
, 6, 1);
3038 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3041 TCGv_i64 frn
, frm
, dest
;
3043 frn
= tcg_temp_new_i64();
3044 frm
= tcg_temp_new_i64();
3045 dest
= tcg_temp_new_i64();
3047 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3048 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3050 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
3052 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
3054 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3055 tcg_temp_free_i64(frn
);
3056 tcg_temp_free_i64(frm
);
3057 tcg_temp_free_i64(dest
);
3059 TCGv_i32 frn
, frm
, dest
;
3061 frn
= tcg_temp_new_i32();
3062 frm
= tcg_temp_new_i32();
3063 dest
= tcg_temp_new_i32();
3065 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3066 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3068 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
3070 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
3072 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3073 tcg_temp_free_i32(frn
);
3074 tcg_temp_free_i32(frm
);
3075 tcg_temp_free_i32(dest
);
3078 tcg_temp_free_ptr(fpst
);
3082 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3085 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3088 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3089 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3094 tcg_op
= tcg_temp_new_i64();
3095 tcg_res
= tcg_temp_new_i64();
3096 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3097 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
3098 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3099 tcg_temp_free_i64(tcg_op
);
3100 tcg_temp_free_i64(tcg_res
);
3104 tcg_op
= tcg_temp_new_i32();
3105 tcg_res
= tcg_temp_new_i32();
3106 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3107 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
3108 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3109 tcg_temp_free_i32(tcg_op
);
3110 tcg_temp_free_i32(tcg_res
);
3113 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3114 tcg_temp_free_i32(tcg_rmode
);
3116 tcg_temp_free_ptr(fpst
);
3120 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3123 bool is_signed
= extract32(insn
, 7, 1);
3124 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3125 TCGv_i32 tcg_rmode
, tcg_shift
;
3127 tcg_shift
= tcg_const_i32(0);
3129 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3130 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3133 TCGv_i64 tcg_double
, tcg_res
;
3135 /* Rd is encoded as a single precision register even when the source
3136 * is double precision.
3138 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3139 tcg_double
= tcg_temp_new_i64();
3140 tcg_res
= tcg_temp_new_i64();
3141 tcg_tmp
= tcg_temp_new_i32();
3142 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3144 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3146 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3148 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3149 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3150 tcg_temp_free_i32(tcg_tmp
);
3151 tcg_temp_free_i64(tcg_res
);
3152 tcg_temp_free_i64(tcg_double
);
3154 TCGv_i32 tcg_single
, tcg_res
;
3155 tcg_single
= tcg_temp_new_i32();
3156 tcg_res
= tcg_temp_new_i32();
3157 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3159 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3161 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3163 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3164 tcg_temp_free_i32(tcg_res
);
3165 tcg_temp_free_i32(tcg_single
);
3168 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3169 tcg_temp_free_i32(tcg_rmode
);
3171 tcg_temp_free_i32(tcg_shift
);
3173 tcg_temp_free_ptr(fpst
);
3178 /* Table for converting the most common AArch32 encoding of
3179 * rounding mode to arm_fprounding order (which matches the
3180 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3182 static const uint8_t fp_decode_rm
[] = {
3189 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3191 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3193 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3198 VFP_DREG_D(rd
, insn
);
3199 VFP_DREG_N(rn
, insn
);
3200 VFP_DREG_M(rm
, insn
);
3202 rd
= VFP_SREG_D(insn
);
3203 rn
= VFP_SREG_N(insn
);
3204 rm
= VFP_SREG_M(insn
);
3207 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3208 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3209 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3210 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3211 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3212 /* VRINTA, VRINTN, VRINTP, VRINTM */
3213 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3214 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3215 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3216 /* VCVTA, VCVTN, VCVTP, VCVTM */
3217 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3218 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3223 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3224 (ie. an undefined instruction). */
3225 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3227 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3233 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3237 /* FIXME: this access check should not take precedence over UNDEF
3238 * for invalid encodings; we will generate incorrect syndrome information
3239 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3241 if (s
->fp_excp_el
) {
3242 gen_exception_insn(s
, 4, EXCP_UDEF
,
3243 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3247 if (!s
->vfp_enabled
) {
3248 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3249 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3251 rn
= (insn
>> 16) & 0xf;
3252 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3253 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3258 if (extract32(insn
, 28, 4) == 0xf) {
3259 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3260 * only used in v8 and above.
3262 return disas_vfp_v8_insn(s
, insn
);
3265 dp
= ((insn
& 0xf00) == 0xb00);
3266 switch ((insn
>> 24) & 0xf) {
3268 if (insn
& (1 << 4)) {
3269 /* single register transfer */
3270 rd
= (insn
>> 12) & 0xf;
3275 VFP_DREG_N(rn
, insn
);
3278 if (insn
& 0x00c00060
3279 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3283 pass
= (insn
>> 21) & 1;
3284 if (insn
& (1 << 22)) {
3286 offset
= ((insn
>> 5) & 3) * 8;
3287 } else if (insn
& (1 << 5)) {
3289 offset
= (insn
& (1 << 6)) ? 16 : 0;
3294 if (insn
& ARM_CP_RW_BIT
) {
3296 tmp
= neon_load_reg(rn
, pass
);
3300 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3301 if (insn
& (1 << 23))
3307 if (insn
& (1 << 23)) {
3309 tcg_gen_shri_i32(tmp
, tmp
, 16);
3315 tcg_gen_sari_i32(tmp
, tmp
, 16);
3324 store_reg(s
, rd
, tmp
);
3327 tmp
= load_reg(s
, rd
);
3328 if (insn
& (1 << 23)) {
3331 gen_neon_dup_u8(tmp
, 0);
3332 } else if (size
== 1) {
3333 gen_neon_dup_low16(tmp
);
3335 for (n
= 0; n
<= pass
* 2; n
++) {
3336 tmp2
= tcg_temp_new_i32();
3337 tcg_gen_mov_i32(tmp2
, tmp
);
3338 neon_store_reg(rn
, n
, tmp2
);
3340 neon_store_reg(rn
, n
, tmp
);
3345 tmp2
= neon_load_reg(rn
, pass
);
3346 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3347 tcg_temp_free_i32(tmp2
);
3350 tmp2
= neon_load_reg(rn
, pass
);
3351 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3352 tcg_temp_free_i32(tmp2
);
3357 neon_store_reg(rn
, pass
, tmp
);
3361 if ((insn
& 0x6f) != 0x00)
3363 rn
= VFP_SREG_N(insn
);
3364 if (insn
& ARM_CP_RW_BIT
) {
3366 if (insn
& (1 << 21)) {
3367 /* system register */
3372 /* VFP2 allows access to FSID from userspace.
3373 VFP3 restricts all id registers to privileged
3376 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3379 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3384 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3386 case ARM_VFP_FPINST
:
3387 case ARM_VFP_FPINST2
:
3388 /* Not present in VFP3. */
3390 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3393 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3397 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3398 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3400 tmp
= tcg_temp_new_i32();
3401 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3405 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3412 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3415 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3421 gen_mov_F0_vreg(0, rn
);
3422 tmp
= gen_vfp_mrs();
3425 /* Set the 4 flag bits in the CPSR. */
3427 tcg_temp_free_i32(tmp
);
3429 store_reg(s
, rd
, tmp
);
3433 if (insn
& (1 << 21)) {
3435 /* system register */
3440 /* Writes are ignored. */
3443 tmp
= load_reg(s
, rd
);
3444 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3445 tcg_temp_free_i32(tmp
);
3451 /* TODO: VFP subarchitecture support.
3452 * For now, keep the EN bit only */
3453 tmp
= load_reg(s
, rd
);
3454 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3455 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3458 case ARM_VFP_FPINST
:
3459 case ARM_VFP_FPINST2
:
3463 tmp
= load_reg(s
, rd
);
3464 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3470 tmp
= load_reg(s
, rd
);
3472 gen_mov_vreg_F0(0, rn
);
3477 /* data processing */
3478 /* The opcode is in bits 23, 21, 20 and 6. */
3479 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3483 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3485 /* rn is register number */
3486 VFP_DREG_N(rn
, insn
);
3489 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3490 ((rn
& 0x1e) == 0x6))) {
3491 /* Integer or single/half precision destination. */
3492 rd
= VFP_SREG_D(insn
);
3494 VFP_DREG_D(rd
, insn
);
3497 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3498 ((rn
& 0x1e) == 0x4))) {
3499 /* VCVT from int or half precision is always from S reg
3500 * regardless of dp bit. VCVT with immediate frac_bits
3501 * has same format as SREG_M.
3503 rm
= VFP_SREG_M(insn
);
3505 VFP_DREG_M(rm
, insn
);
3508 rn
= VFP_SREG_N(insn
);
3509 if (op
== 15 && rn
== 15) {
3510 /* Double precision destination. */
3511 VFP_DREG_D(rd
, insn
);
3513 rd
= VFP_SREG_D(insn
);
3515 /* NB that we implicitly rely on the encoding for the frac_bits
3516 * in VCVT of fixed to float being the same as that of an SREG_M
3518 rm
= VFP_SREG_M(insn
);
3521 veclen
= s
->vec_len
;
3522 if (op
== 15 && rn
> 3)
3525 /* Shut up compiler warnings. */
3536 /* Figure out what type of vector operation this is. */
3537 if ((rd
& bank_mask
) == 0) {
3542 delta_d
= (s
->vec_stride
>> 1) + 1;
3544 delta_d
= s
->vec_stride
+ 1;
3546 if ((rm
& bank_mask
) == 0) {
3547 /* mixed scalar/vector */
3556 /* Load the initial operands. */
3561 /* Integer source */
3562 gen_mov_F0_vreg(0, rm
);
3567 gen_mov_F0_vreg(dp
, rd
);
3568 gen_mov_F1_vreg(dp
, rm
);
3572 /* Compare with zero */
3573 gen_mov_F0_vreg(dp
, rd
);
3584 /* Source and destination the same. */
3585 gen_mov_F0_vreg(dp
, rd
);
3591 /* VCVTB, VCVTT: only present with the halfprec extension
3592 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3593 * (we choose to UNDEF)
3595 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3596 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3599 if (!extract32(rn
, 1, 1)) {
3600 /* Half precision source. */
3601 gen_mov_F0_vreg(0, rm
);
3604 /* Otherwise fall through */
3606 /* One source operand. */
3607 gen_mov_F0_vreg(dp
, rm
);
3611 /* Two source operands. */
3612 gen_mov_F0_vreg(dp
, rn
);
3613 gen_mov_F1_vreg(dp
, rm
);
3617 /* Perform the calculation. */
3619 case 0: /* VMLA: fd + (fn * fm) */
3620 /* Note that order of inputs to the add matters for NaNs */
3622 gen_mov_F0_vreg(dp
, rd
);
3625 case 1: /* VMLS: fd + -(fn * fm) */
3628 gen_mov_F0_vreg(dp
, rd
);
3631 case 2: /* VNMLS: -fd + (fn * fm) */
3632 /* Note that it isn't valid to replace (-A + B) with (B - A)
3633 * or similar plausible looking simplifications
3634 * because this will give wrong results for NaNs.
3637 gen_mov_F0_vreg(dp
, rd
);
3641 case 3: /* VNMLA: -fd + -(fn * fm) */
3644 gen_mov_F0_vreg(dp
, rd
);
3648 case 4: /* mul: fn * fm */
3651 case 5: /* nmul: -(fn * fm) */
3655 case 6: /* add: fn + fm */
3658 case 7: /* sub: fn - fm */
3661 case 8: /* div: fn / fm */
3664 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3665 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3666 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3667 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3668 /* These are fused multiply-add, and must be done as one
3669 * floating point operation with no rounding between the
3670 * multiplication and addition steps.
3671 * NB that doing the negations here as separate steps is
3672 * correct : an input NaN should come out with its sign bit
3673 * flipped if it is a negated-input.
3675 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3683 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3685 frd
= tcg_temp_new_i64();
3686 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3689 gen_helper_vfp_negd(frd
, frd
);
3691 fpst
= get_fpstatus_ptr(0);
3692 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3693 cpu_F1d
, frd
, fpst
);
3694 tcg_temp_free_ptr(fpst
);
3695 tcg_temp_free_i64(frd
);
3701 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3703 frd
= tcg_temp_new_i32();
3704 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3706 gen_helper_vfp_negs(frd
, frd
);
3708 fpst
= get_fpstatus_ptr(0);
3709 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3710 cpu_F1s
, frd
, fpst
);
3711 tcg_temp_free_ptr(fpst
);
3712 tcg_temp_free_i32(frd
);
3715 case 14: /* fconst */
3716 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3720 n
= (insn
<< 12) & 0x80000000;
3721 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3728 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3735 tcg_gen_movi_i32(cpu_F0s
, n
);
3738 case 15: /* extension space */
3752 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3753 tmp
= gen_vfp_mrs();
3754 tcg_gen_ext16u_i32(tmp
, tmp
);
3756 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3759 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3762 tcg_temp_free_i32(tmp
);
3764 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3765 tmp
= gen_vfp_mrs();
3766 tcg_gen_shri_i32(tmp
, tmp
, 16);
3768 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3771 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3774 tcg_temp_free_i32(tmp
);
3776 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3777 tmp
= tcg_temp_new_i32();
3779 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3782 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3785 gen_mov_F0_vreg(0, rd
);
3786 tmp2
= gen_vfp_mrs();
3787 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3788 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3789 tcg_temp_free_i32(tmp2
);
3792 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3793 tmp
= tcg_temp_new_i32();
3795 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3798 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3801 tcg_gen_shli_i32(tmp
, tmp
, 16);
3802 gen_mov_F0_vreg(0, rd
);
3803 tmp2
= gen_vfp_mrs();
3804 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3805 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3806 tcg_temp_free_i32(tmp2
);
3818 case 11: /* cmpez */
3822 case 12: /* vrintr */
3824 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3826 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3828 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3830 tcg_temp_free_ptr(fpst
);
3833 case 13: /* vrintz */
3835 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3837 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3838 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3840 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3842 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3844 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3845 tcg_temp_free_i32(tcg_rmode
);
3846 tcg_temp_free_ptr(fpst
);
3849 case 14: /* vrintx */
3851 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3853 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3855 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3857 tcg_temp_free_ptr(fpst
);
3860 case 15: /* single<->double conversion */
3862 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3864 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3866 case 16: /* fuito */
3867 gen_vfp_uito(dp
, 0);
3869 case 17: /* fsito */
3870 gen_vfp_sito(dp
, 0);
3872 case 20: /* fshto */
3873 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3876 gen_vfp_shto(dp
, 16 - rm
, 0);
3878 case 21: /* fslto */
3879 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3882 gen_vfp_slto(dp
, 32 - rm
, 0);
3884 case 22: /* fuhto */
3885 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3888 gen_vfp_uhto(dp
, 16 - rm
, 0);
3890 case 23: /* fulto */
3891 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3894 gen_vfp_ulto(dp
, 32 - rm
, 0);
3896 case 24: /* ftoui */
3897 gen_vfp_toui(dp
, 0);
3899 case 25: /* ftouiz */
3900 gen_vfp_touiz(dp
, 0);
3902 case 26: /* ftosi */
3903 gen_vfp_tosi(dp
, 0);
3905 case 27: /* ftosiz */
3906 gen_vfp_tosiz(dp
, 0);
3908 case 28: /* ftosh */
3909 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3912 gen_vfp_tosh(dp
, 16 - rm
, 0);
3914 case 29: /* ftosl */
3915 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3918 gen_vfp_tosl(dp
, 32 - rm
, 0);
3920 case 30: /* ftouh */
3921 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3924 gen_vfp_touh(dp
, 16 - rm
, 0);
3926 case 31: /* ftoul */
3927 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3930 gen_vfp_toul(dp
, 32 - rm
, 0);
3932 default: /* undefined */
3936 default: /* undefined */
3940 /* Write back the result. */
3941 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3942 /* Comparison, do nothing. */
3943 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3944 (rn
& 0x1e) == 0x6)) {
3945 /* VCVT double to int: always integer result.
3946 * VCVT double to half precision is always a single
3949 gen_mov_vreg_F0(0, rd
);
3950 } else if (op
== 15 && rn
== 15) {
3952 gen_mov_vreg_F0(!dp
, rd
);
3954 gen_mov_vreg_F0(dp
, rd
);
3957 /* break out of the loop if we have finished */
3961 if (op
== 15 && delta_m
== 0) {
3962 /* single source one-many */
3964 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3966 gen_mov_vreg_F0(dp
, rd
);
3970 /* Setup the next operands. */
3972 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3976 /* One source operand. */
3977 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3979 gen_mov_F0_vreg(dp
, rm
);
3981 /* Two source operands. */
3982 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3984 gen_mov_F0_vreg(dp
, rn
);
3986 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3988 gen_mov_F1_vreg(dp
, rm
);
3996 if ((insn
& 0x03e00000) == 0x00400000) {
3997 /* two-register transfer */
3998 rn
= (insn
>> 16) & 0xf;
3999 rd
= (insn
>> 12) & 0xf;
4001 VFP_DREG_M(rm
, insn
);
4003 rm
= VFP_SREG_M(insn
);
4006 if (insn
& ARM_CP_RW_BIT
) {
4009 gen_mov_F0_vreg(0, rm
* 2);
4010 tmp
= gen_vfp_mrs();
4011 store_reg(s
, rd
, tmp
);
4012 gen_mov_F0_vreg(0, rm
* 2 + 1);
4013 tmp
= gen_vfp_mrs();
4014 store_reg(s
, rn
, tmp
);
4016 gen_mov_F0_vreg(0, rm
);
4017 tmp
= gen_vfp_mrs();
4018 store_reg(s
, rd
, tmp
);
4019 gen_mov_F0_vreg(0, rm
+ 1);
4020 tmp
= gen_vfp_mrs();
4021 store_reg(s
, rn
, tmp
);
4026 tmp
= load_reg(s
, rd
);
4028 gen_mov_vreg_F0(0, rm
* 2);
4029 tmp
= load_reg(s
, rn
);
4031 gen_mov_vreg_F0(0, rm
* 2 + 1);
4033 tmp
= load_reg(s
, rd
);
4035 gen_mov_vreg_F0(0, rm
);
4036 tmp
= load_reg(s
, rn
);
4038 gen_mov_vreg_F0(0, rm
+ 1);
4043 rn
= (insn
>> 16) & 0xf;
4045 VFP_DREG_D(rd
, insn
);
4047 rd
= VFP_SREG_D(insn
);
4048 if ((insn
& 0x01200000) == 0x01000000) {
4049 /* Single load/store */
4050 offset
= (insn
& 0xff) << 2;
4051 if ((insn
& (1 << 23)) == 0)
4053 if (s
->thumb
&& rn
== 15) {
4054 /* This is actually UNPREDICTABLE */
4055 addr
= tcg_temp_new_i32();
4056 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4058 addr
= load_reg(s
, rn
);
4060 tcg_gen_addi_i32(addr
, addr
, offset
);
4061 if (insn
& (1 << 20)) {
4062 gen_vfp_ld(s
, dp
, addr
);
4063 gen_mov_vreg_F0(dp
, rd
);
4065 gen_mov_F0_vreg(dp
, rd
);
4066 gen_vfp_st(s
, dp
, addr
);
4068 tcg_temp_free_i32(addr
);
4070 /* load/store multiple */
4071 int w
= insn
& (1 << 21);
4073 n
= (insn
>> 1) & 0x7f;
4077 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
4078 /* P == U , W == 1 => UNDEF */
4081 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
4082 /* UNPREDICTABLE cases for bad immediates: we choose to
4083 * UNDEF to avoid generating huge numbers of TCG ops
4087 if (rn
== 15 && w
) {
4088 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4092 if (s
->thumb
&& rn
== 15) {
4093 /* This is actually UNPREDICTABLE */
4094 addr
= tcg_temp_new_i32();
4095 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4097 addr
= load_reg(s
, rn
);
4099 if (insn
& (1 << 24)) /* pre-decrement */
4100 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4106 for (i
= 0; i
< n
; i
++) {
4107 if (insn
& ARM_CP_RW_BIT
) {
4109 gen_vfp_ld(s
, dp
, addr
);
4110 gen_mov_vreg_F0(dp
, rd
+ i
);
4113 gen_mov_F0_vreg(dp
, rd
+ i
);
4114 gen_vfp_st(s
, dp
, addr
);
4116 tcg_gen_addi_i32(addr
, addr
, offset
);
4120 if (insn
& (1 << 24))
4121 offset
= -offset
* n
;
4122 else if (dp
&& (insn
& 1))
4128 tcg_gen_addi_i32(addr
, addr
, offset
);
4129 store_reg(s
, rn
, addr
);
4131 tcg_temp_free_i32(addr
);
4137 /* Should never happen. */
4143 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4145 #ifndef CONFIG_USER_ONLY
4146 return (s
->tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4147 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4153 static void gen_goto_ptr(void)
4155 TCGv addr
= tcg_temp_new();
4156 tcg_gen_extu_i32_tl(addr
, cpu_R
[15]);
4157 tcg_gen_lookup_and_goto_ptr(addr
);
4158 tcg_temp_free(addr
);
4161 /* This will end the TB but doesn't guarantee we'll return to
4162 * cpu_loop_exec. Any live exit_requests will be processed as we
4163 * enter the next TB.
4165 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4167 if (use_goto_tb(s
, dest
)) {
4169 gen_set_pc_im(s
, dest
);
4170 tcg_gen_exit_tb((uintptr_t)s
->tb
+ n
);
4172 gen_set_pc_im(s
, dest
);
4175 s
->is_jmp
= DISAS_TB_JUMP
;
4178 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4180 if (unlikely(is_singlestepping(s
))) {
4181 /* An indirect jump so that we still trigger the debug exception. */
4186 gen_goto_tb(s
, 0, dest
);
4190 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4193 tcg_gen_sari_i32(t0
, t0
, 16);
4197 tcg_gen_sari_i32(t1
, t1
, 16);
4200 tcg_gen_mul_i32(t0
, t0
, t1
);
4203 /* Return the mask of PSR bits set by a MSR instruction. */
4204 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4209 if (flags
& (1 << 0))
4211 if (flags
& (1 << 1))
4213 if (flags
& (1 << 2))
4215 if (flags
& (1 << 3))
4218 /* Mask out undefined bits. */
4219 mask
&= ~CPSR_RESERVED
;
4220 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4223 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4224 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4226 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4227 mask
&= ~(CPSR_E
| CPSR_GE
);
4229 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4232 /* Mask out execution state and reserved bits. */
4234 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4236 /* Mask out privileged bits. */
4242 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4243 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4247 /* ??? This is also undefined in system mode. */
4251 tmp
= load_cpu_field(spsr
);
4252 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4253 tcg_gen_andi_i32(t0
, t0
, mask
);
4254 tcg_gen_or_i32(tmp
, tmp
, t0
);
4255 store_cpu_field(tmp
, spsr
);
4257 gen_set_cpsr(t0
, mask
);
4259 tcg_temp_free_i32(t0
);
4264 /* Returns nonzero if access to the PSR is not permitted. */
4265 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4268 tmp
= tcg_temp_new_i32();
4269 tcg_gen_movi_i32(tmp
, val
);
4270 return gen_set_psr(s
, mask
, spsr
, tmp
);
4273 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4274 int *tgtmode
, int *regno
)
4276 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4277 * the target mode and register number, and identify the various
4278 * unpredictable cases.
4279 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4280 * + executed in user mode
4281 * + using R15 as the src/dest register
4282 * + accessing an unimplemented register
4283 * + accessing a register that's inaccessible at current PL/security state*
4284 * + accessing a register that you could access with a different insn
4285 * We choose to UNDEF in all these cases.
4286 * Since we don't know which of the various AArch32 modes we are in
4287 * we have to defer some checks to runtime.
4288 * Accesses to Monitor mode registers from Secure EL1 (which implies
4289 * that EL3 is AArch64) must trap to EL3.
4291 * If the access checks fail this function will emit code to take
4292 * an exception and return false. Otherwise it will return true,
4293 * and set *tgtmode and *regno appropriately.
4295 int exc_target
= default_exception_el(s
);
4297 /* These instructions are present only in ARMv8, or in ARMv7 with the
4298 * Virtualization Extensions.
4300 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4301 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4305 if (IS_USER(s
) || rn
== 15) {
4309 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4310 * of registers into (r, sysm).
4313 /* SPSRs for other modes */
4315 case 0xe: /* SPSR_fiq */
4316 *tgtmode
= ARM_CPU_MODE_FIQ
;
4318 case 0x10: /* SPSR_irq */
4319 *tgtmode
= ARM_CPU_MODE_IRQ
;
4321 case 0x12: /* SPSR_svc */
4322 *tgtmode
= ARM_CPU_MODE_SVC
;
4324 case 0x14: /* SPSR_abt */
4325 *tgtmode
= ARM_CPU_MODE_ABT
;
4327 case 0x16: /* SPSR_und */
4328 *tgtmode
= ARM_CPU_MODE_UND
;
4330 case 0x1c: /* SPSR_mon */
4331 *tgtmode
= ARM_CPU_MODE_MON
;
4333 case 0x1e: /* SPSR_hyp */
4334 *tgtmode
= ARM_CPU_MODE_HYP
;
4336 default: /* unallocated */
4339 /* We arbitrarily assign SPSR a register number of 16. */
4342 /* general purpose registers for other modes */
4344 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4345 *tgtmode
= ARM_CPU_MODE_USR
;
4348 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4349 *tgtmode
= ARM_CPU_MODE_FIQ
;
4352 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4353 *tgtmode
= ARM_CPU_MODE_IRQ
;
4354 *regno
= sysm
& 1 ? 13 : 14;
4356 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4357 *tgtmode
= ARM_CPU_MODE_SVC
;
4358 *regno
= sysm
& 1 ? 13 : 14;
4360 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4361 *tgtmode
= ARM_CPU_MODE_ABT
;
4362 *regno
= sysm
& 1 ? 13 : 14;
4364 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4365 *tgtmode
= ARM_CPU_MODE_UND
;
4366 *regno
= sysm
& 1 ? 13 : 14;
4368 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4369 *tgtmode
= ARM_CPU_MODE_MON
;
4370 *regno
= sysm
& 1 ? 13 : 14;
4372 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4373 *tgtmode
= ARM_CPU_MODE_HYP
;
4374 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4375 *regno
= sysm
& 1 ? 13 : 17;
4377 default: /* unallocated */
4382 /* Catch the 'accessing inaccessible register' cases we can detect
4383 * at translate time.
4386 case ARM_CPU_MODE_MON
:
4387 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4390 if (s
->current_el
== 1) {
4391 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4392 * then accesses to Mon registers trap to EL3
4398 case ARM_CPU_MODE_HYP
:
4399 /* Note that we can forbid accesses from EL2 here because they
4400 * must be from Hyp mode itself
4402 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4413 /* If we get here then some access check did not pass */
4414 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4418 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4420 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4421 int tgtmode
= 0, regno
= 0;
4423 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4427 /* Sync state because msr_banked() can raise exceptions */
4428 gen_set_condexec(s
);
4429 gen_set_pc_im(s
, s
->pc
- 4);
4430 tcg_reg
= load_reg(s
, rn
);
4431 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4432 tcg_regno
= tcg_const_i32(regno
);
4433 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4434 tcg_temp_free_i32(tcg_tgtmode
);
4435 tcg_temp_free_i32(tcg_regno
);
4436 tcg_temp_free_i32(tcg_reg
);
4437 s
->is_jmp
= DISAS_UPDATE
;
4440 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4442 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4443 int tgtmode
= 0, regno
= 0;
4445 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4449 /* Sync state because mrs_banked() can raise exceptions */
4450 gen_set_condexec(s
);
4451 gen_set_pc_im(s
, s
->pc
- 4);
4452 tcg_reg
= tcg_temp_new_i32();
4453 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4454 tcg_regno
= tcg_const_i32(regno
);
4455 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4456 tcg_temp_free_i32(tcg_tgtmode
);
4457 tcg_temp_free_i32(tcg_regno
);
4458 store_reg(s
, rn
, tcg_reg
);
4459 s
->is_jmp
= DISAS_UPDATE
;
4462 /* Store value to PC as for an exception return (ie don't
4463 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4464 * will do the masking based on the new value of the Thumb bit.
4466 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4468 tcg_gen_mov_i32(cpu_R
[15], pc
);
4469 tcg_temp_free_i32(pc
);
4472 /* Generate a v6 exception return. Marks both values as dead. */
4473 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4475 store_pc_exc_ret(s
, pc
);
4476 /* The cpsr_write_eret helper will mask the low bits of PC
4477 * appropriately depending on the new Thumb bit, so it must
4478 * be called after storing the new PC.
4480 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4481 tcg_temp_free_i32(cpsr
);
4482 s
->is_jmp
= DISAS_JUMP
;
4485 /* Generate an old-style exception return. Marks pc as dead. */
4486 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4488 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4492 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4493 * only call the helper when running single threaded TCG code to ensure
4494 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4495 * just skip this instruction. Currently the SEV/SEVL instructions
4496 * which are *one* of many ways to wake the CPU from WFE are not
4497 * implemented so we can't sleep like WFI does.
4499 static void gen_nop_hint(DisasContext
*s
, int val
)
4503 if (!parallel_cpus
) {
4504 gen_set_pc_im(s
, s
->pc
);
4505 s
->is_jmp
= DISAS_YIELD
;
4509 gen_set_pc_im(s
, s
->pc
);
4510 s
->is_jmp
= DISAS_WFI
;
4513 if (!parallel_cpus
) {
4514 gen_set_pc_im(s
, s
->pc
);
4515 s
->is_jmp
= DISAS_WFE
;
4520 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4526 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4528 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4531 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4532 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4533 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4538 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4541 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4542 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4543 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4548 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4549 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4550 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4551 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4552 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4554 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4555 switch ((size << 1) | u) { \
4557 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4560 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4563 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4566 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4569 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4572 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4574 default: return 1; \
4577 #define GEN_NEON_INTEGER_OP(name) do { \
4578 switch ((size << 1) | u) { \
4580 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4583 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4586 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4589 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4592 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4595 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4597 default: return 1; \
4600 static TCGv_i32
neon_load_scratch(int scratch
)
4602 TCGv_i32 tmp
= tcg_temp_new_i32();
4603 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4607 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4609 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4610 tcg_temp_free_i32(var
);
4613 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4617 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4619 gen_neon_dup_high16(tmp
);
4621 gen_neon_dup_low16(tmp
);
4624 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4629 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4632 if (!q
&& size
== 2) {
4635 tmp
= tcg_const_i32(rd
);
4636 tmp2
= tcg_const_i32(rm
);
4640 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4643 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4646 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4654 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4657 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4663 tcg_temp_free_i32(tmp
);
4664 tcg_temp_free_i32(tmp2
);
4668 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4671 if (!q
&& size
== 2) {
4674 tmp
= tcg_const_i32(rd
);
4675 tmp2
= tcg_const_i32(rm
);
4679 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4682 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4685 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4693 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4696 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4702 tcg_temp_free_i32(tmp
);
4703 tcg_temp_free_i32(tmp2
);
4707 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4711 rd
= tcg_temp_new_i32();
4712 tmp
= tcg_temp_new_i32();
4714 tcg_gen_shli_i32(rd
, t0
, 8);
4715 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4716 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4717 tcg_gen_or_i32(rd
, rd
, tmp
);
4719 tcg_gen_shri_i32(t1
, t1
, 8);
4720 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4721 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4722 tcg_gen_or_i32(t1
, t1
, tmp
);
4723 tcg_gen_mov_i32(t0
, rd
);
4725 tcg_temp_free_i32(tmp
);
4726 tcg_temp_free_i32(rd
);
4729 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4733 rd
= tcg_temp_new_i32();
4734 tmp
= tcg_temp_new_i32();
4736 tcg_gen_shli_i32(rd
, t0
, 16);
4737 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4738 tcg_gen_or_i32(rd
, rd
, tmp
);
4739 tcg_gen_shri_i32(t1
, t1
, 16);
4740 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4741 tcg_gen_or_i32(t1
, t1
, tmp
);
4742 tcg_gen_mov_i32(t0
, rd
);
4744 tcg_temp_free_i32(tmp
);
4745 tcg_temp_free_i32(rd
);
4753 } neon_ls_element_type
[11] = {
4767 /* Translate a NEON load/store element instruction. Return nonzero if the
4768 instruction is invalid. */
4769 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4788 /* FIXME: this access check should not take precedence over UNDEF
4789 * for invalid encodings; we will generate incorrect syndrome information
4790 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4792 if (s
->fp_excp_el
) {
4793 gen_exception_insn(s
, 4, EXCP_UDEF
,
4794 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4798 if (!s
->vfp_enabled
)
4800 VFP_DREG_D(rd
, insn
);
4801 rn
= (insn
>> 16) & 0xf;
4803 load
= (insn
& (1 << 21)) != 0;
4804 if ((insn
& (1 << 23)) == 0) {
4805 /* Load store all elements. */
4806 op
= (insn
>> 8) & 0xf;
4807 size
= (insn
>> 6) & 3;
4810 /* Catch UNDEF cases for bad values of align field */
4813 if (((insn
>> 5) & 1) == 1) {
4818 if (((insn
>> 4) & 3) == 3) {
4825 nregs
= neon_ls_element_type
[op
].nregs
;
4826 interleave
= neon_ls_element_type
[op
].interleave
;
4827 spacing
= neon_ls_element_type
[op
].spacing
;
4828 if (size
== 3 && (interleave
| spacing
) != 1)
4830 addr
= tcg_temp_new_i32();
4831 load_reg_var(s
, addr
, rn
);
4832 stride
= (1 << size
) * interleave
;
4833 for (reg
= 0; reg
< nregs
; reg
++) {
4834 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4835 load_reg_var(s
, addr
, rn
);
4836 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4837 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4838 load_reg_var(s
, addr
, rn
);
4839 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4842 tmp64
= tcg_temp_new_i64();
4844 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4845 neon_store_reg64(tmp64
, rd
);
4847 neon_load_reg64(tmp64
, rd
);
4848 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4850 tcg_temp_free_i64(tmp64
);
4851 tcg_gen_addi_i32(addr
, addr
, stride
);
4853 for (pass
= 0; pass
< 2; pass
++) {
4856 tmp
= tcg_temp_new_i32();
4857 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4858 neon_store_reg(rd
, pass
, tmp
);
4860 tmp
= neon_load_reg(rd
, pass
);
4861 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4862 tcg_temp_free_i32(tmp
);
4864 tcg_gen_addi_i32(addr
, addr
, stride
);
4865 } else if (size
== 1) {
4867 tmp
= tcg_temp_new_i32();
4868 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4869 tcg_gen_addi_i32(addr
, addr
, stride
);
4870 tmp2
= tcg_temp_new_i32();
4871 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4872 tcg_gen_addi_i32(addr
, addr
, stride
);
4873 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4874 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4875 tcg_temp_free_i32(tmp2
);
4876 neon_store_reg(rd
, pass
, tmp
);
4878 tmp
= neon_load_reg(rd
, pass
);
4879 tmp2
= tcg_temp_new_i32();
4880 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4881 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4882 tcg_temp_free_i32(tmp
);
4883 tcg_gen_addi_i32(addr
, addr
, stride
);
4884 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4885 tcg_temp_free_i32(tmp2
);
4886 tcg_gen_addi_i32(addr
, addr
, stride
);
4888 } else /* size == 0 */ {
4890 TCGV_UNUSED_I32(tmp2
);
4891 for (n
= 0; n
< 4; n
++) {
4892 tmp
= tcg_temp_new_i32();
4893 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4894 tcg_gen_addi_i32(addr
, addr
, stride
);
4898 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4899 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4900 tcg_temp_free_i32(tmp
);
4903 neon_store_reg(rd
, pass
, tmp2
);
4905 tmp2
= neon_load_reg(rd
, pass
);
4906 for (n
= 0; n
< 4; n
++) {
4907 tmp
= tcg_temp_new_i32();
4909 tcg_gen_mov_i32(tmp
, tmp2
);
4911 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4913 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4914 tcg_temp_free_i32(tmp
);
4915 tcg_gen_addi_i32(addr
, addr
, stride
);
4917 tcg_temp_free_i32(tmp2
);
4924 tcg_temp_free_i32(addr
);
4927 size
= (insn
>> 10) & 3;
4929 /* Load single element to all lanes. */
4930 int a
= (insn
>> 4) & 1;
4934 size
= (insn
>> 6) & 3;
4935 nregs
= ((insn
>> 8) & 3) + 1;
4938 if (nregs
!= 4 || a
== 0) {
4941 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4944 if (nregs
== 1 && a
== 1 && size
== 0) {
4947 if (nregs
== 3 && a
== 1) {
4950 addr
= tcg_temp_new_i32();
4951 load_reg_var(s
, addr
, rn
);
4953 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4954 tmp
= gen_load_and_replicate(s
, addr
, size
);
4955 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4956 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4957 if (insn
& (1 << 5)) {
4958 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4959 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4961 tcg_temp_free_i32(tmp
);
4963 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4964 stride
= (insn
& (1 << 5)) ? 2 : 1;
4965 for (reg
= 0; reg
< nregs
; reg
++) {
4966 tmp
= gen_load_and_replicate(s
, addr
, size
);
4967 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4968 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4969 tcg_temp_free_i32(tmp
);
4970 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4974 tcg_temp_free_i32(addr
);
4975 stride
= (1 << size
) * nregs
;
4977 /* Single element. */
4978 int idx
= (insn
>> 4) & 0xf;
4979 pass
= (insn
>> 7) & 1;
4982 shift
= ((insn
>> 5) & 3) * 8;
4986 shift
= ((insn
>> 6) & 1) * 16;
4987 stride
= (insn
& (1 << 5)) ? 2 : 1;
4991 stride
= (insn
& (1 << 6)) ? 2 : 1;
4996 nregs
= ((insn
>> 8) & 3) + 1;
4997 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5000 if (((idx
& (1 << size
)) != 0) ||
5001 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
5006 if ((idx
& 1) != 0) {
5011 if (size
== 2 && (idx
& 2) != 0) {
5016 if ((size
== 2) && ((idx
& 3) == 3)) {
5023 if ((rd
+ stride
* (nregs
- 1)) > 31) {
5024 /* Attempts to write off the end of the register file
5025 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5026 * the neon_load_reg() would write off the end of the array.
5030 addr
= tcg_temp_new_i32();
5031 load_reg_var(s
, addr
, rn
);
5032 for (reg
= 0; reg
< nregs
; reg
++) {
5034 tmp
= tcg_temp_new_i32();
5037 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
5040 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
5043 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
5045 default: /* Avoid compiler warnings. */
5049 tmp2
= neon_load_reg(rd
, pass
);
5050 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
5051 shift
, size
? 16 : 8);
5052 tcg_temp_free_i32(tmp2
);
5054 neon_store_reg(rd
, pass
, tmp
);
5055 } else { /* Store */
5056 tmp
= neon_load_reg(rd
, pass
);
5058 tcg_gen_shri_i32(tmp
, tmp
, shift
);
5061 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
5064 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
5067 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5070 tcg_temp_free_i32(tmp
);
5073 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5075 tcg_temp_free_i32(addr
);
5076 stride
= nregs
* (1 << size
);
5082 base
= load_reg(s
, rn
);
5084 tcg_gen_addi_i32(base
, base
, stride
);
5087 index
= load_reg(s
, rm
);
5088 tcg_gen_add_i32(base
, base
, index
);
5089 tcg_temp_free_i32(index
);
5091 store_reg(s
, rn
, base
);
5096 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5097 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
5099 tcg_gen_and_i32(t
, t
, c
);
5100 tcg_gen_andc_i32(f
, f
, c
);
5101 tcg_gen_or_i32(dest
, t
, f
);
5104 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5107 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
5108 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
5109 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
5114 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5117 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
5118 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
5119 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5124 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5127 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5128 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5129 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5134 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5137 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5138 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5139 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5144 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5150 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5151 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5156 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5157 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5164 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5165 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5170 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5171 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5178 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5182 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5183 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5184 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5189 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5190 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5191 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5195 tcg_temp_free_i32(src
);
5198 static inline void gen_neon_addl(int size
)
5201 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5202 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5203 case 2: tcg_gen_add_i64(CPU_V001
); break;
5208 static inline void gen_neon_subl(int size
)
5211 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5212 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5213 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5218 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5221 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5222 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5224 tcg_gen_neg_i64(var
, var
);
5230 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5233 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5234 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5239 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5244 switch ((size
<< 1) | u
) {
5245 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5246 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5247 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5248 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5250 tmp
= gen_muls_i64_i32(a
, b
);
5251 tcg_gen_mov_i64(dest
, tmp
);
5252 tcg_temp_free_i64(tmp
);
5255 tmp
= gen_mulu_i64_i32(a
, b
);
5256 tcg_gen_mov_i64(dest
, tmp
);
5257 tcg_temp_free_i64(tmp
);
5262 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5263 Don't forget to clean them now. */
5265 tcg_temp_free_i32(a
);
5266 tcg_temp_free_i32(b
);
5270 static void gen_neon_narrow_op(int op
, int u
, int size
,
5271 TCGv_i32 dest
, TCGv_i64 src
)
5275 gen_neon_unarrow_sats(size
, dest
, src
);
5277 gen_neon_narrow(size
, dest
, src
);
5281 gen_neon_narrow_satu(size
, dest
, src
);
5283 gen_neon_narrow_sats(size
, dest
, src
);
5288 /* Symbolic constants for op fields for Neon 3-register same-length.
5289 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5292 #define NEON_3R_VHADD 0
5293 #define NEON_3R_VQADD 1
5294 #define NEON_3R_VRHADD 2
5295 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5296 #define NEON_3R_VHSUB 4
5297 #define NEON_3R_VQSUB 5
5298 #define NEON_3R_VCGT 6
5299 #define NEON_3R_VCGE 7
5300 #define NEON_3R_VSHL 8
5301 #define NEON_3R_VQSHL 9
5302 #define NEON_3R_VRSHL 10
5303 #define NEON_3R_VQRSHL 11
5304 #define NEON_3R_VMAX 12
5305 #define NEON_3R_VMIN 13
5306 #define NEON_3R_VABD 14
5307 #define NEON_3R_VABA 15
5308 #define NEON_3R_VADD_VSUB 16
5309 #define NEON_3R_VTST_VCEQ 17
5310 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5311 #define NEON_3R_VMUL 19
5312 #define NEON_3R_VPMAX 20
5313 #define NEON_3R_VPMIN 21
5314 #define NEON_3R_VQDMULH_VQRDMULH 22
5315 #define NEON_3R_VPADD 23
5316 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5317 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5318 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5319 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5320 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5321 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5322 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5323 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5325 static const uint8_t neon_3r_sizes
[] = {
5326 [NEON_3R_VHADD
] = 0x7,
5327 [NEON_3R_VQADD
] = 0xf,
5328 [NEON_3R_VRHADD
] = 0x7,
5329 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5330 [NEON_3R_VHSUB
] = 0x7,
5331 [NEON_3R_VQSUB
] = 0xf,
5332 [NEON_3R_VCGT
] = 0x7,
5333 [NEON_3R_VCGE
] = 0x7,
5334 [NEON_3R_VSHL
] = 0xf,
5335 [NEON_3R_VQSHL
] = 0xf,
5336 [NEON_3R_VRSHL
] = 0xf,
5337 [NEON_3R_VQRSHL
] = 0xf,
5338 [NEON_3R_VMAX
] = 0x7,
5339 [NEON_3R_VMIN
] = 0x7,
5340 [NEON_3R_VABD
] = 0x7,
5341 [NEON_3R_VABA
] = 0x7,
5342 [NEON_3R_VADD_VSUB
] = 0xf,
5343 [NEON_3R_VTST_VCEQ
] = 0x7,
5344 [NEON_3R_VML
] = 0x7,
5345 [NEON_3R_VMUL
] = 0x7,
5346 [NEON_3R_VPMAX
] = 0x7,
5347 [NEON_3R_VPMIN
] = 0x7,
5348 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5349 [NEON_3R_VPADD
] = 0x7,
5350 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5351 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5352 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5353 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5354 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5355 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5356 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5357 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5360 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5361 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5364 #define NEON_2RM_VREV64 0
5365 #define NEON_2RM_VREV32 1
5366 #define NEON_2RM_VREV16 2
5367 #define NEON_2RM_VPADDL 4
5368 #define NEON_2RM_VPADDL_U 5
5369 #define NEON_2RM_AESE 6 /* Includes AESD */
5370 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5371 #define NEON_2RM_VCLS 8
5372 #define NEON_2RM_VCLZ 9
5373 #define NEON_2RM_VCNT 10
5374 #define NEON_2RM_VMVN 11
5375 #define NEON_2RM_VPADAL 12
5376 #define NEON_2RM_VPADAL_U 13
5377 #define NEON_2RM_VQABS 14
5378 #define NEON_2RM_VQNEG 15
5379 #define NEON_2RM_VCGT0 16
5380 #define NEON_2RM_VCGE0 17
5381 #define NEON_2RM_VCEQ0 18
5382 #define NEON_2RM_VCLE0 19
5383 #define NEON_2RM_VCLT0 20
5384 #define NEON_2RM_SHA1H 21
5385 #define NEON_2RM_VABS 22
5386 #define NEON_2RM_VNEG 23
5387 #define NEON_2RM_VCGT0_F 24
5388 #define NEON_2RM_VCGE0_F 25
5389 #define NEON_2RM_VCEQ0_F 26
5390 #define NEON_2RM_VCLE0_F 27
5391 #define NEON_2RM_VCLT0_F 28
5392 #define NEON_2RM_VABS_F 30
5393 #define NEON_2RM_VNEG_F 31
5394 #define NEON_2RM_VSWP 32
5395 #define NEON_2RM_VTRN 33
5396 #define NEON_2RM_VUZP 34
5397 #define NEON_2RM_VZIP 35
5398 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5399 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5400 #define NEON_2RM_VSHLL 38
5401 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5402 #define NEON_2RM_VRINTN 40
5403 #define NEON_2RM_VRINTX 41
5404 #define NEON_2RM_VRINTA 42
5405 #define NEON_2RM_VRINTZ 43
5406 #define NEON_2RM_VCVT_F16_F32 44
5407 #define NEON_2RM_VRINTM 45
5408 #define NEON_2RM_VCVT_F32_F16 46
5409 #define NEON_2RM_VRINTP 47
5410 #define NEON_2RM_VCVTAU 48
5411 #define NEON_2RM_VCVTAS 49
5412 #define NEON_2RM_VCVTNU 50
5413 #define NEON_2RM_VCVTNS 51
5414 #define NEON_2RM_VCVTPU 52
5415 #define NEON_2RM_VCVTPS 53
5416 #define NEON_2RM_VCVTMU 54
5417 #define NEON_2RM_VCVTMS 55
5418 #define NEON_2RM_VRECPE 56
5419 #define NEON_2RM_VRSQRTE 57
5420 #define NEON_2RM_VRECPE_F 58
5421 #define NEON_2RM_VRSQRTE_F 59
5422 #define NEON_2RM_VCVT_FS 60
5423 #define NEON_2RM_VCVT_FU 61
5424 #define NEON_2RM_VCVT_SF 62
5425 #define NEON_2RM_VCVT_UF 63
5427 static int neon_2rm_is_float_op(int op
)
5429 /* Return true if this neon 2reg-misc op is float-to-float */
5430 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5431 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5432 op
== NEON_2RM_VRINTM
||
5433 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5434 op
>= NEON_2RM_VRECPE_F
);
5437 static bool neon_2rm_is_v8_op(int op
)
5439 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5441 case NEON_2RM_VRINTN
:
5442 case NEON_2RM_VRINTA
:
5443 case NEON_2RM_VRINTM
:
5444 case NEON_2RM_VRINTP
:
5445 case NEON_2RM_VRINTZ
:
5446 case NEON_2RM_VRINTX
:
5447 case NEON_2RM_VCVTAU
:
5448 case NEON_2RM_VCVTAS
:
5449 case NEON_2RM_VCVTNU
:
5450 case NEON_2RM_VCVTNS
:
5451 case NEON_2RM_VCVTPU
:
5452 case NEON_2RM_VCVTPS
:
5453 case NEON_2RM_VCVTMU
:
5454 case NEON_2RM_VCVTMS
:
5461 /* Each entry in this array has bit n set if the insn allows
5462 * size value n (otherwise it will UNDEF). Since unallocated
5463 * op values will have no bits set they always UNDEF.
5465 static const uint8_t neon_2rm_sizes
[] = {
5466 [NEON_2RM_VREV64
] = 0x7,
5467 [NEON_2RM_VREV32
] = 0x3,
5468 [NEON_2RM_VREV16
] = 0x1,
5469 [NEON_2RM_VPADDL
] = 0x7,
5470 [NEON_2RM_VPADDL_U
] = 0x7,
5471 [NEON_2RM_AESE
] = 0x1,
5472 [NEON_2RM_AESMC
] = 0x1,
5473 [NEON_2RM_VCLS
] = 0x7,
5474 [NEON_2RM_VCLZ
] = 0x7,
5475 [NEON_2RM_VCNT
] = 0x1,
5476 [NEON_2RM_VMVN
] = 0x1,
5477 [NEON_2RM_VPADAL
] = 0x7,
5478 [NEON_2RM_VPADAL_U
] = 0x7,
5479 [NEON_2RM_VQABS
] = 0x7,
5480 [NEON_2RM_VQNEG
] = 0x7,
5481 [NEON_2RM_VCGT0
] = 0x7,
5482 [NEON_2RM_VCGE0
] = 0x7,
5483 [NEON_2RM_VCEQ0
] = 0x7,
5484 [NEON_2RM_VCLE0
] = 0x7,
5485 [NEON_2RM_VCLT0
] = 0x7,
5486 [NEON_2RM_SHA1H
] = 0x4,
5487 [NEON_2RM_VABS
] = 0x7,
5488 [NEON_2RM_VNEG
] = 0x7,
5489 [NEON_2RM_VCGT0_F
] = 0x4,
5490 [NEON_2RM_VCGE0_F
] = 0x4,
5491 [NEON_2RM_VCEQ0_F
] = 0x4,
5492 [NEON_2RM_VCLE0_F
] = 0x4,
5493 [NEON_2RM_VCLT0_F
] = 0x4,
5494 [NEON_2RM_VABS_F
] = 0x4,
5495 [NEON_2RM_VNEG_F
] = 0x4,
5496 [NEON_2RM_VSWP
] = 0x1,
5497 [NEON_2RM_VTRN
] = 0x7,
5498 [NEON_2RM_VUZP
] = 0x7,
5499 [NEON_2RM_VZIP
] = 0x7,
5500 [NEON_2RM_VMOVN
] = 0x7,
5501 [NEON_2RM_VQMOVN
] = 0x7,
5502 [NEON_2RM_VSHLL
] = 0x7,
5503 [NEON_2RM_SHA1SU1
] = 0x4,
5504 [NEON_2RM_VRINTN
] = 0x4,
5505 [NEON_2RM_VRINTX
] = 0x4,
5506 [NEON_2RM_VRINTA
] = 0x4,
5507 [NEON_2RM_VRINTZ
] = 0x4,
5508 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5509 [NEON_2RM_VRINTM
] = 0x4,
5510 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5511 [NEON_2RM_VRINTP
] = 0x4,
5512 [NEON_2RM_VCVTAU
] = 0x4,
5513 [NEON_2RM_VCVTAS
] = 0x4,
5514 [NEON_2RM_VCVTNU
] = 0x4,
5515 [NEON_2RM_VCVTNS
] = 0x4,
5516 [NEON_2RM_VCVTPU
] = 0x4,
5517 [NEON_2RM_VCVTPS
] = 0x4,
5518 [NEON_2RM_VCVTMU
] = 0x4,
5519 [NEON_2RM_VCVTMS
] = 0x4,
5520 [NEON_2RM_VRECPE
] = 0x4,
5521 [NEON_2RM_VRSQRTE
] = 0x4,
5522 [NEON_2RM_VRECPE_F
] = 0x4,
5523 [NEON_2RM_VRSQRTE_F
] = 0x4,
5524 [NEON_2RM_VCVT_FS
] = 0x4,
5525 [NEON_2RM_VCVT_FU
] = 0x4,
5526 [NEON_2RM_VCVT_SF
] = 0x4,
5527 [NEON_2RM_VCVT_UF
] = 0x4,
5530 /* Translate a NEON data processing instruction. Return nonzero if the
5531 instruction is invalid.
5532 We process data in a mixture of 32-bit and 64-bit chunks.
5533 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5535 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5547 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5550 /* FIXME: this access check should not take precedence over UNDEF
5551 * for invalid encodings; we will generate incorrect syndrome information
5552 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5554 if (s
->fp_excp_el
) {
5555 gen_exception_insn(s
, 4, EXCP_UDEF
,
5556 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5560 if (!s
->vfp_enabled
)
5562 q
= (insn
& (1 << 6)) != 0;
5563 u
= (insn
>> 24) & 1;
5564 VFP_DREG_D(rd
, insn
);
5565 VFP_DREG_N(rn
, insn
);
5566 VFP_DREG_M(rm
, insn
);
5567 size
= (insn
>> 20) & 3;
5568 if ((insn
& (1 << 23)) == 0) {
5569 /* Three register same length. */
5570 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5571 /* Catch invalid op and bad size combinations: UNDEF */
5572 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5575 /* All insns of this form UNDEF for either this condition or the
5576 * superset of cases "Q==1"; we catch the latter later.
5578 if (q
&& ((rd
| rn
| rm
) & 1)) {
5582 * The SHA-1/SHA-256 3-register instructions require special treatment
5583 * here, as their size field is overloaded as an op type selector, and
5584 * they all consume their input in a single pass.
5586 if (op
== NEON_3R_SHA
) {
5590 if (!u
) { /* SHA-1 */
5591 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5594 tmp
= tcg_const_i32(rd
);
5595 tmp2
= tcg_const_i32(rn
);
5596 tmp3
= tcg_const_i32(rm
);
5597 tmp4
= tcg_const_i32(size
);
5598 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5599 tcg_temp_free_i32(tmp4
);
5600 } else { /* SHA-256 */
5601 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5604 tmp
= tcg_const_i32(rd
);
5605 tmp2
= tcg_const_i32(rn
);
5606 tmp3
= tcg_const_i32(rm
);
5609 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5612 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5615 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5619 tcg_temp_free_i32(tmp
);
5620 tcg_temp_free_i32(tmp2
);
5621 tcg_temp_free_i32(tmp3
);
5624 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5625 /* 64-bit element instructions. */
5626 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5627 neon_load_reg64(cpu_V0
, rn
+ pass
);
5628 neon_load_reg64(cpu_V1
, rm
+ pass
);
5632 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5635 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5641 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5644 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5650 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5652 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5657 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5660 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5666 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5668 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5671 case NEON_3R_VQRSHL
:
5673 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5676 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5680 case NEON_3R_VADD_VSUB
:
5682 tcg_gen_sub_i64(CPU_V001
);
5684 tcg_gen_add_i64(CPU_V001
);
5690 neon_store_reg64(cpu_V0
, rd
+ pass
);
5699 case NEON_3R_VQRSHL
:
5702 /* Shift instruction operands are reversed. */
5717 case NEON_3R_FLOAT_ARITH
:
5718 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5720 case NEON_3R_FLOAT_MINMAX
:
5721 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5723 case NEON_3R_FLOAT_CMP
:
5725 /* no encoding for U=0 C=1x */
5729 case NEON_3R_FLOAT_ACMP
:
5734 case NEON_3R_FLOAT_MISC
:
5735 /* VMAXNM/VMINNM in ARMv8 */
5736 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5741 if (u
&& (size
!= 0)) {
5742 /* UNDEF on invalid size for polynomial subcase */
5747 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5755 if (pairwise
&& q
) {
5756 /* All the pairwise insns UNDEF if Q is set */
5760 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5765 tmp
= neon_load_reg(rn
, 0);
5766 tmp2
= neon_load_reg(rn
, 1);
5768 tmp
= neon_load_reg(rm
, 0);
5769 tmp2
= neon_load_reg(rm
, 1);
5773 tmp
= neon_load_reg(rn
, pass
);
5774 tmp2
= neon_load_reg(rm
, pass
);
5778 GEN_NEON_INTEGER_OP(hadd
);
5781 GEN_NEON_INTEGER_OP_ENV(qadd
);
5783 case NEON_3R_VRHADD
:
5784 GEN_NEON_INTEGER_OP(rhadd
);
5786 case NEON_3R_LOGIC
: /* Logic ops. */
5787 switch ((u
<< 2) | size
) {
5789 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5792 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5795 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5798 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5801 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5804 tmp3
= neon_load_reg(rd
, pass
);
5805 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5806 tcg_temp_free_i32(tmp3
);
5809 tmp3
= neon_load_reg(rd
, pass
);
5810 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5811 tcg_temp_free_i32(tmp3
);
5814 tmp3
= neon_load_reg(rd
, pass
);
5815 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5816 tcg_temp_free_i32(tmp3
);
5821 GEN_NEON_INTEGER_OP(hsub
);
5824 GEN_NEON_INTEGER_OP_ENV(qsub
);
5827 GEN_NEON_INTEGER_OP(cgt
);
5830 GEN_NEON_INTEGER_OP(cge
);
5833 GEN_NEON_INTEGER_OP(shl
);
5836 GEN_NEON_INTEGER_OP_ENV(qshl
);
5839 GEN_NEON_INTEGER_OP(rshl
);
5841 case NEON_3R_VQRSHL
:
5842 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5845 GEN_NEON_INTEGER_OP(max
);
5848 GEN_NEON_INTEGER_OP(min
);
5851 GEN_NEON_INTEGER_OP(abd
);
5854 GEN_NEON_INTEGER_OP(abd
);
5855 tcg_temp_free_i32(tmp2
);
5856 tmp2
= neon_load_reg(rd
, pass
);
5857 gen_neon_add(size
, tmp
, tmp2
);
5859 case NEON_3R_VADD_VSUB
:
5860 if (!u
) { /* VADD */
5861 gen_neon_add(size
, tmp
, tmp2
);
5864 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5865 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5866 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5871 case NEON_3R_VTST_VCEQ
:
5872 if (!u
) { /* VTST */
5874 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5875 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5876 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5881 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5882 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5883 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5888 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5890 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5891 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5892 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5895 tcg_temp_free_i32(tmp2
);
5896 tmp2
= neon_load_reg(rd
, pass
);
5898 gen_neon_rsb(size
, tmp
, tmp2
);
5900 gen_neon_add(size
, tmp
, tmp2
);
5904 if (u
) { /* polynomial */
5905 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5906 } else { /* Integer */
5908 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5909 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5910 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5916 GEN_NEON_INTEGER_OP(pmax
);
5919 GEN_NEON_INTEGER_OP(pmin
);
5921 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5922 if (!u
) { /* VQDMULH */
5925 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5928 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5932 } else { /* VQRDMULH */
5935 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5938 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5946 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5947 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5948 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5952 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5954 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5955 switch ((u
<< 2) | size
) {
5958 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5961 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5964 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5969 tcg_temp_free_ptr(fpstatus
);
5972 case NEON_3R_FLOAT_MULTIPLY
:
5974 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5975 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5977 tcg_temp_free_i32(tmp2
);
5978 tmp2
= neon_load_reg(rd
, pass
);
5980 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5982 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5985 tcg_temp_free_ptr(fpstatus
);
5988 case NEON_3R_FLOAT_CMP
:
5990 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5992 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5995 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5997 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6000 tcg_temp_free_ptr(fpstatus
);
6003 case NEON_3R_FLOAT_ACMP
:
6005 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6007 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6009 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6011 tcg_temp_free_ptr(fpstatus
);
6014 case NEON_3R_FLOAT_MINMAX
:
6016 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6018 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6020 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6022 tcg_temp_free_ptr(fpstatus
);
6025 case NEON_3R_FLOAT_MISC
:
6028 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6030 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6032 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6034 tcg_temp_free_ptr(fpstatus
);
6037 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6039 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6045 /* VFMA, VFMS: fused multiply-add */
6046 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6047 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6050 gen_helper_vfp_negs(tmp
, tmp
);
6052 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6053 tcg_temp_free_i32(tmp3
);
6054 tcg_temp_free_ptr(fpstatus
);
6060 tcg_temp_free_i32(tmp2
);
6062 /* Save the result. For elementwise operations we can put it
6063 straight into the destination register. For pairwise operations
6064 we have to be careful to avoid clobbering the source operands. */
6065 if (pairwise
&& rd
== rm
) {
6066 neon_store_scratch(pass
, tmp
);
6068 neon_store_reg(rd
, pass
, tmp
);
6072 if (pairwise
&& rd
== rm
) {
6073 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6074 tmp
= neon_load_scratch(pass
);
6075 neon_store_reg(rd
, pass
, tmp
);
6078 /* End of 3 register same size operations. */
6079 } else if (insn
& (1 << 4)) {
6080 if ((insn
& 0x00380080) != 0) {
6081 /* Two registers and shift. */
6082 op
= (insn
>> 8) & 0xf;
6083 if (insn
& (1 << 7)) {
6091 while ((insn
& (1 << (size
+ 19))) == 0)
6094 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6095 /* To avoid excessive duplication of ops we implement shift
6096 by immediate using the variable shift operations. */
6098 /* Shift by immediate:
6099 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6100 if (q
&& ((rd
| rm
) & 1)) {
6103 if (!u
&& (op
== 4 || op
== 6)) {
6106 /* Right shifts are encoded as N - shift, where N is the
6107 element size in bits. */
6109 shift
= shift
- (1 << (size
+ 3));
6117 imm
= (uint8_t) shift
;
6122 imm
= (uint16_t) shift
;
6133 for (pass
= 0; pass
< count
; pass
++) {
6135 neon_load_reg64(cpu_V0
, rm
+ pass
);
6136 tcg_gen_movi_i64(cpu_V1
, imm
);
6141 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6143 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6148 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6150 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6153 case 5: /* VSHL, VSLI */
6154 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6156 case 6: /* VQSHLU */
6157 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6162 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6165 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6170 if (op
== 1 || op
== 3) {
6172 neon_load_reg64(cpu_V1
, rd
+ pass
);
6173 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6174 } else if (op
== 4 || (op
== 5 && u
)) {
6176 neon_load_reg64(cpu_V1
, rd
+ pass
);
6178 if (shift
< -63 || shift
> 63) {
6182 mask
= 0xffffffffffffffffull
>> -shift
;
6184 mask
= 0xffffffffffffffffull
<< shift
;
6187 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6188 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6190 neon_store_reg64(cpu_V0
, rd
+ pass
);
6191 } else { /* size < 3 */
6192 /* Operands in T0 and T1. */
6193 tmp
= neon_load_reg(rm
, pass
);
6194 tmp2
= tcg_temp_new_i32();
6195 tcg_gen_movi_i32(tmp2
, imm
);
6199 GEN_NEON_INTEGER_OP(shl
);
6203 GEN_NEON_INTEGER_OP(rshl
);
6206 case 5: /* VSHL, VSLI */
6208 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6209 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6210 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6214 case 6: /* VQSHLU */
6217 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6221 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6225 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6233 GEN_NEON_INTEGER_OP_ENV(qshl
);
6236 tcg_temp_free_i32(tmp2
);
6238 if (op
== 1 || op
== 3) {
6240 tmp2
= neon_load_reg(rd
, pass
);
6241 gen_neon_add(size
, tmp
, tmp2
);
6242 tcg_temp_free_i32(tmp2
);
6243 } else if (op
== 4 || (op
== 5 && u
)) {
6248 mask
= 0xff >> -shift
;
6250 mask
= (uint8_t)(0xff << shift
);
6256 mask
= 0xffff >> -shift
;
6258 mask
= (uint16_t)(0xffff << shift
);
6262 if (shift
< -31 || shift
> 31) {
6266 mask
= 0xffffffffu
>> -shift
;
6268 mask
= 0xffffffffu
<< shift
;
6274 tmp2
= neon_load_reg(rd
, pass
);
6275 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6276 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6277 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6278 tcg_temp_free_i32(tmp2
);
6280 neon_store_reg(rd
, pass
, tmp
);
6283 } else if (op
< 10) {
6284 /* Shift by immediate and narrow:
6285 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6286 int input_unsigned
= (op
== 8) ? !u
: u
;
6290 shift
= shift
- (1 << (size
+ 3));
6293 tmp64
= tcg_const_i64(shift
);
6294 neon_load_reg64(cpu_V0
, rm
);
6295 neon_load_reg64(cpu_V1
, rm
+ 1);
6296 for (pass
= 0; pass
< 2; pass
++) {
6304 if (input_unsigned
) {
6305 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6307 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6310 if (input_unsigned
) {
6311 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6313 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6316 tmp
= tcg_temp_new_i32();
6317 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6318 neon_store_reg(rd
, pass
, tmp
);
6320 tcg_temp_free_i64(tmp64
);
6323 imm
= (uint16_t)shift
;
6327 imm
= (uint32_t)shift
;
6329 tmp2
= tcg_const_i32(imm
);
6330 tmp4
= neon_load_reg(rm
+ 1, 0);
6331 tmp5
= neon_load_reg(rm
+ 1, 1);
6332 for (pass
= 0; pass
< 2; pass
++) {
6334 tmp
= neon_load_reg(rm
, 0);
6338 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6341 tmp3
= neon_load_reg(rm
, 1);
6345 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6347 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6348 tcg_temp_free_i32(tmp
);
6349 tcg_temp_free_i32(tmp3
);
6350 tmp
= tcg_temp_new_i32();
6351 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6352 neon_store_reg(rd
, pass
, tmp
);
6354 tcg_temp_free_i32(tmp2
);
6356 } else if (op
== 10) {
6358 if (q
|| (rd
& 1)) {
6361 tmp
= neon_load_reg(rm
, 0);
6362 tmp2
= neon_load_reg(rm
, 1);
6363 for (pass
= 0; pass
< 2; pass
++) {
6367 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6370 /* The shift is less than the width of the source
6371 type, so we can just shift the whole register. */
6372 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6373 /* Widen the result of shift: we need to clear
6374 * the potential overflow bits resulting from
6375 * left bits of the narrow input appearing as
6376 * right bits of left the neighbour narrow
6378 if (size
< 2 || !u
) {
6381 imm
= (0xffu
>> (8 - shift
));
6383 } else if (size
== 1) {
6384 imm
= 0xffff >> (16 - shift
);
6387 imm
= 0xffffffff >> (32 - shift
);
6390 imm64
= imm
| (((uint64_t)imm
) << 32);
6394 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6397 neon_store_reg64(cpu_V0
, rd
+ pass
);
6399 } else if (op
>= 14) {
6400 /* VCVT fixed-point. */
6401 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6404 /* We have already masked out the must-be-1 top bit of imm6,
6405 * hence this 32-shift where the ARM ARM has 64-imm6.
6408 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6409 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6412 gen_vfp_ulto(0, shift
, 1);
6414 gen_vfp_slto(0, shift
, 1);
6417 gen_vfp_toul(0, shift
, 1);
6419 gen_vfp_tosl(0, shift
, 1);
6421 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6426 } else { /* (insn & 0x00380080) == 0 */
6428 if (q
&& (rd
& 1)) {
6432 op
= (insn
>> 8) & 0xf;
6433 /* One register and immediate. */
6434 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6435 invert
= (insn
& (1 << 5)) != 0;
6436 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6437 * We choose to not special-case this and will behave as if a
6438 * valid constant encoding of 0 had been given.
6457 imm
= (imm
<< 8) | (imm
<< 24);
6460 imm
= (imm
<< 8) | 0xff;
6463 imm
= (imm
<< 16) | 0xffff;
6466 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6474 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6475 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6481 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6482 if (op
& 1 && op
< 12) {
6483 tmp
= neon_load_reg(rd
, pass
);
6485 /* The immediate value has already been inverted, so
6487 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6489 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6493 tmp
= tcg_temp_new_i32();
6494 if (op
== 14 && invert
) {
6498 for (n
= 0; n
< 4; n
++) {
6499 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6500 val
|= 0xff << (n
* 8);
6502 tcg_gen_movi_i32(tmp
, val
);
6504 tcg_gen_movi_i32(tmp
, imm
);
6507 neon_store_reg(rd
, pass
, tmp
);
6510 } else { /* (insn & 0x00800010 == 0x00800000) */
6512 op
= (insn
>> 8) & 0xf;
6513 if ((insn
& (1 << 6)) == 0) {
6514 /* Three registers of different lengths. */
6518 /* undefreq: bit 0 : UNDEF if size == 0
6519 * bit 1 : UNDEF if size == 1
6520 * bit 2 : UNDEF if size == 2
6521 * bit 3 : UNDEF if U == 1
6522 * Note that [2:0] set implies 'always UNDEF'
6525 /* prewiden, src1_wide, src2_wide, undefreq */
6526 static const int neon_3reg_wide
[16][4] = {
6527 {1, 0, 0, 0}, /* VADDL */
6528 {1, 1, 0, 0}, /* VADDW */
6529 {1, 0, 0, 0}, /* VSUBL */
6530 {1, 1, 0, 0}, /* VSUBW */
6531 {0, 1, 1, 0}, /* VADDHN */
6532 {0, 0, 0, 0}, /* VABAL */
6533 {0, 1, 1, 0}, /* VSUBHN */
6534 {0, 0, 0, 0}, /* VABDL */
6535 {0, 0, 0, 0}, /* VMLAL */
6536 {0, 0, 0, 9}, /* VQDMLAL */
6537 {0, 0, 0, 0}, /* VMLSL */
6538 {0, 0, 0, 9}, /* VQDMLSL */
6539 {0, 0, 0, 0}, /* Integer VMULL */
6540 {0, 0, 0, 1}, /* VQDMULL */
6541 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6542 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6545 prewiden
= neon_3reg_wide
[op
][0];
6546 src1_wide
= neon_3reg_wide
[op
][1];
6547 src2_wide
= neon_3reg_wide
[op
][2];
6548 undefreq
= neon_3reg_wide
[op
][3];
6550 if ((undefreq
& (1 << size
)) ||
6551 ((undefreq
& 8) && u
)) {
6554 if ((src1_wide
&& (rn
& 1)) ||
6555 (src2_wide
&& (rm
& 1)) ||
6556 (!src2_wide
&& (rd
& 1))) {
6560 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6561 * outside the loop below as it only performs a single pass.
6563 if (op
== 14 && size
== 2) {
6564 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6566 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6569 tcg_rn
= tcg_temp_new_i64();
6570 tcg_rm
= tcg_temp_new_i64();
6571 tcg_rd
= tcg_temp_new_i64();
6572 neon_load_reg64(tcg_rn
, rn
);
6573 neon_load_reg64(tcg_rm
, rm
);
6574 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6575 neon_store_reg64(tcg_rd
, rd
);
6576 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6577 neon_store_reg64(tcg_rd
, rd
+ 1);
6578 tcg_temp_free_i64(tcg_rn
);
6579 tcg_temp_free_i64(tcg_rm
);
6580 tcg_temp_free_i64(tcg_rd
);
6584 /* Avoid overlapping operands. Wide source operands are
6585 always aligned so will never overlap with wide
6586 destinations in problematic ways. */
6587 if (rd
== rm
&& !src2_wide
) {
6588 tmp
= neon_load_reg(rm
, 1);
6589 neon_store_scratch(2, tmp
);
6590 } else if (rd
== rn
&& !src1_wide
) {
6591 tmp
= neon_load_reg(rn
, 1);
6592 neon_store_scratch(2, tmp
);
6594 TCGV_UNUSED_I32(tmp3
);
6595 for (pass
= 0; pass
< 2; pass
++) {
6597 neon_load_reg64(cpu_V0
, rn
+ pass
);
6598 TCGV_UNUSED_I32(tmp
);
6600 if (pass
== 1 && rd
== rn
) {
6601 tmp
= neon_load_scratch(2);
6603 tmp
= neon_load_reg(rn
, pass
);
6606 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6610 neon_load_reg64(cpu_V1
, rm
+ pass
);
6611 TCGV_UNUSED_I32(tmp2
);
6613 if (pass
== 1 && rd
== rm
) {
6614 tmp2
= neon_load_scratch(2);
6616 tmp2
= neon_load_reg(rm
, pass
);
6619 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6623 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6624 gen_neon_addl(size
);
6626 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6627 gen_neon_subl(size
);
6629 case 5: case 7: /* VABAL, VABDL */
6630 switch ((size
<< 1) | u
) {
6632 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6635 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6638 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6641 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6644 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6647 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6651 tcg_temp_free_i32(tmp2
);
6652 tcg_temp_free_i32(tmp
);
6654 case 8: case 9: case 10: case 11: case 12: case 13:
6655 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6656 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6658 case 14: /* Polynomial VMULL */
6659 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6660 tcg_temp_free_i32(tmp2
);
6661 tcg_temp_free_i32(tmp
);
6663 default: /* 15 is RESERVED: caught earlier */
6668 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6669 neon_store_reg64(cpu_V0
, rd
+ pass
);
6670 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6672 neon_load_reg64(cpu_V1
, rd
+ pass
);
6674 case 10: /* VMLSL */
6675 gen_neon_negl(cpu_V0
, size
);
6677 case 5: case 8: /* VABAL, VMLAL */
6678 gen_neon_addl(size
);
6680 case 9: case 11: /* VQDMLAL, VQDMLSL */
6681 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6683 gen_neon_negl(cpu_V0
, size
);
6685 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6690 neon_store_reg64(cpu_V0
, rd
+ pass
);
6691 } else if (op
== 4 || op
== 6) {
6692 /* Narrowing operation. */
6693 tmp
= tcg_temp_new_i32();
6697 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6700 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6703 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6704 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6711 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6714 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6717 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6718 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6719 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6727 neon_store_reg(rd
, 0, tmp3
);
6728 neon_store_reg(rd
, 1, tmp
);
6731 /* Write back the result. */
6732 neon_store_reg64(cpu_V0
, rd
+ pass
);
6736 /* Two registers and a scalar. NB that for ops of this form
6737 * the ARM ARM labels bit 24 as Q, but it is in our variable
6744 case 1: /* Float VMLA scalar */
6745 case 5: /* Floating point VMLS scalar */
6746 case 9: /* Floating point VMUL scalar */
6751 case 0: /* Integer VMLA scalar */
6752 case 4: /* Integer VMLS scalar */
6753 case 8: /* Integer VMUL scalar */
6754 case 12: /* VQDMULH scalar */
6755 case 13: /* VQRDMULH scalar */
6756 if (u
&& ((rd
| rn
) & 1)) {
6759 tmp
= neon_get_scalar(size
, rm
);
6760 neon_store_scratch(0, tmp
);
6761 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6762 tmp
= neon_load_scratch(0);
6763 tmp2
= neon_load_reg(rn
, pass
);
6766 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6768 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6770 } else if (op
== 13) {
6772 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6774 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6776 } else if (op
& 1) {
6777 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6778 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6779 tcg_temp_free_ptr(fpstatus
);
6782 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6783 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6784 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6788 tcg_temp_free_i32(tmp2
);
6791 tmp2
= neon_load_reg(rd
, pass
);
6794 gen_neon_add(size
, tmp
, tmp2
);
6798 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6799 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6800 tcg_temp_free_ptr(fpstatus
);
6804 gen_neon_rsb(size
, tmp
, tmp2
);
6808 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6809 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6810 tcg_temp_free_ptr(fpstatus
);
6816 tcg_temp_free_i32(tmp2
);
6818 neon_store_reg(rd
, pass
, tmp
);
6821 case 3: /* VQDMLAL scalar */
6822 case 7: /* VQDMLSL scalar */
6823 case 11: /* VQDMULL scalar */
6828 case 2: /* VMLAL sclar */
6829 case 6: /* VMLSL scalar */
6830 case 10: /* VMULL scalar */
6834 tmp2
= neon_get_scalar(size
, rm
);
6835 /* We need a copy of tmp2 because gen_neon_mull
6836 * deletes it during pass 0. */
6837 tmp4
= tcg_temp_new_i32();
6838 tcg_gen_mov_i32(tmp4
, tmp2
);
6839 tmp3
= neon_load_reg(rn
, 1);
6841 for (pass
= 0; pass
< 2; pass
++) {
6843 tmp
= neon_load_reg(rn
, 0);
6848 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6850 neon_load_reg64(cpu_V1
, rd
+ pass
);
6854 gen_neon_negl(cpu_V0
, size
);
6857 gen_neon_addl(size
);
6860 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6862 gen_neon_negl(cpu_V0
, size
);
6864 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6870 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6875 neon_store_reg64(cpu_V0
, rd
+ pass
);
6880 default: /* 14 and 15 are RESERVED */
6884 } else { /* size == 3 */
6887 imm
= (insn
>> 8) & 0xf;
6892 if (q
&& ((rd
| rn
| rm
) & 1)) {
6897 neon_load_reg64(cpu_V0
, rn
);
6899 neon_load_reg64(cpu_V1
, rn
+ 1);
6901 } else if (imm
== 8) {
6902 neon_load_reg64(cpu_V0
, rn
+ 1);
6904 neon_load_reg64(cpu_V1
, rm
);
6907 tmp64
= tcg_temp_new_i64();
6909 neon_load_reg64(cpu_V0
, rn
);
6910 neon_load_reg64(tmp64
, rn
+ 1);
6912 neon_load_reg64(cpu_V0
, rn
+ 1);
6913 neon_load_reg64(tmp64
, rm
);
6915 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6916 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6917 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6919 neon_load_reg64(cpu_V1
, rm
);
6921 neon_load_reg64(cpu_V1
, rm
+ 1);
6924 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6925 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6926 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6927 tcg_temp_free_i64(tmp64
);
6930 neon_load_reg64(cpu_V0
, rn
);
6931 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6932 neon_load_reg64(cpu_V1
, rm
);
6933 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6934 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6936 neon_store_reg64(cpu_V0
, rd
);
6938 neon_store_reg64(cpu_V1
, rd
+ 1);
6940 } else if ((insn
& (1 << 11)) == 0) {
6941 /* Two register misc. */
6942 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6943 size
= (insn
>> 18) & 3;
6944 /* UNDEF for unknown op values and bad op-size combinations */
6945 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6948 if (neon_2rm_is_v8_op(op
) &&
6949 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6952 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6953 q
&& ((rm
| rd
) & 1)) {
6957 case NEON_2RM_VREV64
:
6958 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6959 tmp
= neon_load_reg(rm
, pass
* 2);
6960 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6962 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6963 case 1: gen_swap_half(tmp
); break;
6964 case 2: /* no-op */ break;
6967 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6969 neon_store_reg(rd
, pass
* 2, tmp2
);
6972 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6973 case 1: gen_swap_half(tmp2
); break;
6976 neon_store_reg(rd
, pass
* 2, tmp2
);
6980 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6981 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6982 for (pass
= 0; pass
< q
+ 1; pass
++) {
6983 tmp
= neon_load_reg(rm
, pass
* 2);
6984 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6985 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6986 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6988 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6989 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6990 case 2: tcg_gen_add_i64(CPU_V001
); break;
6993 if (op
>= NEON_2RM_VPADAL
) {
6995 neon_load_reg64(cpu_V1
, rd
+ pass
);
6996 gen_neon_addl(size
);
6998 neon_store_reg64(cpu_V0
, rd
+ pass
);
7004 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7005 tmp
= neon_load_reg(rm
, n
);
7006 tmp2
= neon_load_reg(rd
, n
+ 1);
7007 neon_store_reg(rm
, n
, tmp2
);
7008 neon_store_reg(rd
, n
+ 1, tmp
);
7015 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7020 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7024 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7025 /* also VQMOVUN; op field and mnemonics don't line up */
7029 TCGV_UNUSED_I32(tmp2
);
7030 for (pass
= 0; pass
< 2; pass
++) {
7031 neon_load_reg64(cpu_V0
, rm
+ pass
);
7032 tmp
= tcg_temp_new_i32();
7033 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7038 neon_store_reg(rd
, 0, tmp2
);
7039 neon_store_reg(rd
, 1, tmp
);
7043 case NEON_2RM_VSHLL
:
7044 if (q
|| (rd
& 1)) {
7047 tmp
= neon_load_reg(rm
, 0);
7048 tmp2
= neon_load_reg(rm
, 1);
7049 for (pass
= 0; pass
< 2; pass
++) {
7052 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7053 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7054 neon_store_reg64(cpu_V0
, rd
+ pass
);
7057 case NEON_2RM_VCVT_F16_F32
:
7058 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7062 tmp
= tcg_temp_new_i32();
7063 tmp2
= tcg_temp_new_i32();
7064 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7065 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7066 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7067 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7068 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7069 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7070 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7071 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7072 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7073 neon_store_reg(rd
, 0, tmp2
);
7074 tmp2
= tcg_temp_new_i32();
7075 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7076 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7077 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7078 neon_store_reg(rd
, 1, tmp2
);
7079 tcg_temp_free_i32(tmp
);
7081 case NEON_2RM_VCVT_F32_F16
:
7082 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7086 tmp3
= tcg_temp_new_i32();
7087 tmp
= neon_load_reg(rm
, 0);
7088 tmp2
= neon_load_reg(rm
, 1);
7089 tcg_gen_ext16u_i32(tmp3
, tmp
);
7090 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7091 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7092 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7093 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7094 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7095 tcg_temp_free_i32(tmp
);
7096 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7097 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7098 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7099 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7100 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7101 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7102 tcg_temp_free_i32(tmp2
);
7103 tcg_temp_free_i32(tmp3
);
7105 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7106 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
7107 || ((rm
| rd
) & 1)) {
7110 tmp
= tcg_const_i32(rd
);
7111 tmp2
= tcg_const_i32(rm
);
7113 /* Bit 6 is the lowest opcode bit; it distinguishes between
7114 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7116 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7118 if (op
== NEON_2RM_AESE
) {
7119 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
7121 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
7123 tcg_temp_free_i32(tmp
);
7124 tcg_temp_free_i32(tmp2
);
7125 tcg_temp_free_i32(tmp3
);
7127 case NEON_2RM_SHA1H
:
7128 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7129 || ((rm
| rd
) & 1)) {
7132 tmp
= tcg_const_i32(rd
);
7133 tmp2
= tcg_const_i32(rm
);
7135 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
7137 tcg_temp_free_i32(tmp
);
7138 tcg_temp_free_i32(tmp2
);
7140 case NEON_2RM_SHA1SU1
:
7141 if ((rm
| rd
) & 1) {
7144 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7146 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7149 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7152 tmp
= tcg_const_i32(rd
);
7153 tmp2
= tcg_const_i32(rm
);
7155 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
7157 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7159 tcg_temp_free_i32(tmp
);
7160 tcg_temp_free_i32(tmp2
);
7164 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7165 if (neon_2rm_is_float_op(op
)) {
7166 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7167 neon_reg_offset(rm
, pass
));
7168 TCGV_UNUSED_I32(tmp
);
7170 tmp
= neon_load_reg(rm
, pass
);
7173 case NEON_2RM_VREV32
:
7175 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7176 case 1: gen_swap_half(tmp
); break;
7180 case NEON_2RM_VREV16
:
7185 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7186 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7187 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7193 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7194 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7195 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7200 gen_helper_neon_cnt_u8(tmp
, tmp
);
7203 tcg_gen_not_i32(tmp
, tmp
);
7205 case NEON_2RM_VQABS
:
7208 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7211 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7214 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7219 case NEON_2RM_VQNEG
:
7222 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7225 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7228 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7233 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7234 tmp2
= tcg_const_i32(0);
7236 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7237 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7238 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7241 tcg_temp_free_i32(tmp2
);
7242 if (op
== NEON_2RM_VCLE0
) {
7243 tcg_gen_not_i32(tmp
, tmp
);
7246 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7247 tmp2
= tcg_const_i32(0);
7249 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7250 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7251 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7254 tcg_temp_free_i32(tmp2
);
7255 if (op
== NEON_2RM_VCLT0
) {
7256 tcg_gen_not_i32(tmp
, tmp
);
7259 case NEON_2RM_VCEQ0
:
7260 tmp2
= tcg_const_i32(0);
7262 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7263 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7264 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7267 tcg_temp_free_i32(tmp2
);
7271 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7272 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7273 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7278 tmp2
= tcg_const_i32(0);
7279 gen_neon_rsb(size
, tmp
, tmp2
);
7280 tcg_temp_free_i32(tmp2
);
7282 case NEON_2RM_VCGT0_F
:
7284 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7285 tmp2
= tcg_const_i32(0);
7286 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7287 tcg_temp_free_i32(tmp2
);
7288 tcg_temp_free_ptr(fpstatus
);
7291 case NEON_2RM_VCGE0_F
:
7293 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7294 tmp2
= tcg_const_i32(0);
7295 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7296 tcg_temp_free_i32(tmp2
);
7297 tcg_temp_free_ptr(fpstatus
);
7300 case NEON_2RM_VCEQ0_F
:
7302 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7303 tmp2
= tcg_const_i32(0);
7304 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7305 tcg_temp_free_i32(tmp2
);
7306 tcg_temp_free_ptr(fpstatus
);
7309 case NEON_2RM_VCLE0_F
:
7311 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7312 tmp2
= tcg_const_i32(0);
7313 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7314 tcg_temp_free_i32(tmp2
);
7315 tcg_temp_free_ptr(fpstatus
);
7318 case NEON_2RM_VCLT0_F
:
7320 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7321 tmp2
= tcg_const_i32(0);
7322 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7323 tcg_temp_free_i32(tmp2
);
7324 tcg_temp_free_ptr(fpstatus
);
7327 case NEON_2RM_VABS_F
:
7330 case NEON_2RM_VNEG_F
:
7334 tmp2
= neon_load_reg(rd
, pass
);
7335 neon_store_reg(rm
, pass
, tmp2
);
7338 tmp2
= neon_load_reg(rd
, pass
);
7340 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7341 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7344 neon_store_reg(rm
, pass
, tmp2
);
7346 case NEON_2RM_VRINTN
:
7347 case NEON_2RM_VRINTA
:
7348 case NEON_2RM_VRINTM
:
7349 case NEON_2RM_VRINTP
:
7350 case NEON_2RM_VRINTZ
:
7353 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7356 if (op
== NEON_2RM_VRINTZ
) {
7357 rmode
= FPROUNDING_ZERO
;
7359 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7362 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7363 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7365 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7366 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7368 tcg_temp_free_ptr(fpstatus
);
7369 tcg_temp_free_i32(tcg_rmode
);
7372 case NEON_2RM_VRINTX
:
7374 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7375 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7376 tcg_temp_free_ptr(fpstatus
);
7379 case NEON_2RM_VCVTAU
:
7380 case NEON_2RM_VCVTAS
:
7381 case NEON_2RM_VCVTNU
:
7382 case NEON_2RM_VCVTNS
:
7383 case NEON_2RM_VCVTPU
:
7384 case NEON_2RM_VCVTPS
:
7385 case NEON_2RM_VCVTMU
:
7386 case NEON_2RM_VCVTMS
:
7388 bool is_signed
= !extract32(insn
, 7, 1);
7389 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7390 TCGv_i32 tcg_rmode
, tcg_shift
;
7391 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7393 tcg_shift
= tcg_const_i32(0);
7394 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7395 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7399 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7402 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7406 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7408 tcg_temp_free_i32(tcg_rmode
);
7409 tcg_temp_free_i32(tcg_shift
);
7410 tcg_temp_free_ptr(fpst
);
7413 case NEON_2RM_VRECPE
:
7415 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7416 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7417 tcg_temp_free_ptr(fpstatus
);
7420 case NEON_2RM_VRSQRTE
:
7422 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7423 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7424 tcg_temp_free_ptr(fpstatus
);
7427 case NEON_2RM_VRECPE_F
:
7429 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7430 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7431 tcg_temp_free_ptr(fpstatus
);
7434 case NEON_2RM_VRSQRTE_F
:
7436 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7437 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7438 tcg_temp_free_ptr(fpstatus
);
7441 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7444 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7447 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7448 gen_vfp_tosiz(0, 1);
7450 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7451 gen_vfp_touiz(0, 1);
7454 /* Reserved op values were caught by the
7455 * neon_2rm_sizes[] check earlier.
7459 if (neon_2rm_is_float_op(op
)) {
7460 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7461 neon_reg_offset(rd
, pass
));
7463 neon_store_reg(rd
, pass
, tmp
);
7468 } else if ((insn
& (1 << 10)) == 0) {
7470 int n
= ((insn
>> 8) & 3) + 1;
7471 if ((rn
+ n
) > 32) {
7472 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7473 * helper function running off the end of the register file.
7478 if (insn
& (1 << 6)) {
7479 tmp
= neon_load_reg(rd
, 0);
7481 tmp
= tcg_temp_new_i32();
7482 tcg_gen_movi_i32(tmp
, 0);
7484 tmp2
= neon_load_reg(rm
, 0);
7485 tmp4
= tcg_const_i32(rn
);
7486 tmp5
= tcg_const_i32(n
);
7487 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7488 tcg_temp_free_i32(tmp
);
7489 if (insn
& (1 << 6)) {
7490 tmp
= neon_load_reg(rd
, 1);
7492 tmp
= tcg_temp_new_i32();
7493 tcg_gen_movi_i32(tmp
, 0);
7495 tmp3
= neon_load_reg(rm
, 1);
7496 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7497 tcg_temp_free_i32(tmp5
);
7498 tcg_temp_free_i32(tmp4
);
7499 neon_store_reg(rd
, 0, tmp2
);
7500 neon_store_reg(rd
, 1, tmp3
);
7501 tcg_temp_free_i32(tmp
);
7502 } else if ((insn
& 0x380) == 0) {
7504 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7507 if (insn
& (1 << 19)) {
7508 tmp
= neon_load_reg(rm
, 1);
7510 tmp
= neon_load_reg(rm
, 0);
7512 if (insn
& (1 << 16)) {
7513 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7514 } else if (insn
& (1 << 17)) {
7515 if ((insn
>> 18) & 1)
7516 gen_neon_dup_high16(tmp
);
7518 gen_neon_dup_low16(tmp
);
7520 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7521 tmp2
= tcg_temp_new_i32();
7522 tcg_gen_mov_i32(tmp2
, tmp
);
7523 neon_store_reg(rd
, pass
, tmp2
);
7525 tcg_temp_free_i32(tmp
);
7534 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7536 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7537 const ARMCPRegInfo
*ri
;
7539 cpnum
= (insn
>> 8) & 0xf;
7541 /* First check for coprocessor space used for XScale/iwMMXt insns */
7542 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7543 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7546 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7547 return disas_iwmmxt_insn(s
, insn
);
7548 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7549 return disas_dsp_insn(s
, insn
);
7554 /* Otherwise treat as a generic register access */
7555 is64
= (insn
& (1 << 25)) == 0;
7556 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7564 opc1
= (insn
>> 4) & 0xf;
7566 rt2
= (insn
>> 16) & 0xf;
7568 crn
= (insn
>> 16) & 0xf;
7569 opc1
= (insn
>> 21) & 7;
7570 opc2
= (insn
>> 5) & 7;
7573 isread
= (insn
>> 20) & 1;
7574 rt
= (insn
>> 12) & 0xf;
7576 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7577 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7579 /* Check access permissions */
7580 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7585 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7586 /* Emit code to perform further access permissions checks at
7587 * runtime; this may result in an exception.
7588 * Note that on XScale all cp0..c13 registers do an access check
7589 * call in order to handle c15_cpar.
7592 TCGv_i32 tcg_syn
, tcg_isread
;
7595 /* Note that since we are an implementation which takes an
7596 * exception on a trapped conditional instruction only if the
7597 * instruction passes its condition code check, we can take
7598 * advantage of the clause in the ARM ARM that allows us to set
7599 * the COND field in the instruction to 0xE in all cases.
7600 * We could fish the actual condition out of the insn (ARM)
7601 * or the condexec bits (Thumb) but it isn't necessary.
7606 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7609 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7615 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7618 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7623 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7624 * so this can only happen if this is an ARMv7 or earlier CPU,
7625 * in which case the syndrome information won't actually be
7628 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7629 syndrome
= syn_uncategorized();
7633 gen_set_condexec(s
);
7634 gen_set_pc_im(s
, s
->pc
- 4);
7635 tmpptr
= tcg_const_ptr(ri
);
7636 tcg_syn
= tcg_const_i32(syndrome
);
7637 tcg_isread
= tcg_const_i32(isread
);
7638 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7640 tcg_temp_free_ptr(tmpptr
);
7641 tcg_temp_free_i32(tcg_syn
);
7642 tcg_temp_free_i32(tcg_isread
);
7645 /* Handle special cases first */
7646 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7653 gen_set_pc_im(s
, s
->pc
);
7654 s
->is_jmp
= DISAS_WFI
;
7660 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7669 if (ri
->type
& ARM_CP_CONST
) {
7670 tmp64
= tcg_const_i64(ri
->resetvalue
);
7671 } else if (ri
->readfn
) {
7673 tmp64
= tcg_temp_new_i64();
7674 tmpptr
= tcg_const_ptr(ri
);
7675 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7676 tcg_temp_free_ptr(tmpptr
);
7678 tmp64
= tcg_temp_new_i64();
7679 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7681 tmp
= tcg_temp_new_i32();
7682 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7683 store_reg(s
, rt
, tmp
);
7684 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7685 tmp
= tcg_temp_new_i32();
7686 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7687 tcg_temp_free_i64(tmp64
);
7688 store_reg(s
, rt2
, tmp
);
7691 if (ri
->type
& ARM_CP_CONST
) {
7692 tmp
= tcg_const_i32(ri
->resetvalue
);
7693 } else if (ri
->readfn
) {
7695 tmp
= tcg_temp_new_i32();
7696 tmpptr
= tcg_const_ptr(ri
);
7697 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7698 tcg_temp_free_ptr(tmpptr
);
7700 tmp
= load_cpu_offset(ri
->fieldoffset
);
7703 /* Destination register of r15 for 32 bit loads sets
7704 * the condition codes from the high 4 bits of the value
7707 tcg_temp_free_i32(tmp
);
7709 store_reg(s
, rt
, tmp
);
7714 if (ri
->type
& ARM_CP_CONST
) {
7715 /* If not forbidden by access permissions, treat as WI */
7720 TCGv_i32 tmplo
, tmphi
;
7721 TCGv_i64 tmp64
= tcg_temp_new_i64();
7722 tmplo
= load_reg(s
, rt
);
7723 tmphi
= load_reg(s
, rt2
);
7724 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7725 tcg_temp_free_i32(tmplo
);
7726 tcg_temp_free_i32(tmphi
);
7728 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7729 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7730 tcg_temp_free_ptr(tmpptr
);
7732 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7734 tcg_temp_free_i64(tmp64
);
7739 tmp
= load_reg(s
, rt
);
7740 tmpptr
= tcg_const_ptr(ri
);
7741 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7742 tcg_temp_free_ptr(tmpptr
);
7743 tcg_temp_free_i32(tmp
);
7745 TCGv_i32 tmp
= load_reg(s
, rt
);
7746 store_cpu_offset(tmp
, ri
->fieldoffset
);
7751 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7752 /* I/O operations must end the TB here (whether read or write) */
7755 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7756 /* We default to ending the TB on a coprocessor register write,
7757 * but allow this to be suppressed by the register definition
7758 * (usually only necessary to work around guest bugs).
7766 /* Unknown register; this might be a guest error or a QEMU
7767 * unimplemented feature.
7770 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7771 "64 bit system register cp:%d opc1: %d crm:%d "
7773 isread
? "read" : "write", cpnum
, opc1
, crm
,
7774 s
->ns
? "non-secure" : "secure");
7776 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7777 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7779 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7780 s
->ns
? "non-secure" : "secure");
7787 /* Store a 64-bit value to a register pair. Clobbers val. */
7788 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7791 tmp
= tcg_temp_new_i32();
7792 tcg_gen_extrl_i64_i32(tmp
, val
);
7793 store_reg(s
, rlow
, tmp
);
7794 tmp
= tcg_temp_new_i32();
7795 tcg_gen_shri_i64(val
, val
, 32);
7796 tcg_gen_extrl_i64_i32(tmp
, val
);
7797 store_reg(s
, rhigh
, tmp
);
7800 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7801 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7806 /* Load value and extend to 64 bits. */
7807 tmp
= tcg_temp_new_i64();
7808 tmp2
= load_reg(s
, rlow
);
7809 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7810 tcg_temp_free_i32(tmp2
);
7811 tcg_gen_add_i64(val
, val
, tmp
);
7812 tcg_temp_free_i64(tmp
);
7815 /* load and add a 64-bit value from a register pair. */
7816 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7822 /* Load 64-bit value rd:rn. */
7823 tmpl
= load_reg(s
, rlow
);
7824 tmph
= load_reg(s
, rhigh
);
7825 tmp
= tcg_temp_new_i64();
7826 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7827 tcg_temp_free_i32(tmpl
);
7828 tcg_temp_free_i32(tmph
);
7829 tcg_gen_add_i64(val
, val
, tmp
);
7830 tcg_temp_free_i64(tmp
);
7833 /* Set N and Z flags from hi|lo. */
7834 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7836 tcg_gen_mov_i32(cpu_NF
, hi
);
7837 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7840 /* Load/Store exclusive instructions are implemented by remembering
7841 the value/address loaded, and seeing if these are the same
7842 when the store is performed. This should be sufficient to implement
7843 the architecturally mandated semantics, and avoids having to monitor
7844 regular stores. The compare vs the remembered value is done during
7845 the cmpxchg operation, but we must compare the addresses manually. */
7846 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7847 TCGv_i32 addr
, int size
)
7849 TCGv_i32 tmp
= tcg_temp_new_i32();
7850 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7855 TCGv_i32 tmp2
= tcg_temp_new_i32();
7856 TCGv_i64 t64
= tcg_temp_new_i64();
7858 gen_aa32_ld_i64(s
, t64
, addr
, get_mem_index(s
), opc
);
7859 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
7860 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
7861 tcg_temp_free_i64(t64
);
7863 store_reg(s
, rt2
, tmp2
);
7865 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
7866 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7869 store_reg(s
, rt
, tmp
);
7870 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7873 static void gen_clrex(DisasContext
*s
)
7875 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7878 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7879 TCGv_i32 addr
, int size
)
7881 TCGv_i32 t0
, t1
, t2
;
7884 TCGLabel
*done_label
;
7885 TCGLabel
*fail_label
;
7886 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7888 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7894 fail_label
= gen_new_label();
7895 done_label
= gen_new_label();
7896 extaddr
= tcg_temp_new_i64();
7897 tcg_gen_extu_i32_i64(extaddr
, addr
);
7898 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7899 tcg_temp_free_i64(extaddr
);
7901 taddr
= gen_aa32_addr(s
, addr
, opc
);
7902 t0
= tcg_temp_new_i32();
7903 t1
= load_reg(s
, rt
);
7905 TCGv_i64 o64
= tcg_temp_new_i64();
7906 TCGv_i64 n64
= tcg_temp_new_i64();
7908 t2
= load_reg(s
, rt2
);
7909 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
7910 tcg_temp_free_i32(t2
);
7911 gen_aa32_frob64(s
, n64
);
7913 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
7914 get_mem_index(s
), opc
);
7915 tcg_temp_free_i64(n64
);
7917 gen_aa32_frob64(s
, o64
);
7918 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
7919 tcg_gen_extrl_i64_i32(t0
, o64
);
7921 tcg_temp_free_i64(o64
);
7923 t2
= tcg_temp_new_i32();
7924 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
7925 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
7926 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
7927 tcg_temp_free_i32(t2
);
7929 tcg_temp_free_i32(t1
);
7930 tcg_temp_free(taddr
);
7931 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
7932 tcg_temp_free_i32(t0
);
7933 tcg_gen_br(done_label
);
7935 gen_set_label(fail_label
);
7936 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7937 gen_set_label(done_label
);
7938 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7944 * @mode: mode field from insn (which stack to store to)
7945 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7946 * @writeback: true if writeback bit set
7948 * Generate code for the SRS (Store Return State) insn.
7950 static void gen_srs(DisasContext
*s
,
7951 uint32_t mode
, uint32_t amode
, bool writeback
)
7958 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7959 * and specified mode is monitor mode
7960 * - UNDEFINED in Hyp mode
7961 * - UNPREDICTABLE in User or System mode
7962 * - UNPREDICTABLE if the specified mode is:
7963 * -- not implemented
7964 * -- not a valid mode number
7965 * -- a mode that's at a higher exception level
7966 * -- Monitor, if we are Non-secure
7967 * For the UNPREDICTABLE cases we choose to UNDEF.
7969 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7970 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7974 if (s
->current_el
== 0 || s
->current_el
== 2) {
7979 case ARM_CPU_MODE_USR
:
7980 case ARM_CPU_MODE_FIQ
:
7981 case ARM_CPU_MODE_IRQ
:
7982 case ARM_CPU_MODE_SVC
:
7983 case ARM_CPU_MODE_ABT
:
7984 case ARM_CPU_MODE_UND
:
7985 case ARM_CPU_MODE_SYS
:
7987 case ARM_CPU_MODE_HYP
:
7988 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7992 case ARM_CPU_MODE_MON
:
7993 /* No need to check specifically for "are we non-secure" because
7994 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7995 * so if this isn't EL3 then we must be non-secure.
7997 if (s
->current_el
!= 3) {
8006 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8007 default_exception_el(s
));
8011 addr
= tcg_temp_new_i32();
8012 tmp
= tcg_const_i32(mode
);
8013 /* get_r13_banked() will raise an exception if called from System mode */
8014 gen_set_condexec(s
);
8015 gen_set_pc_im(s
, s
->pc
- 4);
8016 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8017 tcg_temp_free_i32(tmp
);
8034 tcg_gen_addi_i32(addr
, addr
, offset
);
8035 tmp
= load_reg(s
, 14);
8036 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8037 tcg_temp_free_i32(tmp
);
8038 tmp
= load_cpu_field(spsr
);
8039 tcg_gen_addi_i32(addr
, addr
, 4);
8040 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8041 tcg_temp_free_i32(tmp
);
8059 tcg_gen_addi_i32(addr
, addr
, offset
);
8060 tmp
= tcg_const_i32(mode
);
8061 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8062 tcg_temp_free_i32(tmp
);
8064 tcg_temp_free_i32(addr
);
8065 s
->is_jmp
= DISAS_UPDATE
;
8068 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8070 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8077 /* M variants do not implement ARM mode; this must raise the INVSTATE
8078 * UsageFault exception.
8080 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8081 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8082 default_exception_el(s
));
8087 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8088 * choose to UNDEF. In ARMv5 and above the space is used
8089 * for miscellaneous unconditional instructions.
8093 /* Unconditional instructions. */
8094 if (((insn
>> 25) & 7) == 1) {
8095 /* NEON Data processing. */
8096 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8100 if (disas_neon_data_insn(s
, insn
)) {
8105 if ((insn
& 0x0f100000) == 0x04000000) {
8106 /* NEON load/store. */
8107 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8111 if (disas_neon_ls_insn(s
, insn
)) {
8116 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8118 if (disas_vfp_insn(s
, insn
)) {
8123 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8124 ((insn
& 0x0f30f010) == 0x0710f000)) {
8125 if ((insn
& (1 << 22)) == 0) {
8127 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8131 /* Otherwise PLD; v5TE+ */
8135 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8136 ((insn
& 0x0f70f010) == 0x0650f000)) {
8138 return; /* PLI; V7 */
8140 if (((insn
& 0x0f700000) == 0x04100000) ||
8141 ((insn
& 0x0f700010) == 0x06100000)) {
8142 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8145 return; /* v7MP: Unallocated memory hint: must NOP */
8148 if ((insn
& 0x0ffffdff) == 0x01010000) {
8151 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8152 gen_helper_setend(cpu_env
);
8153 s
->is_jmp
= DISAS_UPDATE
;
8156 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8157 switch ((insn
>> 4) & 0xf) {
8165 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8168 /* We need to break the TB after this insn to execute
8169 * self-modifying code correctly and also to take
8170 * any pending interrupts immediately.
8172 gen_goto_tb(s
, 0, s
->pc
& ~1);
8177 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8180 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8182 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8188 rn
= (insn
>> 16) & 0xf;
8189 addr
= load_reg(s
, rn
);
8190 i
= (insn
>> 23) & 3;
8192 case 0: offset
= -4; break; /* DA */
8193 case 1: offset
= 0; break; /* IA */
8194 case 2: offset
= -8; break; /* DB */
8195 case 3: offset
= 4; break; /* IB */
8199 tcg_gen_addi_i32(addr
, addr
, offset
);
8200 /* Load PC into tmp and CPSR into tmp2. */
8201 tmp
= tcg_temp_new_i32();
8202 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8203 tcg_gen_addi_i32(addr
, addr
, 4);
8204 tmp2
= tcg_temp_new_i32();
8205 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8206 if (insn
& (1 << 21)) {
8207 /* Base writeback. */
8209 case 0: offset
= -8; break;
8210 case 1: offset
= 4; break;
8211 case 2: offset
= -4; break;
8212 case 3: offset
= 0; break;
8216 tcg_gen_addi_i32(addr
, addr
, offset
);
8217 store_reg(s
, rn
, addr
);
8219 tcg_temp_free_i32(addr
);
8221 gen_rfe(s
, tmp
, tmp2
);
8223 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8224 /* branch link and change to thumb (blx <offset>) */
8227 val
= (uint32_t)s
->pc
;
8228 tmp
= tcg_temp_new_i32();
8229 tcg_gen_movi_i32(tmp
, val
);
8230 store_reg(s
, 14, tmp
);
8231 /* Sign-extend the 24-bit offset */
8232 offset
= (((int32_t)insn
) << 8) >> 8;
8233 /* offset * 4 + bit24 * 2 + (thumb bit) */
8234 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8235 /* pipeline offset */
8237 /* protected by ARCH(5); above, near the start of uncond block */
8240 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8241 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8242 /* iWMMXt register transfer. */
8243 if (extract32(s
->c15_cpar
, 1, 1)) {
8244 if (!disas_iwmmxt_insn(s
, insn
)) {
8249 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8250 /* Coprocessor double register transfer. */
8252 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8253 /* Additional coprocessor register transfer. */
8254 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8257 /* cps (privileged) */
8261 if (insn
& (1 << 19)) {
8262 if (insn
& (1 << 8))
8264 if (insn
& (1 << 7))
8266 if (insn
& (1 << 6))
8268 if (insn
& (1 << 18))
8271 if (insn
& (1 << 17)) {
8273 val
|= (insn
& 0x1f);
8276 gen_set_psr_im(s
, mask
, 0, val
);
8283 /* if not always execute, we generate a conditional jump to
8285 s
->condlabel
= gen_new_label();
8286 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8289 if ((insn
& 0x0f900000) == 0x03000000) {
8290 if ((insn
& (1 << 21)) == 0) {
8292 rd
= (insn
>> 12) & 0xf;
8293 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8294 if ((insn
& (1 << 22)) == 0) {
8296 tmp
= tcg_temp_new_i32();
8297 tcg_gen_movi_i32(tmp
, val
);
8300 tmp
= load_reg(s
, rd
);
8301 tcg_gen_ext16u_i32(tmp
, tmp
);
8302 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8304 store_reg(s
, rd
, tmp
);
8306 if (((insn
>> 12) & 0xf) != 0xf)
8308 if (((insn
>> 16) & 0xf) == 0) {
8309 gen_nop_hint(s
, insn
& 0xff);
8311 /* CPSR = immediate */
8313 shift
= ((insn
>> 8) & 0xf) * 2;
8315 val
= (val
>> shift
) | (val
<< (32 - shift
));
8316 i
= ((insn
& (1 << 22)) != 0);
8317 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8323 } else if ((insn
& 0x0f900000) == 0x01000000
8324 && (insn
& 0x00000090) != 0x00000090) {
8325 /* miscellaneous instructions */
8326 op1
= (insn
>> 21) & 3;
8327 sh
= (insn
>> 4) & 0xf;
8330 case 0x0: /* MSR, MRS */
8331 if (insn
& (1 << 9)) {
8332 /* MSR (banked) and MRS (banked) */
8333 int sysm
= extract32(insn
, 16, 4) |
8334 (extract32(insn
, 8, 1) << 4);
8335 int r
= extract32(insn
, 22, 1);
8339 gen_msr_banked(s
, r
, sysm
, rm
);
8342 int rd
= extract32(insn
, 12, 4);
8344 gen_mrs_banked(s
, r
, sysm
, rd
);
8349 /* MSR, MRS (for PSRs) */
8352 tmp
= load_reg(s
, rm
);
8353 i
= ((op1
& 2) != 0);
8354 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8358 rd
= (insn
>> 12) & 0xf;
8362 tmp
= load_cpu_field(spsr
);
8364 tmp
= tcg_temp_new_i32();
8365 gen_helper_cpsr_read(tmp
, cpu_env
);
8367 store_reg(s
, rd
, tmp
);
8372 /* branch/exchange thumb (bx). */
8374 tmp
= load_reg(s
, rm
);
8376 } else if (op1
== 3) {
8379 rd
= (insn
>> 12) & 0xf;
8380 tmp
= load_reg(s
, rm
);
8381 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8382 store_reg(s
, rd
, tmp
);
8390 /* Trivial implementation equivalent to bx. */
8391 tmp
= load_reg(s
, rm
);
8402 /* branch link/exchange thumb (blx) */
8403 tmp
= load_reg(s
, rm
);
8404 tmp2
= tcg_temp_new_i32();
8405 tcg_gen_movi_i32(tmp2
, s
->pc
);
8406 store_reg(s
, 14, tmp2
);
8412 uint32_t c
= extract32(insn
, 8, 4);
8414 /* Check this CPU supports ARMv8 CRC instructions.
8415 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8416 * Bits 8, 10 and 11 should be zero.
8418 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8423 rn
= extract32(insn
, 16, 4);
8424 rd
= extract32(insn
, 12, 4);
8426 tmp
= load_reg(s
, rn
);
8427 tmp2
= load_reg(s
, rm
);
8429 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8430 } else if (op1
== 1) {
8431 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8433 tmp3
= tcg_const_i32(1 << op1
);
8435 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8437 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8439 tcg_temp_free_i32(tmp2
);
8440 tcg_temp_free_i32(tmp3
);
8441 store_reg(s
, rd
, tmp
);
8444 case 0x5: /* saturating add/subtract */
8446 rd
= (insn
>> 12) & 0xf;
8447 rn
= (insn
>> 16) & 0xf;
8448 tmp
= load_reg(s
, rm
);
8449 tmp2
= load_reg(s
, rn
);
8451 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8453 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8455 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8456 tcg_temp_free_i32(tmp2
);
8457 store_reg(s
, rd
, tmp
);
8461 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8470 gen_exception_insn(s
, 4, EXCP_BKPT
,
8471 syn_aa32_bkpt(imm16
, false),
8472 default_exception_el(s
));
8475 /* Hypervisor call (v7) */
8483 /* Secure monitor call (v6+) */
8491 g_assert_not_reached();
8495 case 0x8: /* signed multiply */
8500 rs
= (insn
>> 8) & 0xf;
8501 rn
= (insn
>> 12) & 0xf;
8502 rd
= (insn
>> 16) & 0xf;
8504 /* (32 * 16) >> 16 */
8505 tmp
= load_reg(s
, rm
);
8506 tmp2
= load_reg(s
, rs
);
8508 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8511 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8512 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8513 tmp
= tcg_temp_new_i32();
8514 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8515 tcg_temp_free_i64(tmp64
);
8516 if ((sh
& 2) == 0) {
8517 tmp2
= load_reg(s
, rn
);
8518 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8519 tcg_temp_free_i32(tmp2
);
8521 store_reg(s
, rd
, tmp
);
8524 tmp
= load_reg(s
, rm
);
8525 tmp2
= load_reg(s
, rs
);
8526 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8527 tcg_temp_free_i32(tmp2
);
8529 tmp64
= tcg_temp_new_i64();
8530 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8531 tcg_temp_free_i32(tmp
);
8532 gen_addq(s
, tmp64
, rn
, rd
);
8533 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8534 tcg_temp_free_i64(tmp64
);
8537 tmp2
= load_reg(s
, rn
);
8538 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8539 tcg_temp_free_i32(tmp2
);
8541 store_reg(s
, rd
, tmp
);
8548 } else if (((insn
& 0x0e000000) == 0 &&
8549 (insn
& 0x00000090) != 0x90) ||
8550 ((insn
& 0x0e000000) == (1 << 25))) {
8551 int set_cc
, logic_cc
, shiftop
;
8553 op1
= (insn
>> 21) & 0xf;
8554 set_cc
= (insn
>> 20) & 1;
8555 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8557 /* data processing instruction */
8558 if (insn
& (1 << 25)) {
8559 /* immediate operand */
8561 shift
= ((insn
>> 8) & 0xf) * 2;
8563 val
= (val
>> shift
) | (val
<< (32 - shift
));
8565 tmp2
= tcg_temp_new_i32();
8566 tcg_gen_movi_i32(tmp2
, val
);
8567 if (logic_cc
&& shift
) {
8568 gen_set_CF_bit31(tmp2
);
8573 tmp2
= load_reg(s
, rm
);
8574 shiftop
= (insn
>> 5) & 3;
8575 if (!(insn
& (1 << 4))) {
8576 shift
= (insn
>> 7) & 0x1f;
8577 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8579 rs
= (insn
>> 8) & 0xf;
8580 tmp
= load_reg(s
, rs
);
8581 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8584 if (op1
!= 0x0f && op1
!= 0x0d) {
8585 rn
= (insn
>> 16) & 0xf;
8586 tmp
= load_reg(s
, rn
);
8588 TCGV_UNUSED_I32(tmp
);
8590 rd
= (insn
>> 12) & 0xf;
8593 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8597 store_reg_bx(s
, rd
, tmp
);
8600 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8604 store_reg_bx(s
, rd
, tmp
);
8607 if (set_cc
&& rd
== 15) {
8608 /* SUBS r15, ... is used for exception return. */
8612 gen_sub_CC(tmp
, tmp
, tmp2
);
8613 gen_exception_return(s
, tmp
);
8616 gen_sub_CC(tmp
, tmp
, tmp2
);
8618 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8620 store_reg_bx(s
, rd
, tmp
);
8625 gen_sub_CC(tmp
, tmp2
, tmp
);
8627 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8629 store_reg_bx(s
, rd
, tmp
);
8633 gen_add_CC(tmp
, tmp
, tmp2
);
8635 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8637 store_reg_bx(s
, rd
, tmp
);
8641 gen_adc_CC(tmp
, tmp
, tmp2
);
8643 gen_add_carry(tmp
, tmp
, tmp2
);
8645 store_reg_bx(s
, rd
, tmp
);
8649 gen_sbc_CC(tmp
, tmp
, tmp2
);
8651 gen_sub_carry(tmp
, tmp
, tmp2
);
8653 store_reg_bx(s
, rd
, tmp
);
8657 gen_sbc_CC(tmp
, tmp2
, tmp
);
8659 gen_sub_carry(tmp
, tmp2
, tmp
);
8661 store_reg_bx(s
, rd
, tmp
);
8665 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8668 tcg_temp_free_i32(tmp
);
8672 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8675 tcg_temp_free_i32(tmp
);
8679 gen_sub_CC(tmp
, tmp
, tmp2
);
8681 tcg_temp_free_i32(tmp
);
8685 gen_add_CC(tmp
, tmp
, tmp2
);
8687 tcg_temp_free_i32(tmp
);
8690 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8694 store_reg_bx(s
, rd
, tmp
);
8697 if (logic_cc
&& rd
== 15) {
8698 /* MOVS r15, ... is used for exception return. */
8702 gen_exception_return(s
, tmp2
);
8707 store_reg_bx(s
, rd
, tmp2
);
8711 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8715 store_reg_bx(s
, rd
, tmp
);
8719 tcg_gen_not_i32(tmp2
, tmp2
);
8723 store_reg_bx(s
, rd
, tmp2
);
8726 if (op1
!= 0x0f && op1
!= 0x0d) {
8727 tcg_temp_free_i32(tmp2
);
8730 /* other instructions */
8731 op1
= (insn
>> 24) & 0xf;
8735 /* multiplies, extra load/stores */
8736 sh
= (insn
>> 5) & 3;
8739 rd
= (insn
>> 16) & 0xf;
8740 rn
= (insn
>> 12) & 0xf;
8741 rs
= (insn
>> 8) & 0xf;
8743 op1
= (insn
>> 20) & 0xf;
8745 case 0: case 1: case 2: case 3: case 6:
8747 tmp
= load_reg(s
, rs
);
8748 tmp2
= load_reg(s
, rm
);
8749 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8750 tcg_temp_free_i32(tmp2
);
8751 if (insn
& (1 << 22)) {
8752 /* Subtract (mls) */
8754 tmp2
= load_reg(s
, rn
);
8755 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8756 tcg_temp_free_i32(tmp2
);
8757 } else if (insn
& (1 << 21)) {
8759 tmp2
= load_reg(s
, rn
);
8760 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8761 tcg_temp_free_i32(tmp2
);
8763 if (insn
& (1 << 20))
8765 store_reg(s
, rd
, tmp
);
8768 /* 64 bit mul double accumulate (UMAAL) */
8770 tmp
= load_reg(s
, rs
);
8771 tmp2
= load_reg(s
, rm
);
8772 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8773 gen_addq_lo(s
, tmp64
, rn
);
8774 gen_addq_lo(s
, tmp64
, rd
);
8775 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8776 tcg_temp_free_i64(tmp64
);
8778 case 8: case 9: case 10: case 11:
8779 case 12: case 13: case 14: case 15:
8780 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8781 tmp
= load_reg(s
, rs
);
8782 tmp2
= load_reg(s
, rm
);
8783 if (insn
& (1 << 22)) {
8784 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8786 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8788 if (insn
& (1 << 21)) { /* mult accumulate */
8789 TCGv_i32 al
= load_reg(s
, rn
);
8790 TCGv_i32 ah
= load_reg(s
, rd
);
8791 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8792 tcg_temp_free_i32(al
);
8793 tcg_temp_free_i32(ah
);
8795 if (insn
& (1 << 20)) {
8796 gen_logicq_cc(tmp
, tmp2
);
8798 store_reg(s
, rn
, tmp
);
8799 store_reg(s
, rd
, tmp2
);
8805 rn
= (insn
>> 16) & 0xf;
8806 rd
= (insn
>> 12) & 0xf;
8807 if (insn
& (1 << 23)) {
8808 /* load/store exclusive */
8809 int op2
= (insn
>> 8) & 3;
8810 op1
= (insn
>> 21) & 0x3;
8813 case 0: /* lda/stl */
8819 case 1: /* reserved */
8821 case 2: /* ldaex/stlex */
8824 case 3: /* ldrex/strex */
8833 addr
= tcg_temp_local_new_i32();
8834 load_reg_var(s
, addr
, rn
);
8836 /* Since the emulation does not have barriers,
8837 the acquire/release semantics need no special
8840 if (insn
& (1 << 20)) {
8841 tmp
= tcg_temp_new_i32();
8844 gen_aa32_ld32u_iss(s
, tmp
, addr
,
8849 gen_aa32_ld8u_iss(s
, tmp
, addr
,
8854 gen_aa32_ld16u_iss(s
, tmp
, addr
,
8861 store_reg(s
, rd
, tmp
);
8864 tmp
= load_reg(s
, rm
);
8867 gen_aa32_st32_iss(s
, tmp
, addr
,
8872 gen_aa32_st8_iss(s
, tmp
, addr
,
8877 gen_aa32_st16_iss(s
, tmp
, addr
,
8884 tcg_temp_free_i32(tmp
);
8886 } else if (insn
& (1 << 20)) {
8889 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8891 case 1: /* ldrexd */
8892 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8894 case 2: /* ldrexb */
8895 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8897 case 3: /* ldrexh */
8898 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8907 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8909 case 1: /* strexd */
8910 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8912 case 2: /* strexb */
8913 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8915 case 3: /* strexh */
8916 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8922 tcg_temp_free_i32(addr
);
8925 TCGMemOp opc
= s
->be_data
;
8927 /* SWP instruction */
8930 if (insn
& (1 << 22)) {
8933 opc
|= MO_UL
| MO_ALIGN
;
8936 addr
= load_reg(s
, rn
);
8937 taddr
= gen_aa32_addr(s
, addr
, opc
);
8938 tcg_temp_free_i32(addr
);
8940 tmp
= load_reg(s
, rm
);
8941 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
8942 get_mem_index(s
), opc
);
8943 tcg_temp_free(taddr
);
8944 store_reg(s
, rd
, tmp
);
8949 bool load
= insn
& (1 << 20);
8950 bool wbit
= insn
& (1 << 21);
8951 bool pbit
= insn
& (1 << 24);
8952 bool doubleword
= false;
8955 /* Misc load/store */
8956 rn
= (insn
>> 16) & 0xf;
8957 rd
= (insn
>> 12) & 0xf;
8959 /* ISS not valid if writeback */
8960 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
8962 if (!load
&& (sh
& 2)) {
8966 /* UNPREDICTABLE; we choose to UNDEF */
8969 load
= (sh
& 1) == 0;
8973 addr
= load_reg(s
, rn
);
8975 gen_add_datah_offset(s
, insn
, 0, addr
);
8982 tmp
= load_reg(s
, rd
);
8983 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8984 tcg_temp_free_i32(tmp
);
8985 tcg_gen_addi_i32(addr
, addr
, 4);
8986 tmp
= load_reg(s
, rd
+ 1);
8987 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8988 tcg_temp_free_i32(tmp
);
8991 tmp
= tcg_temp_new_i32();
8992 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8993 store_reg(s
, rd
, tmp
);
8994 tcg_gen_addi_i32(addr
, addr
, 4);
8995 tmp
= tcg_temp_new_i32();
8996 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8999 address_offset
= -4;
9002 tmp
= tcg_temp_new_i32();
9005 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9009 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9014 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9020 tmp
= load_reg(s
, rd
);
9021 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9022 tcg_temp_free_i32(tmp
);
9024 /* Perform base writeback before the loaded value to
9025 ensure correct behavior with overlapping index registers.
9026 ldrd with base writeback is undefined if the
9027 destination and index registers overlap. */
9029 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9030 store_reg(s
, rn
, addr
);
9033 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9034 store_reg(s
, rn
, addr
);
9036 tcg_temp_free_i32(addr
);
9039 /* Complete the load. */
9040 store_reg(s
, rd
, tmp
);
9049 if (insn
& (1 << 4)) {
9051 /* Armv6 Media instructions. */
9053 rn
= (insn
>> 16) & 0xf;
9054 rd
= (insn
>> 12) & 0xf;
9055 rs
= (insn
>> 8) & 0xf;
9056 switch ((insn
>> 23) & 3) {
9057 case 0: /* Parallel add/subtract. */
9058 op1
= (insn
>> 20) & 7;
9059 tmp
= load_reg(s
, rn
);
9060 tmp2
= load_reg(s
, rm
);
9061 sh
= (insn
>> 5) & 7;
9062 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9064 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9065 tcg_temp_free_i32(tmp2
);
9066 store_reg(s
, rd
, tmp
);
9069 if ((insn
& 0x00700020) == 0) {
9070 /* Halfword pack. */
9071 tmp
= load_reg(s
, rn
);
9072 tmp2
= load_reg(s
, rm
);
9073 shift
= (insn
>> 7) & 0x1f;
9074 if (insn
& (1 << 6)) {
9078 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9079 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9080 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9084 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9085 tcg_gen_ext16u_i32(tmp
, tmp
);
9086 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9088 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9089 tcg_temp_free_i32(tmp2
);
9090 store_reg(s
, rd
, tmp
);
9091 } else if ((insn
& 0x00200020) == 0x00200000) {
9093 tmp
= load_reg(s
, rm
);
9094 shift
= (insn
>> 7) & 0x1f;
9095 if (insn
& (1 << 6)) {
9098 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9100 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9102 sh
= (insn
>> 16) & 0x1f;
9103 tmp2
= tcg_const_i32(sh
);
9104 if (insn
& (1 << 22))
9105 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9107 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9108 tcg_temp_free_i32(tmp2
);
9109 store_reg(s
, rd
, tmp
);
9110 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9112 tmp
= load_reg(s
, rm
);
9113 sh
= (insn
>> 16) & 0x1f;
9114 tmp2
= tcg_const_i32(sh
);
9115 if (insn
& (1 << 22))
9116 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9118 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9119 tcg_temp_free_i32(tmp2
);
9120 store_reg(s
, rd
, tmp
);
9121 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9123 tmp
= load_reg(s
, rn
);
9124 tmp2
= load_reg(s
, rm
);
9125 tmp3
= tcg_temp_new_i32();
9126 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9127 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9128 tcg_temp_free_i32(tmp3
);
9129 tcg_temp_free_i32(tmp2
);
9130 store_reg(s
, rd
, tmp
);
9131 } else if ((insn
& 0x000003e0) == 0x00000060) {
9132 tmp
= load_reg(s
, rm
);
9133 shift
= (insn
>> 10) & 3;
9134 /* ??? In many cases it's not necessary to do a
9135 rotate, a shift is sufficient. */
9137 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9138 op1
= (insn
>> 20) & 7;
9140 case 0: gen_sxtb16(tmp
); break;
9141 case 2: gen_sxtb(tmp
); break;
9142 case 3: gen_sxth(tmp
); break;
9143 case 4: gen_uxtb16(tmp
); break;
9144 case 6: gen_uxtb(tmp
); break;
9145 case 7: gen_uxth(tmp
); break;
9146 default: goto illegal_op
;
9149 tmp2
= load_reg(s
, rn
);
9150 if ((op1
& 3) == 0) {
9151 gen_add16(tmp
, tmp2
);
9153 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9154 tcg_temp_free_i32(tmp2
);
9157 store_reg(s
, rd
, tmp
);
9158 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9160 tmp
= load_reg(s
, rm
);
9161 if (insn
& (1 << 22)) {
9162 if (insn
& (1 << 7)) {
9166 gen_helper_rbit(tmp
, tmp
);
9169 if (insn
& (1 << 7))
9172 tcg_gen_bswap32_i32(tmp
, tmp
);
9174 store_reg(s
, rd
, tmp
);
9179 case 2: /* Multiplies (Type 3). */
9180 switch ((insn
>> 20) & 0x7) {
9182 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9183 /* op2 not 00x or 11x : UNDEF */
9186 /* Signed multiply most significant [accumulate].
9187 (SMMUL, SMMLA, SMMLS) */
9188 tmp
= load_reg(s
, rm
);
9189 tmp2
= load_reg(s
, rs
);
9190 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9193 tmp
= load_reg(s
, rd
);
9194 if (insn
& (1 << 6)) {
9195 tmp64
= gen_subq_msw(tmp64
, tmp
);
9197 tmp64
= gen_addq_msw(tmp64
, tmp
);
9200 if (insn
& (1 << 5)) {
9201 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9203 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9204 tmp
= tcg_temp_new_i32();
9205 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9206 tcg_temp_free_i64(tmp64
);
9207 store_reg(s
, rn
, tmp
);
9211 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9212 if (insn
& (1 << 7)) {
9215 tmp
= load_reg(s
, rm
);
9216 tmp2
= load_reg(s
, rs
);
9217 if (insn
& (1 << 5))
9218 gen_swap_half(tmp2
);
9219 gen_smul_dual(tmp
, tmp2
);
9220 if (insn
& (1 << 22)) {
9221 /* smlald, smlsld */
9224 tmp64
= tcg_temp_new_i64();
9225 tmp64_2
= tcg_temp_new_i64();
9226 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9227 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9228 tcg_temp_free_i32(tmp
);
9229 tcg_temp_free_i32(tmp2
);
9230 if (insn
& (1 << 6)) {
9231 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9233 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9235 tcg_temp_free_i64(tmp64_2
);
9236 gen_addq(s
, tmp64
, rd
, rn
);
9237 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9238 tcg_temp_free_i64(tmp64
);
9240 /* smuad, smusd, smlad, smlsd */
9241 if (insn
& (1 << 6)) {
9242 /* This subtraction cannot overflow. */
9243 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9245 /* This addition cannot overflow 32 bits;
9246 * however it may overflow considered as a
9247 * signed operation, in which case we must set
9250 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9252 tcg_temp_free_i32(tmp2
);
9255 tmp2
= load_reg(s
, rd
);
9256 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9257 tcg_temp_free_i32(tmp2
);
9259 store_reg(s
, rn
, tmp
);
9265 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9268 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9271 tmp
= load_reg(s
, rm
);
9272 tmp2
= load_reg(s
, rs
);
9273 if (insn
& (1 << 21)) {
9274 gen_helper_udiv(tmp
, tmp
, tmp2
);
9276 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9278 tcg_temp_free_i32(tmp2
);
9279 store_reg(s
, rn
, tmp
);
9286 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9288 case 0: /* Unsigned sum of absolute differences. */
9290 tmp
= load_reg(s
, rm
);
9291 tmp2
= load_reg(s
, rs
);
9292 gen_helper_usad8(tmp
, tmp
, tmp2
);
9293 tcg_temp_free_i32(tmp2
);
9295 tmp2
= load_reg(s
, rd
);
9296 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9297 tcg_temp_free_i32(tmp2
);
9299 store_reg(s
, rn
, tmp
);
9301 case 0x20: case 0x24: case 0x28: case 0x2c:
9302 /* Bitfield insert/clear. */
9304 shift
= (insn
>> 7) & 0x1f;
9305 i
= (insn
>> 16) & 0x1f;
9307 /* UNPREDICTABLE; we choose to UNDEF */
9312 tmp
= tcg_temp_new_i32();
9313 tcg_gen_movi_i32(tmp
, 0);
9315 tmp
= load_reg(s
, rm
);
9318 tmp2
= load_reg(s
, rd
);
9319 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9320 tcg_temp_free_i32(tmp2
);
9322 store_reg(s
, rd
, tmp
);
9324 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9325 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9327 tmp
= load_reg(s
, rm
);
9328 shift
= (insn
>> 7) & 0x1f;
9329 i
= ((insn
>> 16) & 0x1f) + 1;
9334 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9336 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9339 store_reg(s
, rd
, tmp
);
9349 /* Check for undefined extension instructions
9350 * per the ARM Bible IE:
9351 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9353 sh
= (0xf << 20) | (0xf << 4);
9354 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9358 /* load/store byte/word */
9359 rn
= (insn
>> 16) & 0xf;
9360 rd
= (insn
>> 12) & 0xf;
9361 tmp2
= load_reg(s
, rn
);
9362 if ((insn
& 0x01200000) == 0x00200000) {
9364 i
= get_a32_user_mem_index(s
);
9366 i
= get_mem_index(s
);
9368 if (insn
& (1 << 24))
9369 gen_add_data_offset(s
, insn
, tmp2
);
9370 if (insn
& (1 << 20)) {
9372 tmp
= tcg_temp_new_i32();
9373 if (insn
& (1 << 22)) {
9374 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9376 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9380 tmp
= load_reg(s
, rd
);
9381 if (insn
& (1 << 22)) {
9382 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9384 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9386 tcg_temp_free_i32(tmp
);
9388 if (!(insn
& (1 << 24))) {
9389 gen_add_data_offset(s
, insn
, tmp2
);
9390 store_reg(s
, rn
, tmp2
);
9391 } else if (insn
& (1 << 21)) {
9392 store_reg(s
, rn
, tmp2
);
9394 tcg_temp_free_i32(tmp2
);
9396 if (insn
& (1 << 20)) {
9397 /* Complete the load. */
9398 store_reg_from_load(s
, rd
, tmp
);
9404 int j
, n
, loaded_base
;
9405 bool exc_return
= false;
9406 bool is_load
= extract32(insn
, 20, 1);
9408 TCGv_i32 loaded_var
;
9409 /* load/store multiple words */
9410 /* XXX: store correct base if write back */
9411 if (insn
& (1 << 22)) {
9412 /* LDM (user), LDM (exception return) and STM (user) */
9414 goto illegal_op
; /* only usable in supervisor mode */
9416 if (is_load
&& extract32(insn
, 15, 1)) {
9422 rn
= (insn
>> 16) & 0xf;
9423 addr
= load_reg(s
, rn
);
9425 /* compute total size */
9427 TCGV_UNUSED_I32(loaded_var
);
9430 if (insn
& (1 << i
))
9433 /* XXX: test invalid n == 0 case ? */
9434 if (insn
& (1 << 23)) {
9435 if (insn
& (1 << 24)) {
9437 tcg_gen_addi_i32(addr
, addr
, 4);
9439 /* post increment */
9442 if (insn
& (1 << 24)) {
9444 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9446 /* post decrement */
9448 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9453 if (insn
& (1 << i
)) {
9456 tmp
= tcg_temp_new_i32();
9457 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9459 tmp2
= tcg_const_i32(i
);
9460 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9461 tcg_temp_free_i32(tmp2
);
9462 tcg_temp_free_i32(tmp
);
9463 } else if (i
== rn
) {
9466 } else if (rn
== 15 && exc_return
) {
9467 store_pc_exc_ret(s
, tmp
);
9469 store_reg_from_load(s
, i
, tmp
);
9474 /* special case: r15 = PC + 8 */
9475 val
= (long)s
->pc
+ 4;
9476 tmp
= tcg_temp_new_i32();
9477 tcg_gen_movi_i32(tmp
, val
);
9479 tmp
= tcg_temp_new_i32();
9480 tmp2
= tcg_const_i32(i
);
9481 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9482 tcg_temp_free_i32(tmp2
);
9484 tmp
= load_reg(s
, i
);
9486 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9487 tcg_temp_free_i32(tmp
);
9490 /* no need to add after the last transfer */
9492 tcg_gen_addi_i32(addr
, addr
, 4);
9495 if (insn
& (1 << 21)) {
9497 if (insn
& (1 << 23)) {
9498 if (insn
& (1 << 24)) {
9501 /* post increment */
9502 tcg_gen_addi_i32(addr
, addr
, 4);
9505 if (insn
& (1 << 24)) {
9508 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9510 /* post decrement */
9511 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9514 store_reg(s
, rn
, addr
);
9516 tcg_temp_free_i32(addr
);
9519 store_reg(s
, rn
, loaded_var
);
9522 /* Restore CPSR from SPSR. */
9523 tmp
= load_cpu_field(spsr
);
9524 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9525 tcg_temp_free_i32(tmp
);
9526 s
->is_jmp
= DISAS_JUMP
;
9535 /* branch (and link) */
9536 val
= (int32_t)s
->pc
;
9537 if (insn
& (1 << 24)) {
9538 tmp
= tcg_temp_new_i32();
9539 tcg_gen_movi_i32(tmp
, val
);
9540 store_reg(s
, 14, tmp
);
9542 offset
= sextract32(insn
<< 2, 0, 26);
9550 if (((insn
>> 8) & 0xe) == 10) {
9552 if (disas_vfp_insn(s
, insn
)) {
9555 } else if (disas_coproc_insn(s
, insn
)) {
9562 gen_set_pc_im(s
, s
->pc
);
9563 s
->svc_imm
= extract32(insn
, 0, 24);
9564 s
->is_jmp
= DISAS_SWI
;
9568 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9569 default_exception_el(s
));
9575 /* Return true if this is a Thumb-2 logical op. */
9577 thumb2_logic_op(int op
)
9582 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9583 then set condition code flags based on the result of the operation.
9584 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9585 to the high bit of T1.
9586 Returns zero if the opcode is valid. */
9589 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9590 TCGv_i32 t0
, TCGv_i32 t1
)
9597 tcg_gen_and_i32(t0
, t0
, t1
);
9601 tcg_gen_andc_i32(t0
, t0
, t1
);
9605 tcg_gen_or_i32(t0
, t0
, t1
);
9609 tcg_gen_orc_i32(t0
, t0
, t1
);
9613 tcg_gen_xor_i32(t0
, t0
, t1
);
9618 gen_add_CC(t0
, t0
, t1
);
9620 tcg_gen_add_i32(t0
, t0
, t1
);
9624 gen_adc_CC(t0
, t0
, t1
);
9630 gen_sbc_CC(t0
, t0
, t1
);
9632 gen_sub_carry(t0
, t0
, t1
);
9637 gen_sub_CC(t0
, t0
, t1
);
9639 tcg_gen_sub_i32(t0
, t0
, t1
);
9643 gen_sub_CC(t0
, t1
, t0
);
9645 tcg_gen_sub_i32(t0
, t1
, t0
);
9647 default: /* 5, 6, 7, 9, 12, 15. */
9653 gen_set_CF_bit31(t1
);
9658 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9660 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9662 uint32_t insn
, imm
, shift
, offset
;
9663 uint32_t rd
, rn
, rm
, rs
;
9674 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9675 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9676 /* Thumb-1 cores may need to treat bl and blx as a pair of
9677 16-bit instructions to get correct prefetch abort behavior. */
9679 if ((insn
& (1 << 12)) == 0) {
9681 /* Second half of blx. */
9682 offset
= ((insn
& 0x7ff) << 1);
9683 tmp
= load_reg(s
, 14);
9684 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9685 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9687 tmp2
= tcg_temp_new_i32();
9688 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9689 store_reg(s
, 14, tmp2
);
9693 if (insn
& (1 << 11)) {
9694 /* Second half of bl. */
9695 offset
= ((insn
& 0x7ff) << 1) | 1;
9696 tmp
= load_reg(s
, 14);
9697 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9699 tmp2
= tcg_temp_new_i32();
9700 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9701 store_reg(s
, 14, tmp2
);
9705 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9706 /* Instruction spans a page boundary. Implement it as two
9707 16-bit instructions in case the second half causes an
9709 offset
= ((int32_t)insn
<< 21) >> 9;
9710 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9713 /* Fall through to 32-bit decode. */
9716 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9718 insn
|= (uint32_t)insn_hw1
<< 16;
9720 if ((insn
& 0xf800e800) != 0xf000e800) {
9724 rn
= (insn
>> 16) & 0xf;
9725 rs
= (insn
>> 12) & 0xf;
9726 rd
= (insn
>> 8) & 0xf;
9728 switch ((insn
>> 25) & 0xf) {
9729 case 0: case 1: case 2: case 3:
9730 /* 16-bit instructions. Should never happen. */
9733 if (insn
& (1 << 22)) {
9734 /* Other load/store, table branch. */
9735 if (insn
& 0x01200000) {
9736 /* Load/store doubleword. */
9738 addr
= tcg_temp_new_i32();
9739 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9741 addr
= load_reg(s
, rn
);
9743 offset
= (insn
& 0xff) * 4;
9744 if ((insn
& (1 << 23)) == 0)
9746 if (insn
& (1 << 24)) {
9747 tcg_gen_addi_i32(addr
, addr
, offset
);
9750 if (insn
& (1 << 20)) {
9752 tmp
= tcg_temp_new_i32();
9753 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9754 store_reg(s
, rs
, tmp
);
9755 tcg_gen_addi_i32(addr
, addr
, 4);
9756 tmp
= tcg_temp_new_i32();
9757 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9758 store_reg(s
, rd
, tmp
);
9761 tmp
= load_reg(s
, rs
);
9762 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9763 tcg_temp_free_i32(tmp
);
9764 tcg_gen_addi_i32(addr
, addr
, 4);
9765 tmp
= load_reg(s
, rd
);
9766 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9767 tcg_temp_free_i32(tmp
);
9769 if (insn
& (1 << 21)) {
9770 /* Base writeback. */
9773 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9774 store_reg(s
, rn
, addr
);
9776 tcg_temp_free_i32(addr
);
9778 } else if ((insn
& (1 << 23)) == 0) {
9779 /* Load/store exclusive word. */
9780 addr
= tcg_temp_local_new_i32();
9781 load_reg_var(s
, addr
, rn
);
9782 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9783 if (insn
& (1 << 20)) {
9784 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9786 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9788 tcg_temp_free_i32(addr
);
9789 } else if ((insn
& (7 << 5)) == 0) {
9792 addr
= tcg_temp_new_i32();
9793 tcg_gen_movi_i32(addr
, s
->pc
);
9795 addr
= load_reg(s
, rn
);
9797 tmp
= load_reg(s
, rm
);
9798 tcg_gen_add_i32(addr
, addr
, tmp
);
9799 if (insn
& (1 << 4)) {
9801 tcg_gen_add_i32(addr
, addr
, tmp
);
9802 tcg_temp_free_i32(tmp
);
9803 tmp
= tcg_temp_new_i32();
9804 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9806 tcg_temp_free_i32(tmp
);
9807 tmp
= tcg_temp_new_i32();
9808 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9810 tcg_temp_free_i32(addr
);
9811 tcg_gen_shli_i32(tmp
, tmp
, 1);
9812 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9813 store_reg(s
, 15, tmp
);
9815 int op2
= (insn
>> 6) & 0x3;
9816 op
= (insn
>> 4) & 0x3;
9821 /* Load/store exclusive byte/halfword/doubleword */
9828 /* Load-acquire/store-release */
9834 /* Load-acquire/store-release exclusive */
9838 addr
= tcg_temp_local_new_i32();
9839 load_reg_var(s
, addr
, rn
);
9841 if (insn
& (1 << 20)) {
9842 tmp
= tcg_temp_new_i32();
9845 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
9849 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9853 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
9859 store_reg(s
, rs
, tmp
);
9861 tmp
= load_reg(s
, rs
);
9864 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
9868 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
9872 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
9878 tcg_temp_free_i32(tmp
);
9880 } else if (insn
& (1 << 20)) {
9881 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9883 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9885 tcg_temp_free_i32(addr
);
9888 /* Load/store multiple, RFE, SRS. */
9889 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9890 /* RFE, SRS: not available in user mode or on M profile */
9891 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9894 if (insn
& (1 << 20)) {
9896 addr
= load_reg(s
, rn
);
9897 if ((insn
& (1 << 24)) == 0)
9898 tcg_gen_addi_i32(addr
, addr
, -8);
9899 /* Load PC into tmp and CPSR into tmp2. */
9900 tmp
= tcg_temp_new_i32();
9901 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9902 tcg_gen_addi_i32(addr
, addr
, 4);
9903 tmp2
= tcg_temp_new_i32();
9904 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9905 if (insn
& (1 << 21)) {
9906 /* Base writeback. */
9907 if (insn
& (1 << 24)) {
9908 tcg_gen_addi_i32(addr
, addr
, 4);
9910 tcg_gen_addi_i32(addr
, addr
, -4);
9912 store_reg(s
, rn
, addr
);
9914 tcg_temp_free_i32(addr
);
9916 gen_rfe(s
, tmp
, tmp2
);
9919 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9923 int i
, loaded_base
= 0;
9924 TCGv_i32 loaded_var
;
9925 /* Load/store multiple. */
9926 addr
= load_reg(s
, rn
);
9928 for (i
= 0; i
< 16; i
++) {
9929 if (insn
& (1 << i
))
9932 if (insn
& (1 << 24)) {
9933 tcg_gen_addi_i32(addr
, addr
, -offset
);
9936 TCGV_UNUSED_I32(loaded_var
);
9937 for (i
= 0; i
< 16; i
++) {
9938 if ((insn
& (1 << i
)) == 0)
9940 if (insn
& (1 << 20)) {
9942 tmp
= tcg_temp_new_i32();
9943 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9945 gen_bx_excret(s
, tmp
);
9946 } else if (i
== rn
) {
9950 store_reg(s
, i
, tmp
);
9954 tmp
= load_reg(s
, i
);
9955 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9956 tcg_temp_free_i32(tmp
);
9958 tcg_gen_addi_i32(addr
, addr
, 4);
9961 store_reg(s
, rn
, loaded_var
);
9963 if (insn
& (1 << 21)) {
9964 /* Base register writeback. */
9965 if (insn
& (1 << 24)) {
9966 tcg_gen_addi_i32(addr
, addr
, -offset
);
9968 /* Fault if writeback register is in register list. */
9969 if (insn
& (1 << rn
))
9971 store_reg(s
, rn
, addr
);
9973 tcg_temp_free_i32(addr
);
9980 op
= (insn
>> 21) & 0xf;
9982 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9985 /* Halfword pack. */
9986 tmp
= load_reg(s
, rn
);
9987 tmp2
= load_reg(s
, rm
);
9988 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9989 if (insn
& (1 << 5)) {
9993 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9994 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9995 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9999 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10000 tcg_gen_ext16u_i32(tmp
, tmp
);
10001 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10003 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10004 tcg_temp_free_i32(tmp2
);
10005 store_reg(s
, rd
, tmp
);
10007 /* Data processing register constant shift. */
10009 tmp
= tcg_temp_new_i32();
10010 tcg_gen_movi_i32(tmp
, 0);
10012 tmp
= load_reg(s
, rn
);
10014 tmp2
= load_reg(s
, rm
);
10016 shiftop
= (insn
>> 4) & 3;
10017 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10018 conds
= (insn
& (1 << 20)) != 0;
10019 logic_cc
= (conds
&& thumb2_logic_op(op
));
10020 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10021 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10023 tcg_temp_free_i32(tmp2
);
10025 store_reg(s
, rd
, tmp
);
10027 tcg_temp_free_i32(tmp
);
10031 case 13: /* Misc data processing. */
10032 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10033 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10036 case 0: /* Register controlled shift. */
10037 tmp
= load_reg(s
, rn
);
10038 tmp2
= load_reg(s
, rm
);
10039 if ((insn
& 0x70) != 0)
10041 op
= (insn
>> 21) & 3;
10042 logic_cc
= (insn
& (1 << 20)) != 0;
10043 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10046 store_reg(s
, rd
, tmp
);
10048 case 1: /* Sign/zero extend. */
10049 op
= (insn
>> 20) & 7;
10051 case 0: /* SXTAH, SXTH */
10052 case 1: /* UXTAH, UXTH */
10053 case 4: /* SXTAB, SXTB */
10054 case 5: /* UXTAB, UXTB */
10056 case 2: /* SXTAB16, SXTB16 */
10057 case 3: /* UXTAB16, UXTB16 */
10058 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10066 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10070 tmp
= load_reg(s
, rm
);
10071 shift
= (insn
>> 4) & 3;
10072 /* ??? In many cases it's not necessary to do a
10073 rotate, a shift is sufficient. */
10075 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10076 op
= (insn
>> 20) & 7;
10078 case 0: gen_sxth(tmp
); break;
10079 case 1: gen_uxth(tmp
); break;
10080 case 2: gen_sxtb16(tmp
); break;
10081 case 3: gen_uxtb16(tmp
); break;
10082 case 4: gen_sxtb(tmp
); break;
10083 case 5: gen_uxtb(tmp
); break;
10085 g_assert_not_reached();
10088 tmp2
= load_reg(s
, rn
);
10089 if ((op
>> 1) == 1) {
10090 gen_add16(tmp
, tmp2
);
10092 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10093 tcg_temp_free_i32(tmp2
);
10096 store_reg(s
, rd
, tmp
);
10098 case 2: /* SIMD add/subtract. */
10099 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10102 op
= (insn
>> 20) & 7;
10103 shift
= (insn
>> 4) & 7;
10104 if ((op
& 3) == 3 || (shift
& 3) == 3)
10106 tmp
= load_reg(s
, rn
);
10107 tmp2
= load_reg(s
, rm
);
10108 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10109 tcg_temp_free_i32(tmp2
);
10110 store_reg(s
, rd
, tmp
);
10112 case 3: /* Other data processing. */
10113 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10115 /* Saturating add/subtract. */
10116 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10119 tmp
= load_reg(s
, rn
);
10120 tmp2
= load_reg(s
, rm
);
10122 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10124 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10126 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10127 tcg_temp_free_i32(tmp2
);
10130 case 0x0a: /* rbit */
10131 case 0x08: /* rev */
10132 case 0x09: /* rev16 */
10133 case 0x0b: /* revsh */
10134 case 0x18: /* clz */
10136 case 0x10: /* sel */
10137 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10141 case 0x20: /* crc32/crc32c */
10147 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10154 tmp
= load_reg(s
, rn
);
10156 case 0x0a: /* rbit */
10157 gen_helper_rbit(tmp
, tmp
);
10159 case 0x08: /* rev */
10160 tcg_gen_bswap32_i32(tmp
, tmp
);
10162 case 0x09: /* rev16 */
10165 case 0x0b: /* revsh */
10168 case 0x10: /* sel */
10169 tmp2
= load_reg(s
, rm
);
10170 tmp3
= tcg_temp_new_i32();
10171 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10172 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10173 tcg_temp_free_i32(tmp3
);
10174 tcg_temp_free_i32(tmp2
);
10176 case 0x18: /* clz */
10177 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10187 uint32_t sz
= op
& 0x3;
10188 uint32_t c
= op
& 0x8;
10190 tmp2
= load_reg(s
, rm
);
10192 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10193 } else if (sz
== 1) {
10194 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10196 tmp3
= tcg_const_i32(1 << sz
);
10198 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10200 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10202 tcg_temp_free_i32(tmp2
);
10203 tcg_temp_free_i32(tmp3
);
10207 g_assert_not_reached();
10210 store_reg(s
, rd
, tmp
);
10212 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10213 switch ((insn
>> 20) & 7) {
10214 case 0: /* 32 x 32 -> 32 */
10215 case 7: /* Unsigned sum of absolute differences. */
10217 case 1: /* 16 x 16 -> 32 */
10218 case 2: /* Dual multiply add. */
10219 case 3: /* 32 * 16 -> 32msb */
10220 case 4: /* Dual multiply subtract. */
10221 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10222 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10227 op
= (insn
>> 4) & 0xf;
10228 tmp
= load_reg(s
, rn
);
10229 tmp2
= load_reg(s
, rm
);
10230 switch ((insn
>> 20) & 7) {
10231 case 0: /* 32 x 32 -> 32 */
10232 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10233 tcg_temp_free_i32(tmp2
);
10235 tmp2
= load_reg(s
, rs
);
10237 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10239 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10240 tcg_temp_free_i32(tmp2
);
10243 case 1: /* 16 x 16 -> 32 */
10244 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10245 tcg_temp_free_i32(tmp2
);
10247 tmp2
= load_reg(s
, rs
);
10248 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10249 tcg_temp_free_i32(tmp2
);
10252 case 2: /* Dual multiply add. */
10253 case 4: /* Dual multiply subtract. */
10255 gen_swap_half(tmp2
);
10256 gen_smul_dual(tmp
, tmp2
);
10257 if (insn
& (1 << 22)) {
10258 /* This subtraction cannot overflow. */
10259 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10261 /* This addition cannot overflow 32 bits;
10262 * however it may overflow considered as a signed
10263 * operation, in which case we must set the Q flag.
10265 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10267 tcg_temp_free_i32(tmp2
);
10270 tmp2
= load_reg(s
, rs
);
10271 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10272 tcg_temp_free_i32(tmp2
);
10275 case 3: /* 32 * 16 -> 32msb */
10277 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10280 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10281 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10282 tmp
= tcg_temp_new_i32();
10283 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10284 tcg_temp_free_i64(tmp64
);
10287 tmp2
= load_reg(s
, rs
);
10288 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10289 tcg_temp_free_i32(tmp2
);
10292 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10293 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10295 tmp
= load_reg(s
, rs
);
10296 if (insn
& (1 << 20)) {
10297 tmp64
= gen_addq_msw(tmp64
, tmp
);
10299 tmp64
= gen_subq_msw(tmp64
, tmp
);
10302 if (insn
& (1 << 4)) {
10303 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10305 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10306 tmp
= tcg_temp_new_i32();
10307 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10308 tcg_temp_free_i64(tmp64
);
10310 case 7: /* Unsigned sum of absolute differences. */
10311 gen_helper_usad8(tmp
, tmp
, tmp2
);
10312 tcg_temp_free_i32(tmp2
);
10314 tmp2
= load_reg(s
, rs
);
10315 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10316 tcg_temp_free_i32(tmp2
);
10320 store_reg(s
, rd
, tmp
);
10322 case 6: case 7: /* 64-bit multiply, Divide. */
10323 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10324 tmp
= load_reg(s
, rn
);
10325 tmp2
= load_reg(s
, rm
);
10326 if ((op
& 0x50) == 0x10) {
10328 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10332 gen_helper_udiv(tmp
, tmp
, tmp2
);
10334 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10335 tcg_temp_free_i32(tmp2
);
10336 store_reg(s
, rd
, tmp
);
10337 } else if ((op
& 0xe) == 0xc) {
10338 /* Dual multiply accumulate long. */
10339 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10340 tcg_temp_free_i32(tmp
);
10341 tcg_temp_free_i32(tmp2
);
10345 gen_swap_half(tmp2
);
10346 gen_smul_dual(tmp
, tmp2
);
10348 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10350 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10352 tcg_temp_free_i32(tmp2
);
10354 tmp64
= tcg_temp_new_i64();
10355 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10356 tcg_temp_free_i32(tmp
);
10357 gen_addq(s
, tmp64
, rs
, rd
);
10358 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10359 tcg_temp_free_i64(tmp64
);
10362 /* Unsigned 64-bit multiply */
10363 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10367 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10368 tcg_temp_free_i32(tmp2
);
10369 tcg_temp_free_i32(tmp
);
10372 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10373 tcg_temp_free_i32(tmp2
);
10374 tmp64
= tcg_temp_new_i64();
10375 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10376 tcg_temp_free_i32(tmp
);
10378 /* Signed 64-bit multiply */
10379 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10384 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10385 tcg_temp_free_i64(tmp64
);
10388 gen_addq_lo(s
, tmp64
, rs
);
10389 gen_addq_lo(s
, tmp64
, rd
);
10390 } else if (op
& 0x40) {
10391 /* 64-bit accumulate. */
10392 gen_addq(s
, tmp64
, rs
, rd
);
10394 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10395 tcg_temp_free_i64(tmp64
);
10400 case 6: case 7: case 14: case 15:
10402 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10403 /* We don't currently implement M profile FP support,
10404 * so this entire space should give a NOCP fault.
10406 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10407 default_exception_el(s
));
10410 if (((insn
>> 24) & 3) == 3) {
10411 /* Translate into the equivalent ARM encoding. */
10412 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10413 if (disas_neon_data_insn(s
, insn
)) {
10416 } else if (((insn
>> 8) & 0xe) == 10) {
10417 if (disas_vfp_insn(s
, insn
)) {
10421 if (insn
& (1 << 28))
10423 if (disas_coproc_insn(s
, insn
)) {
10428 case 8: case 9: case 10: case 11:
10429 if (insn
& (1 << 15)) {
10430 /* Branches, misc control. */
10431 if (insn
& 0x5000) {
10432 /* Unconditional branch. */
10433 /* signextend(hw1[10:0]) -> offset[:12]. */
10434 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10435 /* hw1[10:0] -> offset[11:1]. */
10436 offset
|= (insn
& 0x7ff) << 1;
10437 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10438 offset[24:22] already have the same value because of the
10439 sign extension above. */
10440 offset
^= ((~insn
) & (1 << 13)) << 10;
10441 offset
^= ((~insn
) & (1 << 11)) << 11;
10443 if (insn
& (1 << 14)) {
10444 /* Branch and link. */
10445 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10449 if (insn
& (1 << 12)) {
10451 gen_jmp(s
, offset
);
10454 offset
&= ~(uint32_t)2;
10455 /* thumb2 bx, no need to check */
10456 gen_bx_im(s
, offset
);
10458 } else if (((insn
>> 23) & 7) == 7) {
10460 if (insn
& (1 << 13))
10463 if (insn
& (1 << 26)) {
10464 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10467 if (!(insn
& (1 << 20))) {
10468 /* Hypervisor call (v7) */
10469 int imm16
= extract32(insn
, 16, 4) << 12
10470 | extract32(insn
, 0, 12);
10477 /* Secure monitor call (v6+) */
10485 op
= (insn
>> 20) & 7;
10487 case 0: /* msr cpsr. */
10488 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10489 tmp
= load_reg(s
, rn
);
10490 /* the constant is the mask and SYSm fields */
10491 addr
= tcg_const_i32(insn
& 0xfff);
10492 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10493 tcg_temp_free_i32(addr
);
10494 tcg_temp_free_i32(tmp
);
10499 case 1: /* msr spsr. */
10500 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10504 if (extract32(insn
, 5, 1)) {
10506 int sysm
= extract32(insn
, 8, 4) |
10507 (extract32(insn
, 4, 1) << 4);
10510 gen_msr_banked(s
, r
, sysm
, rm
);
10514 /* MSR (for PSRs) */
10515 tmp
= load_reg(s
, rn
);
10517 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10521 case 2: /* cps, nop-hint. */
10522 if (((insn
>> 8) & 7) == 0) {
10523 gen_nop_hint(s
, insn
& 0xff);
10525 /* Implemented as NOP in user mode. */
10530 if (insn
& (1 << 10)) {
10531 if (insn
& (1 << 7))
10533 if (insn
& (1 << 6))
10535 if (insn
& (1 << 5))
10537 if (insn
& (1 << 9))
10538 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10540 if (insn
& (1 << 8)) {
10542 imm
|= (insn
& 0x1f);
10545 gen_set_psr_im(s
, offset
, 0, imm
);
10548 case 3: /* Special control operations. */
10550 op
= (insn
>> 4) & 0xf;
10552 case 2: /* clrex */
10557 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10560 /* We need to break the TB after this insn
10561 * to execute self-modifying code correctly
10562 * and also to take any pending interrupts
10565 gen_goto_tb(s
, 0, s
->pc
& ~1);
10572 /* Trivial implementation equivalent to bx.
10573 * This instruction doesn't exist at all for M-profile.
10575 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10578 tmp
= load_reg(s
, rn
);
10581 case 5: /* Exception return. */
10585 if (rn
!= 14 || rd
!= 15) {
10588 tmp
= load_reg(s
, rn
);
10589 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10590 gen_exception_return(s
, tmp
);
10593 if (extract32(insn
, 5, 1) &&
10594 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10596 int sysm
= extract32(insn
, 16, 4) |
10597 (extract32(insn
, 4, 1) << 4);
10599 gen_mrs_banked(s
, 0, sysm
, rd
);
10603 if (extract32(insn
, 16, 4) != 0xf) {
10606 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10607 extract32(insn
, 0, 8) != 0) {
10612 tmp
= tcg_temp_new_i32();
10613 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10614 addr
= tcg_const_i32(insn
& 0xff);
10615 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10616 tcg_temp_free_i32(addr
);
10618 gen_helper_cpsr_read(tmp
, cpu_env
);
10620 store_reg(s
, rd
, tmp
);
10623 if (extract32(insn
, 5, 1) &&
10624 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10626 int sysm
= extract32(insn
, 16, 4) |
10627 (extract32(insn
, 4, 1) << 4);
10629 gen_mrs_banked(s
, 1, sysm
, rd
);
10634 /* Not accessible in user mode. */
10635 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10639 if (extract32(insn
, 16, 4) != 0xf ||
10640 extract32(insn
, 0, 8) != 0) {
10644 tmp
= load_cpu_field(spsr
);
10645 store_reg(s
, rd
, tmp
);
10650 /* Conditional branch. */
10651 op
= (insn
>> 22) & 0xf;
10652 /* Generate a conditional jump to next instruction. */
10653 s
->condlabel
= gen_new_label();
10654 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10657 /* offset[11:1] = insn[10:0] */
10658 offset
= (insn
& 0x7ff) << 1;
10659 /* offset[17:12] = insn[21:16]. */
10660 offset
|= (insn
& 0x003f0000) >> 4;
10661 /* offset[31:20] = insn[26]. */
10662 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10663 /* offset[18] = insn[13]. */
10664 offset
|= (insn
& (1 << 13)) << 5;
10665 /* offset[19] = insn[11]. */
10666 offset
|= (insn
& (1 << 11)) << 8;
10668 /* jump to the offset */
10669 gen_jmp(s
, s
->pc
+ offset
);
10672 /* Data processing immediate. */
10673 if (insn
& (1 << 25)) {
10674 if (insn
& (1 << 24)) {
10675 if (insn
& (1 << 20))
10677 /* Bitfield/Saturate. */
10678 op
= (insn
>> 21) & 7;
10680 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10682 tmp
= tcg_temp_new_i32();
10683 tcg_gen_movi_i32(tmp
, 0);
10685 tmp
= load_reg(s
, rn
);
10688 case 2: /* Signed bitfield extract. */
10690 if (shift
+ imm
> 32)
10693 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
10696 case 6: /* Unsigned bitfield extract. */
10698 if (shift
+ imm
> 32)
10701 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
10704 case 3: /* Bitfield insert/clear. */
10707 imm
= imm
+ 1 - shift
;
10709 tmp2
= load_reg(s
, rd
);
10710 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10711 tcg_temp_free_i32(tmp2
);
10716 default: /* Saturate. */
10719 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10721 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10723 tmp2
= tcg_const_i32(imm
);
10726 if ((op
& 1) && shift
== 0) {
10727 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10728 tcg_temp_free_i32(tmp
);
10729 tcg_temp_free_i32(tmp2
);
10732 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10734 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10738 if ((op
& 1) && shift
== 0) {
10739 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10740 tcg_temp_free_i32(tmp
);
10741 tcg_temp_free_i32(tmp2
);
10744 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10746 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10749 tcg_temp_free_i32(tmp2
);
10752 store_reg(s
, rd
, tmp
);
10754 imm
= ((insn
& 0x04000000) >> 15)
10755 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10756 if (insn
& (1 << 22)) {
10757 /* 16-bit immediate. */
10758 imm
|= (insn
>> 4) & 0xf000;
10759 if (insn
& (1 << 23)) {
10761 tmp
= load_reg(s
, rd
);
10762 tcg_gen_ext16u_i32(tmp
, tmp
);
10763 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10766 tmp
= tcg_temp_new_i32();
10767 tcg_gen_movi_i32(tmp
, imm
);
10770 /* Add/sub 12-bit immediate. */
10772 offset
= s
->pc
& ~(uint32_t)3;
10773 if (insn
& (1 << 23))
10777 tmp
= tcg_temp_new_i32();
10778 tcg_gen_movi_i32(tmp
, offset
);
10780 tmp
= load_reg(s
, rn
);
10781 if (insn
& (1 << 23))
10782 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10784 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10787 store_reg(s
, rd
, tmp
);
10790 int shifter_out
= 0;
10791 /* modified 12-bit immediate. */
10792 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10793 imm
= (insn
& 0xff);
10796 /* Nothing to do. */
10798 case 1: /* 00XY00XY */
10801 case 2: /* XY00XY00 */
10805 case 3: /* XYXYXYXY */
10809 default: /* Rotated constant. */
10810 shift
= (shift
<< 1) | (imm
>> 7);
10812 imm
= imm
<< (32 - shift
);
10816 tmp2
= tcg_temp_new_i32();
10817 tcg_gen_movi_i32(tmp2
, imm
);
10818 rn
= (insn
>> 16) & 0xf;
10820 tmp
= tcg_temp_new_i32();
10821 tcg_gen_movi_i32(tmp
, 0);
10823 tmp
= load_reg(s
, rn
);
10825 op
= (insn
>> 21) & 0xf;
10826 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10827 shifter_out
, tmp
, tmp2
))
10829 tcg_temp_free_i32(tmp2
);
10830 rd
= (insn
>> 8) & 0xf;
10832 store_reg(s
, rd
, tmp
);
10834 tcg_temp_free_i32(tmp
);
10839 case 12: /* Load/store single data item. */
10846 if ((insn
& 0x01100000) == 0x01000000) {
10847 if (disas_neon_ls_insn(s
, insn
)) {
10852 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10854 if (!(insn
& (1 << 20))) {
10858 /* Byte or halfword load space with dest == r15 : memory hints.
10859 * Catch them early so we don't emit pointless addressing code.
10860 * This space is a mix of:
10861 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10862 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10864 * unallocated hints, which must be treated as NOPs
10865 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10866 * which is easiest for the decoding logic
10867 * Some space which must UNDEF
10869 int op1
= (insn
>> 23) & 3;
10870 int op2
= (insn
>> 6) & 0x3f;
10875 /* UNPREDICTABLE, unallocated hint or
10876 * PLD/PLDW/PLI (literal)
10881 return 0; /* PLD/PLDW/PLI or unallocated hint */
10883 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10884 return 0; /* PLD/PLDW/PLI or unallocated hint */
10886 /* UNDEF space, or an UNPREDICTABLE */
10890 memidx
= get_mem_index(s
);
10892 addr
= tcg_temp_new_i32();
10894 /* s->pc has already been incremented by 4. */
10895 imm
= s
->pc
& 0xfffffffc;
10896 if (insn
& (1 << 23))
10897 imm
+= insn
& 0xfff;
10899 imm
-= insn
& 0xfff;
10900 tcg_gen_movi_i32(addr
, imm
);
10902 addr
= load_reg(s
, rn
);
10903 if (insn
& (1 << 23)) {
10904 /* Positive offset. */
10905 imm
= insn
& 0xfff;
10906 tcg_gen_addi_i32(addr
, addr
, imm
);
10909 switch ((insn
>> 8) & 0xf) {
10910 case 0x0: /* Shifted Register. */
10911 shift
= (insn
>> 4) & 0xf;
10913 tcg_temp_free_i32(addr
);
10916 tmp
= load_reg(s
, rm
);
10918 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10919 tcg_gen_add_i32(addr
, addr
, tmp
);
10920 tcg_temp_free_i32(tmp
);
10922 case 0xc: /* Negative offset. */
10923 tcg_gen_addi_i32(addr
, addr
, -imm
);
10925 case 0xe: /* User privilege. */
10926 tcg_gen_addi_i32(addr
, addr
, imm
);
10927 memidx
= get_a32_user_mem_index(s
);
10929 case 0x9: /* Post-decrement. */
10931 /* Fall through. */
10932 case 0xb: /* Post-increment. */
10936 case 0xd: /* Pre-decrement. */
10938 /* Fall through. */
10939 case 0xf: /* Pre-increment. */
10940 tcg_gen_addi_i32(addr
, addr
, imm
);
10944 tcg_temp_free_i32(addr
);
10950 issinfo
= writeback
? ISSInvalid
: rs
;
10952 if (insn
& (1 << 20)) {
10954 tmp
= tcg_temp_new_i32();
10957 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10960 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10963 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10966 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10969 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10972 tcg_temp_free_i32(tmp
);
10973 tcg_temp_free_i32(addr
);
10977 gen_bx_excret(s
, tmp
);
10979 store_reg(s
, rs
, tmp
);
10983 tmp
= load_reg(s
, rs
);
10986 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
10989 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
10992 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
10995 tcg_temp_free_i32(tmp
);
10996 tcg_temp_free_i32(addr
);
10999 tcg_temp_free_i32(tmp
);
11002 tcg_gen_addi_i32(addr
, addr
, imm
);
11004 store_reg(s
, rn
, addr
);
11006 tcg_temp_free_i32(addr
);
11018 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
11020 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
11027 if (s
->condexec_mask
) {
11028 cond
= s
->condexec_cond
;
11029 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
11030 s
->condlabel
= gen_new_label();
11031 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11036 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11039 switch (insn
>> 12) {
11043 op
= (insn
>> 11) & 3;
11046 rn
= (insn
>> 3) & 7;
11047 tmp
= load_reg(s
, rn
);
11048 if (insn
& (1 << 10)) {
11050 tmp2
= tcg_temp_new_i32();
11051 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11054 rm
= (insn
>> 6) & 7;
11055 tmp2
= load_reg(s
, rm
);
11057 if (insn
& (1 << 9)) {
11058 if (s
->condexec_mask
)
11059 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11061 gen_sub_CC(tmp
, tmp
, tmp2
);
11063 if (s
->condexec_mask
)
11064 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11066 gen_add_CC(tmp
, tmp
, tmp2
);
11068 tcg_temp_free_i32(tmp2
);
11069 store_reg(s
, rd
, tmp
);
11071 /* shift immediate */
11072 rm
= (insn
>> 3) & 7;
11073 shift
= (insn
>> 6) & 0x1f;
11074 tmp
= load_reg(s
, rm
);
11075 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11076 if (!s
->condexec_mask
)
11078 store_reg(s
, rd
, tmp
);
11082 /* arithmetic large immediate */
11083 op
= (insn
>> 11) & 3;
11084 rd
= (insn
>> 8) & 0x7;
11085 if (op
== 0) { /* mov */
11086 tmp
= tcg_temp_new_i32();
11087 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11088 if (!s
->condexec_mask
)
11090 store_reg(s
, rd
, tmp
);
11092 tmp
= load_reg(s
, rd
);
11093 tmp2
= tcg_temp_new_i32();
11094 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11097 gen_sub_CC(tmp
, tmp
, tmp2
);
11098 tcg_temp_free_i32(tmp
);
11099 tcg_temp_free_i32(tmp2
);
11102 if (s
->condexec_mask
)
11103 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11105 gen_add_CC(tmp
, tmp
, tmp2
);
11106 tcg_temp_free_i32(tmp2
);
11107 store_reg(s
, rd
, tmp
);
11110 if (s
->condexec_mask
)
11111 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11113 gen_sub_CC(tmp
, tmp
, tmp2
);
11114 tcg_temp_free_i32(tmp2
);
11115 store_reg(s
, rd
, tmp
);
11121 if (insn
& (1 << 11)) {
11122 rd
= (insn
>> 8) & 7;
11123 /* load pc-relative. Bit 1 of PC is ignored. */
11124 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11125 val
&= ~(uint32_t)2;
11126 addr
= tcg_temp_new_i32();
11127 tcg_gen_movi_i32(addr
, val
);
11128 tmp
= tcg_temp_new_i32();
11129 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11131 tcg_temp_free_i32(addr
);
11132 store_reg(s
, rd
, tmp
);
11135 if (insn
& (1 << 10)) {
11136 /* data processing extended or blx */
11137 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11138 rm
= (insn
>> 3) & 0xf;
11139 op
= (insn
>> 8) & 3;
11142 tmp
= load_reg(s
, rd
);
11143 tmp2
= load_reg(s
, rm
);
11144 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11145 tcg_temp_free_i32(tmp2
);
11146 store_reg(s
, rd
, tmp
);
11149 tmp
= load_reg(s
, rd
);
11150 tmp2
= load_reg(s
, rm
);
11151 gen_sub_CC(tmp
, tmp
, tmp2
);
11152 tcg_temp_free_i32(tmp2
);
11153 tcg_temp_free_i32(tmp
);
11155 case 2: /* mov/cpy */
11156 tmp
= load_reg(s
, rm
);
11157 store_reg(s
, rd
, tmp
);
11159 case 3:/* branch [and link] exchange thumb register */
11160 tmp
= load_reg(s
, rm
);
11161 if (insn
& (1 << 7)) {
11163 val
= (uint32_t)s
->pc
| 1;
11164 tmp2
= tcg_temp_new_i32();
11165 tcg_gen_movi_i32(tmp2
, val
);
11166 store_reg(s
, 14, tmp2
);
11169 /* Only BX works as exception-return, not BLX */
11170 gen_bx_excret(s
, tmp
);
11177 /* data processing register */
11179 rm
= (insn
>> 3) & 7;
11180 op
= (insn
>> 6) & 0xf;
11181 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11182 /* the shift/rotate ops want the operands backwards */
11191 if (op
== 9) { /* neg */
11192 tmp
= tcg_temp_new_i32();
11193 tcg_gen_movi_i32(tmp
, 0);
11194 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11195 tmp
= load_reg(s
, rd
);
11197 TCGV_UNUSED_I32(tmp
);
11200 tmp2
= load_reg(s
, rm
);
11202 case 0x0: /* and */
11203 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11204 if (!s
->condexec_mask
)
11207 case 0x1: /* eor */
11208 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11209 if (!s
->condexec_mask
)
11212 case 0x2: /* lsl */
11213 if (s
->condexec_mask
) {
11214 gen_shl(tmp2
, tmp2
, tmp
);
11216 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11217 gen_logic_CC(tmp2
);
11220 case 0x3: /* lsr */
11221 if (s
->condexec_mask
) {
11222 gen_shr(tmp2
, tmp2
, tmp
);
11224 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11225 gen_logic_CC(tmp2
);
11228 case 0x4: /* asr */
11229 if (s
->condexec_mask
) {
11230 gen_sar(tmp2
, tmp2
, tmp
);
11232 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11233 gen_logic_CC(tmp2
);
11236 case 0x5: /* adc */
11237 if (s
->condexec_mask
) {
11238 gen_adc(tmp
, tmp2
);
11240 gen_adc_CC(tmp
, tmp
, tmp2
);
11243 case 0x6: /* sbc */
11244 if (s
->condexec_mask
) {
11245 gen_sub_carry(tmp
, tmp
, tmp2
);
11247 gen_sbc_CC(tmp
, tmp
, tmp2
);
11250 case 0x7: /* ror */
11251 if (s
->condexec_mask
) {
11252 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11253 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11255 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11256 gen_logic_CC(tmp2
);
11259 case 0x8: /* tst */
11260 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11264 case 0x9: /* neg */
11265 if (s
->condexec_mask
)
11266 tcg_gen_neg_i32(tmp
, tmp2
);
11268 gen_sub_CC(tmp
, tmp
, tmp2
);
11270 case 0xa: /* cmp */
11271 gen_sub_CC(tmp
, tmp
, tmp2
);
11274 case 0xb: /* cmn */
11275 gen_add_CC(tmp
, tmp
, tmp2
);
11278 case 0xc: /* orr */
11279 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11280 if (!s
->condexec_mask
)
11283 case 0xd: /* mul */
11284 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11285 if (!s
->condexec_mask
)
11288 case 0xe: /* bic */
11289 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11290 if (!s
->condexec_mask
)
11293 case 0xf: /* mvn */
11294 tcg_gen_not_i32(tmp2
, tmp2
);
11295 if (!s
->condexec_mask
)
11296 gen_logic_CC(tmp2
);
11303 store_reg(s
, rm
, tmp2
);
11305 tcg_temp_free_i32(tmp
);
11307 store_reg(s
, rd
, tmp
);
11308 tcg_temp_free_i32(tmp2
);
11311 tcg_temp_free_i32(tmp
);
11312 tcg_temp_free_i32(tmp2
);
11317 /* load/store register offset. */
11319 rn
= (insn
>> 3) & 7;
11320 rm
= (insn
>> 6) & 7;
11321 op
= (insn
>> 9) & 7;
11322 addr
= load_reg(s
, rn
);
11323 tmp
= load_reg(s
, rm
);
11324 tcg_gen_add_i32(addr
, addr
, tmp
);
11325 tcg_temp_free_i32(tmp
);
11327 if (op
< 3) { /* store */
11328 tmp
= load_reg(s
, rd
);
11330 tmp
= tcg_temp_new_i32();
11335 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11338 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11341 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11343 case 3: /* ldrsb */
11344 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11347 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11350 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11353 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11355 case 7: /* ldrsh */
11356 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11359 if (op
>= 3) { /* load */
11360 store_reg(s
, rd
, tmp
);
11362 tcg_temp_free_i32(tmp
);
11364 tcg_temp_free_i32(addr
);
11368 /* load/store word immediate offset */
11370 rn
= (insn
>> 3) & 7;
11371 addr
= load_reg(s
, rn
);
11372 val
= (insn
>> 4) & 0x7c;
11373 tcg_gen_addi_i32(addr
, addr
, val
);
11375 if (insn
& (1 << 11)) {
11377 tmp
= tcg_temp_new_i32();
11378 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11379 store_reg(s
, rd
, tmp
);
11382 tmp
= load_reg(s
, rd
);
11383 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11384 tcg_temp_free_i32(tmp
);
11386 tcg_temp_free_i32(addr
);
11390 /* load/store byte immediate offset */
11392 rn
= (insn
>> 3) & 7;
11393 addr
= load_reg(s
, rn
);
11394 val
= (insn
>> 6) & 0x1f;
11395 tcg_gen_addi_i32(addr
, addr
, val
);
11397 if (insn
& (1 << 11)) {
11399 tmp
= tcg_temp_new_i32();
11400 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11401 store_reg(s
, rd
, tmp
);
11404 tmp
= load_reg(s
, rd
);
11405 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11406 tcg_temp_free_i32(tmp
);
11408 tcg_temp_free_i32(addr
);
11412 /* load/store halfword immediate offset */
11414 rn
= (insn
>> 3) & 7;
11415 addr
= load_reg(s
, rn
);
11416 val
= (insn
>> 5) & 0x3e;
11417 tcg_gen_addi_i32(addr
, addr
, val
);
11419 if (insn
& (1 << 11)) {
11421 tmp
= tcg_temp_new_i32();
11422 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11423 store_reg(s
, rd
, tmp
);
11426 tmp
= load_reg(s
, rd
);
11427 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11428 tcg_temp_free_i32(tmp
);
11430 tcg_temp_free_i32(addr
);
11434 /* load/store from stack */
11435 rd
= (insn
>> 8) & 7;
11436 addr
= load_reg(s
, 13);
11437 val
= (insn
& 0xff) * 4;
11438 tcg_gen_addi_i32(addr
, addr
, val
);
11440 if (insn
& (1 << 11)) {
11442 tmp
= tcg_temp_new_i32();
11443 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11444 store_reg(s
, rd
, tmp
);
11447 tmp
= load_reg(s
, rd
);
11448 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11449 tcg_temp_free_i32(tmp
);
11451 tcg_temp_free_i32(addr
);
11455 /* add to high reg */
11456 rd
= (insn
>> 8) & 7;
11457 if (insn
& (1 << 11)) {
11459 tmp
= load_reg(s
, 13);
11461 /* PC. bit 1 is ignored. */
11462 tmp
= tcg_temp_new_i32();
11463 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11465 val
= (insn
& 0xff) * 4;
11466 tcg_gen_addi_i32(tmp
, tmp
, val
);
11467 store_reg(s
, rd
, tmp
);
11472 op
= (insn
>> 8) & 0xf;
11475 /* adjust stack pointer */
11476 tmp
= load_reg(s
, 13);
11477 val
= (insn
& 0x7f) * 4;
11478 if (insn
& (1 << 7))
11479 val
= -(int32_t)val
;
11480 tcg_gen_addi_i32(tmp
, tmp
, val
);
11481 store_reg(s
, 13, tmp
);
11484 case 2: /* sign/zero extend. */
11487 rm
= (insn
>> 3) & 7;
11488 tmp
= load_reg(s
, rm
);
11489 switch ((insn
>> 6) & 3) {
11490 case 0: gen_sxth(tmp
); break;
11491 case 1: gen_sxtb(tmp
); break;
11492 case 2: gen_uxth(tmp
); break;
11493 case 3: gen_uxtb(tmp
); break;
11495 store_reg(s
, rd
, tmp
);
11497 case 4: case 5: case 0xc: case 0xd:
11499 addr
= load_reg(s
, 13);
11500 if (insn
& (1 << 8))
11504 for (i
= 0; i
< 8; i
++) {
11505 if (insn
& (1 << i
))
11508 if ((insn
& (1 << 11)) == 0) {
11509 tcg_gen_addi_i32(addr
, addr
, -offset
);
11511 for (i
= 0; i
< 8; i
++) {
11512 if (insn
& (1 << i
)) {
11513 if (insn
& (1 << 11)) {
11515 tmp
= tcg_temp_new_i32();
11516 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11517 store_reg(s
, i
, tmp
);
11520 tmp
= load_reg(s
, i
);
11521 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11522 tcg_temp_free_i32(tmp
);
11524 /* advance to the next address. */
11525 tcg_gen_addi_i32(addr
, addr
, 4);
11528 TCGV_UNUSED_I32(tmp
);
11529 if (insn
& (1 << 8)) {
11530 if (insn
& (1 << 11)) {
11532 tmp
= tcg_temp_new_i32();
11533 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11534 /* don't set the pc until the rest of the instruction
11538 tmp
= load_reg(s
, 14);
11539 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11540 tcg_temp_free_i32(tmp
);
11542 tcg_gen_addi_i32(addr
, addr
, 4);
11544 if ((insn
& (1 << 11)) == 0) {
11545 tcg_gen_addi_i32(addr
, addr
, -offset
);
11547 /* write back the new stack pointer */
11548 store_reg(s
, 13, addr
);
11549 /* set the new PC value */
11550 if ((insn
& 0x0900) == 0x0900) {
11551 store_reg_from_load(s
, 15, tmp
);
11555 case 1: case 3: case 9: case 11: /* czb */
11557 tmp
= load_reg(s
, rm
);
11558 s
->condlabel
= gen_new_label();
11560 if (insn
& (1 << 11))
11561 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11563 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11564 tcg_temp_free_i32(tmp
);
11565 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11566 val
= (uint32_t)s
->pc
+ 2;
11571 case 15: /* IT, nop-hint. */
11572 if ((insn
& 0xf) == 0) {
11573 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11577 s
->condexec_cond
= (insn
>> 4) & 0xe;
11578 s
->condexec_mask
= insn
& 0x1f;
11579 /* No actual code generated for this insn, just setup state. */
11582 case 0xe: /* bkpt */
11584 int imm8
= extract32(insn
, 0, 8);
11586 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11587 default_exception_el(s
));
11591 case 0xa: /* rev, and hlt */
11593 int op1
= extract32(insn
, 6, 2);
11597 int imm6
= extract32(insn
, 0, 6);
11603 /* Otherwise this is rev */
11605 rn
= (insn
>> 3) & 0x7;
11607 tmp
= load_reg(s
, rn
);
11609 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11610 case 1: gen_rev16(tmp
); break;
11611 case 3: gen_revsh(tmp
); break;
11613 g_assert_not_reached();
11615 store_reg(s
, rd
, tmp
);
11620 switch ((insn
>> 5) & 7) {
11624 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11625 gen_helper_setend(cpu_env
);
11626 s
->is_jmp
= DISAS_UPDATE
;
11635 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11636 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11639 addr
= tcg_const_i32(19);
11640 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11641 tcg_temp_free_i32(addr
);
11645 addr
= tcg_const_i32(16);
11646 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11647 tcg_temp_free_i32(addr
);
11649 tcg_temp_free_i32(tmp
);
11652 if (insn
& (1 << 4)) {
11653 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11657 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11672 /* load/store multiple */
11673 TCGv_i32 loaded_var
;
11674 TCGV_UNUSED_I32(loaded_var
);
11675 rn
= (insn
>> 8) & 0x7;
11676 addr
= load_reg(s
, rn
);
11677 for (i
= 0; i
< 8; i
++) {
11678 if (insn
& (1 << i
)) {
11679 if (insn
& (1 << 11)) {
11681 tmp
= tcg_temp_new_i32();
11682 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11686 store_reg(s
, i
, tmp
);
11690 tmp
= load_reg(s
, i
);
11691 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11692 tcg_temp_free_i32(tmp
);
11694 /* advance to the next address */
11695 tcg_gen_addi_i32(addr
, addr
, 4);
11698 if ((insn
& (1 << rn
)) == 0) {
11699 /* base reg not in list: base register writeback */
11700 store_reg(s
, rn
, addr
);
11702 /* base reg in list: if load, complete it now */
11703 if (insn
& (1 << 11)) {
11704 store_reg(s
, rn
, loaded_var
);
11706 tcg_temp_free_i32(addr
);
11711 /* conditional branch or swi */
11712 cond
= (insn
>> 8) & 0xf;
11718 gen_set_pc_im(s
, s
->pc
);
11719 s
->svc_imm
= extract32(insn
, 0, 8);
11720 s
->is_jmp
= DISAS_SWI
;
11723 /* generate a conditional jump to next instruction */
11724 s
->condlabel
= gen_new_label();
11725 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11728 /* jump to the offset */
11729 val
= (uint32_t)s
->pc
+ 2;
11730 offset
= ((int32_t)insn
<< 24) >> 24;
11731 val
+= offset
<< 1;
11736 if (insn
& (1 << 11)) {
11737 if (disas_thumb2_insn(env
, s
, insn
))
11741 /* unconditional branch */
11742 val
= (uint32_t)s
->pc
;
11743 offset
= ((int32_t)insn
<< 21) >> 21;
11744 val
+= (offset
<< 1) + 2;
11749 if (disas_thumb2_insn(env
, s
, insn
))
11755 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11756 default_exception_el(s
));
11760 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11761 default_exception_el(s
));
11764 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11766 /* Return true if the insn at dc->pc might cross a page boundary.
11767 * (False positives are OK, false negatives are not.)
11771 if ((s
->pc
& 3) == 0) {
11772 /* At a 4-aligned address we can't be crossing a page */
11776 /* This must be a Thumb insn */
11777 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11779 if ((insn
>> 11) >= 0x1d) {
11780 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11781 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11782 * end up actually treating this as two 16-bit insns (see the
11783 * code at the start of disas_thumb2_insn()) but we don't bother
11784 * to check for that as it is unlikely, and false positives here
11789 /* Definitely a 16-bit insn, can't be crossing a page. */
11793 /* generate intermediate code for basic block 'tb'. */
11794 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11796 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11797 CPUState
*cs
= CPU(cpu
);
11798 DisasContext dc1
, *dc
= &dc1
;
11799 target_ulong pc_start
;
11800 target_ulong next_page_start
;
11805 /* generate intermediate code */
11807 /* The A64 decoder has its own top level loop, because it doesn't need
11808 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11810 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11811 gen_intermediate_code_a64(cpu
, tb
);
11819 dc
->is_jmp
= DISAS_NEXT
;
11821 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11825 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11826 * there is no secure EL1, so we route exceptions to EL3.
11828 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11829 !arm_el_is_aa64(env
, 3);
11830 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11831 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(tb
->flags
);
11832 dc
->be_data
= ARM_TBFLAG_BE_DATA(tb
->flags
) ? MO_BE
: MO_LE
;
11833 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11834 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11835 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, ARM_TBFLAG_MMUIDX(tb
->flags
));
11836 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11837 #if !defined(CONFIG_USER_ONLY)
11838 dc
->user
= (dc
->current_el
== 0);
11840 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11841 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11842 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11843 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11844 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11845 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11846 dc
->v7m_handler_mode
= ARM_TBFLAG_HANDLER(tb
->flags
);
11847 dc
->cp_regs
= cpu
->cp_regs
;
11848 dc
->features
= env
->features
;
11850 /* Single step state. The code-generation logic here is:
11852 * generate code with no special handling for single-stepping (except
11853 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11854 * this happens anyway because those changes are all system register or
11856 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11857 * emit code for one insn
11858 * emit code to clear PSTATE.SS
11859 * emit code to generate software step exception for completed step
11860 * end TB (as usual for having generated an exception)
11861 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11862 * emit code to generate a software step exception
11865 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11866 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11867 dc
->is_ldex
= false;
11868 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11870 cpu_F0s
= tcg_temp_new_i32();
11871 cpu_F1s
= tcg_temp_new_i32();
11872 cpu_F0d
= tcg_temp_new_i64();
11873 cpu_F1d
= tcg_temp_new_i64();
11876 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11877 cpu_M0
= tcg_temp_new_i64();
11878 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11880 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11881 if (max_insns
== 0) {
11882 max_insns
= CF_COUNT_MASK
;
11884 if (max_insns
> TCG_MAX_INSNS
) {
11885 max_insns
= TCG_MAX_INSNS
;
11890 tcg_clear_temp_count();
11892 /* A note on handling of the condexec (IT) bits:
11894 * We want to avoid the overhead of having to write the updated condexec
11895 * bits back to the CPUARMState for every instruction in an IT block. So:
11896 * (1) if the condexec bits are not already zero then we write
11897 * zero back into the CPUARMState now. This avoids complications trying
11898 * to do it at the end of the block. (For example if we don't do this
11899 * it's hard to identify whether we can safely skip writing condexec
11900 * at the end of the TB, which we definitely want to do for the case
11901 * where a TB doesn't do anything with the IT state at all.)
11902 * (2) if we are going to leave the TB then we call gen_set_condexec()
11903 * which will write the correct value into CPUARMState if zero is wrong.
11904 * This is done both for leaving the TB at the end, and for leaving
11905 * it because of an exception we know will happen, which is done in
11906 * gen_exception_insn(). The latter is necessary because we need to
11907 * leave the TB with the PC/IT state just prior to execution of the
11908 * instruction which caused the exception.
11909 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11910 * then the CPUARMState will be wrong and we need to reset it.
11911 * This is handled in the same way as restoration of the
11912 * PC in these situations; we save the value of the condexec bits
11913 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11914 * then uses this to restore them after an exception.
11916 * Note that there are no instructions which can read the condexec
11917 * bits, and none which can write non-static values to them, so
11918 * we don't need to care about whether CPUARMState is correct in the
11922 /* Reset the conditional execution bits immediately. This avoids
11923 complications trying to do it at the end of the block. */
11924 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11926 TCGv_i32 tmp
= tcg_temp_new_i32();
11927 tcg_gen_movi_i32(tmp
, 0);
11928 store_cpu_field(tmp
, condexec_bits
);
11931 dc
->insn_start_idx
= tcg_op_buf_count();
11932 tcg_gen_insn_start(dc
->pc
,
11933 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11937 #ifdef CONFIG_USER_ONLY
11938 /* Intercept jump to the magic kernel page. */
11939 if (dc
->pc
>= 0xffff0000) {
11940 /* We always get here via a jump, so know we are not in a
11941 conditional execution block. */
11942 gen_exception_internal(EXCP_KERNEL_TRAP
);
11943 dc
->is_jmp
= DISAS_EXC
;
11948 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11950 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11951 if (bp
->pc
== dc
->pc
) {
11952 if (bp
->flags
& BP_CPU
) {
11953 gen_set_condexec(dc
);
11954 gen_set_pc_im(dc
, dc
->pc
);
11955 gen_helper_check_breakpoints(cpu_env
);
11956 /* End the TB early; it's likely not going to be executed */
11957 dc
->is_jmp
= DISAS_UPDATE
;
11959 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11960 /* The address covered by the breakpoint must be
11961 included in [tb->pc, tb->pc + tb->size) in order
11962 to for it to be properly cleared -- thus we
11963 increment the PC here so that the logic setting
11964 tb->size below does the right thing. */
11965 /* TODO: Advance PC by correct instruction length to
11966 * avoid disassembler error messages */
11968 goto done_generating
;
11975 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11979 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11980 /* Singlestep state is Active-pending.
11981 * If we're in this state at the start of a TB then either
11982 * a) we just took an exception to an EL which is being debugged
11983 * and this is the first insn in the exception handler
11984 * b) debug exceptions were masked and we just unmasked them
11985 * without changing EL (eg by clearing PSTATE.D)
11986 * In either case we're going to take a swstep exception in the
11987 * "did not step an insn" case, and so the syndrome ISV and EX
11988 * bits should be zero.
11990 assert(num_insns
== 1);
11991 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11992 default_exception_el(dc
));
11993 goto done_generating
;
11997 disas_thumb_insn(env
, dc
);
11998 if (dc
->condexec_mask
) {
11999 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
12000 | ((dc
->condexec_mask
>> 4) & 1);
12001 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12002 if (dc
->condexec_mask
== 0) {
12003 dc
->condexec_cond
= 0;
12007 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12009 disas_arm_insn(dc
, insn
);
12012 if (dc
->condjmp
&& !dc
->is_jmp
) {
12013 gen_set_label(dc
->condlabel
);
12017 if (tcg_check_temp_count()) {
12018 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
12022 /* Translation stops when a conditional branch is encountered.
12023 * Otherwise the subsequent code could get translated several times.
12024 * Also stop translation when a page boundary is reached. This
12025 * ensures prefetch aborts occur at the right place. */
12027 /* We want to stop the TB if the next insn starts in a new page,
12028 * or if it spans between this page and the next. This means that
12029 * if we're looking at the last halfword in the page we need to
12030 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12031 * or a 32-bit Thumb insn (which won't).
12032 * This is to avoid generating a silly TB with a single 16-bit insn
12033 * in it at the end of this page (which would execute correctly
12034 * but isn't very efficient).
12036 end_of_page
= (dc
->pc
>= next_page_start
) ||
12037 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
12039 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
12040 !is_singlestepping(dc
) &&
12043 num_insns
< max_insns
);
12045 if (tb
->cflags
& CF_LAST_IO
) {
12047 /* FIXME: This can theoretically happen with self-modifying
12049 cpu_abort(cs
, "IO on conditional branch instruction");
12054 /* At this stage dc->condjmp will only be set when the skipped
12055 instruction was a conditional branch or trap, and the PC has
12056 already been written. */
12057 gen_set_condexec(dc
);
12058 if (dc
->is_jmp
== DISAS_BX_EXCRET
) {
12059 /* Exception return branches need some special case code at the
12060 * end of the TB, which is complex enough that it has to
12061 * handle the single-step vs not and the condition-failed
12062 * insn codepath itself.
12064 gen_bx_excret_final_code(dc
);
12065 } else if (unlikely(is_singlestepping(dc
))) {
12066 /* Unconditional and "condition passed" instruction codepath. */
12067 switch (dc
->is_jmp
) {
12069 gen_ss_advance(dc
);
12070 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12071 default_exception_el(dc
));
12074 gen_ss_advance(dc
);
12075 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12078 gen_ss_advance(dc
);
12079 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12083 gen_set_pc_im(dc
, dc
->pc
);
12086 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12087 gen_singlestep_exception(dc
);
12090 /* While branches must always occur at the end of an IT block,
12091 there are a few other things that can cause us to terminate
12092 the TB in the middle of an IT block:
12093 - Exception generating instructions (bkpt, swi, undefined).
12095 - Hardware watchpoints.
12096 Hardware breakpoints have already been handled and skip this code.
12098 switch(dc
->is_jmp
) {
12100 gen_goto_tb(dc
, 1, dc
->pc
);
12106 gen_set_pc_im(dc
, dc
->pc
);
12109 /* indicate that the hash table must be used to find the next TB */
12110 tcg_gen_exit_tb(0);
12112 case DISAS_TB_JUMP
:
12114 /* nothing more to generate */
12117 gen_helper_wfi(cpu_env
);
12118 /* The helper doesn't necessarily throw an exception, but we
12119 * must go back to the main loop to check for interrupts anyway.
12121 tcg_gen_exit_tb(0);
12124 gen_helper_wfe(cpu_env
);
12127 gen_helper_yield(cpu_env
);
12130 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12131 default_exception_el(dc
));
12134 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12137 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12143 /* "Condition failed" instruction codepath for the branch/trap insn */
12144 gen_set_label(dc
->condlabel
);
12145 gen_set_condexec(dc
);
12146 if (unlikely(is_singlestepping(dc
))) {
12147 gen_set_pc_im(dc
, dc
->pc
);
12148 gen_singlestep_exception(dc
);
12150 gen_goto_tb(dc
, 1, dc
->pc
);
12155 gen_tb_end(tb
, num_insns
);
12158 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
) &&
12159 qemu_log_in_addr_range(pc_start
)) {
12161 qemu_log("----------------\n");
12162 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
12163 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
12164 dc
->thumb
| (dc
->sctlr_b
<< 1));
12169 tb
->size
= dc
->pc
- pc_start
;
12170 tb
->icount
= num_insns
;
12173 static const char *cpu_mode_names
[16] = {
12174 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12175 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12178 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12181 ARMCPU
*cpu
= ARM_CPU(cs
);
12182 CPUARMState
*env
= &cpu
->env
;
12185 const char *ns_status
;
12188 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12192 for(i
=0;i
<16;i
++) {
12193 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12195 cpu_fprintf(f
, "\n");
12197 cpu_fprintf(f
, " ");
12199 psr
= cpsr_read(env
);
12201 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12202 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12203 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12208 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12210 psr
& (1 << 31) ? 'N' : '-',
12211 psr
& (1 << 30) ? 'Z' : '-',
12212 psr
& (1 << 29) ? 'C' : '-',
12213 psr
& (1 << 28) ? 'V' : '-',
12214 psr
& CPSR_T
? 'T' : 'A',
12216 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12218 if (flags
& CPU_DUMP_FPU
) {
12219 int numvfpregs
= 0;
12220 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12223 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12226 for (i
= 0; i
< numvfpregs
; i
++) {
12227 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12228 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12229 i
* 2, (uint32_t)v
,
12230 i
* 2 + 1, (uint32_t)(v
>> 32),
12233 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12237 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12238 target_ulong
*data
)
12242 env
->condexec_bits
= 0;
12243 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12245 env
->regs
[15] = data
[0];
12246 env
->condexec_bits
= data
[1];
12247 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;