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"
32 #include "exec/helper-proto.h"
33 #include "exec/helper-gen.h"
35 #include "trace-tcg.h"
39 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
40 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
41 /* currently all emulated v5 cores are also v5TE, so don't bother */
42 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
43 #define ENABLE_ARCH_5J 0
44 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
45 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
46 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
47 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
48 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
50 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
52 #include "translate.h"
54 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) (s->user)
61 /* We reuse the same 64-bit temporaries for efficiency. */
62 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
63 static TCGv_i32 cpu_R
[16];
64 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
65 TCGv_i64 cpu_exclusive_addr
;
66 TCGv_i64 cpu_exclusive_val
;
67 #ifdef CONFIG_USER_ONLY
68 TCGv_i64 cpu_exclusive_test
;
69 TCGv_i32 cpu_exclusive_info
;
72 /* FIXME: These should be removed. */
73 static TCGv_i32 cpu_F0s
, cpu_F1s
;
74 static TCGv_i64 cpu_F0d
, cpu_F1d
;
76 #include "exec/gen-icount.h"
78 static const char *regnames
[] =
79 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
80 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
82 /* initialize TCG globals. */
83 void arm_translate_init(void)
87 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
88 tcg_ctx
.tcg_env
= cpu_env
;
90 for (i
= 0; i
< 16; i
++) {
91 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
92 offsetof(CPUARMState
, regs
[i
]),
95 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
96 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
97 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
98 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
100 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
101 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
102 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
103 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
104 #ifdef CONFIG_USER_ONLY
105 cpu_exclusive_test
= tcg_global_mem_new_i64(cpu_env
,
106 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
107 cpu_exclusive_info
= tcg_global_mem_new_i32(cpu_env
,
108 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
111 a64_translate_init();
114 static inline ARMMMUIdx
get_a32_user_mem_index(DisasContext
*s
)
116 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
118 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
119 * otherwise, access as if at PL0.
121 switch (s
->mmu_idx
) {
122 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
123 case ARMMMUIdx_S12NSE0
:
124 case ARMMMUIdx_S12NSE1
:
125 return ARMMMUIdx_S12NSE0
;
127 case ARMMMUIdx_S1SE0
:
128 case ARMMMUIdx_S1SE1
:
129 return ARMMMUIdx_S1SE0
;
132 g_assert_not_reached();
136 static inline TCGv_i32
load_cpu_offset(int offset
)
138 TCGv_i32 tmp
= tcg_temp_new_i32();
139 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
143 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
145 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
147 tcg_gen_st_i32(var
, cpu_env
, offset
);
148 tcg_temp_free_i32(var
);
151 #define store_cpu_field(var, name) \
152 store_cpu_offset(var, offsetof(CPUARMState, name))
154 /* Set a variable to the value of a CPU register. */
155 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
159 /* normally, since we updated PC, we need only to add one insn */
161 addr
= (long)s
->pc
+ 2;
163 addr
= (long)s
->pc
+ 4;
164 tcg_gen_movi_i32(var
, addr
);
166 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
170 /* Create a new temporary and set it to the value of a CPU register. */
171 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
173 TCGv_i32 tmp
= tcg_temp_new_i32();
174 load_reg_var(s
, tmp
, reg
);
178 /* Set a CPU register. The source must be a temporary and will be
180 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
183 tcg_gen_andi_i32(var
, var
, ~1);
184 s
->is_jmp
= DISAS_JUMP
;
186 tcg_gen_mov_i32(cpu_R
[reg
], var
);
187 tcg_temp_free_i32(var
);
190 /* Value extensions. */
191 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
192 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
193 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
194 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
196 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
197 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
200 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
202 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
203 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
204 tcg_temp_free_i32(tmp_mask
);
206 /* Set NZCV flags from the high 4 bits of var. */
207 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
209 static void gen_exception_internal(int excp
)
211 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
213 assert(excp_is_internal(excp
));
214 gen_helper_exception_internal(cpu_env
, tcg_excp
);
215 tcg_temp_free_i32(tcg_excp
);
218 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
220 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
221 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
222 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
224 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
227 tcg_temp_free_i32(tcg_el
);
228 tcg_temp_free_i32(tcg_syn
);
229 tcg_temp_free_i32(tcg_excp
);
232 static void gen_ss_advance(DisasContext
*s
)
234 /* If the singlestep state is Active-not-pending, advance to
239 gen_helper_clear_pstate_ss(cpu_env
);
243 static void gen_step_complete_exception(DisasContext
*s
)
245 /* We just completed step of an insn. Move from Active-not-pending
246 * to Active-pending, and then also take the swstep exception.
247 * This corresponds to making the (IMPDEF) choice to prioritize
248 * swstep exceptions over asynchronous exceptions taken to an exception
249 * level where debug is disabled. This choice has the advantage that
250 * we do not need to maintain internal state corresponding to the
251 * ISV/EX syndrome bits between completion of the step and generation
252 * of the exception, and our syndrome information is always correct.
255 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
256 default_exception_el(s
));
257 s
->is_jmp
= DISAS_EXC
;
260 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
262 TCGv_i32 tmp1
= tcg_temp_new_i32();
263 TCGv_i32 tmp2
= tcg_temp_new_i32();
264 tcg_gen_ext16s_i32(tmp1
, a
);
265 tcg_gen_ext16s_i32(tmp2
, b
);
266 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
267 tcg_temp_free_i32(tmp2
);
268 tcg_gen_sari_i32(a
, a
, 16);
269 tcg_gen_sari_i32(b
, b
, 16);
270 tcg_gen_mul_i32(b
, b
, a
);
271 tcg_gen_mov_i32(a
, tmp1
);
272 tcg_temp_free_i32(tmp1
);
275 /* Byteswap each halfword. */
276 static void gen_rev16(TCGv_i32 var
)
278 TCGv_i32 tmp
= tcg_temp_new_i32();
279 tcg_gen_shri_i32(tmp
, var
, 8);
280 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
281 tcg_gen_shli_i32(var
, var
, 8);
282 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
283 tcg_gen_or_i32(var
, var
, tmp
);
284 tcg_temp_free_i32(tmp
);
287 /* Byteswap low halfword and sign extend. */
288 static void gen_revsh(TCGv_i32 var
)
290 tcg_gen_ext16u_i32(var
, var
);
291 tcg_gen_bswap16_i32(var
, var
);
292 tcg_gen_ext16s_i32(var
, var
);
295 /* Unsigned bitfield extract. */
296 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
299 tcg_gen_shri_i32(var
, var
, shift
);
300 tcg_gen_andi_i32(var
, var
, mask
);
303 /* Signed bitfield extract. */
304 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
309 tcg_gen_sari_i32(var
, var
, shift
);
310 if (shift
+ width
< 32) {
311 signbit
= 1u << (width
- 1);
312 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
313 tcg_gen_xori_i32(var
, var
, signbit
);
314 tcg_gen_subi_i32(var
, var
, signbit
);
318 /* Return (b << 32) + a. Mark inputs as dead */
319 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
321 TCGv_i64 tmp64
= tcg_temp_new_i64();
323 tcg_gen_extu_i32_i64(tmp64
, b
);
324 tcg_temp_free_i32(b
);
325 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
326 tcg_gen_add_i64(a
, tmp64
, a
);
328 tcg_temp_free_i64(tmp64
);
332 /* Return (b << 32) - a. Mark inputs as dead. */
333 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
335 TCGv_i64 tmp64
= tcg_temp_new_i64();
337 tcg_gen_extu_i32_i64(tmp64
, b
);
338 tcg_temp_free_i32(b
);
339 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
340 tcg_gen_sub_i64(a
, tmp64
, a
);
342 tcg_temp_free_i64(tmp64
);
346 /* 32x32->64 multiply. Marks inputs as dead. */
347 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
349 TCGv_i32 lo
= tcg_temp_new_i32();
350 TCGv_i32 hi
= tcg_temp_new_i32();
353 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
354 tcg_temp_free_i32(a
);
355 tcg_temp_free_i32(b
);
357 ret
= tcg_temp_new_i64();
358 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
359 tcg_temp_free_i32(lo
);
360 tcg_temp_free_i32(hi
);
365 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
367 TCGv_i32 lo
= tcg_temp_new_i32();
368 TCGv_i32 hi
= tcg_temp_new_i32();
371 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
372 tcg_temp_free_i32(a
);
373 tcg_temp_free_i32(b
);
375 ret
= tcg_temp_new_i64();
376 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
377 tcg_temp_free_i32(lo
);
378 tcg_temp_free_i32(hi
);
383 /* Swap low and high halfwords. */
384 static void gen_swap_half(TCGv_i32 var
)
386 TCGv_i32 tmp
= tcg_temp_new_i32();
387 tcg_gen_shri_i32(tmp
, var
, 16);
388 tcg_gen_shli_i32(var
, var
, 16);
389 tcg_gen_or_i32(var
, var
, tmp
);
390 tcg_temp_free_i32(tmp
);
393 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
394 tmp = (t0 ^ t1) & 0x8000;
397 t0 = (t0 + t1) ^ tmp;
400 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
402 TCGv_i32 tmp
= tcg_temp_new_i32();
403 tcg_gen_xor_i32(tmp
, t0
, t1
);
404 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
405 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
406 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
407 tcg_gen_add_i32(t0
, t0
, t1
);
408 tcg_gen_xor_i32(t0
, t0
, tmp
);
409 tcg_temp_free_i32(tmp
);
410 tcg_temp_free_i32(t1
);
413 /* Set CF to the top bit of var. */
414 static void gen_set_CF_bit31(TCGv_i32 var
)
416 tcg_gen_shri_i32(cpu_CF
, var
, 31);
419 /* Set N and Z flags from var. */
420 static inline void gen_logic_CC(TCGv_i32 var
)
422 tcg_gen_mov_i32(cpu_NF
, var
);
423 tcg_gen_mov_i32(cpu_ZF
, var
);
427 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
429 tcg_gen_add_i32(t0
, t0
, t1
);
430 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
433 /* dest = T0 + T1 + CF. */
434 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
436 tcg_gen_add_i32(dest
, t0
, t1
);
437 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
440 /* dest = T0 - T1 + CF - 1. */
441 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
443 tcg_gen_sub_i32(dest
, t0
, t1
);
444 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
445 tcg_gen_subi_i32(dest
, dest
, 1);
448 /* dest = T0 + T1. Compute C, N, V and Z flags */
449 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
451 TCGv_i32 tmp
= tcg_temp_new_i32();
452 tcg_gen_movi_i32(tmp
, 0);
453 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
454 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
455 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
456 tcg_gen_xor_i32(tmp
, t0
, t1
);
457 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
458 tcg_temp_free_i32(tmp
);
459 tcg_gen_mov_i32(dest
, cpu_NF
);
462 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
463 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
465 TCGv_i32 tmp
= tcg_temp_new_i32();
466 if (TCG_TARGET_HAS_add2_i32
) {
467 tcg_gen_movi_i32(tmp
, 0);
468 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
469 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
471 TCGv_i64 q0
= tcg_temp_new_i64();
472 TCGv_i64 q1
= tcg_temp_new_i64();
473 tcg_gen_extu_i32_i64(q0
, t0
);
474 tcg_gen_extu_i32_i64(q1
, t1
);
475 tcg_gen_add_i64(q0
, q0
, q1
);
476 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
477 tcg_gen_add_i64(q0
, q0
, q1
);
478 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
479 tcg_temp_free_i64(q0
);
480 tcg_temp_free_i64(q1
);
482 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
483 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
484 tcg_gen_xor_i32(tmp
, t0
, t1
);
485 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
486 tcg_temp_free_i32(tmp
);
487 tcg_gen_mov_i32(dest
, cpu_NF
);
490 /* dest = T0 - T1. Compute C, N, V and Z flags */
491 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
494 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
495 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
496 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
497 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
498 tmp
= tcg_temp_new_i32();
499 tcg_gen_xor_i32(tmp
, t0
, t1
);
500 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
501 tcg_temp_free_i32(tmp
);
502 tcg_gen_mov_i32(dest
, cpu_NF
);
505 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
506 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
508 TCGv_i32 tmp
= tcg_temp_new_i32();
509 tcg_gen_not_i32(tmp
, t1
);
510 gen_adc_CC(dest
, t0
, tmp
);
511 tcg_temp_free_i32(tmp
);
514 #define GEN_SHIFT(name) \
515 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
517 TCGv_i32 tmp1, tmp2, tmp3; \
518 tmp1 = tcg_temp_new_i32(); \
519 tcg_gen_andi_i32(tmp1, t1, 0xff); \
520 tmp2 = tcg_const_i32(0); \
521 tmp3 = tcg_const_i32(0x1f); \
522 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
523 tcg_temp_free_i32(tmp3); \
524 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
525 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
526 tcg_temp_free_i32(tmp2); \
527 tcg_temp_free_i32(tmp1); \
533 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
536 tmp1
= tcg_temp_new_i32();
537 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
538 tmp2
= tcg_const_i32(0x1f);
539 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
540 tcg_temp_free_i32(tmp2
);
541 tcg_gen_sar_i32(dest
, t0
, tmp1
);
542 tcg_temp_free_i32(tmp1
);
545 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
547 TCGv_i32 c0
= tcg_const_i32(0);
548 TCGv_i32 tmp
= tcg_temp_new_i32();
549 tcg_gen_neg_i32(tmp
, src
);
550 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
551 tcg_temp_free_i32(c0
);
552 tcg_temp_free_i32(tmp
);
555 static void shifter_out_im(TCGv_i32 var
, int shift
)
558 tcg_gen_andi_i32(cpu_CF
, var
, 1);
560 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
562 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
567 /* Shift by immediate. Includes special handling for shift == 0. */
568 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
569 int shift
, int flags
)
575 shifter_out_im(var
, 32 - shift
);
576 tcg_gen_shli_i32(var
, var
, shift
);
582 tcg_gen_shri_i32(cpu_CF
, var
, 31);
584 tcg_gen_movi_i32(var
, 0);
587 shifter_out_im(var
, shift
- 1);
588 tcg_gen_shri_i32(var
, var
, shift
);
595 shifter_out_im(var
, shift
- 1);
598 tcg_gen_sari_i32(var
, var
, shift
);
600 case 3: /* ROR/RRX */
603 shifter_out_im(var
, shift
- 1);
604 tcg_gen_rotri_i32(var
, var
, shift
); break;
606 TCGv_i32 tmp
= tcg_temp_new_i32();
607 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
609 shifter_out_im(var
, 0);
610 tcg_gen_shri_i32(var
, var
, 1);
611 tcg_gen_or_i32(var
, var
, tmp
);
612 tcg_temp_free_i32(tmp
);
617 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
618 TCGv_i32 shift
, int flags
)
622 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
623 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
624 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
625 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
630 gen_shl(var
, var
, shift
);
633 gen_shr(var
, var
, shift
);
636 gen_sar(var
, var
, shift
);
638 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
639 tcg_gen_rotr_i32(var
, var
, shift
); break;
642 tcg_temp_free_i32(shift
);
645 #define PAS_OP(pfx) \
647 case 0: gen_pas_helper(glue(pfx,add16)); break; \
648 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
649 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
650 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
651 case 4: gen_pas_helper(glue(pfx,add8)); break; \
652 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
654 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
659 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
661 tmp
= tcg_temp_new_ptr();
662 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
664 tcg_temp_free_ptr(tmp
);
667 tmp
= tcg_temp_new_ptr();
668 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
670 tcg_temp_free_ptr(tmp
);
672 #undef gen_pas_helper
673 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
686 #undef gen_pas_helper
691 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
692 #define PAS_OP(pfx) \
694 case 0: gen_pas_helper(glue(pfx,add8)); break; \
695 case 1: gen_pas_helper(glue(pfx,add16)); break; \
696 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
697 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
698 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
699 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
701 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
706 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
708 tmp
= tcg_temp_new_ptr();
709 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
711 tcg_temp_free_ptr(tmp
);
714 tmp
= tcg_temp_new_ptr();
715 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
717 tcg_temp_free_ptr(tmp
);
719 #undef gen_pas_helper
720 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
733 #undef gen_pas_helper
739 * Generate a conditional based on ARM condition code cc.
740 * This is common between ARM and Aarch64 targets.
742 void arm_test_cc(DisasCompare
*cmp
, int cc
)
773 case 8: /* hi: C && !Z */
774 case 9: /* ls: !C || Z -> !(C && !Z) */
776 value
= tcg_temp_new_i32();
778 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
779 ZF is non-zero for !Z; so AND the two subexpressions. */
780 tcg_gen_neg_i32(value
, cpu_CF
);
781 tcg_gen_and_i32(value
, value
, cpu_ZF
);
784 case 10: /* ge: N == V -> N ^ V == 0 */
785 case 11: /* lt: N != V -> N ^ V != 0 */
786 /* Since we're only interested in the sign bit, == 0 is >= 0. */
788 value
= tcg_temp_new_i32();
790 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
793 case 12: /* gt: !Z && N == V */
794 case 13: /* le: Z || N != V */
796 value
= tcg_temp_new_i32();
798 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
799 * the sign bit then AND with ZF to yield the result. */
800 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
801 tcg_gen_sari_i32(value
, value
, 31);
802 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
805 case 14: /* always */
806 case 15: /* always */
807 /* Use the ALWAYS condition, which will fold early.
808 * It doesn't matter what we use for the value. */
809 cond
= TCG_COND_ALWAYS
;
814 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
819 cond
= tcg_invert_cond(cond
);
825 cmp
->value_global
= global
;
828 void arm_free_cc(DisasCompare
*cmp
)
830 if (!cmp
->value_global
) {
831 tcg_temp_free_i32(cmp
->value
);
835 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
837 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
840 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
843 arm_test_cc(&cmp
, cc
);
844 arm_jump_cc(&cmp
, label
);
848 static const uint8_t table_logic_cc
[16] = {
867 /* Set PC and Thumb state from an immediate address. */
868 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
872 s
->is_jmp
= DISAS_JUMP
;
873 if (s
->thumb
!= (addr
& 1)) {
874 tmp
= tcg_temp_new_i32();
875 tcg_gen_movi_i32(tmp
, addr
& 1);
876 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
877 tcg_temp_free_i32(tmp
);
879 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
882 /* Set PC and Thumb state from var. var is marked as dead. */
883 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
885 s
->is_jmp
= DISAS_JUMP
;
886 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
887 tcg_gen_andi_i32(var
, var
, 1);
888 store_cpu_field(var
, thumb
);
891 /* Variant of store_reg which uses branch&exchange logic when storing
892 to r15 in ARM architecture v7 and above. The source must be a temporary
893 and will be marked as dead. */
894 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
896 if (reg
== 15 && ENABLE_ARCH_7
) {
899 store_reg(s
, reg
, var
);
903 /* Variant of store_reg which uses branch&exchange logic when storing
904 * to r15 in ARM architecture v5T and above. This is used for storing
905 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
906 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
907 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
909 if (reg
== 15 && ENABLE_ARCH_5
) {
912 store_reg(s
, reg
, var
);
916 #ifdef CONFIG_USER_ONLY
917 #define IS_USER_ONLY 1
919 #define IS_USER_ONLY 0
922 /* Abstractions of "generate code to do a guest load/store for
923 * AArch32", where a vaddr is always 32 bits (and is zero
924 * extended if we're a 64 bit core) and data is also
925 * 32 bits unless specifically doing a 64 bit access.
926 * These functions work like tcg_gen_qemu_{ld,st}* except
927 * that the address argument is TCGv_i32 rather than TCGv.
929 #if TARGET_LONG_BITS == 32
931 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
932 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
933 TCGv_i32 addr, int index) \
935 TCGMemOp opc = (OPC) | s->be_data; \
936 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
937 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
938 TCGv addr_be = tcg_temp_new(); \
939 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
940 tcg_gen_qemu_ld_i32(val, addr_be, index, opc); \
941 tcg_temp_free(addr_be); \
944 tcg_gen_qemu_ld_i32(val, addr, index, opc); \
947 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
948 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
949 TCGv_i32 addr, int index) \
951 TCGMemOp opc = (OPC) | s->be_data; \
952 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
953 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
954 TCGv addr_be = tcg_temp_new(); \
955 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
956 tcg_gen_qemu_st_i32(val, addr_be, index, opc); \
957 tcg_temp_free(addr_be); \
960 tcg_gen_qemu_st_i32(val, addr, index, opc); \
963 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
964 TCGv_i32 addr
, int index
)
966 TCGMemOp opc
= MO_Q
| s
->be_data
;
967 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
968 /* Not needed for user-mode BE32, where we use MO_BE instead. */
969 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
970 tcg_gen_rotri_i64(val
, val
, 32);
974 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
975 TCGv_i32 addr
, int index
)
977 TCGMemOp opc
= MO_Q
| s
->be_data
;
978 /* Not needed for user-mode BE32, where we use MO_BE instead. */
979 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
980 TCGv_i64 tmp
= tcg_temp_new_i64();
981 tcg_gen_rotri_i64(tmp
, val
, 32);
982 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
983 tcg_temp_free_i64(tmp
);
986 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
991 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
992 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
993 TCGv_i32 addr, int index) \
995 TCGMemOp opc = (OPC) | s->be_data; \
996 TCGv addr64 = tcg_temp_new(); \
997 tcg_gen_extu_i32_i64(addr64, addr); \
998 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
999 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
1000 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1002 tcg_gen_qemu_ld_i32(val, addr64, index, opc); \
1003 tcg_temp_free(addr64); \
1006 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
1007 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1008 TCGv_i32 addr, int index) \
1010 TCGMemOp opc = (OPC) | s->be_data; \
1011 TCGv addr64 = tcg_temp_new(); \
1012 tcg_gen_extu_i32_i64(addr64, addr); \
1013 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
1014 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
1015 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1017 tcg_gen_qemu_st_i32(val, addr64, index, opc); \
1018 tcg_temp_free(addr64); \
1021 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1022 TCGv_i32 addr
, int index
)
1024 TCGMemOp opc
= MO_Q
| s
->be_data
;
1025 TCGv addr64
= tcg_temp_new();
1026 tcg_gen_extu_i32_i64(addr64
, addr
);
1027 tcg_gen_qemu_ld_i64(val
, addr64
, index
, opc
);
1029 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1030 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1031 tcg_gen_rotri_i64(val
, val
, 32);
1033 tcg_temp_free(addr64
);
1036 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1037 TCGv_i32 addr
, int index
)
1039 TCGMemOp opc
= MO_Q
| s
->be_data
;
1040 TCGv addr64
= tcg_temp_new();
1041 tcg_gen_extu_i32_i64(addr64
, addr
);
1043 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1044 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1045 TCGv tmp
= tcg_temp_new();
1046 tcg_gen_rotri_i64(tmp
, val
, 32);
1047 tcg_gen_qemu_st_i64(tmp
, addr64
, index
, opc
);
1050 tcg_gen_qemu_st_i64(val
, addr64
, index
, opc
);
1052 tcg_temp_free(addr64
);
1057 DO_GEN_LD(8s
, MO_SB
, 3)
1058 DO_GEN_LD(8u, MO_UB
, 3)
1059 DO_GEN_LD(16s
, MO_SW
, 2)
1060 DO_GEN_LD(16u, MO_UW
, 2)
1061 DO_GEN_LD(32u, MO_UL
, 0)
1062 /* 'a' variants include an alignment check */
1063 DO_GEN_LD(16ua
, MO_UW
| MO_ALIGN
, 2)
1064 DO_GEN_LD(32ua
, MO_UL
| MO_ALIGN
, 0)
1065 DO_GEN_ST(8, MO_UB
, 3)
1066 DO_GEN_ST(16, MO_UW
, 2)
1067 DO_GEN_ST(32, MO_UL
, 0)
1069 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
1071 tcg_gen_movi_i32(cpu_R
[15], val
);
1074 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1076 /* The pre HVC helper handles cases when HVC gets trapped
1077 * as an undefined insn by runtime configuration (ie before
1078 * the insn really executes).
1080 gen_set_pc_im(s
, s
->pc
- 4);
1081 gen_helper_pre_hvc(cpu_env
);
1082 /* Otherwise we will treat this as a real exception which
1083 * happens after execution of the insn. (The distinction matters
1084 * for the PC value reported to the exception handler and also
1085 * for single stepping.)
1088 gen_set_pc_im(s
, s
->pc
);
1089 s
->is_jmp
= DISAS_HVC
;
1092 static inline void gen_smc(DisasContext
*s
)
1094 /* As with HVC, we may take an exception either before or after
1095 * the insn executes.
1099 gen_set_pc_im(s
, s
->pc
- 4);
1100 tmp
= tcg_const_i32(syn_aa32_smc());
1101 gen_helper_pre_smc(cpu_env
, tmp
);
1102 tcg_temp_free_i32(tmp
);
1103 gen_set_pc_im(s
, s
->pc
);
1104 s
->is_jmp
= DISAS_SMC
;
1108 gen_set_condexec (DisasContext
*s
)
1110 if (s
->condexec_mask
) {
1111 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1112 TCGv_i32 tmp
= tcg_temp_new_i32();
1113 tcg_gen_movi_i32(tmp
, val
);
1114 store_cpu_field(tmp
, condexec_bits
);
1118 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1120 gen_set_condexec(s
);
1121 gen_set_pc_im(s
, s
->pc
- offset
);
1122 gen_exception_internal(excp
);
1123 s
->is_jmp
= DISAS_JUMP
;
1126 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1127 int syn
, uint32_t target_el
)
1129 gen_set_condexec(s
);
1130 gen_set_pc_im(s
, s
->pc
- offset
);
1131 gen_exception(excp
, syn
, target_el
);
1132 s
->is_jmp
= DISAS_JUMP
;
1135 /* Force a TB lookup after an instruction that changes the CPU state. */
1136 static inline void gen_lookup_tb(DisasContext
*s
)
1138 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1139 s
->is_jmp
= DISAS_JUMP
;
1142 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1145 int val
, rm
, shift
, shiftop
;
1148 if (!(insn
& (1 << 25))) {
1151 if (!(insn
& (1 << 23)))
1154 tcg_gen_addi_i32(var
, var
, val
);
1156 /* shift/register */
1158 shift
= (insn
>> 7) & 0x1f;
1159 shiftop
= (insn
>> 5) & 3;
1160 offset
= load_reg(s
, rm
);
1161 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1162 if (!(insn
& (1 << 23)))
1163 tcg_gen_sub_i32(var
, var
, offset
);
1165 tcg_gen_add_i32(var
, var
, offset
);
1166 tcg_temp_free_i32(offset
);
1170 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1171 int extra
, TCGv_i32 var
)
1176 if (insn
& (1 << 22)) {
1178 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1179 if (!(insn
& (1 << 23)))
1183 tcg_gen_addi_i32(var
, var
, val
);
1187 tcg_gen_addi_i32(var
, var
, extra
);
1189 offset
= load_reg(s
, rm
);
1190 if (!(insn
& (1 << 23)))
1191 tcg_gen_sub_i32(var
, var
, offset
);
1193 tcg_gen_add_i32(var
, var
, offset
);
1194 tcg_temp_free_i32(offset
);
1198 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1200 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1203 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1205 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1207 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1211 #define VFP_OP2(name) \
1212 static inline void gen_vfp_##name(int dp) \
1214 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1216 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1218 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1220 tcg_temp_free_ptr(fpst); \
1230 static inline void gen_vfp_F1_mul(int dp
)
1232 /* Like gen_vfp_mul() but put result in F1 */
1233 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1235 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1237 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1239 tcg_temp_free_ptr(fpst
);
1242 static inline void gen_vfp_F1_neg(int dp
)
1244 /* Like gen_vfp_neg() but put result in F1 */
1246 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1248 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1252 static inline void gen_vfp_abs(int dp
)
1255 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1257 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1260 static inline void gen_vfp_neg(int dp
)
1263 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1265 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1268 static inline void gen_vfp_sqrt(int dp
)
1271 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1273 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1276 static inline void gen_vfp_cmp(int dp
)
1279 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1281 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1284 static inline void gen_vfp_cmpe(int dp
)
1287 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1289 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1292 static inline void gen_vfp_F1_ld0(int dp
)
1295 tcg_gen_movi_i64(cpu_F1d
, 0);
1297 tcg_gen_movi_i32(cpu_F1s
, 0);
1300 #define VFP_GEN_ITOF(name) \
1301 static inline void gen_vfp_##name(int dp, int neon) \
1303 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1305 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1307 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1309 tcg_temp_free_ptr(statusptr); \
1316 #define VFP_GEN_FTOI(name) \
1317 static inline void gen_vfp_##name(int dp, int neon) \
1319 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1321 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1323 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1325 tcg_temp_free_ptr(statusptr); \
1334 #define VFP_GEN_FIX(name, round) \
1335 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1337 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1338 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1340 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1343 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1346 tcg_temp_free_i32(tmp_shift); \
1347 tcg_temp_free_ptr(statusptr); \
1349 VFP_GEN_FIX(tosh
, _round_to_zero
)
1350 VFP_GEN_FIX(tosl
, _round_to_zero
)
1351 VFP_GEN_FIX(touh
, _round_to_zero
)
1352 VFP_GEN_FIX(toul
, _round_to_zero
)
1359 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1362 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1364 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1368 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1371 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1373 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1378 vfp_reg_offset (int dp
, int reg
)
1381 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1383 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1384 + offsetof(CPU_DoubleU
, l
.upper
);
1386 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1387 + offsetof(CPU_DoubleU
, l
.lower
);
1391 /* Return the offset of a 32-bit piece of a NEON register.
1392 zero is the least significant end of the register. */
1394 neon_reg_offset (int reg
, int n
)
1398 return vfp_reg_offset(0, sreg
);
1401 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1403 TCGv_i32 tmp
= tcg_temp_new_i32();
1404 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1408 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1410 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1411 tcg_temp_free_i32(var
);
1414 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1416 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1419 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1421 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1424 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1425 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1426 #define tcg_gen_st_f32 tcg_gen_st_i32
1427 #define tcg_gen_st_f64 tcg_gen_st_i64
1429 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1432 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1434 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1437 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1440 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1442 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1445 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1448 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1450 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1453 #define ARM_CP_RW_BIT (1 << 20)
1455 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1457 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1460 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1462 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1465 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1467 TCGv_i32 var
= tcg_temp_new_i32();
1468 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1472 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1474 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1475 tcg_temp_free_i32(var
);
1478 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1480 iwmmxt_store_reg(cpu_M0
, rn
);
1483 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1485 iwmmxt_load_reg(cpu_M0
, rn
);
1488 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1490 iwmmxt_load_reg(cpu_V1
, rn
);
1491 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1494 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1496 iwmmxt_load_reg(cpu_V1
, rn
);
1497 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1500 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1502 iwmmxt_load_reg(cpu_V1
, rn
);
1503 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1506 #define IWMMXT_OP(name) \
1507 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1509 iwmmxt_load_reg(cpu_V1, rn); \
1510 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1513 #define IWMMXT_OP_ENV(name) \
1514 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1516 iwmmxt_load_reg(cpu_V1, rn); \
1517 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1520 #define IWMMXT_OP_ENV_SIZE(name) \
1521 IWMMXT_OP_ENV(name##b) \
1522 IWMMXT_OP_ENV(name##w) \
1523 IWMMXT_OP_ENV(name##l)
1525 #define IWMMXT_OP_ENV1(name) \
1526 static inline void gen_op_iwmmxt_##name##_M0(void) \
1528 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1542 IWMMXT_OP_ENV_SIZE(unpackl
)
1543 IWMMXT_OP_ENV_SIZE(unpackh
)
1545 IWMMXT_OP_ENV1(unpacklub
)
1546 IWMMXT_OP_ENV1(unpackluw
)
1547 IWMMXT_OP_ENV1(unpacklul
)
1548 IWMMXT_OP_ENV1(unpackhub
)
1549 IWMMXT_OP_ENV1(unpackhuw
)
1550 IWMMXT_OP_ENV1(unpackhul
)
1551 IWMMXT_OP_ENV1(unpacklsb
)
1552 IWMMXT_OP_ENV1(unpacklsw
)
1553 IWMMXT_OP_ENV1(unpacklsl
)
1554 IWMMXT_OP_ENV1(unpackhsb
)
1555 IWMMXT_OP_ENV1(unpackhsw
)
1556 IWMMXT_OP_ENV1(unpackhsl
)
1558 IWMMXT_OP_ENV_SIZE(cmpeq
)
1559 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1560 IWMMXT_OP_ENV_SIZE(cmpgts
)
1562 IWMMXT_OP_ENV_SIZE(mins
)
1563 IWMMXT_OP_ENV_SIZE(minu
)
1564 IWMMXT_OP_ENV_SIZE(maxs
)
1565 IWMMXT_OP_ENV_SIZE(maxu
)
1567 IWMMXT_OP_ENV_SIZE(subn
)
1568 IWMMXT_OP_ENV_SIZE(addn
)
1569 IWMMXT_OP_ENV_SIZE(subu
)
1570 IWMMXT_OP_ENV_SIZE(addu
)
1571 IWMMXT_OP_ENV_SIZE(subs
)
1572 IWMMXT_OP_ENV_SIZE(adds
)
1574 IWMMXT_OP_ENV(avgb0
)
1575 IWMMXT_OP_ENV(avgb1
)
1576 IWMMXT_OP_ENV(avgw0
)
1577 IWMMXT_OP_ENV(avgw1
)
1579 IWMMXT_OP_ENV(packuw
)
1580 IWMMXT_OP_ENV(packul
)
1581 IWMMXT_OP_ENV(packuq
)
1582 IWMMXT_OP_ENV(packsw
)
1583 IWMMXT_OP_ENV(packsl
)
1584 IWMMXT_OP_ENV(packsq
)
1586 static void gen_op_iwmmxt_set_mup(void)
1589 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1590 tcg_gen_ori_i32(tmp
, tmp
, 2);
1591 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1594 static void gen_op_iwmmxt_set_cup(void)
1597 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1598 tcg_gen_ori_i32(tmp
, tmp
, 1);
1599 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1602 static void gen_op_iwmmxt_setpsr_nz(void)
1604 TCGv_i32 tmp
= tcg_temp_new_i32();
1605 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1606 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1609 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1611 iwmmxt_load_reg(cpu_V1
, rn
);
1612 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1613 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1616 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1623 rd
= (insn
>> 16) & 0xf;
1624 tmp
= load_reg(s
, rd
);
1626 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1627 if (insn
& (1 << 24)) {
1629 if (insn
& (1 << 23))
1630 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1632 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1633 tcg_gen_mov_i32(dest
, tmp
);
1634 if (insn
& (1 << 21))
1635 store_reg(s
, rd
, tmp
);
1637 tcg_temp_free_i32(tmp
);
1638 } else if (insn
& (1 << 21)) {
1640 tcg_gen_mov_i32(dest
, tmp
);
1641 if (insn
& (1 << 23))
1642 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1644 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1645 store_reg(s
, rd
, tmp
);
1646 } else if (!(insn
& (1 << 23)))
1651 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1653 int rd
= (insn
>> 0) & 0xf;
1656 if (insn
& (1 << 8)) {
1657 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1660 tmp
= iwmmxt_load_creg(rd
);
1663 tmp
= tcg_temp_new_i32();
1664 iwmmxt_load_reg(cpu_V0
, rd
);
1665 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1667 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1668 tcg_gen_mov_i32(dest
, tmp
);
1669 tcg_temp_free_i32(tmp
);
1673 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1674 (ie. an undefined instruction). */
1675 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1678 int rdhi
, rdlo
, rd0
, rd1
, i
;
1680 TCGv_i32 tmp
, tmp2
, tmp3
;
1682 if ((insn
& 0x0e000e00) == 0x0c000000) {
1683 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1685 rdlo
= (insn
>> 12) & 0xf;
1686 rdhi
= (insn
>> 16) & 0xf;
1687 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1688 iwmmxt_load_reg(cpu_V0
, wrd
);
1689 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1690 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1691 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1692 } else { /* TMCRR */
1693 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1694 iwmmxt_store_reg(cpu_V0
, wrd
);
1695 gen_op_iwmmxt_set_mup();
1700 wrd
= (insn
>> 12) & 0xf;
1701 addr
= tcg_temp_new_i32();
1702 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1703 tcg_temp_free_i32(addr
);
1706 if (insn
& ARM_CP_RW_BIT
) {
1707 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1708 tmp
= tcg_temp_new_i32();
1709 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1710 iwmmxt_store_creg(wrd
, tmp
);
1713 if (insn
& (1 << 8)) {
1714 if (insn
& (1 << 22)) { /* WLDRD */
1715 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1717 } else { /* WLDRW wRd */
1718 tmp
= tcg_temp_new_i32();
1719 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1722 tmp
= tcg_temp_new_i32();
1723 if (insn
& (1 << 22)) { /* WLDRH */
1724 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1725 } else { /* WLDRB */
1726 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1730 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1731 tcg_temp_free_i32(tmp
);
1733 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1736 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1737 tmp
= iwmmxt_load_creg(wrd
);
1738 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1740 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1741 tmp
= tcg_temp_new_i32();
1742 if (insn
& (1 << 8)) {
1743 if (insn
& (1 << 22)) { /* WSTRD */
1744 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1745 } else { /* WSTRW wRd */
1746 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1747 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1750 if (insn
& (1 << 22)) { /* WSTRH */
1751 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1752 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1753 } else { /* WSTRB */
1754 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1755 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1759 tcg_temp_free_i32(tmp
);
1761 tcg_temp_free_i32(addr
);
1765 if ((insn
& 0x0f000000) != 0x0e000000)
1768 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1769 case 0x000: /* WOR */
1770 wrd
= (insn
>> 12) & 0xf;
1771 rd0
= (insn
>> 0) & 0xf;
1772 rd1
= (insn
>> 16) & 0xf;
1773 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1774 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1775 gen_op_iwmmxt_setpsr_nz();
1776 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1777 gen_op_iwmmxt_set_mup();
1778 gen_op_iwmmxt_set_cup();
1780 case 0x011: /* TMCR */
1783 rd
= (insn
>> 12) & 0xf;
1784 wrd
= (insn
>> 16) & 0xf;
1786 case ARM_IWMMXT_wCID
:
1787 case ARM_IWMMXT_wCASF
:
1789 case ARM_IWMMXT_wCon
:
1790 gen_op_iwmmxt_set_cup();
1792 case ARM_IWMMXT_wCSSF
:
1793 tmp
= iwmmxt_load_creg(wrd
);
1794 tmp2
= load_reg(s
, rd
);
1795 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1796 tcg_temp_free_i32(tmp2
);
1797 iwmmxt_store_creg(wrd
, tmp
);
1799 case ARM_IWMMXT_wCGR0
:
1800 case ARM_IWMMXT_wCGR1
:
1801 case ARM_IWMMXT_wCGR2
:
1802 case ARM_IWMMXT_wCGR3
:
1803 gen_op_iwmmxt_set_cup();
1804 tmp
= load_reg(s
, rd
);
1805 iwmmxt_store_creg(wrd
, tmp
);
1811 case 0x100: /* WXOR */
1812 wrd
= (insn
>> 12) & 0xf;
1813 rd0
= (insn
>> 0) & 0xf;
1814 rd1
= (insn
>> 16) & 0xf;
1815 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1816 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1817 gen_op_iwmmxt_setpsr_nz();
1818 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1819 gen_op_iwmmxt_set_mup();
1820 gen_op_iwmmxt_set_cup();
1822 case 0x111: /* TMRC */
1825 rd
= (insn
>> 12) & 0xf;
1826 wrd
= (insn
>> 16) & 0xf;
1827 tmp
= iwmmxt_load_creg(wrd
);
1828 store_reg(s
, rd
, tmp
);
1830 case 0x300: /* WANDN */
1831 wrd
= (insn
>> 12) & 0xf;
1832 rd0
= (insn
>> 0) & 0xf;
1833 rd1
= (insn
>> 16) & 0xf;
1834 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1835 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1836 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1837 gen_op_iwmmxt_setpsr_nz();
1838 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1839 gen_op_iwmmxt_set_mup();
1840 gen_op_iwmmxt_set_cup();
1842 case 0x200: /* WAND */
1843 wrd
= (insn
>> 12) & 0xf;
1844 rd0
= (insn
>> 0) & 0xf;
1845 rd1
= (insn
>> 16) & 0xf;
1846 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1847 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1848 gen_op_iwmmxt_setpsr_nz();
1849 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1850 gen_op_iwmmxt_set_mup();
1851 gen_op_iwmmxt_set_cup();
1853 case 0x810: case 0xa10: /* WMADD */
1854 wrd
= (insn
>> 12) & 0xf;
1855 rd0
= (insn
>> 0) & 0xf;
1856 rd1
= (insn
>> 16) & 0xf;
1857 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1858 if (insn
& (1 << 21))
1859 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1861 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1862 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1863 gen_op_iwmmxt_set_mup();
1865 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1866 wrd
= (insn
>> 12) & 0xf;
1867 rd0
= (insn
>> 16) & 0xf;
1868 rd1
= (insn
>> 0) & 0xf;
1869 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1870 switch ((insn
>> 22) & 3) {
1872 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1875 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1878 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1883 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1884 gen_op_iwmmxt_set_mup();
1885 gen_op_iwmmxt_set_cup();
1887 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1888 wrd
= (insn
>> 12) & 0xf;
1889 rd0
= (insn
>> 16) & 0xf;
1890 rd1
= (insn
>> 0) & 0xf;
1891 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1892 switch ((insn
>> 22) & 3) {
1894 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1897 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1900 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1905 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1906 gen_op_iwmmxt_set_mup();
1907 gen_op_iwmmxt_set_cup();
1909 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1910 wrd
= (insn
>> 12) & 0xf;
1911 rd0
= (insn
>> 16) & 0xf;
1912 rd1
= (insn
>> 0) & 0xf;
1913 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1914 if (insn
& (1 << 22))
1915 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1917 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1918 if (!(insn
& (1 << 20)))
1919 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1920 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1921 gen_op_iwmmxt_set_mup();
1923 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1924 wrd
= (insn
>> 12) & 0xf;
1925 rd0
= (insn
>> 16) & 0xf;
1926 rd1
= (insn
>> 0) & 0xf;
1927 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1928 if (insn
& (1 << 21)) {
1929 if (insn
& (1 << 20))
1930 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1932 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1934 if (insn
& (1 << 20))
1935 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1937 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1939 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1940 gen_op_iwmmxt_set_mup();
1942 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1943 wrd
= (insn
>> 12) & 0xf;
1944 rd0
= (insn
>> 16) & 0xf;
1945 rd1
= (insn
>> 0) & 0xf;
1946 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1947 if (insn
& (1 << 21))
1948 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1950 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1951 if (!(insn
& (1 << 20))) {
1952 iwmmxt_load_reg(cpu_V1
, wrd
);
1953 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1955 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1956 gen_op_iwmmxt_set_mup();
1958 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1959 wrd
= (insn
>> 12) & 0xf;
1960 rd0
= (insn
>> 16) & 0xf;
1961 rd1
= (insn
>> 0) & 0xf;
1962 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1963 switch ((insn
>> 22) & 3) {
1965 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1968 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1971 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1976 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1977 gen_op_iwmmxt_set_mup();
1978 gen_op_iwmmxt_set_cup();
1980 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1981 wrd
= (insn
>> 12) & 0xf;
1982 rd0
= (insn
>> 16) & 0xf;
1983 rd1
= (insn
>> 0) & 0xf;
1984 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1985 if (insn
& (1 << 22)) {
1986 if (insn
& (1 << 20))
1987 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1989 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1991 if (insn
& (1 << 20))
1992 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1994 gen_op_iwmmxt_avgb0_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 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2001 wrd
= (insn
>> 12) & 0xf;
2002 rd0
= (insn
>> 16) & 0xf;
2003 rd1
= (insn
>> 0) & 0xf;
2004 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2005 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2006 tcg_gen_andi_i32(tmp
, tmp
, 7);
2007 iwmmxt_load_reg(cpu_V1
, rd1
);
2008 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2009 tcg_temp_free_i32(tmp
);
2010 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2011 gen_op_iwmmxt_set_mup();
2013 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2014 if (((insn
>> 6) & 3) == 3)
2016 rd
= (insn
>> 12) & 0xf;
2017 wrd
= (insn
>> 16) & 0xf;
2018 tmp
= load_reg(s
, rd
);
2019 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2020 switch ((insn
>> 6) & 3) {
2022 tmp2
= tcg_const_i32(0xff);
2023 tmp3
= tcg_const_i32((insn
& 7) << 3);
2026 tmp2
= tcg_const_i32(0xffff);
2027 tmp3
= tcg_const_i32((insn
& 3) << 4);
2030 tmp2
= tcg_const_i32(0xffffffff);
2031 tmp3
= tcg_const_i32((insn
& 1) << 5);
2034 TCGV_UNUSED_I32(tmp2
);
2035 TCGV_UNUSED_I32(tmp3
);
2037 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2038 tcg_temp_free_i32(tmp3
);
2039 tcg_temp_free_i32(tmp2
);
2040 tcg_temp_free_i32(tmp
);
2041 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2042 gen_op_iwmmxt_set_mup();
2044 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2045 rd
= (insn
>> 12) & 0xf;
2046 wrd
= (insn
>> 16) & 0xf;
2047 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2049 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2050 tmp
= tcg_temp_new_i32();
2051 switch ((insn
>> 22) & 3) {
2053 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2054 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2056 tcg_gen_ext8s_i32(tmp
, tmp
);
2058 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2062 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2063 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2065 tcg_gen_ext16s_i32(tmp
, tmp
);
2067 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2071 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2072 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2075 store_reg(s
, rd
, tmp
);
2077 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2078 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2080 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2081 switch ((insn
>> 22) & 3) {
2083 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2086 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2089 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2092 tcg_gen_shli_i32(tmp
, tmp
, 28);
2094 tcg_temp_free_i32(tmp
);
2096 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2097 if (((insn
>> 6) & 3) == 3)
2099 rd
= (insn
>> 12) & 0xf;
2100 wrd
= (insn
>> 16) & 0xf;
2101 tmp
= load_reg(s
, rd
);
2102 switch ((insn
>> 6) & 3) {
2104 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2107 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2110 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2113 tcg_temp_free_i32(tmp
);
2114 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2115 gen_op_iwmmxt_set_mup();
2117 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2118 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2120 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2121 tmp2
= tcg_temp_new_i32();
2122 tcg_gen_mov_i32(tmp2
, tmp
);
2123 switch ((insn
>> 22) & 3) {
2125 for (i
= 0; i
< 7; i
++) {
2126 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2127 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2131 for (i
= 0; i
< 3; i
++) {
2132 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2133 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2137 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2138 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2142 tcg_temp_free_i32(tmp2
);
2143 tcg_temp_free_i32(tmp
);
2145 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2146 wrd
= (insn
>> 12) & 0xf;
2147 rd0
= (insn
>> 16) & 0xf;
2148 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2149 switch ((insn
>> 22) & 3) {
2151 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2154 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2157 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2162 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2163 gen_op_iwmmxt_set_mup();
2165 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2166 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2168 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2169 tmp2
= tcg_temp_new_i32();
2170 tcg_gen_mov_i32(tmp2
, tmp
);
2171 switch ((insn
>> 22) & 3) {
2173 for (i
= 0; i
< 7; i
++) {
2174 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2175 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2179 for (i
= 0; i
< 3; i
++) {
2180 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2181 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2185 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2186 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2190 tcg_temp_free_i32(tmp2
);
2191 tcg_temp_free_i32(tmp
);
2193 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2194 rd
= (insn
>> 12) & 0xf;
2195 rd0
= (insn
>> 16) & 0xf;
2196 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2198 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2199 tmp
= tcg_temp_new_i32();
2200 switch ((insn
>> 22) & 3) {
2202 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2205 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2208 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2211 store_reg(s
, rd
, tmp
);
2213 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2214 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2215 wrd
= (insn
>> 12) & 0xf;
2216 rd0
= (insn
>> 16) & 0xf;
2217 rd1
= (insn
>> 0) & 0xf;
2218 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2219 switch ((insn
>> 22) & 3) {
2221 if (insn
& (1 << 21))
2222 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2224 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2227 if (insn
& (1 << 21))
2228 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2230 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2233 if (insn
& (1 << 21))
2234 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2236 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2241 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2242 gen_op_iwmmxt_set_mup();
2243 gen_op_iwmmxt_set_cup();
2245 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2246 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2247 wrd
= (insn
>> 12) & 0xf;
2248 rd0
= (insn
>> 16) & 0xf;
2249 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2250 switch ((insn
>> 22) & 3) {
2252 if (insn
& (1 << 21))
2253 gen_op_iwmmxt_unpacklsb_M0();
2255 gen_op_iwmmxt_unpacklub_M0();
2258 if (insn
& (1 << 21))
2259 gen_op_iwmmxt_unpacklsw_M0();
2261 gen_op_iwmmxt_unpackluw_M0();
2264 if (insn
& (1 << 21))
2265 gen_op_iwmmxt_unpacklsl_M0();
2267 gen_op_iwmmxt_unpacklul_M0();
2272 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2273 gen_op_iwmmxt_set_mup();
2274 gen_op_iwmmxt_set_cup();
2276 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2277 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2278 wrd
= (insn
>> 12) & 0xf;
2279 rd0
= (insn
>> 16) & 0xf;
2280 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2281 switch ((insn
>> 22) & 3) {
2283 if (insn
& (1 << 21))
2284 gen_op_iwmmxt_unpackhsb_M0();
2286 gen_op_iwmmxt_unpackhub_M0();
2289 if (insn
& (1 << 21))
2290 gen_op_iwmmxt_unpackhsw_M0();
2292 gen_op_iwmmxt_unpackhuw_M0();
2295 if (insn
& (1 << 21))
2296 gen_op_iwmmxt_unpackhsl_M0();
2298 gen_op_iwmmxt_unpackhul_M0();
2303 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2304 gen_op_iwmmxt_set_mup();
2305 gen_op_iwmmxt_set_cup();
2307 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2308 case 0x214: case 0x614: case 0xa14: case 0xe14:
2309 if (((insn
>> 22) & 3) == 0)
2311 wrd
= (insn
>> 12) & 0xf;
2312 rd0
= (insn
>> 16) & 0xf;
2313 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2314 tmp
= tcg_temp_new_i32();
2315 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2316 tcg_temp_free_i32(tmp
);
2319 switch ((insn
>> 22) & 3) {
2321 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2324 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2327 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2330 tcg_temp_free_i32(tmp
);
2331 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2332 gen_op_iwmmxt_set_mup();
2333 gen_op_iwmmxt_set_cup();
2335 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2336 case 0x014: case 0x414: case 0x814: case 0xc14:
2337 if (((insn
>> 22) & 3) == 0)
2339 wrd
= (insn
>> 12) & 0xf;
2340 rd0
= (insn
>> 16) & 0xf;
2341 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2342 tmp
= tcg_temp_new_i32();
2343 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2344 tcg_temp_free_i32(tmp
);
2347 switch ((insn
>> 22) & 3) {
2349 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2352 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2355 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2358 tcg_temp_free_i32(tmp
);
2359 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2360 gen_op_iwmmxt_set_mup();
2361 gen_op_iwmmxt_set_cup();
2363 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2364 case 0x114: case 0x514: case 0x914: case 0xd14:
2365 if (((insn
>> 22) & 3) == 0)
2367 wrd
= (insn
>> 12) & 0xf;
2368 rd0
= (insn
>> 16) & 0xf;
2369 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2370 tmp
= tcg_temp_new_i32();
2371 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2372 tcg_temp_free_i32(tmp
);
2375 switch ((insn
>> 22) & 3) {
2377 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2380 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2383 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2386 tcg_temp_free_i32(tmp
);
2387 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2388 gen_op_iwmmxt_set_mup();
2389 gen_op_iwmmxt_set_cup();
2391 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2392 case 0x314: case 0x714: case 0xb14: case 0xf14:
2393 if (((insn
>> 22) & 3) == 0)
2395 wrd
= (insn
>> 12) & 0xf;
2396 rd0
= (insn
>> 16) & 0xf;
2397 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2398 tmp
= tcg_temp_new_i32();
2399 switch ((insn
>> 22) & 3) {
2401 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2402 tcg_temp_free_i32(tmp
);
2405 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2408 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2409 tcg_temp_free_i32(tmp
);
2412 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2415 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2416 tcg_temp_free_i32(tmp
);
2419 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2422 tcg_temp_free_i32(tmp
);
2423 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2424 gen_op_iwmmxt_set_mup();
2425 gen_op_iwmmxt_set_cup();
2427 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2428 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2429 wrd
= (insn
>> 12) & 0xf;
2430 rd0
= (insn
>> 16) & 0xf;
2431 rd1
= (insn
>> 0) & 0xf;
2432 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2433 switch ((insn
>> 22) & 3) {
2435 if (insn
& (1 << 21))
2436 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2438 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2441 if (insn
& (1 << 21))
2442 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2444 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2447 if (insn
& (1 << 21))
2448 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2450 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2455 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2456 gen_op_iwmmxt_set_mup();
2458 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2459 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2460 wrd
= (insn
>> 12) & 0xf;
2461 rd0
= (insn
>> 16) & 0xf;
2462 rd1
= (insn
>> 0) & 0xf;
2463 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2464 switch ((insn
>> 22) & 3) {
2466 if (insn
& (1 << 21))
2467 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2469 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2472 if (insn
& (1 << 21))
2473 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2475 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2478 if (insn
& (1 << 21))
2479 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2481 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2486 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2487 gen_op_iwmmxt_set_mup();
2489 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2490 case 0x402: case 0x502: case 0x602: case 0x702:
2491 wrd
= (insn
>> 12) & 0xf;
2492 rd0
= (insn
>> 16) & 0xf;
2493 rd1
= (insn
>> 0) & 0xf;
2494 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2495 tmp
= tcg_const_i32((insn
>> 20) & 3);
2496 iwmmxt_load_reg(cpu_V1
, rd1
);
2497 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2498 tcg_temp_free_i32(tmp
);
2499 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2500 gen_op_iwmmxt_set_mup();
2502 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2503 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2504 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2505 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2506 wrd
= (insn
>> 12) & 0xf;
2507 rd0
= (insn
>> 16) & 0xf;
2508 rd1
= (insn
>> 0) & 0xf;
2509 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2510 switch ((insn
>> 20) & 0xf) {
2512 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2515 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2518 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2521 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2524 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2527 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2530 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2533 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2536 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2541 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2542 gen_op_iwmmxt_set_mup();
2543 gen_op_iwmmxt_set_cup();
2545 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2546 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2547 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2548 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2549 wrd
= (insn
>> 12) & 0xf;
2550 rd0
= (insn
>> 16) & 0xf;
2551 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2552 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2553 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2554 tcg_temp_free_i32(tmp
);
2555 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2556 gen_op_iwmmxt_set_mup();
2557 gen_op_iwmmxt_set_cup();
2559 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2560 case 0x418: case 0x518: case 0x618: case 0x718:
2561 case 0x818: case 0x918: case 0xa18: case 0xb18:
2562 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2563 wrd
= (insn
>> 12) & 0xf;
2564 rd0
= (insn
>> 16) & 0xf;
2565 rd1
= (insn
>> 0) & 0xf;
2566 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2567 switch ((insn
>> 20) & 0xf) {
2569 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2572 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2575 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2578 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2581 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2584 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2587 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2590 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2593 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2598 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2599 gen_op_iwmmxt_set_mup();
2600 gen_op_iwmmxt_set_cup();
2602 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2603 case 0x408: case 0x508: case 0x608: case 0x708:
2604 case 0x808: case 0x908: case 0xa08: case 0xb08:
2605 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2606 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2608 wrd
= (insn
>> 12) & 0xf;
2609 rd0
= (insn
>> 16) & 0xf;
2610 rd1
= (insn
>> 0) & 0xf;
2611 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2612 switch ((insn
>> 22) & 3) {
2614 if (insn
& (1 << 21))
2615 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2617 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2620 if (insn
& (1 << 21))
2621 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2623 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2626 if (insn
& (1 << 21))
2627 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2629 gen_op_iwmmxt_packuq_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 0x201: case 0x203: case 0x205: case 0x207:
2637 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2638 case 0x211: case 0x213: case 0x215: case 0x217:
2639 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2640 wrd
= (insn
>> 5) & 0xf;
2641 rd0
= (insn
>> 12) & 0xf;
2642 rd1
= (insn
>> 0) & 0xf;
2643 if (rd0
== 0xf || rd1
== 0xf)
2645 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2646 tmp
= load_reg(s
, rd0
);
2647 tmp2
= load_reg(s
, rd1
);
2648 switch ((insn
>> 16) & 0xf) {
2649 case 0x0: /* TMIA */
2650 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2652 case 0x8: /* TMIAPH */
2653 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2655 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2656 if (insn
& (1 << 16))
2657 tcg_gen_shri_i32(tmp
, tmp
, 16);
2658 if (insn
& (1 << 17))
2659 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2660 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2663 tcg_temp_free_i32(tmp2
);
2664 tcg_temp_free_i32(tmp
);
2667 tcg_temp_free_i32(tmp2
);
2668 tcg_temp_free_i32(tmp
);
2669 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2670 gen_op_iwmmxt_set_mup();
2679 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2680 (ie. an undefined instruction). */
2681 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2683 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2686 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2687 /* Multiply with Internal Accumulate Format */
2688 rd0
= (insn
>> 12) & 0xf;
2690 acc
= (insn
>> 5) & 7;
2695 tmp
= load_reg(s
, rd0
);
2696 tmp2
= load_reg(s
, rd1
);
2697 switch ((insn
>> 16) & 0xf) {
2699 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2701 case 0x8: /* MIAPH */
2702 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2704 case 0xc: /* MIABB */
2705 case 0xd: /* MIABT */
2706 case 0xe: /* MIATB */
2707 case 0xf: /* MIATT */
2708 if (insn
& (1 << 16))
2709 tcg_gen_shri_i32(tmp
, tmp
, 16);
2710 if (insn
& (1 << 17))
2711 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2712 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2717 tcg_temp_free_i32(tmp2
);
2718 tcg_temp_free_i32(tmp
);
2720 gen_op_iwmmxt_movq_wRn_M0(acc
);
2724 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2725 /* Internal Accumulator Access Format */
2726 rdhi
= (insn
>> 16) & 0xf;
2727 rdlo
= (insn
>> 12) & 0xf;
2733 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2734 iwmmxt_load_reg(cpu_V0
, acc
);
2735 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2736 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2737 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2738 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2740 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2741 iwmmxt_store_reg(cpu_V0
, acc
);
2749 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2750 #define VFP_SREG(insn, bigbit, smallbit) \
2751 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2752 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2753 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2754 reg = (((insn) >> (bigbit)) & 0x0f) \
2755 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2757 if (insn & (1 << (smallbit))) \
2759 reg = ((insn) >> (bigbit)) & 0x0f; \
2762 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2763 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2764 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2765 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2766 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2767 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2769 /* Move between integer and VFP cores. */
2770 static TCGv_i32
gen_vfp_mrs(void)
2772 TCGv_i32 tmp
= tcg_temp_new_i32();
2773 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2777 static void gen_vfp_msr(TCGv_i32 tmp
)
2779 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2780 tcg_temp_free_i32(tmp
);
2783 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2785 TCGv_i32 tmp
= tcg_temp_new_i32();
2787 tcg_gen_shri_i32(var
, var
, shift
);
2788 tcg_gen_ext8u_i32(var
, var
);
2789 tcg_gen_shli_i32(tmp
, var
, 8);
2790 tcg_gen_or_i32(var
, var
, tmp
);
2791 tcg_gen_shli_i32(tmp
, var
, 16);
2792 tcg_gen_or_i32(var
, var
, tmp
);
2793 tcg_temp_free_i32(tmp
);
2796 static void gen_neon_dup_low16(TCGv_i32 var
)
2798 TCGv_i32 tmp
= tcg_temp_new_i32();
2799 tcg_gen_ext16u_i32(var
, var
);
2800 tcg_gen_shli_i32(tmp
, var
, 16);
2801 tcg_gen_or_i32(var
, var
, tmp
);
2802 tcg_temp_free_i32(tmp
);
2805 static void gen_neon_dup_high16(TCGv_i32 var
)
2807 TCGv_i32 tmp
= tcg_temp_new_i32();
2808 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2809 tcg_gen_shri_i32(tmp
, var
, 16);
2810 tcg_gen_or_i32(var
, var
, tmp
);
2811 tcg_temp_free_i32(tmp
);
2814 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2816 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2817 TCGv_i32 tmp
= tcg_temp_new_i32();
2820 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2821 gen_neon_dup_u8(tmp
, 0);
2824 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2825 gen_neon_dup_low16(tmp
);
2828 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2830 default: /* Avoid compiler warnings. */
2836 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2839 uint32_t cc
= extract32(insn
, 20, 2);
2842 TCGv_i64 frn
, frm
, dest
;
2843 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2845 zero
= tcg_const_i64(0);
2847 frn
= tcg_temp_new_i64();
2848 frm
= tcg_temp_new_i64();
2849 dest
= tcg_temp_new_i64();
2851 zf
= tcg_temp_new_i64();
2852 nf
= tcg_temp_new_i64();
2853 vf
= tcg_temp_new_i64();
2855 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2856 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2857 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2859 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2860 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2863 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2867 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2870 case 2: /* ge: N == V -> N ^ V == 0 */
2871 tmp
= tcg_temp_new_i64();
2872 tcg_gen_xor_i64(tmp
, vf
, nf
);
2873 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2875 tcg_temp_free_i64(tmp
);
2877 case 3: /* gt: !Z && N == V */
2878 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2880 tmp
= tcg_temp_new_i64();
2881 tcg_gen_xor_i64(tmp
, vf
, nf
);
2882 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2884 tcg_temp_free_i64(tmp
);
2887 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2888 tcg_temp_free_i64(frn
);
2889 tcg_temp_free_i64(frm
);
2890 tcg_temp_free_i64(dest
);
2892 tcg_temp_free_i64(zf
);
2893 tcg_temp_free_i64(nf
);
2894 tcg_temp_free_i64(vf
);
2896 tcg_temp_free_i64(zero
);
2898 TCGv_i32 frn
, frm
, dest
;
2901 zero
= tcg_const_i32(0);
2903 frn
= tcg_temp_new_i32();
2904 frm
= tcg_temp_new_i32();
2905 dest
= tcg_temp_new_i32();
2906 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2907 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2910 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2914 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2917 case 2: /* ge: N == V -> N ^ V == 0 */
2918 tmp
= tcg_temp_new_i32();
2919 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2920 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2922 tcg_temp_free_i32(tmp
);
2924 case 3: /* gt: !Z && N == V */
2925 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2927 tmp
= tcg_temp_new_i32();
2928 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2929 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2931 tcg_temp_free_i32(tmp
);
2934 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2935 tcg_temp_free_i32(frn
);
2936 tcg_temp_free_i32(frm
);
2937 tcg_temp_free_i32(dest
);
2939 tcg_temp_free_i32(zero
);
2945 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2946 uint32_t rm
, uint32_t dp
)
2948 uint32_t vmin
= extract32(insn
, 6, 1);
2949 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2952 TCGv_i64 frn
, frm
, dest
;
2954 frn
= tcg_temp_new_i64();
2955 frm
= tcg_temp_new_i64();
2956 dest
= tcg_temp_new_i64();
2958 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2959 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2961 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2963 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2965 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2966 tcg_temp_free_i64(frn
);
2967 tcg_temp_free_i64(frm
);
2968 tcg_temp_free_i64(dest
);
2970 TCGv_i32 frn
, frm
, dest
;
2972 frn
= tcg_temp_new_i32();
2973 frm
= tcg_temp_new_i32();
2974 dest
= tcg_temp_new_i32();
2976 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2977 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2979 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2981 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2983 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2984 tcg_temp_free_i32(frn
);
2985 tcg_temp_free_i32(frm
);
2986 tcg_temp_free_i32(dest
);
2989 tcg_temp_free_ptr(fpst
);
2993 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2996 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2999 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3000 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3005 tcg_op
= tcg_temp_new_i64();
3006 tcg_res
= tcg_temp_new_i64();
3007 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3008 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
3009 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3010 tcg_temp_free_i64(tcg_op
);
3011 tcg_temp_free_i64(tcg_res
);
3015 tcg_op
= tcg_temp_new_i32();
3016 tcg_res
= tcg_temp_new_i32();
3017 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3018 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
3019 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3020 tcg_temp_free_i32(tcg_op
);
3021 tcg_temp_free_i32(tcg_res
);
3024 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3025 tcg_temp_free_i32(tcg_rmode
);
3027 tcg_temp_free_ptr(fpst
);
3031 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3034 bool is_signed
= extract32(insn
, 7, 1);
3035 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3036 TCGv_i32 tcg_rmode
, tcg_shift
;
3038 tcg_shift
= tcg_const_i32(0);
3040 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3041 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3044 TCGv_i64 tcg_double
, tcg_res
;
3046 /* Rd is encoded as a single precision register even when the source
3047 * is double precision.
3049 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3050 tcg_double
= tcg_temp_new_i64();
3051 tcg_res
= tcg_temp_new_i64();
3052 tcg_tmp
= tcg_temp_new_i32();
3053 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3055 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3057 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3059 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3060 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3061 tcg_temp_free_i32(tcg_tmp
);
3062 tcg_temp_free_i64(tcg_res
);
3063 tcg_temp_free_i64(tcg_double
);
3065 TCGv_i32 tcg_single
, tcg_res
;
3066 tcg_single
= tcg_temp_new_i32();
3067 tcg_res
= tcg_temp_new_i32();
3068 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3070 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3072 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3074 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3075 tcg_temp_free_i32(tcg_res
);
3076 tcg_temp_free_i32(tcg_single
);
3079 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3080 tcg_temp_free_i32(tcg_rmode
);
3082 tcg_temp_free_i32(tcg_shift
);
3084 tcg_temp_free_ptr(fpst
);
3089 /* Table for converting the most common AArch32 encoding of
3090 * rounding mode to arm_fprounding order (which matches the
3091 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3093 static const uint8_t fp_decode_rm
[] = {
3100 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3102 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3104 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3109 VFP_DREG_D(rd
, insn
);
3110 VFP_DREG_N(rn
, insn
);
3111 VFP_DREG_M(rm
, insn
);
3113 rd
= VFP_SREG_D(insn
);
3114 rn
= VFP_SREG_N(insn
);
3115 rm
= VFP_SREG_M(insn
);
3118 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3119 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3120 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3121 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3122 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3123 /* VRINTA, VRINTN, VRINTP, VRINTM */
3124 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3125 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3126 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3127 /* VCVTA, VCVTN, VCVTP, VCVTM */
3128 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3129 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3134 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3135 (ie. an undefined instruction). */
3136 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3138 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3144 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3148 /* FIXME: this access check should not take precedence over UNDEF
3149 * for invalid encodings; we will generate incorrect syndrome information
3150 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3152 if (s
->fp_excp_el
) {
3153 gen_exception_insn(s
, 4, EXCP_UDEF
,
3154 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3158 if (!s
->vfp_enabled
) {
3159 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3160 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3162 rn
= (insn
>> 16) & 0xf;
3163 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3164 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3169 if (extract32(insn
, 28, 4) == 0xf) {
3170 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3171 * only used in v8 and above.
3173 return disas_vfp_v8_insn(s
, insn
);
3176 dp
= ((insn
& 0xf00) == 0xb00);
3177 switch ((insn
>> 24) & 0xf) {
3179 if (insn
& (1 << 4)) {
3180 /* single register transfer */
3181 rd
= (insn
>> 12) & 0xf;
3186 VFP_DREG_N(rn
, insn
);
3189 if (insn
& 0x00c00060
3190 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3194 pass
= (insn
>> 21) & 1;
3195 if (insn
& (1 << 22)) {
3197 offset
= ((insn
>> 5) & 3) * 8;
3198 } else if (insn
& (1 << 5)) {
3200 offset
= (insn
& (1 << 6)) ? 16 : 0;
3205 if (insn
& ARM_CP_RW_BIT
) {
3207 tmp
= neon_load_reg(rn
, pass
);
3211 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3212 if (insn
& (1 << 23))
3218 if (insn
& (1 << 23)) {
3220 tcg_gen_shri_i32(tmp
, tmp
, 16);
3226 tcg_gen_sari_i32(tmp
, tmp
, 16);
3235 store_reg(s
, rd
, tmp
);
3238 tmp
= load_reg(s
, rd
);
3239 if (insn
& (1 << 23)) {
3242 gen_neon_dup_u8(tmp
, 0);
3243 } else if (size
== 1) {
3244 gen_neon_dup_low16(tmp
);
3246 for (n
= 0; n
<= pass
* 2; n
++) {
3247 tmp2
= tcg_temp_new_i32();
3248 tcg_gen_mov_i32(tmp2
, tmp
);
3249 neon_store_reg(rn
, n
, tmp2
);
3251 neon_store_reg(rn
, n
, tmp
);
3256 tmp2
= neon_load_reg(rn
, pass
);
3257 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3258 tcg_temp_free_i32(tmp2
);
3261 tmp2
= neon_load_reg(rn
, pass
);
3262 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3263 tcg_temp_free_i32(tmp2
);
3268 neon_store_reg(rn
, pass
, tmp
);
3272 if ((insn
& 0x6f) != 0x00)
3274 rn
= VFP_SREG_N(insn
);
3275 if (insn
& ARM_CP_RW_BIT
) {
3277 if (insn
& (1 << 21)) {
3278 /* system register */
3283 /* VFP2 allows access to FSID from userspace.
3284 VFP3 restricts all id registers to privileged
3287 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3290 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3295 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3297 case ARM_VFP_FPINST
:
3298 case ARM_VFP_FPINST2
:
3299 /* Not present in VFP3. */
3301 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3304 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3308 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3309 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3311 tmp
= tcg_temp_new_i32();
3312 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3316 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3323 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3326 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3332 gen_mov_F0_vreg(0, rn
);
3333 tmp
= gen_vfp_mrs();
3336 /* Set the 4 flag bits in the CPSR. */
3338 tcg_temp_free_i32(tmp
);
3340 store_reg(s
, rd
, tmp
);
3344 if (insn
& (1 << 21)) {
3346 /* system register */
3351 /* Writes are ignored. */
3354 tmp
= load_reg(s
, rd
);
3355 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3356 tcg_temp_free_i32(tmp
);
3362 /* TODO: VFP subarchitecture support.
3363 * For now, keep the EN bit only */
3364 tmp
= load_reg(s
, rd
);
3365 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3366 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3369 case ARM_VFP_FPINST
:
3370 case ARM_VFP_FPINST2
:
3374 tmp
= load_reg(s
, rd
);
3375 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3381 tmp
= load_reg(s
, rd
);
3383 gen_mov_vreg_F0(0, rn
);
3388 /* data processing */
3389 /* The opcode is in bits 23, 21, 20 and 6. */
3390 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3394 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3396 /* rn is register number */
3397 VFP_DREG_N(rn
, insn
);
3400 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3401 ((rn
& 0x1e) == 0x6))) {
3402 /* Integer or single/half precision destination. */
3403 rd
= VFP_SREG_D(insn
);
3405 VFP_DREG_D(rd
, insn
);
3408 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3409 ((rn
& 0x1e) == 0x4))) {
3410 /* VCVT from int or half precision is always from S reg
3411 * regardless of dp bit. VCVT with immediate frac_bits
3412 * has same format as SREG_M.
3414 rm
= VFP_SREG_M(insn
);
3416 VFP_DREG_M(rm
, insn
);
3419 rn
= VFP_SREG_N(insn
);
3420 if (op
== 15 && rn
== 15) {
3421 /* Double precision destination. */
3422 VFP_DREG_D(rd
, insn
);
3424 rd
= VFP_SREG_D(insn
);
3426 /* NB that we implicitly rely on the encoding for the frac_bits
3427 * in VCVT of fixed to float being the same as that of an SREG_M
3429 rm
= VFP_SREG_M(insn
);
3432 veclen
= s
->vec_len
;
3433 if (op
== 15 && rn
> 3)
3436 /* Shut up compiler warnings. */
3447 /* Figure out what type of vector operation this is. */
3448 if ((rd
& bank_mask
) == 0) {
3453 delta_d
= (s
->vec_stride
>> 1) + 1;
3455 delta_d
= s
->vec_stride
+ 1;
3457 if ((rm
& bank_mask
) == 0) {
3458 /* mixed scalar/vector */
3467 /* Load the initial operands. */
3472 /* Integer source */
3473 gen_mov_F0_vreg(0, rm
);
3478 gen_mov_F0_vreg(dp
, rd
);
3479 gen_mov_F1_vreg(dp
, rm
);
3483 /* Compare with zero */
3484 gen_mov_F0_vreg(dp
, rd
);
3495 /* Source and destination the same. */
3496 gen_mov_F0_vreg(dp
, rd
);
3502 /* VCVTB, VCVTT: only present with the halfprec extension
3503 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3504 * (we choose to UNDEF)
3506 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3507 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3510 if (!extract32(rn
, 1, 1)) {
3511 /* Half precision source. */
3512 gen_mov_F0_vreg(0, rm
);
3515 /* Otherwise fall through */
3517 /* One source operand. */
3518 gen_mov_F0_vreg(dp
, rm
);
3522 /* Two source operands. */
3523 gen_mov_F0_vreg(dp
, rn
);
3524 gen_mov_F1_vreg(dp
, rm
);
3528 /* Perform the calculation. */
3530 case 0: /* VMLA: fd + (fn * fm) */
3531 /* Note that order of inputs to the add matters for NaNs */
3533 gen_mov_F0_vreg(dp
, rd
);
3536 case 1: /* VMLS: fd + -(fn * fm) */
3539 gen_mov_F0_vreg(dp
, rd
);
3542 case 2: /* VNMLS: -fd + (fn * fm) */
3543 /* Note that it isn't valid to replace (-A + B) with (B - A)
3544 * or similar plausible looking simplifications
3545 * because this will give wrong results for NaNs.
3548 gen_mov_F0_vreg(dp
, rd
);
3552 case 3: /* VNMLA: -fd + -(fn * fm) */
3555 gen_mov_F0_vreg(dp
, rd
);
3559 case 4: /* mul: fn * fm */
3562 case 5: /* nmul: -(fn * fm) */
3566 case 6: /* add: fn + fm */
3569 case 7: /* sub: fn - fm */
3572 case 8: /* div: fn / fm */
3575 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3576 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3577 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3578 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3579 /* These are fused multiply-add, and must be done as one
3580 * floating point operation with no rounding between the
3581 * multiplication and addition steps.
3582 * NB that doing the negations here as separate steps is
3583 * correct : an input NaN should come out with its sign bit
3584 * flipped if it is a negated-input.
3586 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3594 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3596 frd
= tcg_temp_new_i64();
3597 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3600 gen_helper_vfp_negd(frd
, frd
);
3602 fpst
= get_fpstatus_ptr(0);
3603 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3604 cpu_F1d
, frd
, fpst
);
3605 tcg_temp_free_ptr(fpst
);
3606 tcg_temp_free_i64(frd
);
3612 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3614 frd
= tcg_temp_new_i32();
3615 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3617 gen_helper_vfp_negs(frd
, frd
);
3619 fpst
= get_fpstatus_ptr(0);
3620 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3621 cpu_F1s
, frd
, fpst
);
3622 tcg_temp_free_ptr(fpst
);
3623 tcg_temp_free_i32(frd
);
3626 case 14: /* fconst */
3627 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3631 n
= (insn
<< 12) & 0x80000000;
3632 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3639 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3646 tcg_gen_movi_i32(cpu_F0s
, n
);
3649 case 15: /* extension space */
3663 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3664 tmp
= gen_vfp_mrs();
3665 tcg_gen_ext16u_i32(tmp
, tmp
);
3667 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3670 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3673 tcg_temp_free_i32(tmp
);
3675 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3676 tmp
= gen_vfp_mrs();
3677 tcg_gen_shri_i32(tmp
, tmp
, 16);
3679 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3682 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3685 tcg_temp_free_i32(tmp
);
3687 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3688 tmp
= tcg_temp_new_i32();
3690 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3693 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3696 gen_mov_F0_vreg(0, rd
);
3697 tmp2
= gen_vfp_mrs();
3698 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3699 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3700 tcg_temp_free_i32(tmp2
);
3703 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3704 tmp
= tcg_temp_new_i32();
3706 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3709 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3712 tcg_gen_shli_i32(tmp
, tmp
, 16);
3713 gen_mov_F0_vreg(0, rd
);
3714 tmp2
= gen_vfp_mrs();
3715 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3716 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3717 tcg_temp_free_i32(tmp2
);
3729 case 11: /* cmpez */
3733 case 12: /* vrintr */
3735 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3737 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3739 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3741 tcg_temp_free_ptr(fpst
);
3744 case 13: /* vrintz */
3746 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3748 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3749 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3751 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3753 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3755 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3756 tcg_temp_free_i32(tcg_rmode
);
3757 tcg_temp_free_ptr(fpst
);
3760 case 14: /* vrintx */
3762 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3764 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3766 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3768 tcg_temp_free_ptr(fpst
);
3771 case 15: /* single<->double conversion */
3773 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3775 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3777 case 16: /* fuito */
3778 gen_vfp_uito(dp
, 0);
3780 case 17: /* fsito */
3781 gen_vfp_sito(dp
, 0);
3783 case 20: /* fshto */
3784 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3787 gen_vfp_shto(dp
, 16 - rm
, 0);
3789 case 21: /* fslto */
3790 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3793 gen_vfp_slto(dp
, 32 - rm
, 0);
3795 case 22: /* fuhto */
3796 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3799 gen_vfp_uhto(dp
, 16 - rm
, 0);
3801 case 23: /* fulto */
3802 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3805 gen_vfp_ulto(dp
, 32 - rm
, 0);
3807 case 24: /* ftoui */
3808 gen_vfp_toui(dp
, 0);
3810 case 25: /* ftouiz */
3811 gen_vfp_touiz(dp
, 0);
3813 case 26: /* ftosi */
3814 gen_vfp_tosi(dp
, 0);
3816 case 27: /* ftosiz */
3817 gen_vfp_tosiz(dp
, 0);
3819 case 28: /* ftosh */
3820 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3823 gen_vfp_tosh(dp
, 16 - rm
, 0);
3825 case 29: /* ftosl */
3826 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3829 gen_vfp_tosl(dp
, 32 - rm
, 0);
3831 case 30: /* ftouh */
3832 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3835 gen_vfp_touh(dp
, 16 - rm
, 0);
3837 case 31: /* ftoul */
3838 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3841 gen_vfp_toul(dp
, 32 - rm
, 0);
3843 default: /* undefined */
3847 default: /* undefined */
3851 /* Write back the result. */
3852 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3853 /* Comparison, do nothing. */
3854 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3855 (rn
& 0x1e) == 0x6)) {
3856 /* VCVT double to int: always integer result.
3857 * VCVT double to half precision is always a single
3860 gen_mov_vreg_F0(0, rd
);
3861 } else if (op
== 15 && rn
== 15) {
3863 gen_mov_vreg_F0(!dp
, rd
);
3865 gen_mov_vreg_F0(dp
, rd
);
3868 /* break out of the loop if we have finished */
3872 if (op
== 15 && delta_m
== 0) {
3873 /* single source one-many */
3875 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3877 gen_mov_vreg_F0(dp
, rd
);
3881 /* Setup the next operands. */
3883 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3887 /* One source operand. */
3888 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3890 gen_mov_F0_vreg(dp
, rm
);
3892 /* Two source operands. */
3893 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3895 gen_mov_F0_vreg(dp
, rn
);
3897 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3899 gen_mov_F1_vreg(dp
, rm
);
3907 if ((insn
& 0x03e00000) == 0x00400000) {
3908 /* two-register transfer */
3909 rn
= (insn
>> 16) & 0xf;
3910 rd
= (insn
>> 12) & 0xf;
3912 VFP_DREG_M(rm
, insn
);
3914 rm
= VFP_SREG_M(insn
);
3917 if (insn
& ARM_CP_RW_BIT
) {
3920 gen_mov_F0_vreg(0, rm
* 2);
3921 tmp
= gen_vfp_mrs();
3922 store_reg(s
, rd
, tmp
);
3923 gen_mov_F0_vreg(0, rm
* 2 + 1);
3924 tmp
= gen_vfp_mrs();
3925 store_reg(s
, rn
, tmp
);
3927 gen_mov_F0_vreg(0, rm
);
3928 tmp
= gen_vfp_mrs();
3929 store_reg(s
, rd
, tmp
);
3930 gen_mov_F0_vreg(0, rm
+ 1);
3931 tmp
= gen_vfp_mrs();
3932 store_reg(s
, rn
, tmp
);
3937 tmp
= load_reg(s
, rd
);
3939 gen_mov_vreg_F0(0, rm
* 2);
3940 tmp
= load_reg(s
, rn
);
3942 gen_mov_vreg_F0(0, rm
* 2 + 1);
3944 tmp
= load_reg(s
, rd
);
3946 gen_mov_vreg_F0(0, rm
);
3947 tmp
= load_reg(s
, rn
);
3949 gen_mov_vreg_F0(0, rm
+ 1);
3954 rn
= (insn
>> 16) & 0xf;
3956 VFP_DREG_D(rd
, insn
);
3958 rd
= VFP_SREG_D(insn
);
3959 if ((insn
& 0x01200000) == 0x01000000) {
3960 /* Single load/store */
3961 offset
= (insn
& 0xff) << 2;
3962 if ((insn
& (1 << 23)) == 0)
3964 if (s
->thumb
&& rn
== 15) {
3965 /* This is actually UNPREDICTABLE */
3966 addr
= tcg_temp_new_i32();
3967 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3969 addr
= load_reg(s
, rn
);
3971 tcg_gen_addi_i32(addr
, addr
, offset
);
3972 if (insn
& (1 << 20)) {
3973 gen_vfp_ld(s
, dp
, addr
);
3974 gen_mov_vreg_F0(dp
, rd
);
3976 gen_mov_F0_vreg(dp
, rd
);
3977 gen_vfp_st(s
, dp
, addr
);
3979 tcg_temp_free_i32(addr
);
3981 /* load/store multiple */
3982 int w
= insn
& (1 << 21);
3984 n
= (insn
>> 1) & 0x7f;
3988 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3989 /* P == U , W == 1 => UNDEF */
3992 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3993 /* UNPREDICTABLE cases for bad immediates: we choose to
3994 * UNDEF to avoid generating huge numbers of TCG ops
3998 if (rn
== 15 && w
) {
3999 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4003 if (s
->thumb
&& rn
== 15) {
4004 /* This is actually UNPREDICTABLE */
4005 addr
= tcg_temp_new_i32();
4006 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4008 addr
= load_reg(s
, rn
);
4010 if (insn
& (1 << 24)) /* pre-decrement */
4011 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4017 for (i
= 0; i
< n
; i
++) {
4018 if (insn
& ARM_CP_RW_BIT
) {
4020 gen_vfp_ld(s
, dp
, addr
);
4021 gen_mov_vreg_F0(dp
, rd
+ i
);
4024 gen_mov_F0_vreg(dp
, rd
+ i
);
4025 gen_vfp_st(s
, dp
, addr
);
4027 tcg_gen_addi_i32(addr
, addr
, offset
);
4031 if (insn
& (1 << 24))
4032 offset
= -offset
* n
;
4033 else if (dp
&& (insn
& 1))
4039 tcg_gen_addi_i32(addr
, addr
, offset
);
4040 store_reg(s
, rn
, addr
);
4042 tcg_temp_free_i32(addr
);
4048 /* Should never happen. */
4054 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4056 #ifndef CONFIG_USER_ONLY
4057 return (s
->tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4058 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4064 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4066 if (use_goto_tb(s
, dest
)) {
4068 gen_set_pc_im(s
, dest
);
4069 tcg_gen_exit_tb((uintptr_t)s
->tb
+ n
);
4071 gen_set_pc_im(s
, dest
);
4076 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4078 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
4079 /* An indirect jump so that we still trigger the debug exception. */
4084 gen_goto_tb(s
, 0, dest
);
4085 s
->is_jmp
= DISAS_TB_JUMP
;
4089 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4092 tcg_gen_sari_i32(t0
, t0
, 16);
4096 tcg_gen_sari_i32(t1
, t1
, 16);
4099 tcg_gen_mul_i32(t0
, t0
, t1
);
4102 /* Return the mask of PSR bits set by a MSR instruction. */
4103 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4108 if (flags
& (1 << 0))
4110 if (flags
& (1 << 1))
4112 if (flags
& (1 << 2))
4114 if (flags
& (1 << 3))
4117 /* Mask out undefined bits. */
4118 mask
&= ~CPSR_RESERVED
;
4119 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4122 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4123 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4125 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4126 mask
&= ~(CPSR_E
| CPSR_GE
);
4128 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4131 /* Mask out execution state and reserved bits. */
4133 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4135 /* Mask out privileged bits. */
4141 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4142 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4146 /* ??? This is also undefined in system mode. */
4150 tmp
= load_cpu_field(spsr
);
4151 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4152 tcg_gen_andi_i32(t0
, t0
, mask
);
4153 tcg_gen_or_i32(tmp
, tmp
, t0
);
4154 store_cpu_field(tmp
, spsr
);
4156 gen_set_cpsr(t0
, mask
);
4158 tcg_temp_free_i32(t0
);
4163 /* Returns nonzero if access to the PSR is not permitted. */
4164 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4167 tmp
= tcg_temp_new_i32();
4168 tcg_gen_movi_i32(tmp
, val
);
4169 return gen_set_psr(s
, mask
, spsr
, tmp
);
4172 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4173 int *tgtmode
, int *regno
)
4175 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4176 * the target mode and register number, and identify the various
4177 * unpredictable cases.
4178 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4179 * + executed in user mode
4180 * + using R15 as the src/dest register
4181 * + accessing an unimplemented register
4182 * + accessing a register that's inaccessible at current PL/security state*
4183 * + accessing a register that you could access with a different insn
4184 * We choose to UNDEF in all these cases.
4185 * Since we don't know which of the various AArch32 modes we are in
4186 * we have to defer some checks to runtime.
4187 * Accesses to Monitor mode registers from Secure EL1 (which implies
4188 * that EL3 is AArch64) must trap to EL3.
4190 * If the access checks fail this function will emit code to take
4191 * an exception and return false. Otherwise it will return true,
4192 * and set *tgtmode and *regno appropriately.
4194 int exc_target
= default_exception_el(s
);
4196 /* These instructions are present only in ARMv8, or in ARMv7 with the
4197 * Virtualization Extensions.
4199 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4200 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4204 if (IS_USER(s
) || rn
== 15) {
4208 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4209 * of registers into (r, sysm).
4212 /* SPSRs for other modes */
4214 case 0xe: /* SPSR_fiq */
4215 *tgtmode
= ARM_CPU_MODE_FIQ
;
4217 case 0x10: /* SPSR_irq */
4218 *tgtmode
= ARM_CPU_MODE_IRQ
;
4220 case 0x12: /* SPSR_svc */
4221 *tgtmode
= ARM_CPU_MODE_SVC
;
4223 case 0x14: /* SPSR_abt */
4224 *tgtmode
= ARM_CPU_MODE_ABT
;
4226 case 0x16: /* SPSR_und */
4227 *tgtmode
= ARM_CPU_MODE_UND
;
4229 case 0x1c: /* SPSR_mon */
4230 *tgtmode
= ARM_CPU_MODE_MON
;
4232 case 0x1e: /* SPSR_hyp */
4233 *tgtmode
= ARM_CPU_MODE_HYP
;
4235 default: /* unallocated */
4238 /* We arbitrarily assign SPSR a register number of 16. */
4241 /* general purpose registers for other modes */
4243 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4244 *tgtmode
= ARM_CPU_MODE_USR
;
4247 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4248 *tgtmode
= ARM_CPU_MODE_FIQ
;
4251 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4252 *tgtmode
= ARM_CPU_MODE_IRQ
;
4253 *regno
= sysm
& 1 ? 13 : 14;
4255 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4256 *tgtmode
= ARM_CPU_MODE_SVC
;
4257 *regno
= sysm
& 1 ? 13 : 14;
4259 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4260 *tgtmode
= ARM_CPU_MODE_ABT
;
4261 *regno
= sysm
& 1 ? 13 : 14;
4263 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4264 *tgtmode
= ARM_CPU_MODE_UND
;
4265 *regno
= sysm
& 1 ? 13 : 14;
4267 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4268 *tgtmode
= ARM_CPU_MODE_MON
;
4269 *regno
= sysm
& 1 ? 13 : 14;
4271 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4272 *tgtmode
= ARM_CPU_MODE_HYP
;
4273 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4274 *regno
= sysm
& 1 ? 13 : 17;
4276 default: /* unallocated */
4281 /* Catch the 'accessing inaccessible register' cases we can detect
4282 * at translate time.
4285 case ARM_CPU_MODE_MON
:
4286 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4289 if (s
->current_el
== 1) {
4290 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4291 * then accesses to Mon registers trap to EL3
4297 case ARM_CPU_MODE_HYP
:
4298 /* Note that we can forbid accesses from EL2 here because they
4299 * must be from Hyp mode itself
4301 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4312 /* If we get here then some access check did not pass */
4313 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4317 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4319 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4320 int tgtmode
= 0, regno
= 0;
4322 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4326 /* Sync state because msr_banked() can raise exceptions */
4327 gen_set_condexec(s
);
4328 gen_set_pc_im(s
, s
->pc
- 4);
4329 tcg_reg
= load_reg(s
, rn
);
4330 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4331 tcg_regno
= tcg_const_i32(regno
);
4332 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4333 tcg_temp_free_i32(tcg_tgtmode
);
4334 tcg_temp_free_i32(tcg_regno
);
4335 tcg_temp_free_i32(tcg_reg
);
4336 s
->is_jmp
= DISAS_UPDATE
;
4339 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4341 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4342 int tgtmode
= 0, regno
= 0;
4344 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4348 /* Sync state because mrs_banked() can raise exceptions */
4349 gen_set_condexec(s
);
4350 gen_set_pc_im(s
, s
->pc
- 4);
4351 tcg_reg
= tcg_temp_new_i32();
4352 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4353 tcg_regno
= tcg_const_i32(regno
);
4354 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4355 tcg_temp_free_i32(tcg_tgtmode
);
4356 tcg_temp_free_i32(tcg_regno
);
4357 store_reg(s
, rn
, tcg_reg
);
4358 s
->is_jmp
= DISAS_UPDATE
;
4361 /* Generate an old-style exception return. Marks pc as dead. */
4362 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4365 store_reg(s
, 15, pc
);
4366 tmp
= load_cpu_field(spsr
);
4367 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
4368 tcg_temp_free_i32(tmp
);
4369 s
->is_jmp
= DISAS_JUMP
;
4372 /* Generate a v6 exception return. Marks both values as dead. */
4373 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4375 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4376 tcg_temp_free_i32(cpsr
);
4377 store_reg(s
, 15, pc
);
4378 s
->is_jmp
= DISAS_JUMP
;
4381 static void gen_nop_hint(DisasContext
*s
, int val
)
4385 gen_set_pc_im(s
, s
->pc
);
4386 s
->is_jmp
= DISAS_YIELD
;
4389 gen_set_pc_im(s
, s
->pc
);
4390 s
->is_jmp
= DISAS_WFI
;
4393 gen_set_pc_im(s
, s
->pc
);
4394 s
->is_jmp
= DISAS_WFE
;
4398 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4404 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4406 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4409 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4410 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4411 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4416 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4419 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4420 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4421 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4426 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4427 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4428 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4429 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4430 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4432 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4433 switch ((size << 1) | u) { \
4435 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4438 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4441 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4444 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4447 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4450 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4452 default: return 1; \
4455 #define GEN_NEON_INTEGER_OP(name) do { \
4456 switch ((size << 1) | u) { \
4458 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4461 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4464 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4467 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4470 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4473 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4475 default: return 1; \
4478 static TCGv_i32
neon_load_scratch(int scratch
)
4480 TCGv_i32 tmp
= tcg_temp_new_i32();
4481 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4485 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4487 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4488 tcg_temp_free_i32(var
);
4491 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4495 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4497 gen_neon_dup_high16(tmp
);
4499 gen_neon_dup_low16(tmp
);
4502 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4507 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4510 if (!q
&& size
== 2) {
4513 tmp
= tcg_const_i32(rd
);
4514 tmp2
= tcg_const_i32(rm
);
4518 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4521 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4524 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4532 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4535 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4541 tcg_temp_free_i32(tmp
);
4542 tcg_temp_free_i32(tmp2
);
4546 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4549 if (!q
&& size
== 2) {
4552 tmp
= tcg_const_i32(rd
);
4553 tmp2
= tcg_const_i32(rm
);
4557 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4560 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4563 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4571 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4574 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4580 tcg_temp_free_i32(tmp
);
4581 tcg_temp_free_i32(tmp2
);
4585 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4589 rd
= tcg_temp_new_i32();
4590 tmp
= tcg_temp_new_i32();
4592 tcg_gen_shli_i32(rd
, t0
, 8);
4593 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4594 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4595 tcg_gen_or_i32(rd
, rd
, tmp
);
4597 tcg_gen_shri_i32(t1
, t1
, 8);
4598 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4599 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4600 tcg_gen_or_i32(t1
, t1
, tmp
);
4601 tcg_gen_mov_i32(t0
, rd
);
4603 tcg_temp_free_i32(tmp
);
4604 tcg_temp_free_i32(rd
);
4607 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4611 rd
= tcg_temp_new_i32();
4612 tmp
= tcg_temp_new_i32();
4614 tcg_gen_shli_i32(rd
, t0
, 16);
4615 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4616 tcg_gen_or_i32(rd
, rd
, tmp
);
4617 tcg_gen_shri_i32(t1
, t1
, 16);
4618 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4619 tcg_gen_or_i32(t1
, t1
, tmp
);
4620 tcg_gen_mov_i32(t0
, rd
);
4622 tcg_temp_free_i32(tmp
);
4623 tcg_temp_free_i32(rd
);
4631 } neon_ls_element_type
[11] = {
4645 /* Translate a NEON load/store element instruction. Return nonzero if the
4646 instruction is invalid. */
4647 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4666 /* FIXME: this access check should not take precedence over UNDEF
4667 * for invalid encodings; we will generate incorrect syndrome information
4668 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4670 if (s
->fp_excp_el
) {
4671 gen_exception_insn(s
, 4, EXCP_UDEF
,
4672 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4676 if (!s
->vfp_enabled
)
4678 VFP_DREG_D(rd
, insn
);
4679 rn
= (insn
>> 16) & 0xf;
4681 load
= (insn
& (1 << 21)) != 0;
4682 if ((insn
& (1 << 23)) == 0) {
4683 /* Load store all elements. */
4684 op
= (insn
>> 8) & 0xf;
4685 size
= (insn
>> 6) & 3;
4688 /* Catch UNDEF cases for bad values of align field */
4691 if (((insn
>> 5) & 1) == 1) {
4696 if (((insn
>> 4) & 3) == 3) {
4703 nregs
= neon_ls_element_type
[op
].nregs
;
4704 interleave
= neon_ls_element_type
[op
].interleave
;
4705 spacing
= neon_ls_element_type
[op
].spacing
;
4706 if (size
== 3 && (interleave
| spacing
) != 1)
4708 addr
= tcg_temp_new_i32();
4709 load_reg_var(s
, addr
, rn
);
4710 stride
= (1 << size
) * interleave
;
4711 for (reg
= 0; reg
< nregs
; reg
++) {
4712 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4713 load_reg_var(s
, addr
, rn
);
4714 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4715 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4716 load_reg_var(s
, addr
, rn
);
4717 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4720 tmp64
= tcg_temp_new_i64();
4722 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4723 neon_store_reg64(tmp64
, rd
);
4725 neon_load_reg64(tmp64
, rd
);
4726 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4728 tcg_temp_free_i64(tmp64
);
4729 tcg_gen_addi_i32(addr
, addr
, stride
);
4731 for (pass
= 0; pass
< 2; pass
++) {
4734 tmp
= tcg_temp_new_i32();
4735 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4736 neon_store_reg(rd
, pass
, tmp
);
4738 tmp
= neon_load_reg(rd
, pass
);
4739 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4740 tcg_temp_free_i32(tmp
);
4742 tcg_gen_addi_i32(addr
, addr
, stride
);
4743 } else if (size
== 1) {
4745 tmp
= tcg_temp_new_i32();
4746 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4747 tcg_gen_addi_i32(addr
, addr
, stride
);
4748 tmp2
= tcg_temp_new_i32();
4749 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4750 tcg_gen_addi_i32(addr
, addr
, stride
);
4751 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4752 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4753 tcg_temp_free_i32(tmp2
);
4754 neon_store_reg(rd
, pass
, tmp
);
4756 tmp
= neon_load_reg(rd
, pass
);
4757 tmp2
= tcg_temp_new_i32();
4758 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4759 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4760 tcg_temp_free_i32(tmp
);
4761 tcg_gen_addi_i32(addr
, addr
, stride
);
4762 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4763 tcg_temp_free_i32(tmp2
);
4764 tcg_gen_addi_i32(addr
, addr
, stride
);
4766 } else /* size == 0 */ {
4768 TCGV_UNUSED_I32(tmp2
);
4769 for (n
= 0; n
< 4; n
++) {
4770 tmp
= tcg_temp_new_i32();
4771 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4772 tcg_gen_addi_i32(addr
, addr
, stride
);
4776 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4777 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4778 tcg_temp_free_i32(tmp
);
4781 neon_store_reg(rd
, pass
, tmp2
);
4783 tmp2
= neon_load_reg(rd
, pass
);
4784 for (n
= 0; n
< 4; n
++) {
4785 tmp
= tcg_temp_new_i32();
4787 tcg_gen_mov_i32(tmp
, tmp2
);
4789 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4791 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4792 tcg_temp_free_i32(tmp
);
4793 tcg_gen_addi_i32(addr
, addr
, stride
);
4795 tcg_temp_free_i32(tmp2
);
4802 tcg_temp_free_i32(addr
);
4805 size
= (insn
>> 10) & 3;
4807 /* Load single element to all lanes. */
4808 int a
= (insn
>> 4) & 1;
4812 size
= (insn
>> 6) & 3;
4813 nregs
= ((insn
>> 8) & 3) + 1;
4816 if (nregs
!= 4 || a
== 0) {
4819 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4822 if (nregs
== 1 && a
== 1 && size
== 0) {
4825 if (nregs
== 3 && a
== 1) {
4828 addr
= tcg_temp_new_i32();
4829 load_reg_var(s
, addr
, rn
);
4831 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4832 tmp
= gen_load_and_replicate(s
, addr
, size
);
4833 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4834 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4835 if (insn
& (1 << 5)) {
4836 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4837 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4839 tcg_temp_free_i32(tmp
);
4841 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4842 stride
= (insn
& (1 << 5)) ? 2 : 1;
4843 for (reg
= 0; reg
< nregs
; reg
++) {
4844 tmp
= gen_load_and_replicate(s
, addr
, size
);
4845 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4846 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4847 tcg_temp_free_i32(tmp
);
4848 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4852 tcg_temp_free_i32(addr
);
4853 stride
= (1 << size
) * nregs
;
4855 /* Single element. */
4856 int idx
= (insn
>> 4) & 0xf;
4857 pass
= (insn
>> 7) & 1;
4860 shift
= ((insn
>> 5) & 3) * 8;
4864 shift
= ((insn
>> 6) & 1) * 16;
4865 stride
= (insn
& (1 << 5)) ? 2 : 1;
4869 stride
= (insn
& (1 << 6)) ? 2 : 1;
4874 nregs
= ((insn
>> 8) & 3) + 1;
4875 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4878 if (((idx
& (1 << size
)) != 0) ||
4879 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4884 if ((idx
& 1) != 0) {
4889 if (size
== 2 && (idx
& 2) != 0) {
4894 if ((size
== 2) && ((idx
& 3) == 3)) {
4901 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4902 /* Attempts to write off the end of the register file
4903 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4904 * the neon_load_reg() would write off the end of the array.
4908 addr
= tcg_temp_new_i32();
4909 load_reg_var(s
, addr
, rn
);
4910 for (reg
= 0; reg
< nregs
; reg
++) {
4912 tmp
= tcg_temp_new_i32();
4915 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4918 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4921 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4923 default: /* Avoid compiler warnings. */
4927 tmp2
= neon_load_reg(rd
, pass
);
4928 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4929 shift
, size
? 16 : 8);
4930 tcg_temp_free_i32(tmp2
);
4932 neon_store_reg(rd
, pass
, tmp
);
4933 } else { /* Store */
4934 tmp
= neon_load_reg(rd
, pass
);
4936 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4939 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4942 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4945 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4948 tcg_temp_free_i32(tmp
);
4951 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4953 tcg_temp_free_i32(addr
);
4954 stride
= nregs
* (1 << size
);
4960 base
= load_reg(s
, rn
);
4962 tcg_gen_addi_i32(base
, base
, stride
);
4965 index
= load_reg(s
, rm
);
4966 tcg_gen_add_i32(base
, base
, index
);
4967 tcg_temp_free_i32(index
);
4969 store_reg(s
, rn
, base
);
4974 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4975 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4977 tcg_gen_and_i32(t
, t
, c
);
4978 tcg_gen_andc_i32(f
, f
, c
);
4979 tcg_gen_or_i32(dest
, t
, f
);
4982 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4985 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4986 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4987 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4992 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4995 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4996 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4997 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5002 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5005 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5006 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5007 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5012 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5015 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5016 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5017 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5022 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5028 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5029 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5034 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5035 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5042 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5043 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5048 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5049 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5056 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5060 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5061 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5062 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5067 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5068 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5069 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5073 tcg_temp_free_i32(src
);
5076 static inline void gen_neon_addl(int size
)
5079 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5080 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5081 case 2: tcg_gen_add_i64(CPU_V001
); break;
5086 static inline void gen_neon_subl(int size
)
5089 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5090 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5091 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5096 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5099 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5100 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5102 tcg_gen_neg_i64(var
, var
);
5108 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5111 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5112 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5117 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5122 switch ((size
<< 1) | u
) {
5123 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5124 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5125 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5126 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5128 tmp
= gen_muls_i64_i32(a
, b
);
5129 tcg_gen_mov_i64(dest
, tmp
);
5130 tcg_temp_free_i64(tmp
);
5133 tmp
= gen_mulu_i64_i32(a
, b
);
5134 tcg_gen_mov_i64(dest
, tmp
);
5135 tcg_temp_free_i64(tmp
);
5140 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5141 Don't forget to clean them now. */
5143 tcg_temp_free_i32(a
);
5144 tcg_temp_free_i32(b
);
5148 static void gen_neon_narrow_op(int op
, int u
, int size
,
5149 TCGv_i32 dest
, TCGv_i64 src
)
5153 gen_neon_unarrow_sats(size
, dest
, src
);
5155 gen_neon_narrow(size
, dest
, src
);
5159 gen_neon_narrow_satu(size
, dest
, src
);
5161 gen_neon_narrow_sats(size
, dest
, src
);
5166 /* Symbolic constants for op fields for Neon 3-register same-length.
5167 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5170 #define NEON_3R_VHADD 0
5171 #define NEON_3R_VQADD 1
5172 #define NEON_3R_VRHADD 2
5173 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5174 #define NEON_3R_VHSUB 4
5175 #define NEON_3R_VQSUB 5
5176 #define NEON_3R_VCGT 6
5177 #define NEON_3R_VCGE 7
5178 #define NEON_3R_VSHL 8
5179 #define NEON_3R_VQSHL 9
5180 #define NEON_3R_VRSHL 10
5181 #define NEON_3R_VQRSHL 11
5182 #define NEON_3R_VMAX 12
5183 #define NEON_3R_VMIN 13
5184 #define NEON_3R_VABD 14
5185 #define NEON_3R_VABA 15
5186 #define NEON_3R_VADD_VSUB 16
5187 #define NEON_3R_VTST_VCEQ 17
5188 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5189 #define NEON_3R_VMUL 19
5190 #define NEON_3R_VPMAX 20
5191 #define NEON_3R_VPMIN 21
5192 #define NEON_3R_VQDMULH_VQRDMULH 22
5193 #define NEON_3R_VPADD 23
5194 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5195 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5196 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5197 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5198 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5199 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5200 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5201 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5203 static const uint8_t neon_3r_sizes
[] = {
5204 [NEON_3R_VHADD
] = 0x7,
5205 [NEON_3R_VQADD
] = 0xf,
5206 [NEON_3R_VRHADD
] = 0x7,
5207 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5208 [NEON_3R_VHSUB
] = 0x7,
5209 [NEON_3R_VQSUB
] = 0xf,
5210 [NEON_3R_VCGT
] = 0x7,
5211 [NEON_3R_VCGE
] = 0x7,
5212 [NEON_3R_VSHL
] = 0xf,
5213 [NEON_3R_VQSHL
] = 0xf,
5214 [NEON_3R_VRSHL
] = 0xf,
5215 [NEON_3R_VQRSHL
] = 0xf,
5216 [NEON_3R_VMAX
] = 0x7,
5217 [NEON_3R_VMIN
] = 0x7,
5218 [NEON_3R_VABD
] = 0x7,
5219 [NEON_3R_VABA
] = 0x7,
5220 [NEON_3R_VADD_VSUB
] = 0xf,
5221 [NEON_3R_VTST_VCEQ
] = 0x7,
5222 [NEON_3R_VML
] = 0x7,
5223 [NEON_3R_VMUL
] = 0x7,
5224 [NEON_3R_VPMAX
] = 0x7,
5225 [NEON_3R_VPMIN
] = 0x7,
5226 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5227 [NEON_3R_VPADD
] = 0x7,
5228 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5229 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5230 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5231 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5232 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5233 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5234 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5235 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5238 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5239 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5242 #define NEON_2RM_VREV64 0
5243 #define NEON_2RM_VREV32 1
5244 #define NEON_2RM_VREV16 2
5245 #define NEON_2RM_VPADDL 4
5246 #define NEON_2RM_VPADDL_U 5
5247 #define NEON_2RM_AESE 6 /* Includes AESD */
5248 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5249 #define NEON_2RM_VCLS 8
5250 #define NEON_2RM_VCLZ 9
5251 #define NEON_2RM_VCNT 10
5252 #define NEON_2RM_VMVN 11
5253 #define NEON_2RM_VPADAL 12
5254 #define NEON_2RM_VPADAL_U 13
5255 #define NEON_2RM_VQABS 14
5256 #define NEON_2RM_VQNEG 15
5257 #define NEON_2RM_VCGT0 16
5258 #define NEON_2RM_VCGE0 17
5259 #define NEON_2RM_VCEQ0 18
5260 #define NEON_2RM_VCLE0 19
5261 #define NEON_2RM_VCLT0 20
5262 #define NEON_2RM_SHA1H 21
5263 #define NEON_2RM_VABS 22
5264 #define NEON_2RM_VNEG 23
5265 #define NEON_2RM_VCGT0_F 24
5266 #define NEON_2RM_VCGE0_F 25
5267 #define NEON_2RM_VCEQ0_F 26
5268 #define NEON_2RM_VCLE0_F 27
5269 #define NEON_2RM_VCLT0_F 28
5270 #define NEON_2RM_VABS_F 30
5271 #define NEON_2RM_VNEG_F 31
5272 #define NEON_2RM_VSWP 32
5273 #define NEON_2RM_VTRN 33
5274 #define NEON_2RM_VUZP 34
5275 #define NEON_2RM_VZIP 35
5276 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5277 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5278 #define NEON_2RM_VSHLL 38
5279 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5280 #define NEON_2RM_VRINTN 40
5281 #define NEON_2RM_VRINTX 41
5282 #define NEON_2RM_VRINTA 42
5283 #define NEON_2RM_VRINTZ 43
5284 #define NEON_2RM_VCVT_F16_F32 44
5285 #define NEON_2RM_VRINTM 45
5286 #define NEON_2RM_VCVT_F32_F16 46
5287 #define NEON_2RM_VRINTP 47
5288 #define NEON_2RM_VCVTAU 48
5289 #define NEON_2RM_VCVTAS 49
5290 #define NEON_2RM_VCVTNU 50
5291 #define NEON_2RM_VCVTNS 51
5292 #define NEON_2RM_VCVTPU 52
5293 #define NEON_2RM_VCVTPS 53
5294 #define NEON_2RM_VCVTMU 54
5295 #define NEON_2RM_VCVTMS 55
5296 #define NEON_2RM_VRECPE 56
5297 #define NEON_2RM_VRSQRTE 57
5298 #define NEON_2RM_VRECPE_F 58
5299 #define NEON_2RM_VRSQRTE_F 59
5300 #define NEON_2RM_VCVT_FS 60
5301 #define NEON_2RM_VCVT_FU 61
5302 #define NEON_2RM_VCVT_SF 62
5303 #define NEON_2RM_VCVT_UF 63
5305 static int neon_2rm_is_float_op(int op
)
5307 /* Return true if this neon 2reg-misc op is float-to-float */
5308 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5309 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5310 op
== NEON_2RM_VRINTM
||
5311 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5312 op
>= NEON_2RM_VRECPE_F
);
5315 static bool neon_2rm_is_v8_op(int op
)
5317 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5319 case NEON_2RM_VRINTN
:
5320 case NEON_2RM_VRINTA
:
5321 case NEON_2RM_VRINTM
:
5322 case NEON_2RM_VRINTP
:
5323 case NEON_2RM_VRINTZ
:
5324 case NEON_2RM_VRINTX
:
5325 case NEON_2RM_VCVTAU
:
5326 case NEON_2RM_VCVTAS
:
5327 case NEON_2RM_VCVTNU
:
5328 case NEON_2RM_VCVTNS
:
5329 case NEON_2RM_VCVTPU
:
5330 case NEON_2RM_VCVTPS
:
5331 case NEON_2RM_VCVTMU
:
5332 case NEON_2RM_VCVTMS
:
5339 /* Each entry in this array has bit n set if the insn allows
5340 * size value n (otherwise it will UNDEF). Since unallocated
5341 * op values will have no bits set they always UNDEF.
5343 static const uint8_t neon_2rm_sizes
[] = {
5344 [NEON_2RM_VREV64
] = 0x7,
5345 [NEON_2RM_VREV32
] = 0x3,
5346 [NEON_2RM_VREV16
] = 0x1,
5347 [NEON_2RM_VPADDL
] = 0x7,
5348 [NEON_2RM_VPADDL_U
] = 0x7,
5349 [NEON_2RM_AESE
] = 0x1,
5350 [NEON_2RM_AESMC
] = 0x1,
5351 [NEON_2RM_VCLS
] = 0x7,
5352 [NEON_2RM_VCLZ
] = 0x7,
5353 [NEON_2RM_VCNT
] = 0x1,
5354 [NEON_2RM_VMVN
] = 0x1,
5355 [NEON_2RM_VPADAL
] = 0x7,
5356 [NEON_2RM_VPADAL_U
] = 0x7,
5357 [NEON_2RM_VQABS
] = 0x7,
5358 [NEON_2RM_VQNEG
] = 0x7,
5359 [NEON_2RM_VCGT0
] = 0x7,
5360 [NEON_2RM_VCGE0
] = 0x7,
5361 [NEON_2RM_VCEQ0
] = 0x7,
5362 [NEON_2RM_VCLE0
] = 0x7,
5363 [NEON_2RM_VCLT0
] = 0x7,
5364 [NEON_2RM_SHA1H
] = 0x4,
5365 [NEON_2RM_VABS
] = 0x7,
5366 [NEON_2RM_VNEG
] = 0x7,
5367 [NEON_2RM_VCGT0_F
] = 0x4,
5368 [NEON_2RM_VCGE0_F
] = 0x4,
5369 [NEON_2RM_VCEQ0_F
] = 0x4,
5370 [NEON_2RM_VCLE0_F
] = 0x4,
5371 [NEON_2RM_VCLT0_F
] = 0x4,
5372 [NEON_2RM_VABS_F
] = 0x4,
5373 [NEON_2RM_VNEG_F
] = 0x4,
5374 [NEON_2RM_VSWP
] = 0x1,
5375 [NEON_2RM_VTRN
] = 0x7,
5376 [NEON_2RM_VUZP
] = 0x7,
5377 [NEON_2RM_VZIP
] = 0x7,
5378 [NEON_2RM_VMOVN
] = 0x7,
5379 [NEON_2RM_VQMOVN
] = 0x7,
5380 [NEON_2RM_VSHLL
] = 0x7,
5381 [NEON_2RM_SHA1SU1
] = 0x4,
5382 [NEON_2RM_VRINTN
] = 0x4,
5383 [NEON_2RM_VRINTX
] = 0x4,
5384 [NEON_2RM_VRINTA
] = 0x4,
5385 [NEON_2RM_VRINTZ
] = 0x4,
5386 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5387 [NEON_2RM_VRINTM
] = 0x4,
5388 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5389 [NEON_2RM_VRINTP
] = 0x4,
5390 [NEON_2RM_VCVTAU
] = 0x4,
5391 [NEON_2RM_VCVTAS
] = 0x4,
5392 [NEON_2RM_VCVTNU
] = 0x4,
5393 [NEON_2RM_VCVTNS
] = 0x4,
5394 [NEON_2RM_VCVTPU
] = 0x4,
5395 [NEON_2RM_VCVTPS
] = 0x4,
5396 [NEON_2RM_VCVTMU
] = 0x4,
5397 [NEON_2RM_VCVTMS
] = 0x4,
5398 [NEON_2RM_VRECPE
] = 0x4,
5399 [NEON_2RM_VRSQRTE
] = 0x4,
5400 [NEON_2RM_VRECPE_F
] = 0x4,
5401 [NEON_2RM_VRSQRTE_F
] = 0x4,
5402 [NEON_2RM_VCVT_FS
] = 0x4,
5403 [NEON_2RM_VCVT_FU
] = 0x4,
5404 [NEON_2RM_VCVT_SF
] = 0x4,
5405 [NEON_2RM_VCVT_UF
] = 0x4,
5408 /* Translate a NEON data processing instruction. Return nonzero if the
5409 instruction is invalid.
5410 We process data in a mixture of 32-bit and 64-bit chunks.
5411 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5413 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5425 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5428 /* FIXME: this access check should not take precedence over UNDEF
5429 * for invalid encodings; we will generate incorrect syndrome information
5430 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5432 if (s
->fp_excp_el
) {
5433 gen_exception_insn(s
, 4, EXCP_UDEF
,
5434 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5438 if (!s
->vfp_enabled
)
5440 q
= (insn
& (1 << 6)) != 0;
5441 u
= (insn
>> 24) & 1;
5442 VFP_DREG_D(rd
, insn
);
5443 VFP_DREG_N(rn
, insn
);
5444 VFP_DREG_M(rm
, insn
);
5445 size
= (insn
>> 20) & 3;
5446 if ((insn
& (1 << 23)) == 0) {
5447 /* Three register same length. */
5448 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5449 /* Catch invalid op and bad size combinations: UNDEF */
5450 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5453 /* All insns of this form UNDEF for either this condition or the
5454 * superset of cases "Q==1"; we catch the latter later.
5456 if (q
&& ((rd
| rn
| rm
) & 1)) {
5460 * The SHA-1/SHA-256 3-register instructions require special treatment
5461 * here, as their size field is overloaded as an op type selector, and
5462 * they all consume their input in a single pass.
5464 if (op
== NEON_3R_SHA
) {
5468 if (!u
) { /* SHA-1 */
5469 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5472 tmp
= tcg_const_i32(rd
);
5473 tmp2
= tcg_const_i32(rn
);
5474 tmp3
= tcg_const_i32(rm
);
5475 tmp4
= tcg_const_i32(size
);
5476 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5477 tcg_temp_free_i32(tmp4
);
5478 } else { /* SHA-256 */
5479 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5482 tmp
= tcg_const_i32(rd
);
5483 tmp2
= tcg_const_i32(rn
);
5484 tmp3
= tcg_const_i32(rm
);
5487 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5490 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5493 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5497 tcg_temp_free_i32(tmp
);
5498 tcg_temp_free_i32(tmp2
);
5499 tcg_temp_free_i32(tmp3
);
5502 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5503 /* 64-bit element instructions. */
5504 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5505 neon_load_reg64(cpu_V0
, rn
+ pass
);
5506 neon_load_reg64(cpu_V1
, rm
+ pass
);
5510 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5513 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5519 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5522 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5528 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5530 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5535 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5538 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5544 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5546 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5549 case NEON_3R_VQRSHL
:
5551 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5554 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5558 case NEON_3R_VADD_VSUB
:
5560 tcg_gen_sub_i64(CPU_V001
);
5562 tcg_gen_add_i64(CPU_V001
);
5568 neon_store_reg64(cpu_V0
, rd
+ pass
);
5577 case NEON_3R_VQRSHL
:
5580 /* Shift instruction operands are reversed. */
5595 case NEON_3R_FLOAT_ARITH
:
5596 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5598 case NEON_3R_FLOAT_MINMAX
:
5599 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5601 case NEON_3R_FLOAT_CMP
:
5603 /* no encoding for U=0 C=1x */
5607 case NEON_3R_FLOAT_ACMP
:
5612 case NEON_3R_FLOAT_MISC
:
5613 /* VMAXNM/VMINNM in ARMv8 */
5614 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5619 if (u
&& (size
!= 0)) {
5620 /* UNDEF on invalid size for polynomial subcase */
5625 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5633 if (pairwise
&& q
) {
5634 /* All the pairwise insns UNDEF if Q is set */
5638 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5643 tmp
= neon_load_reg(rn
, 0);
5644 tmp2
= neon_load_reg(rn
, 1);
5646 tmp
= neon_load_reg(rm
, 0);
5647 tmp2
= neon_load_reg(rm
, 1);
5651 tmp
= neon_load_reg(rn
, pass
);
5652 tmp2
= neon_load_reg(rm
, pass
);
5656 GEN_NEON_INTEGER_OP(hadd
);
5659 GEN_NEON_INTEGER_OP_ENV(qadd
);
5661 case NEON_3R_VRHADD
:
5662 GEN_NEON_INTEGER_OP(rhadd
);
5664 case NEON_3R_LOGIC
: /* Logic ops. */
5665 switch ((u
<< 2) | size
) {
5667 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5670 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5673 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5676 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5679 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5682 tmp3
= neon_load_reg(rd
, pass
);
5683 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5684 tcg_temp_free_i32(tmp3
);
5687 tmp3
= neon_load_reg(rd
, pass
);
5688 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5689 tcg_temp_free_i32(tmp3
);
5692 tmp3
= neon_load_reg(rd
, pass
);
5693 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5694 tcg_temp_free_i32(tmp3
);
5699 GEN_NEON_INTEGER_OP(hsub
);
5702 GEN_NEON_INTEGER_OP_ENV(qsub
);
5705 GEN_NEON_INTEGER_OP(cgt
);
5708 GEN_NEON_INTEGER_OP(cge
);
5711 GEN_NEON_INTEGER_OP(shl
);
5714 GEN_NEON_INTEGER_OP_ENV(qshl
);
5717 GEN_NEON_INTEGER_OP(rshl
);
5719 case NEON_3R_VQRSHL
:
5720 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5723 GEN_NEON_INTEGER_OP(max
);
5726 GEN_NEON_INTEGER_OP(min
);
5729 GEN_NEON_INTEGER_OP(abd
);
5732 GEN_NEON_INTEGER_OP(abd
);
5733 tcg_temp_free_i32(tmp2
);
5734 tmp2
= neon_load_reg(rd
, pass
);
5735 gen_neon_add(size
, tmp
, tmp2
);
5737 case NEON_3R_VADD_VSUB
:
5738 if (!u
) { /* VADD */
5739 gen_neon_add(size
, tmp
, tmp2
);
5742 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5743 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5744 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5749 case NEON_3R_VTST_VCEQ
:
5750 if (!u
) { /* VTST */
5752 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5753 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5754 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5759 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5760 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5761 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5766 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5768 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5769 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5770 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5773 tcg_temp_free_i32(tmp2
);
5774 tmp2
= neon_load_reg(rd
, pass
);
5776 gen_neon_rsb(size
, tmp
, tmp2
);
5778 gen_neon_add(size
, tmp
, tmp2
);
5782 if (u
) { /* polynomial */
5783 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5784 } else { /* Integer */
5786 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5787 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5788 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5794 GEN_NEON_INTEGER_OP(pmax
);
5797 GEN_NEON_INTEGER_OP(pmin
);
5799 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5800 if (!u
) { /* VQDMULH */
5803 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5806 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5810 } else { /* VQRDMULH */
5813 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5816 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5824 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5825 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5826 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5830 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5832 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5833 switch ((u
<< 2) | size
) {
5836 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5839 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5842 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5847 tcg_temp_free_ptr(fpstatus
);
5850 case NEON_3R_FLOAT_MULTIPLY
:
5852 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5853 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5855 tcg_temp_free_i32(tmp2
);
5856 tmp2
= neon_load_reg(rd
, pass
);
5858 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5860 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5863 tcg_temp_free_ptr(fpstatus
);
5866 case NEON_3R_FLOAT_CMP
:
5868 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5870 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5873 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5875 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5878 tcg_temp_free_ptr(fpstatus
);
5881 case NEON_3R_FLOAT_ACMP
:
5883 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5885 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5887 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5889 tcg_temp_free_ptr(fpstatus
);
5892 case NEON_3R_FLOAT_MINMAX
:
5894 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5896 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5898 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5900 tcg_temp_free_ptr(fpstatus
);
5903 case NEON_3R_FLOAT_MISC
:
5906 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5908 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5910 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5912 tcg_temp_free_ptr(fpstatus
);
5915 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5917 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5923 /* VFMA, VFMS: fused multiply-add */
5924 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5925 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5928 gen_helper_vfp_negs(tmp
, tmp
);
5930 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5931 tcg_temp_free_i32(tmp3
);
5932 tcg_temp_free_ptr(fpstatus
);
5938 tcg_temp_free_i32(tmp2
);
5940 /* Save the result. For elementwise operations we can put it
5941 straight into the destination register. For pairwise operations
5942 we have to be careful to avoid clobbering the source operands. */
5943 if (pairwise
&& rd
== rm
) {
5944 neon_store_scratch(pass
, tmp
);
5946 neon_store_reg(rd
, pass
, tmp
);
5950 if (pairwise
&& rd
== rm
) {
5951 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5952 tmp
= neon_load_scratch(pass
);
5953 neon_store_reg(rd
, pass
, tmp
);
5956 /* End of 3 register same size operations. */
5957 } else if (insn
& (1 << 4)) {
5958 if ((insn
& 0x00380080) != 0) {
5959 /* Two registers and shift. */
5960 op
= (insn
>> 8) & 0xf;
5961 if (insn
& (1 << 7)) {
5969 while ((insn
& (1 << (size
+ 19))) == 0)
5972 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5973 /* To avoid excessive duplication of ops we implement shift
5974 by immediate using the variable shift operations. */
5976 /* Shift by immediate:
5977 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5978 if (q
&& ((rd
| rm
) & 1)) {
5981 if (!u
&& (op
== 4 || op
== 6)) {
5984 /* Right shifts are encoded as N - shift, where N is the
5985 element size in bits. */
5987 shift
= shift
- (1 << (size
+ 3));
5995 imm
= (uint8_t) shift
;
6000 imm
= (uint16_t) shift
;
6011 for (pass
= 0; pass
< count
; pass
++) {
6013 neon_load_reg64(cpu_V0
, rm
+ pass
);
6014 tcg_gen_movi_i64(cpu_V1
, imm
);
6019 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6021 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6026 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6028 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6031 case 5: /* VSHL, VSLI */
6032 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6034 case 6: /* VQSHLU */
6035 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6040 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6043 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6048 if (op
== 1 || op
== 3) {
6050 neon_load_reg64(cpu_V1
, rd
+ pass
);
6051 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6052 } else if (op
== 4 || (op
== 5 && u
)) {
6054 neon_load_reg64(cpu_V1
, rd
+ pass
);
6056 if (shift
< -63 || shift
> 63) {
6060 mask
= 0xffffffffffffffffull
>> -shift
;
6062 mask
= 0xffffffffffffffffull
<< shift
;
6065 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6066 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6068 neon_store_reg64(cpu_V0
, rd
+ pass
);
6069 } else { /* size < 3 */
6070 /* Operands in T0 and T1. */
6071 tmp
= neon_load_reg(rm
, pass
);
6072 tmp2
= tcg_temp_new_i32();
6073 tcg_gen_movi_i32(tmp2
, imm
);
6077 GEN_NEON_INTEGER_OP(shl
);
6081 GEN_NEON_INTEGER_OP(rshl
);
6084 case 5: /* VSHL, VSLI */
6086 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6087 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6088 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6092 case 6: /* VQSHLU */
6095 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6099 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6103 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6111 GEN_NEON_INTEGER_OP_ENV(qshl
);
6114 tcg_temp_free_i32(tmp2
);
6116 if (op
== 1 || op
== 3) {
6118 tmp2
= neon_load_reg(rd
, pass
);
6119 gen_neon_add(size
, tmp
, tmp2
);
6120 tcg_temp_free_i32(tmp2
);
6121 } else if (op
== 4 || (op
== 5 && u
)) {
6126 mask
= 0xff >> -shift
;
6128 mask
= (uint8_t)(0xff << shift
);
6134 mask
= 0xffff >> -shift
;
6136 mask
= (uint16_t)(0xffff << shift
);
6140 if (shift
< -31 || shift
> 31) {
6144 mask
= 0xffffffffu
>> -shift
;
6146 mask
= 0xffffffffu
<< shift
;
6152 tmp2
= neon_load_reg(rd
, pass
);
6153 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6154 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6155 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6156 tcg_temp_free_i32(tmp2
);
6158 neon_store_reg(rd
, pass
, tmp
);
6161 } else if (op
< 10) {
6162 /* Shift by immediate and narrow:
6163 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6164 int input_unsigned
= (op
== 8) ? !u
: u
;
6168 shift
= shift
- (1 << (size
+ 3));
6171 tmp64
= tcg_const_i64(shift
);
6172 neon_load_reg64(cpu_V0
, rm
);
6173 neon_load_reg64(cpu_V1
, rm
+ 1);
6174 for (pass
= 0; pass
< 2; pass
++) {
6182 if (input_unsigned
) {
6183 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6185 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6188 if (input_unsigned
) {
6189 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6191 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6194 tmp
= tcg_temp_new_i32();
6195 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6196 neon_store_reg(rd
, pass
, tmp
);
6198 tcg_temp_free_i64(tmp64
);
6201 imm
= (uint16_t)shift
;
6205 imm
= (uint32_t)shift
;
6207 tmp2
= tcg_const_i32(imm
);
6208 tmp4
= neon_load_reg(rm
+ 1, 0);
6209 tmp5
= neon_load_reg(rm
+ 1, 1);
6210 for (pass
= 0; pass
< 2; pass
++) {
6212 tmp
= neon_load_reg(rm
, 0);
6216 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6219 tmp3
= neon_load_reg(rm
, 1);
6223 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6225 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6226 tcg_temp_free_i32(tmp
);
6227 tcg_temp_free_i32(tmp3
);
6228 tmp
= tcg_temp_new_i32();
6229 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6230 neon_store_reg(rd
, pass
, tmp
);
6232 tcg_temp_free_i32(tmp2
);
6234 } else if (op
== 10) {
6236 if (q
|| (rd
& 1)) {
6239 tmp
= neon_load_reg(rm
, 0);
6240 tmp2
= neon_load_reg(rm
, 1);
6241 for (pass
= 0; pass
< 2; pass
++) {
6245 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6248 /* The shift is less than the width of the source
6249 type, so we can just shift the whole register. */
6250 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6251 /* Widen the result of shift: we need to clear
6252 * the potential overflow bits resulting from
6253 * left bits of the narrow input appearing as
6254 * right bits of left the neighbour narrow
6256 if (size
< 2 || !u
) {
6259 imm
= (0xffu
>> (8 - shift
));
6261 } else if (size
== 1) {
6262 imm
= 0xffff >> (16 - shift
);
6265 imm
= 0xffffffff >> (32 - shift
);
6268 imm64
= imm
| (((uint64_t)imm
) << 32);
6272 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6275 neon_store_reg64(cpu_V0
, rd
+ pass
);
6277 } else if (op
>= 14) {
6278 /* VCVT fixed-point. */
6279 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6282 /* We have already masked out the must-be-1 top bit of imm6,
6283 * hence this 32-shift where the ARM ARM has 64-imm6.
6286 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6287 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6290 gen_vfp_ulto(0, shift
, 1);
6292 gen_vfp_slto(0, shift
, 1);
6295 gen_vfp_toul(0, shift
, 1);
6297 gen_vfp_tosl(0, shift
, 1);
6299 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6304 } else { /* (insn & 0x00380080) == 0 */
6306 if (q
&& (rd
& 1)) {
6310 op
= (insn
>> 8) & 0xf;
6311 /* One register and immediate. */
6312 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6313 invert
= (insn
& (1 << 5)) != 0;
6314 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6315 * We choose to not special-case this and will behave as if a
6316 * valid constant encoding of 0 had been given.
6335 imm
= (imm
<< 8) | (imm
<< 24);
6338 imm
= (imm
<< 8) | 0xff;
6341 imm
= (imm
<< 16) | 0xffff;
6344 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6352 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6353 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6359 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6360 if (op
& 1 && op
< 12) {
6361 tmp
= neon_load_reg(rd
, pass
);
6363 /* The immediate value has already been inverted, so
6365 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6367 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6371 tmp
= tcg_temp_new_i32();
6372 if (op
== 14 && invert
) {
6376 for (n
= 0; n
< 4; n
++) {
6377 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6378 val
|= 0xff << (n
* 8);
6380 tcg_gen_movi_i32(tmp
, val
);
6382 tcg_gen_movi_i32(tmp
, imm
);
6385 neon_store_reg(rd
, pass
, tmp
);
6388 } else { /* (insn & 0x00800010 == 0x00800000) */
6390 op
= (insn
>> 8) & 0xf;
6391 if ((insn
& (1 << 6)) == 0) {
6392 /* Three registers of different lengths. */
6396 /* undefreq: bit 0 : UNDEF if size == 0
6397 * bit 1 : UNDEF if size == 1
6398 * bit 2 : UNDEF if size == 2
6399 * bit 3 : UNDEF if U == 1
6400 * Note that [2:0] set implies 'always UNDEF'
6403 /* prewiden, src1_wide, src2_wide, undefreq */
6404 static const int neon_3reg_wide
[16][4] = {
6405 {1, 0, 0, 0}, /* VADDL */
6406 {1, 1, 0, 0}, /* VADDW */
6407 {1, 0, 0, 0}, /* VSUBL */
6408 {1, 1, 0, 0}, /* VSUBW */
6409 {0, 1, 1, 0}, /* VADDHN */
6410 {0, 0, 0, 0}, /* VABAL */
6411 {0, 1, 1, 0}, /* VSUBHN */
6412 {0, 0, 0, 0}, /* VABDL */
6413 {0, 0, 0, 0}, /* VMLAL */
6414 {0, 0, 0, 9}, /* VQDMLAL */
6415 {0, 0, 0, 0}, /* VMLSL */
6416 {0, 0, 0, 9}, /* VQDMLSL */
6417 {0, 0, 0, 0}, /* Integer VMULL */
6418 {0, 0, 0, 1}, /* VQDMULL */
6419 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6420 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6423 prewiden
= neon_3reg_wide
[op
][0];
6424 src1_wide
= neon_3reg_wide
[op
][1];
6425 src2_wide
= neon_3reg_wide
[op
][2];
6426 undefreq
= neon_3reg_wide
[op
][3];
6428 if ((undefreq
& (1 << size
)) ||
6429 ((undefreq
& 8) && u
)) {
6432 if ((src1_wide
&& (rn
& 1)) ||
6433 (src2_wide
&& (rm
& 1)) ||
6434 (!src2_wide
&& (rd
& 1))) {
6438 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6439 * outside the loop below as it only performs a single pass.
6441 if (op
== 14 && size
== 2) {
6442 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6444 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6447 tcg_rn
= tcg_temp_new_i64();
6448 tcg_rm
= tcg_temp_new_i64();
6449 tcg_rd
= tcg_temp_new_i64();
6450 neon_load_reg64(tcg_rn
, rn
);
6451 neon_load_reg64(tcg_rm
, rm
);
6452 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6453 neon_store_reg64(tcg_rd
, rd
);
6454 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6455 neon_store_reg64(tcg_rd
, rd
+ 1);
6456 tcg_temp_free_i64(tcg_rn
);
6457 tcg_temp_free_i64(tcg_rm
);
6458 tcg_temp_free_i64(tcg_rd
);
6462 /* Avoid overlapping operands. Wide source operands are
6463 always aligned so will never overlap with wide
6464 destinations in problematic ways. */
6465 if (rd
== rm
&& !src2_wide
) {
6466 tmp
= neon_load_reg(rm
, 1);
6467 neon_store_scratch(2, tmp
);
6468 } else if (rd
== rn
&& !src1_wide
) {
6469 tmp
= neon_load_reg(rn
, 1);
6470 neon_store_scratch(2, tmp
);
6472 TCGV_UNUSED_I32(tmp3
);
6473 for (pass
= 0; pass
< 2; pass
++) {
6475 neon_load_reg64(cpu_V0
, rn
+ pass
);
6476 TCGV_UNUSED_I32(tmp
);
6478 if (pass
== 1 && rd
== rn
) {
6479 tmp
= neon_load_scratch(2);
6481 tmp
= neon_load_reg(rn
, pass
);
6484 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6488 neon_load_reg64(cpu_V1
, rm
+ pass
);
6489 TCGV_UNUSED_I32(tmp2
);
6491 if (pass
== 1 && rd
== rm
) {
6492 tmp2
= neon_load_scratch(2);
6494 tmp2
= neon_load_reg(rm
, pass
);
6497 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6501 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6502 gen_neon_addl(size
);
6504 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6505 gen_neon_subl(size
);
6507 case 5: case 7: /* VABAL, VABDL */
6508 switch ((size
<< 1) | u
) {
6510 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6513 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6516 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6519 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6522 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6525 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6529 tcg_temp_free_i32(tmp2
);
6530 tcg_temp_free_i32(tmp
);
6532 case 8: case 9: case 10: case 11: case 12: case 13:
6533 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6534 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6536 case 14: /* Polynomial VMULL */
6537 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6538 tcg_temp_free_i32(tmp2
);
6539 tcg_temp_free_i32(tmp
);
6541 default: /* 15 is RESERVED: caught earlier */
6546 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6547 neon_store_reg64(cpu_V0
, rd
+ pass
);
6548 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6550 neon_load_reg64(cpu_V1
, rd
+ pass
);
6552 case 10: /* VMLSL */
6553 gen_neon_negl(cpu_V0
, size
);
6555 case 5: case 8: /* VABAL, VMLAL */
6556 gen_neon_addl(size
);
6558 case 9: case 11: /* VQDMLAL, VQDMLSL */
6559 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6561 gen_neon_negl(cpu_V0
, size
);
6563 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6568 neon_store_reg64(cpu_V0
, rd
+ pass
);
6569 } else if (op
== 4 || op
== 6) {
6570 /* Narrowing operation. */
6571 tmp
= tcg_temp_new_i32();
6575 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6578 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6581 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6582 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6589 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6592 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6595 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6596 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6597 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6605 neon_store_reg(rd
, 0, tmp3
);
6606 neon_store_reg(rd
, 1, tmp
);
6609 /* Write back the result. */
6610 neon_store_reg64(cpu_V0
, rd
+ pass
);
6614 /* Two registers and a scalar. NB that for ops of this form
6615 * the ARM ARM labels bit 24 as Q, but it is in our variable
6622 case 1: /* Float VMLA scalar */
6623 case 5: /* Floating point VMLS scalar */
6624 case 9: /* Floating point VMUL scalar */
6629 case 0: /* Integer VMLA scalar */
6630 case 4: /* Integer VMLS scalar */
6631 case 8: /* Integer VMUL scalar */
6632 case 12: /* VQDMULH scalar */
6633 case 13: /* VQRDMULH scalar */
6634 if (u
&& ((rd
| rn
) & 1)) {
6637 tmp
= neon_get_scalar(size
, rm
);
6638 neon_store_scratch(0, tmp
);
6639 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6640 tmp
= neon_load_scratch(0);
6641 tmp2
= neon_load_reg(rn
, pass
);
6644 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6646 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6648 } else if (op
== 13) {
6650 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6652 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6654 } else if (op
& 1) {
6655 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6656 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6657 tcg_temp_free_ptr(fpstatus
);
6660 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6661 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6662 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6666 tcg_temp_free_i32(tmp2
);
6669 tmp2
= neon_load_reg(rd
, pass
);
6672 gen_neon_add(size
, tmp
, tmp2
);
6676 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6677 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6678 tcg_temp_free_ptr(fpstatus
);
6682 gen_neon_rsb(size
, tmp
, tmp2
);
6686 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6687 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6688 tcg_temp_free_ptr(fpstatus
);
6694 tcg_temp_free_i32(tmp2
);
6696 neon_store_reg(rd
, pass
, tmp
);
6699 case 3: /* VQDMLAL scalar */
6700 case 7: /* VQDMLSL scalar */
6701 case 11: /* VQDMULL scalar */
6706 case 2: /* VMLAL sclar */
6707 case 6: /* VMLSL scalar */
6708 case 10: /* VMULL scalar */
6712 tmp2
= neon_get_scalar(size
, rm
);
6713 /* We need a copy of tmp2 because gen_neon_mull
6714 * deletes it during pass 0. */
6715 tmp4
= tcg_temp_new_i32();
6716 tcg_gen_mov_i32(tmp4
, tmp2
);
6717 tmp3
= neon_load_reg(rn
, 1);
6719 for (pass
= 0; pass
< 2; pass
++) {
6721 tmp
= neon_load_reg(rn
, 0);
6726 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6728 neon_load_reg64(cpu_V1
, rd
+ pass
);
6732 gen_neon_negl(cpu_V0
, size
);
6735 gen_neon_addl(size
);
6738 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6740 gen_neon_negl(cpu_V0
, size
);
6742 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6748 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6753 neon_store_reg64(cpu_V0
, rd
+ pass
);
6758 default: /* 14 and 15 are RESERVED */
6762 } else { /* size == 3 */
6765 imm
= (insn
>> 8) & 0xf;
6770 if (q
&& ((rd
| rn
| rm
) & 1)) {
6775 neon_load_reg64(cpu_V0
, rn
);
6777 neon_load_reg64(cpu_V1
, rn
+ 1);
6779 } else if (imm
== 8) {
6780 neon_load_reg64(cpu_V0
, rn
+ 1);
6782 neon_load_reg64(cpu_V1
, rm
);
6785 tmp64
= tcg_temp_new_i64();
6787 neon_load_reg64(cpu_V0
, rn
);
6788 neon_load_reg64(tmp64
, rn
+ 1);
6790 neon_load_reg64(cpu_V0
, rn
+ 1);
6791 neon_load_reg64(tmp64
, rm
);
6793 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6794 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6795 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6797 neon_load_reg64(cpu_V1
, rm
);
6799 neon_load_reg64(cpu_V1
, rm
+ 1);
6802 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6803 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6804 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6805 tcg_temp_free_i64(tmp64
);
6808 neon_load_reg64(cpu_V0
, rn
);
6809 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6810 neon_load_reg64(cpu_V1
, rm
);
6811 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6812 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6814 neon_store_reg64(cpu_V0
, rd
);
6816 neon_store_reg64(cpu_V1
, rd
+ 1);
6818 } else if ((insn
& (1 << 11)) == 0) {
6819 /* Two register misc. */
6820 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6821 size
= (insn
>> 18) & 3;
6822 /* UNDEF for unknown op values and bad op-size combinations */
6823 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6826 if (neon_2rm_is_v8_op(op
) &&
6827 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6830 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6831 q
&& ((rm
| rd
) & 1)) {
6835 case NEON_2RM_VREV64
:
6836 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6837 tmp
= neon_load_reg(rm
, pass
* 2);
6838 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6840 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6841 case 1: gen_swap_half(tmp
); break;
6842 case 2: /* no-op */ break;
6845 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6847 neon_store_reg(rd
, pass
* 2, tmp2
);
6850 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6851 case 1: gen_swap_half(tmp2
); break;
6854 neon_store_reg(rd
, pass
* 2, tmp2
);
6858 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6859 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6860 for (pass
= 0; pass
< q
+ 1; pass
++) {
6861 tmp
= neon_load_reg(rm
, pass
* 2);
6862 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6863 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6864 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6866 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6867 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6868 case 2: tcg_gen_add_i64(CPU_V001
); break;
6871 if (op
>= NEON_2RM_VPADAL
) {
6873 neon_load_reg64(cpu_V1
, rd
+ pass
);
6874 gen_neon_addl(size
);
6876 neon_store_reg64(cpu_V0
, rd
+ pass
);
6882 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6883 tmp
= neon_load_reg(rm
, n
);
6884 tmp2
= neon_load_reg(rd
, n
+ 1);
6885 neon_store_reg(rm
, n
, tmp2
);
6886 neon_store_reg(rd
, n
+ 1, tmp
);
6893 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6898 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6902 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6903 /* also VQMOVUN; op field and mnemonics don't line up */
6907 TCGV_UNUSED_I32(tmp2
);
6908 for (pass
= 0; pass
< 2; pass
++) {
6909 neon_load_reg64(cpu_V0
, rm
+ pass
);
6910 tmp
= tcg_temp_new_i32();
6911 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6916 neon_store_reg(rd
, 0, tmp2
);
6917 neon_store_reg(rd
, 1, tmp
);
6921 case NEON_2RM_VSHLL
:
6922 if (q
|| (rd
& 1)) {
6925 tmp
= neon_load_reg(rm
, 0);
6926 tmp2
= neon_load_reg(rm
, 1);
6927 for (pass
= 0; pass
< 2; pass
++) {
6930 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6931 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6932 neon_store_reg64(cpu_V0
, rd
+ pass
);
6935 case NEON_2RM_VCVT_F16_F32
:
6936 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6940 tmp
= tcg_temp_new_i32();
6941 tmp2
= tcg_temp_new_i32();
6942 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6943 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6944 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6945 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6946 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6947 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6948 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6949 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6950 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6951 neon_store_reg(rd
, 0, tmp2
);
6952 tmp2
= tcg_temp_new_i32();
6953 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6954 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6955 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6956 neon_store_reg(rd
, 1, tmp2
);
6957 tcg_temp_free_i32(tmp
);
6959 case NEON_2RM_VCVT_F32_F16
:
6960 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6964 tmp3
= tcg_temp_new_i32();
6965 tmp
= neon_load_reg(rm
, 0);
6966 tmp2
= neon_load_reg(rm
, 1);
6967 tcg_gen_ext16u_i32(tmp3
, tmp
);
6968 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6969 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6970 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6971 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6972 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6973 tcg_temp_free_i32(tmp
);
6974 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6975 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6976 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6977 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6978 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6979 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6980 tcg_temp_free_i32(tmp2
);
6981 tcg_temp_free_i32(tmp3
);
6983 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6984 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6985 || ((rm
| rd
) & 1)) {
6988 tmp
= tcg_const_i32(rd
);
6989 tmp2
= tcg_const_i32(rm
);
6991 /* Bit 6 is the lowest opcode bit; it distinguishes between
6992 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6994 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6996 if (op
== NEON_2RM_AESE
) {
6997 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6999 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
7001 tcg_temp_free_i32(tmp
);
7002 tcg_temp_free_i32(tmp2
);
7003 tcg_temp_free_i32(tmp3
);
7005 case NEON_2RM_SHA1H
:
7006 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7007 || ((rm
| rd
) & 1)) {
7010 tmp
= tcg_const_i32(rd
);
7011 tmp2
= tcg_const_i32(rm
);
7013 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
7015 tcg_temp_free_i32(tmp
);
7016 tcg_temp_free_i32(tmp2
);
7018 case NEON_2RM_SHA1SU1
:
7019 if ((rm
| rd
) & 1) {
7022 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7024 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7027 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7030 tmp
= tcg_const_i32(rd
);
7031 tmp2
= tcg_const_i32(rm
);
7033 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
7035 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7037 tcg_temp_free_i32(tmp
);
7038 tcg_temp_free_i32(tmp2
);
7042 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7043 if (neon_2rm_is_float_op(op
)) {
7044 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7045 neon_reg_offset(rm
, pass
));
7046 TCGV_UNUSED_I32(tmp
);
7048 tmp
= neon_load_reg(rm
, pass
);
7051 case NEON_2RM_VREV32
:
7053 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7054 case 1: gen_swap_half(tmp
); break;
7058 case NEON_2RM_VREV16
:
7063 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7064 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7065 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7071 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7072 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7073 case 2: gen_helper_clz(tmp
, tmp
); break;
7078 gen_helper_neon_cnt_u8(tmp
, tmp
);
7081 tcg_gen_not_i32(tmp
, tmp
);
7083 case NEON_2RM_VQABS
:
7086 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7089 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7092 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7097 case NEON_2RM_VQNEG
:
7100 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7103 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7106 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7111 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7112 tmp2
= tcg_const_i32(0);
7114 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7115 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7116 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7119 tcg_temp_free_i32(tmp2
);
7120 if (op
== NEON_2RM_VCLE0
) {
7121 tcg_gen_not_i32(tmp
, tmp
);
7124 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7125 tmp2
= tcg_const_i32(0);
7127 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7128 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7129 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7132 tcg_temp_free_i32(tmp2
);
7133 if (op
== NEON_2RM_VCLT0
) {
7134 tcg_gen_not_i32(tmp
, tmp
);
7137 case NEON_2RM_VCEQ0
:
7138 tmp2
= tcg_const_i32(0);
7140 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7141 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7142 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7145 tcg_temp_free_i32(tmp2
);
7149 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7150 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7151 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7156 tmp2
= tcg_const_i32(0);
7157 gen_neon_rsb(size
, tmp
, tmp2
);
7158 tcg_temp_free_i32(tmp2
);
7160 case NEON_2RM_VCGT0_F
:
7162 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7163 tmp2
= tcg_const_i32(0);
7164 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7165 tcg_temp_free_i32(tmp2
);
7166 tcg_temp_free_ptr(fpstatus
);
7169 case NEON_2RM_VCGE0_F
:
7171 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7172 tmp2
= tcg_const_i32(0);
7173 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7174 tcg_temp_free_i32(tmp2
);
7175 tcg_temp_free_ptr(fpstatus
);
7178 case NEON_2RM_VCEQ0_F
:
7180 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7181 tmp2
= tcg_const_i32(0);
7182 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7183 tcg_temp_free_i32(tmp2
);
7184 tcg_temp_free_ptr(fpstatus
);
7187 case NEON_2RM_VCLE0_F
:
7189 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7190 tmp2
= tcg_const_i32(0);
7191 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7192 tcg_temp_free_i32(tmp2
);
7193 tcg_temp_free_ptr(fpstatus
);
7196 case NEON_2RM_VCLT0_F
:
7198 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7199 tmp2
= tcg_const_i32(0);
7200 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7201 tcg_temp_free_i32(tmp2
);
7202 tcg_temp_free_ptr(fpstatus
);
7205 case NEON_2RM_VABS_F
:
7208 case NEON_2RM_VNEG_F
:
7212 tmp2
= neon_load_reg(rd
, pass
);
7213 neon_store_reg(rm
, pass
, tmp2
);
7216 tmp2
= neon_load_reg(rd
, pass
);
7218 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7219 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7222 neon_store_reg(rm
, pass
, tmp2
);
7224 case NEON_2RM_VRINTN
:
7225 case NEON_2RM_VRINTA
:
7226 case NEON_2RM_VRINTM
:
7227 case NEON_2RM_VRINTP
:
7228 case NEON_2RM_VRINTZ
:
7231 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7234 if (op
== NEON_2RM_VRINTZ
) {
7235 rmode
= FPROUNDING_ZERO
;
7237 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7240 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7241 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7243 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7244 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7246 tcg_temp_free_ptr(fpstatus
);
7247 tcg_temp_free_i32(tcg_rmode
);
7250 case NEON_2RM_VRINTX
:
7252 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7253 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7254 tcg_temp_free_ptr(fpstatus
);
7257 case NEON_2RM_VCVTAU
:
7258 case NEON_2RM_VCVTAS
:
7259 case NEON_2RM_VCVTNU
:
7260 case NEON_2RM_VCVTNS
:
7261 case NEON_2RM_VCVTPU
:
7262 case NEON_2RM_VCVTPS
:
7263 case NEON_2RM_VCVTMU
:
7264 case NEON_2RM_VCVTMS
:
7266 bool is_signed
= !extract32(insn
, 7, 1);
7267 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7268 TCGv_i32 tcg_rmode
, tcg_shift
;
7269 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7271 tcg_shift
= tcg_const_i32(0);
7272 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7273 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7277 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7280 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7284 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7286 tcg_temp_free_i32(tcg_rmode
);
7287 tcg_temp_free_i32(tcg_shift
);
7288 tcg_temp_free_ptr(fpst
);
7291 case NEON_2RM_VRECPE
:
7293 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7294 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7295 tcg_temp_free_ptr(fpstatus
);
7298 case NEON_2RM_VRSQRTE
:
7300 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7301 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7302 tcg_temp_free_ptr(fpstatus
);
7305 case NEON_2RM_VRECPE_F
:
7307 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7308 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7309 tcg_temp_free_ptr(fpstatus
);
7312 case NEON_2RM_VRSQRTE_F
:
7314 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7315 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7316 tcg_temp_free_ptr(fpstatus
);
7319 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7322 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7325 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7326 gen_vfp_tosiz(0, 1);
7328 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7329 gen_vfp_touiz(0, 1);
7332 /* Reserved op values were caught by the
7333 * neon_2rm_sizes[] check earlier.
7337 if (neon_2rm_is_float_op(op
)) {
7338 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7339 neon_reg_offset(rd
, pass
));
7341 neon_store_reg(rd
, pass
, tmp
);
7346 } else if ((insn
& (1 << 10)) == 0) {
7348 int n
= ((insn
>> 8) & 3) + 1;
7349 if ((rn
+ n
) > 32) {
7350 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7351 * helper function running off the end of the register file.
7356 if (insn
& (1 << 6)) {
7357 tmp
= neon_load_reg(rd
, 0);
7359 tmp
= tcg_temp_new_i32();
7360 tcg_gen_movi_i32(tmp
, 0);
7362 tmp2
= neon_load_reg(rm
, 0);
7363 tmp4
= tcg_const_i32(rn
);
7364 tmp5
= tcg_const_i32(n
);
7365 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7366 tcg_temp_free_i32(tmp
);
7367 if (insn
& (1 << 6)) {
7368 tmp
= neon_load_reg(rd
, 1);
7370 tmp
= tcg_temp_new_i32();
7371 tcg_gen_movi_i32(tmp
, 0);
7373 tmp3
= neon_load_reg(rm
, 1);
7374 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7375 tcg_temp_free_i32(tmp5
);
7376 tcg_temp_free_i32(tmp4
);
7377 neon_store_reg(rd
, 0, tmp2
);
7378 neon_store_reg(rd
, 1, tmp3
);
7379 tcg_temp_free_i32(tmp
);
7380 } else if ((insn
& 0x380) == 0) {
7382 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7385 if (insn
& (1 << 19)) {
7386 tmp
= neon_load_reg(rm
, 1);
7388 tmp
= neon_load_reg(rm
, 0);
7390 if (insn
& (1 << 16)) {
7391 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7392 } else if (insn
& (1 << 17)) {
7393 if ((insn
>> 18) & 1)
7394 gen_neon_dup_high16(tmp
);
7396 gen_neon_dup_low16(tmp
);
7398 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7399 tmp2
= tcg_temp_new_i32();
7400 tcg_gen_mov_i32(tmp2
, tmp
);
7401 neon_store_reg(rd
, pass
, tmp2
);
7403 tcg_temp_free_i32(tmp
);
7412 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7414 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7415 const ARMCPRegInfo
*ri
;
7417 cpnum
= (insn
>> 8) & 0xf;
7419 /* First check for coprocessor space used for XScale/iwMMXt insns */
7420 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7421 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7424 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7425 return disas_iwmmxt_insn(s
, insn
);
7426 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7427 return disas_dsp_insn(s
, insn
);
7432 /* Otherwise treat as a generic register access */
7433 is64
= (insn
& (1 << 25)) == 0;
7434 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7442 opc1
= (insn
>> 4) & 0xf;
7444 rt2
= (insn
>> 16) & 0xf;
7446 crn
= (insn
>> 16) & 0xf;
7447 opc1
= (insn
>> 21) & 7;
7448 opc2
= (insn
>> 5) & 7;
7451 isread
= (insn
>> 20) & 1;
7452 rt
= (insn
>> 12) & 0xf;
7454 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7455 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7457 /* Check access permissions */
7458 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7463 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7464 /* Emit code to perform further access permissions checks at
7465 * runtime; this may result in an exception.
7466 * Note that on XScale all cp0..c13 registers do an access check
7467 * call in order to handle c15_cpar.
7470 TCGv_i32 tcg_syn
, tcg_isread
;
7473 /* Note that since we are an implementation which takes an
7474 * exception on a trapped conditional instruction only if the
7475 * instruction passes its condition code check, we can take
7476 * advantage of the clause in the ARM ARM that allows us to set
7477 * the COND field in the instruction to 0xE in all cases.
7478 * We could fish the actual condition out of the insn (ARM)
7479 * or the condexec bits (Thumb) but it isn't necessary.
7484 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7487 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7493 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7496 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7501 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7502 * so this can only happen if this is an ARMv7 or earlier CPU,
7503 * in which case the syndrome information won't actually be
7506 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7507 syndrome
= syn_uncategorized();
7511 gen_set_condexec(s
);
7512 gen_set_pc_im(s
, s
->pc
- 4);
7513 tmpptr
= tcg_const_ptr(ri
);
7514 tcg_syn
= tcg_const_i32(syndrome
);
7515 tcg_isread
= tcg_const_i32(isread
);
7516 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7518 tcg_temp_free_ptr(tmpptr
);
7519 tcg_temp_free_i32(tcg_syn
);
7520 tcg_temp_free_i32(tcg_isread
);
7523 /* Handle special cases first */
7524 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7531 gen_set_pc_im(s
, s
->pc
);
7532 s
->is_jmp
= DISAS_WFI
;
7538 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7547 if (ri
->type
& ARM_CP_CONST
) {
7548 tmp64
= tcg_const_i64(ri
->resetvalue
);
7549 } else if (ri
->readfn
) {
7551 tmp64
= tcg_temp_new_i64();
7552 tmpptr
= tcg_const_ptr(ri
);
7553 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7554 tcg_temp_free_ptr(tmpptr
);
7556 tmp64
= tcg_temp_new_i64();
7557 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7559 tmp
= tcg_temp_new_i32();
7560 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7561 store_reg(s
, rt
, tmp
);
7562 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7563 tmp
= tcg_temp_new_i32();
7564 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7565 tcg_temp_free_i64(tmp64
);
7566 store_reg(s
, rt2
, tmp
);
7569 if (ri
->type
& ARM_CP_CONST
) {
7570 tmp
= tcg_const_i32(ri
->resetvalue
);
7571 } else if (ri
->readfn
) {
7573 tmp
= tcg_temp_new_i32();
7574 tmpptr
= tcg_const_ptr(ri
);
7575 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7576 tcg_temp_free_ptr(tmpptr
);
7578 tmp
= load_cpu_offset(ri
->fieldoffset
);
7581 /* Destination register of r15 for 32 bit loads sets
7582 * the condition codes from the high 4 bits of the value
7585 tcg_temp_free_i32(tmp
);
7587 store_reg(s
, rt
, tmp
);
7592 if (ri
->type
& ARM_CP_CONST
) {
7593 /* If not forbidden by access permissions, treat as WI */
7598 TCGv_i32 tmplo
, tmphi
;
7599 TCGv_i64 tmp64
= tcg_temp_new_i64();
7600 tmplo
= load_reg(s
, rt
);
7601 tmphi
= load_reg(s
, rt2
);
7602 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7603 tcg_temp_free_i32(tmplo
);
7604 tcg_temp_free_i32(tmphi
);
7606 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7607 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7608 tcg_temp_free_ptr(tmpptr
);
7610 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7612 tcg_temp_free_i64(tmp64
);
7617 tmp
= load_reg(s
, rt
);
7618 tmpptr
= tcg_const_ptr(ri
);
7619 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7620 tcg_temp_free_ptr(tmpptr
);
7621 tcg_temp_free_i32(tmp
);
7623 TCGv_i32 tmp
= load_reg(s
, rt
);
7624 store_cpu_offset(tmp
, ri
->fieldoffset
);
7629 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7630 /* I/O operations must end the TB here (whether read or write) */
7633 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7634 /* We default to ending the TB on a coprocessor register write,
7635 * but allow this to be suppressed by the register definition
7636 * (usually only necessary to work around guest bugs).
7644 /* Unknown register; this might be a guest error or a QEMU
7645 * unimplemented feature.
7648 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7649 "64 bit system register cp:%d opc1: %d crm:%d "
7651 isread
? "read" : "write", cpnum
, opc1
, crm
,
7652 s
->ns
? "non-secure" : "secure");
7654 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7655 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7657 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7658 s
->ns
? "non-secure" : "secure");
7665 /* Store a 64-bit value to a register pair. Clobbers val. */
7666 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7669 tmp
= tcg_temp_new_i32();
7670 tcg_gen_extrl_i64_i32(tmp
, val
);
7671 store_reg(s
, rlow
, tmp
);
7672 tmp
= tcg_temp_new_i32();
7673 tcg_gen_shri_i64(val
, val
, 32);
7674 tcg_gen_extrl_i64_i32(tmp
, val
);
7675 store_reg(s
, rhigh
, tmp
);
7678 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7679 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7684 /* Load value and extend to 64 bits. */
7685 tmp
= tcg_temp_new_i64();
7686 tmp2
= load_reg(s
, rlow
);
7687 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7688 tcg_temp_free_i32(tmp2
);
7689 tcg_gen_add_i64(val
, val
, tmp
);
7690 tcg_temp_free_i64(tmp
);
7693 /* load and add a 64-bit value from a register pair. */
7694 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7700 /* Load 64-bit value rd:rn. */
7701 tmpl
= load_reg(s
, rlow
);
7702 tmph
= load_reg(s
, rhigh
);
7703 tmp
= tcg_temp_new_i64();
7704 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7705 tcg_temp_free_i32(tmpl
);
7706 tcg_temp_free_i32(tmph
);
7707 tcg_gen_add_i64(val
, val
, tmp
);
7708 tcg_temp_free_i64(tmp
);
7711 /* Set N and Z flags from hi|lo. */
7712 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7714 tcg_gen_mov_i32(cpu_NF
, hi
);
7715 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7718 /* Load/Store exclusive instructions are implemented by remembering
7719 the value/address loaded, and seeing if these are the same
7720 when the store is performed. This should be sufficient to implement
7721 the architecturally mandated semantics, and avoids having to monitor
7724 In system emulation mode only one CPU will be running at once, so
7725 this sequence is effectively atomic. In user emulation mode we
7726 throw an exception and handle the atomic operation elsewhere. */
7727 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7728 TCGv_i32 addr
, int size
)
7730 TCGv_i32 tmp
= tcg_temp_new_i32();
7736 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7739 gen_aa32_ld16ua(s
, tmp
, addr
, get_mem_index(s
));
7743 gen_aa32_ld32ua(s
, tmp
, addr
, get_mem_index(s
));
7750 TCGv_i32 tmp2
= tcg_temp_new_i32();
7751 TCGv_i32 tmp3
= tcg_temp_new_i32();
7753 tcg_gen_addi_i32(tmp2
, addr
, 4);
7754 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7755 tcg_temp_free_i32(tmp2
);
7756 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7757 store_reg(s
, rt2
, tmp3
);
7759 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7762 store_reg(s
, rt
, tmp
);
7763 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7766 static void gen_clrex(DisasContext
*s
)
7768 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7771 #ifdef CONFIG_USER_ONLY
7772 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7773 TCGv_i32 addr
, int size
)
7775 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7776 tcg_gen_movi_i32(cpu_exclusive_info
,
7777 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7778 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7781 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7782 TCGv_i32 addr
, int size
)
7785 TCGv_i64 val64
, extaddr
;
7786 TCGLabel
*done_label
;
7787 TCGLabel
*fail_label
;
7789 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7795 fail_label
= gen_new_label();
7796 done_label
= gen_new_label();
7797 extaddr
= tcg_temp_new_i64();
7798 tcg_gen_extu_i32_i64(extaddr
, addr
);
7799 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7800 tcg_temp_free_i64(extaddr
);
7802 tmp
= tcg_temp_new_i32();
7805 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7808 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
7812 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7818 val64
= tcg_temp_new_i64();
7820 TCGv_i32 tmp2
= tcg_temp_new_i32();
7821 TCGv_i32 tmp3
= tcg_temp_new_i32();
7822 tcg_gen_addi_i32(tmp2
, addr
, 4);
7823 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7824 tcg_temp_free_i32(tmp2
);
7825 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7826 tcg_temp_free_i32(tmp3
);
7828 tcg_gen_extu_i32_i64(val64
, tmp
);
7830 tcg_temp_free_i32(tmp
);
7832 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7833 tcg_temp_free_i64(val64
);
7835 tmp
= load_reg(s
, rt
);
7838 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
7841 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
7845 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7850 tcg_temp_free_i32(tmp
);
7852 tcg_gen_addi_i32(addr
, addr
, 4);
7853 tmp
= load_reg(s
, rt2
);
7854 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7855 tcg_temp_free_i32(tmp
);
7857 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7858 tcg_gen_br(done_label
);
7859 gen_set_label(fail_label
);
7860 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7861 gen_set_label(done_label
);
7862 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7869 * @mode: mode field from insn (which stack to store to)
7870 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7871 * @writeback: true if writeback bit set
7873 * Generate code for the SRS (Store Return State) insn.
7875 static void gen_srs(DisasContext
*s
,
7876 uint32_t mode
, uint32_t amode
, bool writeback
)
7883 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7884 * and specified mode is monitor mode
7885 * - UNDEFINED in Hyp mode
7886 * - UNPREDICTABLE in User or System mode
7887 * - UNPREDICTABLE if the specified mode is:
7888 * -- not implemented
7889 * -- not a valid mode number
7890 * -- a mode that's at a higher exception level
7891 * -- Monitor, if we are Non-secure
7892 * For the UNPREDICTABLE cases we choose to UNDEF.
7894 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7895 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7899 if (s
->current_el
== 0 || s
->current_el
== 2) {
7904 case ARM_CPU_MODE_USR
:
7905 case ARM_CPU_MODE_FIQ
:
7906 case ARM_CPU_MODE_IRQ
:
7907 case ARM_CPU_MODE_SVC
:
7908 case ARM_CPU_MODE_ABT
:
7909 case ARM_CPU_MODE_UND
:
7910 case ARM_CPU_MODE_SYS
:
7912 case ARM_CPU_MODE_HYP
:
7913 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7917 case ARM_CPU_MODE_MON
:
7918 /* No need to check specifically for "are we non-secure" because
7919 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7920 * so if this isn't EL3 then we must be non-secure.
7922 if (s
->current_el
!= 3) {
7931 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
7932 default_exception_el(s
));
7936 addr
= tcg_temp_new_i32();
7937 tmp
= tcg_const_i32(mode
);
7938 /* get_r13_banked() will raise an exception if called from System mode */
7939 gen_set_condexec(s
);
7940 gen_set_pc_im(s
, s
->pc
- 4);
7941 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7942 tcg_temp_free_i32(tmp
);
7959 tcg_gen_addi_i32(addr
, addr
, offset
);
7960 tmp
= load_reg(s
, 14);
7961 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7962 tcg_temp_free_i32(tmp
);
7963 tmp
= load_cpu_field(spsr
);
7964 tcg_gen_addi_i32(addr
, addr
, 4);
7965 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7966 tcg_temp_free_i32(tmp
);
7984 tcg_gen_addi_i32(addr
, addr
, offset
);
7985 tmp
= tcg_const_i32(mode
);
7986 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7987 tcg_temp_free_i32(tmp
);
7989 tcg_temp_free_i32(addr
);
7990 s
->is_jmp
= DISAS_UPDATE
;
7993 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7995 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8002 /* M variants do not implement ARM mode. */
8003 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8008 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8009 * choose to UNDEF. In ARMv5 and above the space is used
8010 * for miscellaneous unconditional instructions.
8014 /* Unconditional instructions. */
8015 if (((insn
>> 25) & 7) == 1) {
8016 /* NEON Data processing. */
8017 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8021 if (disas_neon_data_insn(s
, insn
)) {
8026 if ((insn
& 0x0f100000) == 0x04000000) {
8027 /* NEON load/store. */
8028 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8032 if (disas_neon_ls_insn(s
, insn
)) {
8037 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8039 if (disas_vfp_insn(s
, insn
)) {
8044 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8045 ((insn
& 0x0f30f010) == 0x0710f000)) {
8046 if ((insn
& (1 << 22)) == 0) {
8048 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8052 /* Otherwise PLD; v5TE+ */
8056 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8057 ((insn
& 0x0f70f010) == 0x0650f000)) {
8059 return; /* PLI; V7 */
8061 if (((insn
& 0x0f700000) == 0x04100000) ||
8062 ((insn
& 0x0f700010) == 0x06100000)) {
8063 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8066 return; /* v7MP: Unallocated memory hint: must NOP */
8069 if ((insn
& 0x0ffffdff) == 0x01010000) {
8072 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8073 gen_helper_setend(cpu_env
);
8074 s
->is_jmp
= DISAS_UPDATE
;
8077 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8078 switch ((insn
>> 4) & 0xf) {
8086 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8089 /* We need to break the TB after this insn to execute
8090 * self-modifying code correctly and also to take
8091 * any pending interrupts immediately.
8098 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8101 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8103 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8109 rn
= (insn
>> 16) & 0xf;
8110 addr
= load_reg(s
, rn
);
8111 i
= (insn
>> 23) & 3;
8113 case 0: offset
= -4; break; /* DA */
8114 case 1: offset
= 0; break; /* IA */
8115 case 2: offset
= -8; break; /* DB */
8116 case 3: offset
= 4; break; /* IB */
8120 tcg_gen_addi_i32(addr
, addr
, offset
);
8121 /* Load PC into tmp and CPSR into tmp2. */
8122 tmp
= tcg_temp_new_i32();
8123 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8124 tcg_gen_addi_i32(addr
, addr
, 4);
8125 tmp2
= tcg_temp_new_i32();
8126 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8127 if (insn
& (1 << 21)) {
8128 /* Base writeback. */
8130 case 0: offset
= -8; break;
8131 case 1: offset
= 4; break;
8132 case 2: offset
= -4; break;
8133 case 3: offset
= 0; break;
8137 tcg_gen_addi_i32(addr
, addr
, offset
);
8138 store_reg(s
, rn
, addr
);
8140 tcg_temp_free_i32(addr
);
8142 gen_rfe(s
, tmp
, tmp2
);
8144 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8145 /* branch link and change to thumb (blx <offset>) */
8148 val
= (uint32_t)s
->pc
;
8149 tmp
= tcg_temp_new_i32();
8150 tcg_gen_movi_i32(tmp
, val
);
8151 store_reg(s
, 14, tmp
);
8152 /* Sign-extend the 24-bit offset */
8153 offset
= (((int32_t)insn
) << 8) >> 8;
8154 /* offset * 4 + bit24 * 2 + (thumb bit) */
8155 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8156 /* pipeline offset */
8158 /* protected by ARCH(5); above, near the start of uncond block */
8161 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8162 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8163 /* iWMMXt register transfer. */
8164 if (extract32(s
->c15_cpar
, 1, 1)) {
8165 if (!disas_iwmmxt_insn(s
, insn
)) {
8170 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8171 /* Coprocessor double register transfer. */
8173 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8174 /* Additional coprocessor register transfer. */
8175 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8178 /* cps (privileged) */
8182 if (insn
& (1 << 19)) {
8183 if (insn
& (1 << 8))
8185 if (insn
& (1 << 7))
8187 if (insn
& (1 << 6))
8189 if (insn
& (1 << 18))
8192 if (insn
& (1 << 17)) {
8194 val
|= (insn
& 0x1f);
8197 gen_set_psr_im(s
, mask
, 0, val
);
8204 /* if not always execute, we generate a conditional jump to
8206 s
->condlabel
= gen_new_label();
8207 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8210 if ((insn
& 0x0f900000) == 0x03000000) {
8211 if ((insn
& (1 << 21)) == 0) {
8213 rd
= (insn
>> 12) & 0xf;
8214 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8215 if ((insn
& (1 << 22)) == 0) {
8217 tmp
= tcg_temp_new_i32();
8218 tcg_gen_movi_i32(tmp
, val
);
8221 tmp
= load_reg(s
, rd
);
8222 tcg_gen_ext16u_i32(tmp
, tmp
);
8223 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8225 store_reg(s
, rd
, tmp
);
8227 if (((insn
>> 12) & 0xf) != 0xf)
8229 if (((insn
>> 16) & 0xf) == 0) {
8230 gen_nop_hint(s
, insn
& 0xff);
8232 /* CPSR = immediate */
8234 shift
= ((insn
>> 8) & 0xf) * 2;
8236 val
= (val
>> shift
) | (val
<< (32 - shift
));
8237 i
= ((insn
& (1 << 22)) != 0);
8238 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8244 } else if ((insn
& 0x0f900000) == 0x01000000
8245 && (insn
& 0x00000090) != 0x00000090) {
8246 /* miscellaneous instructions */
8247 op1
= (insn
>> 21) & 3;
8248 sh
= (insn
>> 4) & 0xf;
8251 case 0x0: /* MSR, MRS */
8252 if (insn
& (1 << 9)) {
8253 /* MSR (banked) and MRS (banked) */
8254 int sysm
= extract32(insn
, 16, 4) |
8255 (extract32(insn
, 8, 1) << 4);
8256 int r
= extract32(insn
, 22, 1);
8260 gen_msr_banked(s
, r
, sysm
, rm
);
8263 int rd
= extract32(insn
, 12, 4);
8265 gen_mrs_banked(s
, r
, sysm
, rd
);
8270 /* MSR, MRS (for PSRs) */
8273 tmp
= load_reg(s
, rm
);
8274 i
= ((op1
& 2) != 0);
8275 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8279 rd
= (insn
>> 12) & 0xf;
8283 tmp
= load_cpu_field(spsr
);
8285 tmp
= tcg_temp_new_i32();
8286 gen_helper_cpsr_read(tmp
, cpu_env
);
8288 store_reg(s
, rd
, tmp
);
8293 /* branch/exchange thumb (bx). */
8295 tmp
= load_reg(s
, rm
);
8297 } else if (op1
== 3) {
8300 rd
= (insn
>> 12) & 0xf;
8301 tmp
= load_reg(s
, rm
);
8302 gen_helper_clz(tmp
, tmp
);
8303 store_reg(s
, rd
, tmp
);
8311 /* Trivial implementation equivalent to bx. */
8312 tmp
= load_reg(s
, rm
);
8323 /* branch link/exchange thumb (blx) */
8324 tmp
= load_reg(s
, rm
);
8325 tmp2
= tcg_temp_new_i32();
8326 tcg_gen_movi_i32(tmp2
, s
->pc
);
8327 store_reg(s
, 14, tmp2
);
8333 uint32_t c
= extract32(insn
, 8, 4);
8335 /* Check this CPU supports ARMv8 CRC instructions.
8336 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8337 * Bits 8, 10 and 11 should be zero.
8339 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8344 rn
= extract32(insn
, 16, 4);
8345 rd
= extract32(insn
, 12, 4);
8347 tmp
= load_reg(s
, rn
);
8348 tmp2
= load_reg(s
, rm
);
8350 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8351 } else if (op1
== 1) {
8352 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8354 tmp3
= tcg_const_i32(1 << op1
);
8356 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8358 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8360 tcg_temp_free_i32(tmp2
);
8361 tcg_temp_free_i32(tmp3
);
8362 store_reg(s
, rd
, tmp
);
8365 case 0x5: /* saturating add/subtract */
8367 rd
= (insn
>> 12) & 0xf;
8368 rn
= (insn
>> 16) & 0xf;
8369 tmp
= load_reg(s
, rm
);
8370 tmp2
= load_reg(s
, rn
);
8372 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8374 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8376 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8377 tcg_temp_free_i32(tmp2
);
8378 store_reg(s
, rd
, tmp
);
8382 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8387 gen_exception_insn(s
, 4, EXCP_BKPT
,
8388 syn_aa32_bkpt(imm16
, false),
8389 default_exception_el(s
));
8392 /* Hypervisor call (v7) */
8400 /* Secure monitor call (v6+) */
8412 case 0x8: /* signed multiply */
8417 rs
= (insn
>> 8) & 0xf;
8418 rn
= (insn
>> 12) & 0xf;
8419 rd
= (insn
>> 16) & 0xf;
8421 /* (32 * 16) >> 16 */
8422 tmp
= load_reg(s
, rm
);
8423 tmp2
= load_reg(s
, rs
);
8425 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8428 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8429 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8430 tmp
= tcg_temp_new_i32();
8431 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8432 tcg_temp_free_i64(tmp64
);
8433 if ((sh
& 2) == 0) {
8434 tmp2
= load_reg(s
, rn
);
8435 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8436 tcg_temp_free_i32(tmp2
);
8438 store_reg(s
, rd
, tmp
);
8441 tmp
= load_reg(s
, rm
);
8442 tmp2
= load_reg(s
, rs
);
8443 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8444 tcg_temp_free_i32(tmp2
);
8446 tmp64
= tcg_temp_new_i64();
8447 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8448 tcg_temp_free_i32(tmp
);
8449 gen_addq(s
, tmp64
, rn
, rd
);
8450 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8451 tcg_temp_free_i64(tmp64
);
8454 tmp2
= load_reg(s
, rn
);
8455 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8456 tcg_temp_free_i32(tmp2
);
8458 store_reg(s
, rd
, tmp
);
8465 } else if (((insn
& 0x0e000000) == 0 &&
8466 (insn
& 0x00000090) != 0x90) ||
8467 ((insn
& 0x0e000000) == (1 << 25))) {
8468 int set_cc
, logic_cc
, shiftop
;
8470 op1
= (insn
>> 21) & 0xf;
8471 set_cc
= (insn
>> 20) & 1;
8472 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8474 /* data processing instruction */
8475 if (insn
& (1 << 25)) {
8476 /* immediate operand */
8478 shift
= ((insn
>> 8) & 0xf) * 2;
8480 val
= (val
>> shift
) | (val
<< (32 - shift
));
8482 tmp2
= tcg_temp_new_i32();
8483 tcg_gen_movi_i32(tmp2
, val
);
8484 if (logic_cc
&& shift
) {
8485 gen_set_CF_bit31(tmp2
);
8490 tmp2
= load_reg(s
, rm
);
8491 shiftop
= (insn
>> 5) & 3;
8492 if (!(insn
& (1 << 4))) {
8493 shift
= (insn
>> 7) & 0x1f;
8494 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8496 rs
= (insn
>> 8) & 0xf;
8497 tmp
= load_reg(s
, rs
);
8498 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8501 if (op1
!= 0x0f && op1
!= 0x0d) {
8502 rn
= (insn
>> 16) & 0xf;
8503 tmp
= load_reg(s
, rn
);
8505 TCGV_UNUSED_I32(tmp
);
8507 rd
= (insn
>> 12) & 0xf;
8510 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8514 store_reg_bx(s
, rd
, tmp
);
8517 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8521 store_reg_bx(s
, rd
, tmp
);
8524 if (set_cc
&& rd
== 15) {
8525 /* SUBS r15, ... is used for exception return. */
8529 gen_sub_CC(tmp
, tmp
, tmp2
);
8530 gen_exception_return(s
, tmp
);
8533 gen_sub_CC(tmp
, tmp
, tmp2
);
8535 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8537 store_reg_bx(s
, rd
, tmp
);
8542 gen_sub_CC(tmp
, tmp2
, tmp
);
8544 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8546 store_reg_bx(s
, rd
, tmp
);
8550 gen_add_CC(tmp
, tmp
, tmp2
);
8552 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8554 store_reg_bx(s
, rd
, tmp
);
8558 gen_adc_CC(tmp
, tmp
, tmp2
);
8560 gen_add_carry(tmp
, tmp
, tmp2
);
8562 store_reg_bx(s
, rd
, tmp
);
8566 gen_sbc_CC(tmp
, tmp
, tmp2
);
8568 gen_sub_carry(tmp
, tmp
, tmp2
);
8570 store_reg_bx(s
, rd
, tmp
);
8574 gen_sbc_CC(tmp
, tmp2
, tmp
);
8576 gen_sub_carry(tmp
, tmp2
, tmp
);
8578 store_reg_bx(s
, rd
, tmp
);
8582 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8585 tcg_temp_free_i32(tmp
);
8589 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8592 tcg_temp_free_i32(tmp
);
8596 gen_sub_CC(tmp
, tmp
, tmp2
);
8598 tcg_temp_free_i32(tmp
);
8602 gen_add_CC(tmp
, tmp
, tmp2
);
8604 tcg_temp_free_i32(tmp
);
8607 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8611 store_reg_bx(s
, rd
, tmp
);
8614 if (logic_cc
&& rd
== 15) {
8615 /* MOVS r15, ... is used for exception return. */
8619 gen_exception_return(s
, tmp2
);
8624 store_reg_bx(s
, rd
, tmp2
);
8628 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8632 store_reg_bx(s
, rd
, tmp
);
8636 tcg_gen_not_i32(tmp2
, tmp2
);
8640 store_reg_bx(s
, rd
, tmp2
);
8643 if (op1
!= 0x0f && op1
!= 0x0d) {
8644 tcg_temp_free_i32(tmp2
);
8647 /* other instructions */
8648 op1
= (insn
>> 24) & 0xf;
8652 /* multiplies, extra load/stores */
8653 sh
= (insn
>> 5) & 3;
8656 rd
= (insn
>> 16) & 0xf;
8657 rn
= (insn
>> 12) & 0xf;
8658 rs
= (insn
>> 8) & 0xf;
8660 op1
= (insn
>> 20) & 0xf;
8662 case 0: case 1: case 2: case 3: case 6:
8664 tmp
= load_reg(s
, rs
);
8665 tmp2
= load_reg(s
, rm
);
8666 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8667 tcg_temp_free_i32(tmp2
);
8668 if (insn
& (1 << 22)) {
8669 /* Subtract (mls) */
8671 tmp2
= load_reg(s
, rn
);
8672 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8673 tcg_temp_free_i32(tmp2
);
8674 } else if (insn
& (1 << 21)) {
8676 tmp2
= load_reg(s
, rn
);
8677 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8678 tcg_temp_free_i32(tmp2
);
8680 if (insn
& (1 << 20))
8682 store_reg(s
, rd
, tmp
);
8685 /* 64 bit mul double accumulate (UMAAL) */
8687 tmp
= load_reg(s
, rs
);
8688 tmp2
= load_reg(s
, rm
);
8689 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8690 gen_addq_lo(s
, tmp64
, rn
);
8691 gen_addq_lo(s
, tmp64
, rd
);
8692 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8693 tcg_temp_free_i64(tmp64
);
8695 case 8: case 9: case 10: case 11:
8696 case 12: case 13: case 14: case 15:
8697 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8698 tmp
= load_reg(s
, rs
);
8699 tmp2
= load_reg(s
, rm
);
8700 if (insn
& (1 << 22)) {
8701 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8703 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8705 if (insn
& (1 << 21)) { /* mult accumulate */
8706 TCGv_i32 al
= load_reg(s
, rn
);
8707 TCGv_i32 ah
= load_reg(s
, rd
);
8708 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8709 tcg_temp_free_i32(al
);
8710 tcg_temp_free_i32(ah
);
8712 if (insn
& (1 << 20)) {
8713 gen_logicq_cc(tmp
, tmp2
);
8715 store_reg(s
, rn
, tmp
);
8716 store_reg(s
, rd
, tmp2
);
8722 rn
= (insn
>> 16) & 0xf;
8723 rd
= (insn
>> 12) & 0xf;
8724 if (insn
& (1 << 23)) {
8725 /* load/store exclusive */
8726 int op2
= (insn
>> 8) & 3;
8727 op1
= (insn
>> 21) & 0x3;
8730 case 0: /* lda/stl */
8736 case 1: /* reserved */
8738 case 2: /* ldaex/stlex */
8741 case 3: /* ldrex/strex */
8750 addr
= tcg_temp_local_new_i32();
8751 load_reg_var(s
, addr
, rn
);
8753 /* Since the emulation does not have barriers,
8754 the acquire/release semantics need no special
8757 if (insn
& (1 << 20)) {
8758 tmp
= tcg_temp_new_i32();
8761 gen_aa32_ld32u(s
, tmp
, addr
,
8765 gen_aa32_ld8u(s
, tmp
, addr
,
8769 gen_aa32_ld16u(s
, tmp
, addr
,
8775 store_reg(s
, rd
, tmp
);
8778 tmp
= load_reg(s
, rm
);
8781 gen_aa32_st32(s
, tmp
, addr
,
8785 gen_aa32_st8(s
, tmp
, addr
,
8789 gen_aa32_st16(s
, tmp
, addr
,
8795 tcg_temp_free_i32(tmp
);
8797 } else if (insn
& (1 << 20)) {
8800 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8802 case 1: /* ldrexd */
8803 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8805 case 2: /* ldrexb */
8806 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8808 case 3: /* ldrexh */
8809 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8818 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8820 case 1: /* strexd */
8821 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8823 case 2: /* strexb */
8824 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8826 case 3: /* strexh */
8827 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8833 tcg_temp_free_i32(addr
);
8835 /* SWP instruction */
8838 /* ??? This is not really atomic. However we know
8839 we never have multiple CPUs running in parallel,
8840 so it is good enough. */
8841 addr
= load_reg(s
, rn
);
8842 tmp
= load_reg(s
, rm
);
8843 tmp2
= tcg_temp_new_i32();
8844 if (insn
& (1 << 22)) {
8845 gen_aa32_ld8u(s
, tmp2
, addr
, get_mem_index(s
));
8846 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
8848 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8849 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8851 tcg_temp_free_i32(tmp
);
8852 tcg_temp_free_i32(addr
);
8853 store_reg(s
, rd
, tmp2
);
8858 bool load
= insn
& (1 << 20);
8859 bool doubleword
= false;
8860 /* Misc load/store */
8861 rn
= (insn
>> 16) & 0xf;
8862 rd
= (insn
>> 12) & 0xf;
8864 if (!load
&& (sh
& 2)) {
8868 /* UNPREDICTABLE; we choose to UNDEF */
8871 load
= (sh
& 1) == 0;
8875 addr
= load_reg(s
, rn
);
8876 if (insn
& (1 << 24))
8877 gen_add_datah_offset(s
, insn
, 0, addr
);
8883 tmp
= load_reg(s
, rd
);
8884 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8885 tcg_temp_free_i32(tmp
);
8886 tcg_gen_addi_i32(addr
, addr
, 4);
8887 tmp
= load_reg(s
, rd
+ 1);
8888 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8889 tcg_temp_free_i32(tmp
);
8892 tmp
= tcg_temp_new_i32();
8893 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8894 store_reg(s
, rd
, tmp
);
8895 tcg_gen_addi_i32(addr
, addr
, 4);
8896 tmp
= tcg_temp_new_i32();
8897 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8900 address_offset
= -4;
8903 tmp
= tcg_temp_new_i32();
8906 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
8909 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
8913 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
8918 tmp
= load_reg(s
, rd
);
8919 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
8920 tcg_temp_free_i32(tmp
);
8922 /* Perform base writeback before the loaded value to
8923 ensure correct behavior with overlapping index registers.
8924 ldrd with base writeback is undefined if the
8925 destination and index registers overlap. */
8926 if (!(insn
& (1 << 24))) {
8927 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8928 store_reg(s
, rn
, addr
);
8929 } else if (insn
& (1 << 21)) {
8931 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8932 store_reg(s
, rn
, addr
);
8934 tcg_temp_free_i32(addr
);
8937 /* Complete the load. */
8938 store_reg(s
, rd
, tmp
);
8947 if (insn
& (1 << 4)) {
8949 /* Armv6 Media instructions. */
8951 rn
= (insn
>> 16) & 0xf;
8952 rd
= (insn
>> 12) & 0xf;
8953 rs
= (insn
>> 8) & 0xf;
8954 switch ((insn
>> 23) & 3) {
8955 case 0: /* Parallel add/subtract. */
8956 op1
= (insn
>> 20) & 7;
8957 tmp
= load_reg(s
, rn
);
8958 tmp2
= load_reg(s
, rm
);
8959 sh
= (insn
>> 5) & 7;
8960 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8962 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8963 tcg_temp_free_i32(tmp2
);
8964 store_reg(s
, rd
, tmp
);
8967 if ((insn
& 0x00700020) == 0) {
8968 /* Halfword pack. */
8969 tmp
= load_reg(s
, rn
);
8970 tmp2
= load_reg(s
, rm
);
8971 shift
= (insn
>> 7) & 0x1f;
8972 if (insn
& (1 << 6)) {
8976 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8977 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8978 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8982 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8983 tcg_gen_ext16u_i32(tmp
, tmp
);
8984 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8986 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8987 tcg_temp_free_i32(tmp2
);
8988 store_reg(s
, rd
, tmp
);
8989 } else if ((insn
& 0x00200020) == 0x00200000) {
8991 tmp
= load_reg(s
, rm
);
8992 shift
= (insn
>> 7) & 0x1f;
8993 if (insn
& (1 << 6)) {
8996 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8998 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9000 sh
= (insn
>> 16) & 0x1f;
9001 tmp2
= tcg_const_i32(sh
);
9002 if (insn
& (1 << 22))
9003 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9005 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9006 tcg_temp_free_i32(tmp2
);
9007 store_reg(s
, rd
, tmp
);
9008 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9010 tmp
= load_reg(s
, rm
);
9011 sh
= (insn
>> 16) & 0x1f;
9012 tmp2
= tcg_const_i32(sh
);
9013 if (insn
& (1 << 22))
9014 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9016 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9017 tcg_temp_free_i32(tmp2
);
9018 store_reg(s
, rd
, tmp
);
9019 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9021 tmp
= load_reg(s
, rn
);
9022 tmp2
= load_reg(s
, rm
);
9023 tmp3
= tcg_temp_new_i32();
9024 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9025 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9026 tcg_temp_free_i32(tmp3
);
9027 tcg_temp_free_i32(tmp2
);
9028 store_reg(s
, rd
, tmp
);
9029 } else if ((insn
& 0x000003e0) == 0x00000060) {
9030 tmp
= load_reg(s
, rm
);
9031 shift
= (insn
>> 10) & 3;
9032 /* ??? In many cases it's not necessary to do a
9033 rotate, a shift is sufficient. */
9035 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9036 op1
= (insn
>> 20) & 7;
9038 case 0: gen_sxtb16(tmp
); break;
9039 case 2: gen_sxtb(tmp
); break;
9040 case 3: gen_sxth(tmp
); break;
9041 case 4: gen_uxtb16(tmp
); break;
9042 case 6: gen_uxtb(tmp
); break;
9043 case 7: gen_uxth(tmp
); break;
9044 default: goto illegal_op
;
9047 tmp2
= load_reg(s
, rn
);
9048 if ((op1
& 3) == 0) {
9049 gen_add16(tmp
, tmp2
);
9051 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9052 tcg_temp_free_i32(tmp2
);
9055 store_reg(s
, rd
, tmp
);
9056 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9058 tmp
= load_reg(s
, rm
);
9059 if (insn
& (1 << 22)) {
9060 if (insn
& (1 << 7)) {
9064 gen_helper_rbit(tmp
, tmp
);
9067 if (insn
& (1 << 7))
9070 tcg_gen_bswap32_i32(tmp
, tmp
);
9072 store_reg(s
, rd
, tmp
);
9077 case 2: /* Multiplies (Type 3). */
9078 switch ((insn
>> 20) & 0x7) {
9080 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9081 /* op2 not 00x or 11x : UNDEF */
9084 /* Signed multiply most significant [accumulate].
9085 (SMMUL, SMMLA, SMMLS) */
9086 tmp
= load_reg(s
, rm
);
9087 tmp2
= load_reg(s
, rs
);
9088 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9091 tmp
= load_reg(s
, rd
);
9092 if (insn
& (1 << 6)) {
9093 tmp64
= gen_subq_msw(tmp64
, tmp
);
9095 tmp64
= gen_addq_msw(tmp64
, tmp
);
9098 if (insn
& (1 << 5)) {
9099 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9101 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9102 tmp
= tcg_temp_new_i32();
9103 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9104 tcg_temp_free_i64(tmp64
);
9105 store_reg(s
, rn
, tmp
);
9109 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9110 if (insn
& (1 << 7)) {
9113 tmp
= load_reg(s
, rm
);
9114 tmp2
= load_reg(s
, rs
);
9115 if (insn
& (1 << 5))
9116 gen_swap_half(tmp2
);
9117 gen_smul_dual(tmp
, tmp2
);
9118 if (insn
& (1 << 22)) {
9119 /* smlald, smlsld */
9122 tmp64
= tcg_temp_new_i64();
9123 tmp64_2
= tcg_temp_new_i64();
9124 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9125 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9126 tcg_temp_free_i32(tmp
);
9127 tcg_temp_free_i32(tmp2
);
9128 if (insn
& (1 << 6)) {
9129 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9131 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9133 tcg_temp_free_i64(tmp64_2
);
9134 gen_addq(s
, tmp64
, rd
, rn
);
9135 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9136 tcg_temp_free_i64(tmp64
);
9138 /* smuad, smusd, smlad, smlsd */
9139 if (insn
& (1 << 6)) {
9140 /* This subtraction cannot overflow. */
9141 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9143 /* This addition cannot overflow 32 bits;
9144 * however it may overflow considered as a
9145 * signed operation, in which case we must set
9148 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9150 tcg_temp_free_i32(tmp2
);
9153 tmp2
= load_reg(s
, rd
);
9154 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9155 tcg_temp_free_i32(tmp2
);
9157 store_reg(s
, rn
, tmp
);
9163 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9166 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9169 tmp
= load_reg(s
, rm
);
9170 tmp2
= load_reg(s
, rs
);
9171 if (insn
& (1 << 21)) {
9172 gen_helper_udiv(tmp
, tmp
, tmp2
);
9174 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9176 tcg_temp_free_i32(tmp2
);
9177 store_reg(s
, rn
, tmp
);
9184 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9186 case 0: /* Unsigned sum of absolute differences. */
9188 tmp
= load_reg(s
, rm
);
9189 tmp2
= load_reg(s
, rs
);
9190 gen_helper_usad8(tmp
, tmp
, tmp2
);
9191 tcg_temp_free_i32(tmp2
);
9193 tmp2
= load_reg(s
, rd
);
9194 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9195 tcg_temp_free_i32(tmp2
);
9197 store_reg(s
, rn
, tmp
);
9199 case 0x20: case 0x24: case 0x28: case 0x2c:
9200 /* Bitfield insert/clear. */
9202 shift
= (insn
>> 7) & 0x1f;
9203 i
= (insn
>> 16) & 0x1f;
9205 /* UNPREDICTABLE; we choose to UNDEF */
9210 tmp
= tcg_temp_new_i32();
9211 tcg_gen_movi_i32(tmp
, 0);
9213 tmp
= load_reg(s
, rm
);
9216 tmp2
= load_reg(s
, rd
);
9217 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9218 tcg_temp_free_i32(tmp2
);
9220 store_reg(s
, rd
, tmp
);
9222 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9223 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9225 tmp
= load_reg(s
, rm
);
9226 shift
= (insn
>> 7) & 0x1f;
9227 i
= ((insn
>> 16) & 0x1f) + 1;
9232 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
9234 gen_sbfx(tmp
, shift
, i
);
9237 store_reg(s
, rd
, tmp
);
9247 /* Check for undefined extension instructions
9248 * per the ARM Bible IE:
9249 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9251 sh
= (0xf << 20) | (0xf << 4);
9252 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9256 /* load/store byte/word */
9257 rn
= (insn
>> 16) & 0xf;
9258 rd
= (insn
>> 12) & 0xf;
9259 tmp2
= load_reg(s
, rn
);
9260 if ((insn
& 0x01200000) == 0x00200000) {
9262 i
= get_a32_user_mem_index(s
);
9264 i
= get_mem_index(s
);
9266 if (insn
& (1 << 24))
9267 gen_add_data_offset(s
, insn
, tmp2
);
9268 if (insn
& (1 << 20)) {
9270 tmp
= tcg_temp_new_i32();
9271 if (insn
& (1 << 22)) {
9272 gen_aa32_ld8u(s
, tmp
, tmp2
, i
);
9274 gen_aa32_ld32u(s
, tmp
, tmp2
, i
);
9278 tmp
= load_reg(s
, rd
);
9279 if (insn
& (1 << 22)) {
9280 gen_aa32_st8(s
, tmp
, tmp2
, i
);
9282 gen_aa32_st32(s
, tmp
, tmp2
, i
);
9284 tcg_temp_free_i32(tmp
);
9286 if (!(insn
& (1 << 24))) {
9287 gen_add_data_offset(s
, insn
, tmp2
);
9288 store_reg(s
, rn
, tmp2
);
9289 } else if (insn
& (1 << 21)) {
9290 store_reg(s
, rn
, tmp2
);
9292 tcg_temp_free_i32(tmp2
);
9294 if (insn
& (1 << 20)) {
9295 /* Complete the load. */
9296 store_reg_from_load(s
, rd
, tmp
);
9302 int j
, n
, loaded_base
;
9303 bool exc_return
= false;
9304 bool is_load
= extract32(insn
, 20, 1);
9306 TCGv_i32 loaded_var
;
9307 /* load/store multiple words */
9308 /* XXX: store correct base if write back */
9309 if (insn
& (1 << 22)) {
9310 /* LDM (user), LDM (exception return) and STM (user) */
9312 goto illegal_op
; /* only usable in supervisor mode */
9314 if (is_load
&& extract32(insn
, 15, 1)) {
9320 rn
= (insn
>> 16) & 0xf;
9321 addr
= load_reg(s
, rn
);
9323 /* compute total size */
9325 TCGV_UNUSED_I32(loaded_var
);
9328 if (insn
& (1 << i
))
9331 /* XXX: test invalid n == 0 case ? */
9332 if (insn
& (1 << 23)) {
9333 if (insn
& (1 << 24)) {
9335 tcg_gen_addi_i32(addr
, addr
, 4);
9337 /* post increment */
9340 if (insn
& (1 << 24)) {
9342 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9344 /* post decrement */
9346 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9351 if (insn
& (1 << i
)) {
9354 tmp
= tcg_temp_new_i32();
9355 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9357 tmp2
= tcg_const_i32(i
);
9358 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9359 tcg_temp_free_i32(tmp2
);
9360 tcg_temp_free_i32(tmp
);
9361 } else if (i
== rn
) {
9365 store_reg_from_load(s
, i
, tmp
);
9370 /* special case: r15 = PC + 8 */
9371 val
= (long)s
->pc
+ 4;
9372 tmp
= tcg_temp_new_i32();
9373 tcg_gen_movi_i32(tmp
, val
);
9375 tmp
= tcg_temp_new_i32();
9376 tmp2
= tcg_const_i32(i
);
9377 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9378 tcg_temp_free_i32(tmp2
);
9380 tmp
= load_reg(s
, i
);
9382 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9383 tcg_temp_free_i32(tmp
);
9386 /* no need to add after the last transfer */
9388 tcg_gen_addi_i32(addr
, addr
, 4);
9391 if (insn
& (1 << 21)) {
9393 if (insn
& (1 << 23)) {
9394 if (insn
& (1 << 24)) {
9397 /* post increment */
9398 tcg_gen_addi_i32(addr
, addr
, 4);
9401 if (insn
& (1 << 24)) {
9404 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9406 /* post decrement */
9407 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9410 store_reg(s
, rn
, addr
);
9412 tcg_temp_free_i32(addr
);
9415 store_reg(s
, rn
, loaded_var
);
9418 /* Restore CPSR from SPSR. */
9419 tmp
= load_cpu_field(spsr
);
9420 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9421 tcg_temp_free_i32(tmp
);
9422 s
->is_jmp
= DISAS_JUMP
;
9431 /* branch (and link) */
9432 val
= (int32_t)s
->pc
;
9433 if (insn
& (1 << 24)) {
9434 tmp
= tcg_temp_new_i32();
9435 tcg_gen_movi_i32(tmp
, val
);
9436 store_reg(s
, 14, tmp
);
9438 offset
= sextract32(insn
<< 2, 0, 26);
9446 if (((insn
>> 8) & 0xe) == 10) {
9448 if (disas_vfp_insn(s
, insn
)) {
9451 } else if (disas_coproc_insn(s
, insn
)) {
9458 gen_set_pc_im(s
, s
->pc
);
9459 s
->svc_imm
= extract32(insn
, 0, 24);
9460 s
->is_jmp
= DISAS_SWI
;
9464 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9465 default_exception_el(s
));
9471 /* Return true if this is a Thumb-2 logical op. */
9473 thumb2_logic_op(int op
)
9478 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9479 then set condition code flags based on the result of the operation.
9480 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9481 to the high bit of T1.
9482 Returns zero if the opcode is valid. */
9485 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9486 TCGv_i32 t0
, TCGv_i32 t1
)
9493 tcg_gen_and_i32(t0
, t0
, t1
);
9497 tcg_gen_andc_i32(t0
, t0
, t1
);
9501 tcg_gen_or_i32(t0
, t0
, t1
);
9505 tcg_gen_orc_i32(t0
, t0
, t1
);
9509 tcg_gen_xor_i32(t0
, t0
, t1
);
9514 gen_add_CC(t0
, t0
, t1
);
9516 tcg_gen_add_i32(t0
, t0
, t1
);
9520 gen_adc_CC(t0
, t0
, t1
);
9526 gen_sbc_CC(t0
, t0
, t1
);
9528 gen_sub_carry(t0
, t0
, t1
);
9533 gen_sub_CC(t0
, t0
, t1
);
9535 tcg_gen_sub_i32(t0
, t0
, t1
);
9539 gen_sub_CC(t0
, t1
, t0
);
9541 tcg_gen_sub_i32(t0
, t1
, t0
);
9543 default: /* 5, 6, 7, 9, 12, 15. */
9549 gen_set_CF_bit31(t1
);
9554 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9556 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9558 uint32_t insn
, imm
, shift
, offset
;
9559 uint32_t rd
, rn
, rm
, rs
;
9570 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9571 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9572 /* Thumb-1 cores may need to treat bl and blx as a pair of
9573 16-bit instructions to get correct prefetch abort behavior. */
9575 if ((insn
& (1 << 12)) == 0) {
9577 /* Second half of blx. */
9578 offset
= ((insn
& 0x7ff) << 1);
9579 tmp
= load_reg(s
, 14);
9580 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9581 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9583 tmp2
= tcg_temp_new_i32();
9584 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9585 store_reg(s
, 14, tmp2
);
9589 if (insn
& (1 << 11)) {
9590 /* Second half of bl. */
9591 offset
= ((insn
& 0x7ff) << 1) | 1;
9592 tmp
= load_reg(s
, 14);
9593 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9595 tmp2
= tcg_temp_new_i32();
9596 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9597 store_reg(s
, 14, tmp2
);
9601 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9602 /* Instruction spans a page boundary. Implement it as two
9603 16-bit instructions in case the second half causes an
9605 offset
= ((int32_t)insn
<< 21) >> 9;
9606 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9609 /* Fall through to 32-bit decode. */
9612 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9614 insn
|= (uint32_t)insn_hw1
<< 16;
9616 if ((insn
& 0xf800e800) != 0xf000e800) {
9620 rn
= (insn
>> 16) & 0xf;
9621 rs
= (insn
>> 12) & 0xf;
9622 rd
= (insn
>> 8) & 0xf;
9624 switch ((insn
>> 25) & 0xf) {
9625 case 0: case 1: case 2: case 3:
9626 /* 16-bit instructions. Should never happen. */
9629 if (insn
& (1 << 22)) {
9630 /* Other load/store, table branch. */
9631 if (insn
& 0x01200000) {
9632 /* Load/store doubleword. */
9634 addr
= tcg_temp_new_i32();
9635 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9637 addr
= load_reg(s
, rn
);
9639 offset
= (insn
& 0xff) * 4;
9640 if ((insn
& (1 << 23)) == 0)
9642 if (insn
& (1 << 24)) {
9643 tcg_gen_addi_i32(addr
, addr
, offset
);
9646 if (insn
& (1 << 20)) {
9648 tmp
= tcg_temp_new_i32();
9649 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9650 store_reg(s
, rs
, tmp
);
9651 tcg_gen_addi_i32(addr
, addr
, 4);
9652 tmp
= tcg_temp_new_i32();
9653 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9654 store_reg(s
, rd
, tmp
);
9657 tmp
= load_reg(s
, rs
);
9658 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9659 tcg_temp_free_i32(tmp
);
9660 tcg_gen_addi_i32(addr
, addr
, 4);
9661 tmp
= load_reg(s
, rd
);
9662 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9663 tcg_temp_free_i32(tmp
);
9665 if (insn
& (1 << 21)) {
9666 /* Base writeback. */
9669 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9670 store_reg(s
, rn
, addr
);
9672 tcg_temp_free_i32(addr
);
9674 } else if ((insn
& (1 << 23)) == 0) {
9675 /* Load/store exclusive word. */
9676 addr
= tcg_temp_local_new_i32();
9677 load_reg_var(s
, addr
, rn
);
9678 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9679 if (insn
& (1 << 20)) {
9680 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9682 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9684 tcg_temp_free_i32(addr
);
9685 } else if ((insn
& (7 << 5)) == 0) {
9688 addr
= tcg_temp_new_i32();
9689 tcg_gen_movi_i32(addr
, s
->pc
);
9691 addr
= load_reg(s
, rn
);
9693 tmp
= load_reg(s
, rm
);
9694 tcg_gen_add_i32(addr
, addr
, tmp
);
9695 if (insn
& (1 << 4)) {
9697 tcg_gen_add_i32(addr
, addr
, tmp
);
9698 tcg_temp_free_i32(tmp
);
9699 tmp
= tcg_temp_new_i32();
9700 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9702 tcg_temp_free_i32(tmp
);
9703 tmp
= tcg_temp_new_i32();
9704 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9706 tcg_temp_free_i32(addr
);
9707 tcg_gen_shli_i32(tmp
, tmp
, 1);
9708 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9709 store_reg(s
, 15, tmp
);
9711 int op2
= (insn
>> 6) & 0x3;
9712 op
= (insn
>> 4) & 0x3;
9717 /* Load/store exclusive byte/halfword/doubleword */
9724 /* Load-acquire/store-release */
9730 /* Load-acquire/store-release exclusive */
9734 addr
= tcg_temp_local_new_i32();
9735 load_reg_var(s
, addr
, rn
);
9737 if (insn
& (1 << 20)) {
9738 tmp
= tcg_temp_new_i32();
9741 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9744 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9747 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9752 store_reg(s
, rs
, tmp
);
9754 tmp
= load_reg(s
, rs
);
9757 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
9760 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
9763 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9768 tcg_temp_free_i32(tmp
);
9770 } else if (insn
& (1 << 20)) {
9771 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9773 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9775 tcg_temp_free_i32(addr
);
9778 /* Load/store multiple, RFE, SRS. */
9779 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9780 /* RFE, SRS: not available in user mode or on M profile */
9781 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9784 if (insn
& (1 << 20)) {
9786 addr
= load_reg(s
, rn
);
9787 if ((insn
& (1 << 24)) == 0)
9788 tcg_gen_addi_i32(addr
, addr
, -8);
9789 /* Load PC into tmp and CPSR into tmp2. */
9790 tmp
= tcg_temp_new_i32();
9791 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9792 tcg_gen_addi_i32(addr
, addr
, 4);
9793 tmp2
= tcg_temp_new_i32();
9794 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9795 if (insn
& (1 << 21)) {
9796 /* Base writeback. */
9797 if (insn
& (1 << 24)) {
9798 tcg_gen_addi_i32(addr
, addr
, 4);
9800 tcg_gen_addi_i32(addr
, addr
, -4);
9802 store_reg(s
, rn
, addr
);
9804 tcg_temp_free_i32(addr
);
9806 gen_rfe(s
, tmp
, tmp2
);
9809 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9813 int i
, loaded_base
= 0;
9814 TCGv_i32 loaded_var
;
9815 /* Load/store multiple. */
9816 addr
= load_reg(s
, rn
);
9818 for (i
= 0; i
< 16; i
++) {
9819 if (insn
& (1 << i
))
9822 if (insn
& (1 << 24)) {
9823 tcg_gen_addi_i32(addr
, addr
, -offset
);
9826 TCGV_UNUSED_I32(loaded_var
);
9827 for (i
= 0; i
< 16; i
++) {
9828 if ((insn
& (1 << i
)) == 0)
9830 if (insn
& (1 << 20)) {
9832 tmp
= tcg_temp_new_i32();
9833 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9836 } else if (i
== rn
) {
9840 store_reg(s
, i
, tmp
);
9844 tmp
= load_reg(s
, i
);
9845 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9846 tcg_temp_free_i32(tmp
);
9848 tcg_gen_addi_i32(addr
, addr
, 4);
9851 store_reg(s
, rn
, loaded_var
);
9853 if (insn
& (1 << 21)) {
9854 /* Base register writeback. */
9855 if (insn
& (1 << 24)) {
9856 tcg_gen_addi_i32(addr
, addr
, -offset
);
9858 /* Fault if writeback register is in register list. */
9859 if (insn
& (1 << rn
))
9861 store_reg(s
, rn
, addr
);
9863 tcg_temp_free_i32(addr
);
9870 op
= (insn
>> 21) & 0xf;
9872 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9875 /* Halfword pack. */
9876 tmp
= load_reg(s
, rn
);
9877 tmp2
= load_reg(s
, rm
);
9878 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9879 if (insn
& (1 << 5)) {
9883 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9884 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9885 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9889 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9890 tcg_gen_ext16u_i32(tmp
, tmp
);
9891 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9893 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9894 tcg_temp_free_i32(tmp2
);
9895 store_reg(s
, rd
, tmp
);
9897 /* Data processing register constant shift. */
9899 tmp
= tcg_temp_new_i32();
9900 tcg_gen_movi_i32(tmp
, 0);
9902 tmp
= load_reg(s
, rn
);
9904 tmp2
= load_reg(s
, rm
);
9906 shiftop
= (insn
>> 4) & 3;
9907 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9908 conds
= (insn
& (1 << 20)) != 0;
9909 logic_cc
= (conds
&& thumb2_logic_op(op
));
9910 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9911 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9913 tcg_temp_free_i32(tmp2
);
9915 store_reg(s
, rd
, tmp
);
9917 tcg_temp_free_i32(tmp
);
9921 case 13: /* Misc data processing. */
9922 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9923 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9926 case 0: /* Register controlled shift. */
9927 tmp
= load_reg(s
, rn
);
9928 tmp2
= load_reg(s
, rm
);
9929 if ((insn
& 0x70) != 0)
9931 op
= (insn
>> 21) & 3;
9932 logic_cc
= (insn
& (1 << 20)) != 0;
9933 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9936 store_reg_bx(s
, rd
, tmp
);
9938 case 1: /* Sign/zero extend. */
9939 op
= (insn
>> 20) & 7;
9941 case 0: /* SXTAH, SXTH */
9942 case 1: /* UXTAH, UXTH */
9943 case 4: /* SXTAB, SXTB */
9944 case 5: /* UXTAB, UXTB */
9946 case 2: /* SXTAB16, SXTB16 */
9947 case 3: /* UXTAB16, UXTB16 */
9948 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9956 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9960 tmp
= load_reg(s
, rm
);
9961 shift
= (insn
>> 4) & 3;
9962 /* ??? In many cases it's not necessary to do a
9963 rotate, a shift is sufficient. */
9965 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9966 op
= (insn
>> 20) & 7;
9968 case 0: gen_sxth(tmp
); break;
9969 case 1: gen_uxth(tmp
); break;
9970 case 2: gen_sxtb16(tmp
); break;
9971 case 3: gen_uxtb16(tmp
); break;
9972 case 4: gen_sxtb(tmp
); break;
9973 case 5: gen_uxtb(tmp
); break;
9975 g_assert_not_reached();
9978 tmp2
= load_reg(s
, rn
);
9979 if ((op
>> 1) == 1) {
9980 gen_add16(tmp
, tmp2
);
9982 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9983 tcg_temp_free_i32(tmp2
);
9986 store_reg(s
, rd
, tmp
);
9988 case 2: /* SIMD add/subtract. */
9989 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9992 op
= (insn
>> 20) & 7;
9993 shift
= (insn
>> 4) & 7;
9994 if ((op
& 3) == 3 || (shift
& 3) == 3)
9996 tmp
= load_reg(s
, rn
);
9997 tmp2
= load_reg(s
, rm
);
9998 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9999 tcg_temp_free_i32(tmp2
);
10000 store_reg(s
, rd
, tmp
);
10002 case 3: /* Other data processing. */
10003 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10005 /* Saturating add/subtract. */
10006 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10009 tmp
= load_reg(s
, rn
);
10010 tmp2
= load_reg(s
, rm
);
10012 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10014 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10016 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10017 tcg_temp_free_i32(tmp2
);
10020 case 0x0a: /* rbit */
10021 case 0x08: /* rev */
10022 case 0x09: /* rev16 */
10023 case 0x0b: /* revsh */
10024 case 0x18: /* clz */
10026 case 0x10: /* sel */
10027 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10031 case 0x20: /* crc32/crc32c */
10037 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10044 tmp
= load_reg(s
, rn
);
10046 case 0x0a: /* rbit */
10047 gen_helper_rbit(tmp
, tmp
);
10049 case 0x08: /* rev */
10050 tcg_gen_bswap32_i32(tmp
, tmp
);
10052 case 0x09: /* rev16 */
10055 case 0x0b: /* revsh */
10058 case 0x10: /* sel */
10059 tmp2
= load_reg(s
, rm
);
10060 tmp3
= tcg_temp_new_i32();
10061 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10062 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10063 tcg_temp_free_i32(tmp3
);
10064 tcg_temp_free_i32(tmp2
);
10066 case 0x18: /* clz */
10067 gen_helper_clz(tmp
, tmp
);
10077 uint32_t sz
= op
& 0x3;
10078 uint32_t c
= op
& 0x8;
10080 tmp2
= load_reg(s
, rm
);
10082 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10083 } else if (sz
== 1) {
10084 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10086 tmp3
= tcg_const_i32(1 << sz
);
10088 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10090 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10092 tcg_temp_free_i32(tmp2
);
10093 tcg_temp_free_i32(tmp3
);
10097 g_assert_not_reached();
10100 store_reg(s
, rd
, tmp
);
10102 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10103 switch ((insn
>> 20) & 7) {
10104 case 0: /* 32 x 32 -> 32 */
10105 case 7: /* Unsigned sum of absolute differences. */
10107 case 1: /* 16 x 16 -> 32 */
10108 case 2: /* Dual multiply add. */
10109 case 3: /* 32 * 16 -> 32msb */
10110 case 4: /* Dual multiply subtract. */
10111 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10112 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10117 op
= (insn
>> 4) & 0xf;
10118 tmp
= load_reg(s
, rn
);
10119 tmp2
= load_reg(s
, rm
);
10120 switch ((insn
>> 20) & 7) {
10121 case 0: /* 32 x 32 -> 32 */
10122 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10123 tcg_temp_free_i32(tmp2
);
10125 tmp2
= load_reg(s
, rs
);
10127 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10129 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10130 tcg_temp_free_i32(tmp2
);
10133 case 1: /* 16 x 16 -> 32 */
10134 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10135 tcg_temp_free_i32(tmp2
);
10137 tmp2
= load_reg(s
, rs
);
10138 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10139 tcg_temp_free_i32(tmp2
);
10142 case 2: /* Dual multiply add. */
10143 case 4: /* Dual multiply subtract. */
10145 gen_swap_half(tmp2
);
10146 gen_smul_dual(tmp
, tmp2
);
10147 if (insn
& (1 << 22)) {
10148 /* This subtraction cannot overflow. */
10149 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10151 /* This addition cannot overflow 32 bits;
10152 * however it may overflow considered as a signed
10153 * operation, in which case we must set the Q flag.
10155 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10157 tcg_temp_free_i32(tmp2
);
10160 tmp2
= load_reg(s
, rs
);
10161 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10162 tcg_temp_free_i32(tmp2
);
10165 case 3: /* 32 * 16 -> 32msb */
10167 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10170 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10171 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10172 tmp
= tcg_temp_new_i32();
10173 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10174 tcg_temp_free_i64(tmp64
);
10177 tmp2
= load_reg(s
, rs
);
10178 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10179 tcg_temp_free_i32(tmp2
);
10182 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10183 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10185 tmp
= load_reg(s
, rs
);
10186 if (insn
& (1 << 20)) {
10187 tmp64
= gen_addq_msw(tmp64
, tmp
);
10189 tmp64
= gen_subq_msw(tmp64
, tmp
);
10192 if (insn
& (1 << 4)) {
10193 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10195 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10196 tmp
= tcg_temp_new_i32();
10197 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10198 tcg_temp_free_i64(tmp64
);
10200 case 7: /* Unsigned sum of absolute differences. */
10201 gen_helper_usad8(tmp
, tmp
, tmp2
);
10202 tcg_temp_free_i32(tmp2
);
10204 tmp2
= load_reg(s
, rs
);
10205 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10206 tcg_temp_free_i32(tmp2
);
10210 store_reg(s
, rd
, tmp
);
10212 case 6: case 7: /* 64-bit multiply, Divide. */
10213 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10214 tmp
= load_reg(s
, rn
);
10215 tmp2
= load_reg(s
, rm
);
10216 if ((op
& 0x50) == 0x10) {
10218 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10222 gen_helper_udiv(tmp
, tmp
, tmp2
);
10224 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10225 tcg_temp_free_i32(tmp2
);
10226 store_reg(s
, rd
, tmp
);
10227 } else if ((op
& 0xe) == 0xc) {
10228 /* Dual multiply accumulate long. */
10229 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10230 tcg_temp_free_i32(tmp
);
10231 tcg_temp_free_i32(tmp2
);
10235 gen_swap_half(tmp2
);
10236 gen_smul_dual(tmp
, tmp2
);
10238 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10240 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10242 tcg_temp_free_i32(tmp2
);
10244 tmp64
= tcg_temp_new_i64();
10245 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10246 tcg_temp_free_i32(tmp
);
10247 gen_addq(s
, tmp64
, rs
, rd
);
10248 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10249 tcg_temp_free_i64(tmp64
);
10252 /* Unsigned 64-bit multiply */
10253 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10257 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10258 tcg_temp_free_i32(tmp2
);
10259 tcg_temp_free_i32(tmp
);
10262 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10263 tcg_temp_free_i32(tmp2
);
10264 tmp64
= tcg_temp_new_i64();
10265 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10266 tcg_temp_free_i32(tmp
);
10268 /* Signed 64-bit multiply */
10269 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10274 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10275 tcg_temp_free_i64(tmp64
);
10278 gen_addq_lo(s
, tmp64
, rs
);
10279 gen_addq_lo(s
, tmp64
, rd
);
10280 } else if (op
& 0x40) {
10281 /* 64-bit accumulate. */
10282 gen_addq(s
, tmp64
, rs
, rd
);
10284 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10285 tcg_temp_free_i64(tmp64
);
10290 case 6: case 7: case 14: case 15:
10292 if (((insn
>> 24) & 3) == 3) {
10293 /* Translate into the equivalent ARM encoding. */
10294 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10295 if (disas_neon_data_insn(s
, insn
)) {
10298 } else if (((insn
>> 8) & 0xe) == 10) {
10299 if (disas_vfp_insn(s
, insn
)) {
10303 if (insn
& (1 << 28))
10305 if (disas_coproc_insn(s
, insn
)) {
10310 case 8: case 9: case 10: case 11:
10311 if (insn
& (1 << 15)) {
10312 /* Branches, misc control. */
10313 if (insn
& 0x5000) {
10314 /* Unconditional branch. */
10315 /* signextend(hw1[10:0]) -> offset[:12]. */
10316 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10317 /* hw1[10:0] -> offset[11:1]. */
10318 offset
|= (insn
& 0x7ff) << 1;
10319 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10320 offset[24:22] already have the same value because of the
10321 sign extension above. */
10322 offset
^= ((~insn
) & (1 << 13)) << 10;
10323 offset
^= ((~insn
) & (1 << 11)) << 11;
10325 if (insn
& (1 << 14)) {
10326 /* Branch and link. */
10327 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10331 if (insn
& (1 << 12)) {
10333 gen_jmp(s
, offset
);
10336 offset
&= ~(uint32_t)2;
10337 /* thumb2 bx, no need to check */
10338 gen_bx_im(s
, offset
);
10340 } else if (((insn
>> 23) & 7) == 7) {
10342 if (insn
& (1 << 13))
10345 if (insn
& (1 << 26)) {
10346 if (!(insn
& (1 << 20))) {
10347 /* Hypervisor call (v7) */
10348 int imm16
= extract32(insn
, 16, 4) << 12
10349 | extract32(insn
, 0, 12);
10356 /* Secure monitor call (v6+) */
10364 op
= (insn
>> 20) & 7;
10366 case 0: /* msr cpsr. */
10367 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10368 tmp
= load_reg(s
, rn
);
10369 addr
= tcg_const_i32(insn
& 0xff);
10370 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10371 tcg_temp_free_i32(addr
);
10372 tcg_temp_free_i32(tmp
);
10377 case 1: /* msr spsr. */
10378 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10382 if (extract32(insn
, 5, 1)) {
10384 int sysm
= extract32(insn
, 8, 4) |
10385 (extract32(insn
, 4, 1) << 4);
10388 gen_msr_banked(s
, r
, sysm
, rm
);
10392 /* MSR (for PSRs) */
10393 tmp
= load_reg(s
, rn
);
10395 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10399 case 2: /* cps, nop-hint. */
10400 if (((insn
>> 8) & 7) == 0) {
10401 gen_nop_hint(s
, insn
& 0xff);
10403 /* Implemented as NOP in user mode. */
10408 if (insn
& (1 << 10)) {
10409 if (insn
& (1 << 7))
10411 if (insn
& (1 << 6))
10413 if (insn
& (1 << 5))
10415 if (insn
& (1 << 9))
10416 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10418 if (insn
& (1 << 8)) {
10420 imm
|= (insn
& 0x1f);
10423 gen_set_psr_im(s
, offset
, 0, imm
);
10426 case 3: /* Special control operations. */
10428 op
= (insn
>> 4) & 0xf;
10430 case 2: /* clrex */
10435 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10438 /* We need to break the TB after this insn
10439 * to execute self-modifying code correctly
10440 * and also to take any pending interrupts
10450 /* Trivial implementation equivalent to bx. */
10451 tmp
= load_reg(s
, rn
);
10454 case 5: /* Exception return. */
10458 if (rn
!= 14 || rd
!= 15) {
10461 tmp
= load_reg(s
, rn
);
10462 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10463 gen_exception_return(s
, tmp
);
10466 if (extract32(insn
, 5, 1)) {
10468 int sysm
= extract32(insn
, 16, 4) |
10469 (extract32(insn
, 4, 1) << 4);
10471 gen_mrs_banked(s
, 0, sysm
, rd
);
10476 tmp
= tcg_temp_new_i32();
10477 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10478 addr
= tcg_const_i32(insn
& 0xff);
10479 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10480 tcg_temp_free_i32(addr
);
10482 gen_helper_cpsr_read(tmp
, cpu_env
);
10484 store_reg(s
, rd
, tmp
);
10487 if (extract32(insn
, 5, 1)) {
10489 int sysm
= extract32(insn
, 16, 4) |
10490 (extract32(insn
, 4, 1) << 4);
10492 gen_mrs_banked(s
, 1, sysm
, rd
);
10497 /* Not accessible in user mode. */
10498 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10501 tmp
= load_cpu_field(spsr
);
10502 store_reg(s
, rd
, tmp
);
10507 /* Conditional branch. */
10508 op
= (insn
>> 22) & 0xf;
10509 /* Generate a conditional jump to next instruction. */
10510 s
->condlabel
= gen_new_label();
10511 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10514 /* offset[11:1] = insn[10:0] */
10515 offset
= (insn
& 0x7ff) << 1;
10516 /* offset[17:12] = insn[21:16]. */
10517 offset
|= (insn
& 0x003f0000) >> 4;
10518 /* offset[31:20] = insn[26]. */
10519 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10520 /* offset[18] = insn[13]. */
10521 offset
|= (insn
& (1 << 13)) << 5;
10522 /* offset[19] = insn[11]. */
10523 offset
|= (insn
& (1 << 11)) << 8;
10525 /* jump to the offset */
10526 gen_jmp(s
, s
->pc
+ offset
);
10529 /* Data processing immediate. */
10530 if (insn
& (1 << 25)) {
10531 if (insn
& (1 << 24)) {
10532 if (insn
& (1 << 20))
10534 /* Bitfield/Saturate. */
10535 op
= (insn
>> 21) & 7;
10537 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10539 tmp
= tcg_temp_new_i32();
10540 tcg_gen_movi_i32(tmp
, 0);
10542 tmp
= load_reg(s
, rn
);
10545 case 2: /* Signed bitfield extract. */
10547 if (shift
+ imm
> 32)
10550 gen_sbfx(tmp
, shift
, imm
);
10552 case 6: /* Unsigned bitfield extract. */
10554 if (shift
+ imm
> 32)
10557 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
10559 case 3: /* Bitfield insert/clear. */
10562 imm
= imm
+ 1 - shift
;
10564 tmp2
= load_reg(s
, rd
);
10565 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10566 tcg_temp_free_i32(tmp2
);
10571 default: /* Saturate. */
10574 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10576 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10578 tmp2
= tcg_const_i32(imm
);
10581 if ((op
& 1) && shift
== 0) {
10582 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10583 tcg_temp_free_i32(tmp
);
10584 tcg_temp_free_i32(tmp2
);
10587 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10589 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10593 if ((op
& 1) && shift
== 0) {
10594 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10595 tcg_temp_free_i32(tmp
);
10596 tcg_temp_free_i32(tmp2
);
10599 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10601 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10604 tcg_temp_free_i32(tmp2
);
10607 store_reg(s
, rd
, tmp
);
10609 imm
= ((insn
& 0x04000000) >> 15)
10610 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10611 if (insn
& (1 << 22)) {
10612 /* 16-bit immediate. */
10613 imm
|= (insn
>> 4) & 0xf000;
10614 if (insn
& (1 << 23)) {
10616 tmp
= load_reg(s
, rd
);
10617 tcg_gen_ext16u_i32(tmp
, tmp
);
10618 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10621 tmp
= tcg_temp_new_i32();
10622 tcg_gen_movi_i32(tmp
, imm
);
10625 /* Add/sub 12-bit immediate. */
10627 offset
= s
->pc
& ~(uint32_t)3;
10628 if (insn
& (1 << 23))
10632 tmp
= tcg_temp_new_i32();
10633 tcg_gen_movi_i32(tmp
, offset
);
10635 tmp
= load_reg(s
, rn
);
10636 if (insn
& (1 << 23))
10637 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10639 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10642 store_reg(s
, rd
, tmp
);
10645 int shifter_out
= 0;
10646 /* modified 12-bit immediate. */
10647 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10648 imm
= (insn
& 0xff);
10651 /* Nothing to do. */
10653 case 1: /* 00XY00XY */
10656 case 2: /* XY00XY00 */
10660 case 3: /* XYXYXYXY */
10664 default: /* Rotated constant. */
10665 shift
= (shift
<< 1) | (imm
>> 7);
10667 imm
= imm
<< (32 - shift
);
10671 tmp2
= tcg_temp_new_i32();
10672 tcg_gen_movi_i32(tmp2
, imm
);
10673 rn
= (insn
>> 16) & 0xf;
10675 tmp
= tcg_temp_new_i32();
10676 tcg_gen_movi_i32(tmp
, 0);
10678 tmp
= load_reg(s
, rn
);
10680 op
= (insn
>> 21) & 0xf;
10681 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10682 shifter_out
, tmp
, tmp2
))
10684 tcg_temp_free_i32(tmp2
);
10685 rd
= (insn
>> 8) & 0xf;
10687 store_reg(s
, rd
, tmp
);
10689 tcg_temp_free_i32(tmp
);
10694 case 12: /* Load/store single data item. */
10699 if ((insn
& 0x01100000) == 0x01000000) {
10700 if (disas_neon_ls_insn(s
, insn
)) {
10705 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10707 if (!(insn
& (1 << 20))) {
10711 /* Byte or halfword load space with dest == r15 : memory hints.
10712 * Catch them early so we don't emit pointless addressing code.
10713 * This space is a mix of:
10714 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10715 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10717 * unallocated hints, which must be treated as NOPs
10718 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10719 * which is easiest for the decoding logic
10720 * Some space which must UNDEF
10722 int op1
= (insn
>> 23) & 3;
10723 int op2
= (insn
>> 6) & 0x3f;
10728 /* UNPREDICTABLE, unallocated hint or
10729 * PLD/PLDW/PLI (literal)
10734 return 0; /* PLD/PLDW/PLI or unallocated hint */
10736 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10737 return 0; /* PLD/PLDW/PLI or unallocated hint */
10739 /* UNDEF space, or an UNPREDICTABLE */
10743 memidx
= get_mem_index(s
);
10745 addr
= tcg_temp_new_i32();
10747 /* s->pc has already been incremented by 4. */
10748 imm
= s
->pc
& 0xfffffffc;
10749 if (insn
& (1 << 23))
10750 imm
+= insn
& 0xfff;
10752 imm
-= insn
& 0xfff;
10753 tcg_gen_movi_i32(addr
, imm
);
10755 addr
= load_reg(s
, rn
);
10756 if (insn
& (1 << 23)) {
10757 /* Positive offset. */
10758 imm
= insn
& 0xfff;
10759 tcg_gen_addi_i32(addr
, addr
, imm
);
10762 switch ((insn
>> 8) & 0xf) {
10763 case 0x0: /* Shifted Register. */
10764 shift
= (insn
>> 4) & 0xf;
10766 tcg_temp_free_i32(addr
);
10769 tmp
= load_reg(s
, rm
);
10771 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10772 tcg_gen_add_i32(addr
, addr
, tmp
);
10773 tcg_temp_free_i32(tmp
);
10775 case 0xc: /* Negative offset. */
10776 tcg_gen_addi_i32(addr
, addr
, -imm
);
10778 case 0xe: /* User privilege. */
10779 tcg_gen_addi_i32(addr
, addr
, imm
);
10780 memidx
= get_a32_user_mem_index(s
);
10782 case 0x9: /* Post-decrement. */
10784 /* Fall through. */
10785 case 0xb: /* Post-increment. */
10789 case 0xd: /* Pre-decrement. */
10791 /* Fall through. */
10792 case 0xf: /* Pre-increment. */
10793 tcg_gen_addi_i32(addr
, addr
, imm
);
10797 tcg_temp_free_i32(addr
);
10802 if (insn
& (1 << 20)) {
10804 tmp
= tcg_temp_new_i32();
10807 gen_aa32_ld8u(s
, tmp
, addr
, memidx
);
10810 gen_aa32_ld8s(s
, tmp
, addr
, memidx
);
10813 gen_aa32_ld16u(s
, tmp
, addr
, memidx
);
10816 gen_aa32_ld16s(s
, tmp
, addr
, memidx
);
10819 gen_aa32_ld32u(s
, tmp
, addr
, memidx
);
10822 tcg_temp_free_i32(tmp
);
10823 tcg_temp_free_i32(addr
);
10829 store_reg(s
, rs
, tmp
);
10833 tmp
= load_reg(s
, rs
);
10836 gen_aa32_st8(s
, tmp
, addr
, memidx
);
10839 gen_aa32_st16(s
, tmp
, addr
, memidx
);
10842 gen_aa32_st32(s
, tmp
, addr
, memidx
);
10845 tcg_temp_free_i32(tmp
);
10846 tcg_temp_free_i32(addr
);
10849 tcg_temp_free_i32(tmp
);
10852 tcg_gen_addi_i32(addr
, addr
, imm
);
10854 store_reg(s
, rn
, addr
);
10856 tcg_temp_free_i32(addr
);
10868 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10870 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10877 if (s
->condexec_mask
) {
10878 cond
= s
->condexec_cond
;
10879 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10880 s
->condlabel
= gen_new_label();
10881 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10886 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
10889 switch (insn
>> 12) {
10893 op
= (insn
>> 11) & 3;
10896 rn
= (insn
>> 3) & 7;
10897 tmp
= load_reg(s
, rn
);
10898 if (insn
& (1 << 10)) {
10900 tmp2
= tcg_temp_new_i32();
10901 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10904 rm
= (insn
>> 6) & 7;
10905 tmp2
= load_reg(s
, rm
);
10907 if (insn
& (1 << 9)) {
10908 if (s
->condexec_mask
)
10909 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10911 gen_sub_CC(tmp
, tmp
, tmp2
);
10913 if (s
->condexec_mask
)
10914 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10916 gen_add_CC(tmp
, tmp
, tmp2
);
10918 tcg_temp_free_i32(tmp2
);
10919 store_reg(s
, rd
, tmp
);
10921 /* shift immediate */
10922 rm
= (insn
>> 3) & 7;
10923 shift
= (insn
>> 6) & 0x1f;
10924 tmp
= load_reg(s
, rm
);
10925 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10926 if (!s
->condexec_mask
)
10928 store_reg(s
, rd
, tmp
);
10932 /* arithmetic large immediate */
10933 op
= (insn
>> 11) & 3;
10934 rd
= (insn
>> 8) & 0x7;
10935 if (op
== 0) { /* mov */
10936 tmp
= tcg_temp_new_i32();
10937 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10938 if (!s
->condexec_mask
)
10940 store_reg(s
, rd
, tmp
);
10942 tmp
= load_reg(s
, rd
);
10943 tmp2
= tcg_temp_new_i32();
10944 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10947 gen_sub_CC(tmp
, tmp
, tmp2
);
10948 tcg_temp_free_i32(tmp
);
10949 tcg_temp_free_i32(tmp2
);
10952 if (s
->condexec_mask
)
10953 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10955 gen_add_CC(tmp
, tmp
, tmp2
);
10956 tcg_temp_free_i32(tmp2
);
10957 store_reg(s
, rd
, tmp
);
10960 if (s
->condexec_mask
)
10961 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10963 gen_sub_CC(tmp
, tmp
, tmp2
);
10964 tcg_temp_free_i32(tmp2
);
10965 store_reg(s
, rd
, tmp
);
10971 if (insn
& (1 << 11)) {
10972 rd
= (insn
>> 8) & 7;
10973 /* load pc-relative. Bit 1 of PC is ignored. */
10974 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10975 val
&= ~(uint32_t)2;
10976 addr
= tcg_temp_new_i32();
10977 tcg_gen_movi_i32(addr
, val
);
10978 tmp
= tcg_temp_new_i32();
10979 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10980 tcg_temp_free_i32(addr
);
10981 store_reg(s
, rd
, tmp
);
10984 if (insn
& (1 << 10)) {
10985 /* data processing extended or blx */
10986 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10987 rm
= (insn
>> 3) & 0xf;
10988 op
= (insn
>> 8) & 3;
10991 tmp
= load_reg(s
, rd
);
10992 tmp2
= load_reg(s
, rm
);
10993 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10994 tcg_temp_free_i32(tmp2
);
10995 store_reg(s
, rd
, tmp
);
10998 tmp
= load_reg(s
, rd
);
10999 tmp2
= load_reg(s
, rm
);
11000 gen_sub_CC(tmp
, tmp
, tmp2
);
11001 tcg_temp_free_i32(tmp2
);
11002 tcg_temp_free_i32(tmp
);
11004 case 2: /* mov/cpy */
11005 tmp
= load_reg(s
, rm
);
11006 store_reg(s
, rd
, tmp
);
11008 case 3:/* branch [and link] exchange thumb register */
11009 tmp
= load_reg(s
, rm
);
11010 if (insn
& (1 << 7)) {
11012 val
= (uint32_t)s
->pc
| 1;
11013 tmp2
= tcg_temp_new_i32();
11014 tcg_gen_movi_i32(tmp2
, val
);
11015 store_reg(s
, 14, tmp2
);
11017 /* already thumb, no need to check */
11024 /* data processing register */
11026 rm
= (insn
>> 3) & 7;
11027 op
= (insn
>> 6) & 0xf;
11028 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11029 /* the shift/rotate ops want the operands backwards */
11038 if (op
== 9) { /* neg */
11039 tmp
= tcg_temp_new_i32();
11040 tcg_gen_movi_i32(tmp
, 0);
11041 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11042 tmp
= load_reg(s
, rd
);
11044 TCGV_UNUSED_I32(tmp
);
11047 tmp2
= load_reg(s
, rm
);
11049 case 0x0: /* and */
11050 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11051 if (!s
->condexec_mask
)
11054 case 0x1: /* eor */
11055 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11056 if (!s
->condexec_mask
)
11059 case 0x2: /* lsl */
11060 if (s
->condexec_mask
) {
11061 gen_shl(tmp2
, tmp2
, tmp
);
11063 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11064 gen_logic_CC(tmp2
);
11067 case 0x3: /* lsr */
11068 if (s
->condexec_mask
) {
11069 gen_shr(tmp2
, tmp2
, tmp
);
11071 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11072 gen_logic_CC(tmp2
);
11075 case 0x4: /* asr */
11076 if (s
->condexec_mask
) {
11077 gen_sar(tmp2
, tmp2
, tmp
);
11079 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11080 gen_logic_CC(tmp2
);
11083 case 0x5: /* adc */
11084 if (s
->condexec_mask
) {
11085 gen_adc(tmp
, tmp2
);
11087 gen_adc_CC(tmp
, tmp
, tmp2
);
11090 case 0x6: /* sbc */
11091 if (s
->condexec_mask
) {
11092 gen_sub_carry(tmp
, tmp
, tmp2
);
11094 gen_sbc_CC(tmp
, tmp
, tmp2
);
11097 case 0x7: /* ror */
11098 if (s
->condexec_mask
) {
11099 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11100 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11102 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11103 gen_logic_CC(tmp2
);
11106 case 0x8: /* tst */
11107 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11111 case 0x9: /* neg */
11112 if (s
->condexec_mask
)
11113 tcg_gen_neg_i32(tmp
, tmp2
);
11115 gen_sub_CC(tmp
, tmp
, tmp2
);
11117 case 0xa: /* cmp */
11118 gen_sub_CC(tmp
, tmp
, tmp2
);
11121 case 0xb: /* cmn */
11122 gen_add_CC(tmp
, tmp
, tmp2
);
11125 case 0xc: /* orr */
11126 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11127 if (!s
->condexec_mask
)
11130 case 0xd: /* mul */
11131 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11132 if (!s
->condexec_mask
)
11135 case 0xe: /* bic */
11136 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11137 if (!s
->condexec_mask
)
11140 case 0xf: /* mvn */
11141 tcg_gen_not_i32(tmp2
, tmp2
);
11142 if (!s
->condexec_mask
)
11143 gen_logic_CC(tmp2
);
11150 store_reg(s
, rm
, tmp2
);
11152 tcg_temp_free_i32(tmp
);
11154 store_reg(s
, rd
, tmp
);
11155 tcg_temp_free_i32(tmp2
);
11158 tcg_temp_free_i32(tmp
);
11159 tcg_temp_free_i32(tmp2
);
11164 /* load/store register offset. */
11166 rn
= (insn
>> 3) & 7;
11167 rm
= (insn
>> 6) & 7;
11168 op
= (insn
>> 9) & 7;
11169 addr
= load_reg(s
, rn
);
11170 tmp
= load_reg(s
, rm
);
11171 tcg_gen_add_i32(addr
, addr
, tmp
);
11172 tcg_temp_free_i32(tmp
);
11174 if (op
< 3) { /* store */
11175 tmp
= load_reg(s
, rd
);
11177 tmp
= tcg_temp_new_i32();
11182 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11185 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11188 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11190 case 3: /* ldrsb */
11191 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
11194 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11197 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11200 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11202 case 7: /* ldrsh */
11203 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
11206 if (op
>= 3) { /* load */
11207 store_reg(s
, rd
, tmp
);
11209 tcg_temp_free_i32(tmp
);
11211 tcg_temp_free_i32(addr
);
11215 /* load/store word immediate offset */
11217 rn
= (insn
>> 3) & 7;
11218 addr
= load_reg(s
, rn
);
11219 val
= (insn
>> 4) & 0x7c;
11220 tcg_gen_addi_i32(addr
, addr
, val
);
11222 if (insn
& (1 << 11)) {
11224 tmp
= tcg_temp_new_i32();
11225 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11226 store_reg(s
, rd
, tmp
);
11229 tmp
= load_reg(s
, rd
);
11230 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11231 tcg_temp_free_i32(tmp
);
11233 tcg_temp_free_i32(addr
);
11237 /* load/store byte immediate offset */
11239 rn
= (insn
>> 3) & 7;
11240 addr
= load_reg(s
, rn
);
11241 val
= (insn
>> 6) & 0x1f;
11242 tcg_gen_addi_i32(addr
, addr
, val
);
11244 if (insn
& (1 << 11)) {
11246 tmp
= tcg_temp_new_i32();
11247 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11248 store_reg(s
, rd
, tmp
);
11251 tmp
= load_reg(s
, rd
);
11252 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11253 tcg_temp_free_i32(tmp
);
11255 tcg_temp_free_i32(addr
);
11259 /* load/store halfword immediate offset */
11261 rn
= (insn
>> 3) & 7;
11262 addr
= load_reg(s
, rn
);
11263 val
= (insn
>> 5) & 0x3e;
11264 tcg_gen_addi_i32(addr
, addr
, val
);
11266 if (insn
& (1 << 11)) {
11268 tmp
= tcg_temp_new_i32();
11269 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11270 store_reg(s
, rd
, tmp
);
11273 tmp
= load_reg(s
, rd
);
11274 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11275 tcg_temp_free_i32(tmp
);
11277 tcg_temp_free_i32(addr
);
11281 /* load/store from stack */
11282 rd
= (insn
>> 8) & 7;
11283 addr
= load_reg(s
, 13);
11284 val
= (insn
& 0xff) * 4;
11285 tcg_gen_addi_i32(addr
, addr
, val
);
11287 if (insn
& (1 << 11)) {
11289 tmp
= tcg_temp_new_i32();
11290 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11291 store_reg(s
, rd
, tmp
);
11294 tmp
= load_reg(s
, rd
);
11295 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11296 tcg_temp_free_i32(tmp
);
11298 tcg_temp_free_i32(addr
);
11302 /* add to high reg */
11303 rd
= (insn
>> 8) & 7;
11304 if (insn
& (1 << 11)) {
11306 tmp
= load_reg(s
, 13);
11308 /* PC. bit 1 is ignored. */
11309 tmp
= tcg_temp_new_i32();
11310 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11312 val
= (insn
& 0xff) * 4;
11313 tcg_gen_addi_i32(tmp
, tmp
, val
);
11314 store_reg(s
, rd
, tmp
);
11319 op
= (insn
>> 8) & 0xf;
11322 /* adjust stack pointer */
11323 tmp
= load_reg(s
, 13);
11324 val
= (insn
& 0x7f) * 4;
11325 if (insn
& (1 << 7))
11326 val
= -(int32_t)val
;
11327 tcg_gen_addi_i32(tmp
, tmp
, val
);
11328 store_reg(s
, 13, tmp
);
11331 case 2: /* sign/zero extend. */
11334 rm
= (insn
>> 3) & 7;
11335 tmp
= load_reg(s
, rm
);
11336 switch ((insn
>> 6) & 3) {
11337 case 0: gen_sxth(tmp
); break;
11338 case 1: gen_sxtb(tmp
); break;
11339 case 2: gen_uxth(tmp
); break;
11340 case 3: gen_uxtb(tmp
); break;
11342 store_reg(s
, rd
, tmp
);
11344 case 4: case 5: case 0xc: case 0xd:
11346 addr
= load_reg(s
, 13);
11347 if (insn
& (1 << 8))
11351 for (i
= 0; i
< 8; i
++) {
11352 if (insn
& (1 << i
))
11355 if ((insn
& (1 << 11)) == 0) {
11356 tcg_gen_addi_i32(addr
, addr
, -offset
);
11358 for (i
= 0; i
< 8; i
++) {
11359 if (insn
& (1 << i
)) {
11360 if (insn
& (1 << 11)) {
11362 tmp
= tcg_temp_new_i32();
11363 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11364 store_reg(s
, i
, tmp
);
11367 tmp
= load_reg(s
, i
);
11368 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11369 tcg_temp_free_i32(tmp
);
11371 /* advance to the next address. */
11372 tcg_gen_addi_i32(addr
, addr
, 4);
11375 TCGV_UNUSED_I32(tmp
);
11376 if (insn
& (1 << 8)) {
11377 if (insn
& (1 << 11)) {
11379 tmp
= tcg_temp_new_i32();
11380 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11381 /* don't set the pc until the rest of the instruction
11385 tmp
= load_reg(s
, 14);
11386 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11387 tcg_temp_free_i32(tmp
);
11389 tcg_gen_addi_i32(addr
, addr
, 4);
11391 if ((insn
& (1 << 11)) == 0) {
11392 tcg_gen_addi_i32(addr
, addr
, -offset
);
11394 /* write back the new stack pointer */
11395 store_reg(s
, 13, addr
);
11396 /* set the new PC value */
11397 if ((insn
& 0x0900) == 0x0900) {
11398 store_reg_from_load(s
, 15, tmp
);
11402 case 1: case 3: case 9: case 11: /* czb */
11404 tmp
= load_reg(s
, rm
);
11405 s
->condlabel
= gen_new_label();
11407 if (insn
& (1 << 11))
11408 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11410 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11411 tcg_temp_free_i32(tmp
);
11412 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11413 val
= (uint32_t)s
->pc
+ 2;
11418 case 15: /* IT, nop-hint. */
11419 if ((insn
& 0xf) == 0) {
11420 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11424 s
->condexec_cond
= (insn
>> 4) & 0xe;
11425 s
->condexec_mask
= insn
& 0x1f;
11426 /* No actual code generated for this insn, just setup state. */
11429 case 0xe: /* bkpt */
11431 int imm8
= extract32(insn
, 0, 8);
11433 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11434 default_exception_el(s
));
11438 case 0xa: /* rev */
11440 rn
= (insn
>> 3) & 0x7;
11442 tmp
= load_reg(s
, rn
);
11443 switch ((insn
>> 6) & 3) {
11444 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11445 case 1: gen_rev16(tmp
); break;
11446 case 3: gen_revsh(tmp
); break;
11447 default: goto illegal_op
;
11449 store_reg(s
, rd
, tmp
);
11453 switch ((insn
>> 5) & 7) {
11457 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11458 gen_helper_setend(cpu_env
);
11459 s
->is_jmp
= DISAS_UPDATE
;
11468 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11469 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11472 addr
= tcg_const_i32(19);
11473 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11474 tcg_temp_free_i32(addr
);
11478 addr
= tcg_const_i32(16);
11479 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11480 tcg_temp_free_i32(addr
);
11482 tcg_temp_free_i32(tmp
);
11485 if (insn
& (1 << 4)) {
11486 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11490 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11505 /* load/store multiple */
11506 TCGv_i32 loaded_var
;
11507 TCGV_UNUSED_I32(loaded_var
);
11508 rn
= (insn
>> 8) & 0x7;
11509 addr
= load_reg(s
, rn
);
11510 for (i
= 0; i
< 8; i
++) {
11511 if (insn
& (1 << i
)) {
11512 if (insn
& (1 << 11)) {
11514 tmp
= tcg_temp_new_i32();
11515 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11519 store_reg(s
, i
, tmp
);
11523 tmp
= load_reg(s
, i
);
11524 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11525 tcg_temp_free_i32(tmp
);
11527 /* advance to the next address */
11528 tcg_gen_addi_i32(addr
, addr
, 4);
11531 if ((insn
& (1 << rn
)) == 0) {
11532 /* base reg not in list: base register writeback */
11533 store_reg(s
, rn
, addr
);
11535 /* base reg in list: if load, complete it now */
11536 if (insn
& (1 << 11)) {
11537 store_reg(s
, rn
, loaded_var
);
11539 tcg_temp_free_i32(addr
);
11544 /* conditional branch or swi */
11545 cond
= (insn
>> 8) & 0xf;
11551 gen_set_pc_im(s
, s
->pc
);
11552 s
->svc_imm
= extract32(insn
, 0, 8);
11553 s
->is_jmp
= DISAS_SWI
;
11556 /* generate a conditional jump to next instruction */
11557 s
->condlabel
= gen_new_label();
11558 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11561 /* jump to the offset */
11562 val
= (uint32_t)s
->pc
+ 2;
11563 offset
= ((int32_t)insn
<< 24) >> 24;
11564 val
+= offset
<< 1;
11569 if (insn
& (1 << 11)) {
11570 if (disas_thumb2_insn(env
, s
, insn
))
11574 /* unconditional branch */
11575 val
= (uint32_t)s
->pc
;
11576 offset
= ((int32_t)insn
<< 21) >> 21;
11577 val
+= (offset
<< 1) + 2;
11582 if (disas_thumb2_insn(env
, s
, insn
))
11588 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11589 default_exception_el(s
));
11593 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11594 default_exception_el(s
));
11597 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11599 /* Return true if the insn at dc->pc might cross a page boundary.
11600 * (False positives are OK, false negatives are not.)
11604 if ((s
->pc
& 3) == 0) {
11605 /* At a 4-aligned address we can't be crossing a page */
11609 /* This must be a Thumb insn */
11610 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11612 if ((insn
>> 11) >= 0x1d) {
11613 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11614 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11615 * end up actually treating this as two 16-bit insns (see the
11616 * code at the start of disas_thumb2_insn()) but we don't bother
11617 * to check for that as it is unlikely, and false positives here
11622 /* Definitely a 16-bit insn, can't be crossing a page. */
11626 /* generate intermediate code for basic block 'tb'. */
11627 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11629 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11630 CPUState
*cs
= CPU(cpu
);
11631 DisasContext dc1
, *dc
= &dc1
;
11632 target_ulong pc_start
;
11633 target_ulong next_page_start
;
11638 /* generate intermediate code */
11640 /* The A64 decoder has its own top level loop, because it doesn't need
11641 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11643 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11644 gen_intermediate_code_a64(cpu
, tb
);
11652 dc
->is_jmp
= DISAS_NEXT
;
11654 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11658 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11659 * there is no secure EL1, so we route exceptions to EL3.
11661 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11662 !arm_el_is_aa64(env
, 3);
11663 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11664 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(tb
->flags
);
11665 dc
->be_data
= ARM_TBFLAG_BE_DATA(tb
->flags
) ? MO_BE
: MO_LE
;
11666 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11667 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11668 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11669 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11670 #if !defined(CONFIG_USER_ONLY)
11671 dc
->user
= (dc
->current_el
== 0);
11673 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11674 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11675 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11676 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11677 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11678 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11679 dc
->cp_regs
= cpu
->cp_regs
;
11680 dc
->features
= env
->features
;
11682 /* Single step state. The code-generation logic here is:
11684 * generate code with no special handling for single-stepping (except
11685 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11686 * this happens anyway because those changes are all system register or
11688 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11689 * emit code for one insn
11690 * emit code to clear PSTATE.SS
11691 * emit code to generate software step exception for completed step
11692 * end TB (as usual for having generated an exception)
11693 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11694 * emit code to generate a software step exception
11697 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11698 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11699 dc
->is_ldex
= false;
11700 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11702 cpu_F0s
= tcg_temp_new_i32();
11703 cpu_F1s
= tcg_temp_new_i32();
11704 cpu_F0d
= tcg_temp_new_i64();
11705 cpu_F1d
= tcg_temp_new_i64();
11708 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11709 cpu_M0
= tcg_temp_new_i64();
11710 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11712 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11713 if (max_insns
== 0) {
11714 max_insns
= CF_COUNT_MASK
;
11716 if (max_insns
> TCG_MAX_INSNS
) {
11717 max_insns
= TCG_MAX_INSNS
;
11722 tcg_clear_temp_count();
11724 /* A note on handling of the condexec (IT) bits:
11726 * We want to avoid the overhead of having to write the updated condexec
11727 * bits back to the CPUARMState for every instruction in an IT block. So:
11728 * (1) if the condexec bits are not already zero then we write
11729 * zero back into the CPUARMState now. This avoids complications trying
11730 * to do it at the end of the block. (For example if we don't do this
11731 * it's hard to identify whether we can safely skip writing condexec
11732 * at the end of the TB, which we definitely want to do for the case
11733 * where a TB doesn't do anything with the IT state at all.)
11734 * (2) if we are going to leave the TB then we call gen_set_condexec()
11735 * which will write the correct value into CPUARMState if zero is wrong.
11736 * This is done both for leaving the TB at the end, and for leaving
11737 * it because of an exception we know will happen, which is done in
11738 * gen_exception_insn(). The latter is necessary because we need to
11739 * leave the TB with the PC/IT state just prior to execution of the
11740 * instruction which caused the exception.
11741 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11742 * then the CPUARMState will be wrong and we need to reset it.
11743 * This is handled in the same way as restoration of the
11744 * PC in these situations; we save the value of the condexec bits
11745 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11746 * then uses this to restore them after an exception.
11748 * Note that there are no instructions which can read the condexec
11749 * bits, and none which can write non-static values to them, so
11750 * we don't need to care about whether CPUARMState is correct in the
11754 /* Reset the conditional execution bits immediately. This avoids
11755 complications trying to do it at the end of the block. */
11756 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11758 TCGv_i32 tmp
= tcg_temp_new_i32();
11759 tcg_gen_movi_i32(tmp
, 0);
11760 store_cpu_field(tmp
, condexec_bits
);
11763 tcg_gen_insn_start(dc
->pc
,
11764 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11768 #ifdef CONFIG_USER_ONLY
11769 /* Intercept jump to the magic kernel page. */
11770 if (dc
->pc
>= 0xffff0000) {
11771 /* We always get here via a jump, so know we are not in a
11772 conditional execution block. */
11773 gen_exception_internal(EXCP_KERNEL_TRAP
);
11774 dc
->is_jmp
= DISAS_EXC
;
11778 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11779 /* We always get here via a jump, so know we are not in a
11780 conditional execution block. */
11781 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11782 dc
->is_jmp
= DISAS_EXC
;
11787 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11789 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11790 if (bp
->pc
== dc
->pc
) {
11791 if (bp
->flags
& BP_CPU
) {
11792 gen_set_condexec(dc
);
11793 gen_set_pc_im(dc
, dc
->pc
);
11794 gen_helper_check_breakpoints(cpu_env
);
11795 /* End the TB early; it's likely not going to be executed */
11796 dc
->is_jmp
= DISAS_UPDATE
;
11798 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11799 /* The address covered by the breakpoint must be
11800 included in [tb->pc, tb->pc + tb->size) in order
11801 to for it to be properly cleared -- thus we
11802 increment the PC here so that the logic setting
11803 tb->size below does the right thing. */
11804 /* TODO: Advance PC by correct instruction length to
11805 * avoid disassembler error messages */
11807 goto done_generating
;
11814 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11818 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11819 /* Singlestep state is Active-pending.
11820 * If we're in this state at the start of a TB then either
11821 * a) we just took an exception to an EL which is being debugged
11822 * and this is the first insn in the exception handler
11823 * b) debug exceptions were masked and we just unmasked them
11824 * without changing EL (eg by clearing PSTATE.D)
11825 * In either case we're going to take a swstep exception in the
11826 * "did not step an insn" case, and so the syndrome ISV and EX
11827 * bits should be zero.
11829 assert(num_insns
== 1);
11830 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11831 default_exception_el(dc
));
11832 goto done_generating
;
11836 disas_thumb_insn(env
, dc
);
11837 if (dc
->condexec_mask
) {
11838 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11839 | ((dc
->condexec_mask
>> 4) & 1);
11840 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11841 if (dc
->condexec_mask
== 0) {
11842 dc
->condexec_cond
= 0;
11846 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
11848 disas_arm_insn(dc
, insn
);
11851 if (dc
->condjmp
&& !dc
->is_jmp
) {
11852 gen_set_label(dc
->condlabel
);
11856 if (tcg_check_temp_count()) {
11857 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11861 /* Translation stops when a conditional branch is encountered.
11862 * Otherwise the subsequent code could get translated several times.
11863 * Also stop translation when a page boundary is reached. This
11864 * ensures prefetch aborts occur at the right place. */
11866 /* We want to stop the TB if the next insn starts in a new page,
11867 * or if it spans between this page and the next. This means that
11868 * if we're looking at the last halfword in the page we need to
11869 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11870 * or a 32-bit Thumb insn (which won't).
11871 * This is to avoid generating a silly TB with a single 16-bit insn
11872 * in it at the end of this page (which would execute correctly
11873 * but isn't very efficient).
11875 end_of_page
= (dc
->pc
>= next_page_start
) ||
11876 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
11878 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11879 !cs
->singlestep_enabled
&&
11883 num_insns
< max_insns
);
11885 if (tb
->cflags
& CF_LAST_IO
) {
11887 /* FIXME: This can theoretically happen with self-modifying
11889 cpu_abort(cs
, "IO on conditional branch instruction");
11894 /* At this stage dc->condjmp will only be set when the skipped
11895 instruction was a conditional branch or trap, and the PC has
11896 already been written. */
11897 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11898 /* Unconditional and "condition passed" instruction codepath. */
11899 gen_set_condexec(dc
);
11900 switch (dc
->is_jmp
) {
11902 gen_ss_advance(dc
);
11903 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11904 default_exception_el(dc
));
11907 gen_ss_advance(dc
);
11908 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11911 gen_ss_advance(dc
);
11912 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11916 gen_set_pc_im(dc
, dc
->pc
);
11919 if (dc
->ss_active
) {
11920 gen_step_complete_exception(dc
);
11922 /* FIXME: Single stepping a WFI insn will not halt
11924 gen_exception_internal(EXCP_DEBUG
);
11928 /* "Condition failed" instruction codepath. */
11929 gen_set_label(dc
->condlabel
);
11930 gen_set_condexec(dc
);
11931 gen_set_pc_im(dc
, dc
->pc
);
11932 if (dc
->ss_active
) {
11933 gen_step_complete_exception(dc
);
11935 gen_exception_internal(EXCP_DEBUG
);
11939 /* While branches must always occur at the end of an IT block,
11940 there are a few other things that can cause us to terminate
11941 the TB in the middle of an IT block:
11942 - Exception generating instructions (bkpt, swi, undefined).
11944 - Hardware watchpoints.
11945 Hardware breakpoints have already been handled and skip this code.
11947 gen_set_condexec(dc
);
11948 switch(dc
->is_jmp
) {
11950 gen_goto_tb(dc
, 1, dc
->pc
);
11953 gen_set_pc_im(dc
, dc
->pc
);
11957 /* indicate that the hash table must be used to find the next TB */
11958 tcg_gen_exit_tb(0);
11960 case DISAS_TB_JUMP
:
11961 /* nothing more to generate */
11964 gen_helper_wfi(cpu_env
);
11965 /* The helper doesn't necessarily throw an exception, but we
11966 * must go back to the main loop to check for interrupts anyway.
11968 tcg_gen_exit_tb(0);
11971 gen_helper_wfe(cpu_env
);
11974 gen_helper_yield(cpu_env
);
11977 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11978 default_exception_el(dc
));
11981 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11984 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11988 gen_set_label(dc
->condlabel
);
11989 gen_set_condexec(dc
);
11990 gen_goto_tb(dc
, 1, dc
->pc
);
11996 gen_tb_end(tb
, num_insns
);
11999 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
) &&
12000 qemu_log_in_addr_range(pc_start
)) {
12001 qemu_log("----------------\n");
12002 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
12003 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
12004 dc
->thumb
| (dc
->sctlr_b
<< 1));
12008 tb
->size
= dc
->pc
- pc_start
;
12009 tb
->icount
= num_insns
;
12012 static const char *cpu_mode_names
[16] = {
12013 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12014 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12017 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12020 ARMCPU
*cpu
= ARM_CPU(cs
);
12021 CPUARMState
*env
= &cpu
->env
;
12024 const char *ns_status
;
12027 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12031 for(i
=0;i
<16;i
++) {
12032 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12034 cpu_fprintf(f
, "\n");
12036 cpu_fprintf(f
, " ");
12038 psr
= cpsr_read(env
);
12040 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12041 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12042 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12047 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12049 psr
& (1 << 31) ? 'N' : '-',
12050 psr
& (1 << 30) ? 'Z' : '-',
12051 psr
& (1 << 29) ? 'C' : '-',
12052 psr
& (1 << 28) ? 'V' : '-',
12053 psr
& CPSR_T
? 'T' : 'A',
12055 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12057 if (flags
& CPU_DUMP_FPU
) {
12058 int numvfpregs
= 0;
12059 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12062 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12065 for (i
= 0; i
< numvfpregs
; i
++) {
12066 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12067 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12068 i
* 2, (uint32_t)v
,
12069 i
* 2 + 1, (uint32_t)(v
>> 32),
12072 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12076 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12077 target_ulong
*data
)
12081 env
->condexec_bits
= 0;
12082 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12084 env
->regs
[15] = data
[0];
12085 env
->condexec_bits
= data
[1];
12086 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;