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 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4163 if (use_goto_tb(s
, dest
)) {
4165 gen_set_pc_im(s
, dest
);
4166 tcg_gen_exit_tb((uintptr_t)s
->tb
+ n
);
4168 gen_set_pc_im(s
, dest
);
4173 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4175 if (unlikely(is_singlestepping(s
))) {
4176 /* An indirect jump so that we still trigger the debug exception. */
4181 gen_goto_tb(s
, 0, dest
);
4182 s
->is_jmp
= DISAS_TB_JUMP
;
4186 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4189 tcg_gen_sari_i32(t0
, t0
, 16);
4193 tcg_gen_sari_i32(t1
, t1
, 16);
4196 tcg_gen_mul_i32(t0
, t0
, t1
);
4199 /* Return the mask of PSR bits set by a MSR instruction. */
4200 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4205 if (flags
& (1 << 0))
4207 if (flags
& (1 << 1))
4209 if (flags
& (1 << 2))
4211 if (flags
& (1 << 3))
4214 /* Mask out undefined bits. */
4215 mask
&= ~CPSR_RESERVED
;
4216 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4219 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4220 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4222 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4223 mask
&= ~(CPSR_E
| CPSR_GE
);
4225 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4228 /* Mask out execution state and reserved bits. */
4230 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4232 /* Mask out privileged bits. */
4238 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4239 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4243 /* ??? This is also undefined in system mode. */
4247 tmp
= load_cpu_field(spsr
);
4248 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4249 tcg_gen_andi_i32(t0
, t0
, mask
);
4250 tcg_gen_or_i32(tmp
, tmp
, t0
);
4251 store_cpu_field(tmp
, spsr
);
4253 gen_set_cpsr(t0
, mask
);
4255 tcg_temp_free_i32(t0
);
4260 /* Returns nonzero if access to the PSR is not permitted. */
4261 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4264 tmp
= tcg_temp_new_i32();
4265 tcg_gen_movi_i32(tmp
, val
);
4266 return gen_set_psr(s
, mask
, spsr
, tmp
);
4269 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4270 int *tgtmode
, int *regno
)
4272 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4273 * the target mode and register number, and identify the various
4274 * unpredictable cases.
4275 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4276 * + executed in user mode
4277 * + using R15 as the src/dest register
4278 * + accessing an unimplemented register
4279 * + accessing a register that's inaccessible at current PL/security state*
4280 * + accessing a register that you could access with a different insn
4281 * We choose to UNDEF in all these cases.
4282 * Since we don't know which of the various AArch32 modes we are in
4283 * we have to defer some checks to runtime.
4284 * Accesses to Monitor mode registers from Secure EL1 (which implies
4285 * that EL3 is AArch64) must trap to EL3.
4287 * If the access checks fail this function will emit code to take
4288 * an exception and return false. Otherwise it will return true,
4289 * and set *tgtmode and *regno appropriately.
4291 int exc_target
= default_exception_el(s
);
4293 /* These instructions are present only in ARMv8, or in ARMv7 with the
4294 * Virtualization Extensions.
4296 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4297 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4301 if (IS_USER(s
) || rn
== 15) {
4305 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4306 * of registers into (r, sysm).
4309 /* SPSRs for other modes */
4311 case 0xe: /* SPSR_fiq */
4312 *tgtmode
= ARM_CPU_MODE_FIQ
;
4314 case 0x10: /* SPSR_irq */
4315 *tgtmode
= ARM_CPU_MODE_IRQ
;
4317 case 0x12: /* SPSR_svc */
4318 *tgtmode
= ARM_CPU_MODE_SVC
;
4320 case 0x14: /* SPSR_abt */
4321 *tgtmode
= ARM_CPU_MODE_ABT
;
4323 case 0x16: /* SPSR_und */
4324 *tgtmode
= ARM_CPU_MODE_UND
;
4326 case 0x1c: /* SPSR_mon */
4327 *tgtmode
= ARM_CPU_MODE_MON
;
4329 case 0x1e: /* SPSR_hyp */
4330 *tgtmode
= ARM_CPU_MODE_HYP
;
4332 default: /* unallocated */
4335 /* We arbitrarily assign SPSR a register number of 16. */
4338 /* general purpose registers for other modes */
4340 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4341 *tgtmode
= ARM_CPU_MODE_USR
;
4344 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4345 *tgtmode
= ARM_CPU_MODE_FIQ
;
4348 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4349 *tgtmode
= ARM_CPU_MODE_IRQ
;
4350 *regno
= sysm
& 1 ? 13 : 14;
4352 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4353 *tgtmode
= ARM_CPU_MODE_SVC
;
4354 *regno
= sysm
& 1 ? 13 : 14;
4356 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4357 *tgtmode
= ARM_CPU_MODE_ABT
;
4358 *regno
= sysm
& 1 ? 13 : 14;
4360 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4361 *tgtmode
= ARM_CPU_MODE_UND
;
4362 *regno
= sysm
& 1 ? 13 : 14;
4364 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4365 *tgtmode
= ARM_CPU_MODE_MON
;
4366 *regno
= sysm
& 1 ? 13 : 14;
4368 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4369 *tgtmode
= ARM_CPU_MODE_HYP
;
4370 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4371 *regno
= sysm
& 1 ? 13 : 17;
4373 default: /* unallocated */
4378 /* Catch the 'accessing inaccessible register' cases we can detect
4379 * at translate time.
4382 case ARM_CPU_MODE_MON
:
4383 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4386 if (s
->current_el
== 1) {
4387 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4388 * then accesses to Mon registers trap to EL3
4394 case ARM_CPU_MODE_HYP
:
4395 /* Note that we can forbid accesses from EL2 here because they
4396 * must be from Hyp mode itself
4398 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4409 /* If we get here then some access check did not pass */
4410 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4414 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4416 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4417 int tgtmode
= 0, regno
= 0;
4419 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4423 /* Sync state because msr_banked() can raise exceptions */
4424 gen_set_condexec(s
);
4425 gen_set_pc_im(s
, s
->pc
- 4);
4426 tcg_reg
= load_reg(s
, rn
);
4427 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4428 tcg_regno
= tcg_const_i32(regno
);
4429 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4430 tcg_temp_free_i32(tcg_tgtmode
);
4431 tcg_temp_free_i32(tcg_regno
);
4432 tcg_temp_free_i32(tcg_reg
);
4433 s
->is_jmp
= DISAS_UPDATE
;
4436 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4438 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4439 int tgtmode
= 0, regno
= 0;
4441 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4445 /* Sync state because mrs_banked() can raise exceptions */
4446 gen_set_condexec(s
);
4447 gen_set_pc_im(s
, s
->pc
- 4);
4448 tcg_reg
= tcg_temp_new_i32();
4449 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4450 tcg_regno
= tcg_const_i32(regno
);
4451 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4452 tcg_temp_free_i32(tcg_tgtmode
);
4453 tcg_temp_free_i32(tcg_regno
);
4454 store_reg(s
, rn
, tcg_reg
);
4455 s
->is_jmp
= DISAS_UPDATE
;
4458 /* Store value to PC as for an exception return (ie don't
4459 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4460 * will do the masking based on the new value of the Thumb bit.
4462 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4464 tcg_gen_mov_i32(cpu_R
[15], pc
);
4465 tcg_temp_free_i32(pc
);
4468 /* Generate a v6 exception return. Marks both values as dead. */
4469 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4471 store_pc_exc_ret(s
, pc
);
4472 /* The cpsr_write_eret helper will mask the low bits of PC
4473 * appropriately depending on the new Thumb bit, so it must
4474 * be called after storing the new PC.
4476 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4477 tcg_temp_free_i32(cpsr
);
4478 s
->is_jmp
= DISAS_JUMP
;
4481 /* Generate an old-style exception return. Marks pc as dead. */
4482 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4484 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4488 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4489 * only call the helper when running single threaded TCG code to ensure
4490 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4491 * just skip this instruction. Currently the SEV/SEVL instructions
4492 * which are *one* of many ways to wake the CPU from WFE are not
4493 * implemented so we can't sleep like WFI does.
4495 static void gen_nop_hint(DisasContext
*s
, int val
)
4499 if (!parallel_cpus
) {
4500 gen_set_pc_im(s
, s
->pc
);
4501 s
->is_jmp
= DISAS_YIELD
;
4505 gen_set_pc_im(s
, s
->pc
);
4506 s
->is_jmp
= DISAS_WFI
;
4509 if (!parallel_cpus
) {
4510 gen_set_pc_im(s
, s
->pc
);
4511 s
->is_jmp
= DISAS_WFE
;
4516 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4522 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4524 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4527 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4528 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4529 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4534 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4537 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4538 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4539 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4544 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4545 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4546 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4547 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4548 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4550 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4551 switch ((size << 1) | u) { \
4553 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4556 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4559 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4562 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4565 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4568 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4570 default: return 1; \
4573 #define GEN_NEON_INTEGER_OP(name) do { \
4574 switch ((size << 1) | u) { \
4576 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4579 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4582 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4585 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4588 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4591 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4593 default: return 1; \
4596 static TCGv_i32
neon_load_scratch(int scratch
)
4598 TCGv_i32 tmp
= tcg_temp_new_i32();
4599 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4603 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4605 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4606 tcg_temp_free_i32(var
);
4609 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4613 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4615 gen_neon_dup_high16(tmp
);
4617 gen_neon_dup_low16(tmp
);
4620 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4625 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4628 if (!q
&& size
== 2) {
4631 tmp
= tcg_const_i32(rd
);
4632 tmp2
= tcg_const_i32(rm
);
4636 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4639 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4642 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4650 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4653 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4659 tcg_temp_free_i32(tmp
);
4660 tcg_temp_free_i32(tmp2
);
4664 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4667 if (!q
&& size
== 2) {
4670 tmp
= tcg_const_i32(rd
);
4671 tmp2
= tcg_const_i32(rm
);
4675 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4678 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4681 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4689 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4692 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4698 tcg_temp_free_i32(tmp
);
4699 tcg_temp_free_i32(tmp2
);
4703 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4707 rd
= tcg_temp_new_i32();
4708 tmp
= tcg_temp_new_i32();
4710 tcg_gen_shli_i32(rd
, t0
, 8);
4711 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4712 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4713 tcg_gen_or_i32(rd
, rd
, tmp
);
4715 tcg_gen_shri_i32(t1
, t1
, 8);
4716 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4717 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4718 tcg_gen_or_i32(t1
, t1
, tmp
);
4719 tcg_gen_mov_i32(t0
, rd
);
4721 tcg_temp_free_i32(tmp
);
4722 tcg_temp_free_i32(rd
);
4725 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4729 rd
= tcg_temp_new_i32();
4730 tmp
= tcg_temp_new_i32();
4732 tcg_gen_shli_i32(rd
, t0
, 16);
4733 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4734 tcg_gen_or_i32(rd
, rd
, tmp
);
4735 tcg_gen_shri_i32(t1
, t1
, 16);
4736 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4737 tcg_gen_or_i32(t1
, t1
, tmp
);
4738 tcg_gen_mov_i32(t0
, rd
);
4740 tcg_temp_free_i32(tmp
);
4741 tcg_temp_free_i32(rd
);
4749 } neon_ls_element_type
[11] = {
4763 /* Translate a NEON load/store element instruction. Return nonzero if the
4764 instruction is invalid. */
4765 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4784 /* FIXME: this access check should not take precedence over UNDEF
4785 * for invalid encodings; we will generate incorrect syndrome information
4786 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4788 if (s
->fp_excp_el
) {
4789 gen_exception_insn(s
, 4, EXCP_UDEF
,
4790 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4794 if (!s
->vfp_enabled
)
4796 VFP_DREG_D(rd
, insn
);
4797 rn
= (insn
>> 16) & 0xf;
4799 load
= (insn
& (1 << 21)) != 0;
4800 if ((insn
& (1 << 23)) == 0) {
4801 /* Load store all elements. */
4802 op
= (insn
>> 8) & 0xf;
4803 size
= (insn
>> 6) & 3;
4806 /* Catch UNDEF cases for bad values of align field */
4809 if (((insn
>> 5) & 1) == 1) {
4814 if (((insn
>> 4) & 3) == 3) {
4821 nregs
= neon_ls_element_type
[op
].nregs
;
4822 interleave
= neon_ls_element_type
[op
].interleave
;
4823 spacing
= neon_ls_element_type
[op
].spacing
;
4824 if (size
== 3 && (interleave
| spacing
) != 1)
4826 addr
= tcg_temp_new_i32();
4827 load_reg_var(s
, addr
, rn
);
4828 stride
= (1 << size
) * interleave
;
4829 for (reg
= 0; reg
< nregs
; reg
++) {
4830 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4831 load_reg_var(s
, addr
, rn
);
4832 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4833 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4834 load_reg_var(s
, addr
, rn
);
4835 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4838 tmp64
= tcg_temp_new_i64();
4840 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4841 neon_store_reg64(tmp64
, rd
);
4843 neon_load_reg64(tmp64
, rd
);
4844 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4846 tcg_temp_free_i64(tmp64
);
4847 tcg_gen_addi_i32(addr
, addr
, stride
);
4849 for (pass
= 0; pass
< 2; pass
++) {
4852 tmp
= tcg_temp_new_i32();
4853 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4854 neon_store_reg(rd
, pass
, tmp
);
4856 tmp
= neon_load_reg(rd
, pass
);
4857 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4858 tcg_temp_free_i32(tmp
);
4860 tcg_gen_addi_i32(addr
, addr
, stride
);
4861 } else if (size
== 1) {
4863 tmp
= tcg_temp_new_i32();
4864 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4865 tcg_gen_addi_i32(addr
, addr
, stride
);
4866 tmp2
= tcg_temp_new_i32();
4867 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4868 tcg_gen_addi_i32(addr
, addr
, stride
);
4869 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4870 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4871 tcg_temp_free_i32(tmp2
);
4872 neon_store_reg(rd
, pass
, tmp
);
4874 tmp
= neon_load_reg(rd
, pass
);
4875 tmp2
= tcg_temp_new_i32();
4876 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4877 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4878 tcg_temp_free_i32(tmp
);
4879 tcg_gen_addi_i32(addr
, addr
, stride
);
4880 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4881 tcg_temp_free_i32(tmp2
);
4882 tcg_gen_addi_i32(addr
, addr
, stride
);
4884 } else /* size == 0 */ {
4886 TCGV_UNUSED_I32(tmp2
);
4887 for (n
= 0; n
< 4; n
++) {
4888 tmp
= tcg_temp_new_i32();
4889 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4890 tcg_gen_addi_i32(addr
, addr
, stride
);
4894 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4895 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4896 tcg_temp_free_i32(tmp
);
4899 neon_store_reg(rd
, pass
, tmp2
);
4901 tmp2
= neon_load_reg(rd
, pass
);
4902 for (n
= 0; n
< 4; n
++) {
4903 tmp
= tcg_temp_new_i32();
4905 tcg_gen_mov_i32(tmp
, tmp2
);
4907 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4909 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4910 tcg_temp_free_i32(tmp
);
4911 tcg_gen_addi_i32(addr
, addr
, stride
);
4913 tcg_temp_free_i32(tmp2
);
4920 tcg_temp_free_i32(addr
);
4923 size
= (insn
>> 10) & 3;
4925 /* Load single element to all lanes. */
4926 int a
= (insn
>> 4) & 1;
4930 size
= (insn
>> 6) & 3;
4931 nregs
= ((insn
>> 8) & 3) + 1;
4934 if (nregs
!= 4 || a
== 0) {
4937 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4940 if (nregs
== 1 && a
== 1 && size
== 0) {
4943 if (nregs
== 3 && a
== 1) {
4946 addr
= tcg_temp_new_i32();
4947 load_reg_var(s
, addr
, rn
);
4949 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4950 tmp
= gen_load_and_replicate(s
, addr
, size
);
4951 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4952 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4953 if (insn
& (1 << 5)) {
4954 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4955 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4957 tcg_temp_free_i32(tmp
);
4959 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4960 stride
= (insn
& (1 << 5)) ? 2 : 1;
4961 for (reg
= 0; reg
< nregs
; reg
++) {
4962 tmp
= gen_load_and_replicate(s
, addr
, size
);
4963 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4964 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4965 tcg_temp_free_i32(tmp
);
4966 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4970 tcg_temp_free_i32(addr
);
4971 stride
= (1 << size
) * nregs
;
4973 /* Single element. */
4974 int idx
= (insn
>> 4) & 0xf;
4975 pass
= (insn
>> 7) & 1;
4978 shift
= ((insn
>> 5) & 3) * 8;
4982 shift
= ((insn
>> 6) & 1) * 16;
4983 stride
= (insn
& (1 << 5)) ? 2 : 1;
4987 stride
= (insn
& (1 << 6)) ? 2 : 1;
4992 nregs
= ((insn
>> 8) & 3) + 1;
4993 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4996 if (((idx
& (1 << size
)) != 0) ||
4997 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
5002 if ((idx
& 1) != 0) {
5007 if (size
== 2 && (idx
& 2) != 0) {
5012 if ((size
== 2) && ((idx
& 3) == 3)) {
5019 if ((rd
+ stride
* (nregs
- 1)) > 31) {
5020 /* Attempts to write off the end of the register file
5021 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5022 * the neon_load_reg() would write off the end of the array.
5026 addr
= tcg_temp_new_i32();
5027 load_reg_var(s
, addr
, rn
);
5028 for (reg
= 0; reg
< nregs
; reg
++) {
5030 tmp
= tcg_temp_new_i32();
5033 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
5036 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
5039 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
5041 default: /* Avoid compiler warnings. */
5045 tmp2
= neon_load_reg(rd
, pass
);
5046 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
5047 shift
, size
? 16 : 8);
5048 tcg_temp_free_i32(tmp2
);
5050 neon_store_reg(rd
, pass
, tmp
);
5051 } else { /* Store */
5052 tmp
= neon_load_reg(rd
, pass
);
5054 tcg_gen_shri_i32(tmp
, tmp
, shift
);
5057 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
5060 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
5063 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5066 tcg_temp_free_i32(tmp
);
5069 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5071 tcg_temp_free_i32(addr
);
5072 stride
= nregs
* (1 << size
);
5078 base
= load_reg(s
, rn
);
5080 tcg_gen_addi_i32(base
, base
, stride
);
5083 index
= load_reg(s
, rm
);
5084 tcg_gen_add_i32(base
, base
, index
);
5085 tcg_temp_free_i32(index
);
5087 store_reg(s
, rn
, base
);
5092 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5093 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
5095 tcg_gen_and_i32(t
, t
, c
);
5096 tcg_gen_andc_i32(f
, f
, c
);
5097 tcg_gen_or_i32(dest
, t
, f
);
5100 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5103 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
5104 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
5105 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
5110 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5113 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
5114 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
5115 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5120 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5123 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5124 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5125 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5130 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5133 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5134 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5135 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5140 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5146 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5147 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5152 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5153 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5160 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5161 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5166 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5167 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5174 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5178 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5179 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5180 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5185 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5186 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5187 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5191 tcg_temp_free_i32(src
);
5194 static inline void gen_neon_addl(int size
)
5197 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5198 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5199 case 2: tcg_gen_add_i64(CPU_V001
); break;
5204 static inline void gen_neon_subl(int size
)
5207 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5208 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5209 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5214 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5217 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5218 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5220 tcg_gen_neg_i64(var
, var
);
5226 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5229 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5230 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5235 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5240 switch ((size
<< 1) | u
) {
5241 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5242 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5243 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5244 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5246 tmp
= gen_muls_i64_i32(a
, b
);
5247 tcg_gen_mov_i64(dest
, tmp
);
5248 tcg_temp_free_i64(tmp
);
5251 tmp
= gen_mulu_i64_i32(a
, b
);
5252 tcg_gen_mov_i64(dest
, tmp
);
5253 tcg_temp_free_i64(tmp
);
5258 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5259 Don't forget to clean them now. */
5261 tcg_temp_free_i32(a
);
5262 tcg_temp_free_i32(b
);
5266 static void gen_neon_narrow_op(int op
, int u
, int size
,
5267 TCGv_i32 dest
, TCGv_i64 src
)
5271 gen_neon_unarrow_sats(size
, dest
, src
);
5273 gen_neon_narrow(size
, dest
, src
);
5277 gen_neon_narrow_satu(size
, dest
, src
);
5279 gen_neon_narrow_sats(size
, dest
, src
);
5284 /* Symbolic constants for op fields for Neon 3-register same-length.
5285 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5288 #define NEON_3R_VHADD 0
5289 #define NEON_3R_VQADD 1
5290 #define NEON_3R_VRHADD 2
5291 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5292 #define NEON_3R_VHSUB 4
5293 #define NEON_3R_VQSUB 5
5294 #define NEON_3R_VCGT 6
5295 #define NEON_3R_VCGE 7
5296 #define NEON_3R_VSHL 8
5297 #define NEON_3R_VQSHL 9
5298 #define NEON_3R_VRSHL 10
5299 #define NEON_3R_VQRSHL 11
5300 #define NEON_3R_VMAX 12
5301 #define NEON_3R_VMIN 13
5302 #define NEON_3R_VABD 14
5303 #define NEON_3R_VABA 15
5304 #define NEON_3R_VADD_VSUB 16
5305 #define NEON_3R_VTST_VCEQ 17
5306 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5307 #define NEON_3R_VMUL 19
5308 #define NEON_3R_VPMAX 20
5309 #define NEON_3R_VPMIN 21
5310 #define NEON_3R_VQDMULH_VQRDMULH 22
5311 #define NEON_3R_VPADD 23
5312 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5313 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5314 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5315 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5316 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5317 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5318 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5319 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5321 static const uint8_t neon_3r_sizes
[] = {
5322 [NEON_3R_VHADD
] = 0x7,
5323 [NEON_3R_VQADD
] = 0xf,
5324 [NEON_3R_VRHADD
] = 0x7,
5325 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5326 [NEON_3R_VHSUB
] = 0x7,
5327 [NEON_3R_VQSUB
] = 0xf,
5328 [NEON_3R_VCGT
] = 0x7,
5329 [NEON_3R_VCGE
] = 0x7,
5330 [NEON_3R_VSHL
] = 0xf,
5331 [NEON_3R_VQSHL
] = 0xf,
5332 [NEON_3R_VRSHL
] = 0xf,
5333 [NEON_3R_VQRSHL
] = 0xf,
5334 [NEON_3R_VMAX
] = 0x7,
5335 [NEON_3R_VMIN
] = 0x7,
5336 [NEON_3R_VABD
] = 0x7,
5337 [NEON_3R_VABA
] = 0x7,
5338 [NEON_3R_VADD_VSUB
] = 0xf,
5339 [NEON_3R_VTST_VCEQ
] = 0x7,
5340 [NEON_3R_VML
] = 0x7,
5341 [NEON_3R_VMUL
] = 0x7,
5342 [NEON_3R_VPMAX
] = 0x7,
5343 [NEON_3R_VPMIN
] = 0x7,
5344 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5345 [NEON_3R_VPADD
] = 0x7,
5346 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5347 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5348 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5349 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5350 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5351 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5352 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5353 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5356 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5357 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5360 #define NEON_2RM_VREV64 0
5361 #define NEON_2RM_VREV32 1
5362 #define NEON_2RM_VREV16 2
5363 #define NEON_2RM_VPADDL 4
5364 #define NEON_2RM_VPADDL_U 5
5365 #define NEON_2RM_AESE 6 /* Includes AESD */
5366 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5367 #define NEON_2RM_VCLS 8
5368 #define NEON_2RM_VCLZ 9
5369 #define NEON_2RM_VCNT 10
5370 #define NEON_2RM_VMVN 11
5371 #define NEON_2RM_VPADAL 12
5372 #define NEON_2RM_VPADAL_U 13
5373 #define NEON_2RM_VQABS 14
5374 #define NEON_2RM_VQNEG 15
5375 #define NEON_2RM_VCGT0 16
5376 #define NEON_2RM_VCGE0 17
5377 #define NEON_2RM_VCEQ0 18
5378 #define NEON_2RM_VCLE0 19
5379 #define NEON_2RM_VCLT0 20
5380 #define NEON_2RM_SHA1H 21
5381 #define NEON_2RM_VABS 22
5382 #define NEON_2RM_VNEG 23
5383 #define NEON_2RM_VCGT0_F 24
5384 #define NEON_2RM_VCGE0_F 25
5385 #define NEON_2RM_VCEQ0_F 26
5386 #define NEON_2RM_VCLE0_F 27
5387 #define NEON_2RM_VCLT0_F 28
5388 #define NEON_2RM_VABS_F 30
5389 #define NEON_2RM_VNEG_F 31
5390 #define NEON_2RM_VSWP 32
5391 #define NEON_2RM_VTRN 33
5392 #define NEON_2RM_VUZP 34
5393 #define NEON_2RM_VZIP 35
5394 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5395 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5396 #define NEON_2RM_VSHLL 38
5397 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5398 #define NEON_2RM_VRINTN 40
5399 #define NEON_2RM_VRINTX 41
5400 #define NEON_2RM_VRINTA 42
5401 #define NEON_2RM_VRINTZ 43
5402 #define NEON_2RM_VCVT_F16_F32 44
5403 #define NEON_2RM_VRINTM 45
5404 #define NEON_2RM_VCVT_F32_F16 46
5405 #define NEON_2RM_VRINTP 47
5406 #define NEON_2RM_VCVTAU 48
5407 #define NEON_2RM_VCVTAS 49
5408 #define NEON_2RM_VCVTNU 50
5409 #define NEON_2RM_VCVTNS 51
5410 #define NEON_2RM_VCVTPU 52
5411 #define NEON_2RM_VCVTPS 53
5412 #define NEON_2RM_VCVTMU 54
5413 #define NEON_2RM_VCVTMS 55
5414 #define NEON_2RM_VRECPE 56
5415 #define NEON_2RM_VRSQRTE 57
5416 #define NEON_2RM_VRECPE_F 58
5417 #define NEON_2RM_VRSQRTE_F 59
5418 #define NEON_2RM_VCVT_FS 60
5419 #define NEON_2RM_VCVT_FU 61
5420 #define NEON_2RM_VCVT_SF 62
5421 #define NEON_2RM_VCVT_UF 63
5423 static int neon_2rm_is_float_op(int op
)
5425 /* Return true if this neon 2reg-misc op is float-to-float */
5426 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5427 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5428 op
== NEON_2RM_VRINTM
||
5429 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5430 op
>= NEON_2RM_VRECPE_F
);
5433 static bool neon_2rm_is_v8_op(int op
)
5435 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5437 case NEON_2RM_VRINTN
:
5438 case NEON_2RM_VRINTA
:
5439 case NEON_2RM_VRINTM
:
5440 case NEON_2RM_VRINTP
:
5441 case NEON_2RM_VRINTZ
:
5442 case NEON_2RM_VRINTX
:
5443 case NEON_2RM_VCVTAU
:
5444 case NEON_2RM_VCVTAS
:
5445 case NEON_2RM_VCVTNU
:
5446 case NEON_2RM_VCVTNS
:
5447 case NEON_2RM_VCVTPU
:
5448 case NEON_2RM_VCVTPS
:
5449 case NEON_2RM_VCVTMU
:
5450 case NEON_2RM_VCVTMS
:
5457 /* Each entry in this array has bit n set if the insn allows
5458 * size value n (otherwise it will UNDEF). Since unallocated
5459 * op values will have no bits set they always UNDEF.
5461 static const uint8_t neon_2rm_sizes
[] = {
5462 [NEON_2RM_VREV64
] = 0x7,
5463 [NEON_2RM_VREV32
] = 0x3,
5464 [NEON_2RM_VREV16
] = 0x1,
5465 [NEON_2RM_VPADDL
] = 0x7,
5466 [NEON_2RM_VPADDL_U
] = 0x7,
5467 [NEON_2RM_AESE
] = 0x1,
5468 [NEON_2RM_AESMC
] = 0x1,
5469 [NEON_2RM_VCLS
] = 0x7,
5470 [NEON_2RM_VCLZ
] = 0x7,
5471 [NEON_2RM_VCNT
] = 0x1,
5472 [NEON_2RM_VMVN
] = 0x1,
5473 [NEON_2RM_VPADAL
] = 0x7,
5474 [NEON_2RM_VPADAL_U
] = 0x7,
5475 [NEON_2RM_VQABS
] = 0x7,
5476 [NEON_2RM_VQNEG
] = 0x7,
5477 [NEON_2RM_VCGT0
] = 0x7,
5478 [NEON_2RM_VCGE0
] = 0x7,
5479 [NEON_2RM_VCEQ0
] = 0x7,
5480 [NEON_2RM_VCLE0
] = 0x7,
5481 [NEON_2RM_VCLT0
] = 0x7,
5482 [NEON_2RM_SHA1H
] = 0x4,
5483 [NEON_2RM_VABS
] = 0x7,
5484 [NEON_2RM_VNEG
] = 0x7,
5485 [NEON_2RM_VCGT0_F
] = 0x4,
5486 [NEON_2RM_VCGE0_F
] = 0x4,
5487 [NEON_2RM_VCEQ0_F
] = 0x4,
5488 [NEON_2RM_VCLE0_F
] = 0x4,
5489 [NEON_2RM_VCLT0_F
] = 0x4,
5490 [NEON_2RM_VABS_F
] = 0x4,
5491 [NEON_2RM_VNEG_F
] = 0x4,
5492 [NEON_2RM_VSWP
] = 0x1,
5493 [NEON_2RM_VTRN
] = 0x7,
5494 [NEON_2RM_VUZP
] = 0x7,
5495 [NEON_2RM_VZIP
] = 0x7,
5496 [NEON_2RM_VMOVN
] = 0x7,
5497 [NEON_2RM_VQMOVN
] = 0x7,
5498 [NEON_2RM_VSHLL
] = 0x7,
5499 [NEON_2RM_SHA1SU1
] = 0x4,
5500 [NEON_2RM_VRINTN
] = 0x4,
5501 [NEON_2RM_VRINTX
] = 0x4,
5502 [NEON_2RM_VRINTA
] = 0x4,
5503 [NEON_2RM_VRINTZ
] = 0x4,
5504 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5505 [NEON_2RM_VRINTM
] = 0x4,
5506 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5507 [NEON_2RM_VRINTP
] = 0x4,
5508 [NEON_2RM_VCVTAU
] = 0x4,
5509 [NEON_2RM_VCVTAS
] = 0x4,
5510 [NEON_2RM_VCVTNU
] = 0x4,
5511 [NEON_2RM_VCVTNS
] = 0x4,
5512 [NEON_2RM_VCVTPU
] = 0x4,
5513 [NEON_2RM_VCVTPS
] = 0x4,
5514 [NEON_2RM_VCVTMU
] = 0x4,
5515 [NEON_2RM_VCVTMS
] = 0x4,
5516 [NEON_2RM_VRECPE
] = 0x4,
5517 [NEON_2RM_VRSQRTE
] = 0x4,
5518 [NEON_2RM_VRECPE_F
] = 0x4,
5519 [NEON_2RM_VRSQRTE_F
] = 0x4,
5520 [NEON_2RM_VCVT_FS
] = 0x4,
5521 [NEON_2RM_VCVT_FU
] = 0x4,
5522 [NEON_2RM_VCVT_SF
] = 0x4,
5523 [NEON_2RM_VCVT_UF
] = 0x4,
5526 /* Translate a NEON data processing instruction. Return nonzero if the
5527 instruction is invalid.
5528 We process data in a mixture of 32-bit and 64-bit chunks.
5529 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5531 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5543 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5546 /* FIXME: this access check should not take precedence over UNDEF
5547 * for invalid encodings; we will generate incorrect syndrome information
5548 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5550 if (s
->fp_excp_el
) {
5551 gen_exception_insn(s
, 4, EXCP_UDEF
,
5552 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5556 if (!s
->vfp_enabled
)
5558 q
= (insn
& (1 << 6)) != 0;
5559 u
= (insn
>> 24) & 1;
5560 VFP_DREG_D(rd
, insn
);
5561 VFP_DREG_N(rn
, insn
);
5562 VFP_DREG_M(rm
, insn
);
5563 size
= (insn
>> 20) & 3;
5564 if ((insn
& (1 << 23)) == 0) {
5565 /* Three register same length. */
5566 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5567 /* Catch invalid op and bad size combinations: UNDEF */
5568 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5571 /* All insns of this form UNDEF for either this condition or the
5572 * superset of cases "Q==1"; we catch the latter later.
5574 if (q
&& ((rd
| rn
| rm
) & 1)) {
5578 * The SHA-1/SHA-256 3-register instructions require special treatment
5579 * here, as their size field is overloaded as an op type selector, and
5580 * they all consume their input in a single pass.
5582 if (op
== NEON_3R_SHA
) {
5586 if (!u
) { /* SHA-1 */
5587 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5590 tmp
= tcg_const_i32(rd
);
5591 tmp2
= tcg_const_i32(rn
);
5592 tmp3
= tcg_const_i32(rm
);
5593 tmp4
= tcg_const_i32(size
);
5594 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5595 tcg_temp_free_i32(tmp4
);
5596 } else { /* SHA-256 */
5597 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5600 tmp
= tcg_const_i32(rd
);
5601 tmp2
= tcg_const_i32(rn
);
5602 tmp3
= tcg_const_i32(rm
);
5605 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5608 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5611 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5615 tcg_temp_free_i32(tmp
);
5616 tcg_temp_free_i32(tmp2
);
5617 tcg_temp_free_i32(tmp3
);
5620 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5621 /* 64-bit element instructions. */
5622 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5623 neon_load_reg64(cpu_V0
, rn
+ pass
);
5624 neon_load_reg64(cpu_V1
, rm
+ pass
);
5628 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5631 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5637 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5640 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5646 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5648 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5653 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5656 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5662 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5664 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5667 case NEON_3R_VQRSHL
:
5669 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5672 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5676 case NEON_3R_VADD_VSUB
:
5678 tcg_gen_sub_i64(CPU_V001
);
5680 tcg_gen_add_i64(CPU_V001
);
5686 neon_store_reg64(cpu_V0
, rd
+ pass
);
5695 case NEON_3R_VQRSHL
:
5698 /* Shift instruction operands are reversed. */
5713 case NEON_3R_FLOAT_ARITH
:
5714 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5716 case NEON_3R_FLOAT_MINMAX
:
5717 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5719 case NEON_3R_FLOAT_CMP
:
5721 /* no encoding for U=0 C=1x */
5725 case NEON_3R_FLOAT_ACMP
:
5730 case NEON_3R_FLOAT_MISC
:
5731 /* VMAXNM/VMINNM in ARMv8 */
5732 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5737 if (u
&& (size
!= 0)) {
5738 /* UNDEF on invalid size for polynomial subcase */
5743 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5751 if (pairwise
&& q
) {
5752 /* All the pairwise insns UNDEF if Q is set */
5756 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5761 tmp
= neon_load_reg(rn
, 0);
5762 tmp2
= neon_load_reg(rn
, 1);
5764 tmp
= neon_load_reg(rm
, 0);
5765 tmp2
= neon_load_reg(rm
, 1);
5769 tmp
= neon_load_reg(rn
, pass
);
5770 tmp2
= neon_load_reg(rm
, pass
);
5774 GEN_NEON_INTEGER_OP(hadd
);
5777 GEN_NEON_INTEGER_OP_ENV(qadd
);
5779 case NEON_3R_VRHADD
:
5780 GEN_NEON_INTEGER_OP(rhadd
);
5782 case NEON_3R_LOGIC
: /* Logic ops. */
5783 switch ((u
<< 2) | size
) {
5785 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5788 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5791 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5794 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5797 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5800 tmp3
= neon_load_reg(rd
, pass
);
5801 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5802 tcg_temp_free_i32(tmp3
);
5805 tmp3
= neon_load_reg(rd
, pass
);
5806 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5807 tcg_temp_free_i32(tmp3
);
5810 tmp3
= neon_load_reg(rd
, pass
);
5811 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5812 tcg_temp_free_i32(tmp3
);
5817 GEN_NEON_INTEGER_OP(hsub
);
5820 GEN_NEON_INTEGER_OP_ENV(qsub
);
5823 GEN_NEON_INTEGER_OP(cgt
);
5826 GEN_NEON_INTEGER_OP(cge
);
5829 GEN_NEON_INTEGER_OP(shl
);
5832 GEN_NEON_INTEGER_OP_ENV(qshl
);
5835 GEN_NEON_INTEGER_OP(rshl
);
5837 case NEON_3R_VQRSHL
:
5838 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5841 GEN_NEON_INTEGER_OP(max
);
5844 GEN_NEON_INTEGER_OP(min
);
5847 GEN_NEON_INTEGER_OP(abd
);
5850 GEN_NEON_INTEGER_OP(abd
);
5851 tcg_temp_free_i32(tmp2
);
5852 tmp2
= neon_load_reg(rd
, pass
);
5853 gen_neon_add(size
, tmp
, tmp2
);
5855 case NEON_3R_VADD_VSUB
:
5856 if (!u
) { /* VADD */
5857 gen_neon_add(size
, tmp
, tmp2
);
5860 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5861 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5862 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5867 case NEON_3R_VTST_VCEQ
:
5868 if (!u
) { /* VTST */
5870 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5871 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5872 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5877 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5878 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5879 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5884 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5886 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5887 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5888 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5891 tcg_temp_free_i32(tmp2
);
5892 tmp2
= neon_load_reg(rd
, pass
);
5894 gen_neon_rsb(size
, tmp
, tmp2
);
5896 gen_neon_add(size
, tmp
, tmp2
);
5900 if (u
) { /* polynomial */
5901 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5902 } else { /* Integer */
5904 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5905 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5906 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5912 GEN_NEON_INTEGER_OP(pmax
);
5915 GEN_NEON_INTEGER_OP(pmin
);
5917 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5918 if (!u
) { /* VQDMULH */
5921 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5924 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5928 } else { /* VQRDMULH */
5931 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5934 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5942 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5943 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5944 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5948 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5950 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5951 switch ((u
<< 2) | size
) {
5954 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5957 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5960 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5965 tcg_temp_free_ptr(fpstatus
);
5968 case NEON_3R_FLOAT_MULTIPLY
:
5970 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5971 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5973 tcg_temp_free_i32(tmp2
);
5974 tmp2
= neon_load_reg(rd
, pass
);
5976 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5978 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5981 tcg_temp_free_ptr(fpstatus
);
5984 case NEON_3R_FLOAT_CMP
:
5986 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5988 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5991 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5993 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5996 tcg_temp_free_ptr(fpstatus
);
5999 case NEON_3R_FLOAT_ACMP
:
6001 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6003 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6005 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6007 tcg_temp_free_ptr(fpstatus
);
6010 case NEON_3R_FLOAT_MINMAX
:
6012 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6014 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6016 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6018 tcg_temp_free_ptr(fpstatus
);
6021 case NEON_3R_FLOAT_MISC
:
6024 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6026 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6028 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6030 tcg_temp_free_ptr(fpstatus
);
6033 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6035 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6041 /* VFMA, VFMS: fused multiply-add */
6042 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6043 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6046 gen_helper_vfp_negs(tmp
, tmp
);
6048 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6049 tcg_temp_free_i32(tmp3
);
6050 tcg_temp_free_ptr(fpstatus
);
6056 tcg_temp_free_i32(tmp2
);
6058 /* Save the result. For elementwise operations we can put it
6059 straight into the destination register. For pairwise operations
6060 we have to be careful to avoid clobbering the source operands. */
6061 if (pairwise
&& rd
== rm
) {
6062 neon_store_scratch(pass
, tmp
);
6064 neon_store_reg(rd
, pass
, tmp
);
6068 if (pairwise
&& rd
== rm
) {
6069 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6070 tmp
= neon_load_scratch(pass
);
6071 neon_store_reg(rd
, pass
, tmp
);
6074 /* End of 3 register same size operations. */
6075 } else if (insn
& (1 << 4)) {
6076 if ((insn
& 0x00380080) != 0) {
6077 /* Two registers and shift. */
6078 op
= (insn
>> 8) & 0xf;
6079 if (insn
& (1 << 7)) {
6087 while ((insn
& (1 << (size
+ 19))) == 0)
6090 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6091 /* To avoid excessive duplication of ops we implement shift
6092 by immediate using the variable shift operations. */
6094 /* Shift by immediate:
6095 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6096 if (q
&& ((rd
| rm
) & 1)) {
6099 if (!u
&& (op
== 4 || op
== 6)) {
6102 /* Right shifts are encoded as N - shift, where N is the
6103 element size in bits. */
6105 shift
= shift
- (1 << (size
+ 3));
6113 imm
= (uint8_t) shift
;
6118 imm
= (uint16_t) shift
;
6129 for (pass
= 0; pass
< count
; pass
++) {
6131 neon_load_reg64(cpu_V0
, rm
+ pass
);
6132 tcg_gen_movi_i64(cpu_V1
, imm
);
6137 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6139 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6144 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6146 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6149 case 5: /* VSHL, VSLI */
6150 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6152 case 6: /* VQSHLU */
6153 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6158 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6161 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6166 if (op
== 1 || op
== 3) {
6168 neon_load_reg64(cpu_V1
, rd
+ pass
);
6169 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6170 } else if (op
== 4 || (op
== 5 && u
)) {
6172 neon_load_reg64(cpu_V1
, rd
+ pass
);
6174 if (shift
< -63 || shift
> 63) {
6178 mask
= 0xffffffffffffffffull
>> -shift
;
6180 mask
= 0xffffffffffffffffull
<< shift
;
6183 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6184 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6186 neon_store_reg64(cpu_V0
, rd
+ pass
);
6187 } else { /* size < 3 */
6188 /* Operands in T0 and T1. */
6189 tmp
= neon_load_reg(rm
, pass
);
6190 tmp2
= tcg_temp_new_i32();
6191 tcg_gen_movi_i32(tmp2
, imm
);
6195 GEN_NEON_INTEGER_OP(shl
);
6199 GEN_NEON_INTEGER_OP(rshl
);
6202 case 5: /* VSHL, VSLI */
6204 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6205 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6206 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6210 case 6: /* VQSHLU */
6213 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6217 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6221 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6229 GEN_NEON_INTEGER_OP_ENV(qshl
);
6232 tcg_temp_free_i32(tmp2
);
6234 if (op
== 1 || op
== 3) {
6236 tmp2
= neon_load_reg(rd
, pass
);
6237 gen_neon_add(size
, tmp
, tmp2
);
6238 tcg_temp_free_i32(tmp2
);
6239 } else if (op
== 4 || (op
== 5 && u
)) {
6244 mask
= 0xff >> -shift
;
6246 mask
= (uint8_t)(0xff << shift
);
6252 mask
= 0xffff >> -shift
;
6254 mask
= (uint16_t)(0xffff << shift
);
6258 if (shift
< -31 || shift
> 31) {
6262 mask
= 0xffffffffu
>> -shift
;
6264 mask
= 0xffffffffu
<< shift
;
6270 tmp2
= neon_load_reg(rd
, pass
);
6271 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6272 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6273 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6274 tcg_temp_free_i32(tmp2
);
6276 neon_store_reg(rd
, pass
, tmp
);
6279 } else if (op
< 10) {
6280 /* Shift by immediate and narrow:
6281 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6282 int input_unsigned
= (op
== 8) ? !u
: u
;
6286 shift
= shift
- (1 << (size
+ 3));
6289 tmp64
= tcg_const_i64(shift
);
6290 neon_load_reg64(cpu_V0
, rm
);
6291 neon_load_reg64(cpu_V1
, rm
+ 1);
6292 for (pass
= 0; pass
< 2; pass
++) {
6300 if (input_unsigned
) {
6301 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6303 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6306 if (input_unsigned
) {
6307 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6309 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6312 tmp
= tcg_temp_new_i32();
6313 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6314 neon_store_reg(rd
, pass
, tmp
);
6316 tcg_temp_free_i64(tmp64
);
6319 imm
= (uint16_t)shift
;
6323 imm
= (uint32_t)shift
;
6325 tmp2
= tcg_const_i32(imm
);
6326 tmp4
= neon_load_reg(rm
+ 1, 0);
6327 tmp5
= neon_load_reg(rm
+ 1, 1);
6328 for (pass
= 0; pass
< 2; pass
++) {
6330 tmp
= neon_load_reg(rm
, 0);
6334 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6337 tmp3
= neon_load_reg(rm
, 1);
6341 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6343 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6344 tcg_temp_free_i32(tmp
);
6345 tcg_temp_free_i32(tmp3
);
6346 tmp
= tcg_temp_new_i32();
6347 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6348 neon_store_reg(rd
, pass
, tmp
);
6350 tcg_temp_free_i32(tmp2
);
6352 } else if (op
== 10) {
6354 if (q
|| (rd
& 1)) {
6357 tmp
= neon_load_reg(rm
, 0);
6358 tmp2
= neon_load_reg(rm
, 1);
6359 for (pass
= 0; pass
< 2; pass
++) {
6363 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6366 /* The shift is less than the width of the source
6367 type, so we can just shift the whole register. */
6368 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6369 /* Widen the result of shift: we need to clear
6370 * the potential overflow bits resulting from
6371 * left bits of the narrow input appearing as
6372 * right bits of left the neighbour narrow
6374 if (size
< 2 || !u
) {
6377 imm
= (0xffu
>> (8 - shift
));
6379 } else if (size
== 1) {
6380 imm
= 0xffff >> (16 - shift
);
6383 imm
= 0xffffffff >> (32 - shift
);
6386 imm64
= imm
| (((uint64_t)imm
) << 32);
6390 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6393 neon_store_reg64(cpu_V0
, rd
+ pass
);
6395 } else if (op
>= 14) {
6396 /* VCVT fixed-point. */
6397 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6400 /* We have already masked out the must-be-1 top bit of imm6,
6401 * hence this 32-shift where the ARM ARM has 64-imm6.
6404 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6405 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6408 gen_vfp_ulto(0, shift
, 1);
6410 gen_vfp_slto(0, shift
, 1);
6413 gen_vfp_toul(0, shift
, 1);
6415 gen_vfp_tosl(0, shift
, 1);
6417 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6422 } else { /* (insn & 0x00380080) == 0 */
6424 if (q
&& (rd
& 1)) {
6428 op
= (insn
>> 8) & 0xf;
6429 /* One register and immediate. */
6430 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6431 invert
= (insn
& (1 << 5)) != 0;
6432 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6433 * We choose to not special-case this and will behave as if a
6434 * valid constant encoding of 0 had been given.
6453 imm
= (imm
<< 8) | (imm
<< 24);
6456 imm
= (imm
<< 8) | 0xff;
6459 imm
= (imm
<< 16) | 0xffff;
6462 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6470 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6471 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6477 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6478 if (op
& 1 && op
< 12) {
6479 tmp
= neon_load_reg(rd
, pass
);
6481 /* The immediate value has already been inverted, so
6483 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6485 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6489 tmp
= tcg_temp_new_i32();
6490 if (op
== 14 && invert
) {
6494 for (n
= 0; n
< 4; n
++) {
6495 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6496 val
|= 0xff << (n
* 8);
6498 tcg_gen_movi_i32(tmp
, val
);
6500 tcg_gen_movi_i32(tmp
, imm
);
6503 neon_store_reg(rd
, pass
, tmp
);
6506 } else { /* (insn & 0x00800010 == 0x00800000) */
6508 op
= (insn
>> 8) & 0xf;
6509 if ((insn
& (1 << 6)) == 0) {
6510 /* Three registers of different lengths. */
6514 /* undefreq: bit 0 : UNDEF if size == 0
6515 * bit 1 : UNDEF if size == 1
6516 * bit 2 : UNDEF if size == 2
6517 * bit 3 : UNDEF if U == 1
6518 * Note that [2:0] set implies 'always UNDEF'
6521 /* prewiden, src1_wide, src2_wide, undefreq */
6522 static const int neon_3reg_wide
[16][4] = {
6523 {1, 0, 0, 0}, /* VADDL */
6524 {1, 1, 0, 0}, /* VADDW */
6525 {1, 0, 0, 0}, /* VSUBL */
6526 {1, 1, 0, 0}, /* VSUBW */
6527 {0, 1, 1, 0}, /* VADDHN */
6528 {0, 0, 0, 0}, /* VABAL */
6529 {0, 1, 1, 0}, /* VSUBHN */
6530 {0, 0, 0, 0}, /* VABDL */
6531 {0, 0, 0, 0}, /* VMLAL */
6532 {0, 0, 0, 9}, /* VQDMLAL */
6533 {0, 0, 0, 0}, /* VMLSL */
6534 {0, 0, 0, 9}, /* VQDMLSL */
6535 {0, 0, 0, 0}, /* Integer VMULL */
6536 {0, 0, 0, 1}, /* VQDMULL */
6537 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6538 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6541 prewiden
= neon_3reg_wide
[op
][0];
6542 src1_wide
= neon_3reg_wide
[op
][1];
6543 src2_wide
= neon_3reg_wide
[op
][2];
6544 undefreq
= neon_3reg_wide
[op
][3];
6546 if ((undefreq
& (1 << size
)) ||
6547 ((undefreq
& 8) && u
)) {
6550 if ((src1_wide
&& (rn
& 1)) ||
6551 (src2_wide
&& (rm
& 1)) ||
6552 (!src2_wide
&& (rd
& 1))) {
6556 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6557 * outside the loop below as it only performs a single pass.
6559 if (op
== 14 && size
== 2) {
6560 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6562 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6565 tcg_rn
= tcg_temp_new_i64();
6566 tcg_rm
= tcg_temp_new_i64();
6567 tcg_rd
= tcg_temp_new_i64();
6568 neon_load_reg64(tcg_rn
, rn
);
6569 neon_load_reg64(tcg_rm
, rm
);
6570 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6571 neon_store_reg64(tcg_rd
, rd
);
6572 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6573 neon_store_reg64(tcg_rd
, rd
+ 1);
6574 tcg_temp_free_i64(tcg_rn
);
6575 tcg_temp_free_i64(tcg_rm
);
6576 tcg_temp_free_i64(tcg_rd
);
6580 /* Avoid overlapping operands. Wide source operands are
6581 always aligned so will never overlap with wide
6582 destinations in problematic ways. */
6583 if (rd
== rm
&& !src2_wide
) {
6584 tmp
= neon_load_reg(rm
, 1);
6585 neon_store_scratch(2, tmp
);
6586 } else if (rd
== rn
&& !src1_wide
) {
6587 tmp
= neon_load_reg(rn
, 1);
6588 neon_store_scratch(2, tmp
);
6590 TCGV_UNUSED_I32(tmp3
);
6591 for (pass
= 0; pass
< 2; pass
++) {
6593 neon_load_reg64(cpu_V0
, rn
+ pass
);
6594 TCGV_UNUSED_I32(tmp
);
6596 if (pass
== 1 && rd
== rn
) {
6597 tmp
= neon_load_scratch(2);
6599 tmp
= neon_load_reg(rn
, pass
);
6602 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6606 neon_load_reg64(cpu_V1
, rm
+ pass
);
6607 TCGV_UNUSED_I32(tmp2
);
6609 if (pass
== 1 && rd
== rm
) {
6610 tmp2
= neon_load_scratch(2);
6612 tmp2
= neon_load_reg(rm
, pass
);
6615 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6619 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6620 gen_neon_addl(size
);
6622 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6623 gen_neon_subl(size
);
6625 case 5: case 7: /* VABAL, VABDL */
6626 switch ((size
<< 1) | u
) {
6628 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6631 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6634 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6637 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6640 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6643 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6647 tcg_temp_free_i32(tmp2
);
6648 tcg_temp_free_i32(tmp
);
6650 case 8: case 9: case 10: case 11: case 12: case 13:
6651 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6652 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6654 case 14: /* Polynomial VMULL */
6655 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6656 tcg_temp_free_i32(tmp2
);
6657 tcg_temp_free_i32(tmp
);
6659 default: /* 15 is RESERVED: caught earlier */
6664 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6665 neon_store_reg64(cpu_V0
, rd
+ pass
);
6666 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6668 neon_load_reg64(cpu_V1
, rd
+ pass
);
6670 case 10: /* VMLSL */
6671 gen_neon_negl(cpu_V0
, size
);
6673 case 5: case 8: /* VABAL, VMLAL */
6674 gen_neon_addl(size
);
6676 case 9: case 11: /* VQDMLAL, VQDMLSL */
6677 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6679 gen_neon_negl(cpu_V0
, size
);
6681 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6686 neon_store_reg64(cpu_V0
, rd
+ pass
);
6687 } else if (op
== 4 || op
== 6) {
6688 /* Narrowing operation. */
6689 tmp
= tcg_temp_new_i32();
6693 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6696 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6699 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6700 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6707 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6710 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6713 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6714 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6715 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6723 neon_store_reg(rd
, 0, tmp3
);
6724 neon_store_reg(rd
, 1, tmp
);
6727 /* Write back the result. */
6728 neon_store_reg64(cpu_V0
, rd
+ pass
);
6732 /* Two registers and a scalar. NB that for ops of this form
6733 * the ARM ARM labels bit 24 as Q, but it is in our variable
6740 case 1: /* Float VMLA scalar */
6741 case 5: /* Floating point VMLS scalar */
6742 case 9: /* Floating point VMUL scalar */
6747 case 0: /* Integer VMLA scalar */
6748 case 4: /* Integer VMLS scalar */
6749 case 8: /* Integer VMUL scalar */
6750 case 12: /* VQDMULH scalar */
6751 case 13: /* VQRDMULH scalar */
6752 if (u
&& ((rd
| rn
) & 1)) {
6755 tmp
= neon_get_scalar(size
, rm
);
6756 neon_store_scratch(0, tmp
);
6757 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6758 tmp
= neon_load_scratch(0);
6759 tmp2
= neon_load_reg(rn
, pass
);
6762 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6764 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6766 } else if (op
== 13) {
6768 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6770 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6772 } else if (op
& 1) {
6773 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6774 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6775 tcg_temp_free_ptr(fpstatus
);
6778 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6779 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6780 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6784 tcg_temp_free_i32(tmp2
);
6787 tmp2
= neon_load_reg(rd
, pass
);
6790 gen_neon_add(size
, tmp
, tmp2
);
6794 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6795 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6796 tcg_temp_free_ptr(fpstatus
);
6800 gen_neon_rsb(size
, tmp
, tmp2
);
6804 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6805 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6806 tcg_temp_free_ptr(fpstatus
);
6812 tcg_temp_free_i32(tmp2
);
6814 neon_store_reg(rd
, pass
, tmp
);
6817 case 3: /* VQDMLAL scalar */
6818 case 7: /* VQDMLSL scalar */
6819 case 11: /* VQDMULL scalar */
6824 case 2: /* VMLAL sclar */
6825 case 6: /* VMLSL scalar */
6826 case 10: /* VMULL scalar */
6830 tmp2
= neon_get_scalar(size
, rm
);
6831 /* We need a copy of tmp2 because gen_neon_mull
6832 * deletes it during pass 0. */
6833 tmp4
= tcg_temp_new_i32();
6834 tcg_gen_mov_i32(tmp4
, tmp2
);
6835 tmp3
= neon_load_reg(rn
, 1);
6837 for (pass
= 0; pass
< 2; pass
++) {
6839 tmp
= neon_load_reg(rn
, 0);
6844 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6846 neon_load_reg64(cpu_V1
, rd
+ pass
);
6850 gen_neon_negl(cpu_V0
, size
);
6853 gen_neon_addl(size
);
6856 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6858 gen_neon_negl(cpu_V0
, size
);
6860 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6866 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6871 neon_store_reg64(cpu_V0
, rd
+ pass
);
6876 default: /* 14 and 15 are RESERVED */
6880 } else { /* size == 3 */
6883 imm
= (insn
>> 8) & 0xf;
6888 if (q
&& ((rd
| rn
| rm
) & 1)) {
6893 neon_load_reg64(cpu_V0
, rn
);
6895 neon_load_reg64(cpu_V1
, rn
+ 1);
6897 } else if (imm
== 8) {
6898 neon_load_reg64(cpu_V0
, rn
+ 1);
6900 neon_load_reg64(cpu_V1
, rm
);
6903 tmp64
= tcg_temp_new_i64();
6905 neon_load_reg64(cpu_V0
, rn
);
6906 neon_load_reg64(tmp64
, rn
+ 1);
6908 neon_load_reg64(cpu_V0
, rn
+ 1);
6909 neon_load_reg64(tmp64
, rm
);
6911 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6912 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6913 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6915 neon_load_reg64(cpu_V1
, rm
);
6917 neon_load_reg64(cpu_V1
, rm
+ 1);
6920 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6921 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6922 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6923 tcg_temp_free_i64(tmp64
);
6926 neon_load_reg64(cpu_V0
, rn
);
6927 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6928 neon_load_reg64(cpu_V1
, rm
);
6929 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6930 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6932 neon_store_reg64(cpu_V0
, rd
);
6934 neon_store_reg64(cpu_V1
, rd
+ 1);
6936 } else if ((insn
& (1 << 11)) == 0) {
6937 /* Two register misc. */
6938 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6939 size
= (insn
>> 18) & 3;
6940 /* UNDEF for unknown op values and bad op-size combinations */
6941 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6944 if (neon_2rm_is_v8_op(op
) &&
6945 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6948 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6949 q
&& ((rm
| rd
) & 1)) {
6953 case NEON_2RM_VREV64
:
6954 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6955 tmp
= neon_load_reg(rm
, pass
* 2);
6956 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6958 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6959 case 1: gen_swap_half(tmp
); break;
6960 case 2: /* no-op */ break;
6963 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6965 neon_store_reg(rd
, pass
* 2, tmp2
);
6968 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6969 case 1: gen_swap_half(tmp2
); break;
6972 neon_store_reg(rd
, pass
* 2, tmp2
);
6976 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6977 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6978 for (pass
= 0; pass
< q
+ 1; pass
++) {
6979 tmp
= neon_load_reg(rm
, pass
* 2);
6980 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6981 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6982 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6984 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6985 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6986 case 2: tcg_gen_add_i64(CPU_V001
); break;
6989 if (op
>= NEON_2RM_VPADAL
) {
6991 neon_load_reg64(cpu_V1
, rd
+ pass
);
6992 gen_neon_addl(size
);
6994 neon_store_reg64(cpu_V0
, rd
+ pass
);
7000 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7001 tmp
= neon_load_reg(rm
, n
);
7002 tmp2
= neon_load_reg(rd
, n
+ 1);
7003 neon_store_reg(rm
, n
, tmp2
);
7004 neon_store_reg(rd
, n
+ 1, tmp
);
7011 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7016 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7020 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7021 /* also VQMOVUN; op field and mnemonics don't line up */
7025 TCGV_UNUSED_I32(tmp2
);
7026 for (pass
= 0; pass
< 2; pass
++) {
7027 neon_load_reg64(cpu_V0
, rm
+ pass
);
7028 tmp
= tcg_temp_new_i32();
7029 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7034 neon_store_reg(rd
, 0, tmp2
);
7035 neon_store_reg(rd
, 1, tmp
);
7039 case NEON_2RM_VSHLL
:
7040 if (q
|| (rd
& 1)) {
7043 tmp
= neon_load_reg(rm
, 0);
7044 tmp2
= neon_load_reg(rm
, 1);
7045 for (pass
= 0; pass
< 2; pass
++) {
7048 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7049 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7050 neon_store_reg64(cpu_V0
, rd
+ pass
);
7053 case NEON_2RM_VCVT_F16_F32
:
7054 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7058 tmp
= tcg_temp_new_i32();
7059 tmp2
= tcg_temp_new_i32();
7060 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7061 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7062 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7063 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7064 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7065 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7066 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7067 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7068 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7069 neon_store_reg(rd
, 0, tmp2
);
7070 tmp2
= tcg_temp_new_i32();
7071 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7072 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7073 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7074 neon_store_reg(rd
, 1, tmp2
);
7075 tcg_temp_free_i32(tmp
);
7077 case NEON_2RM_VCVT_F32_F16
:
7078 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7082 tmp3
= tcg_temp_new_i32();
7083 tmp
= neon_load_reg(rm
, 0);
7084 tmp2
= neon_load_reg(rm
, 1);
7085 tcg_gen_ext16u_i32(tmp3
, tmp
);
7086 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7087 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7088 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7089 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7090 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7091 tcg_temp_free_i32(tmp
);
7092 tcg_gen_ext16u_i32(tmp3
, tmp2
);
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
, 2));
7095 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7096 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7097 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7098 tcg_temp_free_i32(tmp2
);
7099 tcg_temp_free_i32(tmp3
);
7101 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7102 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
7103 || ((rm
| rd
) & 1)) {
7106 tmp
= tcg_const_i32(rd
);
7107 tmp2
= tcg_const_i32(rm
);
7109 /* Bit 6 is the lowest opcode bit; it distinguishes between
7110 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7112 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7114 if (op
== NEON_2RM_AESE
) {
7115 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
7117 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
7119 tcg_temp_free_i32(tmp
);
7120 tcg_temp_free_i32(tmp2
);
7121 tcg_temp_free_i32(tmp3
);
7123 case NEON_2RM_SHA1H
:
7124 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7125 || ((rm
| rd
) & 1)) {
7128 tmp
= tcg_const_i32(rd
);
7129 tmp2
= tcg_const_i32(rm
);
7131 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
7133 tcg_temp_free_i32(tmp
);
7134 tcg_temp_free_i32(tmp2
);
7136 case NEON_2RM_SHA1SU1
:
7137 if ((rm
| rd
) & 1) {
7140 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7142 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7145 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7148 tmp
= tcg_const_i32(rd
);
7149 tmp2
= tcg_const_i32(rm
);
7151 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
7153 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7155 tcg_temp_free_i32(tmp
);
7156 tcg_temp_free_i32(tmp2
);
7160 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7161 if (neon_2rm_is_float_op(op
)) {
7162 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7163 neon_reg_offset(rm
, pass
));
7164 TCGV_UNUSED_I32(tmp
);
7166 tmp
= neon_load_reg(rm
, pass
);
7169 case NEON_2RM_VREV32
:
7171 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7172 case 1: gen_swap_half(tmp
); break;
7176 case NEON_2RM_VREV16
:
7181 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7182 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7183 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7189 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7190 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7191 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7196 gen_helper_neon_cnt_u8(tmp
, tmp
);
7199 tcg_gen_not_i32(tmp
, tmp
);
7201 case NEON_2RM_VQABS
:
7204 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7207 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7210 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7215 case NEON_2RM_VQNEG
:
7218 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7221 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7224 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7229 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7230 tmp2
= tcg_const_i32(0);
7232 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7233 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7234 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7237 tcg_temp_free_i32(tmp2
);
7238 if (op
== NEON_2RM_VCLE0
) {
7239 tcg_gen_not_i32(tmp
, tmp
);
7242 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7243 tmp2
= tcg_const_i32(0);
7245 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7246 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7247 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7250 tcg_temp_free_i32(tmp2
);
7251 if (op
== NEON_2RM_VCLT0
) {
7252 tcg_gen_not_i32(tmp
, tmp
);
7255 case NEON_2RM_VCEQ0
:
7256 tmp2
= tcg_const_i32(0);
7258 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7259 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7260 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7263 tcg_temp_free_i32(tmp2
);
7267 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7268 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7269 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7274 tmp2
= tcg_const_i32(0);
7275 gen_neon_rsb(size
, tmp
, tmp2
);
7276 tcg_temp_free_i32(tmp2
);
7278 case NEON_2RM_VCGT0_F
:
7280 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7281 tmp2
= tcg_const_i32(0);
7282 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7283 tcg_temp_free_i32(tmp2
);
7284 tcg_temp_free_ptr(fpstatus
);
7287 case NEON_2RM_VCGE0_F
:
7289 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7290 tmp2
= tcg_const_i32(0);
7291 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7292 tcg_temp_free_i32(tmp2
);
7293 tcg_temp_free_ptr(fpstatus
);
7296 case NEON_2RM_VCEQ0_F
:
7298 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7299 tmp2
= tcg_const_i32(0);
7300 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7301 tcg_temp_free_i32(tmp2
);
7302 tcg_temp_free_ptr(fpstatus
);
7305 case NEON_2RM_VCLE0_F
:
7307 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7308 tmp2
= tcg_const_i32(0);
7309 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7310 tcg_temp_free_i32(tmp2
);
7311 tcg_temp_free_ptr(fpstatus
);
7314 case NEON_2RM_VCLT0_F
:
7316 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7317 tmp2
= tcg_const_i32(0);
7318 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7319 tcg_temp_free_i32(tmp2
);
7320 tcg_temp_free_ptr(fpstatus
);
7323 case NEON_2RM_VABS_F
:
7326 case NEON_2RM_VNEG_F
:
7330 tmp2
= neon_load_reg(rd
, pass
);
7331 neon_store_reg(rm
, pass
, tmp2
);
7334 tmp2
= neon_load_reg(rd
, pass
);
7336 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7337 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7340 neon_store_reg(rm
, pass
, tmp2
);
7342 case NEON_2RM_VRINTN
:
7343 case NEON_2RM_VRINTA
:
7344 case NEON_2RM_VRINTM
:
7345 case NEON_2RM_VRINTP
:
7346 case NEON_2RM_VRINTZ
:
7349 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7352 if (op
== NEON_2RM_VRINTZ
) {
7353 rmode
= FPROUNDING_ZERO
;
7355 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7358 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7359 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7361 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7362 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7364 tcg_temp_free_ptr(fpstatus
);
7365 tcg_temp_free_i32(tcg_rmode
);
7368 case NEON_2RM_VRINTX
:
7370 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7371 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7372 tcg_temp_free_ptr(fpstatus
);
7375 case NEON_2RM_VCVTAU
:
7376 case NEON_2RM_VCVTAS
:
7377 case NEON_2RM_VCVTNU
:
7378 case NEON_2RM_VCVTNS
:
7379 case NEON_2RM_VCVTPU
:
7380 case NEON_2RM_VCVTPS
:
7381 case NEON_2RM_VCVTMU
:
7382 case NEON_2RM_VCVTMS
:
7384 bool is_signed
= !extract32(insn
, 7, 1);
7385 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7386 TCGv_i32 tcg_rmode
, tcg_shift
;
7387 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7389 tcg_shift
= tcg_const_i32(0);
7390 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7391 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7395 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7398 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7402 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7404 tcg_temp_free_i32(tcg_rmode
);
7405 tcg_temp_free_i32(tcg_shift
);
7406 tcg_temp_free_ptr(fpst
);
7409 case NEON_2RM_VRECPE
:
7411 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7412 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7413 tcg_temp_free_ptr(fpstatus
);
7416 case NEON_2RM_VRSQRTE
:
7418 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7419 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7420 tcg_temp_free_ptr(fpstatus
);
7423 case NEON_2RM_VRECPE_F
:
7425 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7426 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7427 tcg_temp_free_ptr(fpstatus
);
7430 case NEON_2RM_VRSQRTE_F
:
7432 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7433 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7434 tcg_temp_free_ptr(fpstatus
);
7437 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7440 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7443 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7444 gen_vfp_tosiz(0, 1);
7446 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7447 gen_vfp_touiz(0, 1);
7450 /* Reserved op values were caught by the
7451 * neon_2rm_sizes[] check earlier.
7455 if (neon_2rm_is_float_op(op
)) {
7456 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7457 neon_reg_offset(rd
, pass
));
7459 neon_store_reg(rd
, pass
, tmp
);
7464 } else if ((insn
& (1 << 10)) == 0) {
7466 int n
= ((insn
>> 8) & 3) + 1;
7467 if ((rn
+ n
) > 32) {
7468 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7469 * helper function running off the end of the register file.
7474 if (insn
& (1 << 6)) {
7475 tmp
= neon_load_reg(rd
, 0);
7477 tmp
= tcg_temp_new_i32();
7478 tcg_gen_movi_i32(tmp
, 0);
7480 tmp2
= neon_load_reg(rm
, 0);
7481 tmp4
= tcg_const_i32(rn
);
7482 tmp5
= tcg_const_i32(n
);
7483 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7484 tcg_temp_free_i32(tmp
);
7485 if (insn
& (1 << 6)) {
7486 tmp
= neon_load_reg(rd
, 1);
7488 tmp
= tcg_temp_new_i32();
7489 tcg_gen_movi_i32(tmp
, 0);
7491 tmp3
= neon_load_reg(rm
, 1);
7492 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7493 tcg_temp_free_i32(tmp5
);
7494 tcg_temp_free_i32(tmp4
);
7495 neon_store_reg(rd
, 0, tmp2
);
7496 neon_store_reg(rd
, 1, tmp3
);
7497 tcg_temp_free_i32(tmp
);
7498 } else if ((insn
& 0x380) == 0) {
7500 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7503 if (insn
& (1 << 19)) {
7504 tmp
= neon_load_reg(rm
, 1);
7506 tmp
= neon_load_reg(rm
, 0);
7508 if (insn
& (1 << 16)) {
7509 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7510 } else if (insn
& (1 << 17)) {
7511 if ((insn
>> 18) & 1)
7512 gen_neon_dup_high16(tmp
);
7514 gen_neon_dup_low16(tmp
);
7516 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7517 tmp2
= tcg_temp_new_i32();
7518 tcg_gen_mov_i32(tmp2
, tmp
);
7519 neon_store_reg(rd
, pass
, tmp2
);
7521 tcg_temp_free_i32(tmp
);
7530 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7532 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7533 const ARMCPRegInfo
*ri
;
7535 cpnum
= (insn
>> 8) & 0xf;
7537 /* First check for coprocessor space used for XScale/iwMMXt insns */
7538 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7539 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7542 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7543 return disas_iwmmxt_insn(s
, insn
);
7544 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7545 return disas_dsp_insn(s
, insn
);
7550 /* Otherwise treat as a generic register access */
7551 is64
= (insn
& (1 << 25)) == 0;
7552 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7560 opc1
= (insn
>> 4) & 0xf;
7562 rt2
= (insn
>> 16) & 0xf;
7564 crn
= (insn
>> 16) & 0xf;
7565 opc1
= (insn
>> 21) & 7;
7566 opc2
= (insn
>> 5) & 7;
7569 isread
= (insn
>> 20) & 1;
7570 rt
= (insn
>> 12) & 0xf;
7572 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7573 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7575 /* Check access permissions */
7576 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7581 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7582 /* Emit code to perform further access permissions checks at
7583 * runtime; this may result in an exception.
7584 * Note that on XScale all cp0..c13 registers do an access check
7585 * call in order to handle c15_cpar.
7588 TCGv_i32 tcg_syn
, tcg_isread
;
7591 /* Note that since we are an implementation which takes an
7592 * exception on a trapped conditional instruction only if the
7593 * instruction passes its condition code check, we can take
7594 * advantage of the clause in the ARM ARM that allows us to set
7595 * the COND field in the instruction to 0xE in all cases.
7596 * We could fish the actual condition out of the insn (ARM)
7597 * or the condexec bits (Thumb) but it isn't necessary.
7602 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7605 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7611 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7614 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7619 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7620 * so this can only happen if this is an ARMv7 or earlier CPU,
7621 * in which case the syndrome information won't actually be
7624 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7625 syndrome
= syn_uncategorized();
7629 gen_set_condexec(s
);
7630 gen_set_pc_im(s
, s
->pc
- 4);
7631 tmpptr
= tcg_const_ptr(ri
);
7632 tcg_syn
= tcg_const_i32(syndrome
);
7633 tcg_isread
= tcg_const_i32(isread
);
7634 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7636 tcg_temp_free_ptr(tmpptr
);
7637 tcg_temp_free_i32(tcg_syn
);
7638 tcg_temp_free_i32(tcg_isread
);
7641 /* Handle special cases first */
7642 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7649 gen_set_pc_im(s
, s
->pc
);
7650 s
->is_jmp
= DISAS_WFI
;
7656 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7665 if (ri
->type
& ARM_CP_CONST
) {
7666 tmp64
= tcg_const_i64(ri
->resetvalue
);
7667 } else if (ri
->readfn
) {
7669 tmp64
= tcg_temp_new_i64();
7670 tmpptr
= tcg_const_ptr(ri
);
7671 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7672 tcg_temp_free_ptr(tmpptr
);
7674 tmp64
= tcg_temp_new_i64();
7675 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7677 tmp
= tcg_temp_new_i32();
7678 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7679 store_reg(s
, rt
, tmp
);
7680 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7681 tmp
= tcg_temp_new_i32();
7682 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7683 tcg_temp_free_i64(tmp64
);
7684 store_reg(s
, rt2
, tmp
);
7687 if (ri
->type
& ARM_CP_CONST
) {
7688 tmp
= tcg_const_i32(ri
->resetvalue
);
7689 } else if (ri
->readfn
) {
7691 tmp
= tcg_temp_new_i32();
7692 tmpptr
= tcg_const_ptr(ri
);
7693 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7694 tcg_temp_free_ptr(tmpptr
);
7696 tmp
= load_cpu_offset(ri
->fieldoffset
);
7699 /* Destination register of r15 for 32 bit loads sets
7700 * the condition codes from the high 4 bits of the value
7703 tcg_temp_free_i32(tmp
);
7705 store_reg(s
, rt
, tmp
);
7710 if (ri
->type
& ARM_CP_CONST
) {
7711 /* If not forbidden by access permissions, treat as WI */
7716 TCGv_i32 tmplo
, tmphi
;
7717 TCGv_i64 tmp64
= tcg_temp_new_i64();
7718 tmplo
= load_reg(s
, rt
);
7719 tmphi
= load_reg(s
, rt2
);
7720 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7721 tcg_temp_free_i32(tmplo
);
7722 tcg_temp_free_i32(tmphi
);
7724 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7725 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7726 tcg_temp_free_ptr(tmpptr
);
7728 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7730 tcg_temp_free_i64(tmp64
);
7735 tmp
= load_reg(s
, rt
);
7736 tmpptr
= tcg_const_ptr(ri
);
7737 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7738 tcg_temp_free_ptr(tmpptr
);
7739 tcg_temp_free_i32(tmp
);
7741 TCGv_i32 tmp
= load_reg(s
, rt
);
7742 store_cpu_offset(tmp
, ri
->fieldoffset
);
7747 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7748 /* I/O operations must end the TB here (whether read or write) */
7751 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7752 /* We default to ending the TB on a coprocessor register write,
7753 * but allow this to be suppressed by the register definition
7754 * (usually only necessary to work around guest bugs).
7762 /* Unknown register; this might be a guest error or a QEMU
7763 * unimplemented feature.
7766 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7767 "64 bit system register cp:%d opc1: %d crm:%d "
7769 isread
? "read" : "write", cpnum
, opc1
, crm
,
7770 s
->ns
? "non-secure" : "secure");
7772 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7773 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7775 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7776 s
->ns
? "non-secure" : "secure");
7783 /* Store a 64-bit value to a register pair. Clobbers val. */
7784 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7787 tmp
= tcg_temp_new_i32();
7788 tcg_gen_extrl_i64_i32(tmp
, val
);
7789 store_reg(s
, rlow
, tmp
);
7790 tmp
= tcg_temp_new_i32();
7791 tcg_gen_shri_i64(val
, val
, 32);
7792 tcg_gen_extrl_i64_i32(tmp
, val
);
7793 store_reg(s
, rhigh
, tmp
);
7796 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7797 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7802 /* Load value and extend to 64 bits. */
7803 tmp
= tcg_temp_new_i64();
7804 tmp2
= load_reg(s
, rlow
);
7805 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7806 tcg_temp_free_i32(tmp2
);
7807 tcg_gen_add_i64(val
, val
, tmp
);
7808 tcg_temp_free_i64(tmp
);
7811 /* load and add a 64-bit value from a register pair. */
7812 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7818 /* Load 64-bit value rd:rn. */
7819 tmpl
= load_reg(s
, rlow
);
7820 tmph
= load_reg(s
, rhigh
);
7821 tmp
= tcg_temp_new_i64();
7822 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7823 tcg_temp_free_i32(tmpl
);
7824 tcg_temp_free_i32(tmph
);
7825 tcg_gen_add_i64(val
, val
, tmp
);
7826 tcg_temp_free_i64(tmp
);
7829 /* Set N and Z flags from hi|lo. */
7830 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7832 tcg_gen_mov_i32(cpu_NF
, hi
);
7833 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7836 /* Load/Store exclusive instructions are implemented by remembering
7837 the value/address loaded, and seeing if these are the same
7838 when the store is performed. This should be sufficient to implement
7839 the architecturally mandated semantics, and avoids having to monitor
7840 regular stores. The compare vs the remembered value is done during
7841 the cmpxchg operation, but we must compare the addresses manually. */
7842 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7843 TCGv_i32 addr
, int size
)
7845 TCGv_i32 tmp
= tcg_temp_new_i32();
7846 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7851 TCGv_i32 tmp2
= tcg_temp_new_i32();
7852 TCGv_i64 t64
= tcg_temp_new_i64();
7854 gen_aa32_ld_i64(s
, t64
, addr
, get_mem_index(s
), opc
);
7855 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
7856 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
7857 tcg_temp_free_i64(t64
);
7859 store_reg(s
, rt2
, tmp2
);
7861 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
7862 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7865 store_reg(s
, rt
, tmp
);
7866 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7869 static void gen_clrex(DisasContext
*s
)
7871 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7874 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7875 TCGv_i32 addr
, int size
)
7877 TCGv_i32 t0
, t1
, t2
;
7880 TCGLabel
*done_label
;
7881 TCGLabel
*fail_label
;
7882 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7884 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7890 fail_label
= gen_new_label();
7891 done_label
= gen_new_label();
7892 extaddr
= tcg_temp_new_i64();
7893 tcg_gen_extu_i32_i64(extaddr
, addr
);
7894 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7895 tcg_temp_free_i64(extaddr
);
7897 taddr
= gen_aa32_addr(s
, addr
, opc
);
7898 t0
= tcg_temp_new_i32();
7899 t1
= load_reg(s
, rt
);
7901 TCGv_i64 o64
= tcg_temp_new_i64();
7902 TCGv_i64 n64
= tcg_temp_new_i64();
7904 t2
= load_reg(s
, rt2
);
7905 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
7906 tcg_temp_free_i32(t2
);
7907 gen_aa32_frob64(s
, n64
);
7909 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
7910 get_mem_index(s
), opc
);
7911 tcg_temp_free_i64(n64
);
7913 gen_aa32_frob64(s
, o64
);
7914 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
7915 tcg_gen_extrl_i64_i32(t0
, o64
);
7917 tcg_temp_free_i64(o64
);
7919 t2
= tcg_temp_new_i32();
7920 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
7921 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
7922 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
7923 tcg_temp_free_i32(t2
);
7925 tcg_temp_free_i32(t1
);
7926 tcg_temp_free(taddr
);
7927 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
7928 tcg_temp_free_i32(t0
);
7929 tcg_gen_br(done_label
);
7931 gen_set_label(fail_label
);
7932 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7933 gen_set_label(done_label
);
7934 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7940 * @mode: mode field from insn (which stack to store to)
7941 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7942 * @writeback: true if writeback bit set
7944 * Generate code for the SRS (Store Return State) insn.
7946 static void gen_srs(DisasContext
*s
,
7947 uint32_t mode
, uint32_t amode
, bool writeback
)
7954 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7955 * and specified mode is monitor mode
7956 * - UNDEFINED in Hyp mode
7957 * - UNPREDICTABLE in User or System mode
7958 * - UNPREDICTABLE if the specified mode is:
7959 * -- not implemented
7960 * -- not a valid mode number
7961 * -- a mode that's at a higher exception level
7962 * -- Monitor, if we are Non-secure
7963 * For the UNPREDICTABLE cases we choose to UNDEF.
7965 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7966 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7970 if (s
->current_el
== 0 || s
->current_el
== 2) {
7975 case ARM_CPU_MODE_USR
:
7976 case ARM_CPU_MODE_FIQ
:
7977 case ARM_CPU_MODE_IRQ
:
7978 case ARM_CPU_MODE_SVC
:
7979 case ARM_CPU_MODE_ABT
:
7980 case ARM_CPU_MODE_UND
:
7981 case ARM_CPU_MODE_SYS
:
7983 case ARM_CPU_MODE_HYP
:
7984 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7988 case ARM_CPU_MODE_MON
:
7989 /* No need to check specifically for "are we non-secure" because
7990 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7991 * so if this isn't EL3 then we must be non-secure.
7993 if (s
->current_el
!= 3) {
8002 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8003 default_exception_el(s
));
8007 addr
= tcg_temp_new_i32();
8008 tmp
= tcg_const_i32(mode
);
8009 /* get_r13_banked() will raise an exception if called from System mode */
8010 gen_set_condexec(s
);
8011 gen_set_pc_im(s
, s
->pc
- 4);
8012 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8013 tcg_temp_free_i32(tmp
);
8030 tcg_gen_addi_i32(addr
, addr
, offset
);
8031 tmp
= load_reg(s
, 14);
8032 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8033 tcg_temp_free_i32(tmp
);
8034 tmp
= load_cpu_field(spsr
);
8035 tcg_gen_addi_i32(addr
, addr
, 4);
8036 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8037 tcg_temp_free_i32(tmp
);
8055 tcg_gen_addi_i32(addr
, addr
, offset
);
8056 tmp
= tcg_const_i32(mode
);
8057 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8058 tcg_temp_free_i32(tmp
);
8060 tcg_temp_free_i32(addr
);
8061 s
->is_jmp
= DISAS_UPDATE
;
8064 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8066 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8073 /* M variants do not implement ARM mode; this must raise the INVSTATE
8074 * UsageFault exception.
8076 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8077 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8078 default_exception_el(s
));
8083 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8084 * choose to UNDEF. In ARMv5 and above the space is used
8085 * for miscellaneous unconditional instructions.
8089 /* Unconditional instructions. */
8090 if (((insn
>> 25) & 7) == 1) {
8091 /* NEON Data processing. */
8092 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8096 if (disas_neon_data_insn(s
, insn
)) {
8101 if ((insn
& 0x0f100000) == 0x04000000) {
8102 /* NEON load/store. */
8103 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8107 if (disas_neon_ls_insn(s
, insn
)) {
8112 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8114 if (disas_vfp_insn(s
, insn
)) {
8119 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8120 ((insn
& 0x0f30f010) == 0x0710f000)) {
8121 if ((insn
& (1 << 22)) == 0) {
8123 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8127 /* Otherwise PLD; v5TE+ */
8131 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8132 ((insn
& 0x0f70f010) == 0x0650f000)) {
8134 return; /* PLI; V7 */
8136 if (((insn
& 0x0f700000) == 0x04100000) ||
8137 ((insn
& 0x0f700010) == 0x06100000)) {
8138 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8141 return; /* v7MP: Unallocated memory hint: must NOP */
8144 if ((insn
& 0x0ffffdff) == 0x01010000) {
8147 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8148 gen_helper_setend(cpu_env
);
8149 s
->is_jmp
= DISAS_UPDATE
;
8152 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8153 switch ((insn
>> 4) & 0xf) {
8161 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8164 /* We need to break the TB after this insn to execute
8165 * self-modifying code correctly and also to take
8166 * any pending interrupts immediately.
8173 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8176 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8178 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8184 rn
= (insn
>> 16) & 0xf;
8185 addr
= load_reg(s
, rn
);
8186 i
= (insn
>> 23) & 3;
8188 case 0: offset
= -4; break; /* DA */
8189 case 1: offset
= 0; break; /* IA */
8190 case 2: offset
= -8; break; /* DB */
8191 case 3: offset
= 4; break; /* IB */
8195 tcg_gen_addi_i32(addr
, addr
, offset
);
8196 /* Load PC into tmp and CPSR into tmp2. */
8197 tmp
= tcg_temp_new_i32();
8198 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8199 tcg_gen_addi_i32(addr
, addr
, 4);
8200 tmp2
= tcg_temp_new_i32();
8201 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8202 if (insn
& (1 << 21)) {
8203 /* Base writeback. */
8205 case 0: offset
= -8; break;
8206 case 1: offset
= 4; break;
8207 case 2: offset
= -4; break;
8208 case 3: offset
= 0; break;
8212 tcg_gen_addi_i32(addr
, addr
, offset
);
8213 store_reg(s
, rn
, addr
);
8215 tcg_temp_free_i32(addr
);
8217 gen_rfe(s
, tmp
, tmp2
);
8219 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8220 /* branch link and change to thumb (blx <offset>) */
8223 val
= (uint32_t)s
->pc
;
8224 tmp
= tcg_temp_new_i32();
8225 tcg_gen_movi_i32(tmp
, val
);
8226 store_reg(s
, 14, tmp
);
8227 /* Sign-extend the 24-bit offset */
8228 offset
= (((int32_t)insn
) << 8) >> 8;
8229 /* offset * 4 + bit24 * 2 + (thumb bit) */
8230 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8231 /* pipeline offset */
8233 /* protected by ARCH(5); above, near the start of uncond block */
8236 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8237 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8238 /* iWMMXt register transfer. */
8239 if (extract32(s
->c15_cpar
, 1, 1)) {
8240 if (!disas_iwmmxt_insn(s
, insn
)) {
8245 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8246 /* Coprocessor double register transfer. */
8248 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8249 /* Additional coprocessor register transfer. */
8250 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8253 /* cps (privileged) */
8257 if (insn
& (1 << 19)) {
8258 if (insn
& (1 << 8))
8260 if (insn
& (1 << 7))
8262 if (insn
& (1 << 6))
8264 if (insn
& (1 << 18))
8267 if (insn
& (1 << 17)) {
8269 val
|= (insn
& 0x1f);
8272 gen_set_psr_im(s
, mask
, 0, val
);
8279 /* if not always execute, we generate a conditional jump to
8281 s
->condlabel
= gen_new_label();
8282 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8285 if ((insn
& 0x0f900000) == 0x03000000) {
8286 if ((insn
& (1 << 21)) == 0) {
8288 rd
= (insn
>> 12) & 0xf;
8289 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8290 if ((insn
& (1 << 22)) == 0) {
8292 tmp
= tcg_temp_new_i32();
8293 tcg_gen_movi_i32(tmp
, val
);
8296 tmp
= load_reg(s
, rd
);
8297 tcg_gen_ext16u_i32(tmp
, tmp
);
8298 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8300 store_reg(s
, rd
, tmp
);
8302 if (((insn
>> 12) & 0xf) != 0xf)
8304 if (((insn
>> 16) & 0xf) == 0) {
8305 gen_nop_hint(s
, insn
& 0xff);
8307 /* CPSR = immediate */
8309 shift
= ((insn
>> 8) & 0xf) * 2;
8311 val
= (val
>> shift
) | (val
<< (32 - shift
));
8312 i
= ((insn
& (1 << 22)) != 0);
8313 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8319 } else if ((insn
& 0x0f900000) == 0x01000000
8320 && (insn
& 0x00000090) != 0x00000090) {
8321 /* miscellaneous instructions */
8322 op1
= (insn
>> 21) & 3;
8323 sh
= (insn
>> 4) & 0xf;
8326 case 0x0: /* MSR, MRS */
8327 if (insn
& (1 << 9)) {
8328 /* MSR (banked) and MRS (banked) */
8329 int sysm
= extract32(insn
, 16, 4) |
8330 (extract32(insn
, 8, 1) << 4);
8331 int r
= extract32(insn
, 22, 1);
8335 gen_msr_banked(s
, r
, sysm
, rm
);
8338 int rd
= extract32(insn
, 12, 4);
8340 gen_mrs_banked(s
, r
, sysm
, rd
);
8345 /* MSR, MRS (for PSRs) */
8348 tmp
= load_reg(s
, rm
);
8349 i
= ((op1
& 2) != 0);
8350 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8354 rd
= (insn
>> 12) & 0xf;
8358 tmp
= load_cpu_field(spsr
);
8360 tmp
= tcg_temp_new_i32();
8361 gen_helper_cpsr_read(tmp
, cpu_env
);
8363 store_reg(s
, rd
, tmp
);
8368 /* branch/exchange thumb (bx). */
8370 tmp
= load_reg(s
, rm
);
8372 } else if (op1
== 3) {
8375 rd
= (insn
>> 12) & 0xf;
8376 tmp
= load_reg(s
, rm
);
8377 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8378 store_reg(s
, rd
, tmp
);
8386 /* Trivial implementation equivalent to bx. */
8387 tmp
= load_reg(s
, rm
);
8398 /* branch link/exchange thumb (blx) */
8399 tmp
= load_reg(s
, rm
);
8400 tmp2
= tcg_temp_new_i32();
8401 tcg_gen_movi_i32(tmp2
, s
->pc
);
8402 store_reg(s
, 14, tmp2
);
8408 uint32_t c
= extract32(insn
, 8, 4);
8410 /* Check this CPU supports ARMv8 CRC instructions.
8411 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8412 * Bits 8, 10 and 11 should be zero.
8414 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8419 rn
= extract32(insn
, 16, 4);
8420 rd
= extract32(insn
, 12, 4);
8422 tmp
= load_reg(s
, rn
);
8423 tmp2
= load_reg(s
, rm
);
8425 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8426 } else if (op1
== 1) {
8427 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8429 tmp3
= tcg_const_i32(1 << op1
);
8431 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8433 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8435 tcg_temp_free_i32(tmp2
);
8436 tcg_temp_free_i32(tmp3
);
8437 store_reg(s
, rd
, tmp
);
8440 case 0x5: /* saturating add/subtract */
8442 rd
= (insn
>> 12) & 0xf;
8443 rn
= (insn
>> 16) & 0xf;
8444 tmp
= load_reg(s
, rm
);
8445 tmp2
= load_reg(s
, rn
);
8447 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8449 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8451 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8452 tcg_temp_free_i32(tmp2
);
8453 store_reg(s
, rd
, tmp
);
8457 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8466 gen_exception_insn(s
, 4, EXCP_BKPT
,
8467 syn_aa32_bkpt(imm16
, false),
8468 default_exception_el(s
));
8471 /* Hypervisor call (v7) */
8479 /* Secure monitor call (v6+) */
8487 g_assert_not_reached();
8491 case 0x8: /* signed multiply */
8496 rs
= (insn
>> 8) & 0xf;
8497 rn
= (insn
>> 12) & 0xf;
8498 rd
= (insn
>> 16) & 0xf;
8500 /* (32 * 16) >> 16 */
8501 tmp
= load_reg(s
, rm
);
8502 tmp2
= load_reg(s
, rs
);
8504 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8507 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8508 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8509 tmp
= tcg_temp_new_i32();
8510 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8511 tcg_temp_free_i64(tmp64
);
8512 if ((sh
& 2) == 0) {
8513 tmp2
= load_reg(s
, rn
);
8514 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8515 tcg_temp_free_i32(tmp2
);
8517 store_reg(s
, rd
, tmp
);
8520 tmp
= load_reg(s
, rm
);
8521 tmp2
= load_reg(s
, rs
);
8522 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8523 tcg_temp_free_i32(tmp2
);
8525 tmp64
= tcg_temp_new_i64();
8526 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8527 tcg_temp_free_i32(tmp
);
8528 gen_addq(s
, tmp64
, rn
, rd
);
8529 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8530 tcg_temp_free_i64(tmp64
);
8533 tmp2
= load_reg(s
, rn
);
8534 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8535 tcg_temp_free_i32(tmp2
);
8537 store_reg(s
, rd
, tmp
);
8544 } else if (((insn
& 0x0e000000) == 0 &&
8545 (insn
& 0x00000090) != 0x90) ||
8546 ((insn
& 0x0e000000) == (1 << 25))) {
8547 int set_cc
, logic_cc
, shiftop
;
8549 op1
= (insn
>> 21) & 0xf;
8550 set_cc
= (insn
>> 20) & 1;
8551 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8553 /* data processing instruction */
8554 if (insn
& (1 << 25)) {
8555 /* immediate operand */
8557 shift
= ((insn
>> 8) & 0xf) * 2;
8559 val
= (val
>> shift
) | (val
<< (32 - shift
));
8561 tmp2
= tcg_temp_new_i32();
8562 tcg_gen_movi_i32(tmp2
, val
);
8563 if (logic_cc
&& shift
) {
8564 gen_set_CF_bit31(tmp2
);
8569 tmp2
= load_reg(s
, rm
);
8570 shiftop
= (insn
>> 5) & 3;
8571 if (!(insn
& (1 << 4))) {
8572 shift
= (insn
>> 7) & 0x1f;
8573 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8575 rs
= (insn
>> 8) & 0xf;
8576 tmp
= load_reg(s
, rs
);
8577 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8580 if (op1
!= 0x0f && op1
!= 0x0d) {
8581 rn
= (insn
>> 16) & 0xf;
8582 tmp
= load_reg(s
, rn
);
8584 TCGV_UNUSED_I32(tmp
);
8586 rd
= (insn
>> 12) & 0xf;
8589 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8593 store_reg_bx(s
, rd
, tmp
);
8596 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8600 store_reg_bx(s
, rd
, tmp
);
8603 if (set_cc
&& rd
== 15) {
8604 /* SUBS r15, ... is used for exception return. */
8608 gen_sub_CC(tmp
, tmp
, tmp2
);
8609 gen_exception_return(s
, tmp
);
8612 gen_sub_CC(tmp
, tmp
, tmp2
);
8614 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8616 store_reg_bx(s
, rd
, tmp
);
8621 gen_sub_CC(tmp
, tmp2
, tmp
);
8623 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8625 store_reg_bx(s
, rd
, tmp
);
8629 gen_add_CC(tmp
, tmp
, tmp2
);
8631 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8633 store_reg_bx(s
, rd
, tmp
);
8637 gen_adc_CC(tmp
, tmp
, tmp2
);
8639 gen_add_carry(tmp
, tmp
, tmp2
);
8641 store_reg_bx(s
, rd
, tmp
);
8645 gen_sbc_CC(tmp
, tmp
, tmp2
);
8647 gen_sub_carry(tmp
, tmp
, tmp2
);
8649 store_reg_bx(s
, rd
, tmp
);
8653 gen_sbc_CC(tmp
, tmp2
, tmp
);
8655 gen_sub_carry(tmp
, tmp2
, tmp
);
8657 store_reg_bx(s
, rd
, tmp
);
8661 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8664 tcg_temp_free_i32(tmp
);
8668 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8671 tcg_temp_free_i32(tmp
);
8675 gen_sub_CC(tmp
, tmp
, tmp2
);
8677 tcg_temp_free_i32(tmp
);
8681 gen_add_CC(tmp
, tmp
, tmp2
);
8683 tcg_temp_free_i32(tmp
);
8686 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8690 store_reg_bx(s
, rd
, tmp
);
8693 if (logic_cc
&& rd
== 15) {
8694 /* MOVS r15, ... is used for exception return. */
8698 gen_exception_return(s
, tmp2
);
8703 store_reg_bx(s
, rd
, tmp2
);
8707 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8711 store_reg_bx(s
, rd
, tmp
);
8715 tcg_gen_not_i32(tmp2
, tmp2
);
8719 store_reg_bx(s
, rd
, tmp2
);
8722 if (op1
!= 0x0f && op1
!= 0x0d) {
8723 tcg_temp_free_i32(tmp2
);
8726 /* other instructions */
8727 op1
= (insn
>> 24) & 0xf;
8731 /* multiplies, extra load/stores */
8732 sh
= (insn
>> 5) & 3;
8735 rd
= (insn
>> 16) & 0xf;
8736 rn
= (insn
>> 12) & 0xf;
8737 rs
= (insn
>> 8) & 0xf;
8739 op1
= (insn
>> 20) & 0xf;
8741 case 0: case 1: case 2: case 3: case 6:
8743 tmp
= load_reg(s
, rs
);
8744 tmp2
= load_reg(s
, rm
);
8745 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8746 tcg_temp_free_i32(tmp2
);
8747 if (insn
& (1 << 22)) {
8748 /* Subtract (mls) */
8750 tmp2
= load_reg(s
, rn
);
8751 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8752 tcg_temp_free_i32(tmp2
);
8753 } else if (insn
& (1 << 21)) {
8755 tmp2
= load_reg(s
, rn
);
8756 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8757 tcg_temp_free_i32(tmp2
);
8759 if (insn
& (1 << 20))
8761 store_reg(s
, rd
, tmp
);
8764 /* 64 bit mul double accumulate (UMAAL) */
8766 tmp
= load_reg(s
, rs
);
8767 tmp2
= load_reg(s
, rm
);
8768 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8769 gen_addq_lo(s
, tmp64
, rn
);
8770 gen_addq_lo(s
, tmp64
, rd
);
8771 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8772 tcg_temp_free_i64(tmp64
);
8774 case 8: case 9: case 10: case 11:
8775 case 12: case 13: case 14: case 15:
8776 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8777 tmp
= load_reg(s
, rs
);
8778 tmp2
= load_reg(s
, rm
);
8779 if (insn
& (1 << 22)) {
8780 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8782 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8784 if (insn
& (1 << 21)) { /* mult accumulate */
8785 TCGv_i32 al
= load_reg(s
, rn
);
8786 TCGv_i32 ah
= load_reg(s
, rd
);
8787 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8788 tcg_temp_free_i32(al
);
8789 tcg_temp_free_i32(ah
);
8791 if (insn
& (1 << 20)) {
8792 gen_logicq_cc(tmp
, tmp2
);
8794 store_reg(s
, rn
, tmp
);
8795 store_reg(s
, rd
, tmp2
);
8801 rn
= (insn
>> 16) & 0xf;
8802 rd
= (insn
>> 12) & 0xf;
8803 if (insn
& (1 << 23)) {
8804 /* load/store exclusive */
8805 int op2
= (insn
>> 8) & 3;
8806 op1
= (insn
>> 21) & 0x3;
8809 case 0: /* lda/stl */
8815 case 1: /* reserved */
8817 case 2: /* ldaex/stlex */
8820 case 3: /* ldrex/strex */
8829 addr
= tcg_temp_local_new_i32();
8830 load_reg_var(s
, addr
, rn
);
8832 /* Since the emulation does not have barriers,
8833 the acquire/release semantics need no special
8836 if (insn
& (1 << 20)) {
8837 tmp
= tcg_temp_new_i32();
8840 gen_aa32_ld32u_iss(s
, tmp
, addr
,
8845 gen_aa32_ld8u_iss(s
, tmp
, addr
,
8850 gen_aa32_ld16u_iss(s
, tmp
, addr
,
8857 store_reg(s
, rd
, tmp
);
8860 tmp
= load_reg(s
, rm
);
8863 gen_aa32_st32_iss(s
, tmp
, addr
,
8868 gen_aa32_st8_iss(s
, tmp
, addr
,
8873 gen_aa32_st16_iss(s
, tmp
, addr
,
8880 tcg_temp_free_i32(tmp
);
8882 } else if (insn
& (1 << 20)) {
8885 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8887 case 1: /* ldrexd */
8888 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8890 case 2: /* ldrexb */
8891 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8893 case 3: /* ldrexh */
8894 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8903 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8905 case 1: /* strexd */
8906 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8908 case 2: /* strexb */
8909 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8911 case 3: /* strexh */
8912 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8918 tcg_temp_free_i32(addr
);
8921 TCGMemOp opc
= s
->be_data
;
8923 /* SWP instruction */
8926 if (insn
& (1 << 22)) {
8929 opc
|= MO_UL
| MO_ALIGN
;
8932 addr
= load_reg(s
, rn
);
8933 taddr
= gen_aa32_addr(s
, addr
, opc
);
8934 tcg_temp_free_i32(addr
);
8936 tmp
= load_reg(s
, rm
);
8937 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
8938 get_mem_index(s
), opc
);
8939 tcg_temp_free(taddr
);
8940 store_reg(s
, rd
, tmp
);
8945 bool load
= insn
& (1 << 20);
8946 bool wbit
= insn
& (1 << 21);
8947 bool pbit
= insn
& (1 << 24);
8948 bool doubleword
= false;
8951 /* Misc load/store */
8952 rn
= (insn
>> 16) & 0xf;
8953 rd
= (insn
>> 12) & 0xf;
8955 /* ISS not valid if writeback */
8956 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
8958 if (!load
&& (sh
& 2)) {
8962 /* UNPREDICTABLE; we choose to UNDEF */
8965 load
= (sh
& 1) == 0;
8969 addr
= load_reg(s
, rn
);
8971 gen_add_datah_offset(s
, insn
, 0, addr
);
8978 tmp
= load_reg(s
, rd
);
8979 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8980 tcg_temp_free_i32(tmp
);
8981 tcg_gen_addi_i32(addr
, addr
, 4);
8982 tmp
= load_reg(s
, rd
+ 1);
8983 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8984 tcg_temp_free_i32(tmp
);
8987 tmp
= tcg_temp_new_i32();
8988 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8989 store_reg(s
, rd
, tmp
);
8990 tcg_gen_addi_i32(addr
, addr
, 4);
8991 tmp
= tcg_temp_new_i32();
8992 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8995 address_offset
= -4;
8998 tmp
= tcg_temp_new_i32();
9001 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9005 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9010 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9016 tmp
= load_reg(s
, rd
);
9017 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9018 tcg_temp_free_i32(tmp
);
9020 /* Perform base writeback before the loaded value to
9021 ensure correct behavior with overlapping index registers.
9022 ldrd with base writeback is undefined if the
9023 destination and index registers overlap. */
9025 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9026 store_reg(s
, rn
, addr
);
9029 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9030 store_reg(s
, rn
, addr
);
9032 tcg_temp_free_i32(addr
);
9035 /* Complete the load. */
9036 store_reg(s
, rd
, tmp
);
9045 if (insn
& (1 << 4)) {
9047 /* Armv6 Media instructions. */
9049 rn
= (insn
>> 16) & 0xf;
9050 rd
= (insn
>> 12) & 0xf;
9051 rs
= (insn
>> 8) & 0xf;
9052 switch ((insn
>> 23) & 3) {
9053 case 0: /* Parallel add/subtract. */
9054 op1
= (insn
>> 20) & 7;
9055 tmp
= load_reg(s
, rn
);
9056 tmp2
= load_reg(s
, rm
);
9057 sh
= (insn
>> 5) & 7;
9058 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9060 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9061 tcg_temp_free_i32(tmp2
);
9062 store_reg(s
, rd
, tmp
);
9065 if ((insn
& 0x00700020) == 0) {
9066 /* Halfword pack. */
9067 tmp
= load_reg(s
, rn
);
9068 tmp2
= load_reg(s
, rm
);
9069 shift
= (insn
>> 7) & 0x1f;
9070 if (insn
& (1 << 6)) {
9074 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9075 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9076 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9080 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9081 tcg_gen_ext16u_i32(tmp
, tmp
);
9082 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9084 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9085 tcg_temp_free_i32(tmp2
);
9086 store_reg(s
, rd
, tmp
);
9087 } else if ((insn
& 0x00200020) == 0x00200000) {
9089 tmp
= load_reg(s
, rm
);
9090 shift
= (insn
>> 7) & 0x1f;
9091 if (insn
& (1 << 6)) {
9094 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9096 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9098 sh
= (insn
>> 16) & 0x1f;
9099 tmp2
= tcg_const_i32(sh
);
9100 if (insn
& (1 << 22))
9101 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9103 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9104 tcg_temp_free_i32(tmp2
);
9105 store_reg(s
, rd
, tmp
);
9106 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9108 tmp
= load_reg(s
, rm
);
9109 sh
= (insn
>> 16) & 0x1f;
9110 tmp2
= tcg_const_i32(sh
);
9111 if (insn
& (1 << 22))
9112 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9114 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9115 tcg_temp_free_i32(tmp2
);
9116 store_reg(s
, rd
, tmp
);
9117 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9119 tmp
= load_reg(s
, rn
);
9120 tmp2
= load_reg(s
, rm
);
9121 tmp3
= tcg_temp_new_i32();
9122 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9123 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9124 tcg_temp_free_i32(tmp3
);
9125 tcg_temp_free_i32(tmp2
);
9126 store_reg(s
, rd
, tmp
);
9127 } else if ((insn
& 0x000003e0) == 0x00000060) {
9128 tmp
= load_reg(s
, rm
);
9129 shift
= (insn
>> 10) & 3;
9130 /* ??? In many cases it's not necessary to do a
9131 rotate, a shift is sufficient. */
9133 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9134 op1
= (insn
>> 20) & 7;
9136 case 0: gen_sxtb16(tmp
); break;
9137 case 2: gen_sxtb(tmp
); break;
9138 case 3: gen_sxth(tmp
); break;
9139 case 4: gen_uxtb16(tmp
); break;
9140 case 6: gen_uxtb(tmp
); break;
9141 case 7: gen_uxth(tmp
); break;
9142 default: goto illegal_op
;
9145 tmp2
= load_reg(s
, rn
);
9146 if ((op1
& 3) == 0) {
9147 gen_add16(tmp
, tmp2
);
9149 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9150 tcg_temp_free_i32(tmp2
);
9153 store_reg(s
, rd
, tmp
);
9154 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9156 tmp
= load_reg(s
, rm
);
9157 if (insn
& (1 << 22)) {
9158 if (insn
& (1 << 7)) {
9162 gen_helper_rbit(tmp
, tmp
);
9165 if (insn
& (1 << 7))
9168 tcg_gen_bswap32_i32(tmp
, tmp
);
9170 store_reg(s
, rd
, tmp
);
9175 case 2: /* Multiplies (Type 3). */
9176 switch ((insn
>> 20) & 0x7) {
9178 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9179 /* op2 not 00x or 11x : UNDEF */
9182 /* Signed multiply most significant [accumulate].
9183 (SMMUL, SMMLA, SMMLS) */
9184 tmp
= load_reg(s
, rm
);
9185 tmp2
= load_reg(s
, rs
);
9186 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9189 tmp
= load_reg(s
, rd
);
9190 if (insn
& (1 << 6)) {
9191 tmp64
= gen_subq_msw(tmp64
, tmp
);
9193 tmp64
= gen_addq_msw(tmp64
, tmp
);
9196 if (insn
& (1 << 5)) {
9197 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9199 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9200 tmp
= tcg_temp_new_i32();
9201 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9202 tcg_temp_free_i64(tmp64
);
9203 store_reg(s
, rn
, tmp
);
9207 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9208 if (insn
& (1 << 7)) {
9211 tmp
= load_reg(s
, rm
);
9212 tmp2
= load_reg(s
, rs
);
9213 if (insn
& (1 << 5))
9214 gen_swap_half(tmp2
);
9215 gen_smul_dual(tmp
, tmp2
);
9216 if (insn
& (1 << 22)) {
9217 /* smlald, smlsld */
9220 tmp64
= tcg_temp_new_i64();
9221 tmp64_2
= tcg_temp_new_i64();
9222 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9223 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9224 tcg_temp_free_i32(tmp
);
9225 tcg_temp_free_i32(tmp2
);
9226 if (insn
& (1 << 6)) {
9227 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9229 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9231 tcg_temp_free_i64(tmp64_2
);
9232 gen_addq(s
, tmp64
, rd
, rn
);
9233 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9234 tcg_temp_free_i64(tmp64
);
9236 /* smuad, smusd, smlad, smlsd */
9237 if (insn
& (1 << 6)) {
9238 /* This subtraction cannot overflow. */
9239 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9241 /* This addition cannot overflow 32 bits;
9242 * however it may overflow considered as a
9243 * signed operation, in which case we must set
9246 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9248 tcg_temp_free_i32(tmp2
);
9251 tmp2
= load_reg(s
, rd
);
9252 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9253 tcg_temp_free_i32(tmp2
);
9255 store_reg(s
, rn
, tmp
);
9261 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9264 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9267 tmp
= load_reg(s
, rm
);
9268 tmp2
= load_reg(s
, rs
);
9269 if (insn
& (1 << 21)) {
9270 gen_helper_udiv(tmp
, tmp
, tmp2
);
9272 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9274 tcg_temp_free_i32(tmp2
);
9275 store_reg(s
, rn
, tmp
);
9282 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9284 case 0: /* Unsigned sum of absolute differences. */
9286 tmp
= load_reg(s
, rm
);
9287 tmp2
= load_reg(s
, rs
);
9288 gen_helper_usad8(tmp
, tmp
, tmp2
);
9289 tcg_temp_free_i32(tmp2
);
9291 tmp2
= load_reg(s
, rd
);
9292 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9293 tcg_temp_free_i32(tmp2
);
9295 store_reg(s
, rn
, tmp
);
9297 case 0x20: case 0x24: case 0x28: case 0x2c:
9298 /* Bitfield insert/clear. */
9300 shift
= (insn
>> 7) & 0x1f;
9301 i
= (insn
>> 16) & 0x1f;
9303 /* UNPREDICTABLE; we choose to UNDEF */
9308 tmp
= tcg_temp_new_i32();
9309 tcg_gen_movi_i32(tmp
, 0);
9311 tmp
= load_reg(s
, rm
);
9314 tmp2
= load_reg(s
, rd
);
9315 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9316 tcg_temp_free_i32(tmp2
);
9318 store_reg(s
, rd
, tmp
);
9320 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9321 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9323 tmp
= load_reg(s
, rm
);
9324 shift
= (insn
>> 7) & 0x1f;
9325 i
= ((insn
>> 16) & 0x1f) + 1;
9330 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9332 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9335 store_reg(s
, rd
, tmp
);
9345 /* Check for undefined extension instructions
9346 * per the ARM Bible IE:
9347 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9349 sh
= (0xf << 20) | (0xf << 4);
9350 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9354 /* load/store byte/word */
9355 rn
= (insn
>> 16) & 0xf;
9356 rd
= (insn
>> 12) & 0xf;
9357 tmp2
= load_reg(s
, rn
);
9358 if ((insn
& 0x01200000) == 0x00200000) {
9360 i
= get_a32_user_mem_index(s
);
9362 i
= get_mem_index(s
);
9364 if (insn
& (1 << 24))
9365 gen_add_data_offset(s
, insn
, tmp2
);
9366 if (insn
& (1 << 20)) {
9368 tmp
= tcg_temp_new_i32();
9369 if (insn
& (1 << 22)) {
9370 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9372 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9376 tmp
= load_reg(s
, rd
);
9377 if (insn
& (1 << 22)) {
9378 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9380 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9382 tcg_temp_free_i32(tmp
);
9384 if (!(insn
& (1 << 24))) {
9385 gen_add_data_offset(s
, insn
, tmp2
);
9386 store_reg(s
, rn
, tmp2
);
9387 } else if (insn
& (1 << 21)) {
9388 store_reg(s
, rn
, tmp2
);
9390 tcg_temp_free_i32(tmp2
);
9392 if (insn
& (1 << 20)) {
9393 /* Complete the load. */
9394 store_reg_from_load(s
, rd
, tmp
);
9400 int j
, n
, loaded_base
;
9401 bool exc_return
= false;
9402 bool is_load
= extract32(insn
, 20, 1);
9404 TCGv_i32 loaded_var
;
9405 /* load/store multiple words */
9406 /* XXX: store correct base if write back */
9407 if (insn
& (1 << 22)) {
9408 /* LDM (user), LDM (exception return) and STM (user) */
9410 goto illegal_op
; /* only usable in supervisor mode */
9412 if (is_load
&& extract32(insn
, 15, 1)) {
9418 rn
= (insn
>> 16) & 0xf;
9419 addr
= load_reg(s
, rn
);
9421 /* compute total size */
9423 TCGV_UNUSED_I32(loaded_var
);
9426 if (insn
& (1 << i
))
9429 /* XXX: test invalid n == 0 case ? */
9430 if (insn
& (1 << 23)) {
9431 if (insn
& (1 << 24)) {
9433 tcg_gen_addi_i32(addr
, addr
, 4);
9435 /* post increment */
9438 if (insn
& (1 << 24)) {
9440 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9442 /* post decrement */
9444 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9449 if (insn
& (1 << i
)) {
9452 tmp
= tcg_temp_new_i32();
9453 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9455 tmp2
= tcg_const_i32(i
);
9456 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9457 tcg_temp_free_i32(tmp2
);
9458 tcg_temp_free_i32(tmp
);
9459 } else if (i
== rn
) {
9462 } else if (rn
== 15 && exc_return
) {
9463 store_pc_exc_ret(s
, tmp
);
9465 store_reg_from_load(s
, i
, tmp
);
9470 /* special case: r15 = PC + 8 */
9471 val
= (long)s
->pc
+ 4;
9472 tmp
= tcg_temp_new_i32();
9473 tcg_gen_movi_i32(tmp
, val
);
9475 tmp
= tcg_temp_new_i32();
9476 tmp2
= tcg_const_i32(i
);
9477 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9478 tcg_temp_free_i32(tmp2
);
9480 tmp
= load_reg(s
, i
);
9482 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9483 tcg_temp_free_i32(tmp
);
9486 /* no need to add after the last transfer */
9488 tcg_gen_addi_i32(addr
, addr
, 4);
9491 if (insn
& (1 << 21)) {
9493 if (insn
& (1 << 23)) {
9494 if (insn
& (1 << 24)) {
9497 /* post increment */
9498 tcg_gen_addi_i32(addr
, addr
, 4);
9501 if (insn
& (1 << 24)) {
9504 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9506 /* post decrement */
9507 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9510 store_reg(s
, rn
, addr
);
9512 tcg_temp_free_i32(addr
);
9515 store_reg(s
, rn
, loaded_var
);
9518 /* Restore CPSR from SPSR. */
9519 tmp
= load_cpu_field(spsr
);
9520 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9521 tcg_temp_free_i32(tmp
);
9522 s
->is_jmp
= DISAS_JUMP
;
9531 /* branch (and link) */
9532 val
= (int32_t)s
->pc
;
9533 if (insn
& (1 << 24)) {
9534 tmp
= tcg_temp_new_i32();
9535 tcg_gen_movi_i32(tmp
, val
);
9536 store_reg(s
, 14, tmp
);
9538 offset
= sextract32(insn
<< 2, 0, 26);
9546 if (((insn
>> 8) & 0xe) == 10) {
9548 if (disas_vfp_insn(s
, insn
)) {
9551 } else if (disas_coproc_insn(s
, insn
)) {
9558 gen_set_pc_im(s
, s
->pc
);
9559 s
->svc_imm
= extract32(insn
, 0, 24);
9560 s
->is_jmp
= DISAS_SWI
;
9564 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9565 default_exception_el(s
));
9571 /* Return true if this is a Thumb-2 logical op. */
9573 thumb2_logic_op(int op
)
9578 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9579 then set condition code flags based on the result of the operation.
9580 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9581 to the high bit of T1.
9582 Returns zero if the opcode is valid. */
9585 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9586 TCGv_i32 t0
, TCGv_i32 t1
)
9593 tcg_gen_and_i32(t0
, t0
, t1
);
9597 tcg_gen_andc_i32(t0
, t0
, t1
);
9601 tcg_gen_or_i32(t0
, t0
, t1
);
9605 tcg_gen_orc_i32(t0
, t0
, t1
);
9609 tcg_gen_xor_i32(t0
, t0
, t1
);
9614 gen_add_CC(t0
, t0
, t1
);
9616 tcg_gen_add_i32(t0
, t0
, t1
);
9620 gen_adc_CC(t0
, t0
, t1
);
9626 gen_sbc_CC(t0
, t0
, t1
);
9628 gen_sub_carry(t0
, t0
, t1
);
9633 gen_sub_CC(t0
, t0
, t1
);
9635 tcg_gen_sub_i32(t0
, t0
, t1
);
9639 gen_sub_CC(t0
, t1
, t0
);
9641 tcg_gen_sub_i32(t0
, t1
, t0
);
9643 default: /* 5, 6, 7, 9, 12, 15. */
9649 gen_set_CF_bit31(t1
);
9654 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9656 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9658 uint32_t insn
, imm
, shift
, offset
;
9659 uint32_t rd
, rn
, rm
, rs
;
9670 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9671 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9672 /* Thumb-1 cores may need to treat bl and blx as a pair of
9673 16-bit instructions to get correct prefetch abort behavior. */
9675 if ((insn
& (1 << 12)) == 0) {
9677 /* Second half of blx. */
9678 offset
= ((insn
& 0x7ff) << 1);
9679 tmp
= load_reg(s
, 14);
9680 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9681 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9683 tmp2
= tcg_temp_new_i32();
9684 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9685 store_reg(s
, 14, tmp2
);
9689 if (insn
& (1 << 11)) {
9690 /* Second half of bl. */
9691 offset
= ((insn
& 0x7ff) << 1) | 1;
9692 tmp
= load_reg(s
, 14);
9693 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9695 tmp2
= tcg_temp_new_i32();
9696 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9697 store_reg(s
, 14, tmp2
);
9701 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9702 /* Instruction spans a page boundary. Implement it as two
9703 16-bit instructions in case the second half causes an
9705 offset
= ((int32_t)insn
<< 21) >> 9;
9706 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9709 /* Fall through to 32-bit decode. */
9712 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9714 insn
|= (uint32_t)insn_hw1
<< 16;
9716 if ((insn
& 0xf800e800) != 0xf000e800) {
9720 rn
= (insn
>> 16) & 0xf;
9721 rs
= (insn
>> 12) & 0xf;
9722 rd
= (insn
>> 8) & 0xf;
9724 switch ((insn
>> 25) & 0xf) {
9725 case 0: case 1: case 2: case 3:
9726 /* 16-bit instructions. Should never happen. */
9729 if (insn
& (1 << 22)) {
9730 /* Other load/store, table branch. */
9731 if (insn
& 0x01200000) {
9732 /* Load/store doubleword. */
9734 addr
= tcg_temp_new_i32();
9735 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9737 addr
= load_reg(s
, rn
);
9739 offset
= (insn
& 0xff) * 4;
9740 if ((insn
& (1 << 23)) == 0)
9742 if (insn
& (1 << 24)) {
9743 tcg_gen_addi_i32(addr
, addr
, offset
);
9746 if (insn
& (1 << 20)) {
9748 tmp
= tcg_temp_new_i32();
9749 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9750 store_reg(s
, rs
, tmp
);
9751 tcg_gen_addi_i32(addr
, addr
, 4);
9752 tmp
= tcg_temp_new_i32();
9753 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9754 store_reg(s
, rd
, tmp
);
9757 tmp
= load_reg(s
, rs
);
9758 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9759 tcg_temp_free_i32(tmp
);
9760 tcg_gen_addi_i32(addr
, addr
, 4);
9761 tmp
= load_reg(s
, rd
);
9762 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9763 tcg_temp_free_i32(tmp
);
9765 if (insn
& (1 << 21)) {
9766 /* Base writeback. */
9769 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9770 store_reg(s
, rn
, addr
);
9772 tcg_temp_free_i32(addr
);
9774 } else if ((insn
& (1 << 23)) == 0) {
9775 /* Load/store exclusive word. */
9776 addr
= tcg_temp_local_new_i32();
9777 load_reg_var(s
, addr
, rn
);
9778 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9779 if (insn
& (1 << 20)) {
9780 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9782 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9784 tcg_temp_free_i32(addr
);
9785 } else if ((insn
& (7 << 5)) == 0) {
9788 addr
= tcg_temp_new_i32();
9789 tcg_gen_movi_i32(addr
, s
->pc
);
9791 addr
= load_reg(s
, rn
);
9793 tmp
= load_reg(s
, rm
);
9794 tcg_gen_add_i32(addr
, addr
, tmp
);
9795 if (insn
& (1 << 4)) {
9797 tcg_gen_add_i32(addr
, addr
, tmp
);
9798 tcg_temp_free_i32(tmp
);
9799 tmp
= tcg_temp_new_i32();
9800 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9802 tcg_temp_free_i32(tmp
);
9803 tmp
= tcg_temp_new_i32();
9804 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9806 tcg_temp_free_i32(addr
);
9807 tcg_gen_shli_i32(tmp
, tmp
, 1);
9808 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9809 store_reg(s
, 15, tmp
);
9811 int op2
= (insn
>> 6) & 0x3;
9812 op
= (insn
>> 4) & 0x3;
9817 /* Load/store exclusive byte/halfword/doubleword */
9824 /* Load-acquire/store-release */
9830 /* Load-acquire/store-release exclusive */
9834 addr
= tcg_temp_local_new_i32();
9835 load_reg_var(s
, addr
, rn
);
9837 if (insn
& (1 << 20)) {
9838 tmp
= tcg_temp_new_i32();
9841 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
9845 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9849 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
9855 store_reg(s
, rs
, tmp
);
9857 tmp
= load_reg(s
, rs
);
9860 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
9864 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
9868 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
9874 tcg_temp_free_i32(tmp
);
9876 } else if (insn
& (1 << 20)) {
9877 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9879 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9881 tcg_temp_free_i32(addr
);
9884 /* Load/store multiple, RFE, SRS. */
9885 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9886 /* RFE, SRS: not available in user mode or on M profile */
9887 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9890 if (insn
& (1 << 20)) {
9892 addr
= load_reg(s
, rn
);
9893 if ((insn
& (1 << 24)) == 0)
9894 tcg_gen_addi_i32(addr
, addr
, -8);
9895 /* Load PC into tmp and CPSR into tmp2. */
9896 tmp
= tcg_temp_new_i32();
9897 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9898 tcg_gen_addi_i32(addr
, addr
, 4);
9899 tmp2
= tcg_temp_new_i32();
9900 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9901 if (insn
& (1 << 21)) {
9902 /* Base writeback. */
9903 if (insn
& (1 << 24)) {
9904 tcg_gen_addi_i32(addr
, addr
, 4);
9906 tcg_gen_addi_i32(addr
, addr
, -4);
9908 store_reg(s
, rn
, addr
);
9910 tcg_temp_free_i32(addr
);
9912 gen_rfe(s
, tmp
, tmp2
);
9915 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9919 int i
, loaded_base
= 0;
9920 TCGv_i32 loaded_var
;
9921 /* Load/store multiple. */
9922 addr
= load_reg(s
, rn
);
9924 for (i
= 0; i
< 16; i
++) {
9925 if (insn
& (1 << i
))
9928 if (insn
& (1 << 24)) {
9929 tcg_gen_addi_i32(addr
, addr
, -offset
);
9932 TCGV_UNUSED_I32(loaded_var
);
9933 for (i
= 0; i
< 16; i
++) {
9934 if ((insn
& (1 << i
)) == 0)
9936 if (insn
& (1 << 20)) {
9938 tmp
= tcg_temp_new_i32();
9939 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9941 gen_bx_excret(s
, tmp
);
9942 } else if (i
== rn
) {
9946 store_reg(s
, i
, tmp
);
9950 tmp
= load_reg(s
, i
);
9951 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9952 tcg_temp_free_i32(tmp
);
9954 tcg_gen_addi_i32(addr
, addr
, 4);
9957 store_reg(s
, rn
, loaded_var
);
9959 if (insn
& (1 << 21)) {
9960 /* Base register writeback. */
9961 if (insn
& (1 << 24)) {
9962 tcg_gen_addi_i32(addr
, addr
, -offset
);
9964 /* Fault if writeback register is in register list. */
9965 if (insn
& (1 << rn
))
9967 store_reg(s
, rn
, addr
);
9969 tcg_temp_free_i32(addr
);
9976 op
= (insn
>> 21) & 0xf;
9978 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9981 /* Halfword pack. */
9982 tmp
= load_reg(s
, rn
);
9983 tmp2
= load_reg(s
, rm
);
9984 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9985 if (insn
& (1 << 5)) {
9989 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9990 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9991 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9995 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9996 tcg_gen_ext16u_i32(tmp
, tmp
);
9997 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9999 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10000 tcg_temp_free_i32(tmp2
);
10001 store_reg(s
, rd
, tmp
);
10003 /* Data processing register constant shift. */
10005 tmp
= tcg_temp_new_i32();
10006 tcg_gen_movi_i32(tmp
, 0);
10008 tmp
= load_reg(s
, rn
);
10010 tmp2
= load_reg(s
, rm
);
10012 shiftop
= (insn
>> 4) & 3;
10013 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10014 conds
= (insn
& (1 << 20)) != 0;
10015 logic_cc
= (conds
&& thumb2_logic_op(op
));
10016 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10017 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10019 tcg_temp_free_i32(tmp2
);
10021 store_reg(s
, rd
, tmp
);
10023 tcg_temp_free_i32(tmp
);
10027 case 13: /* Misc data processing. */
10028 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10029 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10032 case 0: /* Register controlled shift. */
10033 tmp
= load_reg(s
, rn
);
10034 tmp2
= load_reg(s
, rm
);
10035 if ((insn
& 0x70) != 0)
10037 op
= (insn
>> 21) & 3;
10038 logic_cc
= (insn
& (1 << 20)) != 0;
10039 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10042 store_reg(s
, rd
, tmp
);
10044 case 1: /* Sign/zero extend. */
10045 op
= (insn
>> 20) & 7;
10047 case 0: /* SXTAH, SXTH */
10048 case 1: /* UXTAH, UXTH */
10049 case 4: /* SXTAB, SXTB */
10050 case 5: /* UXTAB, UXTB */
10052 case 2: /* SXTAB16, SXTB16 */
10053 case 3: /* UXTAB16, UXTB16 */
10054 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10062 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10066 tmp
= load_reg(s
, rm
);
10067 shift
= (insn
>> 4) & 3;
10068 /* ??? In many cases it's not necessary to do a
10069 rotate, a shift is sufficient. */
10071 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10072 op
= (insn
>> 20) & 7;
10074 case 0: gen_sxth(tmp
); break;
10075 case 1: gen_uxth(tmp
); break;
10076 case 2: gen_sxtb16(tmp
); break;
10077 case 3: gen_uxtb16(tmp
); break;
10078 case 4: gen_sxtb(tmp
); break;
10079 case 5: gen_uxtb(tmp
); break;
10081 g_assert_not_reached();
10084 tmp2
= load_reg(s
, rn
);
10085 if ((op
>> 1) == 1) {
10086 gen_add16(tmp
, tmp2
);
10088 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10089 tcg_temp_free_i32(tmp2
);
10092 store_reg(s
, rd
, tmp
);
10094 case 2: /* SIMD add/subtract. */
10095 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10098 op
= (insn
>> 20) & 7;
10099 shift
= (insn
>> 4) & 7;
10100 if ((op
& 3) == 3 || (shift
& 3) == 3)
10102 tmp
= load_reg(s
, rn
);
10103 tmp2
= load_reg(s
, rm
);
10104 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10105 tcg_temp_free_i32(tmp2
);
10106 store_reg(s
, rd
, tmp
);
10108 case 3: /* Other data processing. */
10109 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10111 /* Saturating add/subtract. */
10112 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10115 tmp
= load_reg(s
, rn
);
10116 tmp2
= load_reg(s
, rm
);
10118 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10120 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10122 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10123 tcg_temp_free_i32(tmp2
);
10126 case 0x0a: /* rbit */
10127 case 0x08: /* rev */
10128 case 0x09: /* rev16 */
10129 case 0x0b: /* revsh */
10130 case 0x18: /* clz */
10132 case 0x10: /* sel */
10133 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10137 case 0x20: /* crc32/crc32c */
10143 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10150 tmp
= load_reg(s
, rn
);
10152 case 0x0a: /* rbit */
10153 gen_helper_rbit(tmp
, tmp
);
10155 case 0x08: /* rev */
10156 tcg_gen_bswap32_i32(tmp
, tmp
);
10158 case 0x09: /* rev16 */
10161 case 0x0b: /* revsh */
10164 case 0x10: /* sel */
10165 tmp2
= load_reg(s
, rm
);
10166 tmp3
= tcg_temp_new_i32();
10167 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10168 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10169 tcg_temp_free_i32(tmp3
);
10170 tcg_temp_free_i32(tmp2
);
10172 case 0x18: /* clz */
10173 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10183 uint32_t sz
= op
& 0x3;
10184 uint32_t c
= op
& 0x8;
10186 tmp2
= load_reg(s
, rm
);
10188 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10189 } else if (sz
== 1) {
10190 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10192 tmp3
= tcg_const_i32(1 << sz
);
10194 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10196 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10198 tcg_temp_free_i32(tmp2
);
10199 tcg_temp_free_i32(tmp3
);
10203 g_assert_not_reached();
10206 store_reg(s
, rd
, tmp
);
10208 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10209 switch ((insn
>> 20) & 7) {
10210 case 0: /* 32 x 32 -> 32 */
10211 case 7: /* Unsigned sum of absolute differences. */
10213 case 1: /* 16 x 16 -> 32 */
10214 case 2: /* Dual multiply add. */
10215 case 3: /* 32 * 16 -> 32msb */
10216 case 4: /* Dual multiply subtract. */
10217 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10218 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10223 op
= (insn
>> 4) & 0xf;
10224 tmp
= load_reg(s
, rn
);
10225 tmp2
= load_reg(s
, rm
);
10226 switch ((insn
>> 20) & 7) {
10227 case 0: /* 32 x 32 -> 32 */
10228 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10229 tcg_temp_free_i32(tmp2
);
10231 tmp2
= load_reg(s
, rs
);
10233 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10235 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10236 tcg_temp_free_i32(tmp2
);
10239 case 1: /* 16 x 16 -> 32 */
10240 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10241 tcg_temp_free_i32(tmp2
);
10243 tmp2
= load_reg(s
, rs
);
10244 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10245 tcg_temp_free_i32(tmp2
);
10248 case 2: /* Dual multiply add. */
10249 case 4: /* Dual multiply subtract. */
10251 gen_swap_half(tmp2
);
10252 gen_smul_dual(tmp
, tmp2
);
10253 if (insn
& (1 << 22)) {
10254 /* This subtraction cannot overflow. */
10255 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10257 /* This addition cannot overflow 32 bits;
10258 * however it may overflow considered as a signed
10259 * operation, in which case we must set the Q flag.
10261 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10263 tcg_temp_free_i32(tmp2
);
10266 tmp2
= load_reg(s
, rs
);
10267 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10268 tcg_temp_free_i32(tmp2
);
10271 case 3: /* 32 * 16 -> 32msb */
10273 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10276 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10277 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10278 tmp
= tcg_temp_new_i32();
10279 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10280 tcg_temp_free_i64(tmp64
);
10283 tmp2
= load_reg(s
, rs
);
10284 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10285 tcg_temp_free_i32(tmp2
);
10288 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10289 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10291 tmp
= load_reg(s
, rs
);
10292 if (insn
& (1 << 20)) {
10293 tmp64
= gen_addq_msw(tmp64
, tmp
);
10295 tmp64
= gen_subq_msw(tmp64
, tmp
);
10298 if (insn
& (1 << 4)) {
10299 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10301 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10302 tmp
= tcg_temp_new_i32();
10303 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10304 tcg_temp_free_i64(tmp64
);
10306 case 7: /* Unsigned sum of absolute differences. */
10307 gen_helper_usad8(tmp
, tmp
, tmp2
);
10308 tcg_temp_free_i32(tmp2
);
10310 tmp2
= load_reg(s
, rs
);
10311 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10312 tcg_temp_free_i32(tmp2
);
10316 store_reg(s
, rd
, tmp
);
10318 case 6: case 7: /* 64-bit multiply, Divide. */
10319 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10320 tmp
= load_reg(s
, rn
);
10321 tmp2
= load_reg(s
, rm
);
10322 if ((op
& 0x50) == 0x10) {
10324 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10328 gen_helper_udiv(tmp
, tmp
, tmp2
);
10330 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10331 tcg_temp_free_i32(tmp2
);
10332 store_reg(s
, rd
, tmp
);
10333 } else if ((op
& 0xe) == 0xc) {
10334 /* Dual multiply accumulate long. */
10335 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10336 tcg_temp_free_i32(tmp
);
10337 tcg_temp_free_i32(tmp2
);
10341 gen_swap_half(tmp2
);
10342 gen_smul_dual(tmp
, tmp2
);
10344 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10346 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10348 tcg_temp_free_i32(tmp2
);
10350 tmp64
= tcg_temp_new_i64();
10351 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10352 tcg_temp_free_i32(tmp
);
10353 gen_addq(s
, tmp64
, rs
, rd
);
10354 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10355 tcg_temp_free_i64(tmp64
);
10358 /* Unsigned 64-bit multiply */
10359 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10363 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10364 tcg_temp_free_i32(tmp2
);
10365 tcg_temp_free_i32(tmp
);
10368 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10369 tcg_temp_free_i32(tmp2
);
10370 tmp64
= tcg_temp_new_i64();
10371 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10372 tcg_temp_free_i32(tmp
);
10374 /* Signed 64-bit multiply */
10375 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10380 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10381 tcg_temp_free_i64(tmp64
);
10384 gen_addq_lo(s
, tmp64
, rs
);
10385 gen_addq_lo(s
, tmp64
, rd
);
10386 } else if (op
& 0x40) {
10387 /* 64-bit accumulate. */
10388 gen_addq(s
, tmp64
, rs
, rd
);
10390 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10391 tcg_temp_free_i64(tmp64
);
10396 case 6: case 7: case 14: case 15:
10398 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10399 /* We don't currently implement M profile FP support,
10400 * so this entire space should give a NOCP fault.
10402 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10403 default_exception_el(s
));
10406 if (((insn
>> 24) & 3) == 3) {
10407 /* Translate into the equivalent ARM encoding. */
10408 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10409 if (disas_neon_data_insn(s
, insn
)) {
10412 } else if (((insn
>> 8) & 0xe) == 10) {
10413 if (disas_vfp_insn(s
, insn
)) {
10417 if (insn
& (1 << 28))
10419 if (disas_coproc_insn(s
, insn
)) {
10424 case 8: case 9: case 10: case 11:
10425 if (insn
& (1 << 15)) {
10426 /* Branches, misc control. */
10427 if (insn
& 0x5000) {
10428 /* Unconditional branch. */
10429 /* signextend(hw1[10:0]) -> offset[:12]. */
10430 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10431 /* hw1[10:0] -> offset[11:1]. */
10432 offset
|= (insn
& 0x7ff) << 1;
10433 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10434 offset[24:22] already have the same value because of the
10435 sign extension above. */
10436 offset
^= ((~insn
) & (1 << 13)) << 10;
10437 offset
^= ((~insn
) & (1 << 11)) << 11;
10439 if (insn
& (1 << 14)) {
10440 /* Branch and link. */
10441 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10445 if (insn
& (1 << 12)) {
10447 gen_jmp(s
, offset
);
10450 offset
&= ~(uint32_t)2;
10451 /* thumb2 bx, no need to check */
10452 gen_bx_im(s
, offset
);
10454 } else if (((insn
>> 23) & 7) == 7) {
10456 if (insn
& (1 << 13))
10459 if (insn
& (1 << 26)) {
10460 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10463 if (!(insn
& (1 << 20))) {
10464 /* Hypervisor call (v7) */
10465 int imm16
= extract32(insn
, 16, 4) << 12
10466 | extract32(insn
, 0, 12);
10473 /* Secure monitor call (v6+) */
10481 op
= (insn
>> 20) & 7;
10483 case 0: /* msr cpsr. */
10484 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10485 tmp
= load_reg(s
, rn
);
10486 /* the constant is the mask and SYSm fields */
10487 addr
= tcg_const_i32(insn
& 0xfff);
10488 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10489 tcg_temp_free_i32(addr
);
10490 tcg_temp_free_i32(tmp
);
10495 case 1: /* msr spsr. */
10496 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10500 if (extract32(insn
, 5, 1)) {
10502 int sysm
= extract32(insn
, 8, 4) |
10503 (extract32(insn
, 4, 1) << 4);
10506 gen_msr_banked(s
, r
, sysm
, rm
);
10510 /* MSR (for PSRs) */
10511 tmp
= load_reg(s
, rn
);
10513 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10517 case 2: /* cps, nop-hint. */
10518 if (((insn
>> 8) & 7) == 0) {
10519 gen_nop_hint(s
, insn
& 0xff);
10521 /* Implemented as NOP in user mode. */
10526 if (insn
& (1 << 10)) {
10527 if (insn
& (1 << 7))
10529 if (insn
& (1 << 6))
10531 if (insn
& (1 << 5))
10533 if (insn
& (1 << 9))
10534 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10536 if (insn
& (1 << 8)) {
10538 imm
|= (insn
& 0x1f);
10541 gen_set_psr_im(s
, offset
, 0, imm
);
10544 case 3: /* Special control operations. */
10546 op
= (insn
>> 4) & 0xf;
10548 case 2: /* clrex */
10553 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10556 /* We need to break the TB after this insn
10557 * to execute self-modifying code correctly
10558 * and also to take any pending interrupts
10568 /* Trivial implementation equivalent to bx.
10569 * This instruction doesn't exist at all for M-profile.
10571 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10574 tmp
= load_reg(s
, rn
);
10577 case 5: /* Exception return. */
10581 if (rn
!= 14 || rd
!= 15) {
10584 tmp
= load_reg(s
, rn
);
10585 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10586 gen_exception_return(s
, tmp
);
10589 if (extract32(insn
, 5, 1) &&
10590 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10592 int sysm
= extract32(insn
, 16, 4) |
10593 (extract32(insn
, 4, 1) << 4);
10595 gen_mrs_banked(s
, 0, sysm
, rd
);
10599 if (extract32(insn
, 16, 4) != 0xf) {
10602 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10603 extract32(insn
, 0, 8) != 0) {
10608 tmp
= tcg_temp_new_i32();
10609 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10610 addr
= tcg_const_i32(insn
& 0xff);
10611 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10612 tcg_temp_free_i32(addr
);
10614 gen_helper_cpsr_read(tmp
, cpu_env
);
10616 store_reg(s
, rd
, tmp
);
10619 if (extract32(insn
, 5, 1) &&
10620 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10622 int sysm
= extract32(insn
, 16, 4) |
10623 (extract32(insn
, 4, 1) << 4);
10625 gen_mrs_banked(s
, 1, sysm
, rd
);
10630 /* Not accessible in user mode. */
10631 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10635 if (extract32(insn
, 16, 4) != 0xf ||
10636 extract32(insn
, 0, 8) != 0) {
10640 tmp
= load_cpu_field(spsr
);
10641 store_reg(s
, rd
, tmp
);
10646 /* Conditional branch. */
10647 op
= (insn
>> 22) & 0xf;
10648 /* Generate a conditional jump to next instruction. */
10649 s
->condlabel
= gen_new_label();
10650 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10653 /* offset[11:1] = insn[10:0] */
10654 offset
= (insn
& 0x7ff) << 1;
10655 /* offset[17:12] = insn[21:16]. */
10656 offset
|= (insn
& 0x003f0000) >> 4;
10657 /* offset[31:20] = insn[26]. */
10658 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10659 /* offset[18] = insn[13]. */
10660 offset
|= (insn
& (1 << 13)) << 5;
10661 /* offset[19] = insn[11]. */
10662 offset
|= (insn
& (1 << 11)) << 8;
10664 /* jump to the offset */
10665 gen_jmp(s
, s
->pc
+ offset
);
10668 /* Data processing immediate. */
10669 if (insn
& (1 << 25)) {
10670 if (insn
& (1 << 24)) {
10671 if (insn
& (1 << 20))
10673 /* Bitfield/Saturate. */
10674 op
= (insn
>> 21) & 7;
10676 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10678 tmp
= tcg_temp_new_i32();
10679 tcg_gen_movi_i32(tmp
, 0);
10681 tmp
= load_reg(s
, rn
);
10684 case 2: /* Signed bitfield extract. */
10686 if (shift
+ imm
> 32)
10689 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
10692 case 6: /* Unsigned bitfield extract. */
10694 if (shift
+ imm
> 32)
10697 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
10700 case 3: /* Bitfield insert/clear. */
10703 imm
= imm
+ 1 - shift
;
10705 tmp2
= load_reg(s
, rd
);
10706 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10707 tcg_temp_free_i32(tmp2
);
10712 default: /* Saturate. */
10715 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10717 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10719 tmp2
= tcg_const_i32(imm
);
10722 if ((op
& 1) && shift
== 0) {
10723 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10724 tcg_temp_free_i32(tmp
);
10725 tcg_temp_free_i32(tmp2
);
10728 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10730 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10734 if ((op
& 1) && shift
== 0) {
10735 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10736 tcg_temp_free_i32(tmp
);
10737 tcg_temp_free_i32(tmp2
);
10740 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10742 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10745 tcg_temp_free_i32(tmp2
);
10748 store_reg(s
, rd
, tmp
);
10750 imm
= ((insn
& 0x04000000) >> 15)
10751 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10752 if (insn
& (1 << 22)) {
10753 /* 16-bit immediate. */
10754 imm
|= (insn
>> 4) & 0xf000;
10755 if (insn
& (1 << 23)) {
10757 tmp
= load_reg(s
, rd
);
10758 tcg_gen_ext16u_i32(tmp
, tmp
);
10759 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10762 tmp
= tcg_temp_new_i32();
10763 tcg_gen_movi_i32(tmp
, imm
);
10766 /* Add/sub 12-bit immediate. */
10768 offset
= s
->pc
& ~(uint32_t)3;
10769 if (insn
& (1 << 23))
10773 tmp
= tcg_temp_new_i32();
10774 tcg_gen_movi_i32(tmp
, offset
);
10776 tmp
= load_reg(s
, rn
);
10777 if (insn
& (1 << 23))
10778 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10780 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10783 store_reg(s
, rd
, tmp
);
10786 int shifter_out
= 0;
10787 /* modified 12-bit immediate. */
10788 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10789 imm
= (insn
& 0xff);
10792 /* Nothing to do. */
10794 case 1: /* 00XY00XY */
10797 case 2: /* XY00XY00 */
10801 case 3: /* XYXYXYXY */
10805 default: /* Rotated constant. */
10806 shift
= (shift
<< 1) | (imm
>> 7);
10808 imm
= imm
<< (32 - shift
);
10812 tmp2
= tcg_temp_new_i32();
10813 tcg_gen_movi_i32(tmp2
, imm
);
10814 rn
= (insn
>> 16) & 0xf;
10816 tmp
= tcg_temp_new_i32();
10817 tcg_gen_movi_i32(tmp
, 0);
10819 tmp
= load_reg(s
, rn
);
10821 op
= (insn
>> 21) & 0xf;
10822 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10823 shifter_out
, tmp
, tmp2
))
10825 tcg_temp_free_i32(tmp2
);
10826 rd
= (insn
>> 8) & 0xf;
10828 store_reg(s
, rd
, tmp
);
10830 tcg_temp_free_i32(tmp
);
10835 case 12: /* Load/store single data item. */
10842 if ((insn
& 0x01100000) == 0x01000000) {
10843 if (disas_neon_ls_insn(s
, insn
)) {
10848 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10850 if (!(insn
& (1 << 20))) {
10854 /* Byte or halfword load space with dest == r15 : memory hints.
10855 * Catch them early so we don't emit pointless addressing code.
10856 * This space is a mix of:
10857 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10858 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10860 * unallocated hints, which must be treated as NOPs
10861 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10862 * which is easiest for the decoding logic
10863 * Some space which must UNDEF
10865 int op1
= (insn
>> 23) & 3;
10866 int op2
= (insn
>> 6) & 0x3f;
10871 /* UNPREDICTABLE, unallocated hint or
10872 * PLD/PLDW/PLI (literal)
10877 return 0; /* PLD/PLDW/PLI or unallocated hint */
10879 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10880 return 0; /* PLD/PLDW/PLI or unallocated hint */
10882 /* UNDEF space, or an UNPREDICTABLE */
10886 memidx
= get_mem_index(s
);
10888 addr
= tcg_temp_new_i32();
10890 /* s->pc has already been incremented by 4. */
10891 imm
= s
->pc
& 0xfffffffc;
10892 if (insn
& (1 << 23))
10893 imm
+= insn
& 0xfff;
10895 imm
-= insn
& 0xfff;
10896 tcg_gen_movi_i32(addr
, imm
);
10898 addr
= load_reg(s
, rn
);
10899 if (insn
& (1 << 23)) {
10900 /* Positive offset. */
10901 imm
= insn
& 0xfff;
10902 tcg_gen_addi_i32(addr
, addr
, imm
);
10905 switch ((insn
>> 8) & 0xf) {
10906 case 0x0: /* Shifted Register. */
10907 shift
= (insn
>> 4) & 0xf;
10909 tcg_temp_free_i32(addr
);
10912 tmp
= load_reg(s
, rm
);
10914 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10915 tcg_gen_add_i32(addr
, addr
, tmp
);
10916 tcg_temp_free_i32(tmp
);
10918 case 0xc: /* Negative offset. */
10919 tcg_gen_addi_i32(addr
, addr
, -imm
);
10921 case 0xe: /* User privilege. */
10922 tcg_gen_addi_i32(addr
, addr
, imm
);
10923 memidx
= get_a32_user_mem_index(s
);
10925 case 0x9: /* Post-decrement. */
10927 /* Fall through. */
10928 case 0xb: /* Post-increment. */
10932 case 0xd: /* Pre-decrement. */
10934 /* Fall through. */
10935 case 0xf: /* Pre-increment. */
10936 tcg_gen_addi_i32(addr
, addr
, imm
);
10940 tcg_temp_free_i32(addr
);
10946 issinfo
= writeback
? ISSInvalid
: rs
;
10948 if (insn
& (1 << 20)) {
10950 tmp
= tcg_temp_new_i32();
10953 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10956 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10959 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10962 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10965 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10968 tcg_temp_free_i32(tmp
);
10969 tcg_temp_free_i32(addr
);
10973 gen_bx_excret(s
, tmp
);
10975 store_reg(s
, rs
, tmp
);
10979 tmp
= load_reg(s
, rs
);
10982 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
10985 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
10988 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
10991 tcg_temp_free_i32(tmp
);
10992 tcg_temp_free_i32(addr
);
10995 tcg_temp_free_i32(tmp
);
10998 tcg_gen_addi_i32(addr
, addr
, imm
);
11000 store_reg(s
, rn
, addr
);
11002 tcg_temp_free_i32(addr
);
11014 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
11016 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
11023 if (s
->condexec_mask
) {
11024 cond
= s
->condexec_cond
;
11025 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
11026 s
->condlabel
= gen_new_label();
11027 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11032 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11035 switch (insn
>> 12) {
11039 op
= (insn
>> 11) & 3;
11042 rn
= (insn
>> 3) & 7;
11043 tmp
= load_reg(s
, rn
);
11044 if (insn
& (1 << 10)) {
11046 tmp2
= tcg_temp_new_i32();
11047 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11050 rm
= (insn
>> 6) & 7;
11051 tmp2
= load_reg(s
, rm
);
11053 if (insn
& (1 << 9)) {
11054 if (s
->condexec_mask
)
11055 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11057 gen_sub_CC(tmp
, tmp
, tmp2
);
11059 if (s
->condexec_mask
)
11060 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11062 gen_add_CC(tmp
, tmp
, tmp2
);
11064 tcg_temp_free_i32(tmp2
);
11065 store_reg(s
, rd
, tmp
);
11067 /* shift immediate */
11068 rm
= (insn
>> 3) & 7;
11069 shift
= (insn
>> 6) & 0x1f;
11070 tmp
= load_reg(s
, rm
);
11071 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11072 if (!s
->condexec_mask
)
11074 store_reg(s
, rd
, tmp
);
11078 /* arithmetic large immediate */
11079 op
= (insn
>> 11) & 3;
11080 rd
= (insn
>> 8) & 0x7;
11081 if (op
== 0) { /* mov */
11082 tmp
= tcg_temp_new_i32();
11083 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11084 if (!s
->condexec_mask
)
11086 store_reg(s
, rd
, tmp
);
11088 tmp
= load_reg(s
, rd
);
11089 tmp2
= tcg_temp_new_i32();
11090 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11093 gen_sub_CC(tmp
, tmp
, tmp2
);
11094 tcg_temp_free_i32(tmp
);
11095 tcg_temp_free_i32(tmp2
);
11098 if (s
->condexec_mask
)
11099 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11101 gen_add_CC(tmp
, tmp
, tmp2
);
11102 tcg_temp_free_i32(tmp2
);
11103 store_reg(s
, rd
, tmp
);
11106 if (s
->condexec_mask
)
11107 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11109 gen_sub_CC(tmp
, tmp
, tmp2
);
11110 tcg_temp_free_i32(tmp2
);
11111 store_reg(s
, rd
, tmp
);
11117 if (insn
& (1 << 11)) {
11118 rd
= (insn
>> 8) & 7;
11119 /* load pc-relative. Bit 1 of PC is ignored. */
11120 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11121 val
&= ~(uint32_t)2;
11122 addr
= tcg_temp_new_i32();
11123 tcg_gen_movi_i32(addr
, val
);
11124 tmp
= tcg_temp_new_i32();
11125 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11127 tcg_temp_free_i32(addr
);
11128 store_reg(s
, rd
, tmp
);
11131 if (insn
& (1 << 10)) {
11132 /* data processing extended or blx */
11133 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11134 rm
= (insn
>> 3) & 0xf;
11135 op
= (insn
>> 8) & 3;
11138 tmp
= load_reg(s
, rd
);
11139 tmp2
= load_reg(s
, rm
);
11140 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11141 tcg_temp_free_i32(tmp2
);
11142 store_reg(s
, rd
, tmp
);
11145 tmp
= load_reg(s
, rd
);
11146 tmp2
= load_reg(s
, rm
);
11147 gen_sub_CC(tmp
, tmp
, tmp2
);
11148 tcg_temp_free_i32(tmp2
);
11149 tcg_temp_free_i32(tmp
);
11151 case 2: /* mov/cpy */
11152 tmp
= load_reg(s
, rm
);
11153 store_reg(s
, rd
, tmp
);
11155 case 3:/* branch [and link] exchange thumb register */
11156 tmp
= load_reg(s
, rm
);
11157 if (insn
& (1 << 7)) {
11159 val
= (uint32_t)s
->pc
| 1;
11160 tmp2
= tcg_temp_new_i32();
11161 tcg_gen_movi_i32(tmp2
, val
);
11162 store_reg(s
, 14, tmp2
);
11165 /* Only BX works as exception-return, not BLX */
11166 gen_bx_excret(s
, tmp
);
11173 /* data processing register */
11175 rm
= (insn
>> 3) & 7;
11176 op
= (insn
>> 6) & 0xf;
11177 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11178 /* the shift/rotate ops want the operands backwards */
11187 if (op
== 9) { /* neg */
11188 tmp
= tcg_temp_new_i32();
11189 tcg_gen_movi_i32(tmp
, 0);
11190 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11191 tmp
= load_reg(s
, rd
);
11193 TCGV_UNUSED_I32(tmp
);
11196 tmp2
= load_reg(s
, rm
);
11198 case 0x0: /* and */
11199 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11200 if (!s
->condexec_mask
)
11203 case 0x1: /* eor */
11204 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11205 if (!s
->condexec_mask
)
11208 case 0x2: /* lsl */
11209 if (s
->condexec_mask
) {
11210 gen_shl(tmp2
, tmp2
, tmp
);
11212 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11213 gen_logic_CC(tmp2
);
11216 case 0x3: /* lsr */
11217 if (s
->condexec_mask
) {
11218 gen_shr(tmp2
, tmp2
, tmp
);
11220 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11221 gen_logic_CC(tmp2
);
11224 case 0x4: /* asr */
11225 if (s
->condexec_mask
) {
11226 gen_sar(tmp2
, tmp2
, tmp
);
11228 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11229 gen_logic_CC(tmp2
);
11232 case 0x5: /* adc */
11233 if (s
->condexec_mask
) {
11234 gen_adc(tmp
, tmp2
);
11236 gen_adc_CC(tmp
, tmp
, tmp2
);
11239 case 0x6: /* sbc */
11240 if (s
->condexec_mask
) {
11241 gen_sub_carry(tmp
, tmp
, tmp2
);
11243 gen_sbc_CC(tmp
, tmp
, tmp2
);
11246 case 0x7: /* ror */
11247 if (s
->condexec_mask
) {
11248 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11249 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11251 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11252 gen_logic_CC(tmp2
);
11255 case 0x8: /* tst */
11256 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11260 case 0x9: /* neg */
11261 if (s
->condexec_mask
)
11262 tcg_gen_neg_i32(tmp
, tmp2
);
11264 gen_sub_CC(tmp
, tmp
, tmp2
);
11266 case 0xa: /* cmp */
11267 gen_sub_CC(tmp
, tmp
, tmp2
);
11270 case 0xb: /* cmn */
11271 gen_add_CC(tmp
, tmp
, tmp2
);
11274 case 0xc: /* orr */
11275 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11276 if (!s
->condexec_mask
)
11279 case 0xd: /* mul */
11280 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11281 if (!s
->condexec_mask
)
11284 case 0xe: /* bic */
11285 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11286 if (!s
->condexec_mask
)
11289 case 0xf: /* mvn */
11290 tcg_gen_not_i32(tmp2
, tmp2
);
11291 if (!s
->condexec_mask
)
11292 gen_logic_CC(tmp2
);
11299 store_reg(s
, rm
, tmp2
);
11301 tcg_temp_free_i32(tmp
);
11303 store_reg(s
, rd
, tmp
);
11304 tcg_temp_free_i32(tmp2
);
11307 tcg_temp_free_i32(tmp
);
11308 tcg_temp_free_i32(tmp2
);
11313 /* load/store register offset. */
11315 rn
= (insn
>> 3) & 7;
11316 rm
= (insn
>> 6) & 7;
11317 op
= (insn
>> 9) & 7;
11318 addr
= load_reg(s
, rn
);
11319 tmp
= load_reg(s
, rm
);
11320 tcg_gen_add_i32(addr
, addr
, tmp
);
11321 tcg_temp_free_i32(tmp
);
11323 if (op
< 3) { /* store */
11324 tmp
= load_reg(s
, rd
);
11326 tmp
= tcg_temp_new_i32();
11331 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11334 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11337 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11339 case 3: /* ldrsb */
11340 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11343 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11346 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11349 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11351 case 7: /* ldrsh */
11352 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11355 if (op
>= 3) { /* load */
11356 store_reg(s
, rd
, tmp
);
11358 tcg_temp_free_i32(tmp
);
11360 tcg_temp_free_i32(addr
);
11364 /* load/store word immediate offset */
11366 rn
= (insn
>> 3) & 7;
11367 addr
= load_reg(s
, rn
);
11368 val
= (insn
>> 4) & 0x7c;
11369 tcg_gen_addi_i32(addr
, addr
, val
);
11371 if (insn
& (1 << 11)) {
11373 tmp
= tcg_temp_new_i32();
11374 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11375 store_reg(s
, rd
, tmp
);
11378 tmp
= load_reg(s
, rd
);
11379 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11380 tcg_temp_free_i32(tmp
);
11382 tcg_temp_free_i32(addr
);
11386 /* load/store byte immediate offset */
11388 rn
= (insn
>> 3) & 7;
11389 addr
= load_reg(s
, rn
);
11390 val
= (insn
>> 6) & 0x1f;
11391 tcg_gen_addi_i32(addr
, addr
, val
);
11393 if (insn
& (1 << 11)) {
11395 tmp
= tcg_temp_new_i32();
11396 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11397 store_reg(s
, rd
, tmp
);
11400 tmp
= load_reg(s
, rd
);
11401 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11402 tcg_temp_free_i32(tmp
);
11404 tcg_temp_free_i32(addr
);
11408 /* load/store halfword immediate offset */
11410 rn
= (insn
>> 3) & 7;
11411 addr
= load_reg(s
, rn
);
11412 val
= (insn
>> 5) & 0x3e;
11413 tcg_gen_addi_i32(addr
, addr
, val
);
11415 if (insn
& (1 << 11)) {
11417 tmp
= tcg_temp_new_i32();
11418 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11419 store_reg(s
, rd
, tmp
);
11422 tmp
= load_reg(s
, rd
);
11423 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11424 tcg_temp_free_i32(tmp
);
11426 tcg_temp_free_i32(addr
);
11430 /* load/store from stack */
11431 rd
= (insn
>> 8) & 7;
11432 addr
= load_reg(s
, 13);
11433 val
= (insn
& 0xff) * 4;
11434 tcg_gen_addi_i32(addr
, addr
, val
);
11436 if (insn
& (1 << 11)) {
11438 tmp
= tcg_temp_new_i32();
11439 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11440 store_reg(s
, rd
, tmp
);
11443 tmp
= load_reg(s
, rd
);
11444 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11445 tcg_temp_free_i32(tmp
);
11447 tcg_temp_free_i32(addr
);
11451 /* add to high reg */
11452 rd
= (insn
>> 8) & 7;
11453 if (insn
& (1 << 11)) {
11455 tmp
= load_reg(s
, 13);
11457 /* PC. bit 1 is ignored. */
11458 tmp
= tcg_temp_new_i32();
11459 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11461 val
= (insn
& 0xff) * 4;
11462 tcg_gen_addi_i32(tmp
, tmp
, val
);
11463 store_reg(s
, rd
, tmp
);
11468 op
= (insn
>> 8) & 0xf;
11471 /* adjust stack pointer */
11472 tmp
= load_reg(s
, 13);
11473 val
= (insn
& 0x7f) * 4;
11474 if (insn
& (1 << 7))
11475 val
= -(int32_t)val
;
11476 tcg_gen_addi_i32(tmp
, tmp
, val
);
11477 store_reg(s
, 13, tmp
);
11480 case 2: /* sign/zero extend. */
11483 rm
= (insn
>> 3) & 7;
11484 tmp
= load_reg(s
, rm
);
11485 switch ((insn
>> 6) & 3) {
11486 case 0: gen_sxth(tmp
); break;
11487 case 1: gen_sxtb(tmp
); break;
11488 case 2: gen_uxth(tmp
); break;
11489 case 3: gen_uxtb(tmp
); break;
11491 store_reg(s
, rd
, tmp
);
11493 case 4: case 5: case 0xc: case 0xd:
11495 addr
= load_reg(s
, 13);
11496 if (insn
& (1 << 8))
11500 for (i
= 0; i
< 8; i
++) {
11501 if (insn
& (1 << i
))
11504 if ((insn
& (1 << 11)) == 0) {
11505 tcg_gen_addi_i32(addr
, addr
, -offset
);
11507 for (i
= 0; i
< 8; i
++) {
11508 if (insn
& (1 << i
)) {
11509 if (insn
& (1 << 11)) {
11511 tmp
= tcg_temp_new_i32();
11512 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11513 store_reg(s
, i
, tmp
);
11516 tmp
= load_reg(s
, i
);
11517 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11518 tcg_temp_free_i32(tmp
);
11520 /* advance to the next address. */
11521 tcg_gen_addi_i32(addr
, addr
, 4);
11524 TCGV_UNUSED_I32(tmp
);
11525 if (insn
& (1 << 8)) {
11526 if (insn
& (1 << 11)) {
11528 tmp
= tcg_temp_new_i32();
11529 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11530 /* don't set the pc until the rest of the instruction
11534 tmp
= load_reg(s
, 14);
11535 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11536 tcg_temp_free_i32(tmp
);
11538 tcg_gen_addi_i32(addr
, addr
, 4);
11540 if ((insn
& (1 << 11)) == 0) {
11541 tcg_gen_addi_i32(addr
, addr
, -offset
);
11543 /* write back the new stack pointer */
11544 store_reg(s
, 13, addr
);
11545 /* set the new PC value */
11546 if ((insn
& 0x0900) == 0x0900) {
11547 store_reg_from_load(s
, 15, tmp
);
11551 case 1: case 3: case 9: case 11: /* czb */
11553 tmp
= load_reg(s
, rm
);
11554 s
->condlabel
= gen_new_label();
11556 if (insn
& (1 << 11))
11557 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11559 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11560 tcg_temp_free_i32(tmp
);
11561 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11562 val
= (uint32_t)s
->pc
+ 2;
11567 case 15: /* IT, nop-hint. */
11568 if ((insn
& 0xf) == 0) {
11569 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11573 s
->condexec_cond
= (insn
>> 4) & 0xe;
11574 s
->condexec_mask
= insn
& 0x1f;
11575 /* No actual code generated for this insn, just setup state. */
11578 case 0xe: /* bkpt */
11580 int imm8
= extract32(insn
, 0, 8);
11582 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11583 default_exception_el(s
));
11587 case 0xa: /* rev, and hlt */
11589 int op1
= extract32(insn
, 6, 2);
11593 int imm6
= extract32(insn
, 0, 6);
11599 /* Otherwise this is rev */
11601 rn
= (insn
>> 3) & 0x7;
11603 tmp
= load_reg(s
, rn
);
11605 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11606 case 1: gen_rev16(tmp
); break;
11607 case 3: gen_revsh(tmp
); break;
11609 g_assert_not_reached();
11611 store_reg(s
, rd
, tmp
);
11616 switch ((insn
>> 5) & 7) {
11620 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11621 gen_helper_setend(cpu_env
);
11622 s
->is_jmp
= DISAS_UPDATE
;
11631 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11632 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11635 addr
= tcg_const_i32(19);
11636 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11637 tcg_temp_free_i32(addr
);
11641 addr
= tcg_const_i32(16);
11642 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11643 tcg_temp_free_i32(addr
);
11645 tcg_temp_free_i32(tmp
);
11648 if (insn
& (1 << 4)) {
11649 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11653 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11668 /* load/store multiple */
11669 TCGv_i32 loaded_var
;
11670 TCGV_UNUSED_I32(loaded_var
);
11671 rn
= (insn
>> 8) & 0x7;
11672 addr
= load_reg(s
, rn
);
11673 for (i
= 0; i
< 8; i
++) {
11674 if (insn
& (1 << i
)) {
11675 if (insn
& (1 << 11)) {
11677 tmp
= tcg_temp_new_i32();
11678 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11682 store_reg(s
, i
, tmp
);
11686 tmp
= load_reg(s
, i
);
11687 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11688 tcg_temp_free_i32(tmp
);
11690 /* advance to the next address */
11691 tcg_gen_addi_i32(addr
, addr
, 4);
11694 if ((insn
& (1 << rn
)) == 0) {
11695 /* base reg not in list: base register writeback */
11696 store_reg(s
, rn
, addr
);
11698 /* base reg in list: if load, complete it now */
11699 if (insn
& (1 << 11)) {
11700 store_reg(s
, rn
, loaded_var
);
11702 tcg_temp_free_i32(addr
);
11707 /* conditional branch or swi */
11708 cond
= (insn
>> 8) & 0xf;
11714 gen_set_pc_im(s
, s
->pc
);
11715 s
->svc_imm
= extract32(insn
, 0, 8);
11716 s
->is_jmp
= DISAS_SWI
;
11719 /* generate a conditional jump to next instruction */
11720 s
->condlabel
= gen_new_label();
11721 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11724 /* jump to the offset */
11725 val
= (uint32_t)s
->pc
+ 2;
11726 offset
= ((int32_t)insn
<< 24) >> 24;
11727 val
+= offset
<< 1;
11732 if (insn
& (1 << 11)) {
11733 if (disas_thumb2_insn(env
, s
, insn
))
11737 /* unconditional branch */
11738 val
= (uint32_t)s
->pc
;
11739 offset
= ((int32_t)insn
<< 21) >> 21;
11740 val
+= (offset
<< 1) + 2;
11745 if (disas_thumb2_insn(env
, s
, insn
))
11751 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11752 default_exception_el(s
));
11756 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11757 default_exception_el(s
));
11760 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11762 /* Return true if the insn at dc->pc might cross a page boundary.
11763 * (False positives are OK, false negatives are not.)
11767 if ((s
->pc
& 3) == 0) {
11768 /* At a 4-aligned address we can't be crossing a page */
11772 /* This must be a Thumb insn */
11773 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11775 if ((insn
>> 11) >= 0x1d) {
11776 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11777 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11778 * end up actually treating this as two 16-bit insns (see the
11779 * code at the start of disas_thumb2_insn()) but we don't bother
11780 * to check for that as it is unlikely, and false positives here
11785 /* Definitely a 16-bit insn, can't be crossing a page. */
11789 /* generate intermediate code for basic block 'tb'. */
11790 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11792 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11793 CPUState
*cs
= CPU(cpu
);
11794 DisasContext dc1
, *dc
= &dc1
;
11795 target_ulong pc_start
;
11796 target_ulong next_page_start
;
11801 /* generate intermediate code */
11803 /* The A64 decoder has its own top level loop, because it doesn't need
11804 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11806 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11807 gen_intermediate_code_a64(cpu
, tb
);
11815 dc
->is_jmp
= DISAS_NEXT
;
11817 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11821 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11822 * there is no secure EL1, so we route exceptions to EL3.
11824 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11825 !arm_el_is_aa64(env
, 3);
11826 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11827 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(tb
->flags
);
11828 dc
->be_data
= ARM_TBFLAG_BE_DATA(tb
->flags
) ? MO_BE
: MO_LE
;
11829 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11830 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11831 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, ARM_TBFLAG_MMUIDX(tb
->flags
));
11832 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11833 #if !defined(CONFIG_USER_ONLY)
11834 dc
->user
= (dc
->current_el
== 0);
11836 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11837 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11838 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11839 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11840 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11841 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11842 dc
->v7m_handler_mode
= ARM_TBFLAG_HANDLER(tb
->flags
);
11843 dc
->cp_regs
= cpu
->cp_regs
;
11844 dc
->features
= env
->features
;
11846 /* Single step state. The code-generation logic here is:
11848 * generate code with no special handling for single-stepping (except
11849 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11850 * this happens anyway because those changes are all system register or
11852 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11853 * emit code for one insn
11854 * emit code to clear PSTATE.SS
11855 * emit code to generate software step exception for completed step
11856 * end TB (as usual for having generated an exception)
11857 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11858 * emit code to generate a software step exception
11861 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11862 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11863 dc
->is_ldex
= false;
11864 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11866 cpu_F0s
= tcg_temp_new_i32();
11867 cpu_F1s
= tcg_temp_new_i32();
11868 cpu_F0d
= tcg_temp_new_i64();
11869 cpu_F1d
= tcg_temp_new_i64();
11872 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11873 cpu_M0
= tcg_temp_new_i64();
11874 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11876 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11877 if (max_insns
== 0) {
11878 max_insns
= CF_COUNT_MASK
;
11880 if (max_insns
> TCG_MAX_INSNS
) {
11881 max_insns
= TCG_MAX_INSNS
;
11886 tcg_clear_temp_count();
11888 /* A note on handling of the condexec (IT) bits:
11890 * We want to avoid the overhead of having to write the updated condexec
11891 * bits back to the CPUARMState for every instruction in an IT block. So:
11892 * (1) if the condexec bits are not already zero then we write
11893 * zero back into the CPUARMState now. This avoids complications trying
11894 * to do it at the end of the block. (For example if we don't do this
11895 * it's hard to identify whether we can safely skip writing condexec
11896 * at the end of the TB, which we definitely want to do for the case
11897 * where a TB doesn't do anything with the IT state at all.)
11898 * (2) if we are going to leave the TB then we call gen_set_condexec()
11899 * which will write the correct value into CPUARMState if zero is wrong.
11900 * This is done both for leaving the TB at the end, and for leaving
11901 * it because of an exception we know will happen, which is done in
11902 * gen_exception_insn(). The latter is necessary because we need to
11903 * leave the TB with the PC/IT state just prior to execution of the
11904 * instruction which caused the exception.
11905 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11906 * then the CPUARMState will be wrong and we need to reset it.
11907 * This is handled in the same way as restoration of the
11908 * PC in these situations; we save the value of the condexec bits
11909 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11910 * then uses this to restore them after an exception.
11912 * Note that there are no instructions which can read the condexec
11913 * bits, and none which can write non-static values to them, so
11914 * we don't need to care about whether CPUARMState is correct in the
11918 /* Reset the conditional execution bits immediately. This avoids
11919 complications trying to do it at the end of the block. */
11920 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11922 TCGv_i32 tmp
= tcg_temp_new_i32();
11923 tcg_gen_movi_i32(tmp
, 0);
11924 store_cpu_field(tmp
, condexec_bits
);
11927 dc
->insn_start_idx
= tcg_op_buf_count();
11928 tcg_gen_insn_start(dc
->pc
,
11929 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11933 #ifdef CONFIG_USER_ONLY
11934 /* Intercept jump to the magic kernel page. */
11935 if (dc
->pc
>= 0xffff0000) {
11936 /* We always get here via a jump, so know we are not in a
11937 conditional execution block. */
11938 gen_exception_internal(EXCP_KERNEL_TRAP
);
11939 dc
->is_jmp
= DISAS_EXC
;
11944 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11946 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11947 if (bp
->pc
== dc
->pc
) {
11948 if (bp
->flags
& BP_CPU
) {
11949 gen_set_condexec(dc
);
11950 gen_set_pc_im(dc
, dc
->pc
);
11951 gen_helper_check_breakpoints(cpu_env
);
11952 /* End the TB early; it's likely not going to be executed */
11953 dc
->is_jmp
= DISAS_UPDATE
;
11955 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11956 /* The address covered by the breakpoint must be
11957 included in [tb->pc, tb->pc + tb->size) in order
11958 to for it to be properly cleared -- thus we
11959 increment the PC here so that the logic setting
11960 tb->size below does the right thing. */
11961 /* TODO: Advance PC by correct instruction length to
11962 * avoid disassembler error messages */
11964 goto done_generating
;
11971 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11975 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11976 /* Singlestep state is Active-pending.
11977 * If we're in this state at the start of a TB then either
11978 * a) we just took an exception to an EL which is being debugged
11979 * and this is the first insn in the exception handler
11980 * b) debug exceptions were masked and we just unmasked them
11981 * without changing EL (eg by clearing PSTATE.D)
11982 * In either case we're going to take a swstep exception in the
11983 * "did not step an insn" case, and so the syndrome ISV and EX
11984 * bits should be zero.
11986 assert(num_insns
== 1);
11987 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11988 default_exception_el(dc
));
11989 goto done_generating
;
11993 disas_thumb_insn(env
, dc
);
11994 if (dc
->condexec_mask
) {
11995 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11996 | ((dc
->condexec_mask
>> 4) & 1);
11997 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11998 if (dc
->condexec_mask
== 0) {
11999 dc
->condexec_cond
= 0;
12003 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12005 disas_arm_insn(dc
, insn
);
12008 if (dc
->condjmp
&& !dc
->is_jmp
) {
12009 gen_set_label(dc
->condlabel
);
12013 if (tcg_check_temp_count()) {
12014 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
12018 /* Translation stops when a conditional branch is encountered.
12019 * Otherwise the subsequent code could get translated several times.
12020 * Also stop translation when a page boundary is reached. This
12021 * ensures prefetch aborts occur at the right place. */
12023 /* We want to stop the TB if the next insn starts in a new page,
12024 * or if it spans between this page and the next. This means that
12025 * if we're looking at the last halfword in the page we need to
12026 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12027 * or a 32-bit Thumb insn (which won't).
12028 * This is to avoid generating a silly TB with a single 16-bit insn
12029 * in it at the end of this page (which would execute correctly
12030 * but isn't very efficient).
12032 end_of_page
= (dc
->pc
>= next_page_start
) ||
12033 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
12035 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
12036 !is_singlestepping(dc
) &&
12039 num_insns
< max_insns
);
12041 if (tb
->cflags
& CF_LAST_IO
) {
12043 /* FIXME: This can theoretically happen with self-modifying
12045 cpu_abort(cs
, "IO on conditional branch instruction");
12050 /* At this stage dc->condjmp will only be set when the skipped
12051 instruction was a conditional branch or trap, and the PC has
12052 already been written. */
12053 gen_set_condexec(dc
);
12054 if (dc
->is_jmp
== DISAS_BX_EXCRET
) {
12055 /* Exception return branches need some special case code at the
12056 * end of the TB, which is complex enough that it has to
12057 * handle the single-step vs not and the condition-failed
12058 * insn codepath itself.
12060 gen_bx_excret_final_code(dc
);
12061 } else if (unlikely(is_singlestepping(dc
))) {
12062 /* Unconditional and "condition passed" instruction codepath. */
12063 switch (dc
->is_jmp
) {
12065 gen_ss_advance(dc
);
12066 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12067 default_exception_el(dc
));
12070 gen_ss_advance(dc
);
12071 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12074 gen_ss_advance(dc
);
12075 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12079 gen_set_pc_im(dc
, dc
->pc
);
12082 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12083 gen_singlestep_exception(dc
);
12086 /* While branches must always occur at the end of an IT block,
12087 there are a few other things that can cause us to terminate
12088 the TB in the middle of an IT block:
12089 - Exception generating instructions (bkpt, swi, undefined).
12091 - Hardware watchpoints.
12092 Hardware breakpoints have already been handled and skip this code.
12094 switch(dc
->is_jmp
) {
12096 gen_goto_tb(dc
, 1, dc
->pc
);
12099 gen_set_pc_im(dc
, dc
->pc
);
12105 /* indicate that the hash table must be used to find the next TB */
12106 tcg_gen_exit_tb(0);
12108 case DISAS_TB_JUMP
:
12110 /* nothing more to generate */
12113 gen_helper_wfi(cpu_env
);
12114 /* The helper doesn't necessarily throw an exception, but we
12115 * must go back to the main loop to check for interrupts anyway.
12117 tcg_gen_exit_tb(0);
12120 gen_helper_wfe(cpu_env
);
12123 gen_helper_yield(cpu_env
);
12126 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12127 default_exception_el(dc
));
12130 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12133 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12139 /* "Condition failed" instruction codepath for the branch/trap insn */
12140 gen_set_label(dc
->condlabel
);
12141 gen_set_condexec(dc
);
12142 if (unlikely(is_singlestepping(dc
))) {
12143 gen_set_pc_im(dc
, dc
->pc
);
12144 gen_singlestep_exception(dc
);
12146 gen_goto_tb(dc
, 1, dc
->pc
);
12151 gen_tb_end(tb
, num_insns
);
12154 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
) &&
12155 qemu_log_in_addr_range(pc_start
)) {
12157 qemu_log("----------------\n");
12158 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
12159 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
12160 dc
->thumb
| (dc
->sctlr_b
<< 1));
12165 tb
->size
= dc
->pc
- pc_start
;
12166 tb
->icount
= num_insns
;
12169 static const char *cpu_mode_names
[16] = {
12170 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12171 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12174 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12177 ARMCPU
*cpu
= ARM_CPU(cs
);
12178 CPUARMState
*env
= &cpu
->env
;
12181 const char *ns_status
;
12184 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12188 for(i
=0;i
<16;i
++) {
12189 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12191 cpu_fprintf(f
, "\n");
12193 cpu_fprintf(f
, " ");
12195 psr
= cpsr_read(env
);
12197 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12198 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12199 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12204 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12206 psr
& (1 << 31) ? 'N' : '-',
12207 psr
& (1 << 30) ? 'Z' : '-',
12208 psr
& (1 << 29) ? 'C' : '-',
12209 psr
& (1 << 28) ? 'V' : '-',
12210 psr
& CPSR_T
? 'T' : 'A',
12212 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12214 if (flags
& CPU_DUMP_FPU
) {
12215 int numvfpregs
= 0;
12216 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12219 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12222 for (i
= 0; i
< numvfpregs
; i
++) {
12223 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12224 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12225 i
* 2, (uint32_t)v
,
12226 i
* 2 + 1, (uint32_t)(v
>> 32),
12229 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12233 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12234 target_ulong
*data
)
12238 env
->condexec_bits
= 0;
12239 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12241 env
->regs
[15] = data
[0];
12242 env
->condexec_bits
= data
[1];
12243 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;