4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
29 #include "qemu/bitops.h"
31 #include "exec/semihost.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
36 #include "trace-tcg.h"
40 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
41 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
42 /* currently all emulated v5 cores are also v5TE, so don't bother */
43 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
44 #define ENABLE_ARCH_5J 0
45 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
46 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
47 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
48 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
49 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
51 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
53 #include "translate.h"
55 #if defined(CONFIG_USER_ONLY)
58 #define IS_USER(s) (s->user)
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
64 static TCGv_i32 cpu_R
[16];
65 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
66 TCGv_i64 cpu_exclusive_addr
;
67 TCGv_i64 cpu_exclusive_val
;
69 /* FIXME: These should be removed. */
70 static TCGv_i32 cpu_F0s
, cpu_F1s
;
71 static TCGv_i64 cpu_F0d
, cpu_F1d
;
73 #include "exec/gen-icount.h"
75 static const char *regnames
[] =
76 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
79 /* initialize TCG globals. */
80 void arm_translate_init(void)
84 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
85 tcg_ctx
.tcg_env
= cpu_env
;
87 for (i
= 0; i
< 16; i
++) {
88 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
89 offsetof(CPUARMState
, regs
[i
]),
92 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
93 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
94 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
95 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
97 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
98 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
99 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
100 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
102 a64_translate_init();
105 /* Flags for the disas_set_da_iss info argument:
106 * lower bits hold the Rt register number, higher bits are flags.
108 typedef enum ISSInfo
{
111 ISSInvalid
= (1 << 5),
112 ISSIsAcqRel
= (1 << 6),
113 ISSIsWrite
= (1 << 7),
114 ISSIs16Bit
= (1 << 8),
117 /* Save the syndrome information for a Data Abort */
118 static void disas_set_da_iss(DisasContext
*s
, TCGMemOp memop
, ISSInfo issinfo
)
121 int sas
= memop
& MO_SIZE
;
122 bool sse
= memop
& MO_SIGN
;
123 bool is_acqrel
= issinfo
& ISSIsAcqRel
;
124 bool is_write
= issinfo
& ISSIsWrite
;
125 bool is_16bit
= issinfo
& ISSIs16Bit
;
126 int srt
= issinfo
& ISSRegMask
;
128 if (issinfo
& ISSInvalid
) {
129 /* Some callsites want to conditionally provide ISS info,
130 * eg "only if this was not a writeback"
136 /* For AArch32, insns where the src/dest is R15 never generate
137 * ISS information. Catching that here saves checking at all
143 syn
= syn_data_abort_with_iss(0, sas
, sse
, srt
, 0, is_acqrel
,
144 0, 0, 0, is_write
, 0, is_16bit
);
145 disas_set_insn_syndrome(s
, syn
);
148 static inline int get_a32_user_mem_index(DisasContext
*s
)
150 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
152 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
153 * otherwise, access as if at PL0.
155 switch (s
->mmu_idx
) {
156 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
157 case ARMMMUIdx_S12NSE0
:
158 case ARMMMUIdx_S12NSE1
:
159 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0
);
161 case ARMMMUIdx_S1SE0
:
162 case ARMMMUIdx_S1SE1
:
163 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0
);
164 case ARMMMUIdx_MUser
:
165 case ARMMMUIdx_MPriv
:
166 case ARMMMUIdx_MNegPri
:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser
);
170 g_assert_not_reached();
174 static inline TCGv_i32
load_cpu_offset(int offset
)
176 TCGv_i32 tmp
= tcg_temp_new_i32();
177 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
181 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
183 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
185 tcg_gen_st_i32(var
, cpu_env
, offset
);
186 tcg_temp_free_i32(var
);
189 #define store_cpu_field(var, name) \
190 store_cpu_offset(var, offsetof(CPUARMState, name))
192 /* Set a variable to the value of a CPU register. */
193 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
197 /* normally, since we updated PC, we need only to add one insn */
199 addr
= (long)s
->pc
+ 2;
201 addr
= (long)s
->pc
+ 4;
202 tcg_gen_movi_i32(var
, addr
);
204 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
208 /* Create a new temporary and set it to the value of a CPU register. */
209 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
211 TCGv_i32 tmp
= tcg_temp_new_i32();
212 load_reg_var(s
, tmp
, reg
);
216 /* Set a CPU register. The source must be a temporary and will be
218 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
221 /* In Thumb mode, we must ignore bit 0.
222 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
223 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
224 * We choose to ignore [1:0] in ARM mode for all architecture versions.
226 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
227 s
->base
.is_jmp
= DISAS_JUMP
;
229 tcg_gen_mov_i32(cpu_R
[reg
], var
);
230 tcg_temp_free_i32(var
);
233 /* Value extensions. */
234 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
235 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
236 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
237 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
239 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
240 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
243 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
245 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
246 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
247 tcg_temp_free_i32(tmp_mask
);
249 /* Set NZCV flags from the high 4 bits of var. */
250 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
252 static void gen_exception_internal(int excp
)
254 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
256 assert(excp_is_internal(excp
));
257 gen_helper_exception_internal(cpu_env
, tcg_excp
);
258 tcg_temp_free_i32(tcg_excp
);
261 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
263 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
264 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
265 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
267 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
270 tcg_temp_free_i32(tcg_el
);
271 tcg_temp_free_i32(tcg_syn
);
272 tcg_temp_free_i32(tcg_excp
);
275 static void gen_ss_advance(DisasContext
*s
)
277 /* If the singlestep state is Active-not-pending, advance to
282 gen_helper_clear_pstate_ss(cpu_env
);
286 static void gen_step_complete_exception(DisasContext
*s
)
288 /* We just completed step of an insn. Move from Active-not-pending
289 * to Active-pending, and then also take the swstep exception.
290 * This corresponds to making the (IMPDEF) choice to prioritize
291 * swstep exceptions over asynchronous exceptions taken to an exception
292 * level where debug is disabled. This choice has the advantage that
293 * we do not need to maintain internal state corresponding to the
294 * ISV/EX syndrome bits between completion of the step and generation
295 * of the exception, and our syndrome information is always correct.
298 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
299 default_exception_el(s
));
300 s
->base
.is_jmp
= DISAS_NORETURN
;
303 static void gen_singlestep_exception(DisasContext
*s
)
305 /* Generate the right kind of exception for singlestep, which is
306 * either the architectural singlestep or EXCP_DEBUG for QEMU's
307 * gdb singlestepping.
310 gen_step_complete_exception(s
);
312 gen_exception_internal(EXCP_DEBUG
);
316 static inline bool is_singlestepping(DisasContext
*s
)
318 /* Return true if we are singlestepping either because of
319 * architectural singlestep or QEMU gdbstub singlestep. This does
320 * not include the command line '-singlestep' mode which is rather
321 * misnamed as it only means "one instruction per TB" and doesn't
322 * affect the code we generate.
324 return s
->base
.singlestep_enabled
|| s
->ss_active
;
327 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
329 TCGv_i32 tmp1
= tcg_temp_new_i32();
330 TCGv_i32 tmp2
= tcg_temp_new_i32();
331 tcg_gen_ext16s_i32(tmp1
, a
);
332 tcg_gen_ext16s_i32(tmp2
, b
);
333 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
334 tcg_temp_free_i32(tmp2
);
335 tcg_gen_sari_i32(a
, a
, 16);
336 tcg_gen_sari_i32(b
, b
, 16);
337 tcg_gen_mul_i32(b
, b
, a
);
338 tcg_gen_mov_i32(a
, tmp1
);
339 tcg_temp_free_i32(tmp1
);
342 /* Byteswap each halfword. */
343 static void gen_rev16(TCGv_i32 var
)
345 TCGv_i32 tmp
= tcg_temp_new_i32();
346 TCGv_i32 mask
= tcg_const_i32(0x00ff00ff);
347 tcg_gen_shri_i32(tmp
, var
, 8);
348 tcg_gen_and_i32(tmp
, tmp
, mask
);
349 tcg_gen_and_i32(var
, var
, mask
);
350 tcg_gen_shli_i32(var
, var
, 8);
351 tcg_gen_or_i32(var
, var
, tmp
);
352 tcg_temp_free_i32(mask
);
353 tcg_temp_free_i32(tmp
);
356 /* Byteswap low halfword and sign extend. */
357 static void gen_revsh(TCGv_i32 var
)
359 tcg_gen_ext16u_i32(var
, var
);
360 tcg_gen_bswap16_i32(var
, var
);
361 tcg_gen_ext16s_i32(var
, var
);
364 /* Return (b << 32) + a. Mark inputs as dead */
365 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
367 TCGv_i64 tmp64
= tcg_temp_new_i64();
369 tcg_gen_extu_i32_i64(tmp64
, b
);
370 tcg_temp_free_i32(b
);
371 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
372 tcg_gen_add_i64(a
, tmp64
, a
);
374 tcg_temp_free_i64(tmp64
);
378 /* Return (b << 32) - a. Mark inputs as dead. */
379 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
381 TCGv_i64 tmp64
= tcg_temp_new_i64();
383 tcg_gen_extu_i32_i64(tmp64
, b
);
384 tcg_temp_free_i32(b
);
385 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
386 tcg_gen_sub_i64(a
, tmp64
, a
);
388 tcg_temp_free_i64(tmp64
);
392 /* 32x32->64 multiply. Marks inputs as dead. */
393 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
395 TCGv_i32 lo
= tcg_temp_new_i32();
396 TCGv_i32 hi
= tcg_temp_new_i32();
399 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
400 tcg_temp_free_i32(a
);
401 tcg_temp_free_i32(b
);
403 ret
= tcg_temp_new_i64();
404 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
405 tcg_temp_free_i32(lo
);
406 tcg_temp_free_i32(hi
);
411 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
413 TCGv_i32 lo
= tcg_temp_new_i32();
414 TCGv_i32 hi
= tcg_temp_new_i32();
417 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
418 tcg_temp_free_i32(a
);
419 tcg_temp_free_i32(b
);
421 ret
= tcg_temp_new_i64();
422 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
423 tcg_temp_free_i32(lo
);
424 tcg_temp_free_i32(hi
);
429 /* Swap low and high halfwords. */
430 static void gen_swap_half(TCGv_i32 var
)
432 TCGv_i32 tmp
= tcg_temp_new_i32();
433 tcg_gen_shri_i32(tmp
, var
, 16);
434 tcg_gen_shli_i32(var
, var
, 16);
435 tcg_gen_or_i32(var
, var
, tmp
);
436 tcg_temp_free_i32(tmp
);
439 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
440 tmp = (t0 ^ t1) & 0x8000;
443 t0 = (t0 + t1) ^ tmp;
446 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
448 TCGv_i32 tmp
= tcg_temp_new_i32();
449 tcg_gen_xor_i32(tmp
, t0
, t1
);
450 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
451 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
452 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
453 tcg_gen_add_i32(t0
, t0
, t1
);
454 tcg_gen_xor_i32(t0
, t0
, tmp
);
455 tcg_temp_free_i32(tmp
);
456 tcg_temp_free_i32(t1
);
459 /* Set CF to the top bit of var. */
460 static void gen_set_CF_bit31(TCGv_i32 var
)
462 tcg_gen_shri_i32(cpu_CF
, var
, 31);
465 /* Set N and Z flags from var. */
466 static inline void gen_logic_CC(TCGv_i32 var
)
468 tcg_gen_mov_i32(cpu_NF
, var
);
469 tcg_gen_mov_i32(cpu_ZF
, var
);
473 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
475 tcg_gen_add_i32(t0
, t0
, t1
);
476 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
479 /* dest = T0 + T1 + CF. */
480 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
482 tcg_gen_add_i32(dest
, t0
, t1
);
483 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
486 /* dest = T0 - T1 + CF - 1. */
487 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
489 tcg_gen_sub_i32(dest
, t0
, t1
);
490 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
491 tcg_gen_subi_i32(dest
, dest
, 1);
494 /* dest = T0 + T1. Compute C, N, V and Z flags */
495 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
497 TCGv_i32 tmp
= tcg_temp_new_i32();
498 tcg_gen_movi_i32(tmp
, 0);
499 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
500 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
501 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
502 tcg_gen_xor_i32(tmp
, t0
, t1
);
503 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
504 tcg_temp_free_i32(tmp
);
505 tcg_gen_mov_i32(dest
, cpu_NF
);
508 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
509 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
511 TCGv_i32 tmp
= tcg_temp_new_i32();
512 if (TCG_TARGET_HAS_add2_i32
) {
513 tcg_gen_movi_i32(tmp
, 0);
514 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
515 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
517 TCGv_i64 q0
= tcg_temp_new_i64();
518 TCGv_i64 q1
= tcg_temp_new_i64();
519 tcg_gen_extu_i32_i64(q0
, t0
);
520 tcg_gen_extu_i32_i64(q1
, t1
);
521 tcg_gen_add_i64(q0
, q0
, q1
);
522 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
523 tcg_gen_add_i64(q0
, q0
, q1
);
524 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
525 tcg_temp_free_i64(q0
);
526 tcg_temp_free_i64(q1
);
528 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
529 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
530 tcg_gen_xor_i32(tmp
, t0
, t1
);
531 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
532 tcg_temp_free_i32(tmp
);
533 tcg_gen_mov_i32(dest
, cpu_NF
);
536 /* dest = T0 - T1. Compute C, N, V and Z flags */
537 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
540 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
541 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
542 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
543 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
544 tmp
= tcg_temp_new_i32();
545 tcg_gen_xor_i32(tmp
, t0
, t1
);
546 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
547 tcg_temp_free_i32(tmp
);
548 tcg_gen_mov_i32(dest
, cpu_NF
);
551 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
552 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
554 TCGv_i32 tmp
= tcg_temp_new_i32();
555 tcg_gen_not_i32(tmp
, t1
);
556 gen_adc_CC(dest
, t0
, tmp
);
557 tcg_temp_free_i32(tmp
);
560 #define GEN_SHIFT(name) \
561 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
563 TCGv_i32 tmp1, tmp2, tmp3; \
564 tmp1 = tcg_temp_new_i32(); \
565 tcg_gen_andi_i32(tmp1, t1, 0xff); \
566 tmp2 = tcg_const_i32(0); \
567 tmp3 = tcg_const_i32(0x1f); \
568 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
569 tcg_temp_free_i32(tmp3); \
570 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
571 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
572 tcg_temp_free_i32(tmp2); \
573 tcg_temp_free_i32(tmp1); \
579 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
582 tmp1
= tcg_temp_new_i32();
583 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
584 tmp2
= tcg_const_i32(0x1f);
585 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
586 tcg_temp_free_i32(tmp2
);
587 tcg_gen_sar_i32(dest
, t0
, tmp1
);
588 tcg_temp_free_i32(tmp1
);
591 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
593 TCGv_i32 c0
= tcg_const_i32(0);
594 TCGv_i32 tmp
= tcg_temp_new_i32();
595 tcg_gen_neg_i32(tmp
, src
);
596 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
597 tcg_temp_free_i32(c0
);
598 tcg_temp_free_i32(tmp
);
601 static void shifter_out_im(TCGv_i32 var
, int shift
)
604 tcg_gen_andi_i32(cpu_CF
, var
, 1);
606 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
608 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
613 /* Shift by immediate. Includes special handling for shift == 0. */
614 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
615 int shift
, int flags
)
621 shifter_out_im(var
, 32 - shift
);
622 tcg_gen_shli_i32(var
, var
, shift
);
628 tcg_gen_shri_i32(cpu_CF
, var
, 31);
630 tcg_gen_movi_i32(var
, 0);
633 shifter_out_im(var
, shift
- 1);
634 tcg_gen_shri_i32(var
, var
, shift
);
641 shifter_out_im(var
, shift
- 1);
644 tcg_gen_sari_i32(var
, var
, shift
);
646 case 3: /* ROR/RRX */
649 shifter_out_im(var
, shift
- 1);
650 tcg_gen_rotri_i32(var
, var
, shift
); break;
652 TCGv_i32 tmp
= tcg_temp_new_i32();
653 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
655 shifter_out_im(var
, 0);
656 tcg_gen_shri_i32(var
, var
, 1);
657 tcg_gen_or_i32(var
, var
, tmp
);
658 tcg_temp_free_i32(tmp
);
663 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
664 TCGv_i32 shift
, int flags
)
668 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
669 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
670 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
671 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
676 gen_shl(var
, var
, shift
);
679 gen_shr(var
, var
, shift
);
682 gen_sar(var
, var
, shift
);
684 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
685 tcg_gen_rotr_i32(var
, var
, shift
); break;
688 tcg_temp_free_i32(shift
);
691 #define PAS_OP(pfx) \
693 case 0: gen_pas_helper(glue(pfx,add16)); break; \
694 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
695 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
696 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
697 case 4: gen_pas_helper(glue(pfx,add8)); break; \
698 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
700 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
705 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
707 tmp
= tcg_temp_new_ptr();
708 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
710 tcg_temp_free_ptr(tmp
);
713 tmp
= tcg_temp_new_ptr();
714 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
716 tcg_temp_free_ptr(tmp
);
718 #undef gen_pas_helper
719 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
732 #undef gen_pas_helper
737 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
738 #define PAS_OP(pfx) \
740 case 0: gen_pas_helper(glue(pfx,add8)); break; \
741 case 1: gen_pas_helper(glue(pfx,add16)); break; \
742 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
743 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
744 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
745 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
747 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
752 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
754 tmp
= tcg_temp_new_ptr();
755 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
757 tcg_temp_free_ptr(tmp
);
760 tmp
= tcg_temp_new_ptr();
761 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
763 tcg_temp_free_ptr(tmp
);
765 #undef gen_pas_helper
766 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
779 #undef gen_pas_helper
785 * Generate a conditional based on ARM condition code cc.
786 * This is common between ARM and Aarch64 targets.
788 void arm_test_cc(DisasCompare
*cmp
, int cc
)
819 case 8: /* hi: C && !Z */
820 case 9: /* ls: !C || Z -> !(C && !Z) */
822 value
= tcg_temp_new_i32();
824 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
825 ZF is non-zero for !Z; so AND the two subexpressions. */
826 tcg_gen_neg_i32(value
, cpu_CF
);
827 tcg_gen_and_i32(value
, value
, cpu_ZF
);
830 case 10: /* ge: N == V -> N ^ V == 0 */
831 case 11: /* lt: N != V -> N ^ V != 0 */
832 /* Since we're only interested in the sign bit, == 0 is >= 0. */
834 value
= tcg_temp_new_i32();
836 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
839 case 12: /* gt: !Z && N == V */
840 case 13: /* le: Z || N != V */
842 value
= tcg_temp_new_i32();
844 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
845 * the sign bit then AND with ZF to yield the result. */
846 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
847 tcg_gen_sari_i32(value
, value
, 31);
848 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
851 case 14: /* always */
852 case 15: /* always */
853 /* Use the ALWAYS condition, which will fold early.
854 * It doesn't matter what we use for the value. */
855 cond
= TCG_COND_ALWAYS
;
860 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
865 cond
= tcg_invert_cond(cond
);
871 cmp
->value_global
= global
;
874 void arm_free_cc(DisasCompare
*cmp
)
876 if (!cmp
->value_global
) {
877 tcg_temp_free_i32(cmp
->value
);
881 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
883 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
886 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
889 arm_test_cc(&cmp
, cc
);
890 arm_jump_cc(&cmp
, label
);
894 static const uint8_t table_logic_cc
[16] = {
913 static inline void gen_set_condexec(DisasContext
*s
)
915 if (s
->condexec_mask
) {
916 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
917 TCGv_i32 tmp
= tcg_temp_new_i32();
918 tcg_gen_movi_i32(tmp
, val
);
919 store_cpu_field(tmp
, condexec_bits
);
923 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
925 tcg_gen_movi_i32(cpu_R
[15], val
);
928 /* Set PC and Thumb state from an immediate address. */
929 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
933 s
->base
.is_jmp
= DISAS_JUMP
;
934 if (s
->thumb
!= (addr
& 1)) {
935 tmp
= tcg_temp_new_i32();
936 tcg_gen_movi_i32(tmp
, addr
& 1);
937 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
938 tcg_temp_free_i32(tmp
);
940 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
943 /* Set PC and Thumb state from var. var is marked as dead. */
944 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
946 s
->base
.is_jmp
= DISAS_JUMP
;
947 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
948 tcg_gen_andi_i32(var
, var
, 1);
949 store_cpu_field(var
, thumb
);
952 /* Set PC and Thumb state from var. var is marked as dead.
953 * For M-profile CPUs, include logic to detect exception-return
954 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
955 * and BX reg, and no others, and happens only for code in Handler mode.
957 static inline void gen_bx_excret(DisasContext
*s
, TCGv_i32 var
)
959 /* Generate the same code here as for a simple bx, but flag via
960 * s->base.is_jmp that we need to do the rest of the work later.
963 if (s
->v7m_handler_mode
&& arm_dc_feature(s
, ARM_FEATURE_M
)) {
964 s
->base
.is_jmp
= DISAS_BX_EXCRET
;
968 static inline void gen_bx_excret_final_code(DisasContext
*s
)
970 /* Generate the code to finish possible exception return and end the TB */
971 TCGLabel
*excret_label
= gen_new_label();
973 /* Is the new PC value in the magic range indicating exception return? */
974 tcg_gen_brcondi_i32(TCG_COND_GEU
, cpu_R
[15], 0xff000000, excret_label
);
975 /* No: end the TB as we would for a DISAS_JMP */
976 if (is_singlestepping(s
)) {
977 gen_singlestep_exception(s
);
981 gen_set_label(excret_label
);
982 /* Yes: this is an exception return.
983 * At this point in runtime env->regs[15] and env->thumb will hold
984 * the exception-return magic number, which do_v7m_exception_exit()
985 * will read. Nothing else will be able to see those values because
986 * the cpu-exec main loop guarantees that we will always go straight
987 * from raising the exception to the exception-handling code.
989 * gen_ss_advance(s) does nothing on M profile currently but
990 * calling it is conceptually the right thing as we have executed
991 * this instruction (compare SWI, HVC, SMC handling).
994 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
997 /* Variant of store_reg which uses branch&exchange logic when storing
998 to r15 in ARM architecture v7 and above. The source must be a temporary
999 and will be marked as dead. */
1000 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
1002 if (reg
== 15 && ENABLE_ARCH_7
) {
1005 store_reg(s
, reg
, var
);
1009 /* Variant of store_reg which uses branch&exchange logic when storing
1010 * to r15 in ARM architecture v5T and above. This is used for storing
1011 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1012 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1013 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
1015 if (reg
== 15 && ENABLE_ARCH_5
) {
1016 gen_bx_excret(s
, var
);
1018 store_reg(s
, reg
, var
);
1022 #ifdef CONFIG_USER_ONLY
1023 #define IS_USER_ONLY 1
1025 #define IS_USER_ONLY 0
1028 /* Abstractions of "generate code to do a guest load/store for
1029 * AArch32", where a vaddr is always 32 bits (and is zero
1030 * extended if we're a 64 bit core) and data is also
1031 * 32 bits unless specifically doing a 64 bit access.
1032 * These functions work like tcg_gen_qemu_{ld,st}* except
1033 * that the address argument is TCGv_i32 rather than TCGv.
1036 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, TCGMemOp op
)
1038 TCGv addr
= tcg_temp_new();
1039 tcg_gen_extu_i32_tl(addr
, a32
);
1041 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1042 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
1043 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
1048 static void gen_aa32_ld_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1049 int index
, TCGMemOp opc
)
1051 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1052 tcg_gen_qemu_ld_i32(val
, addr
, index
, opc
);
1053 tcg_temp_free(addr
);
1056 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1057 int index
, TCGMemOp opc
)
1059 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1060 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
1061 tcg_temp_free(addr
);
1064 #define DO_GEN_LD(SUFF, OPC) \
1065 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1066 TCGv_i32 a32, int index) \
1068 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1070 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1072 TCGv_i32 a32, int index, \
1075 gen_aa32_ld##SUFF(s, val, a32, index); \
1076 disas_set_da_iss(s, OPC, issinfo); \
1079 #define DO_GEN_ST(SUFF, OPC) \
1080 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1081 TCGv_i32 a32, int index) \
1083 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1085 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1087 TCGv_i32 a32, int index, \
1090 gen_aa32_st##SUFF(s, val, a32, index); \
1091 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1094 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
1096 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1097 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1098 tcg_gen_rotri_i64(val
, val
, 32);
1102 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1103 int index
, TCGMemOp opc
)
1105 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1106 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
1107 gen_aa32_frob64(s
, val
);
1108 tcg_temp_free(addr
);
1111 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1112 TCGv_i32 a32
, int index
)
1114 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1117 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1118 int index
, TCGMemOp opc
)
1120 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1122 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1123 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1124 TCGv_i64 tmp
= tcg_temp_new_i64();
1125 tcg_gen_rotri_i64(tmp
, val
, 32);
1126 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
1127 tcg_temp_free_i64(tmp
);
1129 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
1131 tcg_temp_free(addr
);
1134 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1135 TCGv_i32 a32
, int index
)
1137 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1140 DO_GEN_LD(8s
, MO_SB
)
1141 DO_GEN_LD(8u, MO_UB
)
1142 DO_GEN_LD(16s
, MO_SW
)
1143 DO_GEN_LD(16u, MO_UW
)
1144 DO_GEN_LD(32u, MO_UL
)
1146 DO_GEN_ST(16, MO_UW
)
1147 DO_GEN_ST(32, MO_UL
)
1149 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1151 /* The pre HVC helper handles cases when HVC gets trapped
1152 * as an undefined insn by runtime configuration (ie before
1153 * the insn really executes).
1155 gen_set_pc_im(s
, s
->pc
- 4);
1156 gen_helper_pre_hvc(cpu_env
);
1157 /* Otherwise we will treat this as a real exception which
1158 * happens after execution of the insn. (The distinction matters
1159 * for the PC value reported to the exception handler and also
1160 * for single stepping.)
1163 gen_set_pc_im(s
, s
->pc
);
1164 s
->base
.is_jmp
= DISAS_HVC
;
1167 static inline void gen_smc(DisasContext
*s
)
1169 /* As with HVC, we may take an exception either before or after
1170 * the insn executes.
1174 gen_set_pc_im(s
, s
->pc
- 4);
1175 tmp
= tcg_const_i32(syn_aa32_smc());
1176 gen_helper_pre_smc(cpu_env
, tmp
);
1177 tcg_temp_free_i32(tmp
);
1178 gen_set_pc_im(s
, s
->pc
);
1179 s
->base
.is_jmp
= DISAS_SMC
;
1182 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1184 gen_set_condexec(s
);
1185 gen_set_pc_im(s
, s
->pc
- offset
);
1186 gen_exception_internal(excp
);
1187 s
->base
.is_jmp
= DISAS_NORETURN
;
1190 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1191 int syn
, uint32_t target_el
)
1193 gen_set_condexec(s
);
1194 gen_set_pc_im(s
, s
->pc
- offset
);
1195 gen_exception(excp
, syn
, target_el
);
1196 s
->base
.is_jmp
= DISAS_NORETURN
;
1199 /* Force a TB lookup after an instruction that changes the CPU state. */
1200 static inline void gen_lookup_tb(DisasContext
*s
)
1202 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1203 s
->base
.is_jmp
= DISAS_EXIT
;
1206 static inline void gen_hlt(DisasContext
*s
, int imm
)
1208 /* HLT. This has two purposes.
1209 * Architecturally, it is an external halting debug instruction.
1210 * Since QEMU doesn't implement external debug, we treat this as
1211 * it is required for halting debug disabled: it will UNDEF.
1212 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1213 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1214 * must trigger semihosting even for ARMv7 and earlier, where
1215 * HLT was an undefined encoding.
1216 * In system mode, we don't allow userspace access to
1217 * semihosting, to provide some semblance of security
1218 * (and for consistency with our 32-bit semihosting).
1220 if (semihosting_enabled() &&
1221 #ifndef CONFIG_USER_ONLY
1222 s
->current_el
!= 0 &&
1224 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1225 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1229 gen_exception_insn(s
, s
->thumb
? 2 : 4, EXCP_UDEF
, syn_uncategorized(),
1230 default_exception_el(s
));
1233 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1236 int val
, rm
, shift
, shiftop
;
1239 if (!(insn
& (1 << 25))) {
1242 if (!(insn
& (1 << 23)))
1245 tcg_gen_addi_i32(var
, var
, val
);
1247 /* shift/register */
1249 shift
= (insn
>> 7) & 0x1f;
1250 shiftop
= (insn
>> 5) & 3;
1251 offset
= load_reg(s
, rm
);
1252 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1253 if (!(insn
& (1 << 23)))
1254 tcg_gen_sub_i32(var
, var
, offset
);
1256 tcg_gen_add_i32(var
, var
, offset
);
1257 tcg_temp_free_i32(offset
);
1261 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1262 int extra
, TCGv_i32 var
)
1267 if (insn
& (1 << 22)) {
1269 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1270 if (!(insn
& (1 << 23)))
1274 tcg_gen_addi_i32(var
, var
, val
);
1278 tcg_gen_addi_i32(var
, var
, extra
);
1280 offset
= load_reg(s
, rm
);
1281 if (!(insn
& (1 << 23)))
1282 tcg_gen_sub_i32(var
, var
, offset
);
1284 tcg_gen_add_i32(var
, var
, offset
);
1285 tcg_temp_free_i32(offset
);
1289 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1291 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1294 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1296 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1298 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1302 #define VFP_OP2(name) \
1303 static inline void gen_vfp_##name(int dp) \
1305 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1307 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1309 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1311 tcg_temp_free_ptr(fpst); \
1321 static inline void gen_vfp_F1_mul(int dp
)
1323 /* Like gen_vfp_mul() but put result in F1 */
1324 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1326 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1328 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1330 tcg_temp_free_ptr(fpst
);
1333 static inline void gen_vfp_F1_neg(int dp
)
1335 /* Like gen_vfp_neg() but put result in F1 */
1337 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1339 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1343 static inline void gen_vfp_abs(int dp
)
1346 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1348 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1351 static inline void gen_vfp_neg(int dp
)
1354 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1356 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1359 static inline void gen_vfp_sqrt(int dp
)
1362 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1364 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1367 static inline void gen_vfp_cmp(int dp
)
1370 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1372 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1375 static inline void gen_vfp_cmpe(int dp
)
1378 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1380 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1383 static inline void gen_vfp_F1_ld0(int dp
)
1386 tcg_gen_movi_i64(cpu_F1d
, 0);
1388 tcg_gen_movi_i32(cpu_F1s
, 0);
1391 #define VFP_GEN_ITOF(name) \
1392 static inline void gen_vfp_##name(int dp, int neon) \
1394 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1396 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1398 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1400 tcg_temp_free_ptr(statusptr); \
1407 #define VFP_GEN_FTOI(name) \
1408 static inline void gen_vfp_##name(int dp, int neon) \
1410 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1412 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1414 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1416 tcg_temp_free_ptr(statusptr); \
1425 #define VFP_GEN_FIX(name, round) \
1426 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1428 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1429 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1431 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1434 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1437 tcg_temp_free_i32(tmp_shift); \
1438 tcg_temp_free_ptr(statusptr); \
1440 VFP_GEN_FIX(tosh
, _round_to_zero
)
1441 VFP_GEN_FIX(tosl
, _round_to_zero
)
1442 VFP_GEN_FIX(touh
, _round_to_zero
)
1443 VFP_GEN_FIX(toul
, _round_to_zero
)
1450 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1453 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1455 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1459 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1462 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1464 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1469 vfp_reg_offset (int dp
, int reg
)
1472 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1474 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1475 + offsetof(CPU_DoubleU
, l
.upper
);
1477 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1478 + offsetof(CPU_DoubleU
, l
.lower
);
1482 /* Return the offset of a 32-bit piece of a NEON register.
1483 zero is the least significant end of the register. */
1485 neon_reg_offset (int reg
, int n
)
1489 return vfp_reg_offset(0, sreg
);
1492 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1494 TCGv_i32 tmp
= tcg_temp_new_i32();
1495 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1499 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1501 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1502 tcg_temp_free_i32(var
);
1505 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1507 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1510 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1512 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1515 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1516 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1517 #define tcg_gen_st_f32 tcg_gen_st_i32
1518 #define tcg_gen_st_f64 tcg_gen_st_i64
1520 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1523 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1525 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1528 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1531 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1533 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1536 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1539 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1541 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1544 #define ARM_CP_RW_BIT (1 << 20)
1546 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1548 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1551 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1553 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1556 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1558 TCGv_i32 var
= tcg_temp_new_i32();
1559 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1563 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1565 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1566 tcg_temp_free_i32(var
);
1569 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1571 iwmmxt_store_reg(cpu_M0
, rn
);
1574 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1576 iwmmxt_load_reg(cpu_M0
, rn
);
1579 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1581 iwmmxt_load_reg(cpu_V1
, rn
);
1582 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1585 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1587 iwmmxt_load_reg(cpu_V1
, rn
);
1588 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1591 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1593 iwmmxt_load_reg(cpu_V1
, rn
);
1594 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1597 #define IWMMXT_OP(name) \
1598 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1600 iwmmxt_load_reg(cpu_V1, rn); \
1601 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1604 #define IWMMXT_OP_ENV(name) \
1605 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1607 iwmmxt_load_reg(cpu_V1, rn); \
1608 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1611 #define IWMMXT_OP_ENV_SIZE(name) \
1612 IWMMXT_OP_ENV(name##b) \
1613 IWMMXT_OP_ENV(name##w) \
1614 IWMMXT_OP_ENV(name##l)
1616 #define IWMMXT_OP_ENV1(name) \
1617 static inline void gen_op_iwmmxt_##name##_M0(void) \
1619 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1633 IWMMXT_OP_ENV_SIZE(unpackl
)
1634 IWMMXT_OP_ENV_SIZE(unpackh
)
1636 IWMMXT_OP_ENV1(unpacklub
)
1637 IWMMXT_OP_ENV1(unpackluw
)
1638 IWMMXT_OP_ENV1(unpacklul
)
1639 IWMMXT_OP_ENV1(unpackhub
)
1640 IWMMXT_OP_ENV1(unpackhuw
)
1641 IWMMXT_OP_ENV1(unpackhul
)
1642 IWMMXT_OP_ENV1(unpacklsb
)
1643 IWMMXT_OP_ENV1(unpacklsw
)
1644 IWMMXT_OP_ENV1(unpacklsl
)
1645 IWMMXT_OP_ENV1(unpackhsb
)
1646 IWMMXT_OP_ENV1(unpackhsw
)
1647 IWMMXT_OP_ENV1(unpackhsl
)
1649 IWMMXT_OP_ENV_SIZE(cmpeq
)
1650 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1651 IWMMXT_OP_ENV_SIZE(cmpgts
)
1653 IWMMXT_OP_ENV_SIZE(mins
)
1654 IWMMXT_OP_ENV_SIZE(minu
)
1655 IWMMXT_OP_ENV_SIZE(maxs
)
1656 IWMMXT_OP_ENV_SIZE(maxu
)
1658 IWMMXT_OP_ENV_SIZE(subn
)
1659 IWMMXT_OP_ENV_SIZE(addn
)
1660 IWMMXT_OP_ENV_SIZE(subu
)
1661 IWMMXT_OP_ENV_SIZE(addu
)
1662 IWMMXT_OP_ENV_SIZE(subs
)
1663 IWMMXT_OP_ENV_SIZE(adds
)
1665 IWMMXT_OP_ENV(avgb0
)
1666 IWMMXT_OP_ENV(avgb1
)
1667 IWMMXT_OP_ENV(avgw0
)
1668 IWMMXT_OP_ENV(avgw1
)
1670 IWMMXT_OP_ENV(packuw
)
1671 IWMMXT_OP_ENV(packul
)
1672 IWMMXT_OP_ENV(packuq
)
1673 IWMMXT_OP_ENV(packsw
)
1674 IWMMXT_OP_ENV(packsl
)
1675 IWMMXT_OP_ENV(packsq
)
1677 static void gen_op_iwmmxt_set_mup(void)
1680 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1681 tcg_gen_ori_i32(tmp
, tmp
, 2);
1682 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1685 static void gen_op_iwmmxt_set_cup(void)
1688 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1689 tcg_gen_ori_i32(tmp
, tmp
, 1);
1690 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1693 static void gen_op_iwmmxt_setpsr_nz(void)
1695 TCGv_i32 tmp
= tcg_temp_new_i32();
1696 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1697 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1700 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1702 iwmmxt_load_reg(cpu_V1
, rn
);
1703 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1704 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1707 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1714 rd
= (insn
>> 16) & 0xf;
1715 tmp
= load_reg(s
, rd
);
1717 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1718 if (insn
& (1 << 24)) {
1720 if (insn
& (1 << 23))
1721 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1723 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1724 tcg_gen_mov_i32(dest
, tmp
);
1725 if (insn
& (1 << 21))
1726 store_reg(s
, rd
, tmp
);
1728 tcg_temp_free_i32(tmp
);
1729 } else if (insn
& (1 << 21)) {
1731 tcg_gen_mov_i32(dest
, tmp
);
1732 if (insn
& (1 << 23))
1733 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1735 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1736 store_reg(s
, rd
, tmp
);
1737 } else if (!(insn
& (1 << 23)))
1742 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1744 int rd
= (insn
>> 0) & 0xf;
1747 if (insn
& (1 << 8)) {
1748 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1751 tmp
= iwmmxt_load_creg(rd
);
1754 tmp
= tcg_temp_new_i32();
1755 iwmmxt_load_reg(cpu_V0
, rd
);
1756 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1758 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1759 tcg_gen_mov_i32(dest
, tmp
);
1760 tcg_temp_free_i32(tmp
);
1764 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1765 (ie. an undefined instruction). */
1766 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1769 int rdhi
, rdlo
, rd0
, rd1
, i
;
1771 TCGv_i32 tmp
, tmp2
, tmp3
;
1773 if ((insn
& 0x0e000e00) == 0x0c000000) {
1774 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1776 rdlo
= (insn
>> 12) & 0xf;
1777 rdhi
= (insn
>> 16) & 0xf;
1778 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1779 iwmmxt_load_reg(cpu_V0
, wrd
);
1780 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1781 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1782 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1783 } else { /* TMCRR */
1784 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1785 iwmmxt_store_reg(cpu_V0
, wrd
);
1786 gen_op_iwmmxt_set_mup();
1791 wrd
= (insn
>> 12) & 0xf;
1792 addr
= tcg_temp_new_i32();
1793 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1794 tcg_temp_free_i32(addr
);
1797 if (insn
& ARM_CP_RW_BIT
) {
1798 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1799 tmp
= tcg_temp_new_i32();
1800 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1801 iwmmxt_store_creg(wrd
, tmp
);
1804 if (insn
& (1 << 8)) {
1805 if (insn
& (1 << 22)) { /* WLDRD */
1806 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1808 } else { /* WLDRW wRd */
1809 tmp
= tcg_temp_new_i32();
1810 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1813 tmp
= tcg_temp_new_i32();
1814 if (insn
& (1 << 22)) { /* WLDRH */
1815 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1816 } else { /* WLDRB */
1817 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1821 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1822 tcg_temp_free_i32(tmp
);
1824 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1827 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1828 tmp
= iwmmxt_load_creg(wrd
);
1829 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1831 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1832 tmp
= tcg_temp_new_i32();
1833 if (insn
& (1 << 8)) {
1834 if (insn
& (1 << 22)) { /* WSTRD */
1835 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1836 } else { /* WSTRW wRd */
1837 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1838 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1841 if (insn
& (1 << 22)) { /* WSTRH */
1842 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1843 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1844 } else { /* WSTRB */
1845 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1846 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1850 tcg_temp_free_i32(tmp
);
1852 tcg_temp_free_i32(addr
);
1856 if ((insn
& 0x0f000000) != 0x0e000000)
1859 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1860 case 0x000: /* WOR */
1861 wrd
= (insn
>> 12) & 0xf;
1862 rd0
= (insn
>> 0) & 0xf;
1863 rd1
= (insn
>> 16) & 0xf;
1864 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1865 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1866 gen_op_iwmmxt_setpsr_nz();
1867 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1868 gen_op_iwmmxt_set_mup();
1869 gen_op_iwmmxt_set_cup();
1871 case 0x011: /* TMCR */
1874 rd
= (insn
>> 12) & 0xf;
1875 wrd
= (insn
>> 16) & 0xf;
1877 case ARM_IWMMXT_wCID
:
1878 case ARM_IWMMXT_wCASF
:
1880 case ARM_IWMMXT_wCon
:
1881 gen_op_iwmmxt_set_cup();
1883 case ARM_IWMMXT_wCSSF
:
1884 tmp
= iwmmxt_load_creg(wrd
);
1885 tmp2
= load_reg(s
, rd
);
1886 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1887 tcg_temp_free_i32(tmp2
);
1888 iwmmxt_store_creg(wrd
, tmp
);
1890 case ARM_IWMMXT_wCGR0
:
1891 case ARM_IWMMXT_wCGR1
:
1892 case ARM_IWMMXT_wCGR2
:
1893 case ARM_IWMMXT_wCGR3
:
1894 gen_op_iwmmxt_set_cup();
1895 tmp
= load_reg(s
, rd
);
1896 iwmmxt_store_creg(wrd
, tmp
);
1902 case 0x100: /* WXOR */
1903 wrd
= (insn
>> 12) & 0xf;
1904 rd0
= (insn
>> 0) & 0xf;
1905 rd1
= (insn
>> 16) & 0xf;
1906 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1907 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1908 gen_op_iwmmxt_setpsr_nz();
1909 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1910 gen_op_iwmmxt_set_mup();
1911 gen_op_iwmmxt_set_cup();
1913 case 0x111: /* TMRC */
1916 rd
= (insn
>> 12) & 0xf;
1917 wrd
= (insn
>> 16) & 0xf;
1918 tmp
= iwmmxt_load_creg(wrd
);
1919 store_reg(s
, rd
, tmp
);
1921 case 0x300: /* WANDN */
1922 wrd
= (insn
>> 12) & 0xf;
1923 rd0
= (insn
>> 0) & 0xf;
1924 rd1
= (insn
>> 16) & 0xf;
1925 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1926 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1927 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1928 gen_op_iwmmxt_setpsr_nz();
1929 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1930 gen_op_iwmmxt_set_mup();
1931 gen_op_iwmmxt_set_cup();
1933 case 0x200: /* WAND */
1934 wrd
= (insn
>> 12) & 0xf;
1935 rd0
= (insn
>> 0) & 0xf;
1936 rd1
= (insn
>> 16) & 0xf;
1937 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1938 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1939 gen_op_iwmmxt_setpsr_nz();
1940 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1941 gen_op_iwmmxt_set_mup();
1942 gen_op_iwmmxt_set_cup();
1944 case 0x810: case 0xa10: /* WMADD */
1945 wrd
= (insn
>> 12) & 0xf;
1946 rd0
= (insn
>> 0) & 0xf;
1947 rd1
= (insn
>> 16) & 0xf;
1948 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1949 if (insn
& (1 << 21))
1950 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1952 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1953 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1954 gen_op_iwmmxt_set_mup();
1956 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1957 wrd
= (insn
>> 12) & 0xf;
1958 rd0
= (insn
>> 16) & 0xf;
1959 rd1
= (insn
>> 0) & 0xf;
1960 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1961 switch ((insn
>> 22) & 3) {
1963 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1966 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1969 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1974 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1975 gen_op_iwmmxt_set_mup();
1976 gen_op_iwmmxt_set_cup();
1978 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1979 wrd
= (insn
>> 12) & 0xf;
1980 rd0
= (insn
>> 16) & 0xf;
1981 rd1
= (insn
>> 0) & 0xf;
1982 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1983 switch ((insn
>> 22) & 3) {
1985 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1988 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1991 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1996 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1997 gen_op_iwmmxt_set_mup();
1998 gen_op_iwmmxt_set_cup();
2000 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2001 wrd
= (insn
>> 12) & 0xf;
2002 rd0
= (insn
>> 16) & 0xf;
2003 rd1
= (insn
>> 0) & 0xf;
2004 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2005 if (insn
& (1 << 22))
2006 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2008 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2009 if (!(insn
& (1 << 20)))
2010 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2011 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2012 gen_op_iwmmxt_set_mup();
2014 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2015 wrd
= (insn
>> 12) & 0xf;
2016 rd0
= (insn
>> 16) & 0xf;
2017 rd1
= (insn
>> 0) & 0xf;
2018 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2019 if (insn
& (1 << 21)) {
2020 if (insn
& (1 << 20))
2021 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2023 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2025 if (insn
& (1 << 20))
2026 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2028 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2030 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2031 gen_op_iwmmxt_set_mup();
2033 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2034 wrd
= (insn
>> 12) & 0xf;
2035 rd0
= (insn
>> 16) & 0xf;
2036 rd1
= (insn
>> 0) & 0xf;
2037 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2038 if (insn
& (1 << 21))
2039 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2041 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2042 if (!(insn
& (1 << 20))) {
2043 iwmmxt_load_reg(cpu_V1
, wrd
);
2044 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2046 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2047 gen_op_iwmmxt_set_mup();
2049 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2050 wrd
= (insn
>> 12) & 0xf;
2051 rd0
= (insn
>> 16) & 0xf;
2052 rd1
= (insn
>> 0) & 0xf;
2053 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2054 switch ((insn
>> 22) & 3) {
2056 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2059 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2062 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2067 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2068 gen_op_iwmmxt_set_mup();
2069 gen_op_iwmmxt_set_cup();
2071 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2072 wrd
= (insn
>> 12) & 0xf;
2073 rd0
= (insn
>> 16) & 0xf;
2074 rd1
= (insn
>> 0) & 0xf;
2075 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2076 if (insn
& (1 << 22)) {
2077 if (insn
& (1 << 20))
2078 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2080 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2082 if (insn
& (1 << 20))
2083 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2085 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2087 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2088 gen_op_iwmmxt_set_mup();
2089 gen_op_iwmmxt_set_cup();
2091 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2092 wrd
= (insn
>> 12) & 0xf;
2093 rd0
= (insn
>> 16) & 0xf;
2094 rd1
= (insn
>> 0) & 0xf;
2095 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2096 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2097 tcg_gen_andi_i32(tmp
, tmp
, 7);
2098 iwmmxt_load_reg(cpu_V1
, rd1
);
2099 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2100 tcg_temp_free_i32(tmp
);
2101 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2102 gen_op_iwmmxt_set_mup();
2104 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2105 if (((insn
>> 6) & 3) == 3)
2107 rd
= (insn
>> 12) & 0xf;
2108 wrd
= (insn
>> 16) & 0xf;
2109 tmp
= load_reg(s
, rd
);
2110 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2111 switch ((insn
>> 6) & 3) {
2113 tmp2
= tcg_const_i32(0xff);
2114 tmp3
= tcg_const_i32((insn
& 7) << 3);
2117 tmp2
= tcg_const_i32(0xffff);
2118 tmp3
= tcg_const_i32((insn
& 3) << 4);
2121 tmp2
= tcg_const_i32(0xffffffff);
2122 tmp3
= tcg_const_i32((insn
& 1) << 5);
2125 TCGV_UNUSED_I32(tmp2
);
2126 TCGV_UNUSED_I32(tmp3
);
2128 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2129 tcg_temp_free_i32(tmp3
);
2130 tcg_temp_free_i32(tmp2
);
2131 tcg_temp_free_i32(tmp
);
2132 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2133 gen_op_iwmmxt_set_mup();
2135 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2136 rd
= (insn
>> 12) & 0xf;
2137 wrd
= (insn
>> 16) & 0xf;
2138 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2140 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2141 tmp
= tcg_temp_new_i32();
2142 switch ((insn
>> 22) & 3) {
2144 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2145 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2147 tcg_gen_ext8s_i32(tmp
, tmp
);
2149 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2153 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2154 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2156 tcg_gen_ext16s_i32(tmp
, tmp
);
2158 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2162 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2163 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2166 store_reg(s
, rd
, tmp
);
2168 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2169 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2171 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2172 switch ((insn
>> 22) & 3) {
2174 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2177 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2180 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2183 tcg_gen_shli_i32(tmp
, tmp
, 28);
2185 tcg_temp_free_i32(tmp
);
2187 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2188 if (((insn
>> 6) & 3) == 3)
2190 rd
= (insn
>> 12) & 0xf;
2191 wrd
= (insn
>> 16) & 0xf;
2192 tmp
= load_reg(s
, rd
);
2193 switch ((insn
>> 6) & 3) {
2195 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2198 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2201 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2204 tcg_temp_free_i32(tmp
);
2205 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2206 gen_op_iwmmxt_set_mup();
2208 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2209 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2211 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2212 tmp2
= tcg_temp_new_i32();
2213 tcg_gen_mov_i32(tmp2
, tmp
);
2214 switch ((insn
>> 22) & 3) {
2216 for (i
= 0; i
< 7; i
++) {
2217 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2218 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2222 for (i
= 0; i
< 3; i
++) {
2223 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2224 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2228 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2229 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2233 tcg_temp_free_i32(tmp2
);
2234 tcg_temp_free_i32(tmp
);
2236 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2237 wrd
= (insn
>> 12) & 0xf;
2238 rd0
= (insn
>> 16) & 0xf;
2239 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2240 switch ((insn
>> 22) & 3) {
2242 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2245 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2248 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2253 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2254 gen_op_iwmmxt_set_mup();
2256 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2257 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2259 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2260 tmp2
= tcg_temp_new_i32();
2261 tcg_gen_mov_i32(tmp2
, tmp
);
2262 switch ((insn
>> 22) & 3) {
2264 for (i
= 0; i
< 7; i
++) {
2265 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2266 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2270 for (i
= 0; i
< 3; i
++) {
2271 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2272 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2276 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2277 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2281 tcg_temp_free_i32(tmp2
);
2282 tcg_temp_free_i32(tmp
);
2284 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2285 rd
= (insn
>> 12) & 0xf;
2286 rd0
= (insn
>> 16) & 0xf;
2287 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2289 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2290 tmp
= tcg_temp_new_i32();
2291 switch ((insn
>> 22) & 3) {
2293 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2296 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2299 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2302 store_reg(s
, rd
, tmp
);
2304 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2305 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2306 wrd
= (insn
>> 12) & 0xf;
2307 rd0
= (insn
>> 16) & 0xf;
2308 rd1
= (insn
>> 0) & 0xf;
2309 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2310 switch ((insn
>> 22) & 3) {
2312 if (insn
& (1 << 21))
2313 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2315 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2318 if (insn
& (1 << 21))
2319 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2321 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2324 if (insn
& (1 << 21))
2325 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2327 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2332 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2333 gen_op_iwmmxt_set_mup();
2334 gen_op_iwmmxt_set_cup();
2336 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2337 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2338 wrd
= (insn
>> 12) & 0xf;
2339 rd0
= (insn
>> 16) & 0xf;
2340 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2341 switch ((insn
>> 22) & 3) {
2343 if (insn
& (1 << 21))
2344 gen_op_iwmmxt_unpacklsb_M0();
2346 gen_op_iwmmxt_unpacklub_M0();
2349 if (insn
& (1 << 21))
2350 gen_op_iwmmxt_unpacklsw_M0();
2352 gen_op_iwmmxt_unpackluw_M0();
2355 if (insn
& (1 << 21))
2356 gen_op_iwmmxt_unpacklsl_M0();
2358 gen_op_iwmmxt_unpacklul_M0();
2363 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2364 gen_op_iwmmxt_set_mup();
2365 gen_op_iwmmxt_set_cup();
2367 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2368 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2369 wrd
= (insn
>> 12) & 0xf;
2370 rd0
= (insn
>> 16) & 0xf;
2371 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2372 switch ((insn
>> 22) & 3) {
2374 if (insn
& (1 << 21))
2375 gen_op_iwmmxt_unpackhsb_M0();
2377 gen_op_iwmmxt_unpackhub_M0();
2380 if (insn
& (1 << 21))
2381 gen_op_iwmmxt_unpackhsw_M0();
2383 gen_op_iwmmxt_unpackhuw_M0();
2386 if (insn
& (1 << 21))
2387 gen_op_iwmmxt_unpackhsl_M0();
2389 gen_op_iwmmxt_unpackhul_M0();
2394 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2395 gen_op_iwmmxt_set_mup();
2396 gen_op_iwmmxt_set_cup();
2398 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2399 case 0x214: case 0x614: case 0xa14: case 0xe14:
2400 if (((insn
>> 22) & 3) == 0)
2402 wrd
= (insn
>> 12) & 0xf;
2403 rd0
= (insn
>> 16) & 0xf;
2404 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2405 tmp
= tcg_temp_new_i32();
2406 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2407 tcg_temp_free_i32(tmp
);
2410 switch ((insn
>> 22) & 3) {
2412 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2415 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2418 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2421 tcg_temp_free_i32(tmp
);
2422 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2423 gen_op_iwmmxt_set_mup();
2424 gen_op_iwmmxt_set_cup();
2426 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2427 case 0x014: case 0x414: case 0x814: case 0xc14:
2428 if (((insn
>> 22) & 3) == 0)
2430 wrd
= (insn
>> 12) & 0xf;
2431 rd0
= (insn
>> 16) & 0xf;
2432 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2433 tmp
= tcg_temp_new_i32();
2434 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2435 tcg_temp_free_i32(tmp
);
2438 switch ((insn
>> 22) & 3) {
2440 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2443 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2446 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2449 tcg_temp_free_i32(tmp
);
2450 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2451 gen_op_iwmmxt_set_mup();
2452 gen_op_iwmmxt_set_cup();
2454 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2455 case 0x114: case 0x514: case 0x914: case 0xd14:
2456 if (((insn
>> 22) & 3) == 0)
2458 wrd
= (insn
>> 12) & 0xf;
2459 rd0
= (insn
>> 16) & 0xf;
2460 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2461 tmp
= tcg_temp_new_i32();
2462 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2463 tcg_temp_free_i32(tmp
);
2466 switch ((insn
>> 22) & 3) {
2468 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2471 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2474 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2477 tcg_temp_free_i32(tmp
);
2478 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2479 gen_op_iwmmxt_set_mup();
2480 gen_op_iwmmxt_set_cup();
2482 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2483 case 0x314: case 0x714: case 0xb14: case 0xf14:
2484 if (((insn
>> 22) & 3) == 0)
2486 wrd
= (insn
>> 12) & 0xf;
2487 rd0
= (insn
>> 16) & 0xf;
2488 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2489 tmp
= tcg_temp_new_i32();
2490 switch ((insn
>> 22) & 3) {
2492 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2493 tcg_temp_free_i32(tmp
);
2496 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2499 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2500 tcg_temp_free_i32(tmp
);
2503 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2506 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2507 tcg_temp_free_i32(tmp
);
2510 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2513 tcg_temp_free_i32(tmp
);
2514 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2515 gen_op_iwmmxt_set_mup();
2516 gen_op_iwmmxt_set_cup();
2518 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2519 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2520 wrd
= (insn
>> 12) & 0xf;
2521 rd0
= (insn
>> 16) & 0xf;
2522 rd1
= (insn
>> 0) & 0xf;
2523 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2524 switch ((insn
>> 22) & 3) {
2526 if (insn
& (1 << 21))
2527 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2529 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2532 if (insn
& (1 << 21))
2533 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2535 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2538 if (insn
& (1 << 21))
2539 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2541 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2546 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2547 gen_op_iwmmxt_set_mup();
2549 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2550 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2551 wrd
= (insn
>> 12) & 0xf;
2552 rd0
= (insn
>> 16) & 0xf;
2553 rd1
= (insn
>> 0) & 0xf;
2554 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2555 switch ((insn
>> 22) & 3) {
2557 if (insn
& (1 << 21))
2558 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2560 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2563 if (insn
& (1 << 21))
2564 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2566 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2569 if (insn
& (1 << 21))
2570 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2572 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2577 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2578 gen_op_iwmmxt_set_mup();
2580 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2581 case 0x402: case 0x502: case 0x602: case 0x702:
2582 wrd
= (insn
>> 12) & 0xf;
2583 rd0
= (insn
>> 16) & 0xf;
2584 rd1
= (insn
>> 0) & 0xf;
2585 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2586 tmp
= tcg_const_i32((insn
>> 20) & 3);
2587 iwmmxt_load_reg(cpu_V1
, rd1
);
2588 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2589 tcg_temp_free_i32(tmp
);
2590 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2591 gen_op_iwmmxt_set_mup();
2593 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2594 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2595 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2596 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2597 wrd
= (insn
>> 12) & 0xf;
2598 rd0
= (insn
>> 16) & 0xf;
2599 rd1
= (insn
>> 0) & 0xf;
2600 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2601 switch ((insn
>> 20) & 0xf) {
2603 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2606 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2609 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2612 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2615 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2618 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2621 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2624 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2627 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2632 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2633 gen_op_iwmmxt_set_mup();
2634 gen_op_iwmmxt_set_cup();
2636 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2637 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2638 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2639 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2640 wrd
= (insn
>> 12) & 0xf;
2641 rd0
= (insn
>> 16) & 0xf;
2642 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2643 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2644 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2645 tcg_temp_free_i32(tmp
);
2646 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2647 gen_op_iwmmxt_set_mup();
2648 gen_op_iwmmxt_set_cup();
2650 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2651 case 0x418: case 0x518: case 0x618: case 0x718:
2652 case 0x818: case 0x918: case 0xa18: case 0xb18:
2653 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2654 wrd
= (insn
>> 12) & 0xf;
2655 rd0
= (insn
>> 16) & 0xf;
2656 rd1
= (insn
>> 0) & 0xf;
2657 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2658 switch ((insn
>> 20) & 0xf) {
2660 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2663 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2666 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2669 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2672 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2675 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2678 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2681 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2684 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2689 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2690 gen_op_iwmmxt_set_mup();
2691 gen_op_iwmmxt_set_cup();
2693 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2694 case 0x408: case 0x508: case 0x608: case 0x708:
2695 case 0x808: case 0x908: case 0xa08: case 0xb08:
2696 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2697 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2699 wrd
= (insn
>> 12) & 0xf;
2700 rd0
= (insn
>> 16) & 0xf;
2701 rd1
= (insn
>> 0) & 0xf;
2702 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2703 switch ((insn
>> 22) & 3) {
2705 if (insn
& (1 << 21))
2706 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2708 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2711 if (insn
& (1 << 21))
2712 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2714 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2717 if (insn
& (1 << 21))
2718 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2720 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2723 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2724 gen_op_iwmmxt_set_mup();
2725 gen_op_iwmmxt_set_cup();
2727 case 0x201: case 0x203: case 0x205: case 0x207:
2728 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2729 case 0x211: case 0x213: case 0x215: case 0x217:
2730 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2731 wrd
= (insn
>> 5) & 0xf;
2732 rd0
= (insn
>> 12) & 0xf;
2733 rd1
= (insn
>> 0) & 0xf;
2734 if (rd0
== 0xf || rd1
== 0xf)
2736 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2737 tmp
= load_reg(s
, rd0
);
2738 tmp2
= load_reg(s
, rd1
);
2739 switch ((insn
>> 16) & 0xf) {
2740 case 0x0: /* TMIA */
2741 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2743 case 0x8: /* TMIAPH */
2744 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2746 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2747 if (insn
& (1 << 16))
2748 tcg_gen_shri_i32(tmp
, tmp
, 16);
2749 if (insn
& (1 << 17))
2750 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2751 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2754 tcg_temp_free_i32(tmp2
);
2755 tcg_temp_free_i32(tmp
);
2758 tcg_temp_free_i32(tmp2
);
2759 tcg_temp_free_i32(tmp
);
2760 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2761 gen_op_iwmmxt_set_mup();
2770 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2771 (ie. an undefined instruction). */
2772 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2774 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2777 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2778 /* Multiply with Internal Accumulate Format */
2779 rd0
= (insn
>> 12) & 0xf;
2781 acc
= (insn
>> 5) & 7;
2786 tmp
= load_reg(s
, rd0
);
2787 tmp2
= load_reg(s
, rd1
);
2788 switch ((insn
>> 16) & 0xf) {
2790 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2792 case 0x8: /* MIAPH */
2793 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2795 case 0xc: /* MIABB */
2796 case 0xd: /* MIABT */
2797 case 0xe: /* MIATB */
2798 case 0xf: /* MIATT */
2799 if (insn
& (1 << 16))
2800 tcg_gen_shri_i32(tmp
, tmp
, 16);
2801 if (insn
& (1 << 17))
2802 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2803 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2808 tcg_temp_free_i32(tmp2
);
2809 tcg_temp_free_i32(tmp
);
2811 gen_op_iwmmxt_movq_wRn_M0(acc
);
2815 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2816 /* Internal Accumulator Access Format */
2817 rdhi
= (insn
>> 16) & 0xf;
2818 rdlo
= (insn
>> 12) & 0xf;
2824 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2825 iwmmxt_load_reg(cpu_V0
, acc
);
2826 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2827 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2828 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2829 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2831 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2832 iwmmxt_store_reg(cpu_V0
, acc
);
2840 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2841 #define VFP_SREG(insn, bigbit, smallbit) \
2842 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2843 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2844 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2845 reg = (((insn) >> (bigbit)) & 0x0f) \
2846 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2848 if (insn & (1 << (smallbit))) \
2850 reg = ((insn) >> (bigbit)) & 0x0f; \
2853 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2854 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2855 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2856 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2857 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2858 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2860 /* Move between integer and VFP cores. */
2861 static TCGv_i32
gen_vfp_mrs(void)
2863 TCGv_i32 tmp
= tcg_temp_new_i32();
2864 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2868 static void gen_vfp_msr(TCGv_i32 tmp
)
2870 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2871 tcg_temp_free_i32(tmp
);
2874 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2876 TCGv_i32 tmp
= tcg_temp_new_i32();
2878 tcg_gen_shri_i32(var
, var
, shift
);
2879 tcg_gen_ext8u_i32(var
, var
);
2880 tcg_gen_shli_i32(tmp
, var
, 8);
2881 tcg_gen_or_i32(var
, var
, tmp
);
2882 tcg_gen_shli_i32(tmp
, var
, 16);
2883 tcg_gen_or_i32(var
, var
, tmp
);
2884 tcg_temp_free_i32(tmp
);
2887 static void gen_neon_dup_low16(TCGv_i32 var
)
2889 TCGv_i32 tmp
= tcg_temp_new_i32();
2890 tcg_gen_ext16u_i32(var
, var
);
2891 tcg_gen_shli_i32(tmp
, var
, 16);
2892 tcg_gen_or_i32(var
, var
, tmp
);
2893 tcg_temp_free_i32(tmp
);
2896 static void gen_neon_dup_high16(TCGv_i32 var
)
2898 TCGv_i32 tmp
= tcg_temp_new_i32();
2899 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2900 tcg_gen_shri_i32(tmp
, var
, 16);
2901 tcg_gen_or_i32(var
, var
, tmp
);
2902 tcg_temp_free_i32(tmp
);
2905 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2907 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2908 TCGv_i32 tmp
= tcg_temp_new_i32();
2911 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2912 gen_neon_dup_u8(tmp
, 0);
2915 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2916 gen_neon_dup_low16(tmp
);
2919 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2921 default: /* Avoid compiler warnings. */
2927 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2930 uint32_t cc
= extract32(insn
, 20, 2);
2933 TCGv_i64 frn
, frm
, dest
;
2934 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2936 zero
= tcg_const_i64(0);
2938 frn
= tcg_temp_new_i64();
2939 frm
= tcg_temp_new_i64();
2940 dest
= tcg_temp_new_i64();
2942 zf
= tcg_temp_new_i64();
2943 nf
= tcg_temp_new_i64();
2944 vf
= tcg_temp_new_i64();
2946 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2947 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2948 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2950 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2951 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2954 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2958 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2961 case 2: /* ge: N == V -> N ^ V == 0 */
2962 tmp
= tcg_temp_new_i64();
2963 tcg_gen_xor_i64(tmp
, vf
, nf
);
2964 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2966 tcg_temp_free_i64(tmp
);
2968 case 3: /* gt: !Z && N == V */
2969 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2971 tmp
= tcg_temp_new_i64();
2972 tcg_gen_xor_i64(tmp
, vf
, nf
);
2973 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2975 tcg_temp_free_i64(tmp
);
2978 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2979 tcg_temp_free_i64(frn
);
2980 tcg_temp_free_i64(frm
);
2981 tcg_temp_free_i64(dest
);
2983 tcg_temp_free_i64(zf
);
2984 tcg_temp_free_i64(nf
);
2985 tcg_temp_free_i64(vf
);
2987 tcg_temp_free_i64(zero
);
2989 TCGv_i32 frn
, frm
, dest
;
2992 zero
= tcg_const_i32(0);
2994 frn
= tcg_temp_new_i32();
2995 frm
= tcg_temp_new_i32();
2996 dest
= tcg_temp_new_i32();
2997 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2998 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3001 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
3005 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
3008 case 2: /* ge: N == V -> N ^ V == 0 */
3009 tmp
= tcg_temp_new_i32();
3010 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3011 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3013 tcg_temp_free_i32(tmp
);
3015 case 3: /* gt: !Z && N == V */
3016 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
3018 tmp
= tcg_temp_new_i32();
3019 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
3020 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
3022 tcg_temp_free_i32(tmp
);
3025 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3026 tcg_temp_free_i32(frn
);
3027 tcg_temp_free_i32(frm
);
3028 tcg_temp_free_i32(dest
);
3030 tcg_temp_free_i32(zero
);
3036 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
3037 uint32_t rm
, uint32_t dp
)
3039 uint32_t vmin
= extract32(insn
, 6, 1);
3040 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3043 TCGv_i64 frn
, frm
, dest
;
3045 frn
= tcg_temp_new_i64();
3046 frm
= tcg_temp_new_i64();
3047 dest
= tcg_temp_new_i64();
3049 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3050 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3052 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
3054 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
3056 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3057 tcg_temp_free_i64(frn
);
3058 tcg_temp_free_i64(frm
);
3059 tcg_temp_free_i64(dest
);
3061 TCGv_i32 frn
, frm
, dest
;
3063 frn
= tcg_temp_new_i32();
3064 frm
= tcg_temp_new_i32();
3065 dest
= tcg_temp_new_i32();
3067 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
3068 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
3070 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
3072 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
3074 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
3075 tcg_temp_free_i32(frn
);
3076 tcg_temp_free_i32(frm
);
3077 tcg_temp_free_i32(dest
);
3080 tcg_temp_free_ptr(fpst
);
3084 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3087 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3090 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3091 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3096 tcg_op
= tcg_temp_new_i64();
3097 tcg_res
= tcg_temp_new_i64();
3098 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3099 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
3100 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3101 tcg_temp_free_i64(tcg_op
);
3102 tcg_temp_free_i64(tcg_res
);
3106 tcg_op
= tcg_temp_new_i32();
3107 tcg_res
= tcg_temp_new_i32();
3108 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3109 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
3110 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3111 tcg_temp_free_i32(tcg_op
);
3112 tcg_temp_free_i32(tcg_res
);
3115 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3116 tcg_temp_free_i32(tcg_rmode
);
3118 tcg_temp_free_ptr(fpst
);
3122 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3125 bool is_signed
= extract32(insn
, 7, 1);
3126 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3127 TCGv_i32 tcg_rmode
, tcg_shift
;
3129 tcg_shift
= tcg_const_i32(0);
3131 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3132 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3135 TCGv_i64 tcg_double
, tcg_res
;
3137 /* Rd is encoded as a single precision register even when the source
3138 * is double precision.
3140 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3141 tcg_double
= tcg_temp_new_i64();
3142 tcg_res
= tcg_temp_new_i64();
3143 tcg_tmp
= tcg_temp_new_i32();
3144 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3146 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3148 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3150 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3151 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3152 tcg_temp_free_i32(tcg_tmp
);
3153 tcg_temp_free_i64(tcg_res
);
3154 tcg_temp_free_i64(tcg_double
);
3156 TCGv_i32 tcg_single
, tcg_res
;
3157 tcg_single
= tcg_temp_new_i32();
3158 tcg_res
= tcg_temp_new_i32();
3159 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3161 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3163 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3165 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3166 tcg_temp_free_i32(tcg_res
);
3167 tcg_temp_free_i32(tcg_single
);
3170 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3171 tcg_temp_free_i32(tcg_rmode
);
3173 tcg_temp_free_i32(tcg_shift
);
3175 tcg_temp_free_ptr(fpst
);
3180 /* Table for converting the most common AArch32 encoding of
3181 * rounding mode to arm_fprounding order (which matches the
3182 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3184 static const uint8_t fp_decode_rm
[] = {
3191 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3193 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3195 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3200 VFP_DREG_D(rd
, insn
);
3201 VFP_DREG_N(rn
, insn
);
3202 VFP_DREG_M(rm
, insn
);
3204 rd
= VFP_SREG_D(insn
);
3205 rn
= VFP_SREG_N(insn
);
3206 rm
= VFP_SREG_M(insn
);
3209 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3210 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3211 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3212 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3213 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3214 /* VRINTA, VRINTN, VRINTP, VRINTM */
3215 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3216 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3217 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3218 /* VCVTA, VCVTN, VCVTP, VCVTM */
3219 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3220 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3225 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3226 (ie. an undefined instruction). */
3227 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3229 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3235 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3239 /* FIXME: this access check should not take precedence over UNDEF
3240 * for invalid encodings; we will generate incorrect syndrome information
3241 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3243 if (s
->fp_excp_el
) {
3244 gen_exception_insn(s
, 4, EXCP_UDEF
,
3245 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3249 if (!s
->vfp_enabled
) {
3250 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3251 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3253 rn
= (insn
>> 16) & 0xf;
3254 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3255 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3260 if (extract32(insn
, 28, 4) == 0xf) {
3261 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3262 * only used in v8 and above.
3264 return disas_vfp_v8_insn(s
, insn
);
3267 dp
= ((insn
& 0xf00) == 0xb00);
3268 switch ((insn
>> 24) & 0xf) {
3270 if (insn
& (1 << 4)) {
3271 /* single register transfer */
3272 rd
= (insn
>> 12) & 0xf;
3277 VFP_DREG_N(rn
, insn
);
3280 if (insn
& 0x00c00060
3281 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3285 pass
= (insn
>> 21) & 1;
3286 if (insn
& (1 << 22)) {
3288 offset
= ((insn
>> 5) & 3) * 8;
3289 } else if (insn
& (1 << 5)) {
3291 offset
= (insn
& (1 << 6)) ? 16 : 0;
3296 if (insn
& ARM_CP_RW_BIT
) {
3298 tmp
= neon_load_reg(rn
, pass
);
3302 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3303 if (insn
& (1 << 23))
3309 if (insn
& (1 << 23)) {
3311 tcg_gen_shri_i32(tmp
, tmp
, 16);
3317 tcg_gen_sari_i32(tmp
, tmp
, 16);
3326 store_reg(s
, rd
, tmp
);
3329 tmp
= load_reg(s
, rd
);
3330 if (insn
& (1 << 23)) {
3333 gen_neon_dup_u8(tmp
, 0);
3334 } else if (size
== 1) {
3335 gen_neon_dup_low16(tmp
);
3337 for (n
= 0; n
<= pass
* 2; n
++) {
3338 tmp2
= tcg_temp_new_i32();
3339 tcg_gen_mov_i32(tmp2
, tmp
);
3340 neon_store_reg(rn
, n
, tmp2
);
3342 neon_store_reg(rn
, n
, tmp
);
3347 tmp2
= neon_load_reg(rn
, pass
);
3348 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3349 tcg_temp_free_i32(tmp2
);
3352 tmp2
= neon_load_reg(rn
, pass
);
3353 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3354 tcg_temp_free_i32(tmp2
);
3359 neon_store_reg(rn
, pass
, tmp
);
3363 if ((insn
& 0x6f) != 0x00)
3365 rn
= VFP_SREG_N(insn
);
3366 if (insn
& ARM_CP_RW_BIT
) {
3368 if (insn
& (1 << 21)) {
3369 /* system register */
3374 /* VFP2 allows access to FSID from userspace.
3375 VFP3 restricts all id registers to privileged
3378 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3381 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3386 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3388 case ARM_VFP_FPINST
:
3389 case ARM_VFP_FPINST2
:
3390 /* Not present in VFP3. */
3392 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3395 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3399 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3400 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3402 tmp
= tcg_temp_new_i32();
3403 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3407 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3414 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3417 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3423 gen_mov_F0_vreg(0, rn
);
3424 tmp
= gen_vfp_mrs();
3427 /* Set the 4 flag bits in the CPSR. */
3429 tcg_temp_free_i32(tmp
);
3431 store_reg(s
, rd
, tmp
);
3435 if (insn
& (1 << 21)) {
3437 /* system register */
3442 /* Writes are ignored. */
3445 tmp
= load_reg(s
, rd
);
3446 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3447 tcg_temp_free_i32(tmp
);
3453 /* TODO: VFP subarchitecture support.
3454 * For now, keep the EN bit only */
3455 tmp
= load_reg(s
, rd
);
3456 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3457 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3460 case ARM_VFP_FPINST
:
3461 case ARM_VFP_FPINST2
:
3465 tmp
= load_reg(s
, rd
);
3466 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3472 tmp
= load_reg(s
, rd
);
3474 gen_mov_vreg_F0(0, rn
);
3479 /* data processing */
3480 /* The opcode is in bits 23, 21, 20 and 6. */
3481 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3485 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3487 /* rn is register number */
3488 VFP_DREG_N(rn
, insn
);
3491 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3492 ((rn
& 0x1e) == 0x6))) {
3493 /* Integer or single/half precision destination. */
3494 rd
= VFP_SREG_D(insn
);
3496 VFP_DREG_D(rd
, insn
);
3499 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3500 ((rn
& 0x1e) == 0x4))) {
3501 /* VCVT from int or half precision is always from S reg
3502 * regardless of dp bit. VCVT with immediate frac_bits
3503 * has same format as SREG_M.
3505 rm
= VFP_SREG_M(insn
);
3507 VFP_DREG_M(rm
, insn
);
3510 rn
= VFP_SREG_N(insn
);
3511 if (op
== 15 && rn
== 15) {
3512 /* Double precision destination. */
3513 VFP_DREG_D(rd
, insn
);
3515 rd
= VFP_SREG_D(insn
);
3517 /* NB that we implicitly rely on the encoding for the frac_bits
3518 * in VCVT of fixed to float being the same as that of an SREG_M
3520 rm
= VFP_SREG_M(insn
);
3523 veclen
= s
->vec_len
;
3524 if (op
== 15 && rn
> 3)
3527 /* Shut up compiler warnings. */
3538 /* Figure out what type of vector operation this is. */
3539 if ((rd
& bank_mask
) == 0) {
3544 delta_d
= (s
->vec_stride
>> 1) + 1;
3546 delta_d
= s
->vec_stride
+ 1;
3548 if ((rm
& bank_mask
) == 0) {
3549 /* mixed scalar/vector */
3558 /* Load the initial operands. */
3563 /* Integer source */
3564 gen_mov_F0_vreg(0, rm
);
3569 gen_mov_F0_vreg(dp
, rd
);
3570 gen_mov_F1_vreg(dp
, rm
);
3574 /* Compare with zero */
3575 gen_mov_F0_vreg(dp
, rd
);
3586 /* Source and destination the same. */
3587 gen_mov_F0_vreg(dp
, rd
);
3593 /* VCVTB, VCVTT: only present with the halfprec extension
3594 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3595 * (we choose to UNDEF)
3597 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3598 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3601 if (!extract32(rn
, 1, 1)) {
3602 /* Half precision source. */
3603 gen_mov_F0_vreg(0, rm
);
3606 /* Otherwise fall through */
3608 /* One source operand. */
3609 gen_mov_F0_vreg(dp
, rm
);
3613 /* Two source operands. */
3614 gen_mov_F0_vreg(dp
, rn
);
3615 gen_mov_F1_vreg(dp
, rm
);
3619 /* Perform the calculation. */
3621 case 0: /* VMLA: fd + (fn * fm) */
3622 /* Note that order of inputs to the add matters for NaNs */
3624 gen_mov_F0_vreg(dp
, rd
);
3627 case 1: /* VMLS: fd + -(fn * fm) */
3630 gen_mov_F0_vreg(dp
, rd
);
3633 case 2: /* VNMLS: -fd + (fn * fm) */
3634 /* Note that it isn't valid to replace (-A + B) with (B - A)
3635 * or similar plausible looking simplifications
3636 * because this will give wrong results for NaNs.
3639 gen_mov_F0_vreg(dp
, rd
);
3643 case 3: /* VNMLA: -fd + -(fn * fm) */
3646 gen_mov_F0_vreg(dp
, rd
);
3650 case 4: /* mul: fn * fm */
3653 case 5: /* nmul: -(fn * fm) */
3657 case 6: /* add: fn + fm */
3660 case 7: /* sub: fn - fm */
3663 case 8: /* div: fn / fm */
3666 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3667 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3668 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3669 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3670 /* These are fused multiply-add, and must be done as one
3671 * floating point operation with no rounding between the
3672 * multiplication and addition steps.
3673 * NB that doing the negations here as separate steps is
3674 * correct : an input NaN should come out with its sign bit
3675 * flipped if it is a negated-input.
3677 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3685 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3687 frd
= tcg_temp_new_i64();
3688 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3691 gen_helper_vfp_negd(frd
, frd
);
3693 fpst
= get_fpstatus_ptr(0);
3694 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3695 cpu_F1d
, frd
, fpst
);
3696 tcg_temp_free_ptr(fpst
);
3697 tcg_temp_free_i64(frd
);
3703 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3705 frd
= tcg_temp_new_i32();
3706 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3708 gen_helper_vfp_negs(frd
, frd
);
3710 fpst
= get_fpstatus_ptr(0);
3711 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3712 cpu_F1s
, frd
, fpst
);
3713 tcg_temp_free_ptr(fpst
);
3714 tcg_temp_free_i32(frd
);
3717 case 14: /* fconst */
3718 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3722 n
= (insn
<< 12) & 0x80000000;
3723 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3730 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3737 tcg_gen_movi_i32(cpu_F0s
, n
);
3740 case 15: /* extension space */
3754 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3755 tmp
= gen_vfp_mrs();
3756 tcg_gen_ext16u_i32(tmp
, tmp
);
3758 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3761 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3764 tcg_temp_free_i32(tmp
);
3766 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3767 tmp
= gen_vfp_mrs();
3768 tcg_gen_shri_i32(tmp
, tmp
, 16);
3770 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3773 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3776 tcg_temp_free_i32(tmp
);
3778 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3779 tmp
= tcg_temp_new_i32();
3781 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3784 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3787 gen_mov_F0_vreg(0, rd
);
3788 tmp2
= gen_vfp_mrs();
3789 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3790 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3791 tcg_temp_free_i32(tmp2
);
3794 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3795 tmp
= tcg_temp_new_i32();
3797 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3800 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3803 tcg_gen_shli_i32(tmp
, tmp
, 16);
3804 gen_mov_F0_vreg(0, rd
);
3805 tmp2
= gen_vfp_mrs();
3806 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3807 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3808 tcg_temp_free_i32(tmp2
);
3820 case 11: /* cmpez */
3824 case 12: /* vrintr */
3826 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3828 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3830 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3832 tcg_temp_free_ptr(fpst
);
3835 case 13: /* vrintz */
3837 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3839 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3840 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3842 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3844 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3846 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3847 tcg_temp_free_i32(tcg_rmode
);
3848 tcg_temp_free_ptr(fpst
);
3851 case 14: /* vrintx */
3853 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3855 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3857 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3859 tcg_temp_free_ptr(fpst
);
3862 case 15: /* single<->double conversion */
3864 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3866 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3868 case 16: /* fuito */
3869 gen_vfp_uito(dp
, 0);
3871 case 17: /* fsito */
3872 gen_vfp_sito(dp
, 0);
3874 case 20: /* fshto */
3875 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3878 gen_vfp_shto(dp
, 16 - rm
, 0);
3880 case 21: /* fslto */
3881 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3884 gen_vfp_slto(dp
, 32 - rm
, 0);
3886 case 22: /* fuhto */
3887 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3890 gen_vfp_uhto(dp
, 16 - rm
, 0);
3892 case 23: /* fulto */
3893 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3896 gen_vfp_ulto(dp
, 32 - rm
, 0);
3898 case 24: /* ftoui */
3899 gen_vfp_toui(dp
, 0);
3901 case 25: /* ftouiz */
3902 gen_vfp_touiz(dp
, 0);
3904 case 26: /* ftosi */
3905 gen_vfp_tosi(dp
, 0);
3907 case 27: /* ftosiz */
3908 gen_vfp_tosiz(dp
, 0);
3910 case 28: /* ftosh */
3911 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3914 gen_vfp_tosh(dp
, 16 - rm
, 0);
3916 case 29: /* ftosl */
3917 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3920 gen_vfp_tosl(dp
, 32 - rm
, 0);
3922 case 30: /* ftouh */
3923 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3926 gen_vfp_touh(dp
, 16 - rm
, 0);
3928 case 31: /* ftoul */
3929 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3932 gen_vfp_toul(dp
, 32 - rm
, 0);
3934 default: /* undefined */
3938 default: /* undefined */
3942 /* Write back the result. */
3943 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3944 /* Comparison, do nothing. */
3945 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3946 (rn
& 0x1e) == 0x6)) {
3947 /* VCVT double to int: always integer result.
3948 * VCVT double to half precision is always a single
3951 gen_mov_vreg_F0(0, rd
);
3952 } else if (op
== 15 && rn
== 15) {
3954 gen_mov_vreg_F0(!dp
, rd
);
3956 gen_mov_vreg_F0(dp
, rd
);
3959 /* break out of the loop if we have finished */
3963 if (op
== 15 && delta_m
== 0) {
3964 /* single source one-many */
3966 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3968 gen_mov_vreg_F0(dp
, rd
);
3972 /* Setup the next operands. */
3974 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3978 /* One source operand. */
3979 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3981 gen_mov_F0_vreg(dp
, rm
);
3983 /* Two source operands. */
3984 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3986 gen_mov_F0_vreg(dp
, rn
);
3988 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3990 gen_mov_F1_vreg(dp
, rm
);
3998 if ((insn
& 0x03e00000) == 0x00400000) {
3999 /* two-register transfer */
4000 rn
= (insn
>> 16) & 0xf;
4001 rd
= (insn
>> 12) & 0xf;
4003 VFP_DREG_M(rm
, insn
);
4005 rm
= VFP_SREG_M(insn
);
4008 if (insn
& ARM_CP_RW_BIT
) {
4011 gen_mov_F0_vreg(0, rm
* 2);
4012 tmp
= gen_vfp_mrs();
4013 store_reg(s
, rd
, tmp
);
4014 gen_mov_F0_vreg(0, rm
* 2 + 1);
4015 tmp
= gen_vfp_mrs();
4016 store_reg(s
, rn
, tmp
);
4018 gen_mov_F0_vreg(0, rm
);
4019 tmp
= gen_vfp_mrs();
4020 store_reg(s
, rd
, tmp
);
4021 gen_mov_F0_vreg(0, rm
+ 1);
4022 tmp
= gen_vfp_mrs();
4023 store_reg(s
, rn
, tmp
);
4028 tmp
= load_reg(s
, rd
);
4030 gen_mov_vreg_F0(0, rm
* 2);
4031 tmp
= load_reg(s
, rn
);
4033 gen_mov_vreg_F0(0, rm
* 2 + 1);
4035 tmp
= load_reg(s
, rd
);
4037 gen_mov_vreg_F0(0, rm
);
4038 tmp
= load_reg(s
, rn
);
4040 gen_mov_vreg_F0(0, rm
+ 1);
4045 rn
= (insn
>> 16) & 0xf;
4047 VFP_DREG_D(rd
, insn
);
4049 rd
= VFP_SREG_D(insn
);
4050 if ((insn
& 0x01200000) == 0x01000000) {
4051 /* Single load/store */
4052 offset
= (insn
& 0xff) << 2;
4053 if ((insn
& (1 << 23)) == 0)
4055 if (s
->thumb
&& rn
== 15) {
4056 /* This is actually UNPREDICTABLE */
4057 addr
= tcg_temp_new_i32();
4058 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4060 addr
= load_reg(s
, rn
);
4062 tcg_gen_addi_i32(addr
, addr
, offset
);
4063 if (insn
& (1 << 20)) {
4064 gen_vfp_ld(s
, dp
, addr
);
4065 gen_mov_vreg_F0(dp
, rd
);
4067 gen_mov_F0_vreg(dp
, rd
);
4068 gen_vfp_st(s
, dp
, addr
);
4070 tcg_temp_free_i32(addr
);
4072 /* load/store multiple */
4073 int w
= insn
& (1 << 21);
4075 n
= (insn
>> 1) & 0x7f;
4079 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
4080 /* P == U , W == 1 => UNDEF */
4083 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
4084 /* UNPREDICTABLE cases for bad immediates: we choose to
4085 * UNDEF to avoid generating huge numbers of TCG ops
4089 if (rn
== 15 && w
) {
4090 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4094 if (s
->thumb
&& rn
== 15) {
4095 /* This is actually UNPREDICTABLE */
4096 addr
= tcg_temp_new_i32();
4097 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4099 addr
= load_reg(s
, rn
);
4101 if (insn
& (1 << 24)) /* pre-decrement */
4102 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4108 for (i
= 0; i
< n
; i
++) {
4109 if (insn
& ARM_CP_RW_BIT
) {
4111 gen_vfp_ld(s
, dp
, addr
);
4112 gen_mov_vreg_F0(dp
, rd
+ i
);
4115 gen_mov_F0_vreg(dp
, rd
+ i
);
4116 gen_vfp_st(s
, dp
, addr
);
4118 tcg_gen_addi_i32(addr
, addr
, offset
);
4122 if (insn
& (1 << 24))
4123 offset
= -offset
* n
;
4124 else if (dp
&& (insn
& 1))
4130 tcg_gen_addi_i32(addr
, addr
, offset
);
4131 store_reg(s
, rn
, addr
);
4133 tcg_temp_free_i32(addr
);
4139 /* Should never happen. */
4145 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4147 #ifndef CONFIG_USER_ONLY
4148 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4149 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4155 static void gen_goto_ptr(void)
4157 TCGv addr
= tcg_temp_new();
4158 tcg_gen_extu_i32_tl(addr
, cpu_R
[15]);
4159 tcg_gen_lookup_and_goto_ptr(addr
);
4160 tcg_temp_free(addr
);
4163 /* This will end the TB but doesn't guarantee we'll return to
4164 * cpu_loop_exec. Any live exit_requests will be processed as we
4165 * enter the next TB.
4167 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4169 if (use_goto_tb(s
, dest
)) {
4171 gen_set_pc_im(s
, dest
);
4172 tcg_gen_exit_tb((uintptr_t)s
->base
.tb
+ n
);
4174 gen_set_pc_im(s
, dest
);
4177 s
->base
.is_jmp
= DISAS_NORETURN
;
4180 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4182 if (unlikely(is_singlestepping(s
))) {
4183 /* An indirect jump so that we still trigger the debug exception. */
4188 gen_goto_tb(s
, 0, dest
);
4192 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4195 tcg_gen_sari_i32(t0
, t0
, 16);
4199 tcg_gen_sari_i32(t1
, t1
, 16);
4202 tcg_gen_mul_i32(t0
, t0
, t1
);
4205 /* Return the mask of PSR bits set by a MSR instruction. */
4206 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4211 if (flags
& (1 << 0))
4213 if (flags
& (1 << 1))
4215 if (flags
& (1 << 2))
4217 if (flags
& (1 << 3))
4220 /* Mask out undefined bits. */
4221 mask
&= ~CPSR_RESERVED
;
4222 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4225 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4226 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4228 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4229 mask
&= ~(CPSR_E
| CPSR_GE
);
4231 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4234 /* Mask out execution state and reserved bits. */
4236 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4238 /* Mask out privileged bits. */
4244 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4245 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4249 /* ??? This is also undefined in system mode. */
4253 tmp
= load_cpu_field(spsr
);
4254 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4255 tcg_gen_andi_i32(t0
, t0
, mask
);
4256 tcg_gen_or_i32(tmp
, tmp
, t0
);
4257 store_cpu_field(tmp
, spsr
);
4259 gen_set_cpsr(t0
, mask
);
4261 tcg_temp_free_i32(t0
);
4266 /* Returns nonzero if access to the PSR is not permitted. */
4267 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4270 tmp
= tcg_temp_new_i32();
4271 tcg_gen_movi_i32(tmp
, val
);
4272 return gen_set_psr(s
, mask
, spsr
, tmp
);
4275 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4276 int *tgtmode
, int *regno
)
4278 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4279 * the target mode and register number, and identify the various
4280 * unpredictable cases.
4281 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4282 * + executed in user mode
4283 * + using R15 as the src/dest register
4284 * + accessing an unimplemented register
4285 * + accessing a register that's inaccessible at current PL/security state*
4286 * + accessing a register that you could access with a different insn
4287 * We choose to UNDEF in all these cases.
4288 * Since we don't know which of the various AArch32 modes we are in
4289 * we have to defer some checks to runtime.
4290 * Accesses to Monitor mode registers from Secure EL1 (which implies
4291 * that EL3 is AArch64) must trap to EL3.
4293 * If the access checks fail this function will emit code to take
4294 * an exception and return false. Otherwise it will return true,
4295 * and set *tgtmode and *regno appropriately.
4297 int exc_target
= default_exception_el(s
);
4299 /* These instructions are present only in ARMv8, or in ARMv7 with the
4300 * Virtualization Extensions.
4302 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4303 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4307 if (IS_USER(s
) || rn
== 15) {
4311 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4312 * of registers into (r, sysm).
4315 /* SPSRs for other modes */
4317 case 0xe: /* SPSR_fiq */
4318 *tgtmode
= ARM_CPU_MODE_FIQ
;
4320 case 0x10: /* SPSR_irq */
4321 *tgtmode
= ARM_CPU_MODE_IRQ
;
4323 case 0x12: /* SPSR_svc */
4324 *tgtmode
= ARM_CPU_MODE_SVC
;
4326 case 0x14: /* SPSR_abt */
4327 *tgtmode
= ARM_CPU_MODE_ABT
;
4329 case 0x16: /* SPSR_und */
4330 *tgtmode
= ARM_CPU_MODE_UND
;
4332 case 0x1c: /* SPSR_mon */
4333 *tgtmode
= ARM_CPU_MODE_MON
;
4335 case 0x1e: /* SPSR_hyp */
4336 *tgtmode
= ARM_CPU_MODE_HYP
;
4338 default: /* unallocated */
4341 /* We arbitrarily assign SPSR a register number of 16. */
4344 /* general purpose registers for other modes */
4346 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4347 *tgtmode
= ARM_CPU_MODE_USR
;
4350 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4351 *tgtmode
= ARM_CPU_MODE_FIQ
;
4354 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4355 *tgtmode
= ARM_CPU_MODE_IRQ
;
4356 *regno
= sysm
& 1 ? 13 : 14;
4358 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4359 *tgtmode
= ARM_CPU_MODE_SVC
;
4360 *regno
= sysm
& 1 ? 13 : 14;
4362 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4363 *tgtmode
= ARM_CPU_MODE_ABT
;
4364 *regno
= sysm
& 1 ? 13 : 14;
4366 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4367 *tgtmode
= ARM_CPU_MODE_UND
;
4368 *regno
= sysm
& 1 ? 13 : 14;
4370 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4371 *tgtmode
= ARM_CPU_MODE_MON
;
4372 *regno
= sysm
& 1 ? 13 : 14;
4374 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4375 *tgtmode
= ARM_CPU_MODE_HYP
;
4376 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4377 *regno
= sysm
& 1 ? 13 : 17;
4379 default: /* unallocated */
4384 /* Catch the 'accessing inaccessible register' cases we can detect
4385 * at translate time.
4388 case ARM_CPU_MODE_MON
:
4389 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4392 if (s
->current_el
== 1) {
4393 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4394 * then accesses to Mon registers trap to EL3
4400 case ARM_CPU_MODE_HYP
:
4401 /* Note that we can forbid accesses from EL2 here because they
4402 * must be from Hyp mode itself
4404 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4415 /* If we get here then some access check did not pass */
4416 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4420 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4422 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4423 int tgtmode
= 0, regno
= 0;
4425 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4429 /* Sync state because msr_banked() can raise exceptions */
4430 gen_set_condexec(s
);
4431 gen_set_pc_im(s
, s
->pc
- 4);
4432 tcg_reg
= load_reg(s
, rn
);
4433 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4434 tcg_regno
= tcg_const_i32(regno
);
4435 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4436 tcg_temp_free_i32(tcg_tgtmode
);
4437 tcg_temp_free_i32(tcg_regno
);
4438 tcg_temp_free_i32(tcg_reg
);
4439 s
->base
.is_jmp
= DISAS_UPDATE
;
4442 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4444 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4445 int tgtmode
= 0, regno
= 0;
4447 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4451 /* Sync state because mrs_banked() can raise exceptions */
4452 gen_set_condexec(s
);
4453 gen_set_pc_im(s
, s
->pc
- 4);
4454 tcg_reg
= tcg_temp_new_i32();
4455 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4456 tcg_regno
= tcg_const_i32(regno
);
4457 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4458 tcg_temp_free_i32(tcg_tgtmode
);
4459 tcg_temp_free_i32(tcg_regno
);
4460 store_reg(s
, rn
, tcg_reg
);
4461 s
->base
.is_jmp
= DISAS_UPDATE
;
4464 /* Store value to PC as for an exception return (ie don't
4465 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4466 * will do the masking based on the new value of the Thumb bit.
4468 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4470 tcg_gen_mov_i32(cpu_R
[15], pc
);
4471 tcg_temp_free_i32(pc
);
4474 /* Generate a v6 exception return. Marks both values as dead. */
4475 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4477 store_pc_exc_ret(s
, pc
);
4478 /* The cpsr_write_eret helper will mask the low bits of PC
4479 * appropriately depending on the new Thumb bit, so it must
4480 * be called after storing the new PC.
4482 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4483 tcg_temp_free_i32(cpsr
);
4484 /* Must exit loop to check un-masked IRQs */
4485 s
->base
.is_jmp
= DISAS_EXIT
;
4488 /* Generate an old-style exception return. Marks pc as dead. */
4489 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4491 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4495 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4496 * only call the helper when running single threaded TCG code to ensure
4497 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4498 * just skip this instruction. Currently the SEV/SEVL instructions
4499 * which are *one* of many ways to wake the CPU from WFE are not
4500 * implemented so we can't sleep like WFI does.
4502 static void gen_nop_hint(DisasContext
*s
, int val
)
4506 if (!parallel_cpus
) {
4507 gen_set_pc_im(s
, s
->pc
);
4508 s
->base
.is_jmp
= DISAS_YIELD
;
4512 gen_set_pc_im(s
, s
->pc
);
4513 s
->base
.is_jmp
= DISAS_WFI
;
4516 if (!parallel_cpus
) {
4517 gen_set_pc_im(s
, s
->pc
);
4518 s
->base
.is_jmp
= DISAS_WFE
;
4523 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4529 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4531 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4534 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4535 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4536 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4541 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4544 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4545 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4546 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4551 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4552 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4553 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4554 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4555 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4557 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4558 switch ((size << 1) | u) { \
4560 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4563 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4566 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4569 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4572 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4575 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4577 default: return 1; \
4580 #define GEN_NEON_INTEGER_OP(name) do { \
4581 switch ((size << 1) | u) { \
4583 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4586 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4589 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4592 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4595 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4598 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4600 default: return 1; \
4603 static TCGv_i32
neon_load_scratch(int scratch
)
4605 TCGv_i32 tmp
= tcg_temp_new_i32();
4606 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4610 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4612 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4613 tcg_temp_free_i32(var
);
4616 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4620 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4622 gen_neon_dup_high16(tmp
);
4624 gen_neon_dup_low16(tmp
);
4627 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4632 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4635 if (!q
&& size
== 2) {
4638 tmp
= tcg_const_i32(rd
);
4639 tmp2
= tcg_const_i32(rm
);
4643 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4646 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4649 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4657 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4660 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4666 tcg_temp_free_i32(tmp
);
4667 tcg_temp_free_i32(tmp2
);
4671 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4674 if (!q
&& size
== 2) {
4677 tmp
= tcg_const_i32(rd
);
4678 tmp2
= tcg_const_i32(rm
);
4682 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4685 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4688 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4696 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4699 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4705 tcg_temp_free_i32(tmp
);
4706 tcg_temp_free_i32(tmp2
);
4710 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4714 rd
= tcg_temp_new_i32();
4715 tmp
= tcg_temp_new_i32();
4717 tcg_gen_shli_i32(rd
, t0
, 8);
4718 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4719 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4720 tcg_gen_or_i32(rd
, rd
, tmp
);
4722 tcg_gen_shri_i32(t1
, t1
, 8);
4723 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4724 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
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
);
4732 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4736 rd
= tcg_temp_new_i32();
4737 tmp
= tcg_temp_new_i32();
4739 tcg_gen_shli_i32(rd
, t0
, 16);
4740 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4741 tcg_gen_or_i32(rd
, rd
, tmp
);
4742 tcg_gen_shri_i32(t1
, t1
, 16);
4743 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4744 tcg_gen_or_i32(t1
, t1
, tmp
);
4745 tcg_gen_mov_i32(t0
, rd
);
4747 tcg_temp_free_i32(tmp
);
4748 tcg_temp_free_i32(rd
);
4756 } neon_ls_element_type
[11] = {
4770 /* Translate a NEON load/store element instruction. Return nonzero if the
4771 instruction is invalid. */
4772 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4791 /* FIXME: this access check should not take precedence over UNDEF
4792 * for invalid encodings; we will generate incorrect syndrome information
4793 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4795 if (s
->fp_excp_el
) {
4796 gen_exception_insn(s
, 4, EXCP_UDEF
,
4797 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4801 if (!s
->vfp_enabled
)
4803 VFP_DREG_D(rd
, insn
);
4804 rn
= (insn
>> 16) & 0xf;
4806 load
= (insn
& (1 << 21)) != 0;
4807 if ((insn
& (1 << 23)) == 0) {
4808 /* Load store all elements. */
4809 op
= (insn
>> 8) & 0xf;
4810 size
= (insn
>> 6) & 3;
4813 /* Catch UNDEF cases for bad values of align field */
4816 if (((insn
>> 5) & 1) == 1) {
4821 if (((insn
>> 4) & 3) == 3) {
4828 nregs
= neon_ls_element_type
[op
].nregs
;
4829 interleave
= neon_ls_element_type
[op
].interleave
;
4830 spacing
= neon_ls_element_type
[op
].spacing
;
4831 if (size
== 3 && (interleave
| spacing
) != 1)
4833 addr
= tcg_temp_new_i32();
4834 load_reg_var(s
, addr
, rn
);
4835 stride
= (1 << size
) * interleave
;
4836 for (reg
= 0; reg
< nregs
; reg
++) {
4837 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4838 load_reg_var(s
, addr
, rn
);
4839 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4840 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4841 load_reg_var(s
, addr
, rn
);
4842 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4845 tmp64
= tcg_temp_new_i64();
4847 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4848 neon_store_reg64(tmp64
, rd
);
4850 neon_load_reg64(tmp64
, rd
);
4851 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4853 tcg_temp_free_i64(tmp64
);
4854 tcg_gen_addi_i32(addr
, addr
, stride
);
4856 for (pass
= 0; pass
< 2; pass
++) {
4859 tmp
= tcg_temp_new_i32();
4860 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4861 neon_store_reg(rd
, pass
, tmp
);
4863 tmp
= neon_load_reg(rd
, pass
);
4864 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4865 tcg_temp_free_i32(tmp
);
4867 tcg_gen_addi_i32(addr
, addr
, stride
);
4868 } else if (size
== 1) {
4870 tmp
= tcg_temp_new_i32();
4871 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4872 tcg_gen_addi_i32(addr
, addr
, stride
);
4873 tmp2
= tcg_temp_new_i32();
4874 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4875 tcg_gen_addi_i32(addr
, addr
, stride
);
4876 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4877 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4878 tcg_temp_free_i32(tmp2
);
4879 neon_store_reg(rd
, pass
, tmp
);
4881 tmp
= neon_load_reg(rd
, pass
);
4882 tmp2
= tcg_temp_new_i32();
4883 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4884 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4885 tcg_temp_free_i32(tmp
);
4886 tcg_gen_addi_i32(addr
, addr
, stride
);
4887 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4888 tcg_temp_free_i32(tmp2
);
4889 tcg_gen_addi_i32(addr
, addr
, stride
);
4891 } else /* size == 0 */ {
4893 TCGV_UNUSED_I32(tmp2
);
4894 for (n
= 0; n
< 4; n
++) {
4895 tmp
= tcg_temp_new_i32();
4896 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4897 tcg_gen_addi_i32(addr
, addr
, stride
);
4901 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4902 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4903 tcg_temp_free_i32(tmp
);
4906 neon_store_reg(rd
, pass
, tmp2
);
4908 tmp2
= neon_load_reg(rd
, pass
);
4909 for (n
= 0; n
< 4; n
++) {
4910 tmp
= tcg_temp_new_i32();
4912 tcg_gen_mov_i32(tmp
, tmp2
);
4914 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4916 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4917 tcg_temp_free_i32(tmp
);
4918 tcg_gen_addi_i32(addr
, addr
, stride
);
4920 tcg_temp_free_i32(tmp2
);
4927 tcg_temp_free_i32(addr
);
4930 size
= (insn
>> 10) & 3;
4932 /* Load single element to all lanes. */
4933 int a
= (insn
>> 4) & 1;
4937 size
= (insn
>> 6) & 3;
4938 nregs
= ((insn
>> 8) & 3) + 1;
4941 if (nregs
!= 4 || a
== 0) {
4944 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4947 if (nregs
== 1 && a
== 1 && size
== 0) {
4950 if (nregs
== 3 && a
== 1) {
4953 addr
= tcg_temp_new_i32();
4954 load_reg_var(s
, addr
, rn
);
4956 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4957 tmp
= gen_load_and_replicate(s
, addr
, size
);
4958 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4959 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4960 if (insn
& (1 << 5)) {
4961 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4962 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4964 tcg_temp_free_i32(tmp
);
4966 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4967 stride
= (insn
& (1 << 5)) ? 2 : 1;
4968 for (reg
= 0; reg
< nregs
; reg
++) {
4969 tmp
= gen_load_and_replicate(s
, addr
, size
);
4970 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4971 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4972 tcg_temp_free_i32(tmp
);
4973 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4977 tcg_temp_free_i32(addr
);
4978 stride
= (1 << size
) * nregs
;
4980 /* Single element. */
4981 int idx
= (insn
>> 4) & 0xf;
4982 pass
= (insn
>> 7) & 1;
4985 shift
= ((insn
>> 5) & 3) * 8;
4989 shift
= ((insn
>> 6) & 1) * 16;
4990 stride
= (insn
& (1 << 5)) ? 2 : 1;
4994 stride
= (insn
& (1 << 6)) ? 2 : 1;
4999 nregs
= ((insn
>> 8) & 3) + 1;
5000 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5003 if (((idx
& (1 << size
)) != 0) ||
5004 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
5009 if ((idx
& 1) != 0) {
5014 if (size
== 2 && (idx
& 2) != 0) {
5019 if ((size
== 2) && ((idx
& 3) == 3)) {
5026 if ((rd
+ stride
* (nregs
- 1)) > 31) {
5027 /* Attempts to write off the end of the register file
5028 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5029 * the neon_load_reg() would write off the end of the array.
5033 addr
= tcg_temp_new_i32();
5034 load_reg_var(s
, addr
, rn
);
5035 for (reg
= 0; reg
< nregs
; reg
++) {
5037 tmp
= tcg_temp_new_i32();
5040 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
5043 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
5046 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
5048 default: /* Avoid compiler warnings. */
5052 tmp2
= neon_load_reg(rd
, pass
);
5053 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
5054 shift
, size
? 16 : 8);
5055 tcg_temp_free_i32(tmp2
);
5057 neon_store_reg(rd
, pass
, tmp
);
5058 } else { /* Store */
5059 tmp
= neon_load_reg(rd
, pass
);
5061 tcg_gen_shri_i32(tmp
, tmp
, shift
);
5064 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
5067 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
5070 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
5073 tcg_temp_free_i32(tmp
);
5076 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
5078 tcg_temp_free_i32(addr
);
5079 stride
= nregs
* (1 << size
);
5085 base
= load_reg(s
, rn
);
5087 tcg_gen_addi_i32(base
, base
, stride
);
5090 index
= load_reg(s
, rm
);
5091 tcg_gen_add_i32(base
, base
, index
);
5092 tcg_temp_free_i32(index
);
5094 store_reg(s
, rn
, base
);
5099 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5100 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
5102 tcg_gen_and_i32(t
, t
, c
);
5103 tcg_gen_andc_i32(f
, f
, c
);
5104 tcg_gen_or_i32(dest
, t
, f
);
5107 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5110 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
5111 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
5112 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
5117 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5120 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
5121 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
5122 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5127 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5130 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5131 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5132 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5137 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5140 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5141 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5142 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5147 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5153 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5154 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5159 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5160 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5167 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5168 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5173 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5174 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5181 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5185 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5186 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5187 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5192 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5193 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5194 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5198 tcg_temp_free_i32(src
);
5201 static inline void gen_neon_addl(int size
)
5204 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5205 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5206 case 2: tcg_gen_add_i64(CPU_V001
); break;
5211 static inline void gen_neon_subl(int size
)
5214 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5215 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5216 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5221 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5224 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5225 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5227 tcg_gen_neg_i64(var
, var
);
5233 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5236 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5237 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5242 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5247 switch ((size
<< 1) | u
) {
5248 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5249 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5250 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5251 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5253 tmp
= gen_muls_i64_i32(a
, b
);
5254 tcg_gen_mov_i64(dest
, tmp
);
5255 tcg_temp_free_i64(tmp
);
5258 tmp
= gen_mulu_i64_i32(a
, b
);
5259 tcg_gen_mov_i64(dest
, tmp
);
5260 tcg_temp_free_i64(tmp
);
5265 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5266 Don't forget to clean them now. */
5268 tcg_temp_free_i32(a
);
5269 tcg_temp_free_i32(b
);
5273 static void gen_neon_narrow_op(int op
, int u
, int size
,
5274 TCGv_i32 dest
, TCGv_i64 src
)
5278 gen_neon_unarrow_sats(size
, dest
, src
);
5280 gen_neon_narrow(size
, dest
, src
);
5284 gen_neon_narrow_satu(size
, dest
, src
);
5286 gen_neon_narrow_sats(size
, dest
, src
);
5291 /* Symbolic constants for op fields for Neon 3-register same-length.
5292 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5295 #define NEON_3R_VHADD 0
5296 #define NEON_3R_VQADD 1
5297 #define NEON_3R_VRHADD 2
5298 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5299 #define NEON_3R_VHSUB 4
5300 #define NEON_3R_VQSUB 5
5301 #define NEON_3R_VCGT 6
5302 #define NEON_3R_VCGE 7
5303 #define NEON_3R_VSHL 8
5304 #define NEON_3R_VQSHL 9
5305 #define NEON_3R_VRSHL 10
5306 #define NEON_3R_VQRSHL 11
5307 #define NEON_3R_VMAX 12
5308 #define NEON_3R_VMIN 13
5309 #define NEON_3R_VABD 14
5310 #define NEON_3R_VABA 15
5311 #define NEON_3R_VADD_VSUB 16
5312 #define NEON_3R_VTST_VCEQ 17
5313 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5314 #define NEON_3R_VMUL 19
5315 #define NEON_3R_VPMAX 20
5316 #define NEON_3R_VPMIN 21
5317 #define NEON_3R_VQDMULH_VQRDMULH 22
5318 #define NEON_3R_VPADD 23
5319 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5320 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5321 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5322 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5323 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5324 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5325 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5326 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5328 static const uint8_t neon_3r_sizes
[] = {
5329 [NEON_3R_VHADD
] = 0x7,
5330 [NEON_3R_VQADD
] = 0xf,
5331 [NEON_3R_VRHADD
] = 0x7,
5332 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5333 [NEON_3R_VHSUB
] = 0x7,
5334 [NEON_3R_VQSUB
] = 0xf,
5335 [NEON_3R_VCGT
] = 0x7,
5336 [NEON_3R_VCGE
] = 0x7,
5337 [NEON_3R_VSHL
] = 0xf,
5338 [NEON_3R_VQSHL
] = 0xf,
5339 [NEON_3R_VRSHL
] = 0xf,
5340 [NEON_3R_VQRSHL
] = 0xf,
5341 [NEON_3R_VMAX
] = 0x7,
5342 [NEON_3R_VMIN
] = 0x7,
5343 [NEON_3R_VABD
] = 0x7,
5344 [NEON_3R_VABA
] = 0x7,
5345 [NEON_3R_VADD_VSUB
] = 0xf,
5346 [NEON_3R_VTST_VCEQ
] = 0x7,
5347 [NEON_3R_VML
] = 0x7,
5348 [NEON_3R_VMUL
] = 0x7,
5349 [NEON_3R_VPMAX
] = 0x7,
5350 [NEON_3R_VPMIN
] = 0x7,
5351 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5352 [NEON_3R_VPADD
] = 0x7,
5353 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5354 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5355 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5356 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5357 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5358 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5359 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5360 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5363 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5364 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5367 #define NEON_2RM_VREV64 0
5368 #define NEON_2RM_VREV32 1
5369 #define NEON_2RM_VREV16 2
5370 #define NEON_2RM_VPADDL 4
5371 #define NEON_2RM_VPADDL_U 5
5372 #define NEON_2RM_AESE 6 /* Includes AESD */
5373 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5374 #define NEON_2RM_VCLS 8
5375 #define NEON_2RM_VCLZ 9
5376 #define NEON_2RM_VCNT 10
5377 #define NEON_2RM_VMVN 11
5378 #define NEON_2RM_VPADAL 12
5379 #define NEON_2RM_VPADAL_U 13
5380 #define NEON_2RM_VQABS 14
5381 #define NEON_2RM_VQNEG 15
5382 #define NEON_2RM_VCGT0 16
5383 #define NEON_2RM_VCGE0 17
5384 #define NEON_2RM_VCEQ0 18
5385 #define NEON_2RM_VCLE0 19
5386 #define NEON_2RM_VCLT0 20
5387 #define NEON_2RM_SHA1H 21
5388 #define NEON_2RM_VABS 22
5389 #define NEON_2RM_VNEG 23
5390 #define NEON_2RM_VCGT0_F 24
5391 #define NEON_2RM_VCGE0_F 25
5392 #define NEON_2RM_VCEQ0_F 26
5393 #define NEON_2RM_VCLE0_F 27
5394 #define NEON_2RM_VCLT0_F 28
5395 #define NEON_2RM_VABS_F 30
5396 #define NEON_2RM_VNEG_F 31
5397 #define NEON_2RM_VSWP 32
5398 #define NEON_2RM_VTRN 33
5399 #define NEON_2RM_VUZP 34
5400 #define NEON_2RM_VZIP 35
5401 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5402 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5403 #define NEON_2RM_VSHLL 38
5404 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5405 #define NEON_2RM_VRINTN 40
5406 #define NEON_2RM_VRINTX 41
5407 #define NEON_2RM_VRINTA 42
5408 #define NEON_2RM_VRINTZ 43
5409 #define NEON_2RM_VCVT_F16_F32 44
5410 #define NEON_2RM_VRINTM 45
5411 #define NEON_2RM_VCVT_F32_F16 46
5412 #define NEON_2RM_VRINTP 47
5413 #define NEON_2RM_VCVTAU 48
5414 #define NEON_2RM_VCVTAS 49
5415 #define NEON_2RM_VCVTNU 50
5416 #define NEON_2RM_VCVTNS 51
5417 #define NEON_2RM_VCVTPU 52
5418 #define NEON_2RM_VCVTPS 53
5419 #define NEON_2RM_VCVTMU 54
5420 #define NEON_2RM_VCVTMS 55
5421 #define NEON_2RM_VRECPE 56
5422 #define NEON_2RM_VRSQRTE 57
5423 #define NEON_2RM_VRECPE_F 58
5424 #define NEON_2RM_VRSQRTE_F 59
5425 #define NEON_2RM_VCVT_FS 60
5426 #define NEON_2RM_VCVT_FU 61
5427 #define NEON_2RM_VCVT_SF 62
5428 #define NEON_2RM_VCVT_UF 63
5430 static int neon_2rm_is_float_op(int op
)
5432 /* Return true if this neon 2reg-misc op is float-to-float */
5433 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5434 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5435 op
== NEON_2RM_VRINTM
||
5436 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5437 op
>= NEON_2RM_VRECPE_F
);
5440 static bool neon_2rm_is_v8_op(int op
)
5442 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5444 case NEON_2RM_VRINTN
:
5445 case NEON_2RM_VRINTA
:
5446 case NEON_2RM_VRINTM
:
5447 case NEON_2RM_VRINTP
:
5448 case NEON_2RM_VRINTZ
:
5449 case NEON_2RM_VRINTX
:
5450 case NEON_2RM_VCVTAU
:
5451 case NEON_2RM_VCVTAS
:
5452 case NEON_2RM_VCVTNU
:
5453 case NEON_2RM_VCVTNS
:
5454 case NEON_2RM_VCVTPU
:
5455 case NEON_2RM_VCVTPS
:
5456 case NEON_2RM_VCVTMU
:
5457 case NEON_2RM_VCVTMS
:
5464 /* Each entry in this array has bit n set if the insn allows
5465 * size value n (otherwise it will UNDEF). Since unallocated
5466 * op values will have no bits set they always UNDEF.
5468 static const uint8_t neon_2rm_sizes
[] = {
5469 [NEON_2RM_VREV64
] = 0x7,
5470 [NEON_2RM_VREV32
] = 0x3,
5471 [NEON_2RM_VREV16
] = 0x1,
5472 [NEON_2RM_VPADDL
] = 0x7,
5473 [NEON_2RM_VPADDL_U
] = 0x7,
5474 [NEON_2RM_AESE
] = 0x1,
5475 [NEON_2RM_AESMC
] = 0x1,
5476 [NEON_2RM_VCLS
] = 0x7,
5477 [NEON_2RM_VCLZ
] = 0x7,
5478 [NEON_2RM_VCNT
] = 0x1,
5479 [NEON_2RM_VMVN
] = 0x1,
5480 [NEON_2RM_VPADAL
] = 0x7,
5481 [NEON_2RM_VPADAL_U
] = 0x7,
5482 [NEON_2RM_VQABS
] = 0x7,
5483 [NEON_2RM_VQNEG
] = 0x7,
5484 [NEON_2RM_VCGT0
] = 0x7,
5485 [NEON_2RM_VCGE0
] = 0x7,
5486 [NEON_2RM_VCEQ0
] = 0x7,
5487 [NEON_2RM_VCLE0
] = 0x7,
5488 [NEON_2RM_VCLT0
] = 0x7,
5489 [NEON_2RM_SHA1H
] = 0x4,
5490 [NEON_2RM_VABS
] = 0x7,
5491 [NEON_2RM_VNEG
] = 0x7,
5492 [NEON_2RM_VCGT0_F
] = 0x4,
5493 [NEON_2RM_VCGE0_F
] = 0x4,
5494 [NEON_2RM_VCEQ0_F
] = 0x4,
5495 [NEON_2RM_VCLE0_F
] = 0x4,
5496 [NEON_2RM_VCLT0_F
] = 0x4,
5497 [NEON_2RM_VABS_F
] = 0x4,
5498 [NEON_2RM_VNEG_F
] = 0x4,
5499 [NEON_2RM_VSWP
] = 0x1,
5500 [NEON_2RM_VTRN
] = 0x7,
5501 [NEON_2RM_VUZP
] = 0x7,
5502 [NEON_2RM_VZIP
] = 0x7,
5503 [NEON_2RM_VMOVN
] = 0x7,
5504 [NEON_2RM_VQMOVN
] = 0x7,
5505 [NEON_2RM_VSHLL
] = 0x7,
5506 [NEON_2RM_SHA1SU1
] = 0x4,
5507 [NEON_2RM_VRINTN
] = 0x4,
5508 [NEON_2RM_VRINTX
] = 0x4,
5509 [NEON_2RM_VRINTA
] = 0x4,
5510 [NEON_2RM_VRINTZ
] = 0x4,
5511 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5512 [NEON_2RM_VRINTM
] = 0x4,
5513 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5514 [NEON_2RM_VRINTP
] = 0x4,
5515 [NEON_2RM_VCVTAU
] = 0x4,
5516 [NEON_2RM_VCVTAS
] = 0x4,
5517 [NEON_2RM_VCVTNU
] = 0x4,
5518 [NEON_2RM_VCVTNS
] = 0x4,
5519 [NEON_2RM_VCVTPU
] = 0x4,
5520 [NEON_2RM_VCVTPS
] = 0x4,
5521 [NEON_2RM_VCVTMU
] = 0x4,
5522 [NEON_2RM_VCVTMS
] = 0x4,
5523 [NEON_2RM_VRECPE
] = 0x4,
5524 [NEON_2RM_VRSQRTE
] = 0x4,
5525 [NEON_2RM_VRECPE_F
] = 0x4,
5526 [NEON_2RM_VRSQRTE_F
] = 0x4,
5527 [NEON_2RM_VCVT_FS
] = 0x4,
5528 [NEON_2RM_VCVT_FU
] = 0x4,
5529 [NEON_2RM_VCVT_SF
] = 0x4,
5530 [NEON_2RM_VCVT_UF
] = 0x4,
5533 /* Translate a NEON data processing instruction. Return nonzero if the
5534 instruction is invalid.
5535 We process data in a mixture of 32-bit and 64-bit chunks.
5536 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5538 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5550 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5553 /* FIXME: this access check should not take precedence over UNDEF
5554 * for invalid encodings; we will generate incorrect syndrome information
5555 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5557 if (s
->fp_excp_el
) {
5558 gen_exception_insn(s
, 4, EXCP_UDEF
,
5559 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5563 if (!s
->vfp_enabled
)
5565 q
= (insn
& (1 << 6)) != 0;
5566 u
= (insn
>> 24) & 1;
5567 VFP_DREG_D(rd
, insn
);
5568 VFP_DREG_N(rn
, insn
);
5569 VFP_DREG_M(rm
, insn
);
5570 size
= (insn
>> 20) & 3;
5571 if ((insn
& (1 << 23)) == 0) {
5572 /* Three register same length. */
5573 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5574 /* Catch invalid op and bad size combinations: UNDEF */
5575 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5578 /* All insns of this form UNDEF for either this condition or the
5579 * superset of cases "Q==1"; we catch the latter later.
5581 if (q
&& ((rd
| rn
| rm
) & 1)) {
5585 * The SHA-1/SHA-256 3-register instructions require special treatment
5586 * here, as their size field is overloaded as an op type selector, and
5587 * they all consume their input in a single pass.
5589 if (op
== NEON_3R_SHA
) {
5593 if (!u
) { /* SHA-1 */
5594 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5597 tmp
= tcg_const_i32(rd
);
5598 tmp2
= tcg_const_i32(rn
);
5599 tmp3
= tcg_const_i32(rm
);
5600 tmp4
= tcg_const_i32(size
);
5601 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5602 tcg_temp_free_i32(tmp4
);
5603 } else { /* SHA-256 */
5604 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5607 tmp
= tcg_const_i32(rd
);
5608 tmp2
= tcg_const_i32(rn
);
5609 tmp3
= tcg_const_i32(rm
);
5612 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5615 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5618 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5622 tcg_temp_free_i32(tmp
);
5623 tcg_temp_free_i32(tmp2
);
5624 tcg_temp_free_i32(tmp3
);
5627 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5628 /* 64-bit element instructions. */
5629 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5630 neon_load_reg64(cpu_V0
, rn
+ pass
);
5631 neon_load_reg64(cpu_V1
, rm
+ pass
);
5635 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5638 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5644 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5647 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5653 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5655 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5660 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5663 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5669 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5671 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5674 case NEON_3R_VQRSHL
:
5676 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5679 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5683 case NEON_3R_VADD_VSUB
:
5685 tcg_gen_sub_i64(CPU_V001
);
5687 tcg_gen_add_i64(CPU_V001
);
5693 neon_store_reg64(cpu_V0
, rd
+ pass
);
5702 case NEON_3R_VQRSHL
:
5705 /* Shift instruction operands are reversed. */
5720 case NEON_3R_FLOAT_ARITH
:
5721 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5723 case NEON_3R_FLOAT_MINMAX
:
5724 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5726 case NEON_3R_FLOAT_CMP
:
5728 /* no encoding for U=0 C=1x */
5732 case NEON_3R_FLOAT_ACMP
:
5737 case NEON_3R_FLOAT_MISC
:
5738 /* VMAXNM/VMINNM in ARMv8 */
5739 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5744 if (u
&& (size
!= 0)) {
5745 /* UNDEF on invalid size for polynomial subcase */
5750 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5758 if (pairwise
&& q
) {
5759 /* All the pairwise insns UNDEF if Q is set */
5763 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5768 tmp
= neon_load_reg(rn
, 0);
5769 tmp2
= neon_load_reg(rn
, 1);
5771 tmp
= neon_load_reg(rm
, 0);
5772 tmp2
= neon_load_reg(rm
, 1);
5776 tmp
= neon_load_reg(rn
, pass
);
5777 tmp2
= neon_load_reg(rm
, pass
);
5781 GEN_NEON_INTEGER_OP(hadd
);
5784 GEN_NEON_INTEGER_OP_ENV(qadd
);
5786 case NEON_3R_VRHADD
:
5787 GEN_NEON_INTEGER_OP(rhadd
);
5789 case NEON_3R_LOGIC
: /* Logic ops. */
5790 switch ((u
<< 2) | size
) {
5792 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5795 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5798 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5801 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5804 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5807 tmp3
= neon_load_reg(rd
, pass
);
5808 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5809 tcg_temp_free_i32(tmp3
);
5812 tmp3
= neon_load_reg(rd
, pass
);
5813 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5814 tcg_temp_free_i32(tmp3
);
5817 tmp3
= neon_load_reg(rd
, pass
);
5818 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5819 tcg_temp_free_i32(tmp3
);
5824 GEN_NEON_INTEGER_OP(hsub
);
5827 GEN_NEON_INTEGER_OP_ENV(qsub
);
5830 GEN_NEON_INTEGER_OP(cgt
);
5833 GEN_NEON_INTEGER_OP(cge
);
5836 GEN_NEON_INTEGER_OP(shl
);
5839 GEN_NEON_INTEGER_OP_ENV(qshl
);
5842 GEN_NEON_INTEGER_OP(rshl
);
5844 case NEON_3R_VQRSHL
:
5845 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5848 GEN_NEON_INTEGER_OP(max
);
5851 GEN_NEON_INTEGER_OP(min
);
5854 GEN_NEON_INTEGER_OP(abd
);
5857 GEN_NEON_INTEGER_OP(abd
);
5858 tcg_temp_free_i32(tmp2
);
5859 tmp2
= neon_load_reg(rd
, pass
);
5860 gen_neon_add(size
, tmp
, tmp2
);
5862 case NEON_3R_VADD_VSUB
:
5863 if (!u
) { /* VADD */
5864 gen_neon_add(size
, tmp
, tmp2
);
5867 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5868 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5869 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5874 case NEON_3R_VTST_VCEQ
:
5875 if (!u
) { /* VTST */
5877 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5878 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5879 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5884 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5885 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5886 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5891 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5893 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5894 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5895 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5898 tcg_temp_free_i32(tmp2
);
5899 tmp2
= neon_load_reg(rd
, pass
);
5901 gen_neon_rsb(size
, tmp
, tmp2
);
5903 gen_neon_add(size
, tmp
, tmp2
);
5907 if (u
) { /* polynomial */
5908 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5909 } else { /* Integer */
5911 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5912 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5913 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5919 GEN_NEON_INTEGER_OP(pmax
);
5922 GEN_NEON_INTEGER_OP(pmin
);
5924 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5925 if (!u
) { /* VQDMULH */
5928 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5931 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5935 } else { /* VQRDMULH */
5938 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5941 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5949 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5950 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5951 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5955 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5957 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5958 switch ((u
<< 2) | size
) {
5961 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5964 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5967 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5972 tcg_temp_free_ptr(fpstatus
);
5975 case NEON_3R_FLOAT_MULTIPLY
:
5977 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5978 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5980 tcg_temp_free_i32(tmp2
);
5981 tmp2
= neon_load_reg(rd
, pass
);
5983 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5985 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5988 tcg_temp_free_ptr(fpstatus
);
5991 case NEON_3R_FLOAT_CMP
:
5993 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5995 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5998 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6000 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6003 tcg_temp_free_ptr(fpstatus
);
6006 case NEON_3R_FLOAT_ACMP
:
6008 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6010 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6012 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6014 tcg_temp_free_ptr(fpstatus
);
6017 case NEON_3R_FLOAT_MINMAX
:
6019 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6021 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
6023 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
6025 tcg_temp_free_ptr(fpstatus
);
6028 case NEON_3R_FLOAT_MISC
:
6031 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6033 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
6035 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
6037 tcg_temp_free_ptr(fpstatus
);
6040 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
6042 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
6048 /* VFMA, VFMS: fused multiply-add */
6049 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6050 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
6053 gen_helper_vfp_negs(tmp
, tmp
);
6055 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
6056 tcg_temp_free_i32(tmp3
);
6057 tcg_temp_free_ptr(fpstatus
);
6063 tcg_temp_free_i32(tmp2
);
6065 /* Save the result. For elementwise operations we can put it
6066 straight into the destination register. For pairwise operations
6067 we have to be careful to avoid clobbering the source operands. */
6068 if (pairwise
&& rd
== rm
) {
6069 neon_store_scratch(pass
, tmp
);
6071 neon_store_reg(rd
, pass
, tmp
);
6075 if (pairwise
&& rd
== rm
) {
6076 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6077 tmp
= neon_load_scratch(pass
);
6078 neon_store_reg(rd
, pass
, tmp
);
6081 /* End of 3 register same size operations. */
6082 } else if (insn
& (1 << 4)) {
6083 if ((insn
& 0x00380080) != 0) {
6084 /* Two registers and shift. */
6085 op
= (insn
>> 8) & 0xf;
6086 if (insn
& (1 << 7)) {
6094 while ((insn
& (1 << (size
+ 19))) == 0)
6097 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
6098 /* To avoid excessive duplication of ops we implement shift
6099 by immediate using the variable shift operations. */
6101 /* Shift by immediate:
6102 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6103 if (q
&& ((rd
| rm
) & 1)) {
6106 if (!u
&& (op
== 4 || op
== 6)) {
6109 /* Right shifts are encoded as N - shift, where N is the
6110 element size in bits. */
6112 shift
= shift
- (1 << (size
+ 3));
6120 imm
= (uint8_t) shift
;
6125 imm
= (uint16_t) shift
;
6136 for (pass
= 0; pass
< count
; pass
++) {
6138 neon_load_reg64(cpu_V0
, rm
+ pass
);
6139 tcg_gen_movi_i64(cpu_V1
, imm
);
6144 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6146 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6151 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6153 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6156 case 5: /* VSHL, VSLI */
6157 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6159 case 6: /* VQSHLU */
6160 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6165 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6168 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6173 if (op
== 1 || op
== 3) {
6175 neon_load_reg64(cpu_V1
, rd
+ pass
);
6176 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6177 } else if (op
== 4 || (op
== 5 && u
)) {
6179 neon_load_reg64(cpu_V1
, rd
+ pass
);
6181 if (shift
< -63 || shift
> 63) {
6185 mask
= 0xffffffffffffffffull
>> -shift
;
6187 mask
= 0xffffffffffffffffull
<< shift
;
6190 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6191 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6193 neon_store_reg64(cpu_V0
, rd
+ pass
);
6194 } else { /* size < 3 */
6195 /* Operands in T0 and T1. */
6196 tmp
= neon_load_reg(rm
, pass
);
6197 tmp2
= tcg_temp_new_i32();
6198 tcg_gen_movi_i32(tmp2
, imm
);
6202 GEN_NEON_INTEGER_OP(shl
);
6206 GEN_NEON_INTEGER_OP(rshl
);
6209 case 5: /* VSHL, VSLI */
6211 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6212 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6213 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6217 case 6: /* VQSHLU */
6220 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6224 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6228 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6236 GEN_NEON_INTEGER_OP_ENV(qshl
);
6239 tcg_temp_free_i32(tmp2
);
6241 if (op
== 1 || op
== 3) {
6243 tmp2
= neon_load_reg(rd
, pass
);
6244 gen_neon_add(size
, tmp
, tmp2
);
6245 tcg_temp_free_i32(tmp2
);
6246 } else if (op
== 4 || (op
== 5 && u
)) {
6251 mask
= 0xff >> -shift
;
6253 mask
= (uint8_t)(0xff << shift
);
6259 mask
= 0xffff >> -shift
;
6261 mask
= (uint16_t)(0xffff << shift
);
6265 if (shift
< -31 || shift
> 31) {
6269 mask
= 0xffffffffu
>> -shift
;
6271 mask
= 0xffffffffu
<< shift
;
6277 tmp2
= neon_load_reg(rd
, pass
);
6278 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6279 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6280 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6281 tcg_temp_free_i32(tmp2
);
6283 neon_store_reg(rd
, pass
, tmp
);
6286 } else if (op
< 10) {
6287 /* Shift by immediate and narrow:
6288 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6289 int input_unsigned
= (op
== 8) ? !u
: u
;
6293 shift
= shift
- (1 << (size
+ 3));
6296 tmp64
= tcg_const_i64(shift
);
6297 neon_load_reg64(cpu_V0
, rm
);
6298 neon_load_reg64(cpu_V1
, rm
+ 1);
6299 for (pass
= 0; pass
< 2; pass
++) {
6307 if (input_unsigned
) {
6308 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6310 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6313 if (input_unsigned
) {
6314 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6316 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6319 tmp
= tcg_temp_new_i32();
6320 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6321 neon_store_reg(rd
, pass
, tmp
);
6323 tcg_temp_free_i64(tmp64
);
6326 imm
= (uint16_t)shift
;
6330 imm
= (uint32_t)shift
;
6332 tmp2
= tcg_const_i32(imm
);
6333 tmp4
= neon_load_reg(rm
+ 1, 0);
6334 tmp5
= neon_load_reg(rm
+ 1, 1);
6335 for (pass
= 0; pass
< 2; pass
++) {
6337 tmp
= neon_load_reg(rm
, 0);
6341 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6344 tmp3
= neon_load_reg(rm
, 1);
6348 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6350 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6351 tcg_temp_free_i32(tmp
);
6352 tcg_temp_free_i32(tmp3
);
6353 tmp
= tcg_temp_new_i32();
6354 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6355 neon_store_reg(rd
, pass
, tmp
);
6357 tcg_temp_free_i32(tmp2
);
6359 } else if (op
== 10) {
6361 if (q
|| (rd
& 1)) {
6364 tmp
= neon_load_reg(rm
, 0);
6365 tmp2
= neon_load_reg(rm
, 1);
6366 for (pass
= 0; pass
< 2; pass
++) {
6370 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6373 /* The shift is less than the width of the source
6374 type, so we can just shift the whole register. */
6375 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6376 /* Widen the result of shift: we need to clear
6377 * the potential overflow bits resulting from
6378 * left bits of the narrow input appearing as
6379 * right bits of left the neighbour narrow
6381 if (size
< 2 || !u
) {
6384 imm
= (0xffu
>> (8 - shift
));
6386 } else if (size
== 1) {
6387 imm
= 0xffff >> (16 - shift
);
6390 imm
= 0xffffffff >> (32 - shift
);
6393 imm64
= imm
| (((uint64_t)imm
) << 32);
6397 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6400 neon_store_reg64(cpu_V0
, rd
+ pass
);
6402 } else if (op
>= 14) {
6403 /* VCVT fixed-point. */
6404 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6407 /* We have already masked out the must-be-1 top bit of imm6,
6408 * hence this 32-shift where the ARM ARM has 64-imm6.
6411 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6412 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6415 gen_vfp_ulto(0, shift
, 1);
6417 gen_vfp_slto(0, shift
, 1);
6420 gen_vfp_toul(0, shift
, 1);
6422 gen_vfp_tosl(0, shift
, 1);
6424 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6429 } else { /* (insn & 0x00380080) == 0 */
6431 if (q
&& (rd
& 1)) {
6435 op
= (insn
>> 8) & 0xf;
6436 /* One register and immediate. */
6437 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6438 invert
= (insn
& (1 << 5)) != 0;
6439 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6440 * We choose to not special-case this and will behave as if a
6441 * valid constant encoding of 0 had been given.
6460 imm
= (imm
<< 8) | (imm
<< 24);
6463 imm
= (imm
<< 8) | 0xff;
6466 imm
= (imm
<< 16) | 0xffff;
6469 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6477 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6478 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6484 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6485 if (op
& 1 && op
< 12) {
6486 tmp
= neon_load_reg(rd
, pass
);
6488 /* The immediate value has already been inverted, so
6490 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6492 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6496 tmp
= tcg_temp_new_i32();
6497 if (op
== 14 && invert
) {
6501 for (n
= 0; n
< 4; n
++) {
6502 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6503 val
|= 0xff << (n
* 8);
6505 tcg_gen_movi_i32(tmp
, val
);
6507 tcg_gen_movi_i32(tmp
, imm
);
6510 neon_store_reg(rd
, pass
, tmp
);
6513 } else { /* (insn & 0x00800010 == 0x00800000) */
6515 op
= (insn
>> 8) & 0xf;
6516 if ((insn
& (1 << 6)) == 0) {
6517 /* Three registers of different lengths. */
6521 /* undefreq: bit 0 : UNDEF if size == 0
6522 * bit 1 : UNDEF if size == 1
6523 * bit 2 : UNDEF if size == 2
6524 * bit 3 : UNDEF if U == 1
6525 * Note that [2:0] set implies 'always UNDEF'
6528 /* prewiden, src1_wide, src2_wide, undefreq */
6529 static const int neon_3reg_wide
[16][4] = {
6530 {1, 0, 0, 0}, /* VADDL */
6531 {1, 1, 0, 0}, /* VADDW */
6532 {1, 0, 0, 0}, /* VSUBL */
6533 {1, 1, 0, 0}, /* VSUBW */
6534 {0, 1, 1, 0}, /* VADDHN */
6535 {0, 0, 0, 0}, /* VABAL */
6536 {0, 1, 1, 0}, /* VSUBHN */
6537 {0, 0, 0, 0}, /* VABDL */
6538 {0, 0, 0, 0}, /* VMLAL */
6539 {0, 0, 0, 9}, /* VQDMLAL */
6540 {0, 0, 0, 0}, /* VMLSL */
6541 {0, 0, 0, 9}, /* VQDMLSL */
6542 {0, 0, 0, 0}, /* Integer VMULL */
6543 {0, 0, 0, 1}, /* VQDMULL */
6544 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6545 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6548 prewiden
= neon_3reg_wide
[op
][0];
6549 src1_wide
= neon_3reg_wide
[op
][1];
6550 src2_wide
= neon_3reg_wide
[op
][2];
6551 undefreq
= neon_3reg_wide
[op
][3];
6553 if ((undefreq
& (1 << size
)) ||
6554 ((undefreq
& 8) && u
)) {
6557 if ((src1_wide
&& (rn
& 1)) ||
6558 (src2_wide
&& (rm
& 1)) ||
6559 (!src2_wide
&& (rd
& 1))) {
6563 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6564 * outside the loop below as it only performs a single pass.
6566 if (op
== 14 && size
== 2) {
6567 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6569 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6572 tcg_rn
= tcg_temp_new_i64();
6573 tcg_rm
= tcg_temp_new_i64();
6574 tcg_rd
= tcg_temp_new_i64();
6575 neon_load_reg64(tcg_rn
, rn
);
6576 neon_load_reg64(tcg_rm
, rm
);
6577 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6578 neon_store_reg64(tcg_rd
, rd
);
6579 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6580 neon_store_reg64(tcg_rd
, rd
+ 1);
6581 tcg_temp_free_i64(tcg_rn
);
6582 tcg_temp_free_i64(tcg_rm
);
6583 tcg_temp_free_i64(tcg_rd
);
6587 /* Avoid overlapping operands. Wide source operands are
6588 always aligned so will never overlap with wide
6589 destinations in problematic ways. */
6590 if (rd
== rm
&& !src2_wide
) {
6591 tmp
= neon_load_reg(rm
, 1);
6592 neon_store_scratch(2, tmp
);
6593 } else if (rd
== rn
&& !src1_wide
) {
6594 tmp
= neon_load_reg(rn
, 1);
6595 neon_store_scratch(2, tmp
);
6597 TCGV_UNUSED_I32(tmp3
);
6598 for (pass
= 0; pass
< 2; pass
++) {
6600 neon_load_reg64(cpu_V0
, rn
+ pass
);
6601 TCGV_UNUSED_I32(tmp
);
6603 if (pass
== 1 && rd
== rn
) {
6604 tmp
= neon_load_scratch(2);
6606 tmp
= neon_load_reg(rn
, pass
);
6609 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6613 neon_load_reg64(cpu_V1
, rm
+ pass
);
6614 TCGV_UNUSED_I32(tmp2
);
6616 if (pass
== 1 && rd
== rm
) {
6617 tmp2
= neon_load_scratch(2);
6619 tmp2
= neon_load_reg(rm
, pass
);
6622 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6626 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6627 gen_neon_addl(size
);
6629 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6630 gen_neon_subl(size
);
6632 case 5: case 7: /* VABAL, VABDL */
6633 switch ((size
<< 1) | u
) {
6635 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6638 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6641 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6644 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6647 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6650 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6654 tcg_temp_free_i32(tmp2
);
6655 tcg_temp_free_i32(tmp
);
6657 case 8: case 9: case 10: case 11: case 12: case 13:
6658 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6659 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6661 case 14: /* Polynomial VMULL */
6662 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6663 tcg_temp_free_i32(tmp2
);
6664 tcg_temp_free_i32(tmp
);
6666 default: /* 15 is RESERVED: caught earlier */
6671 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6672 neon_store_reg64(cpu_V0
, rd
+ pass
);
6673 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6675 neon_load_reg64(cpu_V1
, rd
+ pass
);
6677 case 10: /* VMLSL */
6678 gen_neon_negl(cpu_V0
, size
);
6680 case 5: case 8: /* VABAL, VMLAL */
6681 gen_neon_addl(size
);
6683 case 9: case 11: /* VQDMLAL, VQDMLSL */
6684 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6686 gen_neon_negl(cpu_V0
, size
);
6688 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6693 neon_store_reg64(cpu_V0
, rd
+ pass
);
6694 } else if (op
== 4 || op
== 6) {
6695 /* Narrowing operation. */
6696 tmp
= tcg_temp_new_i32();
6700 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6703 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6706 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6707 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6714 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6717 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6720 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6721 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6722 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6730 neon_store_reg(rd
, 0, tmp3
);
6731 neon_store_reg(rd
, 1, tmp
);
6734 /* Write back the result. */
6735 neon_store_reg64(cpu_V0
, rd
+ pass
);
6739 /* Two registers and a scalar. NB that for ops of this form
6740 * the ARM ARM labels bit 24 as Q, but it is in our variable
6747 case 1: /* Float VMLA scalar */
6748 case 5: /* Floating point VMLS scalar */
6749 case 9: /* Floating point VMUL scalar */
6754 case 0: /* Integer VMLA scalar */
6755 case 4: /* Integer VMLS scalar */
6756 case 8: /* Integer VMUL scalar */
6757 case 12: /* VQDMULH scalar */
6758 case 13: /* VQRDMULH scalar */
6759 if (u
&& ((rd
| rn
) & 1)) {
6762 tmp
= neon_get_scalar(size
, rm
);
6763 neon_store_scratch(0, tmp
);
6764 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6765 tmp
= neon_load_scratch(0);
6766 tmp2
= neon_load_reg(rn
, pass
);
6769 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6771 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6773 } else if (op
== 13) {
6775 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6777 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6779 } else if (op
& 1) {
6780 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6781 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6782 tcg_temp_free_ptr(fpstatus
);
6785 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6786 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6787 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6791 tcg_temp_free_i32(tmp2
);
6794 tmp2
= neon_load_reg(rd
, pass
);
6797 gen_neon_add(size
, tmp
, tmp2
);
6801 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6802 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6803 tcg_temp_free_ptr(fpstatus
);
6807 gen_neon_rsb(size
, tmp
, tmp2
);
6811 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6812 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6813 tcg_temp_free_ptr(fpstatus
);
6819 tcg_temp_free_i32(tmp2
);
6821 neon_store_reg(rd
, pass
, tmp
);
6824 case 3: /* VQDMLAL scalar */
6825 case 7: /* VQDMLSL scalar */
6826 case 11: /* VQDMULL scalar */
6831 case 2: /* VMLAL sclar */
6832 case 6: /* VMLSL scalar */
6833 case 10: /* VMULL scalar */
6837 tmp2
= neon_get_scalar(size
, rm
);
6838 /* We need a copy of tmp2 because gen_neon_mull
6839 * deletes it during pass 0. */
6840 tmp4
= tcg_temp_new_i32();
6841 tcg_gen_mov_i32(tmp4
, tmp2
);
6842 tmp3
= neon_load_reg(rn
, 1);
6844 for (pass
= 0; pass
< 2; pass
++) {
6846 tmp
= neon_load_reg(rn
, 0);
6851 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6853 neon_load_reg64(cpu_V1
, rd
+ pass
);
6857 gen_neon_negl(cpu_V0
, size
);
6860 gen_neon_addl(size
);
6863 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6865 gen_neon_negl(cpu_V0
, size
);
6867 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6873 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6878 neon_store_reg64(cpu_V0
, rd
+ pass
);
6883 default: /* 14 and 15 are RESERVED */
6887 } else { /* size == 3 */
6890 imm
= (insn
>> 8) & 0xf;
6895 if (q
&& ((rd
| rn
| rm
) & 1)) {
6900 neon_load_reg64(cpu_V0
, rn
);
6902 neon_load_reg64(cpu_V1
, rn
+ 1);
6904 } else if (imm
== 8) {
6905 neon_load_reg64(cpu_V0
, rn
+ 1);
6907 neon_load_reg64(cpu_V1
, rm
);
6910 tmp64
= tcg_temp_new_i64();
6912 neon_load_reg64(cpu_V0
, rn
);
6913 neon_load_reg64(tmp64
, rn
+ 1);
6915 neon_load_reg64(cpu_V0
, rn
+ 1);
6916 neon_load_reg64(tmp64
, rm
);
6918 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6919 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6920 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6922 neon_load_reg64(cpu_V1
, rm
);
6924 neon_load_reg64(cpu_V1
, rm
+ 1);
6927 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6928 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6929 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6930 tcg_temp_free_i64(tmp64
);
6933 neon_load_reg64(cpu_V0
, rn
);
6934 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6935 neon_load_reg64(cpu_V1
, rm
);
6936 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6937 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6939 neon_store_reg64(cpu_V0
, rd
);
6941 neon_store_reg64(cpu_V1
, rd
+ 1);
6943 } else if ((insn
& (1 << 11)) == 0) {
6944 /* Two register misc. */
6945 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6946 size
= (insn
>> 18) & 3;
6947 /* UNDEF for unknown op values and bad op-size combinations */
6948 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6951 if (neon_2rm_is_v8_op(op
) &&
6952 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6955 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6956 q
&& ((rm
| rd
) & 1)) {
6960 case NEON_2RM_VREV64
:
6961 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6962 tmp
= neon_load_reg(rm
, pass
* 2);
6963 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6965 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6966 case 1: gen_swap_half(tmp
); break;
6967 case 2: /* no-op */ break;
6970 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6972 neon_store_reg(rd
, pass
* 2, tmp2
);
6975 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6976 case 1: gen_swap_half(tmp2
); break;
6979 neon_store_reg(rd
, pass
* 2, tmp2
);
6983 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6984 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6985 for (pass
= 0; pass
< q
+ 1; pass
++) {
6986 tmp
= neon_load_reg(rm
, pass
* 2);
6987 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6988 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6989 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6991 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6992 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6993 case 2: tcg_gen_add_i64(CPU_V001
); break;
6996 if (op
>= NEON_2RM_VPADAL
) {
6998 neon_load_reg64(cpu_V1
, rd
+ pass
);
6999 gen_neon_addl(size
);
7001 neon_store_reg64(cpu_V0
, rd
+ pass
);
7007 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
7008 tmp
= neon_load_reg(rm
, n
);
7009 tmp2
= neon_load_reg(rd
, n
+ 1);
7010 neon_store_reg(rm
, n
, tmp2
);
7011 neon_store_reg(rd
, n
+ 1, tmp
);
7018 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
7023 if (gen_neon_zip(rd
, rm
, size
, q
)) {
7027 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
7028 /* also VQMOVUN; op field and mnemonics don't line up */
7032 TCGV_UNUSED_I32(tmp2
);
7033 for (pass
= 0; pass
< 2; pass
++) {
7034 neon_load_reg64(cpu_V0
, rm
+ pass
);
7035 tmp
= tcg_temp_new_i32();
7036 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
7041 neon_store_reg(rd
, 0, tmp2
);
7042 neon_store_reg(rd
, 1, tmp
);
7046 case NEON_2RM_VSHLL
:
7047 if (q
|| (rd
& 1)) {
7050 tmp
= neon_load_reg(rm
, 0);
7051 tmp2
= neon_load_reg(rm
, 1);
7052 for (pass
= 0; pass
< 2; pass
++) {
7055 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
7056 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
7057 neon_store_reg64(cpu_V0
, rd
+ pass
);
7060 case NEON_2RM_VCVT_F16_F32
:
7061 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7065 tmp
= tcg_temp_new_i32();
7066 tmp2
= tcg_temp_new_i32();
7067 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
7068 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7069 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
7070 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7071 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7072 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7073 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
7074 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
7075 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
7076 neon_store_reg(rd
, 0, tmp2
);
7077 tmp2
= tcg_temp_new_i32();
7078 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
7079 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
7080 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
7081 neon_store_reg(rd
, 1, tmp2
);
7082 tcg_temp_free_i32(tmp
);
7084 case NEON_2RM_VCVT_F32_F16
:
7085 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
7089 tmp3
= tcg_temp_new_i32();
7090 tmp
= neon_load_reg(rm
, 0);
7091 tmp2
= neon_load_reg(rm
, 1);
7092 tcg_gen_ext16u_i32(tmp3
, tmp
);
7093 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7094 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
7095 tcg_gen_shri_i32(tmp3
, tmp
, 16);
7096 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7097 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
7098 tcg_temp_free_i32(tmp
);
7099 tcg_gen_ext16u_i32(tmp3
, tmp2
);
7100 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7101 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
7102 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
7103 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
7104 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
7105 tcg_temp_free_i32(tmp2
);
7106 tcg_temp_free_i32(tmp3
);
7108 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
7109 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
7110 || ((rm
| rd
) & 1)) {
7113 tmp
= tcg_const_i32(rd
);
7114 tmp2
= tcg_const_i32(rm
);
7116 /* Bit 6 is the lowest opcode bit; it distinguishes between
7117 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7119 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7121 if (op
== NEON_2RM_AESE
) {
7122 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
7124 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
7126 tcg_temp_free_i32(tmp
);
7127 tcg_temp_free_i32(tmp2
);
7128 tcg_temp_free_i32(tmp3
);
7130 case NEON_2RM_SHA1H
:
7131 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7132 || ((rm
| rd
) & 1)) {
7135 tmp
= tcg_const_i32(rd
);
7136 tmp2
= tcg_const_i32(rm
);
7138 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
7140 tcg_temp_free_i32(tmp
);
7141 tcg_temp_free_i32(tmp2
);
7143 case NEON_2RM_SHA1SU1
:
7144 if ((rm
| rd
) & 1) {
7147 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7149 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7152 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7155 tmp
= tcg_const_i32(rd
);
7156 tmp2
= tcg_const_i32(rm
);
7158 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
7160 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7162 tcg_temp_free_i32(tmp
);
7163 tcg_temp_free_i32(tmp2
);
7167 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7168 if (neon_2rm_is_float_op(op
)) {
7169 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7170 neon_reg_offset(rm
, pass
));
7171 TCGV_UNUSED_I32(tmp
);
7173 tmp
= neon_load_reg(rm
, pass
);
7176 case NEON_2RM_VREV32
:
7178 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7179 case 1: gen_swap_half(tmp
); break;
7183 case NEON_2RM_VREV16
:
7188 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7189 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7190 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7196 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7197 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7198 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7203 gen_helper_neon_cnt_u8(tmp
, tmp
);
7206 tcg_gen_not_i32(tmp
, tmp
);
7208 case NEON_2RM_VQABS
:
7211 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7214 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7217 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7222 case NEON_2RM_VQNEG
:
7225 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7228 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7231 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7236 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7237 tmp2
= tcg_const_i32(0);
7239 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7240 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7241 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7244 tcg_temp_free_i32(tmp2
);
7245 if (op
== NEON_2RM_VCLE0
) {
7246 tcg_gen_not_i32(tmp
, tmp
);
7249 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7250 tmp2
= tcg_const_i32(0);
7252 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7253 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7254 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7257 tcg_temp_free_i32(tmp2
);
7258 if (op
== NEON_2RM_VCLT0
) {
7259 tcg_gen_not_i32(tmp
, tmp
);
7262 case NEON_2RM_VCEQ0
:
7263 tmp2
= tcg_const_i32(0);
7265 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7266 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7267 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7270 tcg_temp_free_i32(tmp2
);
7274 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7275 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7276 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7281 tmp2
= tcg_const_i32(0);
7282 gen_neon_rsb(size
, tmp
, tmp2
);
7283 tcg_temp_free_i32(tmp2
);
7285 case NEON_2RM_VCGT0_F
:
7287 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7288 tmp2
= tcg_const_i32(0);
7289 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7290 tcg_temp_free_i32(tmp2
);
7291 tcg_temp_free_ptr(fpstatus
);
7294 case NEON_2RM_VCGE0_F
:
7296 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7297 tmp2
= tcg_const_i32(0);
7298 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7299 tcg_temp_free_i32(tmp2
);
7300 tcg_temp_free_ptr(fpstatus
);
7303 case NEON_2RM_VCEQ0_F
:
7305 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7306 tmp2
= tcg_const_i32(0);
7307 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7308 tcg_temp_free_i32(tmp2
);
7309 tcg_temp_free_ptr(fpstatus
);
7312 case NEON_2RM_VCLE0_F
:
7314 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7315 tmp2
= tcg_const_i32(0);
7316 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7317 tcg_temp_free_i32(tmp2
);
7318 tcg_temp_free_ptr(fpstatus
);
7321 case NEON_2RM_VCLT0_F
:
7323 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7324 tmp2
= tcg_const_i32(0);
7325 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7326 tcg_temp_free_i32(tmp2
);
7327 tcg_temp_free_ptr(fpstatus
);
7330 case NEON_2RM_VABS_F
:
7333 case NEON_2RM_VNEG_F
:
7337 tmp2
= neon_load_reg(rd
, pass
);
7338 neon_store_reg(rm
, pass
, tmp2
);
7341 tmp2
= neon_load_reg(rd
, pass
);
7343 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7344 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7347 neon_store_reg(rm
, pass
, tmp2
);
7349 case NEON_2RM_VRINTN
:
7350 case NEON_2RM_VRINTA
:
7351 case NEON_2RM_VRINTM
:
7352 case NEON_2RM_VRINTP
:
7353 case NEON_2RM_VRINTZ
:
7356 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7359 if (op
== NEON_2RM_VRINTZ
) {
7360 rmode
= FPROUNDING_ZERO
;
7362 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7365 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7366 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7368 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7369 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7371 tcg_temp_free_ptr(fpstatus
);
7372 tcg_temp_free_i32(tcg_rmode
);
7375 case NEON_2RM_VRINTX
:
7377 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7378 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7379 tcg_temp_free_ptr(fpstatus
);
7382 case NEON_2RM_VCVTAU
:
7383 case NEON_2RM_VCVTAS
:
7384 case NEON_2RM_VCVTNU
:
7385 case NEON_2RM_VCVTNS
:
7386 case NEON_2RM_VCVTPU
:
7387 case NEON_2RM_VCVTPS
:
7388 case NEON_2RM_VCVTMU
:
7389 case NEON_2RM_VCVTMS
:
7391 bool is_signed
= !extract32(insn
, 7, 1);
7392 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7393 TCGv_i32 tcg_rmode
, tcg_shift
;
7394 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7396 tcg_shift
= tcg_const_i32(0);
7397 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7398 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7402 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7405 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7409 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7411 tcg_temp_free_i32(tcg_rmode
);
7412 tcg_temp_free_i32(tcg_shift
);
7413 tcg_temp_free_ptr(fpst
);
7416 case NEON_2RM_VRECPE
:
7418 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7419 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7420 tcg_temp_free_ptr(fpstatus
);
7423 case NEON_2RM_VRSQRTE
:
7425 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7426 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7427 tcg_temp_free_ptr(fpstatus
);
7430 case NEON_2RM_VRECPE_F
:
7432 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7433 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7434 tcg_temp_free_ptr(fpstatus
);
7437 case NEON_2RM_VRSQRTE_F
:
7439 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7440 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7441 tcg_temp_free_ptr(fpstatus
);
7444 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7447 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7450 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7451 gen_vfp_tosiz(0, 1);
7453 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7454 gen_vfp_touiz(0, 1);
7457 /* Reserved op values were caught by the
7458 * neon_2rm_sizes[] check earlier.
7462 if (neon_2rm_is_float_op(op
)) {
7463 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7464 neon_reg_offset(rd
, pass
));
7466 neon_store_reg(rd
, pass
, tmp
);
7471 } else if ((insn
& (1 << 10)) == 0) {
7473 int n
= ((insn
>> 8) & 3) + 1;
7474 if ((rn
+ n
) > 32) {
7475 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7476 * helper function running off the end of the register file.
7481 if (insn
& (1 << 6)) {
7482 tmp
= neon_load_reg(rd
, 0);
7484 tmp
= tcg_temp_new_i32();
7485 tcg_gen_movi_i32(tmp
, 0);
7487 tmp2
= neon_load_reg(rm
, 0);
7488 tmp4
= tcg_const_i32(rn
);
7489 tmp5
= tcg_const_i32(n
);
7490 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7491 tcg_temp_free_i32(tmp
);
7492 if (insn
& (1 << 6)) {
7493 tmp
= neon_load_reg(rd
, 1);
7495 tmp
= tcg_temp_new_i32();
7496 tcg_gen_movi_i32(tmp
, 0);
7498 tmp3
= neon_load_reg(rm
, 1);
7499 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7500 tcg_temp_free_i32(tmp5
);
7501 tcg_temp_free_i32(tmp4
);
7502 neon_store_reg(rd
, 0, tmp2
);
7503 neon_store_reg(rd
, 1, tmp3
);
7504 tcg_temp_free_i32(tmp
);
7505 } else if ((insn
& 0x380) == 0) {
7507 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7510 if (insn
& (1 << 19)) {
7511 tmp
= neon_load_reg(rm
, 1);
7513 tmp
= neon_load_reg(rm
, 0);
7515 if (insn
& (1 << 16)) {
7516 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7517 } else if (insn
& (1 << 17)) {
7518 if ((insn
>> 18) & 1)
7519 gen_neon_dup_high16(tmp
);
7521 gen_neon_dup_low16(tmp
);
7523 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7524 tmp2
= tcg_temp_new_i32();
7525 tcg_gen_mov_i32(tmp2
, tmp
);
7526 neon_store_reg(rd
, pass
, tmp2
);
7528 tcg_temp_free_i32(tmp
);
7537 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7539 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7540 const ARMCPRegInfo
*ri
;
7542 cpnum
= (insn
>> 8) & 0xf;
7544 /* First check for coprocessor space used for XScale/iwMMXt insns */
7545 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7546 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7549 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7550 return disas_iwmmxt_insn(s
, insn
);
7551 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7552 return disas_dsp_insn(s
, insn
);
7557 /* Otherwise treat as a generic register access */
7558 is64
= (insn
& (1 << 25)) == 0;
7559 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7567 opc1
= (insn
>> 4) & 0xf;
7569 rt2
= (insn
>> 16) & 0xf;
7571 crn
= (insn
>> 16) & 0xf;
7572 opc1
= (insn
>> 21) & 7;
7573 opc2
= (insn
>> 5) & 7;
7576 isread
= (insn
>> 20) & 1;
7577 rt
= (insn
>> 12) & 0xf;
7579 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7580 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7582 /* Check access permissions */
7583 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7588 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7589 /* Emit code to perform further access permissions checks at
7590 * runtime; this may result in an exception.
7591 * Note that on XScale all cp0..c13 registers do an access check
7592 * call in order to handle c15_cpar.
7595 TCGv_i32 tcg_syn
, tcg_isread
;
7598 /* Note that since we are an implementation which takes an
7599 * exception on a trapped conditional instruction only if the
7600 * instruction passes its condition code check, we can take
7601 * advantage of the clause in the ARM ARM that allows us to set
7602 * the COND field in the instruction to 0xE in all cases.
7603 * We could fish the actual condition out of the insn (ARM)
7604 * or the condexec bits (Thumb) but it isn't necessary.
7609 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7612 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7618 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7621 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7626 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7627 * so this can only happen if this is an ARMv7 or earlier CPU,
7628 * in which case the syndrome information won't actually be
7631 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7632 syndrome
= syn_uncategorized();
7636 gen_set_condexec(s
);
7637 gen_set_pc_im(s
, s
->pc
- 4);
7638 tmpptr
= tcg_const_ptr(ri
);
7639 tcg_syn
= tcg_const_i32(syndrome
);
7640 tcg_isread
= tcg_const_i32(isread
);
7641 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7643 tcg_temp_free_ptr(tmpptr
);
7644 tcg_temp_free_i32(tcg_syn
);
7645 tcg_temp_free_i32(tcg_isread
);
7648 /* Handle special cases first */
7649 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7656 gen_set_pc_im(s
, s
->pc
);
7657 s
->base
.is_jmp
= DISAS_WFI
;
7663 if ((s
->base
.tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7672 if (ri
->type
& ARM_CP_CONST
) {
7673 tmp64
= tcg_const_i64(ri
->resetvalue
);
7674 } else if (ri
->readfn
) {
7676 tmp64
= tcg_temp_new_i64();
7677 tmpptr
= tcg_const_ptr(ri
);
7678 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7679 tcg_temp_free_ptr(tmpptr
);
7681 tmp64
= tcg_temp_new_i64();
7682 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7684 tmp
= tcg_temp_new_i32();
7685 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7686 store_reg(s
, rt
, tmp
);
7687 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7688 tmp
= tcg_temp_new_i32();
7689 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7690 tcg_temp_free_i64(tmp64
);
7691 store_reg(s
, rt2
, tmp
);
7694 if (ri
->type
& ARM_CP_CONST
) {
7695 tmp
= tcg_const_i32(ri
->resetvalue
);
7696 } else if (ri
->readfn
) {
7698 tmp
= tcg_temp_new_i32();
7699 tmpptr
= tcg_const_ptr(ri
);
7700 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7701 tcg_temp_free_ptr(tmpptr
);
7703 tmp
= load_cpu_offset(ri
->fieldoffset
);
7706 /* Destination register of r15 for 32 bit loads sets
7707 * the condition codes from the high 4 bits of the value
7710 tcg_temp_free_i32(tmp
);
7712 store_reg(s
, rt
, tmp
);
7717 if (ri
->type
& ARM_CP_CONST
) {
7718 /* If not forbidden by access permissions, treat as WI */
7723 TCGv_i32 tmplo
, tmphi
;
7724 TCGv_i64 tmp64
= tcg_temp_new_i64();
7725 tmplo
= load_reg(s
, rt
);
7726 tmphi
= load_reg(s
, rt2
);
7727 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7728 tcg_temp_free_i32(tmplo
);
7729 tcg_temp_free_i32(tmphi
);
7731 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7732 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7733 tcg_temp_free_ptr(tmpptr
);
7735 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7737 tcg_temp_free_i64(tmp64
);
7742 tmp
= load_reg(s
, rt
);
7743 tmpptr
= tcg_const_ptr(ri
);
7744 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7745 tcg_temp_free_ptr(tmpptr
);
7746 tcg_temp_free_i32(tmp
);
7748 TCGv_i32 tmp
= load_reg(s
, rt
);
7749 store_cpu_offset(tmp
, ri
->fieldoffset
);
7754 if ((s
->base
.tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7755 /* I/O operations must end the TB here (whether read or write) */
7758 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7759 /* We default to ending the TB on a coprocessor register write,
7760 * but allow this to be suppressed by the register definition
7761 * (usually only necessary to work around guest bugs).
7769 /* Unknown register; this might be a guest error or a QEMU
7770 * unimplemented feature.
7773 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7774 "64 bit system register cp:%d opc1: %d crm:%d "
7776 isread
? "read" : "write", cpnum
, opc1
, crm
,
7777 s
->ns
? "non-secure" : "secure");
7779 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7780 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7782 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7783 s
->ns
? "non-secure" : "secure");
7790 /* Store a 64-bit value to a register pair. Clobbers val. */
7791 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7794 tmp
= tcg_temp_new_i32();
7795 tcg_gen_extrl_i64_i32(tmp
, val
);
7796 store_reg(s
, rlow
, tmp
);
7797 tmp
= tcg_temp_new_i32();
7798 tcg_gen_shri_i64(val
, val
, 32);
7799 tcg_gen_extrl_i64_i32(tmp
, val
);
7800 store_reg(s
, rhigh
, tmp
);
7803 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7804 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7809 /* Load value and extend to 64 bits. */
7810 tmp
= tcg_temp_new_i64();
7811 tmp2
= load_reg(s
, rlow
);
7812 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7813 tcg_temp_free_i32(tmp2
);
7814 tcg_gen_add_i64(val
, val
, tmp
);
7815 tcg_temp_free_i64(tmp
);
7818 /* load and add a 64-bit value from a register pair. */
7819 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7825 /* Load 64-bit value rd:rn. */
7826 tmpl
= load_reg(s
, rlow
);
7827 tmph
= load_reg(s
, rhigh
);
7828 tmp
= tcg_temp_new_i64();
7829 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7830 tcg_temp_free_i32(tmpl
);
7831 tcg_temp_free_i32(tmph
);
7832 tcg_gen_add_i64(val
, val
, tmp
);
7833 tcg_temp_free_i64(tmp
);
7836 /* Set N and Z flags from hi|lo. */
7837 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7839 tcg_gen_mov_i32(cpu_NF
, hi
);
7840 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7843 /* Load/Store exclusive instructions are implemented by remembering
7844 the value/address loaded, and seeing if these are the same
7845 when the store is performed. This should be sufficient to implement
7846 the architecturally mandated semantics, and avoids having to monitor
7847 regular stores. The compare vs the remembered value is done during
7848 the cmpxchg operation, but we must compare the addresses manually. */
7849 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7850 TCGv_i32 addr
, int size
)
7852 TCGv_i32 tmp
= tcg_temp_new_i32();
7853 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7858 TCGv_i32 tmp2
= tcg_temp_new_i32();
7859 TCGv_i64 t64
= tcg_temp_new_i64();
7861 gen_aa32_ld_i64(s
, t64
, addr
, get_mem_index(s
), opc
);
7862 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
7863 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
7864 tcg_temp_free_i64(t64
);
7866 store_reg(s
, rt2
, tmp2
);
7868 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
7869 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7872 store_reg(s
, rt
, tmp
);
7873 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7876 static void gen_clrex(DisasContext
*s
)
7878 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7881 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7882 TCGv_i32 addr
, int size
)
7884 TCGv_i32 t0
, t1
, t2
;
7887 TCGLabel
*done_label
;
7888 TCGLabel
*fail_label
;
7889 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7891 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7897 fail_label
= gen_new_label();
7898 done_label
= gen_new_label();
7899 extaddr
= tcg_temp_new_i64();
7900 tcg_gen_extu_i32_i64(extaddr
, addr
);
7901 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7902 tcg_temp_free_i64(extaddr
);
7904 taddr
= gen_aa32_addr(s
, addr
, opc
);
7905 t0
= tcg_temp_new_i32();
7906 t1
= load_reg(s
, rt
);
7908 TCGv_i64 o64
= tcg_temp_new_i64();
7909 TCGv_i64 n64
= tcg_temp_new_i64();
7911 t2
= load_reg(s
, rt2
);
7912 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
7913 tcg_temp_free_i32(t2
);
7914 gen_aa32_frob64(s
, n64
);
7916 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
7917 get_mem_index(s
), opc
);
7918 tcg_temp_free_i64(n64
);
7920 gen_aa32_frob64(s
, o64
);
7921 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
7922 tcg_gen_extrl_i64_i32(t0
, o64
);
7924 tcg_temp_free_i64(o64
);
7926 t2
= tcg_temp_new_i32();
7927 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
7928 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
7929 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
7930 tcg_temp_free_i32(t2
);
7932 tcg_temp_free_i32(t1
);
7933 tcg_temp_free(taddr
);
7934 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
7935 tcg_temp_free_i32(t0
);
7936 tcg_gen_br(done_label
);
7938 gen_set_label(fail_label
);
7939 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7940 gen_set_label(done_label
);
7941 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7947 * @mode: mode field from insn (which stack to store to)
7948 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7949 * @writeback: true if writeback bit set
7951 * Generate code for the SRS (Store Return State) insn.
7953 static void gen_srs(DisasContext
*s
,
7954 uint32_t mode
, uint32_t amode
, bool writeback
)
7961 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7962 * and specified mode is monitor mode
7963 * - UNDEFINED in Hyp mode
7964 * - UNPREDICTABLE in User or System mode
7965 * - UNPREDICTABLE if the specified mode is:
7966 * -- not implemented
7967 * -- not a valid mode number
7968 * -- a mode that's at a higher exception level
7969 * -- Monitor, if we are Non-secure
7970 * For the UNPREDICTABLE cases we choose to UNDEF.
7972 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7973 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7977 if (s
->current_el
== 0 || s
->current_el
== 2) {
7982 case ARM_CPU_MODE_USR
:
7983 case ARM_CPU_MODE_FIQ
:
7984 case ARM_CPU_MODE_IRQ
:
7985 case ARM_CPU_MODE_SVC
:
7986 case ARM_CPU_MODE_ABT
:
7987 case ARM_CPU_MODE_UND
:
7988 case ARM_CPU_MODE_SYS
:
7990 case ARM_CPU_MODE_HYP
:
7991 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7995 case ARM_CPU_MODE_MON
:
7996 /* No need to check specifically for "are we non-secure" because
7997 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7998 * so if this isn't EL3 then we must be non-secure.
8000 if (s
->current_el
!= 3) {
8009 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
8010 default_exception_el(s
));
8014 addr
= tcg_temp_new_i32();
8015 tmp
= tcg_const_i32(mode
);
8016 /* get_r13_banked() will raise an exception if called from System mode */
8017 gen_set_condexec(s
);
8018 gen_set_pc_im(s
, s
->pc
- 4);
8019 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8020 tcg_temp_free_i32(tmp
);
8037 tcg_gen_addi_i32(addr
, addr
, offset
);
8038 tmp
= load_reg(s
, 14);
8039 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8040 tcg_temp_free_i32(tmp
);
8041 tmp
= load_cpu_field(spsr
);
8042 tcg_gen_addi_i32(addr
, addr
, 4);
8043 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8044 tcg_temp_free_i32(tmp
);
8062 tcg_gen_addi_i32(addr
, addr
, offset
);
8063 tmp
= tcg_const_i32(mode
);
8064 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8065 tcg_temp_free_i32(tmp
);
8067 tcg_temp_free_i32(addr
);
8068 s
->base
.is_jmp
= DISAS_UPDATE
;
8071 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8073 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8080 /* M variants do not implement ARM mode; this must raise the INVSTATE
8081 * UsageFault exception.
8083 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8084 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
8085 default_exception_el(s
));
8090 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8091 * choose to UNDEF. In ARMv5 and above the space is used
8092 * for miscellaneous unconditional instructions.
8096 /* Unconditional instructions. */
8097 if (((insn
>> 25) & 7) == 1) {
8098 /* NEON Data processing. */
8099 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8103 if (disas_neon_data_insn(s
, insn
)) {
8108 if ((insn
& 0x0f100000) == 0x04000000) {
8109 /* NEON load/store. */
8110 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8114 if (disas_neon_ls_insn(s
, insn
)) {
8119 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8121 if (disas_vfp_insn(s
, insn
)) {
8126 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8127 ((insn
& 0x0f30f010) == 0x0710f000)) {
8128 if ((insn
& (1 << 22)) == 0) {
8130 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8134 /* Otherwise PLD; v5TE+ */
8138 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8139 ((insn
& 0x0f70f010) == 0x0650f000)) {
8141 return; /* PLI; V7 */
8143 if (((insn
& 0x0f700000) == 0x04100000) ||
8144 ((insn
& 0x0f700010) == 0x06100000)) {
8145 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8148 return; /* v7MP: Unallocated memory hint: must NOP */
8151 if ((insn
& 0x0ffffdff) == 0x01010000) {
8154 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8155 gen_helper_setend(cpu_env
);
8156 s
->base
.is_jmp
= DISAS_UPDATE
;
8159 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8160 switch ((insn
>> 4) & 0xf) {
8168 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8171 /* We need to break the TB after this insn to execute
8172 * self-modifying code correctly and also to take
8173 * any pending interrupts immediately.
8175 gen_goto_tb(s
, 0, s
->pc
& ~1);
8180 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8183 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8185 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8191 rn
= (insn
>> 16) & 0xf;
8192 addr
= load_reg(s
, rn
);
8193 i
= (insn
>> 23) & 3;
8195 case 0: offset
= -4; break; /* DA */
8196 case 1: offset
= 0; break; /* IA */
8197 case 2: offset
= -8; break; /* DB */
8198 case 3: offset
= 4; break; /* IB */
8202 tcg_gen_addi_i32(addr
, addr
, offset
);
8203 /* Load PC into tmp and CPSR into tmp2. */
8204 tmp
= tcg_temp_new_i32();
8205 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8206 tcg_gen_addi_i32(addr
, addr
, 4);
8207 tmp2
= tcg_temp_new_i32();
8208 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8209 if (insn
& (1 << 21)) {
8210 /* Base writeback. */
8212 case 0: offset
= -8; break;
8213 case 1: offset
= 4; break;
8214 case 2: offset
= -4; break;
8215 case 3: offset
= 0; break;
8219 tcg_gen_addi_i32(addr
, addr
, offset
);
8220 store_reg(s
, rn
, addr
);
8222 tcg_temp_free_i32(addr
);
8224 gen_rfe(s
, tmp
, tmp2
);
8226 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8227 /* branch link and change to thumb (blx <offset>) */
8230 val
= (uint32_t)s
->pc
;
8231 tmp
= tcg_temp_new_i32();
8232 tcg_gen_movi_i32(tmp
, val
);
8233 store_reg(s
, 14, tmp
);
8234 /* Sign-extend the 24-bit offset */
8235 offset
= (((int32_t)insn
) << 8) >> 8;
8236 /* offset * 4 + bit24 * 2 + (thumb bit) */
8237 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8238 /* pipeline offset */
8240 /* protected by ARCH(5); above, near the start of uncond block */
8243 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8244 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8245 /* iWMMXt register transfer. */
8246 if (extract32(s
->c15_cpar
, 1, 1)) {
8247 if (!disas_iwmmxt_insn(s
, insn
)) {
8252 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8253 /* Coprocessor double register transfer. */
8255 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8256 /* Additional coprocessor register transfer. */
8257 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8260 /* cps (privileged) */
8264 if (insn
& (1 << 19)) {
8265 if (insn
& (1 << 8))
8267 if (insn
& (1 << 7))
8269 if (insn
& (1 << 6))
8271 if (insn
& (1 << 18))
8274 if (insn
& (1 << 17)) {
8276 val
|= (insn
& 0x1f);
8279 gen_set_psr_im(s
, mask
, 0, val
);
8286 /* if not always execute, we generate a conditional jump to
8288 s
->condlabel
= gen_new_label();
8289 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8292 if ((insn
& 0x0f900000) == 0x03000000) {
8293 if ((insn
& (1 << 21)) == 0) {
8295 rd
= (insn
>> 12) & 0xf;
8296 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8297 if ((insn
& (1 << 22)) == 0) {
8299 tmp
= tcg_temp_new_i32();
8300 tcg_gen_movi_i32(tmp
, val
);
8303 tmp
= load_reg(s
, rd
);
8304 tcg_gen_ext16u_i32(tmp
, tmp
);
8305 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8307 store_reg(s
, rd
, tmp
);
8309 if (((insn
>> 12) & 0xf) != 0xf)
8311 if (((insn
>> 16) & 0xf) == 0) {
8312 gen_nop_hint(s
, insn
& 0xff);
8314 /* CPSR = immediate */
8316 shift
= ((insn
>> 8) & 0xf) * 2;
8318 val
= (val
>> shift
) | (val
<< (32 - shift
));
8319 i
= ((insn
& (1 << 22)) != 0);
8320 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8326 } else if ((insn
& 0x0f900000) == 0x01000000
8327 && (insn
& 0x00000090) != 0x00000090) {
8328 /* miscellaneous instructions */
8329 op1
= (insn
>> 21) & 3;
8330 sh
= (insn
>> 4) & 0xf;
8333 case 0x0: /* MSR, MRS */
8334 if (insn
& (1 << 9)) {
8335 /* MSR (banked) and MRS (banked) */
8336 int sysm
= extract32(insn
, 16, 4) |
8337 (extract32(insn
, 8, 1) << 4);
8338 int r
= extract32(insn
, 22, 1);
8342 gen_msr_banked(s
, r
, sysm
, rm
);
8345 int rd
= extract32(insn
, 12, 4);
8347 gen_mrs_banked(s
, r
, sysm
, rd
);
8352 /* MSR, MRS (for PSRs) */
8355 tmp
= load_reg(s
, rm
);
8356 i
= ((op1
& 2) != 0);
8357 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8361 rd
= (insn
>> 12) & 0xf;
8365 tmp
= load_cpu_field(spsr
);
8367 tmp
= tcg_temp_new_i32();
8368 gen_helper_cpsr_read(tmp
, cpu_env
);
8370 store_reg(s
, rd
, tmp
);
8375 /* branch/exchange thumb (bx). */
8377 tmp
= load_reg(s
, rm
);
8379 } else if (op1
== 3) {
8382 rd
= (insn
>> 12) & 0xf;
8383 tmp
= load_reg(s
, rm
);
8384 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8385 store_reg(s
, rd
, tmp
);
8393 /* Trivial implementation equivalent to bx. */
8394 tmp
= load_reg(s
, rm
);
8405 /* branch link/exchange thumb (blx) */
8406 tmp
= load_reg(s
, rm
);
8407 tmp2
= tcg_temp_new_i32();
8408 tcg_gen_movi_i32(tmp2
, s
->pc
);
8409 store_reg(s
, 14, tmp2
);
8415 uint32_t c
= extract32(insn
, 8, 4);
8417 /* Check this CPU supports ARMv8 CRC instructions.
8418 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8419 * Bits 8, 10 and 11 should be zero.
8421 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8426 rn
= extract32(insn
, 16, 4);
8427 rd
= extract32(insn
, 12, 4);
8429 tmp
= load_reg(s
, rn
);
8430 tmp2
= load_reg(s
, rm
);
8432 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8433 } else if (op1
== 1) {
8434 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8436 tmp3
= tcg_const_i32(1 << op1
);
8438 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8440 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8442 tcg_temp_free_i32(tmp2
);
8443 tcg_temp_free_i32(tmp3
);
8444 store_reg(s
, rd
, tmp
);
8447 case 0x5: /* saturating add/subtract */
8449 rd
= (insn
>> 12) & 0xf;
8450 rn
= (insn
>> 16) & 0xf;
8451 tmp
= load_reg(s
, rm
);
8452 tmp2
= load_reg(s
, rn
);
8454 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8456 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8458 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8459 tcg_temp_free_i32(tmp2
);
8460 store_reg(s
, rd
, tmp
);
8464 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8473 gen_exception_insn(s
, 4, EXCP_BKPT
,
8474 syn_aa32_bkpt(imm16
, false),
8475 default_exception_el(s
));
8478 /* Hypervisor call (v7) */
8486 /* Secure monitor call (v6+) */
8494 g_assert_not_reached();
8498 case 0x8: /* signed multiply */
8503 rs
= (insn
>> 8) & 0xf;
8504 rn
= (insn
>> 12) & 0xf;
8505 rd
= (insn
>> 16) & 0xf;
8507 /* (32 * 16) >> 16 */
8508 tmp
= load_reg(s
, rm
);
8509 tmp2
= load_reg(s
, rs
);
8511 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8514 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8515 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8516 tmp
= tcg_temp_new_i32();
8517 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8518 tcg_temp_free_i64(tmp64
);
8519 if ((sh
& 2) == 0) {
8520 tmp2
= load_reg(s
, rn
);
8521 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8522 tcg_temp_free_i32(tmp2
);
8524 store_reg(s
, rd
, tmp
);
8527 tmp
= load_reg(s
, rm
);
8528 tmp2
= load_reg(s
, rs
);
8529 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8530 tcg_temp_free_i32(tmp2
);
8532 tmp64
= tcg_temp_new_i64();
8533 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8534 tcg_temp_free_i32(tmp
);
8535 gen_addq(s
, tmp64
, rn
, rd
);
8536 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8537 tcg_temp_free_i64(tmp64
);
8540 tmp2
= load_reg(s
, rn
);
8541 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8542 tcg_temp_free_i32(tmp2
);
8544 store_reg(s
, rd
, tmp
);
8551 } else if (((insn
& 0x0e000000) == 0 &&
8552 (insn
& 0x00000090) != 0x90) ||
8553 ((insn
& 0x0e000000) == (1 << 25))) {
8554 int set_cc
, logic_cc
, shiftop
;
8556 op1
= (insn
>> 21) & 0xf;
8557 set_cc
= (insn
>> 20) & 1;
8558 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8560 /* data processing instruction */
8561 if (insn
& (1 << 25)) {
8562 /* immediate operand */
8564 shift
= ((insn
>> 8) & 0xf) * 2;
8566 val
= (val
>> shift
) | (val
<< (32 - shift
));
8568 tmp2
= tcg_temp_new_i32();
8569 tcg_gen_movi_i32(tmp2
, val
);
8570 if (logic_cc
&& shift
) {
8571 gen_set_CF_bit31(tmp2
);
8576 tmp2
= load_reg(s
, rm
);
8577 shiftop
= (insn
>> 5) & 3;
8578 if (!(insn
& (1 << 4))) {
8579 shift
= (insn
>> 7) & 0x1f;
8580 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8582 rs
= (insn
>> 8) & 0xf;
8583 tmp
= load_reg(s
, rs
);
8584 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8587 if (op1
!= 0x0f && op1
!= 0x0d) {
8588 rn
= (insn
>> 16) & 0xf;
8589 tmp
= load_reg(s
, rn
);
8591 TCGV_UNUSED_I32(tmp
);
8593 rd
= (insn
>> 12) & 0xf;
8596 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8600 store_reg_bx(s
, rd
, tmp
);
8603 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8607 store_reg_bx(s
, rd
, tmp
);
8610 if (set_cc
&& rd
== 15) {
8611 /* SUBS r15, ... is used for exception return. */
8615 gen_sub_CC(tmp
, tmp
, tmp2
);
8616 gen_exception_return(s
, tmp
);
8619 gen_sub_CC(tmp
, tmp
, tmp2
);
8621 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8623 store_reg_bx(s
, rd
, tmp
);
8628 gen_sub_CC(tmp
, tmp2
, tmp
);
8630 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8632 store_reg_bx(s
, rd
, tmp
);
8636 gen_add_CC(tmp
, tmp
, tmp2
);
8638 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8640 store_reg_bx(s
, rd
, tmp
);
8644 gen_adc_CC(tmp
, tmp
, tmp2
);
8646 gen_add_carry(tmp
, tmp
, tmp2
);
8648 store_reg_bx(s
, rd
, tmp
);
8652 gen_sbc_CC(tmp
, tmp
, tmp2
);
8654 gen_sub_carry(tmp
, tmp
, tmp2
);
8656 store_reg_bx(s
, rd
, tmp
);
8660 gen_sbc_CC(tmp
, tmp2
, tmp
);
8662 gen_sub_carry(tmp
, tmp2
, tmp
);
8664 store_reg_bx(s
, rd
, tmp
);
8668 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8671 tcg_temp_free_i32(tmp
);
8675 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8678 tcg_temp_free_i32(tmp
);
8682 gen_sub_CC(tmp
, tmp
, tmp2
);
8684 tcg_temp_free_i32(tmp
);
8688 gen_add_CC(tmp
, tmp
, tmp2
);
8690 tcg_temp_free_i32(tmp
);
8693 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8697 store_reg_bx(s
, rd
, tmp
);
8700 if (logic_cc
&& rd
== 15) {
8701 /* MOVS r15, ... is used for exception return. */
8705 gen_exception_return(s
, tmp2
);
8710 store_reg_bx(s
, rd
, tmp2
);
8714 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8718 store_reg_bx(s
, rd
, tmp
);
8722 tcg_gen_not_i32(tmp2
, tmp2
);
8726 store_reg_bx(s
, rd
, tmp2
);
8729 if (op1
!= 0x0f && op1
!= 0x0d) {
8730 tcg_temp_free_i32(tmp2
);
8733 /* other instructions */
8734 op1
= (insn
>> 24) & 0xf;
8738 /* multiplies, extra load/stores */
8739 sh
= (insn
>> 5) & 3;
8742 rd
= (insn
>> 16) & 0xf;
8743 rn
= (insn
>> 12) & 0xf;
8744 rs
= (insn
>> 8) & 0xf;
8746 op1
= (insn
>> 20) & 0xf;
8748 case 0: case 1: case 2: case 3: case 6:
8750 tmp
= load_reg(s
, rs
);
8751 tmp2
= load_reg(s
, rm
);
8752 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8753 tcg_temp_free_i32(tmp2
);
8754 if (insn
& (1 << 22)) {
8755 /* Subtract (mls) */
8757 tmp2
= load_reg(s
, rn
);
8758 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8759 tcg_temp_free_i32(tmp2
);
8760 } else if (insn
& (1 << 21)) {
8762 tmp2
= load_reg(s
, rn
);
8763 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8764 tcg_temp_free_i32(tmp2
);
8766 if (insn
& (1 << 20))
8768 store_reg(s
, rd
, tmp
);
8771 /* 64 bit mul double accumulate (UMAAL) */
8773 tmp
= load_reg(s
, rs
);
8774 tmp2
= load_reg(s
, rm
);
8775 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8776 gen_addq_lo(s
, tmp64
, rn
);
8777 gen_addq_lo(s
, tmp64
, rd
);
8778 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8779 tcg_temp_free_i64(tmp64
);
8781 case 8: case 9: case 10: case 11:
8782 case 12: case 13: case 14: case 15:
8783 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8784 tmp
= load_reg(s
, rs
);
8785 tmp2
= load_reg(s
, rm
);
8786 if (insn
& (1 << 22)) {
8787 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8789 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8791 if (insn
& (1 << 21)) { /* mult accumulate */
8792 TCGv_i32 al
= load_reg(s
, rn
);
8793 TCGv_i32 ah
= load_reg(s
, rd
);
8794 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8795 tcg_temp_free_i32(al
);
8796 tcg_temp_free_i32(ah
);
8798 if (insn
& (1 << 20)) {
8799 gen_logicq_cc(tmp
, tmp2
);
8801 store_reg(s
, rn
, tmp
);
8802 store_reg(s
, rd
, tmp2
);
8808 rn
= (insn
>> 16) & 0xf;
8809 rd
= (insn
>> 12) & 0xf;
8810 if (insn
& (1 << 23)) {
8811 /* load/store exclusive */
8812 int op2
= (insn
>> 8) & 3;
8813 op1
= (insn
>> 21) & 0x3;
8816 case 0: /* lda/stl */
8822 case 1: /* reserved */
8824 case 2: /* ldaex/stlex */
8827 case 3: /* ldrex/strex */
8836 addr
= tcg_temp_local_new_i32();
8837 load_reg_var(s
, addr
, rn
);
8839 /* Since the emulation does not have barriers,
8840 the acquire/release semantics need no special
8843 if (insn
& (1 << 20)) {
8844 tmp
= tcg_temp_new_i32();
8847 gen_aa32_ld32u_iss(s
, tmp
, addr
,
8852 gen_aa32_ld8u_iss(s
, tmp
, addr
,
8857 gen_aa32_ld16u_iss(s
, tmp
, addr
,
8864 store_reg(s
, rd
, tmp
);
8867 tmp
= load_reg(s
, rm
);
8870 gen_aa32_st32_iss(s
, tmp
, addr
,
8875 gen_aa32_st8_iss(s
, tmp
, addr
,
8880 gen_aa32_st16_iss(s
, tmp
, addr
,
8887 tcg_temp_free_i32(tmp
);
8889 } else if (insn
& (1 << 20)) {
8892 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8894 case 1: /* ldrexd */
8895 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8897 case 2: /* ldrexb */
8898 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8900 case 3: /* ldrexh */
8901 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8910 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8912 case 1: /* strexd */
8913 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8915 case 2: /* strexb */
8916 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8918 case 3: /* strexh */
8919 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8925 tcg_temp_free_i32(addr
);
8928 TCGMemOp opc
= s
->be_data
;
8930 /* SWP instruction */
8933 if (insn
& (1 << 22)) {
8936 opc
|= MO_UL
| MO_ALIGN
;
8939 addr
= load_reg(s
, rn
);
8940 taddr
= gen_aa32_addr(s
, addr
, opc
);
8941 tcg_temp_free_i32(addr
);
8943 tmp
= load_reg(s
, rm
);
8944 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
8945 get_mem_index(s
), opc
);
8946 tcg_temp_free(taddr
);
8947 store_reg(s
, rd
, tmp
);
8952 bool load
= insn
& (1 << 20);
8953 bool wbit
= insn
& (1 << 21);
8954 bool pbit
= insn
& (1 << 24);
8955 bool doubleword
= false;
8958 /* Misc load/store */
8959 rn
= (insn
>> 16) & 0xf;
8960 rd
= (insn
>> 12) & 0xf;
8962 /* ISS not valid if writeback */
8963 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
8965 if (!load
&& (sh
& 2)) {
8969 /* UNPREDICTABLE; we choose to UNDEF */
8972 load
= (sh
& 1) == 0;
8976 addr
= load_reg(s
, rn
);
8978 gen_add_datah_offset(s
, insn
, 0, addr
);
8985 tmp
= load_reg(s
, rd
);
8986 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8987 tcg_temp_free_i32(tmp
);
8988 tcg_gen_addi_i32(addr
, addr
, 4);
8989 tmp
= load_reg(s
, rd
+ 1);
8990 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8991 tcg_temp_free_i32(tmp
);
8994 tmp
= tcg_temp_new_i32();
8995 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8996 store_reg(s
, rd
, tmp
);
8997 tcg_gen_addi_i32(addr
, addr
, 4);
8998 tmp
= tcg_temp_new_i32();
8999 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9002 address_offset
= -4;
9005 tmp
= tcg_temp_new_i32();
9008 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9012 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
9017 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
9023 tmp
= load_reg(s
, rd
);
9024 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
9025 tcg_temp_free_i32(tmp
);
9027 /* Perform base writeback before the loaded value to
9028 ensure correct behavior with overlapping index registers.
9029 ldrd with base writeback is undefined if the
9030 destination and index registers overlap. */
9032 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
9033 store_reg(s
, rn
, addr
);
9036 tcg_gen_addi_i32(addr
, addr
, address_offset
);
9037 store_reg(s
, rn
, addr
);
9039 tcg_temp_free_i32(addr
);
9042 /* Complete the load. */
9043 store_reg(s
, rd
, tmp
);
9052 if (insn
& (1 << 4)) {
9054 /* Armv6 Media instructions. */
9056 rn
= (insn
>> 16) & 0xf;
9057 rd
= (insn
>> 12) & 0xf;
9058 rs
= (insn
>> 8) & 0xf;
9059 switch ((insn
>> 23) & 3) {
9060 case 0: /* Parallel add/subtract. */
9061 op1
= (insn
>> 20) & 7;
9062 tmp
= load_reg(s
, rn
);
9063 tmp2
= load_reg(s
, rm
);
9064 sh
= (insn
>> 5) & 7;
9065 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
9067 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
9068 tcg_temp_free_i32(tmp2
);
9069 store_reg(s
, rd
, tmp
);
9072 if ((insn
& 0x00700020) == 0) {
9073 /* Halfword pack. */
9074 tmp
= load_reg(s
, rn
);
9075 tmp2
= load_reg(s
, rm
);
9076 shift
= (insn
>> 7) & 0x1f;
9077 if (insn
& (1 << 6)) {
9081 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9082 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9083 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9087 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9088 tcg_gen_ext16u_i32(tmp
, tmp
);
9089 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9091 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9092 tcg_temp_free_i32(tmp2
);
9093 store_reg(s
, rd
, tmp
);
9094 } else if ((insn
& 0x00200020) == 0x00200000) {
9096 tmp
= load_reg(s
, rm
);
9097 shift
= (insn
>> 7) & 0x1f;
9098 if (insn
& (1 << 6)) {
9101 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9103 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9105 sh
= (insn
>> 16) & 0x1f;
9106 tmp2
= tcg_const_i32(sh
);
9107 if (insn
& (1 << 22))
9108 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9110 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9111 tcg_temp_free_i32(tmp2
);
9112 store_reg(s
, rd
, tmp
);
9113 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9115 tmp
= load_reg(s
, rm
);
9116 sh
= (insn
>> 16) & 0x1f;
9117 tmp2
= tcg_const_i32(sh
);
9118 if (insn
& (1 << 22))
9119 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9121 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9122 tcg_temp_free_i32(tmp2
);
9123 store_reg(s
, rd
, tmp
);
9124 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9126 tmp
= load_reg(s
, rn
);
9127 tmp2
= load_reg(s
, rm
);
9128 tmp3
= tcg_temp_new_i32();
9129 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9130 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9131 tcg_temp_free_i32(tmp3
);
9132 tcg_temp_free_i32(tmp2
);
9133 store_reg(s
, rd
, tmp
);
9134 } else if ((insn
& 0x000003e0) == 0x00000060) {
9135 tmp
= load_reg(s
, rm
);
9136 shift
= (insn
>> 10) & 3;
9137 /* ??? In many cases it's not necessary to do a
9138 rotate, a shift is sufficient. */
9140 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9141 op1
= (insn
>> 20) & 7;
9143 case 0: gen_sxtb16(tmp
); break;
9144 case 2: gen_sxtb(tmp
); break;
9145 case 3: gen_sxth(tmp
); break;
9146 case 4: gen_uxtb16(tmp
); break;
9147 case 6: gen_uxtb(tmp
); break;
9148 case 7: gen_uxth(tmp
); break;
9149 default: goto illegal_op
;
9152 tmp2
= load_reg(s
, rn
);
9153 if ((op1
& 3) == 0) {
9154 gen_add16(tmp
, tmp2
);
9156 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9157 tcg_temp_free_i32(tmp2
);
9160 store_reg(s
, rd
, tmp
);
9161 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9163 tmp
= load_reg(s
, rm
);
9164 if (insn
& (1 << 22)) {
9165 if (insn
& (1 << 7)) {
9169 gen_helper_rbit(tmp
, tmp
);
9172 if (insn
& (1 << 7))
9175 tcg_gen_bswap32_i32(tmp
, tmp
);
9177 store_reg(s
, rd
, tmp
);
9182 case 2: /* Multiplies (Type 3). */
9183 switch ((insn
>> 20) & 0x7) {
9185 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9186 /* op2 not 00x or 11x : UNDEF */
9189 /* Signed multiply most significant [accumulate].
9190 (SMMUL, SMMLA, SMMLS) */
9191 tmp
= load_reg(s
, rm
);
9192 tmp2
= load_reg(s
, rs
);
9193 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9196 tmp
= load_reg(s
, rd
);
9197 if (insn
& (1 << 6)) {
9198 tmp64
= gen_subq_msw(tmp64
, tmp
);
9200 tmp64
= gen_addq_msw(tmp64
, tmp
);
9203 if (insn
& (1 << 5)) {
9204 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9206 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9207 tmp
= tcg_temp_new_i32();
9208 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9209 tcg_temp_free_i64(tmp64
);
9210 store_reg(s
, rn
, tmp
);
9214 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9215 if (insn
& (1 << 7)) {
9218 tmp
= load_reg(s
, rm
);
9219 tmp2
= load_reg(s
, rs
);
9220 if (insn
& (1 << 5))
9221 gen_swap_half(tmp2
);
9222 gen_smul_dual(tmp
, tmp2
);
9223 if (insn
& (1 << 22)) {
9224 /* smlald, smlsld */
9227 tmp64
= tcg_temp_new_i64();
9228 tmp64_2
= tcg_temp_new_i64();
9229 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9230 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9231 tcg_temp_free_i32(tmp
);
9232 tcg_temp_free_i32(tmp2
);
9233 if (insn
& (1 << 6)) {
9234 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9236 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9238 tcg_temp_free_i64(tmp64_2
);
9239 gen_addq(s
, tmp64
, rd
, rn
);
9240 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9241 tcg_temp_free_i64(tmp64
);
9243 /* smuad, smusd, smlad, smlsd */
9244 if (insn
& (1 << 6)) {
9245 /* This subtraction cannot overflow. */
9246 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9248 /* This addition cannot overflow 32 bits;
9249 * however it may overflow considered as a
9250 * signed operation, in which case we must set
9253 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9255 tcg_temp_free_i32(tmp2
);
9258 tmp2
= load_reg(s
, rd
);
9259 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9260 tcg_temp_free_i32(tmp2
);
9262 store_reg(s
, rn
, tmp
);
9268 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9271 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9274 tmp
= load_reg(s
, rm
);
9275 tmp2
= load_reg(s
, rs
);
9276 if (insn
& (1 << 21)) {
9277 gen_helper_udiv(tmp
, tmp
, tmp2
);
9279 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9281 tcg_temp_free_i32(tmp2
);
9282 store_reg(s
, rn
, tmp
);
9289 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9291 case 0: /* Unsigned sum of absolute differences. */
9293 tmp
= load_reg(s
, rm
);
9294 tmp2
= load_reg(s
, rs
);
9295 gen_helper_usad8(tmp
, tmp
, tmp2
);
9296 tcg_temp_free_i32(tmp2
);
9298 tmp2
= load_reg(s
, rd
);
9299 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9300 tcg_temp_free_i32(tmp2
);
9302 store_reg(s
, rn
, tmp
);
9304 case 0x20: case 0x24: case 0x28: case 0x2c:
9305 /* Bitfield insert/clear. */
9307 shift
= (insn
>> 7) & 0x1f;
9308 i
= (insn
>> 16) & 0x1f;
9310 /* UNPREDICTABLE; we choose to UNDEF */
9315 tmp
= tcg_temp_new_i32();
9316 tcg_gen_movi_i32(tmp
, 0);
9318 tmp
= load_reg(s
, rm
);
9321 tmp2
= load_reg(s
, rd
);
9322 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9323 tcg_temp_free_i32(tmp2
);
9325 store_reg(s
, rd
, tmp
);
9327 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9328 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9330 tmp
= load_reg(s
, rm
);
9331 shift
= (insn
>> 7) & 0x1f;
9332 i
= ((insn
>> 16) & 0x1f) + 1;
9337 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9339 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9342 store_reg(s
, rd
, tmp
);
9352 /* Check for undefined extension instructions
9353 * per the ARM Bible IE:
9354 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9356 sh
= (0xf << 20) | (0xf << 4);
9357 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9361 /* load/store byte/word */
9362 rn
= (insn
>> 16) & 0xf;
9363 rd
= (insn
>> 12) & 0xf;
9364 tmp2
= load_reg(s
, rn
);
9365 if ((insn
& 0x01200000) == 0x00200000) {
9367 i
= get_a32_user_mem_index(s
);
9369 i
= get_mem_index(s
);
9371 if (insn
& (1 << 24))
9372 gen_add_data_offset(s
, insn
, tmp2
);
9373 if (insn
& (1 << 20)) {
9375 tmp
= tcg_temp_new_i32();
9376 if (insn
& (1 << 22)) {
9377 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9379 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9383 tmp
= load_reg(s
, rd
);
9384 if (insn
& (1 << 22)) {
9385 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9387 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9389 tcg_temp_free_i32(tmp
);
9391 if (!(insn
& (1 << 24))) {
9392 gen_add_data_offset(s
, insn
, tmp2
);
9393 store_reg(s
, rn
, tmp2
);
9394 } else if (insn
& (1 << 21)) {
9395 store_reg(s
, rn
, tmp2
);
9397 tcg_temp_free_i32(tmp2
);
9399 if (insn
& (1 << 20)) {
9400 /* Complete the load. */
9401 store_reg_from_load(s
, rd
, tmp
);
9407 int j
, n
, loaded_base
;
9408 bool exc_return
= false;
9409 bool is_load
= extract32(insn
, 20, 1);
9411 TCGv_i32 loaded_var
;
9412 /* load/store multiple words */
9413 /* XXX: store correct base if write back */
9414 if (insn
& (1 << 22)) {
9415 /* LDM (user), LDM (exception return) and STM (user) */
9417 goto illegal_op
; /* only usable in supervisor mode */
9419 if (is_load
&& extract32(insn
, 15, 1)) {
9425 rn
= (insn
>> 16) & 0xf;
9426 addr
= load_reg(s
, rn
);
9428 /* compute total size */
9430 TCGV_UNUSED_I32(loaded_var
);
9433 if (insn
& (1 << i
))
9436 /* XXX: test invalid n == 0 case ? */
9437 if (insn
& (1 << 23)) {
9438 if (insn
& (1 << 24)) {
9440 tcg_gen_addi_i32(addr
, addr
, 4);
9442 /* post increment */
9445 if (insn
& (1 << 24)) {
9447 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9449 /* post decrement */
9451 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9456 if (insn
& (1 << i
)) {
9459 tmp
= tcg_temp_new_i32();
9460 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9462 tmp2
= tcg_const_i32(i
);
9463 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9464 tcg_temp_free_i32(tmp2
);
9465 tcg_temp_free_i32(tmp
);
9466 } else if (i
== rn
) {
9469 } else if (rn
== 15 && exc_return
) {
9470 store_pc_exc_ret(s
, tmp
);
9472 store_reg_from_load(s
, i
, tmp
);
9477 /* special case: r15 = PC + 8 */
9478 val
= (long)s
->pc
+ 4;
9479 tmp
= tcg_temp_new_i32();
9480 tcg_gen_movi_i32(tmp
, val
);
9482 tmp
= tcg_temp_new_i32();
9483 tmp2
= tcg_const_i32(i
);
9484 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9485 tcg_temp_free_i32(tmp2
);
9487 tmp
= load_reg(s
, i
);
9489 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9490 tcg_temp_free_i32(tmp
);
9493 /* no need to add after the last transfer */
9495 tcg_gen_addi_i32(addr
, addr
, 4);
9498 if (insn
& (1 << 21)) {
9500 if (insn
& (1 << 23)) {
9501 if (insn
& (1 << 24)) {
9504 /* post increment */
9505 tcg_gen_addi_i32(addr
, addr
, 4);
9508 if (insn
& (1 << 24)) {
9511 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9513 /* post decrement */
9514 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9517 store_reg(s
, rn
, addr
);
9519 tcg_temp_free_i32(addr
);
9522 store_reg(s
, rn
, loaded_var
);
9525 /* Restore CPSR from SPSR. */
9526 tmp
= load_cpu_field(spsr
);
9527 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9528 tcg_temp_free_i32(tmp
);
9529 /* Must exit loop to check un-masked IRQs */
9530 s
->base
.is_jmp
= DISAS_EXIT
;
9539 /* branch (and link) */
9540 val
= (int32_t)s
->pc
;
9541 if (insn
& (1 << 24)) {
9542 tmp
= tcg_temp_new_i32();
9543 tcg_gen_movi_i32(tmp
, val
);
9544 store_reg(s
, 14, tmp
);
9546 offset
= sextract32(insn
<< 2, 0, 26);
9554 if (((insn
>> 8) & 0xe) == 10) {
9556 if (disas_vfp_insn(s
, insn
)) {
9559 } else if (disas_coproc_insn(s
, insn
)) {
9566 gen_set_pc_im(s
, s
->pc
);
9567 s
->svc_imm
= extract32(insn
, 0, 24);
9568 s
->base
.is_jmp
= DISAS_SWI
;
9572 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9573 default_exception_el(s
));
9579 /* Return true if this is a Thumb-2 logical op. */
9581 thumb2_logic_op(int op
)
9586 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9587 then set condition code flags based on the result of the operation.
9588 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9589 to the high bit of T1.
9590 Returns zero if the opcode is valid. */
9593 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9594 TCGv_i32 t0
, TCGv_i32 t1
)
9601 tcg_gen_and_i32(t0
, t0
, t1
);
9605 tcg_gen_andc_i32(t0
, t0
, t1
);
9609 tcg_gen_or_i32(t0
, t0
, t1
);
9613 tcg_gen_orc_i32(t0
, t0
, t1
);
9617 tcg_gen_xor_i32(t0
, t0
, t1
);
9622 gen_add_CC(t0
, t0
, t1
);
9624 tcg_gen_add_i32(t0
, t0
, t1
);
9628 gen_adc_CC(t0
, t0
, t1
);
9634 gen_sbc_CC(t0
, t0
, t1
);
9636 gen_sub_carry(t0
, t0
, t1
);
9641 gen_sub_CC(t0
, t0
, t1
);
9643 tcg_gen_sub_i32(t0
, t0
, t1
);
9647 gen_sub_CC(t0
, t1
, t0
);
9649 tcg_gen_sub_i32(t0
, t1
, t0
);
9651 default: /* 5, 6, 7, 9, 12, 15. */
9657 gen_set_CF_bit31(t1
);
9662 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9664 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9666 uint32_t insn
, imm
, shift
, offset
;
9667 uint32_t rd
, rn
, rm
, rs
;
9678 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9679 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9680 /* Thumb-1 cores may need to treat bl and blx as a pair of
9681 16-bit instructions to get correct prefetch abort behavior. */
9683 if ((insn
& (1 << 12)) == 0) {
9685 /* Second half of blx. */
9686 offset
= ((insn
& 0x7ff) << 1);
9687 tmp
= load_reg(s
, 14);
9688 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9689 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9691 tmp2
= tcg_temp_new_i32();
9692 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9693 store_reg(s
, 14, tmp2
);
9697 if (insn
& (1 << 11)) {
9698 /* Second half of bl. */
9699 offset
= ((insn
& 0x7ff) << 1) | 1;
9700 tmp
= load_reg(s
, 14);
9701 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9703 tmp2
= tcg_temp_new_i32();
9704 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9705 store_reg(s
, 14, tmp2
);
9709 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9710 /* Instruction spans a page boundary. Implement it as two
9711 16-bit instructions in case the second half causes an
9713 offset
= ((int32_t)insn
<< 21) >> 9;
9714 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9717 /* Fall through to 32-bit decode. */
9720 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9722 insn
|= (uint32_t)insn_hw1
<< 16;
9724 if ((insn
& 0xf800e800) != 0xf000e800) {
9728 rn
= (insn
>> 16) & 0xf;
9729 rs
= (insn
>> 12) & 0xf;
9730 rd
= (insn
>> 8) & 0xf;
9732 switch ((insn
>> 25) & 0xf) {
9733 case 0: case 1: case 2: case 3:
9734 /* 16-bit instructions. Should never happen. */
9737 if (insn
& (1 << 22)) {
9738 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9739 * - load/store doubleword, load/store exclusive, ldacq/strel,
9742 if (insn
& 0x01200000) {
9743 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9744 * - load/store dual (post-indexed)
9745 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9746 * - load/store dual (literal and immediate)
9747 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9748 * - load/store dual (pre-indexed)
9751 if (insn
& (1 << 21)) {
9755 addr
= tcg_temp_new_i32();
9756 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9758 addr
= load_reg(s
, rn
);
9760 offset
= (insn
& 0xff) * 4;
9761 if ((insn
& (1 << 23)) == 0)
9763 if (insn
& (1 << 24)) {
9764 tcg_gen_addi_i32(addr
, addr
, offset
);
9767 if (insn
& (1 << 20)) {
9769 tmp
= tcg_temp_new_i32();
9770 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9771 store_reg(s
, rs
, tmp
);
9772 tcg_gen_addi_i32(addr
, addr
, 4);
9773 tmp
= tcg_temp_new_i32();
9774 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9775 store_reg(s
, rd
, tmp
);
9778 tmp
= load_reg(s
, rs
);
9779 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9780 tcg_temp_free_i32(tmp
);
9781 tcg_gen_addi_i32(addr
, addr
, 4);
9782 tmp
= load_reg(s
, rd
);
9783 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9784 tcg_temp_free_i32(tmp
);
9786 if (insn
& (1 << 21)) {
9787 /* Base writeback. */
9788 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9789 store_reg(s
, rn
, addr
);
9791 tcg_temp_free_i32(addr
);
9793 } else if ((insn
& (1 << 23)) == 0) {
9794 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9795 * - load/store exclusive word
9800 addr
= tcg_temp_local_new_i32();
9801 load_reg_var(s
, addr
, rn
);
9802 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9803 if (insn
& (1 << 20)) {
9804 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9806 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9808 tcg_temp_free_i32(addr
);
9809 } else if ((insn
& (7 << 5)) == 0) {
9812 addr
= tcg_temp_new_i32();
9813 tcg_gen_movi_i32(addr
, s
->pc
);
9815 addr
= load_reg(s
, rn
);
9817 tmp
= load_reg(s
, rm
);
9818 tcg_gen_add_i32(addr
, addr
, tmp
);
9819 if (insn
& (1 << 4)) {
9821 tcg_gen_add_i32(addr
, addr
, tmp
);
9822 tcg_temp_free_i32(tmp
);
9823 tmp
= tcg_temp_new_i32();
9824 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9826 tcg_temp_free_i32(tmp
);
9827 tmp
= tcg_temp_new_i32();
9828 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9830 tcg_temp_free_i32(addr
);
9831 tcg_gen_shli_i32(tmp
, tmp
, 1);
9832 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9833 store_reg(s
, 15, tmp
);
9835 int op2
= (insn
>> 6) & 0x3;
9836 op
= (insn
>> 4) & 0x3;
9841 /* Load/store exclusive byte/halfword/doubleword */
9848 /* Load-acquire/store-release */
9854 /* Load-acquire/store-release exclusive */
9858 addr
= tcg_temp_local_new_i32();
9859 load_reg_var(s
, addr
, rn
);
9861 if (insn
& (1 << 20)) {
9862 tmp
= tcg_temp_new_i32();
9865 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
9869 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9873 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
9879 store_reg(s
, rs
, tmp
);
9881 tmp
= load_reg(s
, rs
);
9884 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
9888 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
9892 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
9898 tcg_temp_free_i32(tmp
);
9900 } else if (insn
& (1 << 20)) {
9901 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9903 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9905 tcg_temp_free_i32(addr
);
9908 /* Load/store multiple, RFE, SRS. */
9909 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9910 /* RFE, SRS: not available in user mode or on M profile */
9911 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9914 if (insn
& (1 << 20)) {
9916 addr
= load_reg(s
, rn
);
9917 if ((insn
& (1 << 24)) == 0)
9918 tcg_gen_addi_i32(addr
, addr
, -8);
9919 /* Load PC into tmp and CPSR into tmp2. */
9920 tmp
= tcg_temp_new_i32();
9921 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9922 tcg_gen_addi_i32(addr
, addr
, 4);
9923 tmp2
= tcg_temp_new_i32();
9924 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9925 if (insn
& (1 << 21)) {
9926 /* Base writeback. */
9927 if (insn
& (1 << 24)) {
9928 tcg_gen_addi_i32(addr
, addr
, 4);
9930 tcg_gen_addi_i32(addr
, addr
, -4);
9932 store_reg(s
, rn
, addr
);
9934 tcg_temp_free_i32(addr
);
9936 gen_rfe(s
, tmp
, tmp2
);
9939 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9943 int i
, loaded_base
= 0;
9944 TCGv_i32 loaded_var
;
9945 /* Load/store multiple. */
9946 addr
= load_reg(s
, rn
);
9948 for (i
= 0; i
< 16; i
++) {
9949 if (insn
& (1 << i
))
9952 if (insn
& (1 << 24)) {
9953 tcg_gen_addi_i32(addr
, addr
, -offset
);
9956 TCGV_UNUSED_I32(loaded_var
);
9957 for (i
= 0; i
< 16; i
++) {
9958 if ((insn
& (1 << i
)) == 0)
9960 if (insn
& (1 << 20)) {
9962 tmp
= tcg_temp_new_i32();
9963 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9965 gen_bx_excret(s
, tmp
);
9966 } else if (i
== rn
) {
9970 store_reg(s
, i
, tmp
);
9974 tmp
= load_reg(s
, i
);
9975 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9976 tcg_temp_free_i32(tmp
);
9978 tcg_gen_addi_i32(addr
, addr
, 4);
9981 store_reg(s
, rn
, loaded_var
);
9983 if (insn
& (1 << 21)) {
9984 /* Base register writeback. */
9985 if (insn
& (1 << 24)) {
9986 tcg_gen_addi_i32(addr
, addr
, -offset
);
9988 /* Fault if writeback register is in register list. */
9989 if (insn
& (1 << rn
))
9991 store_reg(s
, rn
, addr
);
9993 tcg_temp_free_i32(addr
);
10000 op
= (insn
>> 21) & 0xf;
10002 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10005 /* Halfword pack. */
10006 tmp
= load_reg(s
, rn
);
10007 tmp2
= load_reg(s
, rm
);
10008 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
10009 if (insn
& (1 << 5)) {
10013 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
10014 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
10015 tcg_gen_ext16u_i32(tmp2
, tmp2
);
10019 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
10020 tcg_gen_ext16u_i32(tmp
, tmp
);
10021 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
10023 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10024 tcg_temp_free_i32(tmp2
);
10025 store_reg(s
, rd
, tmp
);
10027 /* Data processing register constant shift. */
10029 tmp
= tcg_temp_new_i32();
10030 tcg_gen_movi_i32(tmp
, 0);
10032 tmp
= load_reg(s
, rn
);
10034 tmp2
= load_reg(s
, rm
);
10036 shiftop
= (insn
>> 4) & 3;
10037 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10038 conds
= (insn
& (1 << 20)) != 0;
10039 logic_cc
= (conds
&& thumb2_logic_op(op
));
10040 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
10041 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
10043 tcg_temp_free_i32(tmp2
);
10045 store_reg(s
, rd
, tmp
);
10047 tcg_temp_free_i32(tmp
);
10051 case 13: /* Misc data processing. */
10052 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
10053 if (op
< 4 && (insn
& 0xf000) != 0xf000)
10056 case 0: /* Register controlled shift. */
10057 tmp
= load_reg(s
, rn
);
10058 tmp2
= load_reg(s
, rm
);
10059 if ((insn
& 0x70) != 0)
10061 op
= (insn
>> 21) & 3;
10062 logic_cc
= (insn
& (1 << 20)) != 0;
10063 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
10066 store_reg(s
, rd
, tmp
);
10068 case 1: /* Sign/zero extend. */
10069 op
= (insn
>> 20) & 7;
10071 case 0: /* SXTAH, SXTH */
10072 case 1: /* UXTAH, UXTH */
10073 case 4: /* SXTAB, SXTB */
10074 case 5: /* UXTAB, UXTB */
10076 case 2: /* SXTAB16, SXTB16 */
10077 case 3: /* UXTAB16, UXTB16 */
10078 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10086 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10090 tmp
= load_reg(s
, rm
);
10091 shift
= (insn
>> 4) & 3;
10092 /* ??? In many cases it's not necessary to do a
10093 rotate, a shift is sufficient. */
10095 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
10096 op
= (insn
>> 20) & 7;
10098 case 0: gen_sxth(tmp
); break;
10099 case 1: gen_uxth(tmp
); break;
10100 case 2: gen_sxtb16(tmp
); break;
10101 case 3: gen_uxtb16(tmp
); break;
10102 case 4: gen_sxtb(tmp
); break;
10103 case 5: gen_uxtb(tmp
); break;
10105 g_assert_not_reached();
10108 tmp2
= load_reg(s
, rn
);
10109 if ((op
>> 1) == 1) {
10110 gen_add16(tmp
, tmp2
);
10112 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10113 tcg_temp_free_i32(tmp2
);
10116 store_reg(s
, rd
, tmp
);
10118 case 2: /* SIMD add/subtract. */
10119 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10122 op
= (insn
>> 20) & 7;
10123 shift
= (insn
>> 4) & 7;
10124 if ((op
& 3) == 3 || (shift
& 3) == 3)
10126 tmp
= load_reg(s
, rn
);
10127 tmp2
= load_reg(s
, rm
);
10128 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10129 tcg_temp_free_i32(tmp2
);
10130 store_reg(s
, rd
, tmp
);
10132 case 3: /* Other data processing. */
10133 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10135 /* Saturating add/subtract. */
10136 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10139 tmp
= load_reg(s
, rn
);
10140 tmp2
= load_reg(s
, rm
);
10142 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10144 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10146 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10147 tcg_temp_free_i32(tmp2
);
10150 case 0x0a: /* rbit */
10151 case 0x08: /* rev */
10152 case 0x09: /* rev16 */
10153 case 0x0b: /* revsh */
10154 case 0x18: /* clz */
10156 case 0x10: /* sel */
10157 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10161 case 0x20: /* crc32/crc32c */
10167 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10174 tmp
= load_reg(s
, rn
);
10176 case 0x0a: /* rbit */
10177 gen_helper_rbit(tmp
, tmp
);
10179 case 0x08: /* rev */
10180 tcg_gen_bswap32_i32(tmp
, tmp
);
10182 case 0x09: /* rev16 */
10185 case 0x0b: /* revsh */
10188 case 0x10: /* sel */
10189 tmp2
= load_reg(s
, rm
);
10190 tmp3
= tcg_temp_new_i32();
10191 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10192 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10193 tcg_temp_free_i32(tmp3
);
10194 tcg_temp_free_i32(tmp2
);
10196 case 0x18: /* clz */
10197 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10207 uint32_t sz
= op
& 0x3;
10208 uint32_t c
= op
& 0x8;
10210 tmp2
= load_reg(s
, rm
);
10212 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10213 } else if (sz
== 1) {
10214 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10216 tmp3
= tcg_const_i32(1 << sz
);
10218 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10220 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10222 tcg_temp_free_i32(tmp2
);
10223 tcg_temp_free_i32(tmp3
);
10227 g_assert_not_reached();
10230 store_reg(s
, rd
, tmp
);
10232 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10233 switch ((insn
>> 20) & 7) {
10234 case 0: /* 32 x 32 -> 32 */
10235 case 7: /* Unsigned sum of absolute differences. */
10237 case 1: /* 16 x 16 -> 32 */
10238 case 2: /* Dual multiply add. */
10239 case 3: /* 32 * 16 -> 32msb */
10240 case 4: /* Dual multiply subtract. */
10241 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10242 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10247 op
= (insn
>> 4) & 0xf;
10248 tmp
= load_reg(s
, rn
);
10249 tmp2
= load_reg(s
, rm
);
10250 switch ((insn
>> 20) & 7) {
10251 case 0: /* 32 x 32 -> 32 */
10252 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10253 tcg_temp_free_i32(tmp2
);
10255 tmp2
= load_reg(s
, rs
);
10257 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10259 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10260 tcg_temp_free_i32(tmp2
);
10263 case 1: /* 16 x 16 -> 32 */
10264 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10265 tcg_temp_free_i32(tmp2
);
10267 tmp2
= load_reg(s
, rs
);
10268 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10269 tcg_temp_free_i32(tmp2
);
10272 case 2: /* Dual multiply add. */
10273 case 4: /* Dual multiply subtract. */
10275 gen_swap_half(tmp2
);
10276 gen_smul_dual(tmp
, tmp2
);
10277 if (insn
& (1 << 22)) {
10278 /* This subtraction cannot overflow. */
10279 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10281 /* This addition cannot overflow 32 bits;
10282 * however it may overflow considered as a signed
10283 * operation, in which case we must set the Q flag.
10285 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10287 tcg_temp_free_i32(tmp2
);
10290 tmp2
= load_reg(s
, rs
);
10291 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10292 tcg_temp_free_i32(tmp2
);
10295 case 3: /* 32 * 16 -> 32msb */
10297 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10300 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10301 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10302 tmp
= tcg_temp_new_i32();
10303 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10304 tcg_temp_free_i64(tmp64
);
10307 tmp2
= load_reg(s
, rs
);
10308 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10309 tcg_temp_free_i32(tmp2
);
10312 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10313 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10315 tmp
= load_reg(s
, rs
);
10316 if (insn
& (1 << 20)) {
10317 tmp64
= gen_addq_msw(tmp64
, tmp
);
10319 tmp64
= gen_subq_msw(tmp64
, tmp
);
10322 if (insn
& (1 << 4)) {
10323 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10325 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10326 tmp
= tcg_temp_new_i32();
10327 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10328 tcg_temp_free_i64(tmp64
);
10330 case 7: /* Unsigned sum of absolute differences. */
10331 gen_helper_usad8(tmp
, tmp
, tmp2
);
10332 tcg_temp_free_i32(tmp2
);
10334 tmp2
= load_reg(s
, rs
);
10335 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10336 tcg_temp_free_i32(tmp2
);
10340 store_reg(s
, rd
, tmp
);
10342 case 6: case 7: /* 64-bit multiply, Divide. */
10343 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10344 tmp
= load_reg(s
, rn
);
10345 tmp2
= load_reg(s
, rm
);
10346 if ((op
& 0x50) == 0x10) {
10348 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10352 gen_helper_udiv(tmp
, tmp
, tmp2
);
10354 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10355 tcg_temp_free_i32(tmp2
);
10356 store_reg(s
, rd
, tmp
);
10357 } else if ((op
& 0xe) == 0xc) {
10358 /* Dual multiply accumulate long. */
10359 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10360 tcg_temp_free_i32(tmp
);
10361 tcg_temp_free_i32(tmp2
);
10365 gen_swap_half(tmp2
);
10366 gen_smul_dual(tmp
, tmp2
);
10368 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10370 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10372 tcg_temp_free_i32(tmp2
);
10374 tmp64
= tcg_temp_new_i64();
10375 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10376 tcg_temp_free_i32(tmp
);
10377 gen_addq(s
, tmp64
, rs
, rd
);
10378 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10379 tcg_temp_free_i64(tmp64
);
10382 /* Unsigned 64-bit multiply */
10383 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10387 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10388 tcg_temp_free_i32(tmp2
);
10389 tcg_temp_free_i32(tmp
);
10392 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10393 tcg_temp_free_i32(tmp2
);
10394 tmp64
= tcg_temp_new_i64();
10395 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10396 tcg_temp_free_i32(tmp
);
10398 /* Signed 64-bit multiply */
10399 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10404 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10405 tcg_temp_free_i64(tmp64
);
10408 gen_addq_lo(s
, tmp64
, rs
);
10409 gen_addq_lo(s
, tmp64
, rd
);
10410 } else if (op
& 0x40) {
10411 /* 64-bit accumulate. */
10412 gen_addq(s
, tmp64
, rs
, rd
);
10414 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10415 tcg_temp_free_i64(tmp64
);
10420 case 6: case 7: case 14: case 15:
10422 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10423 /* We don't currently implement M profile FP support,
10424 * so this entire space should give a NOCP fault.
10426 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10427 default_exception_el(s
));
10430 if (((insn
>> 24) & 3) == 3) {
10431 /* Translate into the equivalent ARM encoding. */
10432 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10433 if (disas_neon_data_insn(s
, insn
)) {
10436 } else if (((insn
>> 8) & 0xe) == 10) {
10437 if (disas_vfp_insn(s
, insn
)) {
10441 if (insn
& (1 << 28))
10443 if (disas_coproc_insn(s
, insn
)) {
10448 case 8: case 9: case 10: case 11:
10449 if (insn
& (1 << 15)) {
10450 /* Branches, misc control. */
10451 if (insn
& 0x5000) {
10452 /* Unconditional branch. */
10453 /* signextend(hw1[10:0]) -> offset[:12]. */
10454 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10455 /* hw1[10:0] -> offset[11:1]. */
10456 offset
|= (insn
& 0x7ff) << 1;
10457 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10458 offset[24:22] already have the same value because of the
10459 sign extension above. */
10460 offset
^= ((~insn
) & (1 << 13)) << 10;
10461 offset
^= ((~insn
) & (1 << 11)) << 11;
10463 if (insn
& (1 << 14)) {
10464 /* Branch and link. */
10465 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10469 if (insn
& (1 << 12)) {
10471 gen_jmp(s
, offset
);
10474 offset
&= ~(uint32_t)2;
10475 /* thumb2 bx, no need to check */
10476 gen_bx_im(s
, offset
);
10478 } else if (((insn
>> 23) & 7) == 7) {
10480 if (insn
& (1 << 13))
10483 if (insn
& (1 << 26)) {
10484 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10487 if (!(insn
& (1 << 20))) {
10488 /* Hypervisor call (v7) */
10489 int imm16
= extract32(insn
, 16, 4) << 12
10490 | extract32(insn
, 0, 12);
10497 /* Secure monitor call (v6+) */
10505 op
= (insn
>> 20) & 7;
10507 case 0: /* msr cpsr. */
10508 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10509 tmp
= load_reg(s
, rn
);
10510 /* the constant is the mask and SYSm fields */
10511 addr
= tcg_const_i32(insn
& 0xfff);
10512 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10513 tcg_temp_free_i32(addr
);
10514 tcg_temp_free_i32(tmp
);
10519 case 1: /* msr spsr. */
10520 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10524 if (extract32(insn
, 5, 1)) {
10526 int sysm
= extract32(insn
, 8, 4) |
10527 (extract32(insn
, 4, 1) << 4);
10530 gen_msr_banked(s
, r
, sysm
, rm
);
10534 /* MSR (for PSRs) */
10535 tmp
= load_reg(s
, rn
);
10537 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10541 case 2: /* cps, nop-hint. */
10542 if (((insn
>> 8) & 7) == 0) {
10543 gen_nop_hint(s
, insn
& 0xff);
10545 /* Implemented as NOP in user mode. */
10550 if (insn
& (1 << 10)) {
10551 if (insn
& (1 << 7))
10553 if (insn
& (1 << 6))
10555 if (insn
& (1 << 5))
10557 if (insn
& (1 << 9))
10558 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10560 if (insn
& (1 << 8)) {
10562 imm
|= (insn
& 0x1f);
10565 gen_set_psr_im(s
, offset
, 0, imm
);
10568 case 3: /* Special control operations. */
10570 op
= (insn
>> 4) & 0xf;
10572 case 2: /* clrex */
10577 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10580 /* We need to break the TB after this insn
10581 * to execute self-modifying code correctly
10582 * and also to take any pending interrupts
10585 gen_goto_tb(s
, 0, s
->pc
& ~1);
10592 /* Trivial implementation equivalent to bx.
10593 * This instruction doesn't exist at all for M-profile.
10595 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10598 tmp
= load_reg(s
, rn
);
10601 case 5: /* Exception return. */
10605 if (rn
!= 14 || rd
!= 15) {
10608 tmp
= load_reg(s
, rn
);
10609 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10610 gen_exception_return(s
, tmp
);
10613 if (extract32(insn
, 5, 1) &&
10614 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10616 int sysm
= extract32(insn
, 16, 4) |
10617 (extract32(insn
, 4, 1) << 4);
10619 gen_mrs_banked(s
, 0, sysm
, rd
);
10623 if (extract32(insn
, 16, 4) != 0xf) {
10626 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10627 extract32(insn
, 0, 8) != 0) {
10632 tmp
= tcg_temp_new_i32();
10633 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10634 addr
= tcg_const_i32(insn
& 0xff);
10635 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10636 tcg_temp_free_i32(addr
);
10638 gen_helper_cpsr_read(tmp
, cpu_env
);
10640 store_reg(s
, rd
, tmp
);
10643 if (extract32(insn
, 5, 1) &&
10644 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10646 int sysm
= extract32(insn
, 16, 4) |
10647 (extract32(insn
, 4, 1) << 4);
10649 gen_mrs_banked(s
, 1, sysm
, rd
);
10654 /* Not accessible in user mode. */
10655 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10659 if (extract32(insn
, 16, 4) != 0xf ||
10660 extract32(insn
, 0, 8) != 0) {
10664 tmp
= load_cpu_field(spsr
);
10665 store_reg(s
, rd
, tmp
);
10670 /* Conditional branch. */
10671 op
= (insn
>> 22) & 0xf;
10672 /* Generate a conditional jump to next instruction. */
10673 s
->condlabel
= gen_new_label();
10674 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10677 /* offset[11:1] = insn[10:0] */
10678 offset
= (insn
& 0x7ff) << 1;
10679 /* offset[17:12] = insn[21:16]. */
10680 offset
|= (insn
& 0x003f0000) >> 4;
10681 /* offset[31:20] = insn[26]. */
10682 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10683 /* offset[18] = insn[13]. */
10684 offset
|= (insn
& (1 << 13)) << 5;
10685 /* offset[19] = insn[11]. */
10686 offset
|= (insn
& (1 << 11)) << 8;
10688 /* jump to the offset */
10689 gen_jmp(s
, s
->pc
+ offset
);
10692 /* Data processing immediate. */
10693 if (insn
& (1 << 25)) {
10694 if (insn
& (1 << 24)) {
10695 if (insn
& (1 << 20))
10697 /* Bitfield/Saturate. */
10698 op
= (insn
>> 21) & 7;
10700 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10702 tmp
= tcg_temp_new_i32();
10703 tcg_gen_movi_i32(tmp
, 0);
10705 tmp
= load_reg(s
, rn
);
10708 case 2: /* Signed bitfield extract. */
10710 if (shift
+ imm
> 32)
10713 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
10716 case 6: /* Unsigned bitfield extract. */
10718 if (shift
+ imm
> 32)
10721 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
10724 case 3: /* Bitfield insert/clear. */
10727 imm
= imm
+ 1 - shift
;
10729 tmp2
= load_reg(s
, rd
);
10730 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10731 tcg_temp_free_i32(tmp2
);
10736 default: /* Saturate. */
10739 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10741 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10743 tmp2
= tcg_const_i32(imm
);
10746 if ((op
& 1) && shift
== 0) {
10747 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10748 tcg_temp_free_i32(tmp
);
10749 tcg_temp_free_i32(tmp2
);
10752 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10754 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10758 if ((op
& 1) && shift
== 0) {
10759 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10760 tcg_temp_free_i32(tmp
);
10761 tcg_temp_free_i32(tmp2
);
10764 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10766 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10769 tcg_temp_free_i32(tmp2
);
10772 store_reg(s
, rd
, tmp
);
10774 imm
= ((insn
& 0x04000000) >> 15)
10775 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10776 if (insn
& (1 << 22)) {
10777 /* 16-bit immediate. */
10778 imm
|= (insn
>> 4) & 0xf000;
10779 if (insn
& (1 << 23)) {
10781 tmp
= load_reg(s
, rd
);
10782 tcg_gen_ext16u_i32(tmp
, tmp
);
10783 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10786 tmp
= tcg_temp_new_i32();
10787 tcg_gen_movi_i32(tmp
, imm
);
10790 /* Add/sub 12-bit immediate. */
10792 offset
= s
->pc
& ~(uint32_t)3;
10793 if (insn
& (1 << 23))
10797 tmp
= tcg_temp_new_i32();
10798 tcg_gen_movi_i32(tmp
, offset
);
10800 tmp
= load_reg(s
, rn
);
10801 if (insn
& (1 << 23))
10802 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10804 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10807 store_reg(s
, rd
, tmp
);
10810 int shifter_out
= 0;
10811 /* modified 12-bit immediate. */
10812 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10813 imm
= (insn
& 0xff);
10816 /* Nothing to do. */
10818 case 1: /* 00XY00XY */
10821 case 2: /* XY00XY00 */
10825 case 3: /* XYXYXYXY */
10829 default: /* Rotated constant. */
10830 shift
= (shift
<< 1) | (imm
>> 7);
10832 imm
= imm
<< (32 - shift
);
10836 tmp2
= tcg_temp_new_i32();
10837 tcg_gen_movi_i32(tmp2
, imm
);
10838 rn
= (insn
>> 16) & 0xf;
10840 tmp
= tcg_temp_new_i32();
10841 tcg_gen_movi_i32(tmp
, 0);
10843 tmp
= load_reg(s
, rn
);
10845 op
= (insn
>> 21) & 0xf;
10846 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10847 shifter_out
, tmp
, tmp2
))
10849 tcg_temp_free_i32(tmp2
);
10850 rd
= (insn
>> 8) & 0xf;
10852 store_reg(s
, rd
, tmp
);
10854 tcg_temp_free_i32(tmp
);
10859 case 12: /* Load/store single data item. */
10866 if ((insn
& 0x01100000) == 0x01000000) {
10867 if (disas_neon_ls_insn(s
, insn
)) {
10872 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10874 if (!(insn
& (1 << 20))) {
10878 /* Byte or halfword load space with dest == r15 : memory hints.
10879 * Catch them early so we don't emit pointless addressing code.
10880 * This space is a mix of:
10881 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10882 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10884 * unallocated hints, which must be treated as NOPs
10885 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10886 * which is easiest for the decoding logic
10887 * Some space which must UNDEF
10889 int op1
= (insn
>> 23) & 3;
10890 int op2
= (insn
>> 6) & 0x3f;
10895 /* UNPREDICTABLE, unallocated hint or
10896 * PLD/PLDW/PLI (literal)
10901 return 0; /* PLD/PLDW/PLI or unallocated hint */
10903 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10904 return 0; /* PLD/PLDW/PLI or unallocated hint */
10906 /* UNDEF space, or an UNPREDICTABLE */
10910 memidx
= get_mem_index(s
);
10912 addr
= tcg_temp_new_i32();
10914 /* s->pc has already been incremented by 4. */
10915 imm
= s
->pc
& 0xfffffffc;
10916 if (insn
& (1 << 23))
10917 imm
+= insn
& 0xfff;
10919 imm
-= insn
& 0xfff;
10920 tcg_gen_movi_i32(addr
, imm
);
10922 addr
= load_reg(s
, rn
);
10923 if (insn
& (1 << 23)) {
10924 /* Positive offset. */
10925 imm
= insn
& 0xfff;
10926 tcg_gen_addi_i32(addr
, addr
, imm
);
10929 switch ((insn
>> 8) & 0xf) {
10930 case 0x0: /* Shifted Register. */
10931 shift
= (insn
>> 4) & 0xf;
10933 tcg_temp_free_i32(addr
);
10936 tmp
= load_reg(s
, rm
);
10938 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10939 tcg_gen_add_i32(addr
, addr
, tmp
);
10940 tcg_temp_free_i32(tmp
);
10942 case 0xc: /* Negative offset. */
10943 tcg_gen_addi_i32(addr
, addr
, -imm
);
10945 case 0xe: /* User privilege. */
10946 tcg_gen_addi_i32(addr
, addr
, imm
);
10947 memidx
= get_a32_user_mem_index(s
);
10949 case 0x9: /* Post-decrement. */
10951 /* Fall through. */
10952 case 0xb: /* Post-increment. */
10956 case 0xd: /* Pre-decrement. */
10958 /* Fall through. */
10959 case 0xf: /* Pre-increment. */
10960 tcg_gen_addi_i32(addr
, addr
, imm
);
10964 tcg_temp_free_i32(addr
);
10970 issinfo
= writeback
? ISSInvalid
: rs
;
10972 if (insn
& (1 << 20)) {
10974 tmp
= tcg_temp_new_i32();
10977 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10980 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10983 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10986 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10989 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10992 tcg_temp_free_i32(tmp
);
10993 tcg_temp_free_i32(addr
);
10997 gen_bx_excret(s
, tmp
);
10999 store_reg(s
, rs
, tmp
);
11003 tmp
= load_reg(s
, rs
);
11006 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
11009 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
11012 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
11015 tcg_temp_free_i32(tmp
);
11016 tcg_temp_free_i32(addr
);
11019 tcg_temp_free_i32(tmp
);
11022 tcg_gen_addi_i32(addr
, addr
, imm
);
11024 store_reg(s
, rn
, addr
);
11026 tcg_temp_free_i32(addr
);
11038 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
11040 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
11047 if (s
->condexec_mask
) {
11048 cond
= s
->condexec_cond
;
11049 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
11050 s
->condlabel
= gen_new_label();
11051 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11056 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11059 switch (insn
>> 12) {
11063 op
= (insn
>> 11) & 3;
11066 rn
= (insn
>> 3) & 7;
11067 tmp
= load_reg(s
, rn
);
11068 if (insn
& (1 << 10)) {
11070 tmp2
= tcg_temp_new_i32();
11071 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11074 rm
= (insn
>> 6) & 7;
11075 tmp2
= load_reg(s
, rm
);
11077 if (insn
& (1 << 9)) {
11078 if (s
->condexec_mask
)
11079 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11081 gen_sub_CC(tmp
, tmp
, tmp2
);
11083 if (s
->condexec_mask
)
11084 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11086 gen_add_CC(tmp
, tmp
, tmp2
);
11088 tcg_temp_free_i32(tmp2
);
11089 store_reg(s
, rd
, tmp
);
11091 /* shift immediate */
11092 rm
= (insn
>> 3) & 7;
11093 shift
= (insn
>> 6) & 0x1f;
11094 tmp
= load_reg(s
, rm
);
11095 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11096 if (!s
->condexec_mask
)
11098 store_reg(s
, rd
, tmp
);
11102 /* arithmetic large immediate */
11103 op
= (insn
>> 11) & 3;
11104 rd
= (insn
>> 8) & 0x7;
11105 if (op
== 0) { /* mov */
11106 tmp
= tcg_temp_new_i32();
11107 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11108 if (!s
->condexec_mask
)
11110 store_reg(s
, rd
, tmp
);
11112 tmp
= load_reg(s
, rd
);
11113 tmp2
= tcg_temp_new_i32();
11114 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11117 gen_sub_CC(tmp
, tmp
, tmp2
);
11118 tcg_temp_free_i32(tmp
);
11119 tcg_temp_free_i32(tmp2
);
11122 if (s
->condexec_mask
)
11123 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11125 gen_add_CC(tmp
, tmp
, tmp2
);
11126 tcg_temp_free_i32(tmp2
);
11127 store_reg(s
, rd
, tmp
);
11130 if (s
->condexec_mask
)
11131 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11133 gen_sub_CC(tmp
, tmp
, tmp2
);
11134 tcg_temp_free_i32(tmp2
);
11135 store_reg(s
, rd
, tmp
);
11141 if (insn
& (1 << 11)) {
11142 rd
= (insn
>> 8) & 7;
11143 /* load pc-relative. Bit 1 of PC is ignored. */
11144 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11145 val
&= ~(uint32_t)2;
11146 addr
= tcg_temp_new_i32();
11147 tcg_gen_movi_i32(addr
, val
);
11148 tmp
= tcg_temp_new_i32();
11149 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11151 tcg_temp_free_i32(addr
);
11152 store_reg(s
, rd
, tmp
);
11155 if (insn
& (1 << 10)) {
11156 /* 0b0100_01xx_xxxx_xxxx
11157 * - data processing extended, branch and exchange
11159 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11160 rm
= (insn
>> 3) & 0xf;
11161 op
= (insn
>> 8) & 3;
11164 tmp
= load_reg(s
, rd
);
11165 tmp2
= load_reg(s
, rm
);
11166 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11167 tcg_temp_free_i32(tmp2
);
11168 store_reg(s
, rd
, tmp
);
11171 tmp
= load_reg(s
, rd
);
11172 tmp2
= load_reg(s
, rm
);
11173 gen_sub_CC(tmp
, tmp
, tmp2
);
11174 tcg_temp_free_i32(tmp2
);
11175 tcg_temp_free_i32(tmp
);
11177 case 2: /* mov/cpy */
11178 tmp
= load_reg(s
, rm
);
11179 store_reg(s
, rd
, tmp
);
11183 /* 0b0100_0111_xxxx_xxxx
11184 * - branch [and link] exchange thumb register
11186 bool link
= insn
& (1 << 7);
11194 tmp
= load_reg(s
, rm
);
11196 val
= (uint32_t)s
->pc
| 1;
11197 tmp2
= tcg_temp_new_i32();
11198 tcg_gen_movi_i32(tmp2
, val
);
11199 store_reg(s
, 14, tmp2
);
11202 /* Only BX works as exception-return, not BLX */
11203 gen_bx_excret(s
, tmp
);
11211 /* data processing register */
11213 rm
= (insn
>> 3) & 7;
11214 op
= (insn
>> 6) & 0xf;
11215 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11216 /* the shift/rotate ops want the operands backwards */
11225 if (op
== 9) { /* neg */
11226 tmp
= tcg_temp_new_i32();
11227 tcg_gen_movi_i32(tmp
, 0);
11228 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11229 tmp
= load_reg(s
, rd
);
11231 TCGV_UNUSED_I32(tmp
);
11234 tmp2
= load_reg(s
, rm
);
11236 case 0x0: /* and */
11237 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11238 if (!s
->condexec_mask
)
11241 case 0x1: /* eor */
11242 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11243 if (!s
->condexec_mask
)
11246 case 0x2: /* lsl */
11247 if (s
->condexec_mask
) {
11248 gen_shl(tmp2
, tmp2
, tmp
);
11250 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11251 gen_logic_CC(tmp2
);
11254 case 0x3: /* lsr */
11255 if (s
->condexec_mask
) {
11256 gen_shr(tmp2
, tmp2
, tmp
);
11258 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11259 gen_logic_CC(tmp2
);
11262 case 0x4: /* asr */
11263 if (s
->condexec_mask
) {
11264 gen_sar(tmp2
, tmp2
, tmp
);
11266 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11267 gen_logic_CC(tmp2
);
11270 case 0x5: /* adc */
11271 if (s
->condexec_mask
) {
11272 gen_adc(tmp
, tmp2
);
11274 gen_adc_CC(tmp
, tmp
, tmp2
);
11277 case 0x6: /* sbc */
11278 if (s
->condexec_mask
) {
11279 gen_sub_carry(tmp
, tmp
, tmp2
);
11281 gen_sbc_CC(tmp
, tmp
, tmp2
);
11284 case 0x7: /* ror */
11285 if (s
->condexec_mask
) {
11286 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11287 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11289 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11290 gen_logic_CC(tmp2
);
11293 case 0x8: /* tst */
11294 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11298 case 0x9: /* neg */
11299 if (s
->condexec_mask
)
11300 tcg_gen_neg_i32(tmp
, tmp2
);
11302 gen_sub_CC(tmp
, tmp
, tmp2
);
11304 case 0xa: /* cmp */
11305 gen_sub_CC(tmp
, tmp
, tmp2
);
11308 case 0xb: /* cmn */
11309 gen_add_CC(tmp
, tmp
, tmp2
);
11312 case 0xc: /* orr */
11313 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11314 if (!s
->condexec_mask
)
11317 case 0xd: /* mul */
11318 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11319 if (!s
->condexec_mask
)
11322 case 0xe: /* bic */
11323 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11324 if (!s
->condexec_mask
)
11327 case 0xf: /* mvn */
11328 tcg_gen_not_i32(tmp2
, tmp2
);
11329 if (!s
->condexec_mask
)
11330 gen_logic_CC(tmp2
);
11337 store_reg(s
, rm
, tmp2
);
11339 tcg_temp_free_i32(tmp
);
11341 store_reg(s
, rd
, tmp
);
11342 tcg_temp_free_i32(tmp2
);
11345 tcg_temp_free_i32(tmp
);
11346 tcg_temp_free_i32(tmp2
);
11351 /* load/store register offset. */
11353 rn
= (insn
>> 3) & 7;
11354 rm
= (insn
>> 6) & 7;
11355 op
= (insn
>> 9) & 7;
11356 addr
= load_reg(s
, rn
);
11357 tmp
= load_reg(s
, rm
);
11358 tcg_gen_add_i32(addr
, addr
, tmp
);
11359 tcg_temp_free_i32(tmp
);
11361 if (op
< 3) { /* store */
11362 tmp
= load_reg(s
, rd
);
11364 tmp
= tcg_temp_new_i32();
11369 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11372 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11375 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11377 case 3: /* ldrsb */
11378 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11381 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11384 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11387 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11389 case 7: /* ldrsh */
11390 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11393 if (op
>= 3) { /* load */
11394 store_reg(s
, rd
, tmp
);
11396 tcg_temp_free_i32(tmp
);
11398 tcg_temp_free_i32(addr
);
11402 /* load/store word immediate offset */
11404 rn
= (insn
>> 3) & 7;
11405 addr
= load_reg(s
, rn
);
11406 val
= (insn
>> 4) & 0x7c;
11407 tcg_gen_addi_i32(addr
, addr
, val
);
11409 if (insn
& (1 << 11)) {
11411 tmp
= tcg_temp_new_i32();
11412 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11413 store_reg(s
, rd
, tmp
);
11416 tmp
= load_reg(s
, rd
);
11417 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11418 tcg_temp_free_i32(tmp
);
11420 tcg_temp_free_i32(addr
);
11424 /* load/store byte immediate offset */
11426 rn
= (insn
>> 3) & 7;
11427 addr
= load_reg(s
, rn
);
11428 val
= (insn
>> 6) & 0x1f;
11429 tcg_gen_addi_i32(addr
, addr
, val
);
11431 if (insn
& (1 << 11)) {
11433 tmp
= tcg_temp_new_i32();
11434 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11435 store_reg(s
, rd
, tmp
);
11438 tmp
= load_reg(s
, rd
);
11439 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11440 tcg_temp_free_i32(tmp
);
11442 tcg_temp_free_i32(addr
);
11446 /* load/store halfword immediate offset */
11448 rn
= (insn
>> 3) & 7;
11449 addr
= load_reg(s
, rn
);
11450 val
= (insn
>> 5) & 0x3e;
11451 tcg_gen_addi_i32(addr
, addr
, val
);
11453 if (insn
& (1 << 11)) {
11455 tmp
= tcg_temp_new_i32();
11456 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11457 store_reg(s
, rd
, tmp
);
11460 tmp
= load_reg(s
, rd
);
11461 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11462 tcg_temp_free_i32(tmp
);
11464 tcg_temp_free_i32(addr
);
11468 /* load/store from stack */
11469 rd
= (insn
>> 8) & 7;
11470 addr
= load_reg(s
, 13);
11471 val
= (insn
& 0xff) * 4;
11472 tcg_gen_addi_i32(addr
, addr
, val
);
11474 if (insn
& (1 << 11)) {
11476 tmp
= tcg_temp_new_i32();
11477 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11478 store_reg(s
, rd
, tmp
);
11481 tmp
= load_reg(s
, rd
);
11482 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11483 tcg_temp_free_i32(tmp
);
11485 tcg_temp_free_i32(addr
);
11489 /* add to high reg */
11490 rd
= (insn
>> 8) & 7;
11491 if (insn
& (1 << 11)) {
11493 tmp
= load_reg(s
, 13);
11495 /* PC. bit 1 is ignored. */
11496 tmp
= tcg_temp_new_i32();
11497 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11499 val
= (insn
& 0xff) * 4;
11500 tcg_gen_addi_i32(tmp
, tmp
, val
);
11501 store_reg(s
, rd
, tmp
);
11506 op
= (insn
>> 8) & 0xf;
11509 /* adjust stack pointer */
11510 tmp
= load_reg(s
, 13);
11511 val
= (insn
& 0x7f) * 4;
11512 if (insn
& (1 << 7))
11513 val
= -(int32_t)val
;
11514 tcg_gen_addi_i32(tmp
, tmp
, val
);
11515 store_reg(s
, 13, tmp
);
11518 case 2: /* sign/zero extend. */
11521 rm
= (insn
>> 3) & 7;
11522 tmp
= load_reg(s
, rm
);
11523 switch ((insn
>> 6) & 3) {
11524 case 0: gen_sxth(tmp
); break;
11525 case 1: gen_sxtb(tmp
); break;
11526 case 2: gen_uxth(tmp
); break;
11527 case 3: gen_uxtb(tmp
); break;
11529 store_reg(s
, rd
, tmp
);
11531 case 4: case 5: case 0xc: case 0xd:
11533 addr
= load_reg(s
, 13);
11534 if (insn
& (1 << 8))
11538 for (i
= 0; i
< 8; i
++) {
11539 if (insn
& (1 << i
))
11542 if ((insn
& (1 << 11)) == 0) {
11543 tcg_gen_addi_i32(addr
, addr
, -offset
);
11545 for (i
= 0; i
< 8; i
++) {
11546 if (insn
& (1 << i
)) {
11547 if (insn
& (1 << 11)) {
11549 tmp
= tcg_temp_new_i32();
11550 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11551 store_reg(s
, i
, tmp
);
11554 tmp
= load_reg(s
, i
);
11555 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11556 tcg_temp_free_i32(tmp
);
11558 /* advance to the next address. */
11559 tcg_gen_addi_i32(addr
, addr
, 4);
11562 TCGV_UNUSED_I32(tmp
);
11563 if (insn
& (1 << 8)) {
11564 if (insn
& (1 << 11)) {
11566 tmp
= tcg_temp_new_i32();
11567 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11568 /* don't set the pc until the rest of the instruction
11572 tmp
= load_reg(s
, 14);
11573 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11574 tcg_temp_free_i32(tmp
);
11576 tcg_gen_addi_i32(addr
, addr
, 4);
11578 if ((insn
& (1 << 11)) == 0) {
11579 tcg_gen_addi_i32(addr
, addr
, -offset
);
11581 /* write back the new stack pointer */
11582 store_reg(s
, 13, addr
);
11583 /* set the new PC value */
11584 if ((insn
& 0x0900) == 0x0900) {
11585 store_reg_from_load(s
, 15, tmp
);
11589 case 1: case 3: case 9: case 11: /* czb */
11591 tmp
= load_reg(s
, rm
);
11592 s
->condlabel
= gen_new_label();
11594 if (insn
& (1 << 11))
11595 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11597 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11598 tcg_temp_free_i32(tmp
);
11599 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11600 val
= (uint32_t)s
->pc
+ 2;
11605 case 15: /* IT, nop-hint. */
11606 if ((insn
& 0xf) == 0) {
11607 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11611 s
->condexec_cond
= (insn
>> 4) & 0xe;
11612 s
->condexec_mask
= insn
& 0x1f;
11613 /* No actual code generated for this insn, just setup state. */
11616 case 0xe: /* bkpt */
11618 int imm8
= extract32(insn
, 0, 8);
11620 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11621 default_exception_el(s
));
11625 case 0xa: /* rev, and hlt */
11627 int op1
= extract32(insn
, 6, 2);
11631 int imm6
= extract32(insn
, 0, 6);
11637 /* Otherwise this is rev */
11639 rn
= (insn
>> 3) & 0x7;
11641 tmp
= load_reg(s
, rn
);
11643 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11644 case 1: gen_rev16(tmp
); break;
11645 case 3: gen_revsh(tmp
); break;
11647 g_assert_not_reached();
11649 store_reg(s
, rd
, tmp
);
11654 switch ((insn
>> 5) & 7) {
11658 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11659 gen_helper_setend(cpu_env
);
11660 s
->base
.is_jmp
= DISAS_UPDATE
;
11669 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11670 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11673 addr
= tcg_const_i32(19);
11674 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11675 tcg_temp_free_i32(addr
);
11679 addr
= tcg_const_i32(16);
11680 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11681 tcg_temp_free_i32(addr
);
11683 tcg_temp_free_i32(tmp
);
11686 if (insn
& (1 << 4)) {
11687 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11691 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11706 /* load/store multiple */
11707 TCGv_i32 loaded_var
;
11708 TCGV_UNUSED_I32(loaded_var
);
11709 rn
= (insn
>> 8) & 0x7;
11710 addr
= load_reg(s
, rn
);
11711 for (i
= 0; i
< 8; i
++) {
11712 if (insn
& (1 << i
)) {
11713 if (insn
& (1 << 11)) {
11715 tmp
= tcg_temp_new_i32();
11716 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11720 store_reg(s
, i
, tmp
);
11724 tmp
= load_reg(s
, i
);
11725 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11726 tcg_temp_free_i32(tmp
);
11728 /* advance to the next address */
11729 tcg_gen_addi_i32(addr
, addr
, 4);
11732 if ((insn
& (1 << rn
)) == 0) {
11733 /* base reg not in list: base register writeback */
11734 store_reg(s
, rn
, addr
);
11736 /* base reg in list: if load, complete it now */
11737 if (insn
& (1 << 11)) {
11738 store_reg(s
, rn
, loaded_var
);
11740 tcg_temp_free_i32(addr
);
11745 /* conditional branch or swi */
11746 cond
= (insn
>> 8) & 0xf;
11752 gen_set_pc_im(s
, s
->pc
);
11753 s
->svc_imm
= extract32(insn
, 0, 8);
11754 s
->base
.is_jmp
= DISAS_SWI
;
11757 /* generate a conditional jump to next instruction */
11758 s
->condlabel
= gen_new_label();
11759 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11762 /* jump to the offset */
11763 val
= (uint32_t)s
->pc
+ 2;
11764 offset
= ((int32_t)insn
<< 24) >> 24;
11765 val
+= offset
<< 1;
11770 if (insn
& (1 << 11)) {
11771 if (disas_thumb2_insn(env
, s
, insn
))
11775 /* unconditional branch */
11776 val
= (uint32_t)s
->pc
;
11777 offset
= ((int32_t)insn
<< 21) >> 21;
11778 val
+= (offset
<< 1) + 2;
11783 if (disas_thumb2_insn(env
, s
, insn
))
11789 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11790 default_exception_el(s
));
11794 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11795 default_exception_el(s
));
11798 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11800 /* Return true if the insn at dc->pc might cross a page boundary.
11801 * (False positives are OK, false negatives are not.)
11805 if ((s
->pc
& 3) == 0) {
11806 /* At a 4-aligned address we can't be crossing a page */
11810 /* This must be a Thumb insn */
11811 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11813 if ((insn
>> 11) >= 0x1d) {
11814 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11815 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11816 * end up actually treating this as two 16-bit insns (see the
11817 * code at the start of disas_thumb2_insn()) but we don't bother
11818 * to check for that as it is unlikely, and false positives here
11823 /* Definitely a 16-bit insn, can't be crossing a page. */
11827 static int arm_tr_init_disas_context(DisasContextBase
*dcbase
,
11828 CPUState
*cs
, int max_insns
)
11830 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11831 CPUARMState
*env
= cs
->env_ptr
;
11832 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11834 dc
->pc
= dc
->base
.pc_first
;
11838 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11839 * there is no secure EL1, so we route exceptions to EL3.
11841 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11842 !arm_el_is_aa64(env
, 3);
11843 dc
->thumb
= ARM_TBFLAG_THUMB(dc
->base
.tb
->flags
);
11844 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(dc
->base
.tb
->flags
);
11845 dc
->be_data
= ARM_TBFLAG_BE_DATA(dc
->base
.tb
->flags
) ? MO_BE
: MO_LE
;
11846 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) & 0xf) << 1;
11847 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(dc
->base
.tb
->flags
) >> 4;
11848 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, ARM_TBFLAG_MMUIDX(dc
->base
.tb
->flags
));
11849 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11850 #if !defined(CONFIG_USER_ONLY)
11851 dc
->user
= (dc
->current_el
== 0);
11853 dc
->ns
= ARM_TBFLAG_NS(dc
->base
.tb
->flags
);
11854 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(dc
->base
.tb
->flags
);
11855 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(dc
->base
.tb
->flags
);
11856 dc
->vec_len
= ARM_TBFLAG_VECLEN(dc
->base
.tb
->flags
);
11857 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(dc
->base
.tb
->flags
);
11858 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(dc
->base
.tb
->flags
);
11859 dc
->v7m_handler_mode
= ARM_TBFLAG_HANDLER(dc
->base
.tb
->flags
);
11860 dc
->cp_regs
= cpu
->cp_regs
;
11861 dc
->features
= env
->features
;
11863 /* Single step state. The code-generation logic here is:
11865 * generate code with no special handling for single-stepping (except
11866 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11867 * this happens anyway because those changes are all system register or
11869 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11870 * emit code for one insn
11871 * emit code to clear PSTATE.SS
11872 * emit code to generate software step exception for completed step
11873 * end TB (as usual for having generated an exception)
11874 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11875 * emit code to generate a software step exception
11878 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(dc
->base
.tb
->flags
);
11879 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(dc
->base
.tb
->flags
);
11880 dc
->is_ldex
= false;
11881 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11884 cpu_F0s
= tcg_temp_new_i32();
11885 cpu_F1s
= tcg_temp_new_i32();
11886 cpu_F0d
= tcg_temp_new_i64();
11887 cpu_F1d
= tcg_temp_new_i64();
11890 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11891 cpu_M0
= tcg_temp_new_i64();
11896 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
11898 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11900 /* A note on handling of the condexec (IT) bits:
11902 * We want to avoid the overhead of having to write the updated condexec
11903 * bits back to the CPUARMState for every instruction in an IT block. So:
11904 * (1) if the condexec bits are not already zero then we write
11905 * zero back into the CPUARMState now. This avoids complications trying
11906 * to do it at the end of the block. (For example if we don't do this
11907 * it's hard to identify whether we can safely skip writing condexec
11908 * at the end of the TB, which we definitely want to do for the case
11909 * where a TB doesn't do anything with the IT state at all.)
11910 * (2) if we are going to leave the TB then we call gen_set_condexec()
11911 * which will write the correct value into CPUARMState if zero is wrong.
11912 * This is done both for leaving the TB at the end, and for leaving
11913 * it because of an exception we know will happen, which is done in
11914 * gen_exception_insn(). The latter is necessary because we need to
11915 * leave the TB with the PC/IT state just prior to execution of the
11916 * instruction which caused the exception.
11917 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11918 * then the CPUARMState will be wrong and we need to reset it.
11919 * This is handled in the same way as restoration of the
11920 * PC in these situations; we save the value of the condexec bits
11921 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11922 * then uses this to restore them after an exception.
11924 * Note that there are no instructions which can read the condexec
11925 * bits, and none which can write non-static values to them, so
11926 * we don't need to care about whether CPUARMState is correct in the
11930 /* Reset the conditional execution bits immediately. This avoids
11931 complications trying to do it at the end of the block. */
11932 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
11933 TCGv_i32 tmp
= tcg_temp_new_i32();
11934 tcg_gen_movi_i32(tmp
, 0);
11935 store_cpu_field(tmp
, condexec_bits
);
11939 /* generate intermediate code for basic block 'tb'. */
11940 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
)
11942 CPUARMState
*env
= cs
->env_ptr
;
11943 DisasContext dc1
, *dc
= &dc1
;
11944 target_ulong next_page_start
;
11948 /* generate intermediate code */
11950 /* The A64 decoder has its own top level loop, because it doesn't need
11951 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11953 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11954 gen_intermediate_code_a64(&dc
->base
, cs
, tb
);
11959 dc
->base
.pc_first
= dc
->base
.tb
->pc
;
11960 dc
->base
.pc_next
= dc
->base
.pc_first
;
11961 dc
->base
.is_jmp
= DISAS_NEXT
;
11962 dc
->base
.num_insns
= 0;
11963 dc
->base
.singlestep_enabled
= cs
->singlestep_enabled
;
11965 next_page_start
= (dc
->base
.pc_first
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11966 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11967 if (max_insns
== 0) {
11968 max_insns
= CF_COUNT_MASK
;
11970 if (max_insns
> TCG_MAX_INSNS
) {
11971 max_insns
= TCG_MAX_INSNS
;
11973 max_insns
= arm_tr_init_disas_context(&dc
->base
, cs
, max_insns
);
11977 tcg_clear_temp_count();
11978 arm_tr_tb_start(&dc
->base
, cs
);
11981 dc
->base
.num_insns
++;
11982 dc
->insn_start_idx
= tcg_op_buf_count();
11983 tcg_gen_insn_start(dc
->pc
,
11984 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11987 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11989 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11990 if (bp
->pc
== dc
->pc
) {
11991 if (bp
->flags
& BP_CPU
) {
11992 gen_set_condexec(dc
);
11993 gen_set_pc_im(dc
, dc
->pc
);
11994 gen_helper_check_breakpoints(cpu_env
);
11995 /* End the TB early; it's likely not going to be executed */
11996 dc
->base
.is_jmp
= DISAS_UPDATE
;
11998 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11999 /* The address covered by the breakpoint must be
12000 included in [tb->pc, tb->pc + tb->size) in order
12001 to for it to be properly cleared -- thus we
12002 increment the PC here so that the logic setting
12003 tb->size below does the right thing. */
12004 /* TODO: Advance PC by correct instruction length to
12005 * avoid disassembler error messages */
12007 goto done_generating
;
12014 if (dc
->base
.num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
12018 #ifdef CONFIG_USER_ONLY
12019 /* Intercept jump to the magic kernel page. */
12020 if (dc
->pc
>= 0xffff0000) {
12021 /* We always get here via a jump, so know we are not in a
12022 conditional execution block. */
12023 gen_exception_internal(EXCP_KERNEL_TRAP
);
12024 dc
->base
.is_jmp
= DISAS_NORETURN
;
12029 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12030 /* Singlestep state is Active-pending.
12031 * If we're in this state at the start of a TB then either
12032 * a) we just took an exception to an EL which is being debugged
12033 * and this is the first insn in the exception handler
12034 * b) debug exceptions were masked and we just unmasked them
12035 * without changing EL (eg by clearing PSTATE.D)
12036 * In either case we're going to take a swstep exception in the
12037 * "did not step an insn" case, and so the syndrome ISV and EX
12038 * bits should be zero.
12040 assert(dc
->base
.num_insns
== 1);
12041 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
12042 default_exception_el(dc
));
12043 dc
->base
.is_jmp
= DISAS_NORETURN
;
12048 disas_thumb_insn(env
, dc
);
12049 if (dc
->condexec_mask
) {
12050 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
12051 | ((dc
->condexec_mask
>> 4) & 1);
12052 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12053 if (dc
->condexec_mask
== 0) {
12054 dc
->condexec_cond
= 0;
12058 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12060 disas_arm_insn(dc
, insn
);
12063 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12064 gen_set_label(dc
->condlabel
);
12068 if (tcg_check_temp_count()) {
12069 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
12073 /* Translation stops when a conditional branch is encountered.
12074 * Otherwise the subsequent code could get translated several times.
12075 * Also stop translation when a page boundary is reached. This
12076 * ensures prefetch aborts occur at the right place. */
12078 /* We want to stop the TB if the next insn starts in a new page,
12079 * or if it spans between this page and the next. This means that
12080 * if we're looking at the last halfword in the page we need to
12081 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12082 * or a 32-bit Thumb insn (which won't).
12083 * This is to avoid generating a silly TB with a single 16-bit insn
12084 * in it at the end of this page (which would execute correctly
12085 * but isn't very efficient).
12087 end_of_page
= (dc
->pc
>= next_page_start
) ||
12088 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
12090 } while (!dc
->base
.is_jmp
&& !tcg_op_buf_full() &&
12091 !is_singlestepping(dc
) &&
12094 dc
->base
.num_insns
< max_insns
);
12096 if (tb
->cflags
& CF_LAST_IO
) {
12098 /* FIXME: This can theoretically happen with self-modifying
12100 cpu_abort(cs
, "IO on conditional branch instruction");
12105 /* At this stage dc->condjmp will only be set when the skipped
12106 instruction was a conditional branch or trap, and the PC has
12107 already been written. */
12108 gen_set_condexec(dc
);
12109 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12110 /* Exception return branches need some special case code at the
12111 * end of the TB, which is complex enough that it has to
12112 * handle the single-step vs not and the condition-failed
12113 * insn codepath itself.
12115 gen_bx_excret_final_code(dc
);
12116 } else if (unlikely(is_singlestepping(dc
))) {
12117 /* Unconditional and "condition passed" instruction codepath. */
12118 switch (dc
->base
.is_jmp
) {
12120 gen_ss_advance(dc
);
12121 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12122 default_exception_el(dc
));
12125 gen_ss_advance(dc
);
12126 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12129 gen_ss_advance(dc
);
12130 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12134 gen_set_pc_im(dc
, dc
->pc
);
12137 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12138 gen_singlestep_exception(dc
);
12140 case DISAS_NORETURN
:
12144 /* While branches must always occur at the end of an IT block,
12145 there are a few other things that can cause us to terminate
12146 the TB in the middle of an IT block:
12147 - Exception generating instructions (bkpt, swi, undefined).
12149 - Hardware watchpoints.
12150 Hardware breakpoints have already been handled and skip this code.
12152 switch(dc
->base
.is_jmp
) {
12154 gen_goto_tb(dc
, 1, dc
->pc
);
12160 gen_set_pc_im(dc
, dc
->pc
);
12163 /* indicate that the hash table must be used to find the next TB */
12164 tcg_gen_exit_tb(0);
12166 case DISAS_NORETURN
:
12167 /* nothing more to generate */
12170 gen_helper_wfi(cpu_env
);
12171 /* The helper doesn't necessarily throw an exception, but we
12172 * must go back to the main loop to check for interrupts anyway.
12174 tcg_gen_exit_tb(0);
12177 gen_helper_wfe(cpu_env
);
12180 gen_helper_yield(cpu_env
);
12183 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12184 default_exception_el(dc
));
12187 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12190 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12196 /* "Condition failed" instruction codepath for the branch/trap insn */
12197 gen_set_label(dc
->condlabel
);
12198 gen_set_condexec(dc
);
12199 if (unlikely(is_singlestepping(dc
))) {
12200 gen_set_pc_im(dc
, dc
->pc
);
12201 gen_singlestep_exception(dc
);
12203 gen_goto_tb(dc
, 1, dc
->pc
);
12208 gen_tb_end(tb
, dc
->base
.num_insns
);
12211 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
) &&
12212 qemu_log_in_addr_range(dc
->base
.pc_first
)) {
12214 qemu_log("----------------\n");
12215 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
12216 log_target_disas(cs
, dc
->base
.pc_first
, dc
->pc
- dc
->base
.pc_first
,
12217 dc
->thumb
| (dc
->sctlr_b
<< 1));
12222 tb
->size
= dc
->pc
- dc
->base
.pc_first
;
12223 tb
->icount
= dc
->base
.num_insns
;
12226 static const char *cpu_mode_names
[16] = {
12227 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12228 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12231 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12234 ARMCPU
*cpu
= ARM_CPU(cs
);
12235 CPUARMState
*env
= &cpu
->env
;
12239 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12243 for(i
=0;i
<16;i
++) {
12244 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12246 cpu_fprintf(f
, "\n");
12248 cpu_fprintf(f
, " ");
12251 if (arm_feature(env
, ARM_FEATURE_M
)) {
12252 uint32_t xpsr
= xpsr_read(env
);
12255 if (xpsr
& XPSR_EXCP
) {
12258 if (env
->v7m
.control
& R_V7M_CONTROL_NPRIV_MASK
) {
12259 mode
= "unpriv-thread";
12261 mode
= "priv-thread";
12265 cpu_fprintf(f
, "XPSR=%08x %c%c%c%c %c %s\n",
12267 xpsr
& XPSR_N
? 'N' : '-',
12268 xpsr
& XPSR_Z
? 'Z' : '-',
12269 xpsr
& XPSR_C
? 'C' : '-',
12270 xpsr
& XPSR_V
? 'V' : '-',
12271 xpsr
& XPSR_T
? 'T' : 'A',
12274 uint32_t psr
= cpsr_read(env
);
12275 const char *ns_status
= "";
12277 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12278 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12279 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12282 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12284 psr
& CPSR_N
? 'N' : '-',
12285 psr
& CPSR_Z
? 'Z' : '-',
12286 psr
& CPSR_C
? 'C' : '-',
12287 psr
& CPSR_V
? 'V' : '-',
12288 psr
& CPSR_T
? 'T' : 'A',
12290 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12293 if (flags
& CPU_DUMP_FPU
) {
12294 int numvfpregs
= 0;
12295 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12298 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12301 for (i
= 0; i
< numvfpregs
; i
++) {
12302 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12303 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12304 i
* 2, (uint32_t)v
,
12305 i
* 2 + 1, (uint32_t)(v
>> 32),
12308 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12312 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12313 target_ulong
*data
)
12317 env
->condexec_bits
= 0;
12318 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12320 env
->regs
[15] = data
[0];
12321 env
->condexec_bits
= data
[1];
12322 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;