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
);
166 g_assert_not_reached();
170 static inline TCGv_i32
load_cpu_offset(int offset
)
172 TCGv_i32 tmp
= tcg_temp_new_i32();
173 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
177 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
179 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
181 tcg_gen_st_i32(var
, cpu_env
, offset
);
182 tcg_temp_free_i32(var
);
185 #define store_cpu_field(var, name) \
186 store_cpu_offset(var, offsetof(CPUARMState, name))
188 /* Set a variable to the value of a CPU register. */
189 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
193 /* normally, since we updated PC, we need only to add one insn */
195 addr
= (long)s
->pc
+ 2;
197 addr
= (long)s
->pc
+ 4;
198 tcg_gen_movi_i32(var
, addr
);
200 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
204 /* Create a new temporary and set it to the value of a CPU register. */
205 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
207 TCGv_i32 tmp
= tcg_temp_new_i32();
208 load_reg_var(s
, tmp
, reg
);
212 /* Set a CPU register. The source must be a temporary and will be
214 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
217 /* In Thumb mode, we must ignore bit 0.
218 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
219 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
220 * We choose to ignore [1:0] in ARM mode for all architecture versions.
222 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
223 s
->is_jmp
= DISAS_JUMP
;
225 tcg_gen_mov_i32(cpu_R
[reg
], var
);
226 tcg_temp_free_i32(var
);
229 /* Value extensions. */
230 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
231 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
232 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
233 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
235 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
236 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
239 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
241 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
242 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
243 tcg_temp_free_i32(tmp_mask
);
245 /* Set NZCV flags from the high 4 bits of var. */
246 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
248 static void gen_exception_internal(int excp
)
250 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
252 assert(excp_is_internal(excp
));
253 gen_helper_exception_internal(cpu_env
, tcg_excp
);
254 tcg_temp_free_i32(tcg_excp
);
257 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
259 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
260 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
261 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
263 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
266 tcg_temp_free_i32(tcg_el
);
267 tcg_temp_free_i32(tcg_syn
);
268 tcg_temp_free_i32(tcg_excp
);
271 static void gen_ss_advance(DisasContext
*s
)
273 /* If the singlestep state is Active-not-pending, advance to
278 gen_helper_clear_pstate_ss(cpu_env
);
282 static void gen_step_complete_exception(DisasContext
*s
)
284 /* We just completed step of an insn. Move from Active-not-pending
285 * to Active-pending, and then also take the swstep exception.
286 * This corresponds to making the (IMPDEF) choice to prioritize
287 * swstep exceptions over asynchronous exceptions taken to an exception
288 * level where debug is disabled. This choice has the advantage that
289 * we do not need to maintain internal state corresponding to the
290 * ISV/EX syndrome bits between completion of the step and generation
291 * of the exception, and our syndrome information is always correct.
294 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
295 default_exception_el(s
));
296 s
->is_jmp
= DISAS_EXC
;
299 static void gen_singlestep_exception(DisasContext
*s
)
301 /* Generate the right kind of exception for singlestep, which is
302 * either the architectural singlestep or EXCP_DEBUG for QEMU's
303 * gdb singlestepping.
306 gen_step_complete_exception(s
);
308 gen_exception_internal(EXCP_DEBUG
);
312 static inline bool is_singlestepping(DisasContext
*s
)
314 /* Return true if we are singlestepping either because of
315 * architectural singlestep or QEMU gdbstub singlestep. This does
316 * not include the command line '-singlestep' mode which is rather
317 * misnamed as it only means "one instruction per TB" and doesn't
318 * affect the code we generate.
320 return s
->singlestep_enabled
|| s
->ss_active
;
323 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
325 TCGv_i32 tmp1
= tcg_temp_new_i32();
326 TCGv_i32 tmp2
= tcg_temp_new_i32();
327 tcg_gen_ext16s_i32(tmp1
, a
);
328 tcg_gen_ext16s_i32(tmp2
, b
);
329 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
330 tcg_temp_free_i32(tmp2
);
331 tcg_gen_sari_i32(a
, a
, 16);
332 tcg_gen_sari_i32(b
, b
, 16);
333 tcg_gen_mul_i32(b
, b
, a
);
334 tcg_gen_mov_i32(a
, tmp1
);
335 tcg_temp_free_i32(tmp1
);
338 /* Byteswap each halfword. */
339 static void gen_rev16(TCGv_i32 var
)
341 TCGv_i32 tmp
= tcg_temp_new_i32();
342 tcg_gen_shri_i32(tmp
, var
, 8);
343 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
344 tcg_gen_shli_i32(var
, var
, 8);
345 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
346 tcg_gen_or_i32(var
, var
, tmp
);
347 tcg_temp_free_i32(tmp
);
350 /* Byteswap low halfword and sign extend. */
351 static void gen_revsh(TCGv_i32 var
)
353 tcg_gen_ext16u_i32(var
, var
);
354 tcg_gen_bswap16_i32(var
, var
);
355 tcg_gen_ext16s_i32(var
, var
);
358 /* Return (b << 32) + a. Mark inputs as dead */
359 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
361 TCGv_i64 tmp64
= tcg_temp_new_i64();
363 tcg_gen_extu_i32_i64(tmp64
, b
);
364 tcg_temp_free_i32(b
);
365 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
366 tcg_gen_add_i64(a
, tmp64
, a
);
368 tcg_temp_free_i64(tmp64
);
372 /* Return (b << 32) - a. Mark inputs as dead. */
373 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
375 TCGv_i64 tmp64
= tcg_temp_new_i64();
377 tcg_gen_extu_i32_i64(tmp64
, b
);
378 tcg_temp_free_i32(b
);
379 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
380 tcg_gen_sub_i64(a
, tmp64
, a
);
382 tcg_temp_free_i64(tmp64
);
386 /* 32x32->64 multiply. Marks inputs as dead. */
387 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
389 TCGv_i32 lo
= tcg_temp_new_i32();
390 TCGv_i32 hi
= tcg_temp_new_i32();
393 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
394 tcg_temp_free_i32(a
);
395 tcg_temp_free_i32(b
);
397 ret
= tcg_temp_new_i64();
398 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
399 tcg_temp_free_i32(lo
);
400 tcg_temp_free_i32(hi
);
405 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
407 TCGv_i32 lo
= tcg_temp_new_i32();
408 TCGv_i32 hi
= tcg_temp_new_i32();
411 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
412 tcg_temp_free_i32(a
);
413 tcg_temp_free_i32(b
);
415 ret
= tcg_temp_new_i64();
416 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
417 tcg_temp_free_i32(lo
);
418 tcg_temp_free_i32(hi
);
423 /* Swap low and high halfwords. */
424 static void gen_swap_half(TCGv_i32 var
)
426 TCGv_i32 tmp
= tcg_temp_new_i32();
427 tcg_gen_shri_i32(tmp
, var
, 16);
428 tcg_gen_shli_i32(var
, var
, 16);
429 tcg_gen_or_i32(var
, var
, tmp
);
430 tcg_temp_free_i32(tmp
);
433 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
434 tmp = (t0 ^ t1) & 0x8000;
437 t0 = (t0 + t1) ^ tmp;
440 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
442 TCGv_i32 tmp
= tcg_temp_new_i32();
443 tcg_gen_xor_i32(tmp
, t0
, t1
);
444 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
445 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
446 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
447 tcg_gen_add_i32(t0
, t0
, t1
);
448 tcg_gen_xor_i32(t0
, t0
, tmp
);
449 tcg_temp_free_i32(tmp
);
450 tcg_temp_free_i32(t1
);
453 /* Set CF to the top bit of var. */
454 static void gen_set_CF_bit31(TCGv_i32 var
)
456 tcg_gen_shri_i32(cpu_CF
, var
, 31);
459 /* Set N and Z flags from var. */
460 static inline void gen_logic_CC(TCGv_i32 var
)
462 tcg_gen_mov_i32(cpu_NF
, var
);
463 tcg_gen_mov_i32(cpu_ZF
, var
);
467 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
469 tcg_gen_add_i32(t0
, t0
, t1
);
470 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
473 /* dest = T0 + T1 + CF. */
474 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
476 tcg_gen_add_i32(dest
, t0
, t1
);
477 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
480 /* dest = T0 - T1 + CF - 1. */
481 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
483 tcg_gen_sub_i32(dest
, t0
, t1
);
484 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
485 tcg_gen_subi_i32(dest
, dest
, 1);
488 /* dest = T0 + T1. Compute C, N, V and Z flags */
489 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
491 TCGv_i32 tmp
= tcg_temp_new_i32();
492 tcg_gen_movi_i32(tmp
, 0);
493 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
494 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
495 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
496 tcg_gen_xor_i32(tmp
, t0
, t1
);
497 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
498 tcg_temp_free_i32(tmp
);
499 tcg_gen_mov_i32(dest
, cpu_NF
);
502 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
503 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
505 TCGv_i32 tmp
= tcg_temp_new_i32();
506 if (TCG_TARGET_HAS_add2_i32
) {
507 tcg_gen_movi_i32(tmp
, 0);
508 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
509 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
511 TCGv_i64 q0
= tcg_temp_new_i64();
512 TCGv_i64 q1
= tcg_temp_new_i64();
513 tcg_gen_extu_i32_i64(q0
, t0
);
514 tcg_gen_extu_i32_i64(q1
, t1
);
515 tcg_gen_add_i64(q0
, q0
, q1
);
516 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
517 tcg_gen_add_i64(q0
, q0
, q1
);
518 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
519 tcg_temp_free_i64(q0
);
520 tcg_temp_free_i64(q1
);
522 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
523 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
524 tcg_gen_xor_i32(tmp
, t0
, t1
);
525 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
526 tcg_temp_free_i32(tmp
);
527 tcg_gen_mov_i32(dest
, cpu_NF
);
530 /* dest = T0 - T1. Compute C, N, V and Z flags */
531 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
534 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
535 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
536 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
537 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
538 tmp
= tcg_temp_new_i32();
539 tcg_gen_xor_i32(tmp
, t0
, t1
);
540 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
541 tcg_temp_free_i32(tmp
);
542 tcg_gen_mov_i32(dest
, cpu_NF
);
545 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
546 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
548 TCGv_i32 tmp
= tcg_temp_new_i32();
549 tcg_gen_not_i32(tmp
, t1
);
550 gen_adc_CC(dest
, t0
, tmp
);
551 tcg_temp_free_i32(tmp
);
554 #define GEN_SHIFT(name) \
555 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
557 TCGv_i32 tmp1, tmp2, tmp3; \
558 tmp1 = tcg_temp_new_i32(); \
559 tcg_gen_andi_i32(tmp1, t1, 0xff); \
560 tmp2 = tcg_const_i32(0); \
561 tmp3 = tcg_const_i32(0x1f); \
562 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
563 tcg_temp_free_i32(tmp3); \
564 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
565 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
566 tcg_temp_free_i32(tmp2); \
567 tcg_temp_free_i32(tmp1); \
573 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
576 tmp1
= tcg_temp_new_i32();
577 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
578 tmp2
= tcg_const_i32(0x1f);
579 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
580 tcg_temp_free_i32(tmp2
);
581 tcg_gen_sar_i32(dest
, t0
, tmp1
);
582 tcg_temp_free_i32(tmp1
);
585 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
587 TCGv_i32 c0
= tcg_const_i32(0);
588 TCGv_i32 tmp
= tcg_temp_new_i32();
589 tcg_gen_neg_i32(tmp
, src
);
590 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
591 tcg_temp_free_i32(c0
);
592 tcg_temp_free_i32(tmp
);
595 static void shifter_out_im(TCGv_i32 var
, int shift
)
598 tcg_gen_andi_i32(cpu_CF
, var
, 1);
600 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
602 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
607 /* Shift by immediate. Includes special handling for shift == 0. */
608 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
609 int shift
, int flags
)
615 shifter_out_im(var
, 32 - shift
);
616 tcg_gen_shli_i32(var
, var
, shift
);
622 tcg_gen_shri_i32(cpu_CF
, var
, 31);
624 tcg_gen_movi_i32(var
, 0);
627 shifter_out_im(var
, shift
- 1);
628 tcg_gen_shri_i32(var
, var
, shift
);
635 shifter_out_im(var
, shift
- 1);
638 tcg_gen_sari_i32(var
, var
, shift
);
640 case 3: /* ROR/RRX */
643 shifter_out_im(var
, shift
- 1);
644 tcg_gen_rotri_i32(var
, var
, shift
); break;
646 TCGv_i32 tmp
= tcg_temp_new_i32();
647 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
649 shifter_out_im(var
, 0);
650 tcg_gen_shri_i32(var
, var
, 1);
651 tcg_gen_or_i32(var
, var
, tmp
);
652 tcg_temp_free_i32(tmp
);
657 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
658 TCGv_i32 shift
, int flags
)
662 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
663 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
664 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
665 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
670 gen_shl(var
, var
, shift
);
673 gen_shr(var
, var
, shift
);
676 gen_sar(var
, var
, shift
);
678 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
679 tcg_gen_rotr_i32(var
, var
, shift
); break;
682 tcg_temp_free_i32(shift
);
685 #define PAS_OP(pfx) \
687 case 0: gen_pas_helper(glue(pfx,add16)); break; \
688 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
689 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
690 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
691 case 4: gen_pas_helper(glue(pfx,add8)); break; \
692 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
694 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
699 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
701 tmp
= tcg_temp_new_ptr();
702 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
704 tcg_temp_free_ptr(tmp
);
707 tmp
= tcg_temp_new_ptr();
708 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
710 tcg_temp_free_ptr(tmp
);
712 #undef gen_pas_helper
713 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
726 #undef gen_pas_helper
731 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
732 #define PAS_OP(pfx) \
734 case 0: gen_pas_helper(glue(pfx,add8)); break; \
735 case 1: gen_pas_helper(glue(pfx,add16)); break; \
736 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
737 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
738 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
739 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
741 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
746 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
748 tmp
= tcg_temp_new_ptr();
749 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
751 tcg_temp_free_ptr(tmp
);
754 tmp
= tcg_temp_new_ptr();
755 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
757 tcg_temp_free_ptr(tmp
);
759 #undef gen_pas_helper
760 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
773 #undef gen_pas_helper
779 * Generate a conditional based on ARM condition code cc.
780 * This is common between ARM and Aarch64 targets.
782 void arm_test_cc(DisasCompare
*cmp
, int cc
)
813 case 8: /* hi: C && !Z */
814 case 9: /* ls: !C || Z -> !(C && !Z) */
816 value
= tcg_temp_new_i32();
818 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
819 ZF is non-zero for !Z; so AND the two subexpressions. */
820 tcg_gen_neg_i32(value
, cpu_CF
);
821 tcg_gen_and_i32(value
, value
, cpu_ZF
);
824 case 10: /* ge: N == V -> N ^ V == 0 */
825 case 11: /* lt: N != V -> N ^ V != 0 */
826 /* Since we're only interested in the sign bit, == 0 is >= 0. */
828 value
= tcg_temp_new_i32();
830 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
833 case 12: /* gt: !Z && N == V */
834 case 13: /* le: Z || N != V */
836 value
= tcg_temp_new_i32();
838 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
839 * the sign bit then AND with ZF to yield the result. */
840 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
841 tcg_gen_sari_i32(value
, value
, 31);
842 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
845 case 14: /* always */
846 case 15: /* always */
847 /* Use the ALWAYS condition, which will fold early.
848 * It doesn't matter what we use for the value. */
849 cond
= TCG_COND_ALWAYS
;
854 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
859 cond
= tcg_invert_cond(cond
);
865 cmp
->value_global
= global
;
868 void arm_free_cc(DisasCompare
*cmp
)
870 if (!cmp
->value_global
) {
871 tcg_temp_free_i32(cmp
->value
);
875 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
877 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
880 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
883 arm_test_cc(&cmp
, cc
);
884 arm_jump_cc(&cmp
, label
);
888 static const uint8_t table_logic_cc
[16] = {
907 static inline void gen_set_condexec(DisasContext
*s
)
909 if (s
->condexec_mask
) {
910 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
911 TCGv_i32 tmp
= tcg_temp_new_i32();
912 tcg_gen_movi_i32(tmp
, val
);
913 store_cpu_field(tmp
, condexec_bits
);
917 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
919 tcg_gen_movi_i32(cpu_R
[15], val
);
922 /* Set PC and Thumb state from an immediate address. */
923 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
927 s
->is_jmp
= DISAS_JUMP
;
928 if (s
->thumb
!= (addr
& 1)) {
929 tmp
= tcg_temp_new_i32();
930 tcg_gen_movi_i32(tmp
, addr
& 1);
931 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
932 tcg_temp_free_i32(tmp
);
934 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
937 /* Set PC and Thumb state from var. var is marked as dead. */
938 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
940 s
->is_jmp
= DISAS_JUMP
;
941 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
942 tcg_gen_andi_i32(var
, var
, 1);
943 store_cpu_field(var
, thumb
);
946 /* Set PC and Thumb state from var. var is marked as dead.
947 * For M-profile CPUs, include logic to detect exception-return
948 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
949 * and BX reg, and no others, and happens only for code in Handler mode.
951 static inline void gen_bx_excret(DisasContext
*s
, TCGv_i32 var
)
953 /* Generate the same code here as for a simple bx, but flag via
954 * s->is_jmp that we need to do the rest of the work later.
957 if (s
->v7m_handler_mode
&& arm_dc_feature(s
, ARM_FEATURE_M
)) {
958 s
->is_jmp
= DISAS_BX_EXCRET
;
962 static inline void gen_bx_excret_final_code(DisasContext
*s
)
964 /* Generate the code to finish possible exception return and end the TB */
965 TCGLabel
*excret_label
= gen_new_label();
967 /* Is the new PC value in the magic range indicating exception return? */
968 tcg_gen_brcondi_i32(TCG_COND_GEU
, cpu_R
[15], 0xff000000, excret_label
);
969 /* No: end the TB as we would for a DISAS_JMP */
970 if (is_singlestepping(s
)) {
971 gen_singlestep_exception(s
);
975 gen_set_label(excret_label
);
976 /* Yes: this is an exception return.
977 * At this point in runtime env->regs[15] and env->thumb will hold
978 * the exception-return magic number, which do_v7m_exception_exit()
979 * will read. Nothing else will be able to see those values because
980 * the cpu-exec main loop guarantees that we will always go straight
981 * from raising the exception to the exception-handling code.
983 * gen_ss_advance(s) does nothing on M profile currently but
984 * calling it is conceptually the right thing as we have executed
985 * this instruction (compare SWI, HVC, SMC handling).
988 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
991 /* Variant of store_reg which uses branch&exchange logic when storing
992 to r15 in ARM architecture v7 and above. The source must be a temporary
993 and will be marked as dead. */
994 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
996 if (reg
== 15 && ENABLE_ARCH_7
) {
999 store_reg(s
, reg
, var
);
1003 /* Variant of store_reg which uses branch&exchange logic when storing
1004 * to r15 in ARM architecture v5T and above. This is used for storing
1005 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1006 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1007 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
1009 if (reg
== 15 && ENABLE_ARCH_5
) {
1010 gen_bx_excret(s
, var
);
1012 store_reg(s
, reg
, var
);
1016 #ifdef CONFIG_USER_ONLY
1017 #define IS_USER_ONLY 1
1019 #define IS_USER_ONLY 0
1022 /* Abstractions of "generate code to do a guest load/store for
1023 * AArch32", where a vaddr is always 32 bits (and is zero
1024 * extended if we're a 64 bit core) and data is also
1025 * 32 bits unless specifically doing a 64 bit access.
1026 * These functions work like tcg_gen_qemu_{ld,st}* except
1027 * that the address argument is TCGv_i32 rather than TCGv.
1030 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, TCGMemOp op
)
1032 TCGv addr
= tcg_temp_new();
1033 tcg_gen_extu_i32_tl(addr
, a32
);
1035 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1036 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
1037 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
1042 static void gen_aa32_ld_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1043 int index
, TCGMemOp opc
)
1045 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1046 tcg_gen_qemu_ld_i32(val
, addr
, index
, opc
);
1047 tcg_temp_free(addr
);
1050 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1051 int index
, TCGMemOp opc
)
1053 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1054 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
1055 tcg_temp_free(addr
);
1058 #define DO_GEN_LD(SUFF, OPC) \
1059 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1060 TCGv_i32 a32, int index) \
1062 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1064 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1066 TCGv_i32 a32, int index, \
1069 gen_aa32_ld##SUFF(s, val, a32, index); \
1070 disas_set_da_iss(s, OPC, issinfo); \
1073 #define DO_GEN_ST(SUFF, OPC) \
1074 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1075 TCGv_i32 a32, int index) \
1077 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1079 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1081 TCGv_i32 a32, int index, \
1084 gen_aa32_st##SUFF(s, val, a32, index); \
1085 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1088 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
1090 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1091 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1092 tcg_gen_rotri_i64(val
, val
, 32);
1096 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1097 int index
, TCGMemOp opc
)
1099 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1100 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
1101 gen_aa32_frob64(s
, val
);
1102 tcg_temp_free(addr
);
1105 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1106 TCGv_i32 a32
, int index
)
1108 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1111 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1112 int index
, TCGMemOp opc
)
1114 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1116 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1117 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1118 TCGv_i64 tmp
= tcg_temp_new_i64();
1119 tcg_gen_rotri_i64(tmp
, val
, 32);
1120 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
1121 tcg_temp_free_i64(tmp
);
1123 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
1125 tcg_temp_free(addr
);
1128 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1129 TCGv_i32 a32
, int index
)
1131 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1134 DO_GEN_LD(8s
, MO_SB
)
1135 DO_GEN_LD(8u, MO_UB
)
1136 DO_GEN_LD(16s
, MO_SW
)
1137 DO_GEN_LD(16u, MO_UW
)
1138 DO_GEN_LD(32u, MO_UL
)
1140 DO_GEN_ST(16, MO_UW
)
1141 DO_GEN_ST(32, MO_UL
)
1143 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1145 /* The pre HVC helper handles cases when HVC gets trapped
1146 * as an undefined insn by runtime configuration (ie before
1147 * the insn really executes).
1149 gen_set_pc_im(s
, s
->pc
- 4);
1150 gen_helper_pre_hvc(cpu_env
);
1151 /* Otherwise we will treat this as a real exception which
1152 * happens after execution of the insn. (The distinction matters
1153 * for the PC value reported to the exception handler and also
1154 * for single stepping.)
1157 gen_set_pc_im(s
, s
->pc
);
1158 s
->is_jmp
= DISAS_HVC
;
1161 static inline void gen_smc(DisasContext
*s
)
1163 /* As with HVC, we may take an exception either before or after
1164 * the insn executes.
1168 gen_set_pc_im(s
, s
->pc
- 4);
1169 tmp
= tcg_const_i32(syn_aa32_smc());
1170 gen_helper_pre_smc(cpu_env
, tmp
);
1171 tcg_temp_free_i32(tmp
);
1172 gen_set_pc_im(s
, s
->pc
);
1173 s
->is_jmp
= DISAS_SMC
;
1176 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1178 gen_set_condexec(s
);
1179 gen_set_pc_im(s
, s
->pc
- offset
);
1180 gen_exception_internal(excp
);
1181 s
->is_jmp
= DISAS_JUMP
;
1184 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1185 int syn
, uint32_t target_el
)
1187 gen_set_condexec(s
);
1188 gen_set_pc_im(s
, s
->pc
- offset
);
1189 gen_exception(excp
, syn
, target_el
);
1190 s
->is_jmp
= DISAS_JUMP
;
1193 /* Force a TB lookup after an instruction that changes the CPU state. */
1194 static inline void gen_lookup_tb(DisasContext
*s
)
1196 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1197 s
->is_jmp
= DISAS_JUMP
;
1200 static inline void gen_hlt(DisasContext
*s
, int imm
)
1202 /* HLT. This has two purposes.
1203 * Architecturally, it is an external halting debug instruction.
1204 * Since QEMU doesn't implement external debug, we treat this as
1205 * it is required for halting debug disabled: it will UNDEF.
1206 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1207 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1208 * must trigger semihosting even for ARMv7 and earlier, where
1209 * HLT was an undefined encoding.
1210 * In system mode, we don't allow userspace access to
1211 * semihosting, to provide some semblance of security
1212 * (and for consistency with our 32-bit semihosting).
1214 if (semihosting_enabled() &&
1215 #ifndef CONFIG_USER_ONLY
1216 s
->current_el
!= 0 &&
1218 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1219 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1223 gen_exception_insn(s
, s
->thumb
? 2 : 4, EXCP_UDEF
, syn_uncategorized(),
1224 default_exception_el(s
));
1227 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1230 int val
, rm
, shift
, shiftop
;
1233 if (!(insn
& (1 << 25))) {
1236 if (!(insn
& (1 << 23)))
1239 tcg_gen_addi_i32(var
, var
, val
);
1241 /* shift/register */
1243 shift
= (insn
>> 7) & 0x1f;
1244 shiftop
= (insn
>> 5) & 3;
1245 offset
= load_reg(s
, rm
);
1246 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1247 if (!(insn
& (1 << 23)))
1248 tcg_gen_sub_i32(var
, var
, offset
);
1250 tcg_gen_add_i32(var
, var
, offset
);
1251 tcg_temp_free_i32(offset
);
1255 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1256 int extra
, TCGv_i32 var
)
1261 if (insn
& (1 << 22)) {
1263 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1264 if (!(insn
& (1 << 23)))
1268 tcg_gen_addi_i32(var
, var
, val
);
1272 tcg_gen_addi_i32(var
, var
, extra
);
1274 offset
= load_reg(s
, rm
);
1275 if (!(insn
& (1 << 23)))
1276 tcg_gen_sub_i32(var
, var
, offset
);
1278 tcg_gen_add_i32(var
, var
, offset
);
1279 tcg_temp_free_i32(offset
);
1283 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1285 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1288 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1290 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1292 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1296 #define VFP_OP2(name) \
1297 static inline void gen_vfp_##name(int dp) \
1299 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1301 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1303 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1305 tcg_temp_free_ptr(fpst); \
1315 static inline void gen_vfp_F1_mul(int dp
)
1317 /* Like gen_vfp_mul() but put result in F1 */
1318 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1320 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1322 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1324 tcg_temp_free_ptr(fpst
);
1327 static inline void gen_vfp_F1_neg(int dp
)
1329 /* Like gen_vfp_neg() but put result in F1 */
1331 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1333 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1337 static inline void gen_vfp_abs(int dp
)
1340 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1342 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1345 static inline void gen_vfp_neg(int dp
)
1348 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1350 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1353 static inline void gen_vfp_sqrt(int dp
)
1356 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1358 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1361 static inline void gen_vfp_cmp(int dp
)
1364 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1366 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1369 static inline void gen_vfp_cmpe(int dp
)
1372 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1374 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1377 static inline void gen_vfp_F1_ld0(int dp
)
1380 tcg_gen_movi_i64(cpu_F1d
, 0);
1382 tcg_gen_movi_i32(cpu_F1s
, 0);
1385 #define VFP_GEN_ITOF(name) \
1386 static inline void gen_vfp_##name(int dp, int neon) \
1388 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1390 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1392 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1394 tcg_temp_free_ptr(statusptr); \
1401 #define VFP_GEN_FTOI(name) \
1402 static inline void gen_vfp_##name(int dp, int neon) \
1404 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1406 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1408 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1410 tcg_temp_free_ptr(statusptr); \
1419 #define VFP_GEN_FIX(name, round) \
1420 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1422 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1423 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1425 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1428 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1431 tcg_temp_free_i32(tmp_shift); \
1432 tcg_temp_free_ptr(statusptr); \
1434 VFP_GEN_FIX(tosh
, _round_to_zero
)
1435 VFP_GEN_FIX(tosl
, _round_to_zero
)
1436 VFP_GEN_FIX(touh
, _round_to_zero
)
1437 VFP_GEN_FIX(toul
, _round_to_zero
)
1444 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1447 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1449 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1453 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1456 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1458 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1463 vfp_reg_offset (int dp
, int reg
)
1466 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1468 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1469 + offsetof(CPU_DoubleU
, l
.upper
);
1471 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1472 + offsetof(CPU_DoubleU
, l
.lower
);
1476 /* Return the offset of a 32-bit piece of a NEON register.
1477 zero is the least significant end of the register. */
1479 neon_reg_offset (int reg
, int n
)
1483 return vfp_reg_offset(0, sreg
);
1486 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1488 TCGv_i32 tmp
= tcg_temp_new_i32();
1489 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1493 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1495 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1496 tcg_temp_free_i32(var
);
1499 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1501 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1504 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1506 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1509 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1510 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1511 #define tcg_gen_st_f32 tcg_gen_st_i32
1512 #define tcg_gen_st_f64 tcg_gen_st_i64
1514 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1517 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1519 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1522 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1525 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1527 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1530 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1533 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1535 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1538 #define ARM_CP_RW_BIT (1 << 20)
1540 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1542 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1545 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1547 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1550 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1552 TCGv_i32 var
= tcg_temp_new_i32();
1553 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1557 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1559 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1560 tcg_temp_free_i32(var
);
1563 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1565 iwmmxt_store_reg(cpu_M0
, rn
);
1568 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1570 iwmmxt_load_reg(cpu_M0
, rn
);
1573 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1575 iwmmxt_load_reg(cpu_V1
, rn
);
1576 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1579 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1581 iwmmxt_load_reg(cpu_V1
, rn
);
1582 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1585 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1587 iwmmxt_load_reg(cpu_V1
, rn
);
1588 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1591 #define IWMMXT_OP(name) \
1592 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1594 iwmmxt_load_reg(cpu_V1, rn); \
1595 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1598 #define IWMMXT_OP_ENV(name) \
1599 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1601 iwmmxt_load_reg(cpu_V1, rn); \
1602 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1605 #define IWMMXT_OP_ENV_SIZE(name) \
1606 IWMMXT_OP_ENV(name##b) \
1607 IWMMXT_OP_ENV(name##w) \
1608 IWMMXT_OP_ENV(name##l)
1610 #define IWMMXT_OP_ENV1(name) \
1611 static inline void gen_op_iwmmxt_##name##_M0(void) \
1613 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1627 IWMMXT_OP_ENV_SIZE(unpackl
)
1628 IWMMXT_OP_ENV_SIZE(unpackh
)
1630 IWMMXT_OP_ENV1(unpacklub
)
1631 IWMMXT_OP_ENV1(unpackluw
)
1632 IWMMXT_OP_ENV1(unpacklul
)
1633 IWMMXT_OP_ENV1(unpackhub
)
1634 IWMMXT_OP_ENV1(unpackhuw
)
1635 IWMMXT_OP_ENV1(unpackhul
)
1636 IWMMXT_OP_ENV1(unpacklsb
)
1637 IWMMXT_OP_ENV1(unpacklsw
)
1638 IWMMXT_OP_ENV1(unpacklsl
)
1639 IWMMXT_OP_ENV1(unpackhsb
)
1640 IWMMXT_OP_ENV1(unpackhsw
)
1641 IWMMXT_OP_ENV1(unpackhsl
)
1643 IWMMXT_OP_ENV_SIZE(cmpeq
)
1644 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1645 IWMMXT_OP_ENV_SIZE(cmpgts
)
1647 IWMMXT_OP_ENV_SIZE(mins
)
1648 IWMMXT_OP_ENV_SIZE(minu
)
1649 IWMMXT_OP_ENV_SIZE(maxs
)
1650 IWMMXT_OP_ENV_SIZE(maxu
)
1652 IWMMXT_OP_ENV_SIZE(subn
)
1653 IWMMXT_OP_ENV_SIZE(addn
)
1654 IWMMXT_OP_ENV_SIZE(subu
)
1655 IWMMXT_OP_ENV_SIZE(addu
)
1656 IWMMXT_OP_ENV_SIZE(subs
)
1657 IWMMXT_OP_ENV_SIZE(adds
)
1659 IWMMXT_OP_ENV(avgb0
)
1660 IWMMXT_OP_ENV(avgb1
)
1661 IWMMXT_OP_ENV(avgw0
)
1662 IWMMXT_OP_ENV(avgw1
)
1664 IWMMXT_OP_ENV(packuw
)
1665 IWMMXT_OP_ENV(packul
)
1666 IWMMXT_OP_ENV(packuq
)
1667 IWMMXT_OP_ENV(packsw
)
1668 IWMMXT_OP_ENV(packsl
)
1669 IWMMXT_OP_ENV(packsq
)
1671 static void gen_op_iwmmxt_set_mup(void)
1674 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1675 tcg_gen_ori_i32(tmp
, tmp
, 2);
1676 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1679 static void gen_op_iwmmxt_set_cup(void)
1682 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1683 tcg_gen_ori_i32(tmp
, tmp
, 1);
1684 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1687 static void gen_op_iwmmxt_setpsr_nz(void)
1689 TCGv_i32 tmp
= tcg_temp_new_i32();
1690 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1691 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1694 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1696 iwmmxt_load_reg(cpu_V1
, rn
);
1697 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1698 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1701 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1708 rd
= (insn
>> 16) & 0xf;
1709 tmp
= load_reg(s
, rd
);
1711 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1712 if (insn
& (1 << 24)) {
1714 if (insn
& (1 << 23))
1715 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1717 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1718 tcg_gen_mov_i32(dest
, tmp
);
1719 if (insn
& (1 << 21))
1720 store_reg(s
, rd
, tmp
);
1722 tcg_temp_free_i32(tmp
);
1723 } else if (insn
& (1 << 21)) {
1725 tcg_gen_mov_i32(dest
, tmp
);
1726 if (insn
& (1 << 23))
1727 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1729 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1730 store_reg(s
, rd
, tmp
);
1731 } else if (!(insn
& (1 << 23)))
1736 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1738 int rd
= (insn
>> 0) & 0xf;
1741 if (insn
& (1 << 8)) {
1742 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1745 tmp
= iwmmxt_load_creg(rd
);
1748 tmp
= tcg_temp_new_i32();
1749 iwmmxt_load_reg(cpu_V0
, rd
);
1750 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1752 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1753 tcg_gen_mov_i32(dest
, tmp
);
1754 tcg_temp_free_i32(tmp
);
1758 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1759 (ie. an undefined instruction). */
1760 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1763 int rdhi
, rdlo
, rd0
, rd1
, i
;
1765 TCGv_i32 tmp
, tmp2
, tmp3
;
1767 if ((insn
& 0x0e000e00) == 0x0c000000) {
1768 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1770 rdlo
= (insn
>> 12) & 0xf;
1771 rdhi
= (insn
>> 16) & 0xf;
1772 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1773 iwmmxt_load_reg(cpu_V0
, wrd
);
1774 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1775 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1776 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1777 } else { /* TMCRR */
1778 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1779 iwmmxt_store_reg(cpu_V0
, wrd
);
1780 gen_op_iwmmxt_set_mup();
1785 wrd
= (insn
>> 12) & 0xf;
1786 addr
= tcg_temp_new_i32();
1787 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1788 tcg_temp_free_i32(addr
);
1791 if (insn
& ARM_CP_RW_BIT
) {
1792 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1793 tmp
= tcg_temp_new_i32();
1794 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1795 iwmmxt_store_creg(wrd
, tmp
);
1798 if (insn
& (1 << 8)) {
1799 if (insn
& (1 << 22)) { /* WLDRD */
1800 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1802 } else { /* WLDRW wRd */
1803 tmp
= tcg_temp_new_i32();
1804 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1807 tmp
= tcg_temp_new_i32();
1808 if (insn
& (1 << 22)) { /* WLDRH */
1809 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1810 } else { /* WLDRB */
1811 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1815 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1816 tcg_temp_free_i32(tmp
);
1818 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1821 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1822 tmp
= iwmmxt_load_creg(wrd
);
1823 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1825 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1826 tmp
= tcg_temp_new_i32();
1827 if (insn
& (1 << 8)) {
1828 if (insn
& (1 << 22)) { /* WSTRD */
1829 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1830 } else { /* WSTRW wRd */
1831 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1832 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1835 if (insn
& (1 << 22)) { /* WSTRH */
1836 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1837 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1838 } else { /* WSTRB */
1839 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1840 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1844 tcg_temp_free_i32(tmp
);
1846 tcg_temp_free_i32(addr
);
1850 if ((insn
& 0x0f000000) != 0x0e000000)
1853 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1854 case 0x000: /* WOR */
1855 wrd
= (insn
>> 12) & 0xf;
1856 rd0
= (insn
>> 0) & 0xf;
1857 rd1
= (insn
>> 16) & 0xf;
1858 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1859 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1860 gen_op_iwmmxt_setpsr_nz();
1861 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1862 gen_op_iwmmxt_set_mup();
1863 gen_op_iwmmxt_set_cup();
1865 case 0x011: /* TMCR */
1868 rd
= (insn
>> 12) & 0xf;
1869 wrd
= (insn
>> 16) & 0xf;
1871 case ARM_IWMMXT_wCID
:
1872 case ARM_IWMMXT_wCASF
:
1874 case ARM_IWMMXT_wCon
:
1875 gen_op_iwmmxt_set_cup();
1877 case ARM_IWMMXT_wCSSF
:
1878 tmp
= iwmmxt_load_creg(wrd
);
1879 tmp2
= load_reg(s
, rd
);
1880 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1881 tcg_temp_free_i32(tmp2
);
1882 iwmmxt_store_creg(wrd
, tmp
);
1884 case ARM_IWMMXT_wCGR0
:
1885 case ARM_IWMMXT_wCGR1
:
1886 case ARM_IWMMXT_wCGR2
:
1887 case ARM_IWMMXT_wCGR3
:
1888 gen_op_iwmmxt_set_cup();
1889 tmp
= load_reg(s
, rd
);
1890 iwmmxt_store_creg(wrd
, tmp
);
1896 case 0x100: /* WXOR */
1897 wrd
= (insn
>> 12) & 0xf;
1898 rd0
= (insn
>> 0) & 0xf;
1899 rd1
= (insn
>> 16) & 0xf;
1900 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1901 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1902 gen_op_iwmmxt_setpsr_nz();
1903 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1904 gen_op_iwmmxt_set_mup();
1905 gen_op_iwmmxt_set_cup();
1907 case 0x111: /* TMRC */
1910 rd
= (insn
>> 12) & 0xf;
1911 wrd
= (insn
>> 16) & 0xf;
1912 tmp
= iwmmxt_load_creg(wrd
);
1913 store_reg(s
, rd
, tmp
);
1915 case 0x300: /* WANDN */
1916 wrd
= (insn
>> 12) & 0xf;
1917 rd0
= (insn
>> 0) & 0xf;
1918 rd1
= (insn
>> 16) & 0xf;
1919 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1920 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1921 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1922 gen_op_iwmmxt_setpsr_nz();
1923 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1924 gen_op_iwmmxt_set_mup();
1925 gen_op_iwmmxt_set_cup();
1927 case 0x200: /* WAND */
1928 wrd
= (insn
>> 12) & 0xf;
1929 rd0
= (insn
>> 0) & 0xf;
1930 rd1
= (insn
>> 16) & 0xf;
1931 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1932 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1933 gen_op_iwmmxt_setpsr_nz();
1934 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1935 gen_op_iwmmxt_set_mup();
1936 gen_op_iwmmxt_set_cup();
1938 case 0x810: case 0xa10: /* WMADD */
1939 wrd
= (insn
>> 12) & 0xf;
1940 rd0
= (insn
>> 0) & 0xf;
1941 rd1
= (insn
>> 16) & 0xf;
1942 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1943 if (insn
& (1 << 21))
1944 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1946 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1947 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1948 gen_op_iwmmxt_set_mup();
1950 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1951 wrd
= (insn
>> 12) & 0xf;
1952 rd0
= (insn
>> 16) & 0xf;
1953 rd1
= (insn
>> 0) & 0xf;
1954 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1955 switch ((insn
>> 22) & 3) {
1957 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1960 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1963 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1968 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1969 gen_op_iwmmxt_set_mup();
1970 gen_op_iwmmxt_set_cup();
1972 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1973 wrd
= (insn
>> 12) & 0xf;
1974 rd0
= (insn
>> 16) & 0xf;
1975 rd1
= (insn
>> 0) & 0xf;
1976 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1977 switch ((insn
>> 22) & 3) {
1979 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1982 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1985 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1990 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1991 gen_op_iwmmxt_set_mup();
1992 gen_op_iwmmxt_set_cup();
1994 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1995 wrd
= (insn
>> 12) & 0xf;
1996 rd0
= (insn
>> 16) & 0xf;
1997 rd1
= (insn
>> 0) & 0xf;
1998 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1999 if (insn
& (1 << 22))
2000 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2002 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2003 if (!(insn
& (1 << 20)))
2004 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2005 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2006 gen_op_iwmmxt_set_mup();
2008 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2009 wrd
= (insn
>> 12) & 0xf;
2010 rd0
= (insn
>> 16) & 0xf;
2011 rd1
= (insn
>> 0) & 0xf;
2012 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2013 if (insn
& (1 << 21)) {
2014 if (insn
& (1 << 20))
2015 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2017 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2019 if (insn
& (1 << 20))
2020 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2022 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2024 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2025 gen_op_iwmmxt_set_mup();
2027 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2028 wrd
= (insn
>> 12) & 0xf;
2029 rd0
= (insn
>> 16) & 0xf;
2030 rd1
= (insn
>> 0) & 0xf;
2031 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2032 if (insn
& (1 << 21))
2033 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2035 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2036 if (!(insn
& (1 << 20))) {
2037 iwmmxt_load_reg(cpu_V1
, wrd
);
2038 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2040 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2041 gen_op_iwmmxt_set_mup();
2043 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2044 wrd
= (insn
>> 12) & 0xf;
2045 rd0
= (insn
>> 16) & 0xf;
2046 rd1
= (insn
>> 0) & 0xf;
2047 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2048 switch ((insn
>> 22) & 3) {
2050 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2053 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2056 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2061 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2062 gen_op_iwmmxt_set_mup();
2063 gen_op_iwmmxt_set_cup();
2065 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2066 wrd
= (insn
>> 12) & 0xf;
2067 rd0
= (insn
>> 16) & 0xf;
2068 rd1
= (insn
>> 0) & 0xf;
2069 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2070 if (insn
& (1 << 22)) {
2071 if (insn
& (1 << 20))
2072 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2074 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2076 if (insn
& (1 << 20))
2077 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2079 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2081 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2082 gen_op_iwmmxt_set_mup();
2083 gen_op_iwmmxt_set_cup();
2085 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2086 wrd
= (insn
>> 12) & 0xf;
2087 rd0
= (insn
>> 16) & 0xf;
2088 rd1
= (insn
>> 0) & 0xf;
2089 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2090 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2091 tcg_gen_andi_i32(tmp
, tmp
, 7);
2092 iwmmxt_load_reg(cpu_V1
, rd1
);
2093 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2094 tcg_temp_free_i32(tmp
);
2095 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2096 gen_op_iwmmxt_set_mup();
2098 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2099 if (((insn
>> 6) & 3) == 3)
2101 rd
= (insn
>> 12) & 0xf;
2102 wrd
= (insn
>> 16) & 0xf;
2103 tmp
= load_reg(s
, rd
);
2104 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2105 switch ((insn
>> 6) & 3) {
2107 tmp2
= tcg_const_i32(0xff);
2108 tmp3
= tcg_const_i32((insn
& 7) << 3);
2111 tmp2
= tcg_const_i32(0xffff);
2112 tmp3
= tcg_const_i32((insn
& 3) << 4);
2115 tmp2
= tcg_const_i32(0xffffffff);
2116 tmp3
= tcg_const_i32((insn
& 1) << 5);
2119 TCGV_UNUSED_I32(tmp2
);
2120 TCGV_UNUSED_I32(tmp3
);
2122 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2123 tcg_temp_free_i32(tmp3
);
2124 tcg_temp_free_i32(tmp2
);
2125 tcg_temp_free_i32(tmp
);
2126 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2127 gen_op_iwmmxt_set_mup();
2129 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2130 rd
= (insn
>> 12) & 0xf;
2131 wrd
= (insn
>> 16) & 0xf;
2132 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2134 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2135 tmp
= tcg_temp_new_i32();
2136 switch ((insn
>> 22) & 3) {
2138 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2139 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2141 tcg_gen_ext8s_i32(tmp
, tmp
);
2143 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2147 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2148 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2150 tcg_gen_ext16s_i32(tmp
, tmp
);
2152 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2156 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2157 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2160 store_reg(s
, rd
, tmp
);
2162 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2163 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2165 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2166 switch ((insn
>> 22) & 3) {
2168 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2171 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2174 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2177 tcg_gen_shli_i32(tmp
, tmp
, 28);
2179 tcg_temp_free_i32(tmp
);
2181 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2182 if (((insn
>> 6) & 3) == 3)
2184 rd
= (insn
>> 12) & 0xf;
2185 wrd
= (insn
>> 16) & 0xf;
2186 tmp
= load_reg(s
, rd
);
2187 switch ((insn
>> 6) & 3) {
2189 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2192 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2195 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2198 tcg_temp_free_i32(tmp
);
2199 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2200 gen_op_iwmmxt_set_mup();
2202 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2203 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2205 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2206 tmp2
= tcg_temp_new_i32();
2207 tcg_gen_mov_i32(tmp2
, tmp
);
2208 switch ((insn
>> 22) & 3) {
2210 for (i
= 0; i
< 7; i
++) {
2211 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2212 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2216 for (i
= 0; i
< 3; i
++) {
2217 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2218 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2222 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2223 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2227 tcg_temp_free_i32(tmp2
);
2228 tcg_temp_free_i32(tmp
);
2230 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2231 wrd
= (insn
>> 12) & 0xf;
2232 rd0
= (insn
>> 16) & 0xf;
2233 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2234 switch ((insn
>> 22) & 3) {
2236 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2239 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2242 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2247 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2248 gen_op_iwmmxt_set_mup();
2250 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2251 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2253 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2254 tmp2
= tcg_temp_new_i32();
2255 tcg_gen_mov_i32(tmp2
, tmp
);
2256 switch ((insn
>> 22) & 3) {
2258 for (i
= 0; i
< 7; i
++) {
2259 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2260 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2264 for (i
= 0; i
< 3; i
++) {
2265 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2266 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2270 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2271 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2275 tcg_temp_free_i32(tmp2
);
2276 tcg_temp_free_i32(tmp
);
2278 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2279 rd
= (insn
>> 12) & 0xf;
2280 rd0
= (insn
>> 16) & 0xf;
2281 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2283 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2284 tmp
= tcg_temp_new_i32();
2285 switch ((insn
>> 22) & 3) {
2287 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2290 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2293 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2296 store_reg(s
, rd
, tmp
);
2298 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2299 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2300 wrd
= (insn
>> 12) & 0xf;
2301 rd0
= (insn
>> 16) & 0xf;
2302 rd1
= (insn
>> 0) & 0xf;
2303 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2304 switch ((insn
>> 22) & 3) {
2306 if (insn
& (1 << 21))
2307 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2309 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2312 if (insn
& (1 << 21))
2313 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2315 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2318 if (insn
& (1 << 21))
2319 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2321 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2326 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2327 gen_op_iwmmxt_set_mup();
2328 gen_op_iwmmxt_set_cup();
2330 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2331 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2332 wrd
= (insn
>> 12) & 0xf;
2333 rd0
= (insn
>> 16) & 0xf;
2334 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2335 switch ((insn
>> 22) & 3) {
2337 if (insn
& (1 << 21))
2338 gen_op_iwmmxt_unpacklsb_M0();
2340 gen_op_iwmmxt_unpacklub_M0();
2343 if (insn
& (1 << 21))
2344 gen_op_iwmmxt_unpacklsw_M0();
2346 gen_op_iwmmxt_unpackluw_M0();
2349 if (insn
& (1 << 21))
2350 gen_op_iwmmxt_unpacklsl_M0();
2352 gen_op_iwmmxt_unpacklul_M0();
2357 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2358 gen_op_iwmmxt_set_mup();
2359 gen_op_iwmmxt_set_cup();
2361 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2362 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2363 wrd
= (insn
>> 12) & 0xf;
2364 rd0
= (insn
>> 16) & 0xf;
2365 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2366 switch ((insn
>> 22) & 3) {
2368 if (insn
& (1 << 21))
2369 gen_op_iwmmxt_unpackhsb_M0();
2371 gen_op_iwmmxt_unpackhub_M0();
2374 if (insn
& (1 << 21))
2375 gen_op_iwmmxt_unpackhsw_M0();
2377 gen_op_iwmmxt_unpackhuw_M0();
2380 if (insn
& (1 << 21))
2381 gen_op_iwmmxt_unpackhsl_M0();
2383 gen_op_iwmmxt_unpackhul_M0();
2388 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2389 gen_op_iwmmxt_set_mup();
2390 gen_op_iwmmxt_set_cup();
2392 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2393 case 0x214: case 0x614: case 0xa14: case 0xe14:
2394 if (((insn
>> 22) & 3) == 0)
2396 wrd
= (insn
>> 12) & 0xf;
2397 rd0
= (insn
>> 16) & 0xf;
2398 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2399 tmp
= tcg_temp_new_i32();
2400 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2401 tcg_temp_free_i32(tmp
);
2404 switch ((insn
>> 22) & 3) {
2406 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2409 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2412 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2415 tcg_temp_free_i32(tmp
);
2416 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2417 gen_op_iwmmxt_set_mup();
2418 gen_op_iwmmxt_set_cup();
2420 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2421 case 0x014: case 0x414: case 0x814: case 0xc14:
2422 if (((insn
>> 22) & 3) == 0)
2424 wrd
= (insn
>> 12) & 0xf;
2425 rd0
= (insn
>> 16) & 0xf;
2426 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2427 tmp
= tcg_temp_new_i32();
2428 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2429 tcg_temp_free_i32(tmp
);
2432 switch ((insn
>> 22) & 3) {
2434 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2437 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2440 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2443 tcg_temp_free_i32(tmp
);
2444 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2445 gen_op_iwmmxt_set_mup();
2446 gen_op_iwmmxt_set_cup();
2448 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2449 case 0x114: case 0x514: case 0x914: case 0xd14:
2450 if (((insn
>> 22) & 3) == 0)
2452 wrd
= (insn
>> 12) & 0xf;
2453 rd0
= (insn
>> 16) & 0xf;
2454 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2455 tmp
= tcg_temp_new_i32();
2456 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2457 tcg_temp_free_i32(tmp
);
2460 switch ((insn
>> 22) & 3) {
2462 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2465 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2468 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2471 tcg_temp_free_i32(tmp
);
2472 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2473 gen_op_iwmmxt_set_mup();
2474 gen_op_iwmmxt_set_cup();
2476 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2477 case 0x314: case 0x714: case 0xb14: case 0xf14:
2478 if (((insn
>> 22) & 3) == 0)
2480 wrd
= (insn
>> 12) & 0xf;
2481 rd0
= (insn
>> 16) & 0xf;
2482 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2483 tmp
= tcg_temp_new_i32();
2484 switch ((insn
>> 22) & 3) {
2486 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2487 tcg_temp_free_i32(tmp
);
2490 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2493 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2494 tcg_temp_free_i32(tmp
);
2497 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2500 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2501 tcg_temp_free_i32(tmp
);
2504 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2507 tcg_temp_free_i32(tmp
);
2508 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2509 gen_op_iwmmxt_set_mup();
2510 gen_op_iwmmxt_set_cup();
2512 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2513 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2514 wrd
= (insn
>> 12) & 0xf;
2515 rd0
= (insn
>> 16) & 0xf;
2516 rd1
= (insn
>> 0) & 0xf;
2517 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2518 switch ((insn
>> 22) & 3) {
2520 if (insn
& (1 << 21))
2521 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2523 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2526 if (insn
& (1 << 21))
2527 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2529 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2532 if (insn
& (1 << 21))
2533 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2535 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2540 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2541 gen_op_iwmmxt_set_mup();
2543 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2544 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2545 wrd
= (insn
>> 12) & 0xf;
2546 rd0
= (insn
>> 16) & 0xf;
2547 rd1
= (insn
>> 0) & 0xf;
2548 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2549 switch ((insn
>> 22) & 3) {
2551 if (insn
& (1 << 21))
2552 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2554 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2557 if (insn
& (1 << 21))
2558 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2560 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2563 if (insn
& (1 << 21))
2564 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2566 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2571 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2572 gen_op_iwmmxt_set_mup();
2574 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2575 case 0x402: case 0x502: case 0x602: case 0x702:
2576 wrd
= (insn
>> 12) & 0xf;
2577 rd0
= (insn
>> 16) & 0xf;
2578 rd1
= (insn
>> 0) & 0xf;
2579 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2580 tmp
= tcg_const_i32((insn
>> 20) & 3);
2581 iwmmxt_load_reg(cpu_V1
, rd1
);
2582 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2583 tcg_temp_free_i32(tmp
);
2584 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2585 gen_op_iwmmxt_set_mup();
2587 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2588 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2589 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2590 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2591 wrd
= (insn
>> 12) & 0xf;
2592 rd0
= (insn
>> 16) & 0xf;
2593 rd1
= (insn
>> 0) & 0xf;
2594 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2595 switch ((insn
>> 20) & 0xf) {
2597 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2600 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2603 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2606 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2609 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2612 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2615 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2618 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2621 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2626 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2627 gen_op_iwmmxt_set_mup();
2628 gen_op_iwmmxt_set_cup();
2630 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2631 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2632 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2633 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2634 wrd
= (insn
>> 12) & 0xf;
2635 rd0
= (insn
>> 16) & 0xf;
2636 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2637 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2638 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2639 tcg_temp_free_i32(tmp
);
2640 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2641 gen_op_iwmmxt_set_mup();
2642 gen_op_iwmmxt_set_cup();
2644 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2645 case 0x418: case 0x518: case 0x618: case 0x718:
2646 case 0x818: case 0x918: case 0xa18: case 0xb18:
2647 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2648 wrd
= (insn
>> 12) & 0xf;
2649 rd0
= (insn
>> 16) & 0xf;
2650 rd1
= (insn
>> 0) & 0xf;
2651 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2652 switch ((insn
>> 20) & 0xf) {
2654 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2657 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2660 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2663 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2666 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2669 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2672 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2675 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2678 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2683 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2684 gen_op_iwmmxt_set_mup();
2685 gen_op_iwmmxt_set_cup();
2687 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2688 case 0x408: case 0x508: case 0x608: case 0x708:
2689 case 0x808: case 0x908: case 0xa08: case 0xb08:
2690 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2691 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2693 wrd
= (insn
>> 12) & 0xf;
2694 rd0
= (insn
>> 16) & 0xf;
2695 rd1
= (insn
>> 0) & 0xf;
2696 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2697 switch ((insn
>> 22) & 3) {
2699 if (insn
& (1 << 21))
2700 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2702 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2705 if (insn
& (1 << 21))
2706 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2708 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2711 if (insn
& (1 << 21))
2712 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2714 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2717 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2718 gen_op_iwmmxt_set_mup();
2719 gen_op_iwmmxt_set_cup();
2721 case 0x201: case 0x203: case 0x205: case 0x207:
2722 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2723 case 0x211: case 0x213: case 0x215: case 0x217:
2724 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2725 wrd
= (insn
>> 5) & 0xf;
2726 rd0
= (insn
>> 12) & 0xf;
2727 rd1
= (insn
>> 0) & 0xf;
2728 if (rd0
== 0xf || rd1
== 0xf)
2730 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2731 tmp
= load_reg(s
, rd0
);
2732 tmp2
= load_reg(s
, rd1
);
2733 switch ((insn
>> 16) & 0xf) {
2734 case 0x0: /* TMIA */
2735 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2737 case 0x8: /* TMIAPH */
2738 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2740 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2741 if (insn
& (1 << 16))
2742 tcg_gen_shri_i32(tmp
, tmp
, 16);
2743 if (insn
& (1 << 17))
2744 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2745 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2748 tcg_temp_free_i32(tmp2
);
2749 tcg_temp_free_i32(tmp
);
2752 tcg_temp_free_i32(tmp2
);
2753 tcg_temp_free_i32(tmp
);
2754 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2755 gen_op_iwmmxt_set_mup();
2764 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2765 (ie. an undefined instruction). */
2766 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2768 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2771 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2772 /* Multiply with Internal Accumulate Format */
2773 rd0
= (insn
>> 12) & 0xf;
2775 acc
= (insn
>> 5) & 7;
2780 tmp
= load_reg(s
, rd0
);
2781 tmp2
= load_reg(s
, rd1
);
2782 switch ((insn
>> 16) & 0xf) {
2784 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2786 case 0x8: /* MIAPH */
2787 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2789 case 0xc: /* MIABB */
2790 case 0xd: /* MIABT */
2791 case 0xe: /* MIATB */
2792 case 0xf: /* MIATT */
2793 if (insn
& (1 << 16))
2794 tcg_gen_shri_i32(tmp
, tmp
, 16);
2795 if (insn
& (1 << 17))
2796 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2797 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2802 tcg_temp_free_i32(tmp2
);
2803 tcg_temp_free_i32(tmp
);
2805 gen_op_iwmmxt_movq_wRn_M0(acc
);
2809 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2810 /* Internal Accumulator Access Format */
2811 rdhi
= (insn
>> 16) & 0xf;
2812 rdlo
= (insn
>> 12) & 0xf;
2818 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2819 iwmmxt_load_reg(cpu_V0
, acc
);
2820 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2821 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2822 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2823 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2825 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2826 iwmmxt_store_reg(cpu_V0
, acc
);
2834 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2835 #define VFP_SREG(insn, bigbit, smallbit) \
2836 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2837 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2838 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2839 reg = (((insn) >> (bigbit)) & 0x0f) \
2840 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2842 if (insn & (1 << (smallbit))) \
2844 reg = ((insn) >> (bigbit)) & 0x0f; \
2847 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2848 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2849 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2850 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2851 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2852 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2854 /* Move between integer and VFP cores. */
2855 static TCGv_i32
gen_vfp_mrs(void)
2857 TCGv_i32 tmp
= tcg_temp_new_i32();
2858 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2862 static void gen_vfp_msr(TCGv_i32 tmp
)
2864 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2865 tcg_temp_free_i32(tmp
);
2868 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2870 TCGv_i32 tmp
= tcg_temp_new_i32();
2872 tcg_gen_shri_i32(var
, var
, shift
);
2873 tcg_gen_ext8u_i32(var
, var
);
2874 tcg_gen_shli_i32(tmp
, var
, 8);
2875 tcg_gen_or_i32(var
, var
, tmp
);
2876 tcg_gen_shli_i32(tmp
, var
, 16);
2877 tcg_gen_or_i32(var
, var
, tmp
);
2878 tcg_temp_free_i32(tmp
);
2881 static void gen_neon_dup_low16(TCGv_i32 var
)
2883 TCGv_i32 tmp
= tcg_temp_new_i32();
2884 tcg_gen_ext16u_i32(var
, var
);
2885 tcg_gen_shli_i32(tmp
, var
, 16);
2886 tcg_gen_or_i32(var
, var
, tmp
);
2887 tcg_temp_free_i32(tmp
);
2890 static void gen_neon_dup_high16(TCGv_i32 var
)
2892 TCGv_i32 tmp
= tcg_temp_new_i32();
2893 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2894 tcg_gen_shri_i32(tmp
, var
, 16);
2895 tcg_gen_or_i32(var
, var
, tmp
);
2896 tcg_temp_free_i32(tmp
);
2899 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2901 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2902 TCGv_i32 tmp
= tcg_temp_new_i32();
2905 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2906 gen_neon_dup_u8(tmp
, 0);
2909 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2910 gen_neon_dup_low16(tmp
);
2913 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2915 default: /* Avoid compiler warnings. */
2921 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2924 uint32_t cc
= extract32(insn
, 20, 2);
2927 TCGv_i64 frn
, frm
, dest
;
2928 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2930 zero
= tcg_const_i64(0);
2932 frn
= tcg_temp_new_i64();
2933 frm
= tcg_temp_new_i64();
2934 dest
= tcg_temp_new_i64();
2936 zf
= tcg_temp_new_i64();
2937 nf
= tcg_temp_new_i64();
2938 vf
= tcg_temp_new_i64();
2940 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2941 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2942 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2944 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2945 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2948 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2952 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2955 case 2: /* ge: N == V -> N ^ V == 0 */
2956 tmp
= tcg_temp_new_i64();
2957 tcg_gen_xor_i64(tmp
, vf
, nf
);
2958 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2960 tcg_temp_free_i64(tmp
);
2962 case 3: /* gt: !Z && N == V */
2963 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2965 tmp
= tcg_temp_new_i64();
2966 tcg_gen_xor_i64(tmp
, vf
, nf
);
2967 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2969 tcg_temp_free_i64(tmp
);
2972 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2973 tcg_temp_free_i64(frn
);
2974 tcg_temp_free_i64(frm
);
2975 tcg_temp_free_i64(dest
);
2977 tcg_temp_free_i64(zf
);
2978 tcg_temp_free_i64(nf
);
2979 tcg_temp_free_i64(vf
);
2981 tcg_temp_free_i64(zero
);
2983 TCGv_i32 frn
, frm
, dest
;
2986 zero
= tcg_const_i32(0);
2988 frn
= tcg_temp_new_i32();
2989 frm
= tcg_temp_new_i32();
2990 dest
= tcg_temp_new_i32();
2991 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2992 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2995 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2999 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
3002 case 2: /* ge: N == V -> N ^ V == 0 */
3003 tmp
= tcg_temp_new_i32();
3004 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3005 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3007 tcg_temp_free_i32(tmp
);
3009 case 3: /* gt: !Z && N == V */
3010 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
3012 tmp
= tcg_temp_new_i32();
3013 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3014 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3016 tcg_temp_free_i32(tmp
);
3019 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3020 tcg_temp_free_i32(frn
);
3021 tcg_temp_free_i32(frm
);
3022 tcg_temp_free_i32(dest
);
3024 tcg_temp_free_i32(zero
);
3030 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
3031 uint32_t rm
, uint32_t dp
)
3033 uint32_t vmin
= extract32(insn
, 6, 1);
3034 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3037 TCGv_i64 frn
, frm
, dest
;
3039 frn
= tcg_temp_new_i64();
3040 frm
= tcg_temp_new_i64();
3041 dest
= tcg_temp_new_i64();
3043 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3044 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3046 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
3048 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
3050 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3051 tcg_temp_free_i64(frn
);
3052 tcg_temp_free_i64(frm
);
3053 tcg_temp_free_i64(dest
);
3055 TCGv_i32 frn
, frm
, dest
;
3057 frn
= tcg_temp_new_i32();
3058 frm
= tcg_temp_new_i32();
3059 dest
= tcg_temp_new_i32();
3061 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3062 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3064 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
3066 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
3068 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3069 tcg_temp_free_i32(frn
);
3070 tcg_temp_free_i32(frm
);
3071 tcg_temp_free_i32(dest
);
3074 tcg_temp_free_ptr(fpst
);
3078 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3081 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3084 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3085 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3090 tcg_op
= tcg_temp_new_i64();
3091 tcg_res
= tcg_temp_new_i64();
3092 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3093 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
3094 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3095 tcg_temp_free_i64(tcg_op
);
3096 tcg_temp_free_i64(tcg_res
);
3100 tcg_op
= tcg_temp_new_i32();
3101 tcg_res
= tcg_temp_new_i32();
3102 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3103 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
3104 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3105 tcg_temp_free_i32(tcg_op
);
3106 tcg_temp_free_i32(tcg_res
);
3109 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3110 tcg_temp_free_i32(tcg_rmode
);
3112 tcg_temp_free_ptr(fpst
);
3116 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3119 bool is_signed
= extract32(insn
, 7, 1);
3120 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3121 TCGv_i32 tcg_rmode
, tcg_shift
;
3123 tcg_shift
= tcg_const_i32(0);
3125 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3126 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3129 TCGv_i64 tcg_double
, tcg_res
;
3131 /* Rd is encoded as a single precision register even when the source
3132 * is double precision.
3134 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3135 tcg_double
= tcg_temp_new_i64();
3136 tcg_res
= tcg_temp_new_i64();
3137 tcg_tmp
= tcg_temp_new_i32();
3138 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3140 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3142 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3144 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3145 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3146 tcg_temp_free_i32(tcg_tmp
);
3147 tcg_temp_free_i64(tcg_res
);
3148 tcg_temp_free_i64(tcg_double
);
3150 TCGv_i32 tcg_single
, tcg_res
;
3151 tcg_single
= tcg_temp_new_i32();
3152 tcg_res
= tcg_temp_new_i32();
3153 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3155 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3157 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3159 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3160 tcg_temp_free_i32(tcg_res
);
3161 tcg_temp_free_i32(tcg_single
);
3164 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3165 tcg_temp_free_i32(tcg_rmode
);
3167 tcg_temp_free_i32(tcg_shift
);
3169 tcg_temp_free_ptr(fpst
);
3174 /* Table for converting the most common AArch32 encoding of
3175 * rounding mode to arm_fprounding order (which matches the
3176 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3178 static const uint8_t fp_decode_rm
[] = {
3185 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3187 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3189 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3194 VFP_DREG_D(rd
, insn
);
3195 VFP_DREG_N(rn
, insn
);
3196 VFP_DREG_M(rm
, insn
);
3198 rd
= VFP_SREG_D(insn
);
3199 rn
= VFP_SREG_N(insn
);
3200 rm
= VFP_SREG_M(insn
);
3203 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3204 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3205 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3206 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3207 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3208 /* VRINTA, VRINTN, VRINTP, VRINTM */
3209 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3210 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3211 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3212 /* VCVTA, VCVTN, VCVTP, VCVTM */
3213 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3214 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3219 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3220 (ie. an undefined instruction). */
3221 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3223 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3229 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3233 /* FIXME: this access check should not take precedence over UNDEF
3234 * for invalid encodings; we will generate incorrect syndrome information
3235 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3237 if (s
->fp_excp_el
) {
3238 gen_exception_insn(s
, 4, EXCP_UDEF
,
3239 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3243 if (!s
->vfp_enabled
) {
3244 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3245 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3247 rn
= (insn
>> 16) & 0xf;
3248 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3249 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3254 if (extract32(insn
, 28, 4) == 0xf) {
3255 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3256 * only used in v8 and above.
3258 return disas_vfp_v8_insn(s
, insn
);
3261 dp
= ((insn
& 0xf00) == 0xb00);
3262 switch ((insn
>> 24) & 0xf) {
3264 if (insn
& (1 << 4)) {
3265 /* single register transfer */
3266 rd
= (insn
>> 12) & 0xf;
3271 VFP_DREG_N(rn
, insn
);
3274 if (insn
& 0x00c00060
3275 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3279 pass
= (insn
>> 21) & 1;
3280 if (insn
& (1 << 22)) {
3282 offset
= ((insn
>> 5) & 3) * 8;
3283 } else if (insn
& (1 << 5)) {
3285 offset
= (insn
& (1 << 6)) ? 16 : 0;
3290 if (insn
& ARM_CP_RW_BIT
) {
3292 tmp
= neon_load_reg(rn
, pass
);
3296 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3297 if (insn
& (1 << 23))
3303 if (insn
& (1 << 23)) {
3305 tcg_gen_shri_i32(tmp
, tmp
, 16);
3311 tcg_gen_sari_i32(tmp
, tmp
, 16);
3320 store_reg(s
, rd
, tmp
);
3323 tmp
= load_reg(s
, rd
);
3324 if (insn
& (1 << 23)) {
3327 gen_neon_dup_u8(tmp
, 0);
3328 } else if (size
== 1) {
3329 gen_neon_dup_low16(tmp
);
3331 for (n
= 0; n
<= pass
* 2; n
++) {
3332 tmp2
= tcg_temp_new_i32();
3333 tcg_gen_mov_i32(tmp2
, tmp
);
3334 neon_store_reg(rn
, n
, tmp2
);
3336 neon_store_reg(rn
, n
, tmp
);
3341 tmp2
= neon_load_reg(rn
, pass
);
3342 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3343 tcg_temp_free_i32(tmp2
);
3346 tmp2
= neon_load_reg(rn
, pass
);
3347 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3348 tcg_temp_free_i32(tmp2
);
3353 neon_store_reg(rn
, pass
, tmp
);
3357 if ((insn
& 0x6f) != 0x00)
3359 rn
= VFP_SREG_N(insn
);
3360 if (insn
& ARM_CP_RW_BIT
) {
3362 if (insn
& (1 << 21)) {
3363 /* system register */
3368 /* VFP2 allows access to FSID from userspace.
3369 VFP3 restricts all id registers to privileged
3372 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3375 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3380 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3382 case ARM_VFP_FPINST
:
3383 case ARM_VFP_FPINST2
:
3384 /* Not present in VFP3. */
3386 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3389 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3393 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3394 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3396 tmp
= tcg_temp_new_i32();
3397 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3401 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3408 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3411 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3417 gen_mov_F0_vreg(0, rn
);
3418 tmp
= gen_vfp_mrs();
3421 /* Set the 4 flag bits in the CPSR. */
3423 tcg_temp_free_i32(tmp
);
3425 store_reg(s
, rd
, tmp
);
3429 if (insn
& (1 << 21)) {
3431 /* system register */
3436 /* Writes are ignored. */
3439 tmp
= load_reg(s
, rd
);
3440 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3441 tcg_temp_free_i32(tmp
);
3447 /* TODO: VFP subarchitecture support.
3448 * For now, keep the EN bit only */
3449 tmp
= load_reg(s
, rd
);
3450 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3451 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3454 case ARM_VFP_FPINST
:
3455 case ARM_VFP_FPINST2
:
3459 tmp
= load_reg(s
, rd
);
3460 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3466 tmp
= load_reg(s
, rd
);
3468 gen_mov_vreg_F0(0, rn
);
3473 /* data processing */
3474 /* The opcode is in bits 23, 21, 20 and 6. */
3475 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3479 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3481 /* rn is register number */
3482 VFP_DREG_N(rn
, insn
);
3485 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3486 ((rn
& 0x1e) == 0x6))) {
3487 /* Integer or single/half precision destination. */
3488 rd
= VFP_SREG_D(insn
);
3490 VFP_DREG_D(rd
, insn
);
3493 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3494 ((rn
& 0x1e) == 0x4))) {
3495 /* VCVT from int or half precision is always from S reg
3496 * regardless of dp bit. VCVT with immediate frac_bits
3497 * has same format as SREG_M.
3499 rm
= VFP_SREG_M(insn
);
3501 VFP_DREG_M(rm
, insn
);
3504 rn
= VFP_SREG_N(insn
);
3505 if (op
== 15 && rn
== 15) {
3506 /* Double precision destination. */
3507 VFP_DREG_D(rd
, insn
);
3509 rd
= VFP_SREG_D(insn
);
3511 /* NB that we implicitly rely on the encoding for the frac_bits
3512 * in VCVT of fixed to float being the same as that of an SREG_M
3514 rm
= VFP_SREG_M(insn
);
3517 veclen
= s
->vec_len
;
3518 if (op
== 15 && rn
> 3)
3521 /* Shut up compiler warnings. */
3532 /* Figure out what type of vector operation this is. */
3533 if ((rd
& bank_mask
) == 0) {
3538 delta_d
= (s
->vec_stride
>> 1) + 1;
3540 delta_d
= s
->vec_stride
+ 1;
3542 if ((rm
& bank_mask
) == 0) {
3543 /* mixed scalar/vector */
3552 /* Load the initial operands. */
3557 /* Integer source */
3558 gen_mov_F0_vreg(0, rm
);
3563 gen_mov_F0_vreg(dp
, rd
);
3564 gen_mov_F1_vreg(dp
, rm
);
3568 /* Compare with zero */
3569 gen_mov_F0_vreg(dp
, rd
);
3580 /* Source and destination the same. */
3581 gen_mov_F0_vreg(dp
, rd
);
3587 /* VCVTB, VCVTT: only present with the halfprec extension
3588 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3589 * (we choose to UNDEF)
3591 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3592 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3595 if (!extract32(rn
, 1, 1)) {
3596 /* Half precision source. */
3597 gen_mov_F0_vreg(0, rm
);
3600 /* Otherwise fall through */
3602 /* One source operand. */
3603 gen_mov_F0_vreg(dp
, rm
);
3607 /* Two source operands. */
3608 gen_mov_F0_vreg(dp
, rn
);
3609 gen_mov_F1_vreg(dp
, rm
);
3613 /* Perform the calculation. */
3615 case 0: /* VMLA: fd + (fn * fm) */
3616 /* Note that order of inputs to the add matters for NaNs */
3618 gen_mov_F0_vreg(dp
, rd
);
3621 case 1: /* VMLS: fd + -(fn * fm) */
3624 gen_mov_F0_vreg(dp
, rd
);
3627 case 2: /* VNMLS: -fd + (fn * fm) */
3628 /* Note that it isn't valid to replace (-A + B) with (B - A)
3629 * or similar plausible looking simplifications
3630 * because this will give wrong results for NaNs.
3633 gen_mov_F0_vreg(dp
, rd
);
3637 case 3: /* VNMLA: -fd + -(fn * fm) */
3640 gen_mov_F0_vreg(dp
, rd
);
3644 case 4: /* mul: fn * fm */
3647 case 5: /* nmul: -(fn * fm) */
3651 case 6: /* add: fn + fm */
3654 case 7: /* sub: fn - fm */
3657 case 8: /* div: fn / fm */
3660 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3661 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3662 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3663 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3664 /* These are fused multiply-add, and must be done as one
3665 * floating point operation with no rounding between the
3666 * multiplication and addition steps.
3667 * NB that doing the negations here as separate steps is
3668 * correct : an input NaN should come out with its sign bit
3669 * flipped if it is a negated-input.
3671 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3679 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3681 frd
= tcg_temp_new_i64();
3682 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3685 gen_helper_vfp_negd(frd
, frd
);
3687 fpst
= get_fpstatus_ptr(0);
3688 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3689 cpu_F1d
, frd
, fpst
);
3690 tcg_temp_free_ptr(fpst
);
3691 tcg_temp_free_i64(frd
);
3697 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3699 frd
= tcg_temp_new_i32();
3700 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3702 gen_helper_vfp_negs(frd
, frd
);
3704 fpst
= get_fpstatus_ptr(0);
3705 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3706 cpu_F1s
, frd
, fpst
);
3707 tcg_temp_free_ptr(fpst
);
3708 tcg_temp_free_i32(frd
);
3711 case 14: /* fconst */
3712 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3716 n
= (insn
<< 12) & 0x80000000;
3717 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3724 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3731 tcg_gen_movi_i32(cpu_F0s
, n
);
3734 case 15: /* extension space */
3748 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3749 tmp
= gen_vfp_mrs();
3750 tcg_gen_ext16u_i32(tmp
, tmp
);
3752 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3755 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3758 tcg_temp_free_i32(tmp
);
3760 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3761 tmp
= gen_vfp_mrs();
3762 tcg_gen_shri_i32(tmp
, tmp
, 16);
3764 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3767 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3770 tcg_temp_free_i32(tmp
);
3772 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3773 tmp
= tcg_temp_new_i32();
3775 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3778 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3781 gen_mov_F0_vreg(0, rd
);
3782 tmp2
= gen_vfp_mrs();
3783 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3784 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3785 tcg_temp_free_i32(tmp2
);
3788 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3789 tmp
= tcg_temp_new_i32();
3791 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3794 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3797 tcg_gen_shli_i32(tmp
, tmp
, 16);
3798 gen_mov_F0_vreg(0, rd
);
3799 tmp2
= gen_vfp_mrs();
3800 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3801 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3802 tcg_temp_free_i32(tmp2
);
3814 case 11: /* cmpez */
3818 case 12: /* vrintr */
3820 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3822 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3824 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3826 tcg_temp_free_ptr(fpst
);
3829 case 13: /* vrintz */
3831 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3833 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3834 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3836 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3838 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3840 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3841 tcg_temp_free_i32(tcg_rmode
);
3842 tcg_temp_free_ptr(fpst
);
3845 case 14: /* vrintx */
3847 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3849 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3851 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3853 tcg_temp_free_ptr(fpst
);
3856 case 15: /* single<->double conversion */
3858 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3860 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3862 case 16: /* fuito */
3863 gen_vfp_uito(dp
, 0);
3865 case 17: /* fsito */
3866 gen_vfp_sito(dp
, 0);
3868 case 20: /* fshto */
3869 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3872 gen_vfp_shto(dp
, 16 - rm
, 0);
3874 case 21: /* fslto */
3875 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3878 gen_vfp_slto(dp
, 32 - rm
, 0);
3880 case 22: /* fuhto */
3881 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3884 gen_vfp_uhto(dp
, 16 - rm
, 0);
3886 case 23: /* fulto */
3887 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3890 gen_vfp_ulto(dp
, 32 - rm
, 0);
3892 case 24: /* ftoui */
3893 gen_vfp_toui(dp
, 0);
3895 case 25: /* ftouiz */
3896 gen_vfp_touiz(dp
, 0);
3898 case 26: /* ftosi */
3899 gen_vfp_tosi(dp
, 0);
3901 case 27: /* ftosiz */
3902 gen_vfp_tosiz(dp
, 0);
3904 case 28: /* ftosh */
3905 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3908 gen_vfp_tosh(dp
, 16 - rm
, 0);
3910 case 29: /* ftosl */
3911 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3914 gen_vfp_tosl(dp
, 32 - rm
, 0);
3916 case 30: /* ftouh */
3917 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3920 gen_vfp_touh(dp
, 16 - rm
, 0);
3922 case 31: /* ftoul */
3923 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3926 gen_vfp_toul(dp
, 32 - rm
, 0);
3928 default: /* undefined */
3932 default: /* undefined */
3936 /* Write back the result. */
3937 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3938 /* Comparison, do nothing. */
3939 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3940 (rn
& 0x1e) == 0x6)) {
3941 /* VCVT double to int: always integer result.
3942 * VCVT double to half precision is always a single
3945 gen_mov_vreg_F0(0, rd
);
3946 } else if (op
== 15 && rn
== 15) {
3948 gen_mov_vreg_F0(!dp
, rd
);
3950 gen_mov_vreg_F0(dp
, rd
);
3953 /* break out of the loop if we have finished */
3957 if (op
== 15 && delta_m
== 0) {
3958 /* single source one-many */
3960 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3962 gen_mov_vreg_F0(dp
, rd
);
3966 /* Setup the next operands. */
3968 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3972 /* One source operand. */
3973 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3975 gen_mov_F0_vreg(dp
, rm
);
3977 /* Two source operands. */
3978 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3980 gen_mov_F0_vreg(dp
, rn
);
3982 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3984 gen_mov_F1_vreg(dp
, rm
);
3992 if ((insn
& 0x03e00000) == 0x00400000) {
3993 /* two-register transfer */
3994 rn
= (insn
>> 16) & 0xf;
3995 rd
= (insn
>> 12) & 0xf;
3997 VFP_DREG_M(rm
, insn
);
3999 rm
= VFP_SREG_M(insn
);
4002 if (insn
& ARM_CP_RW_BIT
) {
4005 gen_mov_F0_vreg(0, rm
* 2);
4006 tmp
= gen_vfp_mrs();
4007 store_reg(s
, rd
, tmp
);
4008 gen_mov_F0_vreg(0, rm
* 2 + 1);
4009 tmp
= gen_vfp_mrs();
4010 store_reg(s
, rn
, tmp
);
4012 gen_mov_F0_vreg(0, rm
);
4013 tmp
= gen_vfp_mrs();
4014 store_reg(s
, rd
, tmp
);
4015 gen_mov_F0_vreg(0, rm
+ 1);
4016 tmp
= gen_vfp_mrs();
4017 store_reg(s
, rn
, tmp
);
4022 tmp
= load_reg(s
, rd
);
4024 gen_mov_vreg_F0(0, rm
* 2);
4025 tmp
= load_reg(s
, rn
);
4027 gen_mov_vreg_F0(0, rm
* 2 + 1);
4029 tmp
= load_reg(s
, rd
);
4031 gen_mov_vreg_F0(0, rm
);
4032 tmp
= load_reg(s
, rn
);
4034 gen_mov_vreg_F0(0, rm
+ 1);
4039 rn
= (insn
>> 16) & 0xf;
4041 VFP_DREG_D(rd
, insn
);
4043 rd
= VFP_SREG_D(insn
);
4044 if ((insn
& 0x01200000) == 0x01000000) {
4045 /* Single load/store */
4046 offset
= (insn
& 0xff) << 2;
4047 if ((insn
& (1 << 23)) == 0)
4049 if (s
->thumb
&& rn
== 15) {
4050 /* This is actually UNPREDICTABLE */
4051 addr
= tcg_temp_new_i32();
4052 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4054 addr
= load_reg(s
, rn
);
4056 tcg_gen_addi_i32(addr
, addr
, offset
);
4057 if (insn
& (1 << 20)) {
4058 gen_vfp_ld(s
, dp
, addr
);
4059 gen_mov_vreg_F0(dp
, rd
);
4061 gen_mov_F0_vreg(dp
, rd
);
4062 gen_vfp_st(s
, dp
, addr
);
4064 tcg_temp_free_i32(addr
);
4066 /* load/store multiple */
4067 int w
= insn
& (1 << 21);
4069 n
= (insn
>> 1) & 0x7f;
4073 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
4074 /* P == U , W == 1 => UNDEF */
4077 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
4078 /* UNPREDICTABLE cases for bad immediates: we choose to
4079 * UNDEF to avoid generating huge numbers of TCG ops
4083 if (rn
== 15 && w
) {
4084 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4088 if (s
->thumb
&& rn
== 15) {
4089 /* This is actually UNPREDICTABLE */
4090 addr
= tcg_temp_new_i32();
4091 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4093 addr
= load_reg(s
, rn
);
4095 if (insn
& (1 << 24)) /* pre-decrement */
4096 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4102 for (i
= 0; i
< n
; i
++) {
4103 if (insn
& ARM_CP_RW_BIT
) {
4105 gen_vfp_ld(s
, dp
, addr
);
4106 gen_mov_vreg_F0(dp
, rd
+ i
);
4109 gen_mov_F0_vreg(dp
, rd
+ i
);
4110 gen_vfp_st(s
, dp
, addr
);
4112 tcg_gen_addi_i32(addr
, addr
, offset
);
4116 if (insn
& (1 << 24))
4117 offset
= -offset
* n
;
4118 else if (dp
&& (insn
& 1))
4124 tcg_gen_addi_i32(addr
, addr
, offset
);
4125 store_reg(s
, rn
, addr
);
4127 tcg_temp_free_i32(addr
);
4133 /* Should never happen. */
4139 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4141 #ifndef CONFIG_USER_ONLY
4142 return (s
->tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4143 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4149 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4151 if (use_goto_tb(s
, dest
)) {
4153 gen_set_pc_im(s
, dest
);
4154 tcg_gen_exit_tb((uintptr_t)s
->tb
+ n
);
4156 gen_set_pc_im(s
, dest
);
4161 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4163 if (unlikely(is_singlestepping(s
))) {
4164 /* An indirect jump so that we still trigger the debug exception. */
4169 gen_goto_tb(s
, 0, dest
);
4170 s
->is_jmp
= DISAS_TB_JUMP
;
4174 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4177 tcg_gen_sari_i32(t0
, t0
, 16);
4181 tcg_gen_sari_i32(t1
, t1
, 16);
4184 tcg_gen_mul_i32(t0
, t0
, t1
);
4187 /* Return the mask of PSR bits set by a MSR instruction. */
4188 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4193 if (flags
& (1 << 0))
4195 if (flags
& (1 << 1))
4197 if (flags
& (1 << 2))
4199 if (flags
& (1 << 3))
4202 /* Mask out undefined bits. */
4203 mask
&= ~CPSR_RESERVED
;
4204 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4207 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4208 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4210 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4211 mask
&= ~(CPSR_E
| CPSR_GE
);
4213 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4216 /* Mask out execution state and reserved bits. */
4218 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4220 /* Mask out privileged bits. */
4226 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4227 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4231 /* ??? This is also undefined in system mode. */
4235 tmp
= load_cpu_field(spsr
);
4236 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4237 tcg_gen_andi_i32(t0
, t0
, mask
);
4238 tcg_gen_or_i32(tmp
, tmp
, t0
);
4239 store_cpu_field(tmp
, spsr
);
4241 gen_set_cpsr(t0
, mask
);
4243 tcg_temp_free_i32(t0
);
4248 /* Returns nonzero if access to the PSR is not permitted. */
4249 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4252 tmp
= tcg_temp_new_i32();
4253 tcg_gen_movi_i32(tmp
, val
);
4254 return gen_set_psr(s
, mask
, spsr
, tmp
);
4257 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4258 int *tgtmode
, int *regno
)
4260 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4261 * the target mode and register number, and identify the various
4262 * unpredictable cases.
4263 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4264 * + executed in user mode
4265 * + using R15 as the src/dest register
4266 * + accessing an unimplemented register
4267 * + accessing a register that's inaccessible at current PL/security state*
4268 * + accessing a register that you could access with a different insn
4269 * We choose to UNDEF in all these cases.
4270 * Since we don't know which of the various AArch32 modes we are in
4271 * we have to defer some checks to runtime.
4272 * Accesses to Monitor mode registers from Secure EL1 (which implies
4273 * that EL3 is AArch64) must trap to EL3.
4275 * If the access checks fail this function will emit code to take
4276 * an exception and return false. Otherwise it will return true,
4277 * and set *tgtmode and *regno appropriately.
4279 int exc_target
= default_exception_el(s
);
4281 /* These instructions are present only in ARMv8, or in ARMv7 with the
4282 * Virtualization Extensions.
4284 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4285 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4289 if (IS_USER(s
) || rn
== 15) {
4293 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4294 * of registers into (r, sysm).
4297 /* SPSRs for other modes */
4299 case 0xe: /* SPSR_fiq */
4300 *tgtmode
= ARM_CPU_MODE_FIQ
;
4302 case 0x10: /* SPSR_irq */
4303 *tgtmode
= ARM_CPU_MODE_IRQ
;
4305 case 0x12: /* SPSR_svc */
4306 *tgtmode
= ARM_CPU_MODE_SVC
;
4308 case 0x14: /* SPSR_abt */
4309 *tgtmode
= ARM_CPU_MODE_ABT
;
4311 case 0x16: /* SPSR_und */
4312 *tgtmode
= ARM_CPU_MODE_UND
;
4314 case 0x1c: /* SPSR_mon */
4315 *tgtmode
= ARM_CPU_MODE_MON
;
4317 case 0x1e: /* SPSR_hyp */
4318 *tgtmode
= ARM_CPU_MODE_HYP
;
4320 default: /* unallocated */
4323 /* We arbitrarily assign SPSR a register number of 16. */
4326 /* general purpose registers for other modes */
4328 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4329 *tgtmode
= ARM_CPU_MODE_USR
;
4332 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4333 *tgtmode
= ARM_CPU_MODE_FIQ
;
4336 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4337 *tgtmode
= ARM_CPU_MODE_IRQ
;
4338 *regno
= sysm
& 1 ? 13 : 14;
4340 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4341 *tgtmode
= ARM_CPU_MODE_SVC
;
4342 *regno
= sysm
& 1 ? 13 : 14;
4344 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4345 *tgtmode
= ARM_CPU_MODE_ABT
;
4346 *regno
= sysm
& 1 ? 13 : 14;
4348 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4349 *tgtmode
= ARM_CPU_MODE_UND
;
4350 *regno
= sysm
& 1 ? 13 : 14;
4352 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4353 *tgtmode
= ARM_CPU_MODE_MON
;
4354 *regno
= sysm
& 1 ? 13 : 14;
4356 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4357 *tgtmode
= ARM_CPU_MODE_HYP
;
4358 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4359 *regno
= sysm
& 1 ? 13 : 17;
4361 default: /* unallocated */
4366 /* Catch the 'accessing inaccessible register' cases we can detect
4367 * at translate time.
4370 case ARM_CPU_MODE_MON
:
4371 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4374 if (s
->current_el
== 1) {
4375 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4376 * then accesses to Mon registers trap to EL3
4382 case ARM_CPU_MODE_HYP
:
4383 /* Note that we can forbid accesses from EL2 here because they
4384 * must be from Hyp mode itself
4386 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4397 /* If we get here then some access check did not pass */
4398 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4402 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4404 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4405 int tgtmode
= 0, regno
= 0;
4407 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4411 /* Sync state because msr_banked() can raise exceptions */
4412 gen_set_condexec(s
);
4413 gen_set_pc_im(s
, s
->pc
- 4);
4414 tcg_reg
= load_reg(s
, rn
);
4415 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4416 tcg_regno
= tcg_const_i32(regno
);
4417 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4418 tcg_temp_free_i32(tcg_tgtmode
);
4419 tcg_temp_free_i32(tcg_regno
);
4420 tcg_temp_free_i32(tcg_reg
);
4421 s
->is_jmp
= DISAS_UPDATE
;
4424 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4426 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4427 int tgtmode
= 0, regno
= 0;
4429 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4433 /* Sync state because mrs_banked() can raise exceptions */
4434 gen_set_condexec(s
);
4435 gen_set_pc_im(s
, s
->pc
- 4);
4436 tcg_reg
= tcg_temp_new_i32();
4437 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4438 tcg_regno
= tcg_const_i32(regno
);
4439 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4440 tcg_temp_free_i32(tcg_tgtmode
);
4441 tcg_temp_free_i32(tcg_regno
);
4442 store_reg(s
, rn
, tcg_reg
);
4443 s
->is_jmp
= DISAS_UPDATE
;
4446 /* Store value to PC as for an exception return (ie don't
4447 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4448 * will do the masking based on the new value of the Thumb bit.
4450 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4452 tcg_gen_mov_i32(cpu_R
[15], pc
);
4453 tcg_temp_free_i32(pc
);
4456 /* Generate a v6 exception return. Marks both values as dead. */
4457 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4459 store_pc_exc_ret(s
, pc
);
4460 /* The cpsr_write_eret helper will mask the low bits of PC
4461 * appropriately depending on the new Thumb bit, so it must
4462 * be called after storing the new PC.
4464 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4465 tcg_temp_free_i32(cpsr
);
4466 s
->is_jmp
= DISAS_JUMP
;
4469 /* Generate an old-style exception return. Marks pc as dead. */
4470 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4472 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4476 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4477 * only call the helper when running single threaded TCG code to ensure
4478 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4479 * just skip this instruction. Currently the SEV/SEVL instructions
4480 * which are *one* of many ways to wake the CPU from WFE are not
4481 * implemented so we can't sleep like WFI does.
4483 static void gen_nop_hint(DisasContext
*s
, int val
)
4487 if (!parallel_cpus
) {
4488 gen_set_pc_im(s
, s
->pc
);
4489 s
->is_jmp
= DISAS_YIELD
;
4493 gen_set_pc_im(s
, s
->pc
);
4494 s
->is_jmp
= DISAS_WFI
;
4497 if (!parallel_cpus
) {
4498 gen_set_pc_im(s
, s
->pc
);
4499 s
->is_jmp
= DISAS_WFE
;
4504 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4510 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4512 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4515 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4516 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4517 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4522 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4525 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4526 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4527 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4532 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4533 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4534 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4535 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4536 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4538 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4539 switch ((size << 1) | u) { \
4541 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4544 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4547 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4550 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4553 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4556 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4558 default: return 1; \
4561 #define GEN_NEON_INTEGER_OP(name) do { \
4562 switch ((size << 1) | u) { \
4564 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4567 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4570 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4573 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4576 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4579 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4581 default: return 1; \
4584 static TCGv_i32
neon_load_scratch(int scratch
)
4586 TCGv_i32 tmp
= tcg_temp_new_i32();
4587 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4591 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4593 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4594 tcg_temp_free_i32(var
);
4597 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4601 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4603 gen_neon_dup_high16(tmp
);
4605 gen_neon_dup_low16(tmp
);
4608 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4613 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4616 if (!q
&& size
== 2) {
4619 tmp
= tcg_const_i32(rd
);
4620 tmp2
= tcg_const_i32(rm
);
4624 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4627 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4630 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4638 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4641 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4647 tcg_temp_free_i32(tmp
);
4648 tcg_temp_free_i32(tmp2
);
4652 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4655 if (!q
&& size
== 2) {
4658 tmp
= tcg_const_i32(rd
);
4659 tmp2
= tcg_const_i32(rm
);
4663 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4666 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4669 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4677 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4680 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4686 tcg_temp_free_i32(tmp
);
4687 tcg_temp_free_i32(tmp2
);
4691 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4695 rd
= tcg_temp_new_i32();
4696 tmp
= tcg_temp_new_i32();
4698 tcg_gen_shli_i32(rd
, t0
, 8);
4699 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4700 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4701 tcg_gen_or_i32(rd
, rd
, tmp
);
4703 tcg_gen_shri_i32(t1
, t1
, 8);
4704 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4705 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4706 tcg_gen_or_i32(t1
, t1
, tmp
);
4707 tcg_gen_mov_i32(t0
, rd
);
4709 tcg_temp_free_i32(tmp
);
4710 tcg_temp_free_i32(rd
);
4713 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4717 rd
= tcg_temp_new_i32();
4718 tmp
= tcg_temp_new_i32();
4720 tcg_gen_shli_i32(rd
, t0
, 16);
4721 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4722 tcg_gen_or_i32(rd
, rd
, tmp
);
4723 tcg_gen_shri_i32(t1
, t1
, 16);
4724 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4725 tcg_gen_or_i32(t1
, t1
, tmp
);
4726 tcg_gen_mov_i32(t0
, rd
);
4728 tcg_temp_free_i32(tmp
);
4729 tcg_temp_free_i32(rd
);
4737 } neon_ls_element_type
[11] = {
4751 /* Translate a NEON load/store element instruction. Return nonzero if the
4752 instruction is invalid. */
4753 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4772 /* FIXME: this access check should not take precedence over UNDEF
4773 * for invalid encodings; we will generate incorrect syndrome information
4774 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4776 if (s
->fp_excp_el
) {
4777 gen_exception_insn(s
, 4, EXCP_UDEF
,
4778 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4782 if (!s
->vfp_enabled
)
4784 VFP_DREG_D(rd
, insn
);
4785 rn
= (insn
>> 16) & 0xf;
4787 load
= (insn
& (1 << 21)) != 0;
4788 if ((insn
& (1 << 23)) == 0) {
4789 /* Load store all elements. */
4790 op
= (insn
>> 8) & 0xf;
4791 size
= (insn
>> 6) & 3;
4794 /* Catch UNDEF cases for bad values of align field */
4797 if (((insn
>> 5) & 1) == 1) {
4802 if (((insn
>> 4) & 3) == 3) {
4809 nregs
= neon_ls_element_type
[op
].nregs
;
4810 interleave
= neon_ls_element_type
[op
].interleave
;
4811 spacing
= neon_ls_element_type
[op
].spacing
;
4812 if (size
== 3 && (interleave
| spacing
) != 1)
4814 addr
= tcg_temp_new_i32();
4815 load_reg_var(s
, addr
, rn
);
4816 stride
= (1 << size
) * interleave
;
4817 for (reg
= 0; reg
< nregs
; reg
++) {
4818 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4819 load_reg_var(s
, addr
, rn
);
4820 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4821 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4822 load_reg_var(s
, addr
, rn
);
4823 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4826 tmp64
= tcg_temp_new_i64();
4828 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4829 neon_store_reg64(tmp64
, rd
);
4831 neon_load_reg64(tmp64
, rd
);
4832 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4834 tcg_temp_free_i64(tmp64
);
4835 tcg_gen_addi_i32(addr
, addr
, stride
);
4837 for (pass
= 0; pass
< 2; pass
++) {
4840 tmp
= tcg_temp_new_i32();
4841 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4842 neon_store_reg(rd
, pass
, tmp
);
4844 tmp
= neon_load_reg(rd
, pass
);
4845 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4846 tcg_temp_free_i32(tmp
);
4848 tcg_gen_addi_i32(addr
, addr
, stride
);
4849 } else if (size
== 1) {
4851 tmp
= tcg_temp_new_i32();
4852 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4853 tcg_gen_addi_i32(addr
, addr
, stride
);
4854 tmp2
= tcg_temp_new_i32();
4855 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4856 tcg_gen_addi_i32(addr
, addr
, stride
);
4857 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4858 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4859 tcg_temp_free_i32(tmp2
);
4860 neon_store_reg(rd
, pass
, tmp
);
4862 tmp
= neon_load_reg(rd
, pass
);
4863 tmp2
= tcg_temp_new_i32();
4864 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4865 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4866 tcg_temp_free_i32(tmp
);
4867 tcg_gen_addi_i32(addr
, addr
, stride
);
4868 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4869 tcg_temp_free_i32(tmp2
);
4870 tcg_gen_addi_i32(addr
, addr
, stride
);
4872 } else /* size == 0 */ {
4874 TCGV_UNUSED_I32(tmp2
);
4875 for (n
= 0; n
< 4; n
++) {
4876 tmp
= tcg_temp_new_i32();
4877 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4878 tcg_gen_addi_i32(addr
, addr
, stride
);
4882 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4883 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4884 tcg_temp_free_i32(tmp
);
4887 neon_store_reg(rd
, pass
, tmp2
);
4889 tmp2
= neon_load_reg(rd
, pass
);
4890 for (n
= 0; n
< 4; n
++) {
4891 tmp
= tcg_temp_new_i32();
4893 tcg_gen_mov_i32(tmp
, tmp2
);
4895 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4897 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4898 tcg_temp_free_i32(tmp
);
4899 tcg_gen_addi_i32(addr
, addr
, stride
);
4901 tcg_temp_free_i32(tmp2
);
4908 tcg_temp_free_i32(addr
);
4911 size
= (insn
>> 10) & 3;
4913 /* Load single element to all lanes. */
4914 int a
= (insn
>> 4) & 1;
4918 size
= (insn
>> 6) & 3;
4919 nregs
= ((insn
>> 8) & 3) + 1;
4922 if (nregs
!= 4 || a
== 0) {
4925 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4928 if (nregs
== 1 && a
== 1 && size
== 0) {
4931 if (nregs
== 3 && a
== 1) {
4934 addr
= tcg_temp_new_i32();
4935 load_reg_var(s
, addr
, rn
);
4937 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4938 tmp
= gen_load_and_replicate(s
, addr
, size
);
4939 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4940 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4941 if (insn
& (1 << 5)) {
4942 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4943 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4945 tcg_temp_free_i32(tmp
);
4947 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4948 stride
= (insn
& (1 << 5)) ? 2 : 1;
4949 for (reg
= 0; reg
< nregs
; reg
++) {
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 tcg_temp_free_i32(tmp
);
4954 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4958 tcg_temp_free_i32(addr
);
4959 stride
= (1 << size
) * nregs
;
4961 /* Single element. */
4962 int idx
= (insn
>> 4) & 0xf;
4963 pass
= (insn
>> 7) & 1;
4966 shift
= ((insn
>> 5) & 3) * 8;
4970 shift
= ((insn
>> 6) & 1) * 16;
4971 stride
= (insn
& (1 << 5)) ? 2 : 1;
4975 stride
= (insn
& (1 << 6)) ? 2 : 1;
4980 nregs
= ((insn
>> 8) & 3) + 1;
4981 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4984 if (((idx
& (1 << size
)) != 0) ||
4985 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4990 if ((idx
& 1) != 0) {
4995 if (size
== 2 && (idx
& 2) != 0) {
5000 if ((size
== 2) && ((idx
& 3) == 3)) {
5007 if ((rd
+ stride
* (nregs
- 1)) > 31) {
5008 /* Attempts to write off the end of the register file
5009 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5010 * the neon_load_reg() would write off the end of the array.
5014 addr
= tcg_temp_new_i32();
5015 load_reg_var(s
, addr
, rn
);
5016 for (reg
= 0; reg
< nregs
; reg
++) {
5018 tmp
= tcg_temp_new_i32();
5021 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
5024 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
5027 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
5029 default: /* Avoid compiler warnings. */
5033 tmp2
= neon_load_reg(rd
, pass
);
5034 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
5035 shift
, size
? 16 : 8);
5036 tcg_temp_free_i32(tmp2
);
5038 neon_store_reg(rd
, pass
, tmp
);
5039 } else { /* Store */
5040 tmp
= neon_load_reg(rd
, pass
);
5042 tcg_gen_shri_i32(tmp
, tmp
, shift
);
5045 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
5048 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
5051 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5054 tcg_temp_free_i32(tmp
);
5057 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5059 tcg_temp_free_i32(addr
);
5060 stride
= nregs
* (1 << size
);
5066 base
= load_reg(s
, rn
);
5068 tcg_gen_addi_i32(base
, base
, stride
);
5071 index
= load_reg(s
, rm
);
5072 tcg_gen_add_i32(base
, base
, index
);
5073 tcg_temp_free_i32(index
);
5075 store_reg(s
, rn
, base
);
5080 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5081 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
5083 tcg_gen_and_i32(t
, t
, c
);
5084 tcg_gen_andc_i32(f
, f
, c
);
5085 tcg_gen_or_i32(dest
, t
, f
);
5088 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5091 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
5092 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
5093 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
5098 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5101 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
5102 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
5103 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5108 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5111 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5112 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5113 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5118 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5121 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5122 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5123 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5128 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5134 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5135 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5140 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5141 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5148 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5149 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5154 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5155 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5162 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5166 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5167 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5168 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5173 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5174 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5175 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5179 tcg_temp_free_i32(src
);
5182 static inline void gen_neon_addl(int size
)
5185 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5186 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5187 case 2: tcg_gen_add_i64(CPU_V001
); break;
5192 static inline void gen_neon_subl(int size
)
5195 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5196 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5197 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5202 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5205 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5206 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5208 tcg_gen_neg_i64(var
, var
);
5214 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5217 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5218 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5223 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5228 switch ((size
<< 1) | u
) {
5229 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5230 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5231 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5232 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5234 tmp
= gen_muls_i64_i32(a
, b
);
5235 tcg_gen_mov_i64(dest
, tmp
);
5236 tcg_temp_free_i64(tmp
);
5239 tmp
= gen_mulu_i64_i32(a
, b
);
5240 tcg_gen_mov_i64(dest
, tmp
);
5241 tcg_temp_free_i64(tmp
);
5246 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5247 Don't forget to clean them now. */
5249 tcg_temp_free_i32(a
);
5250 tcg_temp_free_i32(b
);
5254 static void gen_neon_narrow_op(int op
, int u
, int size
,
5255 TCGv_i32 dest
, TCGv_i64 src
)
5259 gen_neon_unarrow_sats(size
, dest
, src
);
5261 gen_neon_narrow(size
, dest
, src
);
5265 gen_neon_narrow_satu(size
, dest
, src
);
5267 gen_neon_narrow_sats(size
, dest
, src
);
5272 /* Symbolic constants for op fields for Neon 3-register same-length.
5273 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5276 #define NEON_3R_VHADD 0
5277 #define NEON_3R_VQADD 1
5278 #define NEON_3R_VRHADD 2
5279 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5280 #define NEON_3R_VHSUB 4
5281 #define NEON_3R_VQSUB 5
5282 #define NEON_3R_VCGT 6
5283 #define NEON_3R_VCGE 7
5284 #define NEON_3R_VSHL 8
5285 #define NEON_3R_VQSHL 9
5286 #define NEON_3R_VRSHL 10
5287 #define NEON_3R_VQRSHL 11
5288 #define NEON_3R_VMAX 12
5289 #define NEON_3R_VMIN 13
5290 #define NEON_3R_VABD 14
5291 #define NEON_3R_VABA 15
5292 #define NEON_3R_VADD_VSUB 16
5293 #define NEON_3R_VTST_VCEQ 17
5294 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5295 #define NEON_3R_VMUL 19
5296 #define NEON_3R_VPMAX 20
5297 #define NEON_3R_VPMIN 21
5298 #define NEON_3R_VQDMULH_VQRDMULH 22
5299 #define NEON_3R_VPADD 23
5300 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5301 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5302 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5303 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5304 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5305 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5306 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5307 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5309 static const uint8_t neon_3r_sizes
[] = {
5310 [NEON_3R_VHADD
] = 0x7,
5311 [NEON_3R_VQADD
] = 0xf,
5312 [NEON_3R_VRHADD
] = 0x7,
5313 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5314 [NEON_3R_VHSUB
] = 0x7,
5315 [NEON_3R_VQSUB
] = 0xf,
5316 [NEON_3R_VCGT
] = 0x7,
5317 [NEON_3R_VCGE
] = 0x7,
5318 [NEON_3R_VSHL
] = 0xf,
5319 [NEON_3R_VQSHL
] = 0xf,
5320 [NEON_3R_VRSHL
] = 0xf,
5321 [NEON_3R_VQRSHL
] = 0xf,
5322 [NEON_3R_VMAX
] = 0x7,
5323 [NEON_3R_VMIN
] = 0x7,
5324 [NEON_3R_VABD
] = 0x7,
5325 [NEON_3R_VABA
] = 0x7,
5326 [NEON_3R_VADD_VSUB
] = 0xf,
5327 [NEON_3R_VTST_VCEQ
] = 0x7,
5328 [NEON_3R_VML
] = 0x7,
5329 [NEON_3R_VMUL
] = 0x7,
5330 [NEON_3R_VPMAX
] = 0x7,
5331 [NEON_3R_VPMIN
] = 0x7,
5332 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5333 [NEON_3R_VPADD
] = 0x7,
5334 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5335 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5336 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5337 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5338 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5339 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5340 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5341 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5344 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5345 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5348 #define NEON_2RM_VREV64 0
5349 #define NEON_2RM_VREV32 1
5350 #define NEON_2RM_VREV16 2
5351 #define NEON_2RM_VPADDL 4
5352 #define NEON_2RM_VPADDL_U 5
5353 #define NEON_2RM_AESE 6 /* Includes AESD */
5354 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5355 #define NEON_2RM_VCLS 8
5356 #define NEON_2RM_VCLZ 9
5357 #define NEON_2RM_VCNT 10
5358 #define NEON_2RM_VMVN 11
5359 #define NEON_2RM_VPADAL 12
5360 #define NEON_2RM_VPADAL_U 13
5361 #define NEON_2RM_VQABS 14
5362 #define NEON_2RM_VQNEG 15
5363 #define NEON_2RM_VCGT0 16
5364 #define NEON_2RM_VCGE0 17
5365 #define NEON_2RM_VCEQ0 18
5366 #define NEON_2RM_VCLE0 19
5367 #define NEON_2RM_VCLT0 20
5368 #define NEON_2RM_SHA1H 21
5369 #define NEON_2RM_VABS 22
5370 #define NEON_2RM_VNEG 23
5371 #define NEON_2RM_VCGT0_F 24
5372 #define NEON_2RM_VCGE0_F 25
5373 #define NEON_2RM_VCEQ0_F 26
5374 #define NEON_2RM_VCLE0_F 27
5375 #define NEON_2RM_VCLT0_F 28
5376 #define NEON_2RM_VABS_F 30
5377 #define NEON_2RM_VNEG_F 31
5378 #define NEON_2RM_VSWP 32
5379 #define NEON_2RM_VTRN 33
5380 #define NEON_2RM_VUZP 34
5381 #define NEON_2RM_VZIP 35
5382 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5383 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5384 #define NEON_2RM_VSHLL 38
5385 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5386 #define NEON_2RM_VRINTN 40
5387 #define NEON_2RM_VRINTX 41
5388 #define NEON_2RM_VRINTA 42
5389 #define NEON_2RM_VRINTZ 43
5390 #define NEON_2RM_VCVT_F16_F32 44
5391 #define NEON_2RM_VRINTM 45
5392 #define NEON_2RM_VCVT_F32_F16 46
5393 #define NEON_2RM_VRINTP 47
5394 #define NEON_2RM_VCVTAU 48
5395 #define NEON_2RM_VCVTAS 49
5396 #define NEON_2RM_VCVTNU 50
5397 #define NEON_2RM_VCVTNS 51
5398 #define NEON_2RM_VCVTPU 52
5399 #define NEON_2RM_VCVTPS 53
5400 #define NEON_2RM_VCVTMU 54
5401 #define NEON_2RM_VCVTMS 55
5402 #define NEON_2RM_VRECPE 56
5403 #define NEON_2RM_VRSQRTE 57
5404 #define NEON_2RM_VRECPE_F 58
5405 #define NEON_2RM_VRSQRTE_F 59
5406 #define NEON_2RM_VCVT_FS 60
5407 #define NEON_2RM_VCVT_FU 61
5408 #define NEON_2RM_VCVT_SF 62
5409 #define NEON_2RM_VCVT_UF 63
5411 static int neon_2rm_is_float_op(int op
)
5413 /* Return true if this neon 2reg-misc op is float-to-float */
5414 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5415 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5416 op
== NEON_2RM_VRINTM
||
5417 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5418 op
>= NEON_2RM_VRECPE_F
);
5421 static bool neon_2rm_is_v8_op(int op
)
5423 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5425 case NEON_2RM_VRINTN
:
5426 case NEON_2RM_VRINTA
:
5427 case NEON_2RM_VRINTM
:
5428 case NEON_2RM_VRINTP
:
5429 case NEON_2RM_VRINTZ
:
5430 case NEON_2RM_VRINTX
:
5431 case NEON_2RM_VCVTAU
:
5432 case NEON_2RM_VCVTAS
:
5433 case NEON_2RM_VCVTNU
:
5434 case NEON_2RM_VCVTNS
:
5435 case NEON_2RM_VCVTPU
:
5436 case NEON_2RM_VCVTPS
:
5437 case NEON_2RM_VCVTMU
:
5438 case NEON_2RM_VCVTMS
:
5445 /* Each entry in this array has bit n set if the insn allows
5446 * size value n (otherwise it will UNDEF). Since unallocated
5447 * op values will have no bits set they always UNDEF.
5449 static const uint8_t neon_2rm_sizes
[] = {
5450 [NEON_2RM_VREV64
] = 0x7,
5451 [NEON_2RM_VREV32
] = 0x3,
5452 [NEON_2RM_VREV16
] = 0x1,
5453 [NEON_2RM_VPADDL
] = 0x7,
5454 [NEON_2RM_VPADDL_U
] = 0x7,
5455 [NEON_2RM_AESE
] = 0x1,
5456 [NEON_2RM_AESMC
] = 0x1,
5457 [NEON_2RM_VCLS
] = 0x7,
5458 [NEON_2RM_VCLZ
] = 0x7,
5459 [NEON_2RM_VCNT
] = 0x1,
5460 [NEON_2RM_VMVN
] = 0x1,
5461 [NEON_2RM_VPADAL
] = 0x7,
5462 [NEON_2RM_VPADAL_U
] = 0x7,
5463 [NEON_2RM_VQABS
] = 0x7,
5464 [NEON_2RM_VQNEG
] = 0x7,
5465 [NEON_2RM_VCGT0
] = 0x7,
5466 [NEON_2RM_VCGE0
] = 0x7,
5467 [NEON_2RM_VCEQ0
] = 0x7,
5468 [NEON_2RM_VCLE0
] = 0x7,
5469 [NEON_2RM_VCLT0
] = 0x7,
5470 [NEON_2RM_SHA1H
] = 0x4,
5471 [NEON_2RM_VABS
] = 0x7,
5472 [NEON_2RM_VNEG
] = 0x7,
5473 [NEON_2RM_VCGT0_F
] = 0x4,
5474 [NEON_2RM_VCGE0_F
] = 0x4,
5475 [NEON_2RM_VCEQ0_F
] = 0x4,
5476 [NEON_2RM_VCLE0_F
] = 0x4,
5477 [NEON_2RM_VCLT0_F
] = 0x4,
5478 [NEON_2RM_VABS_F
] = 0x4,
5479 [NEON_2RM_VNEG_F
] = 0x4,
5480 [NEON_2RM_VSWP
] = 0x1,
5481 [NEON_2RM_VTRN
] = 0x7,
5482 [NEON_2RM_VUZP
] = 0x7,
5483 [NEON_2RM_VZIP
] = 0x7,
5484 [NEON_2RM_VMOVN
] = 0x7,
5485 [NEON_2RM_VQMOVN
] = 0x7,
5486 [NEON_2RM_VSHLL
] = 0x7,
5487 [NEON_2RM_SHA1SU1
] = 0x4,
5488 [NEON_2RM_VRINTN
] = 0x4,
5489 [NEON_2RM_VRINTX
] = 0x4,
5490 [NEON_2RM_VRINTA
] = 0x4,
5491 [NEON_2RM_VRINTZ
] = 0x4,
5492 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5493 [NEON_2RM_VRINTM
] = 0x4,
5494 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5495 [NEON_2RM_VRINTP
] = 0x4,
5496 [NEON_2RM_VCVTAU
] = 0x4,
5497 [NEON_2RM_VCVTAS
] = 0x4,
5498 [NEON_2RM_VCVTNU
] = 0x4,
5499 [NEON_2RM_VCVTNS
] = 0x4,
5500 [NEON_2RM_VCVTPU
] = 0x4,
5501 [NEON_2RM_VCVTPS
] = 0x4,
5502 [NEON_2RM_VCVTMU
] = 0x4,
5503 [NEON_2RM_VCVTMS
] = 0x4,
5504 [NEON_2RM_VRECPE
] = 0x4,
5505 [NEON_2RM_VRSQRTE
] = 0x4,
5506 [NEON_2RM_VRECPE_F
] = 0x4,
5507 [NEON_2RM_VRSQRTE_F
] = 0x4,
5508 [NEON_2RM_VCVT_FS
] = 0x4,
5509 [NEON_2RM_VCVT_FU
] = 0x4,
5510 [NEON_2RM_VCVT_SF
] = 0x4,
5511 [NEON_2RM_VCVT_UF
] = 0x4,
5514 /* Translate a NEON data processing instruction. Return nonzero if the
5515 instruction is invalid.
5516 We process data in a mixture of 32-bit and 64-bit chunks.
5517 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5519 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5531 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5534 /* FIXME: this access check should not take precedence over UNDEF
5535 * for invalid encodings; we will generate incorrect syndrome information
5536 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5538 if (s
->fp_excp_el
) {
5539 gen_exception_insn(s
, 4, EXCP_UDEF
,
5540 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5544 if (!s
->vfp_enabled
)
5546 q
= (insn
& (1 << 6)) != 0;
5547 u
= (insn
>> 24) & 1;
5548 VFP_DREG_D(rd
, insn
);
5549 VFP_DREG_N(rn
, insn
);
5550 VFP_DREG_M(rm
, insn
);
5551 size
= (insn
>> 20) & 3;
5552 if ((insn
& (1 << 23)) == 0) {
5553 /* Three register same length. */
5554 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5555 /* Catch invalid op and bad size combinations: UNDEF */
5556 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5559 /* All insns of this form UNDEF for either this condition or the
5560 * superset of cases "Q==1"; we catch the latter later.
5562 if (q
&& ((rd
| rn
| rm
) & 1)) {
5566 * The SHA-1/SHA-256 3-register instructions require special treatment
5567 * here, as their size field is overloaded as an op type selector, and
5568 * they all consume their input in a single pass.
5570 if (op
== NEON_3R_SHA
) {
5574 if (!u
) { /* SHA-1 */
5575 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5578 tmp
= tcg_const_i32(rd
);
5579 tmp2
= tcg_const_i32(rn
);
5580 tmp3
= tcg_const_i32(rm
);
5581 tmp4
= tcg_const_i32(size
);
5582 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5583 tcg_temp_free_i32(tmp4
);
5584 } else { /* SHA-256 */
5585 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5588 tmp
= tcg_const_i32(rd
);
5589 tmp2
= tcg_const_i32(rn
);
5590 tmp3
= tcg_const_i32(rm
);
5593 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5596 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5599 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5603 tcg_temp_free_i32(tmp
);
5604 tcg_temp_free_i32(tmp2
);
5605 tcg_temp_free_i32(tmp3
);
5608 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5609 /* 64-bit element instructions. */
5610 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5611 neon_load_reg64(cpu_V0
, rn
+ pass
);
5612 neon_load_reg64(cpu_V1
, rm
+ pass
);
5616 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5619 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5625 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5628 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5634 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5636 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5641 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5644 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5650 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5652 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5655 case NEON_3R_VQRSHL
:
5657 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5660 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5664 case NEON_3R_VADD_VSUB
:
5666 tcg_gen_sub_i64(CPU_V001
);
5668 tcg_gen_add_i64(CPU_V001
);
5674 neon_store_reg64(cpu_V0
, rd
+ pass
);
5683 case NEON_3R_VQRSHL
:
5686 /* Shift instruction operands are reversed. */
5701 case NEON_3R_FLOAT_ARITH
:
5702 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5704 case NEON_3R_FLOAT_MINMAX
:
5705 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5707 case NEON_3R_FLOAT_CMP
:
5709 /* no encoding for U=0 C=1x */
5713 case NEON_3R_FLOAT_ACMP
:
5718 case NEON_3R_FLOAT_MISC
:
5719 /* VMAXNM/VMINNM in ARMv8 */
5720 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5725 if (u
&& (size
!= 0)) {
5726 /* UNDEF on invalid size for polynomial subcase */
5731 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5739 if (pairwise
&& q
) {
5740 /* All the pairwise insns UNDEF if Q is set */
5744 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5749 tmp
= neon_load_reg(rn
, 0);
5750 tmp2
= neon_load_reg(rn
, 1);
5752 tmp
= neon_load_reg(rm
, 0);
5753 tmp2
= neon_load_reg(rm
, 1);
5757 tmp
= neon_load_reg(rn
, pass
);
5758 tmp2
= neon_load_reg(rm
, pass
);
5762 GEN_NEON_INTEGER_OP(hadd
);
5765 GEN_NEON_INTEGER_OP_ENV(qadd
);
5767 case NEON_3R_VRHADD
:
5768 GEN_NEON_INTEGER_OP(rhadd
);
5770 case NEON_3R_LOGIC
: /* Logic ops. */
5771 switch ((u
<< 2) | size
) {
5773 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5776 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5779 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5782 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5785 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5788 tmp3
= neon_load_reg(rd
, pass
);
5789 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5790 tcg_temp_free_i32(tmp3
);
5793 tmp3
= neon_load_reg(rd
, pass
);
5794 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5795 tcg_temp_free_i32(tmp3
);
5798 tmp3
= neon_load_reg(rd
, pass
);
5799 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5800 tcg_temp_free_i32(tmp3
);
5805 GEN_NEON_INTEGER_OP(hsub
);
5808 GEN_NEON_INTEGER_OP_ENV(qsub
);
5811 GEN_NEON_INTEGER_OP(cgt
);
5814 GEN_NEON_INTEGER_OP(cge
);
5817 GEN_NEON_INTEGER_OP(shl
);
5820 GEN_NEON_INTEGER_OP_ENV(qshl
);
5823 GEN_NEON_INTEGER_OP(rshl
);
5825 case NEON_3R_VQRSHL
:
5826 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5829 GEN_NEON_INTEGER_OP(max
);
5832 GEN_NEON_INTEGER_OP(min
);
5835 GEN_NEON_INTEGER_OP(abd
);
5838 GEN_NEON_INTEGER_OP(abd
);
5839 tcg_temp_free_i32(tmp2
);
5840 tmp2
= neon_load_reg(rd
, pass
);
5841 gen_neon_add(size
, tmp
, tmp2
);
5843 case NEON_3R_VADD_VSUB
:
5844 if (!u
) { /* VADD */
5845 gen_neon_add(size
, tmp
, tmp2
);
5848 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5849 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5850 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5855 case NEON_3R_VTST_VCEQ
:
5856 if (!u
) { /* VTST */
5858 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5859 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5860 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5865 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5866 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5867 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5872 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5874 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5875 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5876 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5879 tcg_temp_free_i32(tmp2
);
5880 tmp2
= neon_load_reg(rd
, pass
);
5882 gen_neon_rsb(size
, tmp
, tmp2
);
5884 gen_neon_add(size
, tmp
, tmp2
);
5888 if (u
) { /* polynomial */
5889 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5890 } else { /* Integer */
5892 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5893 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5894 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5900 GEN_NEON_INTEGER_OP(pmax
);
5903 GEN_NEON_INTEGER_OP(pmin
);
5905 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5906 if (!u
) { /* VQDMULH */
5909 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5912 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5916 } else { /* VQRDMULH */
5919 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5922 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5930 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5931 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5932 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5936 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5938 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5939 switch ((u
<< 2) | size
) {
5942 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5945 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5948 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5953 tcg_temp_free_ptr(fpstatus
);
5956 case NEON_3R_FLOAT_MULTIPLY
:
5958 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5959 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5961 tcg_temp_free_i32(tmp2
);
5962 tmp2
= neon_load_reg(rd
, pass
);
5964 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5966 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5969 tcg_temp_free_ptr(fpstatus
);
5972 case NEON_3R_FLOAT_CMP
:
5974 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5976 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5979 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5981 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5984 tcg_temp_free_ptr(fpstatus
);
5987 case NEON_3R_FLOAT_ACMP
:
5989 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5991 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5993 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5995 tcg_temp_free_ptr(fpstatus
);
5998 case NEON_3R_FLOAT_MINMAX
:
6000 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6002 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6004 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6006 tcg_temp_free_ptr(fpstatus
);
6009 case NEON_3R_FLOAT_MISC
:
6012 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6014 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6016 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6018 tcg_temp_free_ptr(fpstatus
);
6021 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6023 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6029 /* VFMA, VFMS: fused multiply-add */
6030 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6031 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6034 gen_helper_vfp_negs(tmp
, tmp
);
6036 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6037 tcg_temp_free_i32(tmp3
);
6038 tcg_temp_free_ptr(fpstatus
);
6044 tcg_temp_free_i32(tmp2
);
6046 /* Save the result. For elementwise operations we can put it
6047 straight into the destination register. For pairwise operations
6048 we have to be careful to avoid clobbering the source operands. */
6049 if (pairwise
&& rd
== rm
) {
6050 neon_store_scratch(pass
, tmp
);
6052 neon_store_reg(rd
, pass
, tmp
);
6056 if (pairwise
&& rd
== rm
) {
6057 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6058 tmp
= neon_load_scratch(pass
);
6059 neon_store_reg(rd
, pass
, tmp
);
6062 /* End of 3 register same size operations. */
6063 } else if (insn
& (1 << 4)) {
6064 if ((insn
& 0x00380080) != 0) {
6065 /* Two registers and shift. */
6066 op
= (insn
>> 8) & 0xf;
6067 if (insn
& (1 << 7)) {
6075 while ((insn
& (1 << (size
+ 19))) == 0)
6078 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6079 /* To avoid excessive duplication of ops we implement shift
6080 by immediate using the variable shift operations. */
6082 /* Shift by immediate:
6083 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6084 if (q
&& ((rd
| rm
) & 1)) {
6087 if (!u
&& (op
== 4 || op
== 6)) {
6090 /* Right shifts are encoded as N - shift, where N is the
6091 element size in bits. */
6093 shift
= shift
- (1 << (size
+ 3));
6101 imm
= (uint8_t) shift
;
6106 imm
= (uint16_t) shift
;
6117 for (pass
= 0; pass
< count
; pass
++) {
6119 neon_load_reg64(cpu_V0
, rm
+ pass
);
6120 tcg_gen_movi_i64(cpu_V1
, imm
);
6125 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6127 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6132 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6134 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6137 case 5: /* VSHL, VSLI */
6138 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6140 case 6: /* VQSHLU */
6141 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6146 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6149 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6154 if (op
== 1 || op
== 3) {
6156 neon_load_reg64(cpu_V1
, rd
+ pass
);
6157 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6158 } else if (op
== 4 || (op
== 5 && u
)) {
6160 neon_load_reg64(cpu_V1
, rd
+ pass
);
6162 if (shift
< -63 || shift
> 63) {
6166 mask
= 0xffffffffffffffffull
>> -shift
;
6168 mask
= 0xffffffffffffffffull
<< shift
;
6171 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6172 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6174 neon_store_reg64(cpu_V0
, rd
+ pass
);
6175 } else { /* size < 3 */
6176 /* Operands in T0 and T1. */
6177 tmp
= neon_load_reg(rm
, pass
);
6178 tmp2
= tcg_temp_new_i32();
6179 tcg_gen_movi_i32(tmp2
, imm
);
6183 GEN_NEON_INTEGER_OP(shl
);
6187 GEN_NEON_INTEGER_OP(rshl
);
6190 case 5: /* VSHL, VSLI */
6192 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6193 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6194 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6198 case 6: /* VQSHLU */
6201 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6205 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6209 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6217 GEN_NEON_INTEGER_OP_ENV(qshl
);
6220 tcg_temp_free_i32(tmp2
);
6222 if (op
== 1 || op
== 3) {
6224 tmp2
= neon_load_reg(rd
, pass
);
6225 gen_neon_add(size
, tmp
, tmp2
);
6226 tcg_temp_free_i32(tmp2
);
6227 } else if (op
== 4 || (op
== 5 && u
)) {
6232 mask
= 0xff >> -shift
;
6234 mask
= (uint8_t)(0xff << shift
);
6240 mask
= 0xffff >> -shift
;
6242 mask
= (uint16_t)(0xffff << shift
);
6246 if (shift
< -31 || shift
> 31) {
6250 mask
= 0xffffffffu
>> -shift
;
6252 mask
= 0xffffffffu
<< shift
;
6258 tmp2
= neon_load_reg(rd
, pass
);
6259 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6260 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6261 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6262 tcg_temp_free_i32(tmp2
);
6264 neon_store_reg(rd
, pass
, tmp
);
6267 } else if (op
< 10) {
6268 /* Shift by immediate and narrow:
6269 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6270 int input_unsigned
= (op
== 8) ? !u
: u
;
6274 shift
= shift
- (1 << (size
+ 3));
6277 tmp64
= tcg_const_i64(shift
);
6278 neon_load_reg64(cpu_V0
, rm
);
6279 neon_load_reg64(cpu_V1
, rm
+ 1);
6280 for (pass
= 0; pass
< 2; pass
++) {
6288 if (input_unsigned
) {
6289 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6291 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6294 if (input_unsigned
) {
6295 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6297 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6300 tmp
= tcg_temp_new_i32();
6301 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6302 neon_store_reg(rd
, pass
, tmp
);
6304 tcg_temp_free_i64(tmp64
);
6307 imm
= (uint16_t)shift
;
6311 imm
= (uint32_t)shift
;
6313 tmp2
= tcg_const_i32(imm
);
6314 tmp4
= neon_load_reg(rm
+ 1, 0);
6315 tmp5
= neon_load_reg(rm
+ 1, 1);
6316 for (pass
= 0; pass
< 2; pass
++) {
6318 tmp
= neon_load_reg(rm
, 0);
6322 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6325 tmp3
= neon_load_reg(rm
, 1);
6329 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6331 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6332 tcg_temp_free_i32(tmp
);
6333 tcg_temp_free_i32(tmp3
);
6334 tmp
= tcg_temp_new_i32();
6335 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6336 neon_store_reg(rd
, pass
, tmp
);
6338 tcg_temp_free_i32(tmp2
);
6340 } else if (op
== 10) {
6342 if (q
|| (rd
& 1)) {
6345 tmp
= neon_load_reg(rm
, 0);
6346 tmp2
= neon_load_reg(rm
, 1);
6347 for (pass
= 0; pass
< 2; pass
++) {
6351 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6354 /* The shift is less than the width of the source
6355 type, so we can just shift the whole register. */
6356 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6357 /* Widen the result of shift: we need to clear
6358 * the potential overflow bits resulting from
6359 * left bits of the narrow input appearing as
6360 * right bits of left the neighbour narrow
6362 if (size
< 2 || !u
) {
6365 imm
= (0xffu
>> (8 - shift
));
6367 } else if (size
== 1) {
6368 imm
= 0xffff >> (16 - shift
);
6371 imm
= 0xffffffff >> (32 - shift
);
6374 imm64
= imm
| (((uint64_t)imm
) << 32);
6378 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6381 neon_store_reg64(cpu_V0
, rd
+ pass
);
6383 } else if (op
>= 14) {
6384 /* VCVT fixed-point. */
6385 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6388 /* We have already masked out the must-be-1 top bit of imm6,
6389 * hence this 32-shift where the ARM ARM has 64-imm6.
6392 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6393 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6396 gen_vfp_ulto(0, shift
, 1);
6398 gen_vfp_slto(0, shift
, 1);
6401 gen_vfp_toul(0, shift
, 1);
6403 gen_vfp_tosl(0, shift
, 1);
6405 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6410 } else { /* (insn & 0x00380080) == 0 */
6412 if (q
&& (rd
& 1)) {
6416 op
= (insn
>> 8) & 0xf;
6417 /* One register and immediate. */
6418 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6419 invert
= (insn
& (1 << 5)) != 0;
6420 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6421 * We choose to not special-case this and will behave as if a
6422 * valid constant encoding of 0 had been given.
6441 imm
= (imm
<< 8) | (imm
<< 24);
6444 imm
= (imm
<< 8) | 0xff;
6447 imm
= (imm
<< 16) | 0xffff;
6450 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6458 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6459 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6465 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6466 if (op
& 1 && op
< 12) {
6467 tmp
= neon_load_reg(rd
, pass
);
6469 /* The immediate value has already been inverted, so
6471 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6473 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6477 tmp
= tcg_temp_new_i32();
6478 if (op
== 14 && invert
) {
6482 for (n
= 0; n
< 4; n
++) {
6483 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6484 val
|= 0xff << (n
* 8);
6486 tcg_gen_movi_i32(tmp
, val
);
6488 tcg_gen_movi_i32(tmp
, imm
);
6491 neon_store_reg(rd
, pass
, tmp
);
6494 } else { /* (insn & 0x00800010 == 0x00800000) */
6496 op
= (insn
>> 8) & 0xf;
6497 if ((insn
& (1 << 6)) == 0) {
6498 /* Three registers of different lengths. */
6502 /* undefreq: bit 0 : UNDEF if size == 0
6503 * bit 1 : UNDEF if size == 1
6504 * bit 2 : UNDEF if size == 2
6505 * bit 3 : UNDEF if U == 1
6506 * Note that [2:0] set implies 'always UNDEF'
6509 /* prewiden, src1_wide, src2_wide, undefreq */
6510 static const int neon_3reg_wide
[16][4] = {
6511 {1, 0, 0, 0}, /* VADDL */
6512 {1, 1, 0, 0}, /* VADDW */
6513 {1, 0, 0, 0}, /* VSUBL */
6514 {1, 1, 0, 0}, /* VSUBW */
6515 {0, 1, 1, 0}, /* VADDHN */
6516 {0, 0, 0, 0}, /* VABAL */
6517 {0, 1, 1, 0}, /* VSUBHN */
6518 {0, 0, 0, 0}, /* VABDL */
6519 {0, 0, 0, 0}, /* VMLAL */
6520 {0, 0, 0, 9}, /* VQDMLAL */
6521 {0, 0, 0, 0}, /* VMLSL */
6522 {0, 0, 0, 9}, /* VQDMLSL */
6523 {0, 0, 0, 0}, /* Integer VMULL */
6524 {0, 0, 0, 1}, /* VQDMULL */
6525 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6526 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6529 prewiden
= neon_3reg_wide
[op
][0];
6530 src1_wide
= neon_3reg_wide
[op
][1];
6531 src2_wide
= neon_3reg_wide
[op
][2];
6532 undefreq
= neon_3reg_wide
[op
][3];
6534 if ((undefreq
& (1 << size
)) ||
6535 ((undefreq
& 8) && u
)) {
6538 if ((src1_wide
&& (rn
& 1)) ||
6539 (src2_wide
&& (rm
& 1)) ||
6540 (!src2_wide
&& (rd
& 1))) {
6544 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6545 * outside the loop below as it only performs a single pass.
6547 if (op
== 14 && size
== 2) {
6548 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6550 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6553 tcg_rn
= tcg_temp_new_i64();
6554 tcg_rm
= tcg_temp_new_i64();
6555 tcg_rd
= tcg_temp_new_i64();
6556 neon_load_reg64(tcg_rn
, rn
);
6557 neon_load_reg64(tcg_rm
, rm
);
6558 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6559 neon_store_reg64(tcg_rd
, rd
);
6560 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6561 neon_store_reg64(tcg_rd
, rd
+ 1);
6562 tcg_temp_free_i64(tcg_rn
);
6563 tcg_temp_free_i64(tcg_rm
);
6564 tcg_temp_free_i64(tcg_rd
);
6568 /* Avoid overlapping operands. Wide source operands are
6569 always aligned so will never overlap with wide
6570 destinations in problematic ways. */
6571 if (rd
== rm
&& !src2_wide
) {
6572 tmp
= neon_load_reg(rm
, 1);
6573 neon_store_scratch(2, tmp
);
6574 } else if (rd
== rn
&& !src1_wide
) {
6575 tmp
= neon_load_reg(rn
, 1);
6576 neon_store_scratch(2, tmp
);
6578 TCGV_UNUSED_I32(tmp3
);
6579 for (pass
= 0; pass
< 2; pass
++) {
6581 neon_load_reg64(cpu_V0
, rn
+ pass
);
6582 TCGV_UNUSED_I32(tmp
);
6584 if (pass
== 1 && rd
== rn
) {
6585 tmp
= neon_load_scratch(2);
6587 tmp
= neon_load_reg(rn
, pass
);
6590 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6594 neon_load_reg64(cpu_V1
, rm
+ pass
);
6595 TCGV_UNUSED_I32(tmp2
);
6597 if (pass
== 1 && rd
== rm
) {
6598 tmp2
= neon_load_scratch(2);
6600 tmp2
= neon_load_reg(rm
, pass
);
6603 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6607 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6608 gen_neon_addl(size
);
6610 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6611 gen_neon_subl(size
);
6613 case 5: case 7: /* VABAL, VABDL */
6614 switch ((size
<< 1) | u
) {
6616 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6619 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6622 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6625 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6628 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6631 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6635 tcg_temp_free_i32(tmp2
);
6636 tcg_temp_free_i32(tmp
);
6638 case 8: case 9: case 10: case 11: case 12: case 13:
6639 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6640 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6642 case 14: /* Polynomial VMULL */
6643 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6644 tcg_temp_free_i32(tmp2
);
6645 tcg_temp_free_i32(tmp
);
6647 default: /* 15 is RESERVED: caught earlier */
6652 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6653 neon_store_reg64(cpu_V0
, rd
+ pass
);
6654 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6656 neon_load_reg64(cpu_V1
, rd
+ pass
);
6658 case 10: /* VMLSL */
6659 gen_neon_negl(cpu_V0
, size
);
6661 case 5: case 8: /* VABAL, VMLAL */
6662 gen_neon_addl(size
);
6664 case 9: case 11: /* VQDMLAL, VQDMLSL */
6665 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6667 gen_neon_negl(cpu_V0
, size
);
6669 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6674 neon_store_reg64(cpu_V0
, rd
+ pass
);
6675 } else if (op
== 4 || op
== 6) {
6676 /* Narrowing operation. */
6677 tmp
= tcg_temp_new_i32();
6681 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6684 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6687 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6688 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6695 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6698 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6701 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6702 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6703 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6711 neon_store_reg(rd
, 0, tmp3
);
6712 neon_store_reg(rd
, 1, tmp
);
6715 /* Write back the result. */
6716 neon_store_reg64(cpu_V0
, rd
+ pass
);
6720 /* Two registers and a scalar. NB that for ops of this form
6721 * the ARM ARM labels bit 24 as Q, but it is in our variable
6728 case 1: /* Float VMLA scalar */
6729 case 5: /* Floating point VMLS scalar */
6730 case 9: /* Floating point VMUL scalar */
6735 case 0: /* Integer VMLA scalar */
6736 case 4: /* Integer VMLS scalar */
6737 case 8: /* Integer VMUL scalar */
6738 case 12: /* VQDMULH scalar */
6739 case 13: /* VQRDMULH scalar */
6740 if (u
&& ((rd
| rn
) & 1)) {
6743 tmp
= neon_get_scalar(size
, rm
);
6744 neon_store_scratch(0, tmp
);
6745 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6746 tmp
= neon_load_scratch(0);
6747 tmp2
= neon_load_reg(rn
, pass
);
6750 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6752 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6754 } else if (op
== 13) {
6756 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6758 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6760 } else if (op
& 1) {
6761 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6762 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6763 tcg_temp_free_ptr(fpstatus
);
6766 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6767 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6768 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6772 tcg_temp_free_i32(tmp2
);
6775 tmp2
= neon_load_reg(rd
, pass
);
6778 gen_neon_add(size
, tmp
, tmp2
);
6782 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6783 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6784 tcg_temp_free_ptr(fpstatus
);
6788 gen_neon_rsb(size
, tmp
, tmp2
);
6792 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6793 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6794 tcg_temp_free_ptr(fpstatus
);
6800 tcg_temp_free_i32(tmp2
);
6802 neon_store_reg(rd
, pass
, tmp
);
6805 case 3: /* VQDMLAL scalar */
6806 case 7: /* VQDMLSL scalar */
6807 case 11: /* VQDMULL scalar */
6812 case 2: /* VMLAL sclar */
6813 case 6: /* VMLSL scalar */
6814 case 10: /* VMULL scalar */
6818 tmp2
= neon_get_scalar(size
, rm
);
6819 /* We need a copy of tmp2 because gen_neon_mull
6820 * deletes it during pass 0. */
6821 tmp4
= tcg_temp_new_i32();
6822 tcg_gen_mov_i32(tmp4
, tmp2
);
6823 tmp3
= neon_load_reg(rn
, 1);
6825 for (pass
= 0; pass
< 2; pass
++) {
6827 tmp
= neon_load_reg(rn
, 0);
6832 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6834 neon_load_reg64(cpu_V1
, rd
+ pass
);
6838 gen_neon_negl(cpu_V0
, size
);
6841 gen_neon_addl(size
);
6844 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6846 gen_neon_negl(cpu_V0
, size
);
6848 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6854 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6859 neon_store_reg64(cpu_V0
, rd
+ pass
);
6864 default: /* 14 and 15 are RESERVED */
6868 } else { /* size == 3 */
6871 imm
= (insn
>> 8) & 0xf;
6876 if (q
&& ((rd
| rn
| rm
) & 1)) {
6881 neon_load_reg64(cpu_V0
, rn
);
6883 neon_load_reg64(cpu_V1
, rn
+ 1);
6885 } else if (imm
== 8) {
6886 neon_load_reg64(cpu_V0
, rn
+ 1);
6888 neon_load_reg64(cpu_V1
, rm
);
6891 tmp64
= tcg_temp_new_i64();
6893 neon_load_reg64(cpu_V0
, rn
);
6894 neon_load_reg64(tmp64
, rn
+ 1);
6896 neon_load_reg64(cpu_V0
, rn
+ 1);
6897 neon_load_reg64(tmp64
, rm
);
6899 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6900 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6901 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6903 neon_load_reg64(cpu_V1
, rm
);
6905 neon_load_reg64(cpu_V1
, rm
+ 1);
6908 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6909 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6910 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6911 tcg_temp_free_i64(tmp64
);
6914 neon_load_reg64(cpu_V0
, rn
);
6915 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6916 neon_load_reg64(cpu_V1
, rm
);
6917 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6918 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6920 neon_store_reg64(cpu_V0
, rd
);
6922 neon_store_reg64(cpu_V1
, rd
+ 1);
6924 } else if ((insn
& (1 << 11)) == 0) {
6925 /* Two register misc. */
6926 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6927 size
= (insn
>> 18) & 3;
6928 /* UNDEF for unknown op values and bad op-size combinations */
6929 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6932 if (neon_2rm_is_v8_op(op
) &&
6933 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6936 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6937 q
&& ((rm
| rd
) & 1)) {
6941 case NEON_2RM_VREV64
:
6942 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6943 tmp
= neon_load_reg(rm
, pass
* 2);
6944 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6946 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6947 case 1: gen_swap_half(tmp
); break;
6948 case 2: /* no-op */ break;
6951 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6953 neon_store_reg(rd
, pass
* 2, tmp2
);
6956 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6957 case 1: gen_swap_half(tmp2
); break;
6960 neon_store_reg(rd
, pass
* 2, tmp2
);
6964 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6965 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6966 for (pass
= 0; pass
< q
+ 1; pass
++) {
6967 tmp
= neon_load_reg(rm
, pass
* 2);
6968 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6969 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6970 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6972 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6973 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6974 case 2: tcg_gen_add_i64(CPU_V001
); break;
6977 if (op
>= NEON_2RM_VPADAL
) {
6979 neon_load_reg64(cpu_V1
, rd
+ pass
);
6980 gen_neon_addl(size
);
6982 neon_store_reg64(cpu_V0
, rd
+ pass
);
6988 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6989 tmp
= neon_load_reg(rm
, n
);
6990 tmp2
= neon_load_reg(rd
, n
+ 1);
6991 neon_store_reg(rm
, n
, tmp2
);
6992 neon_store_reg(rd
, n
+ 1, tmp
);
6999 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7004 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7008 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7009 /* also VQMOVUN; op field and mnemonics don't line up */
7013 TCGV_UNUSED_I32(tmp2
);
7014 for (pass
= 0; pass
< 2; pass
++) {
7015 neon_load_reg64(cpu_V0
, rm
+ pass
);
7016 tmp
= tcg_temp_new_i32();
7017 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7022 neon_store_reg(rd
, 0, tmp2
);
7023 neon_store_reg(rd
, 1, tmp
);
7027 case NEON_2RM_VSHLL
:
7028 if (q
|| (rd
& 1)) {
7031 tmp
= neon_load_reg(rm
, 0);
7032 tmp2
= neon_load_reg(rm
, 1);
7033 for (pass
= 0; pass
< 2; pass
++) {
7036 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7037 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7038 neon_store_reg64(cpu_V0
, rd
+ pass
);
7041 case NEON_2RM_VCVT_F16_F32
:
7042 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7046 tmp
= tcg_temp_new_i32();
7047 tmp2
= tcg_temp_new_i32();
7048 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7049 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7050 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7051 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7052 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7053 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7054 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7055 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7056 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7057 neon_store_reg(rd
, 0, tmp2
);
7058 tmp2
= tcg_temp_new_i32();
7059 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7060 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7061 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7062 neon_store_reg(rd
, 1, tmp2
);
7063 tcg_temp_free_i32(tmp
);
7065 case NEON_2RM_VCVT_F32_F16
:
7066 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7070 tmp3
= tcg_temp_new_i32();
7071 tmp
= neon_load_reg(rm
, 0);
7072 tmp2
= neon_load_reg(rm
, 1);
7073 tcg_gen_ext16u_i32(tmp3
, tmp
);
7074 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7075 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7076 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7077 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7078 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7079 tcg_temp_free_i32(tmp
);
7080 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7081 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7082 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7083 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7084 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7085 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7086 tcg_temp_free_i32(tmp2
);
7087 tcg_temp_free_i32(tmp3
);
7089 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7090 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
7091 || ((rm
| rd
) & 1)) {
7094 tmp
= tcg_const_i32(rd
);
7095 tmp2
= tcg_const_i32(rm
);
7097 /* Bit 6 is the lowest opcode bit; it distinguishes between
7098 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7100 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7102 if (op
== NEON_2RM_AESE
) {
7103 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
7105 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
7107 tcg_temp_free_i32(tmp
);
7108 tcg_temp_free_i32(tmp2
);
7109 tcg_temp_free_i32(tmp3
);
7111 case NEON_2RM_SHA1H
:
7112 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7113 || ((rm
| rd
) & 1)) {
7116 tmp
= tcg_const_i32(rd
);
7117 tmp2
= tcg_const_i32(rm
);
7119 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
7121 tcg_temp_free_i32(tmp
);
7122 tcg_temp_free_i32(tmp2
);
7124 case NEON_2RM_SHA1SU1
:
7125 if ((rm
| rd
) & 1) {
7128 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7130 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7133 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7136 tmp
= tcg_const_i32(rd
);
7137 tmp2
= tcg_const_i32(rm
);
7139 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
7141 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7143 tcg_temp_free_i32(tmp
);
7144 tcg_temp_free_i32(tmp2
);
7148 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7149 if (neon_2rm_is_float_op(op
)) {
7150 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7151 neon_reg_offset(rm
, pass
));
7152 TCGV_UNUSED_I32(tmp
);
7154 tmp
= neon_load_reg(rm
, pass
);
7157 case NEON_2RM_VREV32
:
7159 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7160 case 1: gen_swap_half(tmp
); break;
7164 case NEON_2RM_VREV16
:
7169 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7170 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7171 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7177 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7178 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7179 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7184 gen_helper_neon_cnt_u8(tmp
, tmp
);
7187 tcg_gen_not_i32(tmp
, tmp
);
7189 case NEON_2RM_VQABS
:
7192 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7195 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7198 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7203 case NEON_2RM_VQNEG
:
7206 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7209 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7212 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7217 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7218 tmp2
= tcg_const_i32(0);
7220 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7221 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7222 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7225 tcg_temp_free_i32(tmp2
);
7226 if (op
== NEON_2RM_VCLE0
) {
7227 tcg_gen_not_i32(tmp
, tmp
);
7230 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7231 tmp2
= tcg_const_i32(0);
7233 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7234 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7235 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7238 tcg_temp_free_i32(tmp2
);
7239 if (op
== NEON_2RM_VCLT0
) {
7240 tcg_gen_not_i32(tmp
, tmp
);
7243 case NEON_2RM_VCEQ0
:
7244 tmp2
= tcg_const_i32(0);
7246 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7247 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7248 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7251 tcg_temp_free_i32(tmp2
);
7255 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7256 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7257 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7262 tmp2
= tcg_const_i32(0);
7263 gen_neon_rsb(size
, tmp
, tmp2
);
7264 tcg_temp_free_i32(tmp2
);
7266 case NEON_2RM_VCGT0_F
:
7268 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7269 tmp2
= tcg_const_i32(0);
7270 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7271 tcg_temp_free_i32(tmp2
);
7272 tcg_temp_free_ptr(fpstatus
);
7275 case NEON_2RM_VCGE0_F
:
7277 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7278 tmp2
= tcg_const_i32(0);
7279 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7280 tcg_temp_free_i32(tmp2
);
7281 tcg_temp_free_ptr(fpstatus
);
7284 case NEON_2RM_VCEQ0_F
:
7286 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7287 tmp2
= tcg_const_i32(0);
7288 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7289 tcg_temp_free_i32(tmp2
);
7290 tcg_temp_free_ptr(fpstatus
);
7293 case NEON_2RM_VCLE0_F
:
7295 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7296 tmp2
= tcg_const_i32(0);
7297 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7298 tcg_temp_free_i32(tmp2
);
7299 tcg_temp_free_ptr(fpstatus
);
7302 case NEON_2RM_VCLT0_F
:
7304 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7305 tmp2
= tcg_const_i32(0);
7306 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7307 tcg_temp_free_i32(tmp2
);
7308 tcg_temp_free_ptr(fpstatus
);
7311 case NEON_2RM_VABS_F
:
7314 case NEON_2RM_VNEG_F
:
7318 tmp2
= neon_load_reg(rd
, pass
);
7319 neon_store_reg(rm
, pass
, tmp2
);
7322 tmp2
= neon_load_reg(rd
, pass
);
7324 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7325 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7328 neon_store_reg(rm
, pass
, tmp2
);
7330 case NEON_2RM_VRINTN
:
7331 case NEON_2RM_VRINTA
:
7332 case NEON_2RM_VRINTM
:
7333 case NEON_2RM_VRINTP
:
7334 case NEON_2RM_VRINTZ
:
7337 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7340 if (op
== NEON_2RM_VRINTZ
) {
7341 rmode
= FPROUNDING_ZERO
;
7343 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7346 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7347 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7349 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7350 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7352 tcg_temp_free_ptr(fpstatus
);
7353 tcg_temp_free_i32(tcg_rmode
);
7356 case NEON_2RM_VRINTX
:
7358 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7359 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7360 tcg_temp_free_ptr(fpstatus
);
7363 case NEON_2RM_VCVTAU
:
7364 case NEON_2RM_VCVTAS
:
7365 case NEON_2RM_VCVTNU
:
7366 case NEON_2RM_VCVTNS
:
7367 case NEON_2RM_VCVTPU
:
7368 case NEON_2RM_VCVTPS
:
7369 case NEON_2RM_VCVTMU
:
7370 case NEON_2RM_VCVTMS
:
7372 bool is_signed
= !extract32(insn
, 7, 1);
7373 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7374 TCGv_i32 tcg_rmode
, tcg_shift
;
7375 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7377 tcg_shift
= tcg_const_i32(0);
7378 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7379 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7383 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7386 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7390 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7392 tcg_temp_free_i32(tcg_rmode
);
7393 tcg_temp_free_i32(tcg_shift
);
7394 tcg_temp_free_ptr(fpst
);
7397 case NEON_2RM_VRECPE
:
7399 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7400 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7401 tcg_temp_free_ptr(fpstatus
);
7404 case NEON_2RM_VRSQRTE
:
7406 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7407 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7408 tcg_temp_free_ptr(fpstatus
);
7411 case NEON_2RM_VRECPE_F
:
7413 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7414 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7415 tcg_temp_free_ptr(fpstatus
);
7418 case NEON_2RM_VRSQRTE_F
:
7420 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7421 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7422 tcg_temp_free_ptr(fpstatus
);
7425 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7428 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7431 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7432 gen_vfp_tosiz(0, 1);
7434 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7435 gen_vfp_touiz(0, 1);
7438 /* Reserved op values were caught by the
7439 * neon_2rm_sizes[] check earlier.
7443 if (neon_2rm_is_float_op(op
)) {
7444 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7445 neon_reg_offset(rd
, pass
));
7447 neon_store_reg(rd
, pass
, tmp
);
7452 } else if ((insn
& (1 << 10)) == 0) {
7454 int n
= ((insn
>> 8) & 3) + 1;
7455 if ((rn
+ n
) > 32) {
7456 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7457 * helper function running off the end of the register file.
7462 if (insn
& (1 << 6)) {
7463 tmp
= neon_load_reg(rd
, 0);
7465 tmp
= tcg_temp_new_i32();
7466 tcg_gen_movi_i32(tmp
, 0);
7468 tmp2
= neon_load_reg(rm
, 0);
7469 tmp4
= tcg_const_i32(rn
);
7470 tmp5
= tcg_const_i32(n
);
7471 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7472 tcg_temp_free_i32(tmp
);
7473 if (insn
& (1 << 6)) {
7474 tmp
= neon_load_reg(rd
, 1);
7476 tmp
= tcg_temp_new_i32();
7477 tcg_gen_movi_i32(tmp
, 0);
7479 tmp3
= neon_load_reg(rm
, 1);
7480 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7481 tcg_temp_free_i32(tmp5
);
7482 tcg_temp_free_i32(tmp4
);
7483 neon_store_reg(rd
, 0, tmp2
);
7484 neon_store_reg(rd
, 1, tmp3
);
7485 tcg_temp_free_i32(tmp
);
7486 } else if ((insn
& 0x380) == 0) {
7488 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7491 if (insn
& (1 << 19)) {
7492 tmp
= neon_load_reg(rm
, 1);
7494 tmp
= neon_load_reg(rm
, 0);
7496 if (insn
& (1 << 16)) {
7497 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7498 } else if (insn
& (1 << 17)) {
7499 if ((insn
>> 18) & 1)
7500 gen_neon_dup_high16(tmp
);
7502 gen_neon_dup_low16(tmp
);
7504 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7505 tmp2
= tcg_temp_new_i32();
7506 tcg_gen_mov_i32(tmp2
, tmp
);
7507 neon_store_reg(rd
, pass
, tmp2
);
7509 tcg_temp_free_i32(tmp
);
7518 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7520 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7521 const ARMCPRegInfo
*ri
;
7523 cpnum
= (insn
>> 8) & 0xf;
7525 /* First check for coprocessor space used for XScale/iwMMXt insns */
7526 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7527 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7530 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7531 return disas_iwmmxt_insn(s
, insn
);
7532 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7533 return disas_dsp_insn(s
, insn
);
7538 /* Otherwise treat as a generic register access */
7539 is64
= (insn
& (1 << 25)) == 0;
7540 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7548 opc1
= (insn
>> 4) & 0xf;
7550 rt2
= (insn
>> 16) & 0xf;
7552 crn
= (insn
>> 16) & 0xf;
7553 opc1
= (insn
>> 21) & 7;
7554 opc2
= (insn
>> 5) & 7;
7557 isread
= (insn
>> 20) & 1;
7558 rt
= (insn
>> 12) & 0xf;
7560 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7561 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7563 /* Check access permissions */
7564 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7569 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7570 /* Emit code to perform further access permissions checks at
7571 * runtime; this may result in an exception.
7572 * Note that on XScale all cp0..c13 registers do an access check
7573 * call in order to handle c15_cpar.
7576 TCGv_i32 tcg_syn
, tcg_isread
;
7579 /* Note that since we are an implementation which takes an
7580 * exception on a trapped conditional instruction only if the
7581 * instruction passes its condition code check, we can take
7582 * advantage of the clause in the ARM ARM that allows us to set
7583 * the COND field in the instruction to 0xE in all cases.
7584 * We could fish the actual condition out of the insn (ARM)
7585 * or the condexec bits (Thumb) but it isn't necessary.
7590 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7593 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7599 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7602 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7607 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7608 * so this can only happen if this is an ARMv7 or earlier CPU,
7609 * in which case the syndrome information won't actually be
7612 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7613 syndrome
= syn_uncategorized();
7617 gen_set_condexec(s
);
7618 gen_set_pc_im(s
, s
->pc
- 4);
7619 tmpptr
= tcg_const_ptr(ri
);
7620 tcg_syn
= tcg_const_i32(syndrome
);
7621 tcg_isread
= tcg_const_i32(isread
);
7622 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7624 tcg_temp_free_ptr(tmpptr
);
7625 tcg_temp_free_i32(tcg_syn
);
7626 tcg_temp_free_i32(tcg_isread
);
7629 /* Handle special cases first */
7630 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7637 gen_set_pc_im(s
, s
->pc
);
7638 s
->is_jmp
= DISAS_WFI
;
7644 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7653 if (ri
->type
& ARM_CP_CONST
) {
7654 tmp64
= tcg_const_i64(ri
->resetvalue
);
7655 } else if (ri
->readfn
) {
7657 tmp64
= tcg_temp_new_i64();
7658 tmpptr
= tcg_const_ptr(ri
);
7659 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7660 tcg_temp_free_ptr(tmpptr
);
7662 tmp64
= tcg_temp_new_i64();
7663 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7665 tmp
= tcg_temp_new_i32();
7666 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7667 store_reg(s
, rt
, tmp
);
7668 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7669 tmp
= tcg_temp_new_i32();
7670 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7671 tcg_temp_free_i64(tmp64
);
7672 store_reg(s
, rt2
, tmp
);
7675 if (ri
->type
& ARM_CP_CONST
) {
7676 tmp
= tcg_const_i32(ri
->resetvalue
);
7677 } else if (ri
->readfn
) {
7679 tmp
= tcg_temp_new_i32();
7680 tmpptr
= tcg_const_ptr(ri
);
7681 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7682 tcg_temp_free_ptr(tmpptr
);
7684 tmp
= load_cpu_offset(ri
->fieldoffset
);
7687 /* Destination register of r15 for 32 bit loads sets
7688 * the condition codes from the high 4 bits of the value
7691 tcg_temp_free_i32(tmp
);
7693 store_reg(s
, rt
, tmp
);
7698 if (ri
->type
& ARM_CP_CONST
) {
7699 /* If not forbidden by access permissions, treat as WI */
7704 TCGv_i32 tmplo
, tmphi
;
7705 TCGv_i64 tmp64
= tcg_temp_new_i64();
7706 tmplo
= load_reg(s
, rt
);
7707 tmphi
= load_reg(s
, rt2
);
7708 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7709 tcg_temp_free_i32(tmplo
);
7710 tcg_temp_free_i32(tmphi
);
7712 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7713 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7714 tcg_temp_free_ptr(tmpptr
);
7716 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7718 tcg_temp_free_i64(tmp64
);
7723 tmp
= load_reg(s
, rt
);
7724 tmpptr
= tcg_const_ptr(ri
);
7725 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7726 tcg_temp_free_ptr(tmpptr
);
7727 tcg_temp_free_i32(tmp
);
7729 TCGv_i32 tmp
= load_reg(s
, rt
);
7730 store_cpu_offset(tmp
, ri
->fieldoffset
);
7735 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7736 /* I/O operations must end the TB here (whether read or write) */
7739 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7740 /* We default to ending the TB on a coprocessor register write,
7741 * but allow this to be suppressed by the register definition
7742 * (usually only necessary to work around guest bugs).
7750 /* Unknown register; this might be a guest error or a QEMU
7751 * unimplemented feature.
7754 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7755 "64 bit system register cp:%d opc1: %d crm:%d "
7757 isread
? "read" : "write", cpnum
, opc1
, crm
,
7758 s
->ns
? "non-secure" : "secure");
7760 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7761 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7763 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7764 s
->ns
? "non-secure" : "secure");
7771 /* Store a 64-bit value to a register pair. Clobbers val. */
7772 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7775 tmp
= tcg_temp_new_i32();
7776 tcg_gen_extrl_i64_i32(tmp
, val
);
7777 store_reg(s
, rlow
, tmp
);
7778 tmp
= tcg_temp_new_i32();
7779 tcg_gen_shri_i64(val
, val
, 32);
7780 tcg_gen_extrl_i64_i32(tmp
, val
);
7781 store_reg(s
, rhigh
, tmp
);
7784 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7785 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7790 /* Load value and extend to 64 bits. */
7791 tmp
= tcg_temp_new_i64();
7792 tmp2
= load_reg(s
, rlow
);
7793 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7794 tcg_temp_free_i32(tmp2
);
7795 tcg_gen_add_i64(val
, val
, tmp
);
7796 tcg_temp_free_i64(tmp
);
7799 /* load and add a 64-bit value from a register pair. */
7800 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7806 /* Load 64-bit value rd:rn. */
7807 tmpl
= load_reg(s
, rlow
);
7808 tmph
= load_reg(s
, rhigh
);
7809 tmp
= tcg_temp_new_i64();
7810 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7811 tcg_temp_free_i32(tmpl
);
7812 tcg_temp_free_i32(tmph
);
7813 tcg_gen_add_i64(val
, val
, tmp
);
7814 tcg_temp_free_i64(tmp
);
7817 /* Set N and Z flags from hi|lo. */
7818 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7820 tcg_gen_mov_i32(cpu_NF
, hi
);
7821 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7824 /* Load/Store exclusive instructions are implemented by remembering
7825 the value/address loaded, and seeing if these are the same
7826 when the store is performed. This should be sufficient to implement
7827 the architecturally mandated semantics, and avoids having to monitor
7828 regular stores. The compare vs the remembered value is done during
7829 the cmpxchg operation, but we must compare the addresses manually. */
7830 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7831 TCGv_i32 addr
, int size
)
7833 TCGv_i32 tmp
= tcg_temp_new_i32();
7834 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7839 TCGv_i32 tmp2
= tcg_temp_new_i32();
7840 TCGv_i64 t64
= tcg_temp_new_i64();
7842 gen_aa32_ld_i64(s
, t64
, addr
, get_mem_index(s
), opc
);
7843 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
7844 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
7845 tcg_temp_free_i64(t64
);
7847 store_reg(s
, rt2
, tmp2
);
7849 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
7850 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7853 store_reg(s
, rt
, tmp
);
7854 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7857 static void gen_clrex(DisasContext
*s
)
7859 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7862 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7863 TCGv_i32 addr
, int size
)
7865 TCGv_i32 t0
, t1
, t2
;
7868 TCGLabel
*done_label
;
7869 TCGLabel
*fail_label
;
7870 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7872 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7878 fail_label
= gen_new_label();
7879 done_label
= gen_new_label();
7880 extaddr
= tcg_temp_new_i64();
7881 tcg_gen_extu_i32_i64(extaddr
, addr
);
7882 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7883 tcg_temp_free_i64(extaddr
);
7885 taddr
= gen_aa32_addr(s
, addr
, opc
);
7886 t0
= tcg_temp_new_i32();
7887 t1
= load_reg(s
, rt
);
7889 TCGv_i64 o64
= tcg_temp_new_i64();
7890 TCGv_i64 n64
= tcg_temp_new_i64();
7892 t2
= load_reg(s
, rt2
);
7893 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
7894 tcg_temp_free_i32(t2
);
7895 gen_aa32_frob64(s
, n64
);
7897 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
7898 get_mem_index(s
), opc
);
7899 tcg_temp_free_i64(n64
);
7901 gen_aa32_frob64(s
, o64
);
7902 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
7903 tcg_gen_extrl_i64_i32(t0
, o64
);
7905 tcg_temp_free_i64(o64
);
7907 t2
= tcg_temp_new_i32();
7908 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
7909 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
7910 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
7911 tcg_temp_free_i32(t2
);
7913 tcg_temp_free_i32(t1
);
7914 tcg_temp_free(taddr
);
7915 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
7916 tcg_temp_free_i32(t0
);
7917 tcg_gen_br(done_label
);
7919 gen_set_label(fail_label
);
7920 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7921 gen_set_label(done_label
);
7922 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7928 * @mode: mode field from insn (which stack to store to)
7929 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7930 * @writeback: true if writeback bit set
7932 * Generate code for the SRS (Store Return State) insn.
7934 static void gen_srs(DisasContext
*s
,
7935 uint32_t mode
, uint32_t amode
, bool writeback
)
7942 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7943 * and specified mode is monitor mode
7944 * - UNDEFINED in Hyp mode
7945 * - UNPREDICTABLE in User or System mode
7946 * - UNPREDICTABLE if the specified mode is:
7947 * -- not implemented
7948 * -- not a valid mode number
7949 * -- a mode that's at a higher exception level
7950 * -- Monitor, if we are Non-secure
7951 * For the UNPREDICTABLE cases we choose to UNDEF.
7953 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7954 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7958 if (s
->current_el
== 0 || s
->current_el
== 2) {
7963 case ARM_CPU_MODE_USR
:
7964 case ARM_CPU_MODE_FIQ
:
7965 case ARM_CPU_MODE_IRQ
:
7966 case ARM_CPU_MODE_SVC
:
7967 case ARM_CPU_MODE_ABT
:
7968 case ARM_CPU_MODE_UND
:
7969 case ARM_CPU_MODE_SYS
:
7971 case ARM_CPU_MODE_HYP
:
7972 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7976 case ARM_CPU_MODE_MON
:
7977 /* No need to check specifically for "are we non-secure" because
7978 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7979 * so if this isn't EL3 then we must be non-secure.
7981 if (s
->current_el
!= 3) {
7990 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
7991 default_exception_el(s
));
7995 addr
= tcg_temp_new_i32();
7996 tmp
= tcg_const_i32(mode
);
7997 /* get_r13_banked() will raise an exception if called from System mode */
7998 gen_set_condexec(s
);
7999 gen_set_pc_im(s
, s
->pc
- 4);
8000 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8001 tcg_temp_free_i32(tmp
);
8018 tcg_gen_addi_i32(addr
, addr
, offset
);
8019 tmp
= load_reg(s
, 14);
8020 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8021 tcg_temp_free_i32(tmp
);
8022 tmp
= load_cpu_field(spsr
);
8023 tcg_gen_addi_i32(addr
, addr
, 4);
8024 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8025 tcg_temp_free_i32(tmp
);
8043 tcg_gen_addi_i32(addr
, addr
, offset
);
8044 tmp
= tcg_const_i32(mode
);
8045 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8046 tcg_temp_free_i32(tmp
);
8048 tcg_temp_free_i32(addr
);
8049 s
->is_jmp
= DISAS_UPDATE
;
8052 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8054 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8061 /* M variants do not implement ARM mode; this must raise the INVSTATE
8062 * UsageFault exception.
8064 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8065 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8066 default_exception_el(s
));
8071 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8072 * choose to UNDEF. In ARMv5 and above the space is used
8073 * for miscellaneous unconditional instructions.
8077 /* Unconditional instructions. */
8078 if (((insn
>> 25) & 7) == 1) {
8079 /* NEON Data processing. */
8080 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8084 if (disas_neon_data_insn(s
, insn
)) {
8089 if ((insn
& 0x0f100000) == 0x04000000) {
8090 /* NEON load/store. */
8091 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8095 if (disas_neon_ls_insn(s
, insn
)) {
8100 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8102 if (disas_vfp_insn(s
, insn
)) {
8107 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8108 ((insn
& 0x0f30f010) == 0x0710f000)) {
8109 if ((insn
& (1 << 22)) == 0) {
8111 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8115 /* Otherwise PLD; v5TE+ */
8119 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8120 ((insn
& 0x0f70f010) == 0x0650f000)) {
8122 return; /* PLI; V7 */
8124 if (((insn
& 0x0f700000) == 0x04100000) ||
8125 ((insn
& 0x0f700010) == 0x06100000)) {
8126 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8129 return; /* v7MP: Unallocated memory hint: must NOP */
8132 if ((insn
& 0x0ffffdff) == 0x01010000) {
8135 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8136 gen_helper_setend(cpu_env
);
8137 s
->is_jmp
= DISAS_UPDATE
;
8140 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8141 switch ((insn
>> 4) & 0xf) {
8149 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8152 /* We need to break the TB after this insn to execute
8153 * self-modifying code correctly and also to take
8154 * any pending interrupts immediately.
8161 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8164 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8166 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8172 rn
= (insn
>> 16) & 0xf;
8173 addr
= load_reg(s
, rn
);
8174 i
= (insn
>> 23) & 3;
8176 case 0: offset
= -4; break; /* DA */
8177 case 1: offset
= 0; break; /* IA */
8178 case 2: offset
= -8; break; /* DB */
8179 case 3: offset
= 4; break; /* IB */
8183 tcg_gen_addi_i32(addr
, addr
, offset
);
8184 /* Load PC into tmp and CPSR into tmp2. */
8185 tmp
= tcg_temp_new_i32();
8186 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8187 tcg_gen_addi_i32(addr
, addr
, 4);
8188 tmp2
= tcg_temp_new_i32();
8189 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8190 if (insn
& (1 << 21)) {
8191 /* Base writeback. */
8193 case 0: offset
= -8; break;
8194 case 1: offset
= 4; break;
8195 case 2: offset
= -4; break;
8196 case 3: offset
= 0; break;
8200 tcg_gen_addi_i32(addr
, addr
, offset
);
8201 store_reg(s
, rn
, addr
);
8203 tcg_temp_free_i32(addr
);
8205 gen_rfe(s
, tmp
, tmp2
);
8207 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8208 /* branch link and change to thumb (blx <offset>) */
8211 val
= (uint32_t)s
->pc
;
8212 tmp
= tcg_temp_new_i32();
8213 tcg_gen_movi_i32(tmp
, val
);
8214 store_reg(s
, 14, tmp
);
8215 /* Sign-extend the 24-bit offset */
8216 offset
= (((int32_t)insn
) << 8) >> 8;
8217 /* offset * 4 + bit24 * 2 + (thumb bit) */
8218 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8219 /* pipeline offset */
8221 /* protected by ARCH(5); above, near the start of uncond block */
8224 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8225 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8226 /* iWMMXt register transfer. */
8227 if (extract32(s
->c15_cpar
, 1, 1)) {
8228 if (!disas_iwmmxt_insn(s
, insn
)) {
8233 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8234 /* Coprocessor double register transfer. */
8236 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8237 /* Additional coprocessor register transfer. */
8238 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8241 /* cps (privileged) */
8245 if (insn
& (1 << 19)) {
8246 if (insn
& (1 << 8))
8248 if (insn
& (1 << 7))
8250 if (insn
& (1 << 6))
8252 if (insn
& (1 << 18))
8255 if (insn
& (1 << 17)) {
8257 val
|= (insn
& 0x1f);
8260 gen_set_psr_im(s
, mask
, 0, val
);
8267 /* if not always execute, we generate a conditional jump to
8269 s
->condlabel
= gen_new_label();
8270 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8273 if ((insn
& 0x0f900000) == 0x03000000) {
8274 if ((insn
& (1 << 21)) == 0) {
8276 rd
= (insn
>> 12) & 0xf;
8277 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8278 if ((insn
& (1 << 22)) == 0) {
8280 tmp
= tcg_temp_new_i32();
8281 tcg_gen_movi_i32(tmp
, val
);
8284 tmp
= load_reg(s
, rd
);
8285 tcg_gen_ext16u_i32(tmp
, tmp
);
8286 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8288 store_reg(s
, rd
, tmp
);
8290 if (((insn
>> 12) & 0xf) != 0xf)
8292 if (((insn
>> 16) & 0xf) == 0) {
8293 gen_nop_hint(s
, insn
& 0xff);
8295 /* CPSR = immediate */
8297 shift
= ((insn
>> 8) & 0xf) * 2;
8299 val
= (val
>> shift
) | (val
<< (32 - shift
));
8300 i
= ((insn
& (1 << 22)) != 0);
8301 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8307 } else if ((insn
& 0x0f900000) == 0x01000000
8308 && (insn
& 0x00000090) != 0x00000090) {
8309 /* miscellaneous instructions */
8310 op1
= (insn
>> 21) & 3;
8311 sh
= (insn
>> 4) & 0xf;
8314 case 0x0: /* MSR, MRS */
8315 if (insn
& (1 << 9)) {
8316 /* MSR (banked) and MRS (banked) */
8317 int sysm
= extract32(insn
, 16, 4) |
8318 (extract32(insn
, 8, 1) << 4);
8319 int r
= extract32(insn
, 22, 1);
8323 gen_msr_banked(s
, r
, sysm
, rm
);
8326 int rd
= extract32(insn
, 12, 4);
8328 gen_mrs_banked(s
, r
, sysm
, rd
);
8333 /* MSR, MRS (for PSRs) */
8336 tmp
= load_reg(s
, rm
);
8337 i
= ((op1
& 2) != 0);
8338 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8342 rd
= (insn
>> 12) & 0xf;
8346 tmp
= load_cpu_field(spsr
);
8348 tmp
= tcg_temp_new_i32();
8349 gen_helper_cpsr_read(tmp
, cpu_env
);
8351 store_reg(s
, rd
, tmp
);
8356 /* branch/exchange thumb (bx). */
8358 tmp
= load_reg(s
, rm
);
8360 } else if (op1
== 3) {
8363 rd
= (insn
>> 12) & 0xf;
8364 tmp
= load_reg(s
, rm
);
8365 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8366 store_reg(s
, rd
, tmp
);
8374 /* Trivial implementation equivalent to bx. */
8375 tmp
= load_reg(s
, rm
);
8386 /* branch link/exchange thumb (blx) */
8387 tmp
= load_reg(s
, rm
);
8388 tmp2
= tcg_temp_new_i32();
8389 tcg_gen_movi_i32(tmp2
, s
->pc
);
8390 store_reg(s
, 14, tmp2
);
8396 uint32_t c
= extract32(insn
, 8, 4);
8398 /* Check this CPU supports ARMv8 CRC instructions.
8399 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8400 * Bits 8, 10 and 11 should be zero.
8402 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8407 rn
= extract32(insn
, 16, 4);
8408 rd
= extract32(insn
, 12, 4);
8410 tmp
= load_reg(s
, rn
);
8411 tmp2
= load_reg(s
, rm
);
8413 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8414 } else if (op1
== 1) {
8415 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8417 tmp3
= tcg_const_i32(1 << op1
);
8419 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8421 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8423 tcg_temp_free_i32(tmp2
);
8424 tcg_temp_free_i32(tmp3
);
8425 store_reg(s
, rd
, tmp
);
8428 case 0x5: /* saturating add/subtract */
8430 rd
= (insn
>> 12) & 0xf;
8431 rn
= (insn
>> 16) & 0xf;
8432 tmp
= load_reg(s
, rm
);
8433 tmp2
= load_reg(s
, rn
);
8435 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8437 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8439 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8440 tcg_temp_free_i32(tmp2
);
8441 store_reg(s
, rd
, tmp
);
8445 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8454 gen_exception_insn(s
, 4, EXCP_BKPT
,
8455 syn_aa32_bkpt(imm16
, false),
8456 default_exception_el(s
));
8459 /* Hypervisor call (v7) */
8467 /* Secure monitor call (v6+) */
8475 g_assert_not_reached();
8479 case 0x8: /* signed multiply */
8484 rs
= (insn
>> 8) & 0xf;
8485 rn
= (insn
>> 12) & 0xf;
8486 rd
= (insn
>> 16) & 0xf;
8488 /* (32 * 16) >> 16 */
8489 tmp
= load_reg(s
, rm
);
8490 tmp2
= load_reg(s
, rs
);
8492 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8495 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8496 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8497 tmp
= tcg_temp_new_i32();
8498 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8499 tcg_temp_free_i64(tmp64
);
8500 if ((sh
& 2) == 0) {
8501 tmp2
= load_reg(s
, rn
);
8502 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8503 tcg_temp_free_i32(tmp2
);
8505 store_reg(s
, rd
, tmp
);
8508 tmp
= load_reg(s
, rm
);
8509 tmp2
= load_reg(s
, rs
);
8510 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8511 tcg_temp_free_i32(tmp2
);
8513 tmp64
= tcg_temp_new_i64();
8514 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8515 tcg_temp_free_i32(tmp
);
8516 gen_addq(s
, tmp64
, rn
, rd
);
8517 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8518 tcg_temp_free_i64(tmp64
);
8521 tmp2
= load_reg(s
, rn
);
8522 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8523 tcg_temp_free_i32(tmp2
);
8525 store_reg(s
, rd
, tmp
);
8532 } else if (((insn
& 0x0e000000) == 0 &&
8533 (insn
& 0x00000090) != 0x90) ||
8534 ((insn
& 0x0e000000) == (1 << 25))) {
8535 int set_cc
, logic_cc
, shiftop
;
8537 op1
= (insn
>> 21) & 0xf;
8538 set_cc
= (insn
>> 20) & 1;
8539 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8541 /* data processing instruction */
8542 if (insn
& (1 << 25)) {
8543 /* immediate operand */
8545 shift
= ((insn
>> 8) & 0xf) * 2;
8547 val
= (val
>> shift
) | (val
<< (32 - shift
));
8549 tmp2
= tcg_temp_new_i32();
8550 tcg_gen_movi_i32(tmp2
, val
);
8551 if (logic_cc
&& shift
) {
8552 gen_set_CF_bit31(tmp2
);
8557 tmp2
= load_reg(s
, rm
);
8558 shiftop
= (insn
>> 5) & 3;
8559 if (!(insn
& (1 << 4))) {
8560 shift
= (insn
>> 7) & 0x1f;
8561 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8563 rs
= (insn
>> 8) & 0xf;
8564 tmp
= load_reg(s
, rs
);
8565 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8568 if (op1
!= 0x0f && op1
!= 0x0d) {
8569 rn
= (insn
>> 16) & 0xf;
8570 tmp
= load_reg(s
, rn
);
8572 TCGV_UNUSED_I32(tmp
);
8574 rd
= (insn
>> 12) & 0xf;
8577 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8581 store_reg_bx(s
, rd
, tmp
);
8584 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8588 store_reg_bx(s
, rd
, tmp
);
8591 if (set_cc
&& rd
== 15) {
8592 /* SUBS r15, ... is used for exception return. */
8596 gen_sub_CC(tmp
, tmp
, tmp2
);
8597 gen_exception_return(s
, tmp
);
8600 gen_sub_CC(tmp
, tmp
, tmp2
);
8602 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8604 store_reg_bx(s
, rd
, tmp
);
8609 gen_sub_CC(tmp
, tmp2
, tmp
);
8611 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8613 store_reg_bx(s
, rd
, tmp
);
8617 gen_add_CC(tmp
, tmp
, tmp2
);
8619 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8621 store_reg_bx(s
, rd
, tmp
);
8625 gen_adc_CC(tmp
, tmp
, tmp2
);
8627 gen_add_carry(tmp
, tmp
, tmp2
);
8629 store_reg_bx(s
, rd
, tmp
);
8633 gen_sbc_CC(tmp
, tmp
, tmp2
);
8635 gen_sub_carry(tmp
, tmp
, tmp2
);
8637 store_reg_bx(s
, rd
, tmp
);
8641 gen_sbc_CC(tmp
, tmp2
, tmp
);
8643 gen_sub_carry(tmp
, tmp2
, tmp
);
8645 store_reg_bx(s
, rd
, tmp
);
8649 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8652 tcg_temp_free_i32(tmp
);
8656 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8659 tcg_temp_free_i32(tmp
);
8663 gen_sub_CC(tmp
, tmp
, tmp2
);
8665 tcg_temp_free_i32(tmp
);
8669 gen_add_CC(tmp
, tmp
, tmp2
);
8671 tcg_temp_free_i32(tmp
);
8674 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8678 store_reg_bx(s
, rd
, tmp
);
8681 if (logic_cc
&& rd
== 15) {
8682 /* MOVS r15, ... is used for exception return. */
8686 gen_exception_return(s
, tmp2
);
8691 store_reg_bx(s
, rd
, tmp2
);
8695 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8699 store_reg_bx(s
, rd
, tmp
);
8703 tcg_gen_not_i32(tmp2
, tmp2
);
8707 store_reg_bx(s
, rd
, tmp2
);
8710 if (op1
!= 0x0f && op1
!= 0x0d) {
8711 tcg_temp_free_i32(tmp2
);
8714 /* other instructions */
8715 op1
= (insn
>> 24) & 0xf;
8719 /* multiplies, extra load/stores */
8720 sh
= (insn
>> 5) & 3;
8723 rd
= (insn
>> 16) & 0xf;
8724 rn
= (insn
>> 12) & 0xf;
8725 rs
= (insn
>> 8) & 0xf;
8727 op1
= (insn
>> 20) & 0xf;
8729 case 0: case 1: case 2: case 3: case 6:
8731 tmp
= load_reg(s
, rs
);
8732 tmp2
= load_reg(s
, rm
);
8733 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8734 tcg_temp_free_i32(tmp2
);
8735 if (insn
& (1 << 22)) {
8736 /* Subtract (mls) */
8738 tmp2
= load_reg(s
, rn
);
8739 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8740 tcg_temp_free_i32(tmp2
);
8741 } else if (insn
& (1 << 21)) {
8743 tmp2
= load_reg(s
, rn
);
8744 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8745 tcg_temp_free_i32(tmp2
);
8747 if (insn
& (1 << 20))
8749 store_reg(s
, rd
, tmp
);
8752 /* 64 bit mul double accumulate (UMAAL) */
8754 tmp
= load_reg(s
, rs
);
8755 tmp2
= load_reg(s
, rm
);
8756 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8757 gen_addq_lo(s
, tmp64
, rn
);
8758 gen_addq_lo(s
, tmp64
, rd
);
8759 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8760 tcg_temp_free_i64(tmp64
);
8762 case 8: case 9: case 10: case 11:
8763 case 12: case 13: case 14: case 15:
8764 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8765 tmp
= load_reg(s
, rs
);
8766 tmp2
= load_reg(s
, rm
);
8767 if (insn
& (1 << 22)) {
8768 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8770 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8772 if (insn
& (1 << 21)) { /* mult accumulate */
8773 TCGv_i32 al
= load_reg(s
, rn
);
8774 TCGv_i32 ah
= load_reg(s
, rd
);
8775 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8776 tcg_temp_free_i32(al
);
8777 tcg_temp_free_i32(ah
);
8779 if (insn
& (1 << 20)) {
8780 gen_logicq_cc(tmp
, tmp2
);
8782 store_reg(s
, rn
, tmp
);
8783 store_reg(s
, rd
, tmp2
);
8789 rn
= (insn
>> 16) & 0xf;
8790 rd
= (insn
>> 12) & 0xf;
8791 if (insn
& (1 << 23)) {
8792 /* load/store exclusive */
8793 int op2
= (insn
>> 8) & 3;
8794 op1
= (insn
>> 21) & 0x3;
8797 case 0: /* lda/stl */
8803 case 1: /* reserved */
8805 case 2: /* ldaex/stlex */
8808 case 3: /* ldrex/strex */
8817 addr
= tcg_temp_local_new_i32();
8818 load_reg_var(s
, addr
, rn
);
8820 /* Since the emulation does not have barriers,
8821 the acquire/release semantics need no special
8824 if (insn
& (1 << 20)) {
8825 tmp
= tcg_temp_new_i32();
8828 gen_aa32_ld32u_iss(s
, tmp
, addr
,
8833 gen_aa32_ld8u_iss(s
, tmp
, addr
,
8838 gen_aa32_ld16u_iss(s
, tmp
, addr
,
8845 store_reg(s
, rd
, tmp
);
8848 tmp
= load_reg(s
, rm
);
8851 gen_aa32_st32_iss(s
, tmp
, addr
,
8856 gen_aa32_st8_iss(s
, tmp
, addr
,
8861 gen_aa32_st16_iss(s
, tmp
, addr
,
8868 tcg_temp_free_i32(tmp
);
8870 } else if (insn
& (1 << 20)) {
8873 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8875 case 1: /* ldrexd */
8876 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8878 case 2: /* ldrexb */
8879 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8881 case 3: /* ldrexh */
8882 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8891 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8893 case 1: /* strexd */
8894 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8896 case 2: /* strexb */
8897 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8899 case 3: /* strexh */
8900 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8906 tcg_temp_free_i32(addr
);
8909 TCGMemOp opc
= s
->be_data
;
8911 /* SWP instruction */
8914 if (insn
& (1 << 22)) {
8917 opc
|= MO_UL
| MO_ALIGN
;
8920 addr
= load_reg(s
, rn
);
8921 taddr
= gen_aa32_addr(s
, addr
, opc
);
8922 tcg_temp_free_i32(addr
);
8924 tmp
= load_reg(s
, rm
);
8925 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
8926 get_mem_index(s
), opc
);
8927 tcg_temp_free(taddr
);
8928 store_reg(s
, rd
, tmp
);
8933 bool load
= insn
& (1 << 20);
8934 bool wbit
= insn
& (1 << 21);
8935 bool pbit
= insn
& (1 << 24);
8936 bool doubleword
= false;
8939 /* Misc load/store */
8940 rn
= (insn
>> 16) & 0xf;
8941 rd
= (insn
>> 12) & 0xf;
8943 /* ISS not valid if writeback */
8944 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
8946 if (!load
&& (sh
& 2)) {
8950 /* UNPREDICTABLE; we choose to UNDEF */
8953 load
= (sh
& 1) == 0;
8957 addr
= load_reg(s
, rn
);
8959 gen_add_datah_offset(s
, insn
, 0, addr
);
8966 tmp
= load_reg(s
, rd
);
8967 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8968 tcg_temp_free_i32(tmp
);
8969 tcg_gen_addi_i32(addr
, addr
, 4);
8970 tmp
= load_reg(s
, rd
+ 1);
8971 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8972 tcg_temp_free_i32(tmp
);
8975 tmp
= tcg_temp_new_i32();
8976 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8977 store_reg(s
, rd
, tmp
);
8978 tcg_gen_addi_i32(addr
, addr
, 4);
8979 tmp
= tcg_temp_new_i32();
8980 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8983 address_offset
= -4;
8986 tmp
= tcg_temp_new_i32();
8989 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
8993 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
8998 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9004 tmp
= load_reg(s
, rd
);
9005 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9006 tcg_temp_free_i32(tmp
);
9008 /* Perform base writeback before the loaded value to
9009 ensure correct behavior with overlapping index registers.
9010 ldrd with base writeback is undefined if the
9011 destination and index registers overlap. */
9013 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9014 store_reg(s
, rn
, addr
);
9017 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9018 store_reg(s
, rn
, addr
);
9020 tcg_temp_free_i32(addr
);
9023 /* Complete the load. */
9024 store_reg(s
, rd
, tmp
);
9033 if (insn
& (1 << 4)) {
9035 /* Armv6 Media instructions. */
9037 rn
= (insn
>> 16) & 0xf;
9038 rd
= (insn
>> 12) & 0xf;
9039 rs
= (insn
>> 8) & 0xf;
9040 switch ((insn
>> 23) & 3) {
9041 case 0: /* Parallel add/subtract. */
9042 op1
= (insn
>> 20) & 7;
9043 tmp
= load_reg(s
, rn
);
9044 tmp2
= load_reg(s
, rm
);
9045 sh
= (insn
>> 5) & 7;
9046 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9048 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9049 tcg_temp_free_i32(tmp2
);
9050 store_reg(s
, rd
, tmp
);
9053 if ((insn
& 0x00700020) == 0) {
9054 /* Halfword pack. */
9055 tmp
= load_reg(s
, rn
);
9056 tmp2
= load_reg(s
, rm
);
9057 shift
= (insn
>> 7) & 0x1f;
9058 if (insn
& (1 << 6)) {
9062 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9063 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9064 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9068 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9069 tcg_gen_ext16u_i32(tmp
, tmp
);
9070 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9072 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9073 tcg_temp_free_i32(tmp2
);
9074 store_reg(s
, rd
, tmp
);
9075 } else if ((insn
& 0x00200020) == 0x00200000) {
9077 tmp
= load_reg(s
, rm
);
9078 shift
= (insn
>> 7) & 0x1f;
9079 if (insn
& (1 << 6)) {
9082 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9084 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9086 sh
= (insn
>> 16) & 0x1f;
9087 tmp2
= tcg_const_i32(sh
);
9088 if (insn
& (1 << 22))
9089 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9091 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9092 tcg_temp_free_i32(tmp2
);
9093 store_reg(s
, rd
, tmp
);
9094 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9096 tmp
= load_reg(s
, rm
);
9097 sh
= (insn
>> 16) & 0x1f;
9098 tmp2
= tcg_const_i32(sh
);
9099 if (insn
& (1 << 22))
9100 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9102 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9103 tcg_temp_free_i32(tmp2
);
9104 store_reg(s
, rd
, tmp
);
9105 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9107 tmp
= load_reg(s
, rn
);
9108 tmp2
= load_reg(s
, rm
);
9109 tmp3
= tcg_temp_new_i32();
9110 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9111 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9112 tcg_temp_free_i32(tmp3
);
9113 tcg_temp_free_i32(tmp2
);
9114 store_reg(s
, rd
, tmp
);
9115 } else if ((insn
& 0x000003e0) == 0x00000060) {
9116 tmp
= load_reg(s
, rm
);
9117 shift
= (insn
>> 10) & 3;
9118 /* ??? In many cases it's not necessary to do a
9119 rotate, a shift is sufficient. */
9121 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9122 op1
= (insn
>> 20) & 7;
9124 case 0: gen_sxtb16(tmp
); break;
9125 case 2: gen_sxtb(tmp
); break;
9126 case 3: gen_sxth(tmp
); break;
9127 case 4: gen_uxtb16(tmp
); break;
9128 case 6: gen_uxtb(tmp
); break;
9129 case 7: gen_uxth(tmp
); break;
9130 default: goto illegal_op
;
9133 tmp2
= load_reg(s
, rn
);
9134 if ((op1
& 3) == 0) {
9135 gen_add16(tmp
, tmp2
);
9137 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9138 tcg_temp_free_i32(tmp2
);
9141 store_reg(s
, rd
, tmp
);
9142 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9144 tmp
= load_reg(s
, rm
);
9145 if (insn
& (1 << 22)) {
9146 if (insn
& (1 << 7)) {
9150 gen_helper_rbit(tmp
, tmp
);
9153 if (insn
& (1 << 7))
9156 tcg_gen_bswap32_i32(tmp
, tmp
);
9158 store_reg(s
, rd
, tmp
);
9163 case 2: /* Multiplies (Type 3). */
9164 switch ((insn
>> 20) & 0x7) {
9166 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9167 /* op2 not 00x or 11x : UNDEF */
9170 /* Signed multiply most significant [accumulate].
9171 (SMMUL, SMMLA, SMMLS) */
9172 tmp
= load_reg(s
, rm
);
9173 tmp2
= load_reg(s
, rs
);
9174 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9177 tmp
= load_reg(s
, rd
);
9178 if (insn
& (1 << 6)) {
9179 tmp64
= gen_subq_msw(tmp64
, tmp
);
9181 tmp64
= gen_addq_msw(tmp64
, tmp
);
9184 if (insn
& (1 << 5)) {
9185 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9187 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9188 tmp
= tcg_temp_new_i32();
9189 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9190 tcg_temp_free_i64(tmp64
);
9191 store_reg(s
, rn
, tmp
);
9195 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9196 if (insn
& (1 << 7)) {
9199 tmp
= load_reg(s
, rm
);
9200 tmp2
= load_reg(s
, rs
);
9201 if (insn
& (1 << 5))
9202 gen_swap_half(tmp2
);
9203 gen_smul_dual(tmp
, tmp2
);
9204 if (insn
& (1 << 22)) {
9205 /* smlald, smlsld */
9208 tmp64
= tcg_temp_new_i64();
9209 tmp64_2
= tcg_temp_new_i64();
9210 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9211 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9212 tcg_temp_free_i32(tmp
);
9213 tcg_temp_free_i32(tmp2
);
9214 if (insn
& (1 << 6)) {
9215 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9217 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9219 tcg_temp_free_i64(tmp64_2
);
9220 gen_addq(s
, tmp64
, rd
, rn
);
9221 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9222 tcg_temp_free_i64(tmp64
);
9224 /* smuad, smusd, smlad, smlsd */
9225 if (insn
& (1 << 6)) {
9226 /* This subtraction cannot overflow. */
9227 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9229 /* This addition cannot overflow 32 bits;
9230 * however it may overflow considered as a
9231 * signed operation, in which case we must set
9234 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9236 tcg_temp_free_i32(tmp2
);
9239 tmp2
= load_reg(s
, rd
);
9240 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9241 tcg_temp_free_i32(tmp2
);
9243 store_reg(s
, rn
, tmp
);
9249 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9252 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9255 tmp
= load_reg(s
, rm
);
9256 tmp2
= load_reg(s
, rs
);
9257 if (insn
& (1 << 21)) {
9258 gen_helper_udiv(tmp
, tmp
, tmp2
);
9260 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9262 tcg_temp_free_i32(tmp2
);
9263 store_reg(s
, rn
, tmp
);
9270 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9272 case 0: /* Unsigned sum of absolute differences. */
9274 tmp
= load_reg(s
, rm
);
9275 tmp2
= load_reg(s
, rs
);
9276 gen_helper_usad8(tmp
, tmp
, tmp2
);
9277 tcg_temp_free_i32(tmp2
);
9279 tmp2
= load_reg(s
, rd
);
9280 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9281 tcg_temp_free_i32(tmp2
);
9283 store_reg(s
, rn
, tmp
);
9285 case 0x20: case 0x24: case 0x28: case 0x2c:
9286 /* Bitfield insert/clear. */
9288 shift
= (insn
>> 7) & 0x1f;
9289 i
= (insn
>> 16) & 0x1f;
9291 /* UNPREDICTABLE; we choose to UNDEF */
9296 tmp
= tcg_temp_new_i32();
9297 tcg_gen_movi_i32(tmp
, 0);
9299 tmp
= load_reg(s
, rm
);
9302 tmp2
= load_reg(s
, rd
);
9303 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9304 tcg_temp_free_i32(tmp2
);
9306 store_reg(s
, rd
, tmp
);
9308 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9309 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9311 tmp
= load_reg(s
, rm
);
9312 shift
= (insn
>> 7) & 0x1f;
9313 i
= ((insn
>> 16) & 0x1f) + 1;
9318 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9320 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9323 store_reg(s
, rd
, tmp
);
9333 /* Check for undefined extension instructions
9334 * per the ARM Bible IE:
9335 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9337 sh
= (0xf << 20) | (0xf << 4);
9338 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9342 /* load/store byte/word */
9343 rn
= (insn
>> 16) & 0xf;
9344 rd
= (insn
>> 12) & 0xf;
9345 tmp2
= load_reg(s
, rn
);
9346 if ((insn
& 0x01200000) == 0x00200000) {
9348 i
= get_a32_user_mem_index(s
);
9350 i
= get_mem_index(s
);
9352 if (insn
& (1 << 24))
9353 gen_add_data_offset(s
, insn
, tmp2
);
9354 if (insn
& (1 << 20)) {
9356 tmp
= tcg_temp_new_i32();
9357 if (insn
& (1 << 22)) {
9358 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9360 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9364 tmp
= load_reg(s
, rd
);
9365 if (insn
& (1 << 22)) {
9366 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9368 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9370 tcg_temp_free_i32(tmp
);
9372 if (!(insn
& (1 << 24))) {
9373 gen_add_data_offset(s
, insn
, tmp2
);
9374 store_reg(s
, rn
, tmp2
);
9375 } else if (insn
& (1 << 21)) {
9376 store_reg(s
, rn
, tmp2
);
9378 tcg_temp_free_i32(tmp2
);
9380 if (insn
& (1 << 20)) {
9381 /* Complete the load. */
9382 store_reg_from_load(s
, rd
, tmp
);
9388 int j
, n
, loaded_base
;
9389 bool exc_return
= false;
9390 bool is_load
= extract32(insn
, 20, 1);
9392 TCGv_i32 loaded_var
;
9393 /* load/store multiple words */
9394 /* XXX: store correct base if write back */
9395 if (insn
& (1 << 22)) {
9396 /* LDM (user), LDM (exception return) and STM (user) */
9398 goto illegal_op
; /* only usable in supervisor mode */
9400 if (is_load
&& extract32(insn
, 15, 1)) {
9406 rn
= (insn
>> 16) & 0xf;
9407 addr
= load_reg(s
, rn
);
9409 /* compute total size */
9411 TCGV_UNUSED_I32(loaded_var
);
9414 if (insn
& (1 << i
))
9417 /* XXX: test invalid n == 0 case ? */
9418 if (insn
& (1 << 23)) {
9419 if (insn
& (1 << 24)) {
9421 tcg_gen_addi_i32(addr
, addr
, 4);
9423 /* post increment */
9426 if (insn
& (1 << 24)) {
9428 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9430 /* post decrement */
9432 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9437 if (insn
& (1 << i
)) {
9440 tmp
= tcg_temp_new_i32();
9441 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9443 tmp2
= tcg_const_i32(i
);
9444 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9445 tcg_temp_free_i32(tmp2
);
9446 tcg_temp_free_i32(tmp
);
9447 } else if (i
== rn
) {
9450 } else if (rn
== 15 && exc_return
) {
9451 store_pc_exc_ret(s
, tmp
);
9453 store_reg_from_load(s
, i
, tmp
);
9458 /* special case: r15 = PC + 8 */
9459 val
= (long)s
->pc
+ 4;
9460 tmp
= tcg_temp_new_i32();
9461 tcg_gen_movi_i32(tmp
, val
);
9463 tmp
= tcg_temp_new_i32();
9464 tmp2
= tcg_const_i32(i
);
9465 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9466 tcg_temp_free_i32(tmp2
);
9468 tmp
= load_reg(s
, i
);
9470 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9471 tcg_temp_free_i32(tmp
);
9474 /* no need to add after the last transfer */
9476 tcg_gen_addi_i32(addr
, addr
, 4);
9479 if (insn
& (1 << 21)) {
9481 if (insn
& (1 << 23)) {
9482 if (insn
& (1 << 24)) {
9485 /* post increment */
9486 tcg_gen_addi_i32(addr
, addr
, 4);
9489 if (insn
& (1 << 24)) {
9492 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9494 /* post decrement */
9495 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9498 store_reg(s
, rn
, addr
);
9500 tcg_temp_free_i32(addr
);
9503 store_reg(s
, rn
, loaded_var
);
9506 /* Restore CPSR from SPSR. */
9507 tmp
= load_cpu_field(spsr
);
9508 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9509 tcg_temp_free_i32(tmp
);
9510 s
->is_jmp
= DISAS_JUMP
;
9519 /* branch (and link) */
9520 val
= (int32_t)s
->pc
;
9521 if (insn
& (1 << 24)) {
9522 tmp
= tcg_temp_new_i32();
9523 tcg_gen_movi_i32(tmp
, val
);
9524 store_reg(s
, 14, tmp
);
9526 offset
= sextract32(insn
<< 2, 0, 26);
9534 if (((insn
>> 8) & 0xe) == 10) {
9536 if (disas_vfp_insn(s
, insn
)) {
9539 } else if (disas_coproc_insn(s
, insn
)) {
9546 gen_set_pc_im(s
, s
->pc
);
9547 s
->svc_imm
= extract32(insn
, 0, 24);
9548 s
->is_jmp
= DISAS_SWI
;
9552 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9553 default_exception_el(s
));
9559 /* Return true if this is a Thumb-2 logical op. */
9561 thumb2_logic_op(int op
)
9566 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9567 then set condition code flags based on the result of the operation.
9568 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9569 to the high bit of T1.
9570 Returns zero if the opcode is valid. */
9573 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9574 TCGv_i32 t0
, TCGv_i32 t1
)
9581 tcg_gen_and_i32(t0
, t0
, t1
);
9585 tcg_gen_andc_i32(t0
, t0
, t1
);
9589 tcg_gen_or_i32(t0
, t0
, t1
);
9593 tcg_gen_orc_i32(t0
, t0
, t1
);
9597 tcg_gen_xor_i32(t0
, t0
, t1
);
9602 gen_add_CC(t0
, t0
, t1
);
9604 tcg_gen_add_i32(t0
, t0
, t1
);
9608 gen_adc_CC(t0
, t0
, t1
);
9614 gen_sbc_CC(t0
, t0
, t1
);
9616 gen_sub_carry(t0
, t0
, t1
);
9621 gen_sub_CC(t0
, t0
, t1
);
9623 tcg_gen_sub_i32(t0
, t0
, t1
);
9627 gen_sub_CC(t0
, t1
, t0
);
9629 tcg_gen_sub_i32(t0
, t1
, t0
);
9631 default: /* 5, 6, 7, 9, 12, 15. */
9637 gen_set_CF_bit31(t1
);
9642 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9644 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9646 uint32_t insn
, imm
, shift
, offset
;
9647 uint32_t rd
, rn
, rm
, rs
;
9658 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9659 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9660 /* Thumb-1 cores may need to treat bl and blx as a pair of
9661 16-bit instructions to get correct prefetch abort behavior. */
9663 if ((insn
& (1 << 12)) == 0) {
9665 /* Second half of blx. */
9666 offset
= ((insn
& 0x7ff) << 1);
9667 tmp
= load_reg(s
, 14);
9668 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9669 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9671 tmp2
= tcg_temp_new_i32();
9672 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9673 store_reg(s
, 14, tmp2
);
9677 if (insn
& (1 << 11)) {
9678 /* Second half of bl. */
9679 offset
= ((insn
& 0x7ff) << 1) | 1;
9680 tmp
= load_reg(s
, 14);
9681 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9683 tmp2
= tcg_temp_new_i32();
9684 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9685 store_reg(s
, 14, tmp2
);
9689 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9690 /* Instruction spans a page boundary. Implement it as two
9691 16-bit instructions in case the second half causes an
9693 offset
= ((int32_t)insn
<< 21) >> 9;
9694 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9697 /* Fall through to 32-bit decode. */
9700 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9702 insn
|= (uint32_t)insn_hw1
<< 16;
9704 if ((insn
& 0xf800e800) != 0xf000e800) {
9708 rn
= (insn
>> 16) & 0xf;
9709 rs
= (insn
>> 12) & 0xf;
9710 rd
= (insn
>> 8) & 0xf;
9712 switch ((insn
>> 25) & 0xf) {
9713 case 0: case 1: case 2: case 3:
9714 /* 16-bit instructions. Should never happen. */
9717 if (insn
& (1 << 22)) {
9718 /* Other load/store, table branch. */
9719 if (insn
& 0x01200000) {
9720 /* Load/store doubleword. */
9722 addr
= tcg_temp_new_i32();
9723 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9725 addr
= load_reg(s
, rn
);
9727 offset
= (insn
& 0xff) * 4;
9728 if ((insn
& (1 << 23)) == 0)
9730 if (insn
& (1 << 24)) {
9731 tcg_gen_addi_i32(addr
, addr
, offset
);
9734 if (insn
& (1 << 20)) {
9736 tmp
= tcg_temp_new_i32();
9737 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9738 store_reg(s
, rs
, tmp
);
9739 tcg_gen_addi_i32(addr
, addr
, 4);
9740 tmp
= tcg_temp_new_i32();
9741 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9742 store_reg(s
, rd
, tmp
);
9745 tmp
= load_reg(s
, rs
);
9746 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9747 tcg_temp_free_i32(tmp
);
9748 tcg_gen_addi_i32(addr
, addr
, 4);
9749 tmp
= load_reg(s
, rd
);
9750 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9751 tcg_temp_free_i32(tmp
);
9753 if (insn
& (1 << 21)) {
9754 /* Base writeback. */
9757 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9758 store_reg(s
, rn
, addr
);
9760 tcg_temp_free_i32(addr
);
9762 } else if ((insn
& (1 << 23)) == 0) {
9763 /* Load/store exclusive word. */
9764 addr
= tcg_temp_local_new_i32();
9765 load_reg_var(s
, addr
, rn
);
9766 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9767 if (insn
& (1 << 20)) {
9768 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9770 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9772 tcg_temp_free_i32(addr
);
9773 } else if ((insn
& (7 << 5)) == 0) {
9776 addr
= tcg_temp_new_i32();
9777 tcg_gen_movi_i32(addr
, s
->pc
);
9779 addr
= load_reg(s
, rn
);
9781 tmp
= load_reg(s
, rm
);
9782 tcg_gen_add_i32(addr
, addr
, tmp
);
9783 if (insn
& (1 << 4)) {
9785 tcg_gen_add_i32(addr
, addr
, tmp
);
9786 tcg_temp_free_i32(tmp
);
9787 tmp
= tcg_temp_new_i32();
9788 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9790 tcg_temp_free_i32(tmp
);
9791 tmp
= tcg_temp_new_i32();
9792 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9794 tcg_temp_free_i32(addr
);
9795 tcg_gen_shli_i32(tmp
, tmp
, 1);
9796 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9797 store_reg(s
, 15, tmp
);
9799 int op2
= (insn
>> 6) & 0x3;
9800 op
= (insn
>> 4) & 0x3;
9805 /* Load/store exclusive byte/halfword/doubleword */
9812 /* Load-acquire/store-release */
9818 /* Load-acquire/store-release exclusive */
9822 addr
= tcg_temp_local_new_i32();
9823 load_reg_var(s
, addr
, rn
);
9825 if (insn
& (1 << 20)) {
9826 tmp
= tcg_temp_new_i32();
9829 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
9833 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9837 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
9843 store_reg(s
, rs
, tmp
);
9845 tmp
= load_reg(s
, rs
);
9848 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
9852 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
9856 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
9862 tcg_temp_free_i32(tmp
);
9864 } else if (insn
& (1 << 20)) {
9865 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9867 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9869 tcg_temp_free_i32(addr
);
9872 /* Load/store multiple, RFE, SRS. */
9873 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9874 /* RFE, SRS: not available in user mode or on M profile */
9875 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9878 if (insn
& (1 << 20)) {
9880 addr
= load_reg(s
, rn
);
9881 if ((insn
& (1 << 24)) == 0)
9882 tcg_gen_addi_i32(addr
, addr
, -8);
9883 /* Load PC into tmp and CPSR into tmp2. */
9884 tmp
= tcg_temp_new_i32();
9885 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9886 tcg_gen_addi_i32(addr
, addr
, 4);
9887 tmp2
= tcg_temp_new_i32();
9888 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9889 if (insn
& (1 << 21)) {
9890 /* Base writeback. */
9891 if (insn
& (1 << 24)) {
9892 tcg_gen_addi_i32(addr
, addr
, 4);
9894 tcg_gen_addi_i32(addr
, addr
, -4);
9896 store_reg(s
, rn
, addr
);
9898 tcg_temp_free_i32(addr
);
9900 gen_rfe(s
, tmp
, tmp2
);
9903 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9907 int i
, loaded_base
= 0;
9908 TCGv_i32 loaded_var
;
9909 /* Load/store multiple. */
9910 addr
= load_reg(s
, rn
);
9912 for (i
= 0; i
< 16; i
++) {
9913 if (insn
& (1 << i
))
9916 if (insn
& (1 << 24)) {
9917 tcg_gen_addi_i32(addr
, addr
, -offset
);
9920 TCGV_UNUSED_I32(loaded_var
);
9921 for (i
= 0; i
< 16; i
++) {
9922 if ((insn
& (1 << i
)) == 0)
9924 if (insn
& (1 << 20)) {
9926 tmp
= tcg_temp_new_i32();
9927 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9929 gen_bx_excret(s
, tmp
);
9930 } else if (i
== rn
) {
9934 store_reg(s
, i
, tmp
);
9938 tmp
= load_reg(s
, i
);
9939 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9940 tcg_temp_free_i32(tmp
);
9942 tcg_gen_addi_i32(addr
, addr
, 4);
9945 store_reg(s
, rn
, loaded_var
);
9947 if (insn
& (1 << 21)) {
9948 /* Base register writeback. */
9949 if (insn
& (1 << 24)) {
9950 tcg_gen_addi_i32(addr
, addr
, -offset
);
9952 /* Fault if writeback register is in register list. */
9953 if (insn
& (1 << rn
))
9955 store_reg(s
, rn
, addr
);
9957 tcg_temp_free_i32(addr
);
9964 op
= (insn
>> 21) & 0xf;
9966 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9969 /* Halfword pack. */
9970 tmp
= load_reg(s
, rn
);
9971 tmp2
= load_reg(s
, rm
);
9972 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9973 if (insn
& (1 << 5)) {
9977 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9978 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9979 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9983 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9984 tcg_gen_ext16u_i32(tmp
, tmp
);
9985 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9987 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9988 tcg_temp_free_i32(tmp2
);
9989 store_reg(s
, rd
, tmp
);
9991 /* Data processing register constant shift. */
9993 tmp
= tcg_temp_new_i32();
9994 tcg_gen_movi_i32(tmp
, 0);
9996 tmp
= load_reg(s
, rn
);
9998 tmp2
= load_reg(s
, rm
);
10000 shiftop
= (insn
>> 4) & 3;
10001 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10002 conds
= (insn
& (1 << 20)) != 0;
10003 logic_cc
= (conds
&& thumb2_logic_op(op
));
10004 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10005 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10007 tcg_temp_free_i32(tmp2
);
10009 store_reg(s
, rd
, tmp
);
10011 tcg_temp_free_i32(tmp
);
10015 case 13: /* Misc data processing. */
10016 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10017 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10020 case 0: /* Register controlled shift. */
10021 tmp
= load_reg(s
, rn
);
10022 tmp2
= load_reg(s
, rm
);
10023 if ((insn
& 0x70) != 0)
10025 op
= (insn
>> 21) & 3;
10026 logic_cc
= (insn
& (1 << 20)) != 0;
10027 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10030 store_reg(s
, rd
, tmp
);
10032 case 1: /* Sign/zero extend. */
10033 op
= (insn
>> 20) & 7;
10035 case 0: /* SXTAH, SXTH */
10036 case 1: /* UXTAH, UXTH */
10037 case 4: /* SXTAB, SXTB */
10038 case 5: /* UXTAB, UXTB */
10040 case 2: /* SXTAB16, SXTB16 */
10041 case 3: /* UXTAB16, UXTB16 */
10042 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10050 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10054 tmp
= load_reg(s
, rm
);
10055 shift
= (insn
>> 4) & 3;
10056 /* ??? In many cases it's not necessary to do a
10057 rotate, a shift is sufficient. */
10059 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10060 op
= (insn
>> 20) & 7;
10062 case 0: gen_sxth(tmp
); break;
10063 case 1: gen_uxth(tmp
); break;
10064 case 2: gen_sxtb16(tmp
); break;
10065 case 3: gen_uxtb16(tmp
); break;
10066 case 4: gen_sxtb(tmp
); break;
10067 case 5: gen_uxtb(tmp
); break;
10069 g_assert_not_reached();
10072 tmp2
= load_reg(s
, rn
);
10073 if ((op
>> 1) == 1) {
10074 gen_add16(tmp
, tmp2
);
10076 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10077 tcg_temp_free_i32(tmp2
);
10080 store_reg(s
, rd
, tmp
);
10082 case 2: /* SIMD add/subtract. */
10083 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10086 op
= (insn
>> 20) & 7;
10087 shift
= (insn
>> 4) & 7;
10088 if ((op
& 3) == 3 || (shift
& 3) == 3)
10090 tmp
= load_reg(s
, rn
);
10091 tmp2
= load_reg(s
, rm
);
10092 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10093 tcg_temp_free_i32(tmp2
);
10094 store_reg(s
, rd
, tmp
);
10096 case 3: /* Other data processing. */
10097 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10099 /* Saturating add/subtract. */
10100 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10103 tmp
= load_reg(s
, rn
);
10104 tmp2
= load_reg(s
, rm
);
10106 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10108 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10110 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10111 tcg_temp_free_i32(tmp2
);
10114 case 0x0a: /* rbit */
10115 case 0x08: /* rev */
10116 case 0x09: /* rev16 */
10117 case 0x0b: /* revsh */
10118 case 0x18: /* clz */
10120 case 0x10: /* sel */
10121 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10125 case 0x20: /* crc32/crc32c */
10131 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10138 tmp
= load_reg(s
, rn
);
10140 case 0x0a: /* rbit */
10141 gen_helper_rbit(tmp
, tmp
);
10143 case 0x08: /* rev */
10144 tcg_gen_bswap32_i32(tmp
, tmp
);
10146 case 0x09: /* rev16 */
10149 case 0x0b: /* revsh */
10152 case 0x10: /* sel */
10153 tmp2
= load_reg(s
, rm
);
10154 tmp3
= tcg_temp_new_i32();
10155 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10156 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10157 tcg_temp_free_i32(tmp3
);
10158 tcg_temp_free_i32(tmp2
);
10160 case 0x18: /* clz */
10161 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10171 uint32_t sz
= op
& 0x3;
10172 uint32_t c
= op
& 0x8;
10174 tmp2
= load_reg(s
, rm
);
10176 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10177 } else if (sz
== 1) {
10178 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10180 tmp3
= tcg_const_i32(1 << sz
);
10182 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10184 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10186 tcg_temp_free_i32(tmp2
);
10187 tcg_temp_free_i32(tmp3
);
10191 g_assert_not_reached();
10194 store_reg(s
, rd
, tmp
);
10196 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10197 switch ((insn
>> 20) & 7) {
10198 case 0: /* 32 x 32 -> 32 */
10199 case 7: /* Unsigned sum of absolute differences. */
10201 case 1: /* 16 x 16 -> 32 */
10202 case 2: /* Dual multiply add. */
10203 case 3: /* 32 * 16 -> 32msb */
10204 case 4: /* Dual multiply subtract. */
10205 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10206 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10211 op
= (insn
>> 4) & 0xf;
10212 tmp
= load_reg(s
, rn
);
10213 tmp2
= load_reg(s
, rm
);
10214 switch ((insn
>> 20) & 7) {
10215 case 0: /* 32 x 32 -> 32 */
10216 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10217 tcg_temp_free_i32(tmp2
);
10219 tmp2
= load_reg(s
, rs
);
10221 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10223 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10224 tcg_temp_free_i32(tmp2
);
10227 case 1: /* 16 x 16 -> 32 */
10228 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10229 tcg_temp_free_i32(tmp2
);
10231 tmp2
= load_reg(s
, rs
);
10232 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10233 tcg_temp_free_i32(tmp2
);
10236 case 2: /* Dual multiply add. */
10237 case 4: /* Dual multiply subtract. */
10239 gen_swap_half(tmp2
);
10240 gen_smul_dual(tmp
, tmp2
);
10241 if (insn
& (1 << 22)) {
10242 /* This subtraction cannot overflow. */
10243 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10245 /* This addition cannot overflow 32 bits;
10246 * however it may overflow considered as a signed
10247 * operation, in which case we must set the Q flag.
10249 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10251 tcg_temp_free_i32(tmp2
);
10254 tmp2
= load_reg(s
, rs
);
10255 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10256 tcg_temp_free_i32(tmp2
);
10259 case 3: /* 32 * 16 -> 32msb */
10261 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10264 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10265 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10266 tmp
= tcg_temp_new_i32();
10267 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10268 tcg_temp_free_i64(tmp64
);
10271 tmp2
= load_reg(s
, rs
);
10272 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10273 tcg_temp_free_i32(tmp2
);
10276 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10277 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10279 tmp
= load_reg(s
, rs
);
10280 if (insn
& (1 << 20)) {
10281 tmp64
= gen_addq_msw(tmp64
, tmp
);
10283 tmp64
= gen_subq_msw(tmp64
, tmp
);
10286 if (insn
& (1 << 4)) {
10287 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10289 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10290 tmp
= tcg_temp_new_i32();
10291 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10292 tcg_temp_free_i64(tmp64
);
10294 case 7: /* Unsigned sum of absolute differences. */
10295 gen_helper_usad8(tmp
, tmp
, tmp2
);
10296 tcg_temp_free_i32(tmp2
);
10298 tmp2
= load_reg(s
, rs
);
10299 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10300 tcg_temp_free_i32(tmp2
);
10304 store_reg(s
, rd
, tmp
);
10306 case 6: case 7: /* 64-bit multiply, Divide. */
10307 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10308 tmp
= load_reg(s
, rn
);
10309 tmp2
= load_reg(s
, rm
);
10310 if ((op
& 0x50) == 0x10) {
10312 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10316 gen_helper_udiv(tmp
, tmp
, tmp2
);
10318 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10319 tcg_temp_free_i32(tmp2
);
10320 store_reg(s
, rd
, tmp
);
10321 } else if ((op
& 0xe) == 0xc) {
10322 /* Dual multiply accumulate long. */
10323 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10324 tcg_temp_free_i32(tmp
);
10325 tcg_temp_free_i32(tmp2
);
10329 gen_swap_half(tmp2
);
10330 gen_smul_dual(tmp
, tmp2
);
10332 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10334 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10336 tcg_temp_free_i32(tmp2
);
10338 tmp64
= tcg_temp_new_i64();
10339 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10340 tcg_temp_free_i32(tmp
);
10341 gen_addq(s
, tmp64
, rs
, rd
);
10342 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10343 tcg_temp_free_i64(tmp64
);
10346 /* Unsigned 64-bit multiply */
10347 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10351 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10352 tcg_temp_free_i32(tmp2
);
10353 tcg_temp_free_i32(tmp
);
10356 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10357 tcg_temp_free_i32(tmp2
);
10358 tmp64
= tcg_temp_new_i64();
10359 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10360 tcg_temp_free_i32(tmp
);
10362 /* Signed 64-bit multiply */
10363 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10368 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10369 tcg_temp_free_i64(tmp64
);
10372 gen_addq_lo(s
, tmp64
, rs
);
10373 gen_addq_lo(s
, tmp64
, rd
);
10374 } else if (op
& 0x40) {
10375 /* 64-bit accumulate. */
10376 gen_addq(s
, tmp64
, rs
, rd
);
10378 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10379 tcg_temp_free_i64(tmp64
);
10384 case 6: case 7: case 14: case 15:
10386 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10387 /* We don't currently implement M profile FP support,
10388 * so this entire space should give a NOCP fault.
10390 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10391 default_exception_el(s
));
10394 if (((insn
>> 24) & 3) == 3) {
10395 /* Translate into the equivalent ARM encoding. */
10396 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10397 if (disas_neon_data_insn(s
, insn
)) {
10400 } else if (((insn
>> 8) & 0xe) == 10) {
10401 if (disas_vfp_insn(s
, insn
)) {
10405 if (insn
& (1 << 28))
10407 if (disas_coproc_insn(s
, insn
)) {
10412 case 8: case 9: case 10: case 11:
10413 if (insn
& (1 << 15)) {
10414 /* Branches, misc control. */
10415 if (insn
& 0x5000) {
10416 /* Unconditional branch. */
10417 /* signextend(hw1[10:0]) -> offset[:12]. */
10418 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10419 /* hw1[10:0] -> offset[11:1]. */
10420 offset
|= (insn
& 0x7ff) << 1;
10421 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10422 offset[24:22] already have the same value because of the
10423 sign extension above. */
10424 offset
^= ((~insn
) & (1 << 13)) << 10;
10425 offset
^= ((~insn
) & (1 << 11)) << 11;
10427 if (insn
& (1 << 14)) {
10428 /* Branch and link. */
10429 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10433 if (insn
& (1 << 12)) {
10435 gen_jmp(s
, offset
);
10438 offset
&= ~(uint32_t)2;
10439 /* thumb2 bx, no need to check */
10440 gen_bx_im(s
, offset
);
10442 } else if (((insn
>> 23) & 7) == 7) {
10444 if (insn
& (1 << 13))
10447 if (insn
& (1 << 26)) {
10448 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10451 if (!(insn
& (1 << 20))) {
10452 /* Hypervisor call (v7) */
10453 int imm16
= extract32(insn
, 16, 4) << 12
10454 | extract32(insn
, 0, 12);
10461 /* Secure monitor call (v6+) */
10469 op
= (insn
>> 20) & 7;
10471 case 0: /* msr cpsr. */
10472 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10473 tmp
= load_reg(s
, rn
);
10474 /* the constant is the mask and SYSm fields */
10475 addr
= tcg_const_i32(insn
& 0xfff);
10476 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10477 tcg_temp_free_i32(addr
);
10478 tcg_temp_free_i32(tmp
);
10483 case 1: /* msr spsr. */
10484 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10488 if (extract32(insn
, 5, 1)) {
10490 int sysm
= extract32(insn
, 8, 4) |
10491 (extract32(insn
, 4, 1) << 4);
10494 gen_msr_banked(s
, r
, sysm
, rm
);
10498 /* MSR (for PSRs) */
10499 tmp
= load_reg(s
, rn
);
10501 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10505 case 2: /* cps, nop-hint. */
10506 if (((insn
>> 8) & 7) == 0) {
10507 gen_nop_hint(s
, insn
& 0xff);
10509 /* Implemented as NOP in user mode. */
10514 if (insn
& (1 << 10)) {
10515 if (insn
& (1 << 7))
10517 if (insn
& (1 << 6))
10519 if (insn
& (1 << 5))
10521 if (insn
& (1 << 9))
10522 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10524 if (insn
& (1 << 8)) {
10526 imm
|= (insn
& 0x1f);
10529 gen_set_psr_im(s
, offset
, 0, imm
);
10532 case 3: /* Special control operations. */
10534 op
= (insn
>> 4) & 0xf;
10536 case 2: /* clrex */
10541 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10544 /* We need to break the TB after this insn
10545 * to execute self-modifying code correctly
10546 * and also to take any pending interrupts
10556 /* Trivial implementation equivalent to bx.
10557 * This instruction doesn't exist at all for M-profile.
10559 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10562 tmp
= load_reg(s
, rn
);
10565 case 5: /* Exception return. */
10569 if (rn
!= 14 || rd
!= 15) {
10572 tmp
= load_reg(s
, rn
);
10573 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10574 gen_exception_return(s
, tmp
);
10577 if (extract32(insn
, 5, 1) &&
10578 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10580 int sysm
= extract32(insn
, 16, 4) |
10581 (extract32(insn
, 4, 1) << 4);
10583 gen_mrs_banked(s
, 0, sysm
, rd
);
10587 if (extract32(insn
, 16, 4) != 0xf) {
10590 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10591 extract32(insn
, 0, 8) != 0) {
10596 tmp
= tcg_temp_new_i32();
10597 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10598 addr
= tcg_const_i32(insn
& 0xff);
10599 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10600 tcg_temp_free_i32(addr
);
10602 gen_helper_cpsr_read(tmp
, cpu_env
);
10604 store_reg(s
, rd
, tmp
);
10607 if (extract32(insn
, 5, 1) &&
10608 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10610 int sysm
= extract32(insn
, 16, 4) |
10611 (extract32(insn
, 4, 1) << 4);
10613 gen_mrs_banked(s
, 1, sysm
, rd
);
10618 /* Not accessible in user mode. */
10619 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10623 if (extract32(insn
, 16, 4) != 0xf ||
10624 extract32(insn
, 0, 8) != 0) {
10628 tmp
= load_cpu_field(spsr
);
10629 store_reg(s
, rd
, tmp
);
10634 /* Conditional branch. */
10635 op
= (insn
>> 22) & 0xf;
10636 /* Generate a conditional jump to next instruction. */
10637 s
->condlabel
= gen_new_label();
10638 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10641 /* offset[11:1] = insn[10:0] */
10642 offset
= (insn
& 0x7ff) << 1;
10643 /* offset[17:12] = insn[21:16]. */
10644 offset
|= (insn
& 0x003f0000) >> 4;
10645 /* offset[31:20] = insn[26]. */
10646 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10647 /* offset[18] = insn[13]. */
10648 offset
|= (insn
& (1 << 13)) << 5;
10649 /* offset[19] = insn[11]. */
10650 offset
|= (insn
& (1 << 11)) << 8;
10652 /* jump to the offset */
10653 gen_jmp(s
, s
->pc
+ offset
);
10656 /* Data processing immediate. */
10657 if (insn
& (1 << 25)) {
10658 if (insn
& (1 << 24)) {
10659 if (insn
& (1 << 20))
10661 /* Bitfield/Saturate. */
10662 op
= (insn
>> 21) & 7;
10664 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10666 tmp
= tcg_temp_new_i32();
10667 tcg_gen_movi_i32(tmp
, 0);
10669 tmp
= load_reg(s
, rn
);
10672 case 2: /* Signed bitfield extract. */
10674 if (shift
+ imm
> 32)
10677 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
10680 case 6: /* Unsigned bitfield extract. */
10682 if (shift
+ imm
> 32)
10685 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
10688 case 3: /* Bitfield insert/clear. */
10691 imm
= imm
+ 1 - shift
;
10693 tmp2
= load_reg(s
, rd
);
10694 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10695 tcg_temp_free_i32(tmp2
);
10700 default: /* Saturate. */
10703 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10705 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10707 tmp2
= tcg_const_i32(imm
);
10710 if ((op
& 1) && shift
== 0) {
10711 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10712 tcg_temp_free_i32(tmp
);
10713 tcg_temp_free_i32(tmp2
);
10716 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10718 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
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_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10730 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10733 tcg_temp_free_i32(tmp2
);
10736 store_reg(s
, rd
, tmp
);
10738 imm
= ((insn
& 0x04000000) >> 15)
10739 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10740 if (insn
& (1 << 22)) {
10741 /* 16-bit immediate. */
10742 imm
|= (insn
>> 4) & 0xf000;
10743 if (insn
& (1 << 23)) {
10745 tmp
= load_reg(s
, rd
);
10746 tcg_gen_ext16u_i32(tmp
, tmp
);
10747 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10750 tmp
= tcg_temp_new_i32();
10751 tcg_gen_movi_i32(tmp
, imm
);
10754 /* Add/sub 12-bit immediate. */
10756 offset
= s
->pc
& ~(uint32_t)3;
10757 if (insn
& (1 << 23))
10761 tmp
= tcg_temp_new_i32();
10762 tcg_gen_movi_i32(tmp
, offset
);
10764 tmp
= load_reg(s
, rn
);
10765 if (insn
& (1 << 23))
10766 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10768 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10771 store_reg(s
, rd
, tmp
);
10774 int shifter_out
= 0;
10775 /* modified 12-bit immediate. */
10776 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10777 imm
= (insn
& 0xff);
10780 /* Nothing to do. */
10782 case 1: /* 00XY00XY */
10785 case 2: /* XY00XY00 */
10789 case 3: /* XYXYXYXY */
10793 default: /* Rotated constant. */
10794 shift
= (shift
<< 1) | (imm
>> 7);
10796 imm
= imm
<< (32 - shift
);
10800 tmp2
= tcg_temp_new_i32();
10801 tcg_gen_movi_i32(tmp2
, imm
);
10802 rn
= (insn
>> 16) & 0xf;
10804 tmp
= tcg_temp_new_i32();
10805 tcg_gen_movi_i32(tmp
, 0);
10807 tmp
= load_reg(s
, rn
);
10809 op
= (insn
>> 21) & 0xf;
10810 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10811 shifter_out
, tmp
, tmp2
))
10813 tcg_temp_free_i32(tmp2
);
10814 rd
= (insn
>> 8) & 0xf;
10816 store_reg(s
, rd
, tmp
);
10818 tcg_temp_free_i32(tmp
);
10823 case 12: /* Load/store single data item. */
10830 if ((insn
& 0x01100000) == 0x01000000) {
10831 if (disas_neon_ls_insn(s
, insn
)) {
10836 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10838 if (!(insn
& (1 << 20))) {
10842 /* Byte or halfword load space with dest == r15 : memory hints.
10843 * Catch them early so we don't emit pointless addressing code.
10844 * This space is a mix of:
10845 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10846 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10848 * unallocated hints, which must be treated as NOPs
10849 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10850 * which is easiest for the decoding logic
10851 * Some space which must UNDEF
10853 int op1
= (insn
>> 23) & 3;
10854 int op2
= (insn
>> 6) & 0x3f;
10859 /* UNPREDICTABLE, unallocated hint or
10860 * PLD/PLDW/PLI (literal)
10865 return 0; /* PLD/PLDW/PLI or unallocated hint */
10867 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10868 return 0; /* PLD/PLDW/PLI or unallocated hint */
10870 /* UNDEF space, or an UNPREDICTABLE */
10874 memidx
= get_mem_index(s
);
10876 addr
= tcg_temp_new_i32();
10878 /* s->pc has already been incremented by 4. */
10879 imm
= s
->pc
& 0xfffffffc;
10880 if (insn
& (1 << 23))
10881 imm
+= insn
& 0xfff;
10883 imm
-= insn
& 0xfff;
10884 tcg_gen_movi_i32(addr
, imm
);
10886 addr
= load_reg(s
, rn
);
10887 if (insn
& (1 << 23)) {
10888 /* Positive offset. */
10889 imm
= insn
& 0xfff;
10890 tcg_gen_addi_i32(addr
, addr
, imm
);
10893 switch ((insn
>> 8) & 0xf) {
10894 case 0x0: /* Shifted Register. */
10895 shift
= (insn
>> 4) & 0xf;
10897 tcg_temp_free_i32(addr
);
10900 tmp
= load_reg(s
, rm
);
10902 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10903 tcg_gen_add_i32(addr
, addr
, tmp
);
10904 tcg_temp_free_i32(tmp
);
10906 case 0xc: /* Negative offset. */
10907 tcg_gen_addi_i32(addr
, addr
, -imm
);
10909 case 0xe: /* User privilege. */
10910 tcg_gen_addi_i32(addr
, addr
, imm
);
10911 memidx
= get_a32_user_mem_index(s
);
10913 case 0x9: /* Post-decrement. */
10915 /* Fall through. */
10916 case 0xb: /* Post-increment. */
10920 case 0xd: /* Pre-decrement. */
10922 /* Fall through. */
10923 case 0xf: /* Pre-increment. */
10924 tcg_gen_addi_i32(addr
, addr
, imm
);
10928 tcg_temp_free_i32(addr
);
10934 issinfo
= writeback
? ISSInvalid
: rs
;
10936 if (insn
& (1 << 20)) {
10938 tmp
= tcg_temp_new_i32();
10941 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10944 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10947 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10950 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10953 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10956 tcg_temp_free_i32(tmp
);
10957 tcg_temp_free_i32(addr
);
10961 gen_bx_excret(s
, tmp
);
10963 store_reg(s
, rs
, tmp
);
10967 tmp
= load_reg(s
, rs
);
10970 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
10973 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
10976 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
10979 tcg_temp_free_i32(tmp
);
10980 tcg_temp_free_i32(addr
);
10983 tcg_temp_free_i32(tmp
);
10986 tcg_gen_addi_i32(addr
, addr
, imm
);
10988 store_reg(s
, rn
, addr
);
10990 tcg_temp_free_i32(addr
);
11002 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
11004 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
11011 if (s
->condexec_mask
) {
11012 cond
= s
->condexec_cond
;
11013 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
11014 s
->condlabel
= gen_new_label();
11015 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11020 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11023 switch (insn
>> 12) {
11027 op
= (insn
>> 11) & 3;
11030 rn
= (insn
>> 3) & 7;
11031 tmp
= load_reg(s
, rn
);
11032 if (insn
& (1 << 10)) {
11034 tmp2
= tcg_temp_new_i32();
11035 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11038 rm
= (insn
>> 6) & 7;
11039 tmp2
= load_reg(s
, rm
);
11041 if (insn
& (1 << 9)) {
11042 if (s
->condexec_mask
)
11043 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11045 gen_sub_CC(tmp
, tmp
, tmp2
);
11047 if (s
->condexec_mask
)
11048 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11050 gen_add_CC(tmp
, tmp
, tmp2
);
11052 tcg_temp_free_i32(tmp2
);
11053 store_reg(s
, rd
, tmp
);
11055 /* shift immediate */
11056 rm
= (insn
>> 3) & 7;
11057 shift
= (insn
>> 6) & 0x1f;
11058 tmp
= load_reg(s
, rm
);
11059 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11060 if (!s
->condexec_mask
)
11062 store_reg(s
, rd
, tmp
);
11066 /* arithmetic large immediate */
11067 op
= (insn
>> 11) & 3;
11068 rd
= (insn
>> 8) & 0x7;
11069 if (op
== 0) { /* mov */
11070 tmp
= tcg_temp_new_i32();
11071 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11072 if (!s
->condexec_mask
)
11074 store_reg(s
, rd
, tmp
);
11076 tmp
= load_reg(s
, rd
);
11077 tmp2
= tcg_temp_new_i32();
11078 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11081 gen_sub_CC(tmp
, tmp
, tmp2
);
11082 tcg_temp_free_i32(tmp
);
11083 tcg_temp_free_i32(tmp2
);
11086 if (s
->condexec_mask
)
11087 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11089 gen_add_CC(tmp
, tmp
, tmp2
);
11090 tcg_temp_free_i32(tmp2
);
11091 store_reg(s
, rd
, tmp
);
11094 if (s
->condexec_mask
)
11095 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11097 gen_sub_CC(tmp
, tmp
, tmp2
);
11098 tcg_temp_free_i32(tmp2
);
11099 store_reg(s
, rd
, tmp
);
11105 if (insn
& (1 << 11)) {
11106 rd
= (insn
>> 8) & 7;
11107 /* load pc-relative. Bit 1 of PC is ignored. */
11108 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11109 val
&= ~(uint32_t)2;
11110 addr
= tcg_temp_new_i32();
11111 tcg_gen_movi_i32(addr
, val
);
11112 tmp
= tcg_temp_new_i32();
11113 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11115 tcg_temp_free_i32(addr
);
11116 store_reg(s
, rd
, tmp
);
11119 if (insn
& (1 << 10)) {
11120 /* data processing extended or blx */
11121 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11122 rm
= (insn
>> 3) & 0xf;
11123 op
= (insn
>> 8) & 3;
11126 tmp
= load_reg(s
, rd
);
11127 tmp2
= load_reg(s
, rm
);
11128 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11129 tcg_temp_free_i32(tmp2
);
11130 store_reg(s
, rd
, tmp
);
11133 tmp
= load_reg(s
, rd
);
11134 tmp2
= load_reg(s
, rm
);
11135 gen_sub_CC(tmp
, tmp
, tmp2
);
11136 tcg_temp_free_i32(tmp2
);
11137 tcg_temp_free_i32(tmp
);
11139 case 2: /* mov/cpy */
11140 tmp
= load_reg(s
, rm
);
11141 store_reg(s
, rd
, tmp
);
11143 case 3:/* branch [and link] exchange thumb register */
11144 tmp
= load_reg(s
, rm
);
11145 if (insn
& (1 << 7)) {
11147 val
= (uint32_t)s
->pc
| 1;
11148 tmp2
= tcg_temp_new_i32();
11149 tcg_gen_movi_i32(tmp2
, val
);
11150 store_reg(s
, 14, tmp2
);
11153 /* Only BX works as exception-return, not BLX */
11154 gen_bx_excret(s
, tmp
);
11161 /* data processing register */
11163 rm
= (insn
>> 3) & 7;
11164 op
= (insn
>> 6) & 0xf;
11165 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11166 /* the shift/rotate ops want the operands backwards */
11175 if (op
== 9) { /* neg */
11176 tmp
= tcg_temp_new_i32();
11177 tcg_gen_movi_i32(tmp
, 0);
11178 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11179 tmp
= load_reg(s
, rd
);
11181 TCGV_UNUSED_I32(tmp
);
11184 tmp2
= load_reg(s
, rm
);
11186 case 0x0: /* and */
11187 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11188 if (!s
->condexec_mask
)
11191 case 0x1: /* eor */
11192 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11193 if (!s
->condexec_mask
)
11196 case 0x2: /* lsl */
11197 if (s
->condexec_mask
) {
11198 gen_shl(tmp2
, tmp2
, tmp
);
11200 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11201 gen_logic_CC(tmp2
);
11204 case 0x3: /* lsr */
11205 if (s
->condexec_mask
) {
11206 gen_shr(tmp2
, tmp2
, tmp
);
11208 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11209 gen_logic_CC(tmp2
);
11212 case 0x4: /* asr */
11213 if (s
->condexec_mask
) {
11214 gen_sar(tmp2
, tmp2
, tmp
);
11216 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11217 gen_logic_CC(tmp2
);
11220 case 0x5: /* adc */
11221 if (s
->condexec_mask
) {
11222 gen_adc(tmp
, tmp2
);
11224 gen_adc_CC(tmp
, tmp
, tmp2
);
11227 case 0x6: /* sbc */
11228 if (s
->condexec_mask
) {
11229 gen_sub_carry(tmp
, tmp
, tmp2
);
11231 gen_sbc_CC(tmp
, tmp
, tmp2
);
11234 case 0x7: /* ror */
11235 if (s
->condexec_mask
) {
11236 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11237 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11239 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11240 gen_logic_CC(tmp2
);
11243 case 0x8: /* tst */
11244 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11248 case 0x9: /* neg */
11249 if (s
->condexec_mask
)
11250 tcg_gen_neg_i32(tmp
, tmp2
);
11252 gen_sub_CC(tmp
, tmp
, tmp2
);
11254 case 0xa: /* cmp */
11255 gen_sub_CC(tmp
, tmp
, tmp2
);
11258 case 0xb: /* cmn */
11259 gen_add_CC(tmp
, tmp
, tmp2
);
11262 case 0xc: /* orr */
11263 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11264 if (!s
->condexec_mask
)
11267 case 0xd: /* mul */
11268 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11269 if (!s
->condexec_mask
)
11272 case 0xe: /* bic */
11273 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11274 if (!s
->condexec_mask
)
11277 case 0xf: /* mvn */
11278 tcg_gen_not_i32(tmp2
, tmp2
);
11279 if (!s
->condexec_mask
)
11280 gen_logic_CC(tmp2
);
11287 store_reg(s
, rm
, tmp2
);
11289 tcg_temp_free_i32(tmp
);
11291 store_reg(s
, rd
, tmp
);
11292 tcg_temp_free_i32(tmp2
);
11295 tcg_temp_free_i32(tmp
);
11296 tcg_temp_free_i32(tmp2
);
11301 /* load/store register offset. */
11303 rn
= (insn
>> 3) & 7;
11304 rm
= (insn
>> 6) & 7;
11305 op
= (insn
>> 9) & 7;
11306 addr
= load_reg(s
, rn
);
11307 tmp
= load_reg(s
, rm
);
11308 tcg_gen_add_i32(addr
, addr
, tmp
);
11309 tcg_temp_free_i32(tmp
);
11311 if (op
< 3) { /* store */
11312 tmp
= load_reg(s
, rd
);
11314 tmp
= tcg_temp_new_i32();
11319 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11322 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11325 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11327 case 3: /* ldrsb */
11328 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11331 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11334 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11337 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11339 case 7: /* ldrsh */
11340 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11343 if (op
>= 3) { /* load */
11344 store_reg(s
, rd
, tmp
);
11346 tcg_temp_free_i32(tmp
);
11348 tcg_temp_free_i32(addr
);
11352 /* load/store word immediate offset */
11354 rn
= (insn
>> 3) & 7;
11355 addr
= load_reg(s
, rn
);
11356 val
= (insn
>> 4) & 0x7c;
11357 tcg_gen_addi_i32(addr
, addr
, val
);
11359 if (insn
& (1 << 11)) {
11361 tmp
= tcg_temp_new_i32();
11362 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11363 store_reg(s
, rd
, tmp
);
11366 tmp
= load_reg(s
, rd
);
11367 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11368 tcg_temp_free_i32(tmp
);
11370 tcg_temp_free_i32(addr
);
11374 /* load/store byte immediate offset */
11376 rn
= (insn
>> 3) & 7;
11377 addr
= load_reg(s
, rn
);
11378 val
= (insn
>> 6) & 0x1f;
11379 tcg_gen_addi_i32(addr
, addr
, val
);
11381 if (insn
& (1 << 11)) {
11383 tmp
= tcg_temp_new_i32();
11384 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11385 store_reg(s
, rd
, tmp
);
11388 tmp
= load_reg(s
, rd
);
11389 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11390 tcg_temp_free_i32(tmp
);
11392 tcg_temp_free_i32(addr
);
11396 /* load/store halfword immediate offset */
11398 rn
= (insn
>> 3) & 7;
11399 addr
= load_reg(s
, rn
);
11400 val
= (insn
>> 5) & 0x3e;
11401 tcg_gen_addi_i32(addr
, addr
, val
);
11403 if (insn
& (1 << 11)) {
11405 tmp
= tcg_temp_new_i32();
11406 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11407 store_reg(s
, rd
, tmp
);
11410 tmp
= load_reg(s
, rd
);
11411 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11412 tcg_temp_free_i32(tmp
);
11414 tcg_temp_free_i32(addr
);
11418 /* load/store from stack */
11419 rd
= (insn
>> 8) & 7;
11420 addr
= load_reg(s
, 13);
11421 val
= (insn
& 0xff) * 4;
11422 tcg_gen_addi_i32(addr
, addr
, val
);
11424 if (insn
& (1 << 11)) {
11426 tmp
= tcg_temp_new_i32();
11427 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11428 store_reg(s
, rd
, tmp
);
11431 tmp
= load_reg(s
, rd
);
11432 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11433 tcg_temp_free_i32(tmp
);
11435 tcg_temp_free_i32(addr
);
11439 /* add to high reg */
11440 rd
= (insn
>> 8) & 7;
11441 if (insn
& (1 << 11)) {
11443 tmp
= load_reg(s
, 13);
11445 /* PC. bit 1 is ignored. */
11446 tmp
= tcg_temp_new_i32();
11447 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11449 val
= (insn
& 0xff) * 4;
11450 tcg_gen_addi_i32(tmp
, tmp
, val
);
11451 store_reg(s
, rd
, tmp
);
11456 op
= (insn
>> 8) & 0xf;
11459 /* adjust stack pointer */
11460 tmp
= load_reg(s
, 13);
11461 val
= (insn
& 0x7f) * 4;
11462 if (insn
& (1 << 7))
11463 val
= -(int32_t)val
;
11464 tcg_gen_addi_i32(tmp
, tmp
, val
);
11465 store_reg(s
, 13, tmp
);
11468 case 2: /* sign/zero extend. */
11471 rm
= (insn
>> 3) & 7;
11472 tmp
= load_reg(s
, rm
);
11473 switch ((insn
>> 6) & 3) {
11474 case 0: gen_sxth(tmp
); break;
11475 case 1: gen_sxtb(tmp
); break;
11476 case 2: gen_uxth(tmp
); break;
11477 case 3: gen_uxtb(tmp
); break;
11479 store_reg(s
, rd
, tmp
);
11481 case 4: case 5: case 0xc: case 0xd:
11483 addr
= load_reg(s
, 13);
11484 if (insn
& (1 << 8))
11488 for (i
= 0; i
< 8; i
++) {
11489 if (insn
& (1 << i
))
11492 if ((insn
& (1 << 11)) == 0) {
11493 tcg_gen_addi_i32(addr
, addr
, -offset
);
11495 for (i
= 0; i
< 8; i
++) {
11496 if (insn
& (1 << i
)) {
11497 if (insn
& (1 << 11)) {
11499 tmp
= tcg_temp_new_i32();
11500 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11501 store_reg(s
, i
, tmp
);
11504 tmp
= load_reg(s
, i
);
11505 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11506 tcg_temp_free_i32(tmp
);
11508 /* advance to the next address. */
11509 tcg_gen_addi_i32(addr
, addr
, 4);
11512 TCGV_UNUSED_I32(tmp
);
11513 if (insn
& (1 << 8)) {
11514 if (insn
& (1 << 11)) {
11516 tmp
= tcg_temp_new_i32();
11517 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11518 /* don't set the pc until the rest of the instruction
11522 tmp
= load_reg(s
, 14);
11523 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11524 tcg_temp_free_i32(tmp
);
11526 tcg_gen_addi_i32(addr
, addr
, 4);
11528 if ((insn
& (1 << 11)) == 0) {
11529 tcg_gen_addi_i32(addr
, addr
, -offset
);
11531 /* write back the new stack pointer */
11532 store_reg(s
, 13, addr
);
11533 /* set the new PC value */
11534 if ((insn
& 0x0900) == 0x0900) {
11535 store_reg_from_load(s
, 15, tmp
);
11539 case 1: case 3: case 9: case 11: /* czb */
11541 tmp
= load_reg(s
, rm
);
11542 s
->condlabel
= gen_new_label();
11544 if (insn
& (1 << 11))
11545 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11547 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11548 tcg_temp_free_i32(tmp
);
11549 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11550 val
= (uint32_t)s
->pc
+ 2;
11555 case 15: /* IT, nop-hint. */
11556 if ((insn
& 0xf) == 0) {
11557 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11561 s
->condexec_cond
= (insn
>> 4) & 0xe;
11562 s
->condexec_mask
= insn
& 0x1f;
11563 /* No actual code generated for this insn, just setup state. */
11566 case 0xe: /* bkpt */
11568 int imm8
= extract32(insn
, 0, 8);
11570 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11571 default_exception_el(s
));
11575 case 0xa: /* rev, and hlt */
11577 int op1
= extract32(insn
, 6, 2);
11581 int imm6
= extract32(insn
, 0, 6);
11587 /* Otherwise this is rev */
11589 rn
= (insn
>> 3) & 0x7;
11591 tmp
= load_reg(s
, rn
);
11593 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11594 case 1: gen_rev16(tmp
); break;
11595 case 3: gen_revsh(tmp
); break;
11597 g_assert_not_reached();
11599 store_reg(s
, rd
, tmp
);
11604 switch ((insn
>> 5) & 7) {
11608 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11609 gen_helper_setend(cpu_env
);
11610 s
->is_jmp
= DISAS_UPDATE
;
11619 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11620 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11623 addr
= tcg_const_i32(19);
11624 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11625 tcg_temp_free_i32(addr
);
11629 addr
= tcg_const_i32(16);
11630 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11631 tcg_temp_free_i32(addr
);
11633 tcg_temp_free_i32(tmp
);
11636 if (insn
& (1 << 4)) {
11637 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11641 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11656 /* load/store multiple */
11657 TCGv_i32 loaded_var
;
11658 TCGV_UNUSED_I32(loaded_var
);
11659 rn
= (insn
>> 8) & 0x7;
11660 addr
= load_reg(s
, rn
);
11661 for (i
= 0; i
< 8; i
++) {
11662 if (insn
& (1 << i
)) {
11663 if (insn
& (1 << 11)) {
11665 tmp
= tcg_temp_new_i32();
11666 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11670 store_reg(s
, i
, tmp
);
11674 tmp
= load_reg(s
, i
);
11675 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11676 tcg_temp_free_i32(tmp
);
11678 /* advance to the next address */
11679 tcg_gen_addi_i32(addr
, addr
, 4);
11682 if ((insn
& (1 << rn
)) == 0) {
11683 /* base reg not in list: base register writeback */
11684 store_reg(s
, rn
, addr
);
11686 /* base reg in list: if load, complete it now */
11687 if (insn
& (1 << 11)) {
11688 store_reg(s
, rn
, loaded_var
);
11690 tcg_temp_free_i32(addr
);
11695 /* conditional branch or swi */
11696 cond
= (insn
>> 8) & 0xf;
11702 gen_set_pc_im(s
, s
->pc
);
11703 s
->svc_imm
= extract32(insn
, 0, 8);
11704 s
->is_jmp
= DISAS_SWI
;
11707 /* generate a conditional jump to next instruction */
11708 s
->condlabel
= gen_new_label();
11709 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11712 /* jump to the offset */
11713 val
= (uint32_t)s
->pc
+ 2;
11714 offset
= ((int32_t)insn
<< 24) >> 24;
11715 val
+= offset
<< 1;
11720 if (insn
& (1 << 11)) {
11721 if (disas_thumb2_insn(env
, s
, insn
))
11725 /* unconditional branch */
11726 val
= (uint32_t)s
->pc
;
11727 offset
= ((int32_t)insn
<< 21) >> 21;
11728 val
+= (offset
<< 1) + 2;
11733 if (disas_thumb2_insn(env
, s
, insn
))
11739 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11740 default_exception_el(s
));
11744 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11745 default_exception_el(s
));
11748 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11750 /* Return true if the insn at dc->pc might cross a page boundary.
11751 * (False positives are OK, false negatives are not.)
11755 if ((s
->pc
& 3) == 0) {
11756 /* At a 4-aligned address we can't be crossing a page */
11760 /* This must be a Thumb insn */
11761 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11763 if ((insn
>> 11) >= 0x1d) {
11764 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11765 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11766 * end up actually treating this as two 16-bit insns (see the
11767 * code at the start of disas_thumb2_insn()) but we don't bother
11768 * to check for that as it is unlikely, and false positives here
11773 /* Definitely a 16-bit insn, can't be crossing a page. */
11777 /* generate intermediate code for basic block 'tb'. */
11778 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11780 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11781 CPUState
*cs
= CPU(cpu
);
11782 DisasContext dc1
, *dc
= &dc1
;
11783 target_ulong pc_start
;
11784 target_ulong next_page_start
;
11789 /* generate intermediate code */
11791 /* The A64 decoder has its own top level loop, because it doesn't need
11792 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11794 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11795 gen_intermediate_code_a64(cpu
, tb
);
11803 dc
->is_jmp
= DISAS_NEXT
;
11805 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11809 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11810 * there is no secure EL1, so we route exceptions to EL3.
11812 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11813 !arm_el_is_aa64(env
, 3);
11814 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11815 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(tb
->flags
);
11816 dc
->be_data
= ARM_TBFLAG_BE_DATA(tb
->flags
) ? MO_BE
: MO_LE
;
11817 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11818 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11819 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, ARM_TBFLAG_MMUIDX(tb
->flags
));
11820 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11821 #if !defined(CONFIG_USER_ONLY)
11822 dc
->user
= (dc
->current_el
== 0);
11824 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11825 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11826 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11827 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11828 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11829 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11830 dc
->v7m_handler_mode
= ARM_TBFLAG_HANDLER(tb
->flags
);
11831 dc
->cp_regs
= cpu
->cp_regs
;
11832 dc
->features
= env
->features
;
11834 /* Single step state. The code-generation logic here is:
11836 * generate code with no special handling for single-stepping (except
11837 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11838 * this happens anyway because those changes are all system register or
11840 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11841 * emit code for one insn
11842 * emit code to clear PSTATE.SS
11843 * emit code to generate software step exception for completed step
11844 * end TB (as usual for having generated an exception)
11845 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11846 * emit code to generate a software step exception
11849 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11850 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11851 dc
->is_ldex
= false;
11852 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11854 cpu_F0s
= tcg_temp_new_i32();
11855 cpu_F1s
= tcg_temp_new_i32();
11856 cpu_F0d
= tcg_temp_new_i64();
11857 cpu_F1d
= tcg_temp_new_i64();
11860 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11861 cpu_M0
= tcg_temp_new_i64();
11862 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11864 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11865 if (max_insns
== 0) {
11866 max_insns
= CF_COUNT_MASK
;
11868 if (max_insns
> TCG_MAX_INSNS
) {
11869 max_insns
= TCG_MAX_INSNS
;
11874 tcg_clear_temp_count();
11876 /* A note on handling of the condexec (IT) bits:
11878 * We want to avoid the overhead of having to write the updated condexec
11879 * bits back to the CPUARMState for every instruction in an IT block. So:
11880 * (1) if the condexec bits are not already zero then we write
11881 * zero back into the CPUARMState now. This avoids complications trying
11882 * to do it at the end of the block. (For example if we don't do this
11883 * it's hard to identify whether we can safely skip writing condexec
11884 * at the end of the TB, which we definitely want to do for the case
11885 * where a TB doesn't do anything with the IT state at all.)
11886 * (2) if we are going to leave the TB then we call gen_set_condexec()
11887 * which will write the correct value into CPUARMState if zero is wrong.
11888 * This is done both for leaving the TB at the end, and for leaving
11889 * it because of an exception we know will happen, which is done in
11890 * gen_exception_insn(). The latter is necessary because we need to
11891 * leave the TB with the PC/IT state just prior to execution of the
11892 * instruction which caused the exception.
11893 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11894 * then the CPUARMState will be wrong and we need to reset it.
11895 * This is handled in the same way as restoration of the
11896 * PC in these situations; we save the value of the condexec bits
11897 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11898 * then uses this to restore them after an exception.
11900 * Note that there are no instructions which can read the condexec
11901 * bits, and none which can write non-static values to them, so
11902 * we don't need to care about whether CPUARMState is correct in the
11906 /* Reset the conditional execution bits immediately. This avoids
11907 complications trying to do it at the end of the block. */
11908 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11910 TCGv_i32 tmp
= tcg_temp_new_i32();
11911 tcg_gen_movi_i32(tmp
, 0);
11912 store_cpu_field(tmp
, condexec_bits
);
11915 dc
->insn_start_idx
= tcg_op_buf_count();
11916 tcg_gen_insn_start(dc
->pc
,
11917 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11921 #ifdef CONFIG_USER_ONLY
11922 /* Intercept jump to the magic kernel page. */
11923 if (dc
->pc
>= 0xffff0000) {
11924 /* We always get here via a jump, so know we are not in a
11925 conditional execution block. */
11926 gen_exception_internal(EXCP_KERNEL_TRAP
);
11927 dc
->is_jmp
= DISAS_EXC
;
11932 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11934 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11935 if (bp
->pc
== dc
->pc
) {
11936 if (bp
->flags
& BP_CPU
) {
11937 gen_set_condexec(dc
);
11938 gen_set_pc_im(dc
, dc
->pc
);
11939 gen_helper_check_breakpoints(cpu_env
);
11940 /* End the TB early; it's likely not going to be executed */
11941 dc
->is_jmp
= DISAS_UPDATE
;
11943 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11944 /* The address covered by the breakpoint must be
11945 included in [tb->pc, tb->pc + tb->size) in order
11946 to for it to be properly cleared -- thus we
11947 increment the PC here so that the logic setting
11948 tb->size below does the right thing. */
11949 /* TODO: Advance PC by correct instruction length to
11950 * avoid disassembler error messages */
11952 goto done_generating
;
11959 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11963 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11964 /* Singlestep state is Active-pending.
11965 * If we're in this state at the start of a TB then either
11966 * a) we just took an exception to an EL which is being debugged
11967 * and this is the first insn in the exception handler
11968 * b) debug exceptions were masked and we just unmasked them
11969 * without changing EL (eg by clearing PSTATE.D)
11970 * In either case we're going to take a swstep exception in the
11971 * "did not step an insn" case, and so the syndrome ISV and EX
11972 * bits should be zero.
11974 assert(num_insns
== 1);
11975 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11976 default_exception_el(dc
));
11977 goto done_generating
;
11981 disas_thumb_insn(env
, dc
);
11982 if (dc
->condexec_mask
) {
11983 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11984 | ((dc
->condexec_mask
>> 4) & 1);
11985 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11986 if (dc
->condexec_mask
== 0) {
11987 dc
->condexec_cond
= 0;
11991 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
11993 disas_arm_insn(dc
, insn
);
11996 if (dc
->condjmp
&& !dc
->is_jmp
) {
11997 gen_set_label(dc
->condlabel
);
12001 if (tcg_check_temp_count()) {
12002 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
12006 /* Translation stops when a conditional branch is encountered.
12007 * Otherwise the subsequent code could get translated several times.
12008 * Also stop translation when a page boundary is reached. This
12009 * ensures prefetch aborts occur at the right place. */
12011 /* We want to stop the TB if the next insn starts in a new page,
12012 * or if it spans between this page and the next. This means that
12013 * if we're looking at the last halfword in the page we need to
12014 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12015 * or a 32-bit Thumb insn (which won't).
12016 * This is to avoid generating a silly TB with a single 16-bit insn
12017 * in it at the end of this page (which would execute correctly
12018 * but isn't very efficient).
12020 end_of_page
= (dc
->pc
>= next_page_start
) ||
12021 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
12023 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
12024 !is_singlestepping(dc
) &&
12027 num_insns
< max_insns
);
12029 if (tb
->cflags
& CF_LAST_IO
) {
12031 /* FIXME: This can theoretically happen with self-modifying
12033 cpu_abort(cs
, "IO on conditional branch instruction");
12038 /* At this stage dc->condjmp will only be set when the skipped
12039 instruction was a conditional branch or trap, and the PC has
12040 already been written. */
12041 gen_set_condexec(dc
);
12042 if (dc
->is_jmp
== DISAS_BX_EXCRET
) {
12043 /* Exception return branches need some special case code at the
12044 * end of the TB, which is complex enough that it has to
12045 * handle the single-step vs not and the condition-failed
12046 * insn codepath itself.
12048 gen_bx_excret_final_code(dc
);
12049 } else if (unlikely(is_singlestepping(dc
))) {
12050 /* Unconditional and "condition passed" instruction codepath. */
12051 switch (dc
->is_jmp
) {
12053 gen_ss_advance(dc
);
12054 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12055 default_exception_el(dc
));
12058 gen_ss_advance(dc
);
12059 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12062 gen_ss_advance(dc
);
12063 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12067 gen_set_pc_im(dc
, dc
->pc
);
12070 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12071 gen_singlestep_exception(dc
);
12074 /* While branches must always occur at the end of an IT block,
12075 there are a few other things that can cause us to terminate
12076 the TB in the middle of an IT block:
12077 - Exception generating instructions (bkpt, swi, undefined).
12079 - Hardware watchpoints.
12080 Hardware breakpoints have already been handled and skip this code.
12082 switch(dc
->is_jmp
) {
12084 gen_goto_tb(dc
, 1, dc
->pc
);
12087 gen_set_pc_im(dc
, dc
->pc
);
12091 /* indicate that the hash table must be used to find the next TB */
12092 tcg_gen_exit_tb(0);
12094 case DISAS_TB_JUMP
:
12095 /* nothing more to generate */
12098 gen_helper_wfi(cpu_env
);
12099 /* The helper doesn't necessarily throw an exception, but we
12100 * must go back to the main loop to check for interrupts anyway.
12102 tcg_gen_exit_tb(0);
12105 gen_helper_wfe(cpu_env
);
12108 gen_helper_yield(cpu_env
);
12111 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12112 default_exception_el(dc
));
12115 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12118 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12124 /* "Condition failed" instruction codepath for the branch/trap insn */
12125 gen_set_label(dc
->condlabel
);
12126 gen_set_condexec(dc
);
12127 if (unlikely(is_singlestepping(dc
))) {
12128 gen_set_pc_im(dc
, dc
->pc
);
12129 gen_singlestep_exception(dc
);
12131 gen_goto_tb(dc
, 1, dc
->pc
);
12136 gen_tb_end(tb
, num_insns
);
12139 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
) &&
12140 qemu_log_in_addr_range(pc_start
)) {
12142 qemu_log("----------------\n");
12143 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
12144 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
12145 dc
->thumb
| (dc
->sctlr_b
<< 1));
12150 tb
->size
= dc
->pc
- pc_start
;
12151 tb
->icount
= num_insns
;
12154 static const char *cpu_mode_names
[16] = {
12155 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12156 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12159 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12162 ARMCPU
*cpu
= ARM_CPU(cs
);
12163 CPUARMState
*env
= &cpu
->env
;
12166 const char *ns_status
;
12169 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12173 for(i
=0;i
<16;i
++) {
12174 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12176 cpu_fprintf(f
, "\n");
12178 cpu_fprintf(f
, " ");
12180 psr
= cpsr_read(env
);
12182 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12183 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12184 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12189 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12191 psr
& (1 << 31) ? 'N' : '-',
12192 psr
& (1 << 30) ? 'Z' : '-',
12193 psr
& (1 << 29) ? 'C' : '-',
12194 psr
& (1 << 28) ? 'V' : '-',
12195 psr
& CPSR_T
? 'T' : 'A',
12197 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12199 if (flags
& CPU_DUMP_FPU
) {
12200 int numvfpregs
= 0;
12201 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12204 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12207 for (i
= 0; i
< numvfpregs
; i
++) {
12208 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12209 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12210 i
* 2, (uint32_t)v
,
12211 i
* 2 + 1, (uint32_t)(v
>> 32),
12214 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12218 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12219 target_ulong
*data
)
12223 env
->condexec_bits
= 0;
12224 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12226 env
->regs
[15] = data
[0];
12227 env
->condexec_bits
= data
[1];
12228 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;