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 /* In Thumb mode, we must ignore bit 0.
184 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
185 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
186 * We choose to ignore [1:0] in ARM mode for all architecture versions.
188 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
189 s
->is_jmp
= DISAS_JUMP
;
191 tcg_gen_mov_i32(cpu_R
[reg
], var
);
192 tcg_temp_free_i32(var
);
195 /* Value extensions. */
196 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
197 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
198 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
199 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
201 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
202 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
205 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
207 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
208 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
209 tcg_temp_free_i32(tmp_mask
);
211 /* Set NZCV flags from the high 4 bits of var. */
212 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
214 static void gen_exception_internal(int excp
)
216 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
218 assert(excp_is_internal(excp
));
219 gen_helper_exception_internal(cpu_env
, tcg_excp
);
220 tcg_temp_free_i32(tcg_excp
);
223 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
225 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
226 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
227 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
229 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
232 tcg_temp_free_i32(tcg_el
);
233 tcg_temp_free_i32(tcg_syn
);
234 tcg_temp_free_i32(tcg_excp
);
237 static void gen_ss_advance(DisasContext
*s
)
239 /* If the singlestep state is Active-not-pending, advance to
244 gen_helper_clear_pstate_ss(cpu_env
);
248 static void gen_step_complete_exception(DisasContext
*s
)
250 /* We just completed step of an insn. Move from Active-not-pending
251 * to Active-pending, and then also take the swstep exception.
252 * This corresponds to making the (IMPDEF) choice to prioritize
253 * swstep exceptions over asynchronous exceptions taken to an exception
254 * level where debug is disabled. This choice has the advantage that
255 * we do not need to maintain internal state corresponding to the
256 * ISV/EX syndrome bits between completion of the step and generation
257 * of the exception, and our syndrome information is always correct.
260 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
261 default_exception_el(s
));
262 s
->is_jmp
= DISAS_EXC
;
265 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
267 TCGv_i32 tmp1
= tcg_temp_new_i32();
268 TCGv_i32 tmp2
= tcg_temp_new_i32();
269 tcg_gen_ext16s_i32(tmp1
, a
);
270 tcg_gen_ext16s_i32(tmp2
, b
);
271 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
272 tcg_temp_free_i32(tmp2
);
273 tcg_gen_sari_i32(a
, a
, 16);
274 tcg_gen_sari_i32(b
, b
, 16);
275 tcg_gen_mul_i32(b
, b
, a
);
276 tcg_gen_mov_i32(a
, tmp1
);
277 tcg_temp_free_i32(tmp1
);
280 /* Byteswap each halfword. */
281 static void gen_rev16(TCGv_i32 var
)
283 TCGv_i32 tmp
= tcg_temp_new_i32();
284 tcg_gen_shri_i32(tmp
, var
, 8);
285 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
286 tcg_gen_shli_i32(var
, var
, 8);
287 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
288 tcg_gen_or_i32(var
, var
, tmp
);
289 tcg_temp_free_i32(tmp
);
292 /* Byteswap low halfword and sign extend. */
293 static void gen_revsh(TCGv_i32 var
)
295 tcg_gen_ext16u_i32(var
, var
);
296 tcg_gen_bswap16_i32(var
, var
);
297 tcg_gen_ext16s_i32(var
, var
);
300 /* Unsigned bitfield extract. */
301 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
304 tcg_gen_shri_i32(var
, var
, shift
);
305 tcg_gen_andi_i32(var
, var
, mask
);
308 /* Signed bitfield extract. */
309 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
314 tcg_gen_sari_i32(var
, var
, shift
);
315 if (shift
+ width
< 32) {
316 signbit
= 1u << (width
- 1);
317 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
318 tcg_gen_xori_i32(var
, var
, signbit
);
319 tcg_gen_subi_i32(var
, var
, signbit
);
323 /* Return (b << 32) + a. Mark inputs as dead */
324 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
326 TCGv_i64 tmp64
= tcg_temp_new_i64();
328 tcg_gen_extu_i32_i64(tmp64
, b
);
329 tcg_temp_free_i32(b
);
330 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
331 tcg_gen_add_i64(a
, tmp64
, a
);
333 tcg_temp_free_i64(tmp64
);
337 /* Return (b << 32) - a. Mark inputs as dead. */
338 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
340 TCGv_i64 tmp64
= tcg_temp_new_i64();
342 tcg_gen_extu_i32_i64(tmp64
, b
);
343 tcg_temp_free_i32(b
);
344 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
345 tcg_gen_sub_i64(a
, tmp64
, a
);
347 tcg_temp_free_i64(tmp64
);
351 /* 32x32->64 multiply. Marks inputs as dead. */
352 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
354 TCGv_i32 lo
= tcg_temp_new_i32();
355 TCGv_i32 hi
= tcg_temp_new_i32();
358 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
359 tcg_temp_free_i32(a
);
360 tcg_temp_free_i32(b
);
362 ret
= tcg_temp_new_i64();
363 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
364 tcg_temp_free_i32(lo
);
365 tcg_temp_free_i32(hi
);
370 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
372 TCGv_i32 lo
= tcg_temp_new_i32();
373 TCGv_i32 hi
= tcg_temp_new_i32();
376 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
377 tcg_temp_free_i32(a
);
378 tcg_temp_free_i32(b
);
380 ret
= tcg_temp_new_i64();
381 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
382 tcg_temp_free_i32(lo
);
383 tcg_temp_free_i32(hi
);
388 /* Swap low and high halfwords. */
389 static void gen_swap_half(TCGv_i32 var
)
391 TCGv_i32 tmp
= tcg_temp_new_i32();
392 tcg_gen_shri_i32(tmp
, var
, 16);
393 tcg_gen_shli_i32(var
, var
, 16);
394 tcg_gen_or_i32(var
, var
, tmp
);
395 tcg_temp_free_i32(tmp
);
398 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
399 tmp = (t0 ^ t1) & 0x8000;
402 t0 = (t0 + t1) ^ tmp;
405 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
407 TCGv_i32 tmp
= tcg_temp_new_i32();
408 tcg_gen_xor_i32(tmp
, t0
, t1
);
409 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
410 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
411 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
412 tcg_gen_add_i32(t0
, t0
, t1
);
413 tcg_gen_xor_i32(t0
, t0
, tmp
);
414 tcg_temp_free_i32(tmp
);
415 tcg_temp_free_i32(t1
);
418 /* Set CF to the top bit of var. */
419 static void gen_set_CF_bit31(TCGv_i32 var
)
421 tcg_gen_shri_i32(cpu_CF
, var
, 31);
424 /* Set N and Z flags from var. */
425 static inline void gen_logic_CC(TCGv_i32 var
)
427 tcg_gen_mov_i32(cpu_NF
, var
);
428 tcg_gen_mov_i32(cpu_ZF
, var
);
432 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
434 tcg_gen_add_i32(t0
, t0
, t1
);
435 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
438 /* dest = T0 + T1 + CF. */
439 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
441 tcg_gen_add_i32(dest
, t0
, t1
);
442 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
445 /* dest = T0 - T1 + CF - 1. */
446 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
448 tcg_gen_sub_i32(dest
, t0
, t1
);
449 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
450 tcg_gen_subi_i32(dest
, dest
, 1);
453 /* dest = T0 + T1. Compute C, N, V and Z flags */
454 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
456 TCGv_i32 tmp
= tcg_temp_new_i32();
457 tcg_gen_movi_i32(tmp
, 0);
458 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
459 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
460 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
461 tcg_gen_xor_i32(tmp
, t0
, t1
);
462 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
463 tcg_temp_free_i32(tmp
);
464 tcg_gen_mov_i32(dest
, cpu_NF
);
467 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
468 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
470 TCGv_i32 tmp
= tcg_temp_new_i32();
471 if (TCG_TARGET_HAS_add2_i32
) {
472 tcg_gen_movi_i32(tmp
, 0);
473 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
474 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
476 TCGv_i64 q0
= tcg_temp_new_i64();
477 TCGv_i64 q1
= tcg_temp_new_i64();
478 tcg_gen_extu_i32_i64(q0
, t0
);
479 tcg_gen_extu_i32_i64(q1
, t1
);
480 tcg_gen_add_i64(q0
, q0
, q1
);
481 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
482 tcg_gen_add_i64(q0
, q0
, q1
);
483 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
484 tcg_temp_free_i64(q0
);
485 tcg_temp_free_i64(q1
);
487 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
488 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
489 tcg_gen_xor_i32(tmp
, t0
, t1
);
490 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
491 tcg_temp_free_i32(tmp
);
492 tcg_gen_mov_i32(dest
, cpu_NF
);
495 /* dest = T0 - T1. Compute C, N, V and Z flags */
496 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
499 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
500 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
501 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
502 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
503 tmp
= tcg_temp_new_i32();
504 tcg_gen_xor_i32(tmp
, t0
, t1
);
505 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
506 tcg_temp_free_i32(tmp
);
507 tcg_gen_mov_i32(dest
, cpu_NF
);
510 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
511 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
513 TCGv_i32 tmp
= tcg_temp_new_i32();
514 tcg_gen_not_i32(tmp
, t1
);
515 gen_adc_CC(dest
, t0
, tmp
);
516 tcg_temp_free_i32(tmp
);
519 #define GEN_SHIFT(name) \
520 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
522 TCGv_i32 tmp1, tmp2, tmp3; \
523 tmp1 = tcg_temp_new_i32(); \
524 tcg_gen_andi_i32(tmp1, t1, 0xff); \
525 tmp2 = tcg_const_i32(0); \
526 tmp3 = tcg_const_i32(0x1f); \
527 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
528 tcg_temp_free_i32(tmp3); \
529 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
530 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
531 tcg_temp_free_i32(tmp2); \
532 tcg_temp_free_i32(tmp1); \
538 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
541 tmp1
= tcg_temp_new_i32();
542 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
543 tmp2
= tcg_const_i32(0x1f);
544 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
545 tcg_temp_free_i32(tmp2
);
546 tcg_gen_sar_i32(dest
, t0
, tmp1
);
547 tcg_temp_free_i32(tmp1
);
550 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
552 TCGv_i32 c0
= tcg_const_i32(0);
553 TCGv_i32 tmp
= tcg_temp_new_i32();
554 tcg_gen_neg_i32(tmp
, src
);
555 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
556 tcg_temp_free_i32(c0
);
557 tcg_temp_free_i32(tmp
);
560 static void shifter_out_im(TCGv_i32 var
, int shift
)
563 tcg_gen_andi_i32(cpu_CF
, var
, 1);
565 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
567 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
572 /* Shift by immediate. Includes special handling for shift == 0. */
573 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
574 int shift
, int flags
)
580 shifter_out_im(var
, 32 - shift
);
581 tcg_gen_shli_i32(var
, var
, shift
);
587 tcg_gen_shri_i32(cpu_CF
, var
, 31);
589 tcg_gen_movi_i32(var
, 0);
592 shifter_out_im(var
, shift
- 1);
593 tcg_gen_shri_i32(var
, var
, shift
);
600 shifter_out_im(var
, shift
- 1);
603 tcg_gen_sari_i32(var
, var
, shift
);
605 case 3: /* ROR/RRX */
608 shifter_out_im(var
, shift
- 1);
609 tcg_gen_rotri_i32(var
, var
, shift
); break;
611 TCGv_i32 tmp
= tcg_temp_new_i32();
612 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
614 shifter_out_im(var
, 0);
615 tcg_gen_shri_i32(var
, var
, 1);
616 tcg_gen_or_i32(var
, var
, tmp
);
617 tcg_temp_free_i32(tmp
);
622 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
623 TCGv_i32 shift
, int flags
)
627 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
628 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
629 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
630 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
635 gen_shl(var
, var
, shift
);
638 gen_shr(var
, var
, shift
);
641 gen_sar(var
, var
, shift
);
643 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
644 tcg_gen_rotr_i32(var
, var
, shift
); break;
647 tcg_temp_free_i32(shift
);
650 #define PAS_OP(pfx) \
652 case 0: gen_pas_helper(glue(pfx,add16)); break; \
653 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
654 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
655 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
656 case 4: gen_pas_helper(glue(pfx,add8)); break; \
657 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
659 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
664 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
666 tmp
= tcg_temp_new_ptr();
667 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
669 tcg_temp_free_ptr(tmp
);
672 tmp
= tcg_temp_new_ptr();
673 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
675 tcg_temp_free_ptr(tmp
);
677 #undef gen_pas_helper
678 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
691 #undef gen_pas_helper
696 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
697 #define PAS_OP(pfx) \
699 case 0: gen_pas_helper(glue(pfx,add8)); break; \
700 case 1: gen_pas_helper(glue(pfx,add16)); break; \
701 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
702 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
703 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
704 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
706 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
711 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
713 tmp
= tcg_temp_new_ptr();
714 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
716 tcg_temp_free_ptr(tmp
);
719 tmp
= tcg_temp_new_ptr();
720 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
722 tcg_temp_free_ptr(tmp
);
724 #undef gen_pas_helper
725 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
738 #undef gen_pas_helper
744 * Generate a conditional based on ARM condition code cc.
745 * This is common between ARM and Aarch64 targets.
747 void arm_test_cc(DisasCompare
*cmp
, int cc
)
778 case 8: /* hi: C && !Z */
779 case 9: /* ls: !C || Z -> !(C && !Z) */
781 value
= tcg_temp_new_i32();
783 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
784 ZF is non-zero for !Z; so AND the two subexpressions. */
785 tcg_gen_neg_i32(value
, cpu_CF
);
786 tcg_gen_and_i32(value
, value
, cpu_ZF
);
789 case 10: /* ge: N == V -> N ^ V == 0 */
790 case 11: /* lt: N != V -> N ^ V != 0 */
791 /* Since we're only interested in the sign bit, == 0 is >= 0. */
793 value
= tcg_temp_new_i32();
795 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
798 case 12: /* gt: !Z && N == V */
799 case 13: /* le: Z || N != V */
801 value
= tcg_temp_new_i32();
803 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
804 * the sign bit then AND with ZF to yield the result. */
805 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
806 tcg_gen_sari_i32(value
, value
, 31);
807 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
810 case 14: /* always */
811 case 15: /* always */
812 /* Use the ALWAYS condition, which will fold early.
813 * It doesn't matter what we use for the value. */
814 cond
= TCG_COND_ALWAYS
;
819 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
824 cond
= tcg_invert_cond(cond
);
830 cmp
->value_global
= global
;
833 void arm_free_cc(DisasCompare
*cmp
)
835 if (!cmp
->value_global
) {
836 tcg_temp_free_i32(cmp
->value
);
840 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
842 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
845 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
848 arm_test_cc(&cmp
, cc
);
849 arm_jump_cc(&cmp
, label
);
853 static const uint8_t table_logic_cc
[16] = {
872 /* Set PC and Thumb state from an immediate address. */
873 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
877 s
->is_jmp
= DISAS_JUMP
;
878 if (s
->thumb
!= (addr
& 1)) {
879 tmp
= tcg_temp_new_i32();
880 tcg_gen_movi_i32(tmp
, addr
& 1);
881 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
882 tcg_temp_free_i32(tmp
);
884 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
887 /* Set PC and Thumb state from var. var is marked as dead. */
888 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
890 s
->is_jmp
= DISAS_JUMP
;
891 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
892 tcg_gen_andi_i32(var
, var
, 1);
893 store_cpu_field(var
, thumb
);
896 /* Variant of store_reg which uses branch&exchange logic when storing
897 to r15 in ARM architecture v7 and above. The source must be a temporary
898 and will be marked as dead. */
899 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
901 if (reg
== 15 && ENABLE_ARCH_7
) {
904 store_reg(s
, reg
, var
);
908 /* Variant of store_reg which uses branch&exchange logic when storing
909 * to r15 in ARM architecture v5T and above. This is used for storing
910 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
911 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
912 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
914 if (reg
== 15 && ENABLE_ARCH_5
) {
917 store_reg(s
, reg
, var
);
921 #ifdef CONFIG_USER_ONLY
922 #define IS_USER_ONLY 1
924 #define IS_USER_ONLY 0
927 /* Abstractions of "generate code to do a guest load/store for
928 * AArch32", where a vaddr is always 32 bits (and is zero
929 * extended if we're a 64 bit core) and data is also
930 * 32 bits unless specifically doing a 64 bit access.
931 * These functions work like tcg_gen_qemu_{ld,st}* except
932 * that the address argument is TCGv_i32 rather than TCGv.
934 #if TARGET_LONG_BITS == 32
936 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
937 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
938 TCGv_i32 addr, int index) \
940 TCGMemOp opc = (OPC) | s->be_data; \
941 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
942 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
943 TCGv addr_be = tcg_temp_new(); \
944 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
945 tcg_gen_qemu_ld_i32(val, addr_be, index, opc); \
946 tcg_temp_free(addr_be); \
949 tcg_gen_qemu_ld_i32(val, addr, index, opc); \
952 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
953 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
954 TCGv_i32 addr, int index) \
956 TCGMemOp opc = (OPC) | s->be_data; \
957 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
958 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
959 TCGv addr_be = tcg_temp_new(); \
960 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
961 tcg_gen_qemu_st_i32(val, addr_be, index, opc); \
962 tcg_temp_free(addr_be); \
965 tcg_gen_qemu_st_i32(val, addr, index, opc); \
968 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
969 TCGv_i32 addr
, int index
)
971 TCGMemOp opc
= MO_Q
| s
->be_data
;
972 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
973 /* Not needed for user-mode BE32, where we use MO_BE instead. */
974 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
975 tcg_gen_rotri_i64(val
, val
, 32);
979 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
980 TCGv_i32 addr
, int index
)
982 TCGMemOp opc
= MO_Q
| s
->be_data
;
983 /* Not needed for user-mode BE32, where we use MO_BE instead. */
984 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
985 TCGv_i64 tmp
= tcg_temp_new_i64();
986 tcg_gen_rotri_i64(tmp
, val
, 32);
987 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
988 tcg_temp_free_i64(tmp
);
991 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
996 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
997 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
998 TCGv_i32 addr, int index) \
1000 TCGMemOp opc = (OPC) | s->be_data; \
1001 TCGv addr64 = tcg_temp_new(); \
1002 tcg_gen_extu_i32_i64(addr64, addr); \
1003 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
1004 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
1005 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1007 tcg_gen_qemu_ld_i32(val, addr64, index, opc); \
1008 tcg_temp_free(addr64); \
1011 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
1012 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1013 TCGv_i32 addr, int index) \
1015 TCGMemOp opc = (OPC) | s->be_data; \
1016 TCGv addr64 = tcg_temp_new(); \
1017 tcg_gen_extu_i32_i64(addr64, addr); \
1018 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
1019 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
1020 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1022 tcg_gen_qemu_st_i32(val, addr64, index, opc); \
1023 tcg_temp_free(addr64); \
1026 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1027 TCGv_i32 addr
, int index
)
1029 TCGMemOp opc
= MO_Q
| s
->be_data
;
1030 TCGv addr64
= tcg_temp_new();
1031 tcg_gen_extu_i32_i64(addr64
, addr
);
1032 tcg_gen_qemu_ld_i64(val
, addr64
, index
, opc
);
1034 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1035 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1036 tcg_gen_rotri_i64(val
, val
, 32);
1038 tcg_temp_free(addr64
);
1041 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1042 TCGv_i32 addr
, int index
)
1044 TCGMemOp opc
= MO_Q
| s
->be_data
;
1045 TCGv addr64
= tcg_temp_new();
1046 tcg_gen_extu_i32_i64(addr64
, addr
);
1048 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1049 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1050 TCGv tmp
= tcg_temp_new();
1051 tcg_gen_rotri_i64(tmp
, val
, 32);
1052 tcg_gen_qemu_st_i64(tmp
, addr64
, index
, opc
);
1055 tcg_gen_qemu_st_i64(val
, addr64
, index
, opc
);
1057 tcg_temp_free(addr64
);
1062 DO_GEN_LD(8s
, MO_SB
, 3)
1063 DO_GEN_LD(8u, MO_UB
, 3)
1064 DO_GEN_LD(16s
, MO_SW
, 2)
1065 DO_GEN_LD(16u, MO_UW
, 2)
1066 DO_GEN_LD(32u, MO_UL
, 0)
1067 /* 'a' variants include an alignment check */
1068 DO_GEN_LD(16ua
, MO_UW
| MO_ALIGN
, 2)
1069 DO_GEN_LD(32ua
, MO_UL
| MO_ALIGN
, 0)
1070 DO_GEN_ST(8, MO_UB
, 3)
1071 DO_GEN_ST(16, MO_UW
, 2)
1072 DO_GEN_ST(32, MO_UL
, 0)
1074 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
1076 tcg_gen_movi_i32(cpu_R
[15], val
);
1079 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1081 /* The pre HVC helper handles cases when HVC gets trapped
1082 * as an undefined insn by runtime configuration (ie before
1083 * the insn really executes).
1085 gen_set_pc_im(s
, s
->pc
- 4);
1086 gen_helper_pre_hvc(cpu_env
);
1087 /* Otherwise we will treat this as a real exception which
1088 * happens after execution of the insn. (The distinction matters
1089 * for the PC value reported to the exception handler and also
1090 * for single stepping.)
1093 gen_set_pc_im(s
, s
->pc
);
1094 s
->is_jmp
= DISAS_HVC
;
1097 static inline void gen_smc(DisasContext
*s
)
1099 /* As with HVC, we may take an exception either before or after
1100 * the insn executes.
1104 gen_set_pc_im(s
, s
->pc
- 4);
1105 tmp
= tcg_const_i32(syn_aa32_smc());
1106 gen_helper_pre_smc(cpu_env
, tmp
);
1107 tcg_temp_free_i32(tmp
);
1108 gen_set_pc_im(s
, s
->pc
);
1109 s
->is_jmp
= DISAS_SMC
;
1113 gen_set_condexec (DisasContext
*s
)
1115 if (s
->condexec_mask
) {
1116 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1117 TCGv_i32 tmp
= tcg_temp_new_i32();
1118 tcg_gen_movi_i32(tmp
, val
);
1119 store_cpu_field(tmp
, condexec_bits
);
1123 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1125 gen_set_condexec(s
);
1126 gen_set_pc_im(s
, s
->pc
- offset
);
1127 gen_exception_internal(excp
);
1128 s
->is_jmp
= DISAS_JUMP
;
1131 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1132 int syn
, uint32_t target_el
)
1134 gen_set_condexec(s
);
1135 gen_set_pc_im(s
, s
->pc
- offset
);
1136 gen_exception(excp
, syn
, target_el
);
1137 s
->is_jmp
= DISAS_JUMP
;
1140 /* Force a TB lookup after an instruction that changes the CPU state. */
1141 static inline void gen_lookup_tb(DisasContext
*s
)
1143 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1144 s
->is_jmp
= DISAS_JUMP
;
1147 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1150 int val
, rm
, shift
, shiftop
;
1153 if (!(insn
& (1 << 25))) {
1156 if (!(insn
& (1 << 23)))
1159 tcg_gen_addi_i32(var
, var
, val
);
1161 /* shift/register */
1163 shift
= (insn
>> 7) & 0x1f;
1164 shiftop
= (insn
>> 5) & 3;
1165 offset
= load_reg(s
, rm
);
1166 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1167 if (!(insn
& (1 << 23)))
1168 tcg_gen_sub_i32(var
, var
, offset
);
1170 tcg_gen_add_i32(var
, var
, offset
);
1171 tcg_temp_free_i32(offset
);
1175 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1176 int extra
, TCGv_i32 var
)
1181 if (insn
& (1 << 22)) {
1183 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1184 if (!(insn
& (1 << 23)))
1188 tcg_gen_addi_i32(var
, var
, val
);
1192 tcg_gen_addi_i32(var
, var
, extra
);
1194 offset
= load_reg(s
, rm
);
1195 if (!(insn
& (1 << 23)))
1196 tcg_gen_sub_i32(var
, var
, offset
);
1198 tcg_gen_add_i32(var
, var
, offset
);
1199 tcg_temp_free_i32(offset
);
1203 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1205 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1208 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1210 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1212 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1216 #define VFP_OP2(name) \
1217 static inline void gen_vfp_##name(int dp) \
1219 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1221 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1223 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1225 tcg_temp_free_ptr(fpst); \
1235 static inline void gen_vfp_F1_mul(int dp
)
1237 /* Like gen_vfp_mul() but put result in F1 */
1238 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1240 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1242 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1244 tcg_temp_free_ptr(fpst
);
1247 static inline void gen_vfp_F1_neg(int dp
)
1249 /* Like gen_vfp_neg() but put result in F1 */
1251 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1253 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1257 static inline void gen_vfp_abs(int dp
)
1260 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1262 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1265 static inline void gen_vfp_neg(int dp
)
1268 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1270 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1273 static inline void gen_vfp_sqrt(int dp
)
1276 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1278 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1281 static inline void gen_vfp_cmp(int dp
)
1284 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1286 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1289 static inline void gen_vfp_cmpe(int dp
)
1292 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1294 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1297 static inline void gen_vfp_F1_ld0(int dp
)
1300 tcg_gen_movi_i64(cpu_F1d
, 0);
1302 tcg_gen_movi_i32(cpu_F1s
, 0);
1305 #define VFP_GEN_ITOF(name) \
1306 static inline void gen_vfp_##name(int dp, int neon) \
1308 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1310 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1312 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1314 tcg_temp_free_ptr(statusptr); \
1321 #define VFP_GEN_FTOI(name) \
1322 static inline void gen_vfp_##name(int dp, int neon) \
1324 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1326 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1328 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1330 tcg_temp_free_ptr(statusptr); \
1339 #define VFP_GEN_FIX(name, round) \
1340 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1342 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1343 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1345 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1348 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1351 tcg_temp_free_i32(tmp_shift); \
1352 tcg_temp_free_ptr(statusptr); \
1354 VFP_GEN_FIX(tosh
, _round_to_zero
)
1355 VFP_GEN_FIX(tosl
, _round_to_zero
)
1356 VFP_GEN_FIX(touh
, _round_to_zero
)
1357 VFP_GEN_FIX(toul
, _round_to_zero
)
1364 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1367 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1369 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1373 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1376 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1378 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1383 vfp_reg_offset (int dp
, int reg
)
1386 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1388 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1389 + offsetof(CPU_DoubleU
, l
.upper
);
1391 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1392 + offsetof(CPU_DoubleU
, l
.lower
);
1396 /* Return the offset of a 32-bit piece of a NEON register.
1397 zero is the least significant end of the register. */
1399 neon_reg_offset (int reg
, int n
)
1403 return vfp_reg_offset(0, sreg
);
1406 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1408 TCGv_i32 tmp
= tcg_temp_new_i32();
1409 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1413 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1415 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1416 tcg_temp_free_i32(var
);
1419 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1421 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1424 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1426 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1429 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1430 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1431 #define tcg_gen_st_f32 tcg_gen_st_i32
1432 #define tcg_gen_st_f64 tcg_gen_st_i64
1434 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1437 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1439 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1442 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1445 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1447 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1450 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1453 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1455 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1458 #define ARM_CP_RW_BIT (1 << 20)
1460 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1462 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1465 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1467 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1470 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1472 TCGv_i32 var
= tcg_temp_new_i32();
1473 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1477 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1479 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1480 tcg_temp_free_i32(var
);
1483 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1485 iwmmxt_store_reg(cpu_M0
, rn
);
1488 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1490 iwmmxt_load_reg(cpu_M0
, rn
);
1493 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1495 iwmmxt_load_reg(cpu_V1
, rn
);
1496 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1499 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1501 iwmmxt_load_reg(cpu_V1
, rn
);
1502 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1505 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1507 iwmmxt_load_reg(cpu_V1
, rn
);
1508 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1511 #define IWMMXT_OP(name) \
1512 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1514 iwmmxt_load_reg(cpu_V1, rn); \
1515 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1518 #define IWMMXT_OP_ENV(name) \
1519 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1521 iwmmxt_load_reg(cpu_V1, rn); \
1522 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1525 #define IWMMXT_OP_ENV_SIZE(name) \
1526 IWMMXT_OP_ENV(name##b) \
1527 IWMMXT_OP_ENV(name##w) \
1528 IWMMXT_OP_ENV(name##l)
1530 #define IWMMXT_OP_ENV1(name) \
1531 static inline void gen_op_iwmmxt_##name##_M0(void) \
1533 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1547 IWMMXT_OP_ENV_SIZE(unpackl
)
1548 IWMMXT_OP_ENV_SIZE(unpackh
)
1550 IWMMXT_OP_ENV1(unpacklub
)
1551 IWMMXT_OP_ENV1(unpackluw
)
1552 IWMMXT_OP_ENV1(unpacklul
)
1553 IWMMXT_OP_ENV1(unpackhub
)
1554 IWMMXT_OP_ENV1(unpackhuw
)
1555 IWMMXT_OP_ENV1(unpackhul
)
1556 IWMMXT_OP_ENV1(unpacklsb
)
1557 IWMMXT_OP_ENV1(unpacklsw
)
1558 IWMMXT_OP_ENV1(unpacklsl
)
1559 IWMMXT_OP_ENV1(unpackhsb
)
1560 IWMMXT_OP_ENV1(unpackhsw
)
1561 IWMMXT_OP_ENV1(unpackhsl
)
1563 IWMMXT_OP_ENV_SIZE(cmpeq
)
1564 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1565 IWMMXT_OP_ENV_SIZE(cmpgts
)
1567 IWMMXT_OP_ENV_SIZE(mins
)
1568 IWMMXT_OP_ENV_SIZE(minu
)
1569 IWMMXT_OP_ENV_SIZE(maxs
)
1570 IWMMXT_OP_ENV_SIZE(maxu
)
1572 IWMMXT_OP_ENV_SIZE(subn
)
1573 IWMMXT_OP_ENV_SIZE(addn
)
1574 IWMMXT_OP_ENV_SIZE(subu
)
1575 IWMMXT_OP_ENV_SIZE(addu
)
1576 IWMMXT_OP_ENV_SIZE(subs
)
1577 IWMMXT_OP_ENV_SIZE(adds
)
1579 IWMMXT_OP_ENV(avgb0
)
1580 IWMMXT_OP_ENV(avgb1
)
1581 IWMMXT_OP_ENV(avgw0
)
1582 IWMMXT_OP_ENV(avgw1
)
1584 IWMMXT_OP_ENV(packuw
)
1585 IWMMXT_OP_ENV(packul
)
1586 IWMMXT_OP_ENV(packuq
)
1587 IWMMXT_OP_ENV(packsw
)
1588 IWMMXT_OP_ENV(packsl
)
1589 IWMMXT_OP_ENV(packsq
)
1591 static void gen_op_iwmmxt_set_mup(void)
1594 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1595 tcg_gen_ori_i32(tmp
, tmp
, 2);
1596 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1599 static void gen_op_iwmmxt_set_cup(void)
1602 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1603 tcg_gen_ori_i32(tmp
, tmp
, 1);
1604 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1607 static void gen_op_iwmmxt_setpsr_nz(void)
1609 TCGv_i32 tmp
= tcg_temp_new_i32();
1610 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1611 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1614 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1616 iwmmxt_load_reg(cpu_V1
, rn
);
1617 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1618 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1621 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1628 rd
= (insn
>> 16) & 0xf;
1629 tmp
= load_reg(s
, rd
);
1631 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1632 if (insn
& (1 << 24)) {
1634 if (insn
& (1 << 23))
1635 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1637 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1638 tcg_gen_mov_i32(dest
, tmp
);
1639 if (insn
& (1 << 21))
1640 store_reg(s
, rd
, tmp
);
1642 tcg_temp_free_i32(tmp
);
1643 } else if (insn
& (1 << 21)) {
1645 tcg_gen_mov_i32(dest
, tmp
);
1646 if (insn
& (1 << 23))
1647 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1649 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1650 store_reg(s
, rd
, tmp
);
1651 } else if (!(insn
& (1 << 23)))
1656 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1658 int rd
= (insn
>> 0) & 0xf;
1661 if (insn
& (1 << 8)) {
1662 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1665 tmp
= iwmmxt_load_creg(rd
);
1668 tmp
= tcg_temp_new_i32();
1669 iwmmxt_load_reg(cpu_V0
, rd
);
1670 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1672 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1673 tcg_gen_mov_i32(dest
, tmp
);
1674 tcg_temp_free_i32(tmp
);
1678 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1679 (ie. an undefined instruction). */
1680 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1683 int rdhi
, rdlo
, rd0
, rd1
, i
;
1685 TCGv_i32 tmp
, tmp2
, tmp3
;
1687 if ((insn
& 0x0e000e00) == 0x0c000000) {
1688 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1690 rdlo
= (insn
>> 12) & 0xf;
1691 rdhi
= (insn
>> 16) & 0xf;
1692 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1693 iwmmxt_load_reg(cpu_V0
, wrd
);
1694 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1695 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1696 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1697 } else { /* TMCRR */
1698 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1699 iwmmxt_store_reg(cpu_V0
, wrd
);
1700 gen_op_iwmmxt_set_mup();
1705 wrd
= (insn
>> 12) & 0xf;
1706 addr
= tcg_temp_new_i32();
1707 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1708 tcg_temp_free_i32(addr
);
1711 if (insn
& ARM_CP_RW_BIT
) {
1712 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1713 tmp
= tcg_temp_new_i32();
1714 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1715 iwmmxt_store_creg(wrd
, tmp
);
1718 if (insn
& (1 << 8)) {
1719 if (insn
& (1 << 22)) { /* WLDRD */
1720 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1722 } else { /* WLDRW wRd */
1723 tmp
= tcg_temp_new_i32();
1724 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1727 tmp
= tcg_temp_new_i32();
1728 if (insn
& (1 << 22)) { /* WLDRH */
1729 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1730 } else { /* WLDRB */
1731 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1735 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1736 tcg_temp_free_i32(tmp
);
1738 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1741 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1742 tmp
= iwmmxt_load_creg(wrd
);
1743 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1745 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1746 tmp
= tcg_temp_new_i32();
1747 if (insn
& (1 << 8)) {
1748 if (insn
& (1 << 22)) { /* WSTRD */
1749 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1750 } else { /* WSTRW wRd */
1751 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1752 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1755 if (insn
& (1 << 22)) { /* WSTRH */
1756 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1757 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1758 } else { /* WSTRB */
1759 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1760 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1764 tcg_temp_free_i32(tmp
);
1766 tcg_temp_free_i32(addr
);
1770 if ((insn
& 0x0f000000) != 0x0e000000)
1773 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1774 case 0x000: /* WOR */
1775 wrd
= (insn
>> 12) & 0xf;
1776 rd0
= (insn
>> 0) & 0xf;
1777 rd1
= (insn
>> 16) & 0xf;
1778 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1779 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1780 gen_op_iwmmxt_setpsr_nz();
1781 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1782 gen_op_iwmmxt_set_mup();
1783 gen_op_iwmmxt_set_cup();
1785 case 0x011: /* TMCR */
1788 rd
= (insn
>> 12) & 0xf;
1789 wrd
= (insn
>> 16) & 0xf;
1791 case ARM_IWMMXT_wCID
:
1792 case ARM_IWMMXT_wCASF
:
1794 case ARM_IWMMXT_wCon
:
1795 gen_op_iwmmxt_set_cup();
1797 case ARM_IWMMXT_wCSSF
:
1798 tmp
= iwmmxt_load_creg(wrd
);
1799 tmp2
= load_reg(s
, rd
);
1800 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1801 tcg_temp_free_i32(tmp2
);
1802 iwmmxt_store_creg(wrd
, tmp
);
1804 case ARM_IWMMXT_wCGR0
:
1805 case ARM_IWMMXT_wCGR1
:
1806 case ARM_IWMMXT_wCGR2
:
1807 case ARM_IWMMXT_wCGR3
:
1808 gen_op_iwmmxt_set_cup();
1809 tmp
= load_reg(s
, rd
);
1810 iwmmxt_store_creg(wrd
, tmp
);
1816 case 0x100: /* WXOR */
1817 wrd
= (insn
>> 12) & 0xf;
1818 rd0
= (insn
>> 0) & 0xf;
1819 rd1
= (insn
>> 16) & 0xf;
1820 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1821 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1822 gen_op_iwmmxt_setpsr_nz();
1823 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1824 gen_op_iwmmxt_set_mup();
1825 gen_op_iwmmxt_set_cup();
1827 case 0x111: /* TMRC */
1830 rd
= (insn
>> 12) & 0xf;
1831 wrd
= (insn
>> 16) & 0xf;
1832 tmp
= iwmmxt_load_creg(wrd
);
1833 store_reg(s
, rd
, tmp
);
1835 case 0x300: /* WANDN */
1836 wrd
= (insn
>> 12) & 0xf;
1837 rd0
= (insn
>> 0) & 0xf;
1838 rd1
= (insn
>> 16) & 0xf;
1839 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1840 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1841 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1842 gen_op_iwmmxt_setpsr_nz();
1843 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1844 gen_op_iwmmxt_set_mup();
1845 gen_op_iwmmxt_set_cup();
1847 case 0x200: /* WAND */
1848 wrd
= (insn
>> 12) & 0xf;
1849 rd0
= (insn
>> 0) & 0xf;
1850 rd1
= (insn
>> 16) & 0xf;
1851 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1852 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1853 gen_op_iwmmxt_setpsr_nz();
1854 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1855 gen_op_iwmmxt_set_mup();
1856 gen_op_iwmmxt_set_cup();
1858 case 0x810: case 0xa10: /* WMADD */
1859 wrd
= (insn
>> 12) & 0xf;
1860 rd0
= (insn
>> 0) & 0xf;
1861 rd1
= (insn
>> 16) & 0xf;
1862 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1863 if (insn
& (1 << 21))
1864 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1866 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1867 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1868 gen_op_iwmmxt_set_mup();
1870 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1871 wrd
= (insn
>> 12) & 0xf;
1872 rd0
= (insn
>> 16) & 0xf;
1873 rd1
= (insn
>> 0) & 0xf;
1874 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1875 switch ((insn
>> 22) & 3) {
1877 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1880 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1883 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1888 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1889 gen_op_iwmmxt_set_mup();
1890 gen_op_iwmmxt_set_cup();
1892 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1893 wrd
= (insn
>> 12) & 0xf;
1894 rd0
= (insn
>> 16) & 0xf;
1895 rd1
= (insn
>> 0) & 0xf;
1896 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1897 switch ((insn
>> 22) & 3) {
1899 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1902 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1905 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1910 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1911 gen_op_iwmmxt_set_mup();
1912 gen_op_iwmmxt_set_cup();
1914 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1915 wrd
= (insn
>> 12) & 0xf;
1916 rd0
= (insn
>> 16) & 0xf;
1917 rd1
= (insn
>> 0) & 0xf;
1918 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1919 if (insn
& (1 << 22))
1920 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1922 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1923 if (!(insn
& (1 << 20)))
1924 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1925 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1926 gen_op_iwmmxt_set_mup();
1928 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1929 wrd
= (insn
>> 12) & 0xf;
1930 rd0
= (insn
>> 16) & 0xf;
1931 rd1
= (insn
>> 0) & 0xf;
1932 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1933 if (insn
& (1 << 21)) {
1934 if (insn
& (1 << 20))
1935 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1937 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1939 if (insn
& (1 << 20))
1940 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1942 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1944 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1945 gen_op_iwmmxt_set_mup();
1947 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1948 wrd
= (insn
>> 12) & 0xf;
1949 rd0
= (insn
>> 16) & 0xf;
1950 rd1
= (insn
>> 0) & 0xf;
1951 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1952 if (insn
& (1 << 21))
1953 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1955 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1956 if (!(insn
& (1 << 20))) {
1957 iwmmxt_load_reg(cpu_V1
, wrd
);
1958 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1960 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1961 gen_op_iwmmxt_set_mup();
1963 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1964 wrd
= (insn
>> 12) & 0xf;
1965 rd0
= (insn
>> 16) & 0xf;
1966 rd1
= (insn
>> 0) & 0xf;
1967 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1968 switch ((insn
>> 22) & 3) {
1970 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1973 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1976 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1981 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1982 gen_op_iwmmxt_set_mup();
1983 gen_op_iwmmxt_set_cup();
1985 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1986 wrd
= (insn
>> 12) & 0xf;
1987 rd0
= (insn
>> 16) & 0xf;
1988 rd1
= (insn
>> 0) & 0xf;
1989 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1990 if (insn
& (1 << 22)) {
1991 if (insn
& (1 << 20))
1992 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1994 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1996 if (insn
& (1 << 20))
1997 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1999 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2001 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2002 gen_op_iwmmxt_set_mup();
2003 gen_op_iwmmxt_set_cup();
2005 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2006 wrd
= (insn
>> 12) & 0xf;
2007 rd0
= (insn
>> 16) & 0xf;
2008 rd1
= (insn
>> 0) & 0xf;
2009 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2010 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2011 tcg_gen_andi_i32(tmp
, tmp
, 7);
2012 iwmmxt_load_reg(cpu_V1
, rd1
);
2013 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2014 tcg_temp_free_i32(tmp
);
2015 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2016 gen_op_iwmmxt_set_mup();
2018 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2019 if (((insn
>> 6) & 3) == 3)
2021 rd
= (insn
>> 12) & 0xf;
2022 wrd
= (insn
>> 16) & 0xf;
2023 tmp
= load_reg(s
, rd
);
2024 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2025 switch ((insn
>> 6) & 3) {
2027 tmp2
= tcg_const_i32(0xff);
2028 tmp3
= tcg_const_i32((insn
& 7) << 3);
2031 tmp2
= tcg_const_i32(0xffff);
2032 tmp3
= tcg_const_i32((insn
& 3) << 4);
2035 tmp2
= tcg_const_i32(0xffffffff);
2036 tmp3
= tcg_const_i32((insn
& 1) << 5);
2039 TCGV_UNUSED_I32(tmp2
);
2040 TCGV_UNUSED_I32(tmp3
);
2042 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2043 tcg_temp_free_i32(tmp3
);
2044 tcg_temp_free_i32(tmp2
);
2045 tcg_temp_free_i32(tmp
);
2046 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2047 gen_op_iwmmxt_set_mup();
2049 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2050 rd
= (insn
>> 12) & 0xf;
2051 wrd
= (insn
>> 16) & 0xf;
2052 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2054 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2055 tmp
= tcg_temp_new_i32();
2056 switch ((insn
>> 22) & 3) {
2058 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2059 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2061 tcg_gen_ext8s_i32(tmp
, tmp
);
2063 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2067 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2068 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2070 tcg_gen_ext16s_i32(tmp
, tmp
);
2072 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2076 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2077 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2080 store_reg(s
, rd
, tmp
);
2082 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2083 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2085 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2086 switch ((insn
>> 22) & 3) {
2088 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2091 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2094 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2097 tcg_gen_shli_i32(tmp
, tmp
, 28);
2099 tcg_temp_free_i32(tmp
);
2101 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2102 if (((insn
>> 6) & 3) == 3)
2104 rd
= (insn
>> 12) & 0xf;
2105 wrd
= (insn
>> 16) & 0xf;
2106 tmp
= load_reg(s
, rd
);
2107 switch ((insn
>> 6) & 3) {
2109 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2112 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2115 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2118 tcg_temp_free_i32(tmp
);
2119 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2120 gen_op_iwmmxt_set_mup();
2122 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2123 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2125 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2126 tmp2
= tcg_temp_new_i32();
2127 tcg_gen_mov_i32(tmp2
, tmp
);
2128 switch ((insn
>> 22) & 3) {
2130 for (i
= 0; i
< 7; i
++) {
2131 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2132 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2136 for (i
= 0; i
< 3; i
++) {
2137 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2138 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2142 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2143 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2147 tcg_temp_free_i32(tmp2
);
2148 tcg_temp_free_i32(tmp
);
2150 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2151 wrd
= (insn
>> 12) & 0xf;
2152 rd0
= (insn
>> 16) & 0xf;
2153 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2154 switch ((insn
>> 22) & 3) {
2156 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2159 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2162 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2167 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2168 gen_op_iwmmxt_set_mup();
2170 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2171 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2173 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2174 tmp2
= tcg_temp_new_i32();
2175 tcg_gen_mov_i32(tmp2
, tmp
);
2176 switch ((insn
>> 22) & 3) {
2178 for (i
= 0; i
< 7; i
++) {
2179 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2180 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2184 for (i
= 0; i
< 3; i
++) {
2185 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2186 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2190 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2191 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2195 tcg_temp_free_i32(tmp2
);
2196 tcg_temp_free_i32(tmp
);
2198 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2199 rd
= (insn
>> 12) & 0xf;
2200 rd0
= (insn
>> 16) & 0xf;
2201 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2203 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2204 tmp
= tcg_temp_new_i32();
2205 switch ((insn
>> 22) & 3) {
2207 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2210 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2213 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2216 store_reg(s
, rd
, tmp
);
2218 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2219 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2220 wrd
= (insn
>> 12) & 0xf;
2221 rd0
= (insn
>> 16) & 0xf;
2222 rd1
= (insn
>> 0) & 0xf;
2223 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2224 switch ((insn
>> 22) & 3) {
2226 if (insn
& (1 << 21))
2227 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2229 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2232 if (insn
& (1 << 21))
2233 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2235 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2238 if (insn
& (1 << 21))
2239 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2241 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2246 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2247 gen_op_iwmmxt_set_mup();
2248 gen_op_iwmmxt_set_cup();
2250 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2251 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2252 wrd
= (insn
>> 12) & 0xf;
2253 rd0
= (insn
>> 16) & 0xf;
2254 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2255 switch ((insn
>> 22) & 3) {
2257 if (insn
& (1 << 21))
2258 gen_op_iwmmxt_unpacklsb_M0();
2260 gen_op_iwmmxt_unpacklub_M0();
2263 if (insn
& (1 << 21))
2264 gen_op_iwmmxt_unpacklsw_M0();
2266 gen_op_iwmmxt_unpackluw_M0();
2269 if (insn
& (1 << 21))
2270 gen_op_iwmmxt_unpacklsl_M0();
2272 gen_op_iwmmxt_unpacklul_M0();
2277 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2278 gen_op_iwmmxt_set_mup();
2279 gen_op_iwmmxt_set_cup();
2281 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2282 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2283 wrd
= (insn
>> 12) & 0xf;
2284 rd0
= (insn
>> 16) & 0xf;
2285 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2286 switch ((insn
>> 22) & 3) {
2288 if (insn
& (1 << 21))
2289 gen_op_iwmmxt_unpackhsb_M0();
2291 gen_op_iwmmxt_unpackhub_M0();
2294 if (insn
& (1 << 21))
2295 gen_op_iwmmxt_unpackhsw_M0();
2297 gen_op_iwmmxt_unpackhuw_M0();
2300 if (insn
& (1 << 21))
2301 gen_op_iwmmxt_unpackhsl_M0();
2303 gen_op_iwmmxt_unpackhul_M0();
2308 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2309 gen_op_iwmmxt_set_mup();
2310 gen_op_iwmmxt_set_cup();
2312 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2313 case 0x214: case 0x614: case 0xa14: case 0xe14:
2314 if (((insn
>> 22) & 3) == 0)
2316 wrd
= (insn
>> 12) & 0xf;
2317 rd0
= (insn
>> 16) & 0xf;
2318 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2319 tmp
= tcg_temp_new_i32();
2320 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2321 tcg_temp_free_i32(tmp
);
2324 switch ((insn
>> 22) & 3) {
2326 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2329 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2332 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2335 tcg_temp_free_i32(tmp
);
2336 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2337 gen_op_iwmmxt_set_mup();
2338 gen_op_iwmmxt_set_cup();
2340 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2341 case 0x014: case 0x414: case 0x814: case 0xc14:
2342 if (((insn
>> 22) & 3) == 0)
2344 wrd
= (insn
>> 12) & 0xf;
2345 rd0
= (insn
>> 16) & 0xf;
2346 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2347 tmp
= tcg_temp_new_i32();
2348 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2349 tcg_temp_free_i32(tmp
);
2352 switch ((insn
>> 22) & 3) {
2354 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2357 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2360 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2363 tcg_temp_free_i32(tmp
);
2364 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2365 gen_op_iwmmxt_set_mup();
2366 gen_op_iwmmxt_set_cup();
2368 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2369 case 0x114: case 0x514: case 0x914: case 0xd14:
2370 if (((insn
>> 22) & 3) == 0)
2372 wrd
= (insn
>> 12) & 0xf;
2373 rd0
= (insn
>> 16) & 0xf;
2374 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2375 tmp
= tcg_temp_new_i32();
2376 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2377 tcg_temp_free_i32(tmp
);
2380 switch ((insn
>> 22) & 3) {
2382 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2385 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2388 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2391 tcg_temp_free_i32(tmp
);
2392 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2393 gen_op_iwmmxt_set_mup();
2394 gen_op_iwmmxt_set_cup();
2396 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2397 case 0x314: case 0x714: case 0xb14: case 0xf14:
2398 if (((insn
>> 22) & 3) == 0)
2400 wrd
= (insn
>> 12) & 0xf;
2401 rd0
= (insn
>> 16) & 0xf;
2402 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2403 tmp
= tcg_temp_new_i32();
2404 switch ((insn
>> 22) & 3) {
2406 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2407 tcg_temp_free_i32(tmp
);
2410 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2413 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2414 tcg_temp_free_i32(tmp
);
2417 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2420 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2421 tcg_temp_free_i32(tmp
);
2424 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2427 tcg_temp_free_i32(tmp
);
2428 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2429 gen_op_iwmmxt_set_mup();
2430 gen_op_iwmmxt_set_cup();
2432 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2433 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2434 wrd
= (insn
>> 12) & 0xf;
2435 rd0
= (insn
>> 16) & 0xf;
2436 rd1
= (insn
>> 0) & 0xf;
2437 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2438 switch ((insn
>> 22) & 3) {
2440 if (insn
& (1 << 21))
2441 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2443 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2446 if (insn
& (1 << 21))
2447 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2449 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2452 if (insn
& (1 << 21))
2453 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2455 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2460 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2461 gen_op_iwmmxt_set_mup();
2463 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2464 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2465 wrd
= (insn
>> 12) & 0xf;
2466 rd0
= (insn
>> 16) & 0xf;
2467 rd1
= (insn
>> 0) & 0xf;
2468 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2469 switch ((insn
>> 22) & 3) {
2471 if (insn
& (1 << 21))
2472 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2474 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2477 if (insn
& (1 << 21))
2478 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2480 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2483 if (insn
& (1 << 21))
2484 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2486 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2491 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2492 gen_op_iwmmxt_set_mup();
2494 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2495 case 0x402: case 0x502: case 0x602: case 0x702:
2496 wrd
= (insn
>> 12) & 0xf;
2497 rd0
= (insn
>> 16) & 0xf;
2498 rd1
= (insn
>> 0) & 0xf;
2499 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2500 tmp
= tcg_const_i32((insn
>> 20) & 3);
2501 iwmmxt_load_reg(cpu_V1
, rd1
);
2502 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2503 tcg_temp_free_i32(tmp
);
2504 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2505 gen_op_iwmmxt_set_mup();
2507 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2508 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2509 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2510 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2511 wrd
= (insn
>> 12) & 0xf;
2512 rd0
= (insn
>> 16) & 0xf;
2513 rd1
= (insn
>> 0) & 0xf;
2514 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2515 switch ((insn
>> 20) & 0xf) {
2517 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2520 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2523 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2526 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2529 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2532 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2535 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2538 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2541 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2546 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2547 gen_op_iwmmxt_set_mup();
2548 gen_op_iwmmxt_set_cup();
2550 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2551 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2552 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2553 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2554 wrd
= (insn
>> 12) & 0xf;
2555 rd0
= (insn
>> 16) & 0xf;
2556 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2557 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2558 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2559 tcg_temp_free_i32(tmp
);
2560 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2561 gen_op_iwmmxt_set_mup();
2562 gen_op_iwmmxt_set_cup();
2564 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2565 case 0x418: case 0x518: case 0x618: case 0x718:
2566 case 0x818: case 0x918: case 0xa18: case 0xb18:
2567 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2568 wrd
= (insn
>> 12) & 0xf;
2569 rd0
= (insn
>> 16) & 0xf;
2570 rd1
= (insn
>> 0) & 0xf;
2571 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2572 switch ((insn
>> 20) & 0xf) {
2574 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2577 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2580 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2583 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2586 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2589 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2592 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2595 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2598 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2603 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2604 gen_op_iwmmxt_set_mup();
2605 gen_op_iwmmxt_set_cup();
2607 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2608 case 0x408: case 0x508: case 0x608: case 0x708:
2609 case 0x808: case 0x908: case 0xa08: case 0xb08:
2610 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2611 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2613 wrd
= (insn
>> 12) & 0xf;
2614 rd0
= (insn
>> 16) & 0xf;
2615 rd1
= (insn
>> 0) & 0xf;
2616 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2617 switch ((insn
>> 22) & 3) {
2619 if (insn
& (1 << 21))
2620 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2622 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2625 if (insn
& (1 << 21))
2626 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2628 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2631 if (insn
& (1 << 21))
2632 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2634 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2637 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2638 gen_op_iwmmxt_set_mup();
2639 gen_op_iwmmxt_set_cup();
2641 case 0x201: case 0x203: case 0x205: case 0x207:
2642 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2643 case 0x211: case 0x213: case 0x215: case 0x217:
2644 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2645 wrd
= (insn
>> 5) & 0xf;
2646 rd0
= (insn
>> 12) & 0xf;
2647 rd1
= (insn
>> 0) & 0xf;
2648 if (rd0
== 0xf || rd1
== 0xf)
2650 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2651 tmp
= load_reg(s
, rd0
);
2652 tmp2
= load_reg(s
, rd1
);
2653 switch ((insn
>> 16) & 0xf) {
2654 case 0x0: /* TMIA */
2655 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2657 case 0x8: /* TMIAPH */
2658 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2660 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2661 if (insn
& (1 << 16))
2662 tcg_gen_shri_i32(tmp
, tmp
, 16);
2663 if (insn
& (1 << 17))
2664 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2665 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2668 tcg_temp_free_i32(tmp2
);
2669 tcg_temp_free_i32(tmp
);
2672 tcg_temp_free_i32(tmp2
);
2673 tcg_temp_free_i32(tmp
);
2674 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2675 gen_op_iwmmxt_set_mup();
2684 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2685 (ie. an undefined instruction). */
2686 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2688 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2691 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2692 /* Multiply with Internal Accumulate Format */
2693 rd0
= (insn
>> 12) & 0xf;
2695 acc
= (insn
>> 5) & 7;
2700 tmp
= load_reg(s
, rd0
);
2701 tmp2
= load_reg(s
, rd1
);
2702 switch ((insn
>> 16) & 0xf) {
2704 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2706 case 0x8: /* MIAPH */
2707 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2709 case 0xc: /* MIABB */
2710 case 0xd: /* MIABT */
2711 case 0xe: /* MIATB */
2712 case 0xf: /* MIATT */
2713 if (insn
& (1 << 16))
2714 tcg_gen_shri_i32(tmp
, tmp
, 16);
2715 if (insn
& (1 << 17))
2716 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2717 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2722 tcg_temp_free_i32(tmp2
);
2723 tcg_temp_free_i32(tmp
);
2725 gen_op_iwmmxt_movq_wRn_M0(acc
);
2729 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2730 /* Internal Accumulator Access Format */
2731 rdhi
= (insn
>> 16) & 0xf;
2732 rdlo
= (insn
>> 12) & 0xf;
2738 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2739 iwmmxt_load_reg(cpu_V0
, acc
);
2740 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2741 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2742 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2743 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2745 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2746 iwmmxt_store_reg(cpu_V0
, acc
);
2754 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2755 #define VFP_SREG(insn, bigbit, smallbit) \
2756 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2757 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2758 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2759 reg = (((insn) >> (bigbit)) & 0x0f) \
2760 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2762 if (insn & (1 << (smallbit))) \
2764 reg = ((insn) >> (bigbit)) & 0x0f; \
2767 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2768 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2769 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2770 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2771 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2772 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2774 /* Move between integer and VFP cores. */
2775 static TCGv_i32
gen_vfp_mrs(void)
2777 TCGv_i32 tmp
= tcg_temp_new_i32();
2778 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2782 static void gen_vfp_msr(TCGv_i32 tmp
)
2784 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2785 tcg_temp_free_i32(tmp
);
2788 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2790 TCGv_i32 tmp
= tcg_temp_new_i32();
2792 tcg_gen_shri_i32(var
, var
, shift
);
2793 tcg_gen_ext8u_i32(var
, var
);
2794 tcg_gen_shli_i32(tmp
, var
, 8);
2795 tcg_gen_or_i32(var
, var
, tmp
);
2796 tcg_gen_shli_i32(tmp
, var
, 16);
2797 tcg_gen_or_i32(var
, var
, tmp
);
2798 tcg_temp_free_i32(tmp
);
2801 static void gen_neon_dup_low16(TCGv_i32 var
)
2803 TCGv_i32 tmp
= tcg_temp_new_i32();
2804 tcg_gen_ext16u_i32(var
, var
);
2805 tcg_gen_shli_i32(tmp
, var
, 16);
2806 tcg_gen_or_i32(var
, var
, tmp
);
2807 tcg_temp_free_i32(tmp
);
2810 static void gen_neon_dup_high16(TCGv_i32 var
)
2812 TCGv_i32 tmp
= tcg_temp_new_i32();
2813 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2814 tcg_gen_shri_i32(tmp
, var
, 16);
2815 tcg_gen_or_i32(var
, var
, tmp
);
2816 tcg_temp_free_i32(tmp
);
2819 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2821 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2822 TCGv_i32 tmp
= tcg_temp_new_i32();
2825 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2826 gen_neon_dup_u8(tmp
, 0);
2829 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2830 gen_neon_dup_low16(tmp
);
2833 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2835 default: /* Avoid compiler warnings. */
2841 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2844 uint32_t cc
= extract32(insn
, 20, 2);
2847 TCGv_i64 frn
, frm
, dest
;
2848 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2850 zero
= tcg_const_i64(0);
2852 frn
= tcg_temp_new_i64();
2853 frm
= tcg_temp_new_i64();
2854 dest
= tcg_temp_new_i64();
2856 zf
= tcg_temp_new_i64();
2857 nf
= tcg_temp_new_i64();
2858 vf
= tcg_temp_new_i64();
2860 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2861 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2862 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2864 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2865 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2868 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2872 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2875 case 2: /* ge: N == V -> N ^ V == 0 */
2876 tmp
= tcg_temp_new_i64();
2877 tcg_gen_xor_i64(tmp
, vf
, nf
);
2878 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2880 tcg_temp_free_i64(tmp
);
2882 case 3: /* gt: !Z && N == V */
2883 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2885 tmp
= tcg_temp_new_i64();
2886 tcg_gen_xor_i64(tmp
, vf
, nf
);
2887 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2889 tcg_temp_free_i64(tmp
);
2892 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2893 tcg_temp_free_i64(frn
);
2894 tcg_temp_free_i64(frm
);
2895 tcg_temp_free_i64(dest
);
2897 tcg_temp_free_i64(zf
);
2898 tcg_temp_free_i64(nf
);
2899 tcg_temp_free_i64(vf
);
2901 tcg_temp_free_i64(zero
);
2903 TCGv_i32 frn
, frm
, dest
;
2906 zero
= tcg_const_i32(0);
2908 frn
= tcg_temp_new_i32();
2909 frm
= tcg_temp_new_i32();
2910 dest
= tcg_temp_new_i32();
2911 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2912 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2915 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2919 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2922 case 2: /* ge: N == V -> N ^ V == 0 */
2923 tmp
= tcg_temp_new_i32();
2924 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2925 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2927 tcg_temp_free_i32(tmp
);
2929 case 3: /* gt: !Z && N == V */
2930 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2932 tmp
= tcg_temp_new_i32();
2933 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2934 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2936 tcg_temp_free_i32(tmp
);
2939 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2940 tcg_temp_free_i32(frn
);
2941 tcg_temp_free_i32(frm
);
2942 tcg_temp_free_i32(dest
);
2944 tcg_temp_free_i32(zero
);
2950 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2951 uint32_t rm
, uint32_t dp
)
2953 uint32_t vmin
= extract32(insn
, 6, 1);
2954 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2957 TCGv_i64 frn
, frm
, dest
;
2959 frn
= tcg_temp_new_i64();
2960 frm
= tcg_temp_new_i64();
2961 dest
= tcg_temp_new_i64();
2963 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2964 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2966 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2968 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2970 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2971 tcg_temp_free_i64(frn
);
2972 tcg_temp_free_i64(frm
);
2973 tcg_temp_free_i64(dest
);
2975 TCGv_i32 frn
, frm
, dest
;
2977 frn
= tcg_temp_new_i32();
2978 frm
= tcg_temp_new_i32();
2979 dest
= tcg_temp_new_i32();
2981 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2982 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2984 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2986 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2988 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2989 tcg_temp_free_i32(frn
);
2990 tcg_temp_free_i32(frm
);
2991 tcg_temp_free_i32(dest
);
2994 tcg_temp_free_ptr(fpst
);
2998 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3001 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3004 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3005 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3010 tcg_op
= tcg_temp_new_i64();
3011 tcg_res
= tcg_temp_new_i64();
3012 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3013 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
3014 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3015 tcg_temp_free_i64(tcg_op
);
3016 tcg_temp_free_i64(tcg_res
);
3020 tcg_op
= tcg_temp_new_i32();
3021 tcg_res
= tcg_temp_new_i32();
3022 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3023 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
3024 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3025 tcg_temp_free_i32(tcg_op
);
3026 tcg_temp_free_i32(tcg_res
);
3029 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3030 tcg_temp_free_i32(tcg_rmode
);
3032 tcg_temp_free_ptr(fpst
);
3036 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3039 bool is_signed
= extract32(insn
, 7, 1);
3040 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3041 TCGv_i32 tcg_rmode
, tcg_shift
;
3043 tcg_shift
= tcg_const_i32(0);
3045 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3046 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3049 TCGv_i64 tcg_double
, tcg_res
;
3051 /* Rd is encoded as a single precision register even when the source
3052 * is double precision.
3054 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3055 tcg_double
= tcg_temp_new_i64();
3056 tcg_res
= tcg_temp_new_i64();
3057 tcg_tmp
= tcg_temp_new_i32();
3058 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3060 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3062 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3064 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3065 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3066 tcg_temp_free_i32(tcg_tmp
);
3067 tcg_temp_free_i64(tcg_res
);
3068 tcg_temp_free_i64(tcg_double
);
3070 TCGv_i32 tcg_single
, tcg_res
;
3071 tcg_single
= tcg_temp_new_i32();
3072 tcg_res
= tcg_temp_new_i32();
3073 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3075 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3077 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3079 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3080 tcg_temp_free_i32(tcg_res
);
3081 tcg_temp_free_i32(tcg_single
);
3084 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3085 tcg_temp_free_i32(tcg_rmode
);
3087 tcg_temp_free_i32(tcg_shift
);
3089 tcg_temp_free_ptr(fpst
);
3094 /* Table for converting the most common AArch32 encoding of
3095 * rounding mode to arm_fprounding order (which matches the
3096 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3098 static const uint8_t fp_decode_rm
[] = {
3105 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3107 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3109 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3114 VFP_DREG_D(rd
, insn
);
3115 VFP_DREG_N(rn
, insn
);
3116 VFP_DREG_M(rm
, insn
);
3118 rd
= VFP_SREG_D(insn
);
3119 rn
= VFP_SREG_N(insn
);
3120 rm
= VFP_SREG_M(insn
);
3123 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3124 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3125 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3126 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3127 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3128 /* VRINTA, VRINTN, VRINTP, VRINTM */
3129 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3130 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3131 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3132 /* VCVTA, VCVTN, VCVTP, VCVTM */
3133 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3134 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3139 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3140 (ie. an undefined instruction). */
3141 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3143 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3149 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3153 /* FIXME: this access check should not take precedence over UNDEF
3154 * for invalid encodings; we will generate incorrect syndrome information
3155 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3157 if (s
->fp_excp_el
) {
3158 gen_exception_insn(s
, 4, EXCP_UDEF
,
3159 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3163 if (!s
->vfp_enabled
) {
3164 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3165 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3167 rn
= (insn
>> 16) & 0xf;
3168 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3169 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3174 if (extract32(insn
, 28, 4) == 0xf) {
3175 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3176 * only used in v8 and above.
3178 return disas_vfp_v8_insn(s
, insn
);
3181 dp
= ((insn
& 0xf00) == 0xb00);
3182 switch ((insn
>> 24) & 0xf) {
3184 if (insn
& (1 << 4)) {
3185 /* single register transfer */
3186 rd
= (insn
>> 12) & 0xf;
3191 VFP_DREG_N(rn
, insn
);
3194 if (insn
& 0x00c00060
3195 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3199 pass
= (insn
>> 21) & 1;
3200 if (insn
& (1 << 22)) {
3202 offset
= ((insn
>> 5) & 3) * 8;
3203 } else if (insn
& (1 << 5)) {
3205 offset
= (insn
& (1 << 6)) ? 16 : 0;
3210 if (insn
& ARM_CP_RW_BIT
) {
3212 tmp
= neon_load_reg(rn
, pass
);
3216 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3217 if (insn
& (1 << 23))
3223 if (insn
& (1 << 23)) {
3225 tcg_gen_shri_i32(tmp
, tmp
, 16);
3231 tcg_gen_sari_i32(tmp
, tmp
, 16);
3240 store_reg(s
, rd
, tmp
);
3243 tmp
= load_reg(s
, rd
);
3244 if (insn
& (1 << 23)) {
3247 gen_neon_dup_u8(tmp
, 0);
3248 } else if (size
== 1) {
3249 gen_neon_dup_low16(tmp
);
3251 for (n
= 0; n
<= pass
* 2; n
++) {
3252 tmp2
= tcg_temp_new_i32();
3253 tcg_gen_mov_i32(tmp2
, tmp
);
3254 neon_store_reg(rn
, n
, tmp2
);
3256 neon_store_reg(rn
, n
, tmp
);
3261 tmp2
= neon_load_reg(rn
, pass
);
3262 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3263 tcg_temp_free_i32(tmp2
);
3266 tmp2
= neon_load_reg(rn
, pass
);
3267 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3268 tcg_temp_free_i32(tmp2
);
3273 neon_store_reg(rn
, pass
, tmp
);
3277 if ((insn
& 0x6f) != 0x00)
3279 rn
= VFP_SREG_N(insn
);
3280 if (insn
& ARM_CP_RW_BIT
) {
3282 if (insn
& (1 << 21)) {
3283 /* system register */
3288 /* VFP2 allows access to FSID from userspace.
3289 VFP3 restricts all id registers to privileged
3292 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3295 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3300 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3302 case ARM_VFP_FPINST
:
3303 case ARM_VFP_FPINST2
:
3304 /* Not present in VFP3. */
3306 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3309 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3313 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3314 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3316 tmp
= tcg_temp_new_i32();
3317 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3321 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3328 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3331 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3337 gen_mov_F0_vreg(0, rn
);
3338 tmp
= gen_vfp_mrs();
3341 /* Set the 4 flag bits in the CPSR. */
3343 tcg_temp_free_i32(tmp
);
3345 store_reg(s
, rd
, tmp
);
3349 if (insn
& (1 << 21)) {
3351 /* system register */
3356 /* Writes are ignored. */
3359 tmp
= load_reg(s
, rd
);
3360 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3361 tcg_temp_free_i32(tmp
);
3367 /* TODO: VFP subarchitecture support.
3368 * For now, keep the EN bit only */
3369 tmp
= load_reg(s
, rd
);
3370 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3371 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3374 case ARM_VFP_FPINST
:
3375 case ARM_VFP_FPINST2
:
3379 tmp
= load_reg(s
, rd
);
3380 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3386 tmp
= load_reg(s
, rd
);
3388 gen_mov_vreg_F0(0, rn
);
3393 /* data processing */
3394 /* The opcode is in bits 23, 21, 20 and 6. */
3395 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3399 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3401 /* rn is register number */
3402 VFP_DREG_N(rn
, insn
);
3405 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3406 ((rn
& 0x1e) == 0x6))) {
3407 /* Integer or single/half precision destination. */
3408 rd
= VFP_SREG_D(insn
);
3410 VFP_DREG_D(rd
, insn
);
3413 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3414 ((rn
& 0x1e) == 0x4))) {
3415 /* VCVT from int or half precision is always from S reg
3416 * regardless of dp bit. VCVT with immediate frac_bits
3417 * has same format as SREG_M.
3419 rm
= VFP_SREG_M(insn
);
3421 VFP_DREG_M(rm
, insn
);
3424 rn
= VFP_SREG_N(insn
);
3425 if (op
== 15 && rn
== 15) {
3426 /* Double precision destination. */
3427 VFP_DREG_D(rd
, insn
);
3429 rd
= VFP_SREG_D(insn
);
3431 /* NB that we implicitly rely on the encoding for the frac_bits
3432 * in VCVT of fixed to float being the same as that of an SREG_M
3434 rm
= VFP_SREG_M(insn
);
3437 veclen
= s
->vec_len
;
3438 if (op
== 15 && rn
> 3)
3441 /* Shut up compiler warnings. */
3452 /* Figure out what type of vector operation this is. */
3453 if ((rd
& bank_mask
) == 0) {
3458 delta_d
= (s
->vec_stride
>> 1) + 1;
3460 delta_d
= s
->vec_stride
+ 1;
3462 if ((rm
& bank_mask
) == 0) {
3463 /* mixed scalar/vector */
3472 /* Load the initial operands. */
3477 /* Integer source */
3478 gen_mov_F0_vreg(0, rm
);
3483 gen_mov_F0_vreg(dp
, rd
);
3484 gen_mov_F1_vreg(dp
, rm
);
3488 /* Compare with zero */
3489 gen_mov_F0_vreg(dp
, rd
);
3500 /* Source and destination the same. */
3501 gen_mov_F0_vreg(dp
, rd
);
3507 /* VCVTB, VCVTT: only present with the halfprec extension
3508 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3509 * (we choose to UNDEF)
3511 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3512 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3515 if (!extract32(rn
, 1, 1)) {
3516 /* Half precision source. */
3517 gen_mov_F0_vreg(0, rm
);
3520 /* Otherwise fall through */
3522 /* One source operand. */
3523 gen_mov_F0_vreg(dp
, rm
);
3527 /* Two source operands. */
3528 gen_mov_F0_vreg(dp
, rn
);
3529 gen_mov_F1_vreg(dp
, rm
);
3533 /* Perform the calculation. */
3535 case 0: /* VMLA: fd + (fn * fm) */
3536 /* Note that order of inputs to the add matters for NaNs */
3538 gen_mov_F0_vreg(dp
, rd
);
3541 case 1: /* VMLS: fd + -(fn * fm) */
3544 gen_mov_F0_vreg(dp
, rd
);
3547 case 2: /* VNMLS: -fd + (fn * fm) */
3548 /* Note that it isn't valid to replace (-A + B) with (B - A)
3549 * or similar plausible looking simplifications
3550 * because this will give wrong results for NaNs.
3553 gen_mov_F0_vreg(dp
, rd
);
3557 case 3: /* VNMLA: -fd + -(fn * fm) */
3560 gen_mov_F0_vreg(dp
, rd
);
3564 case 4: /* mul: fn * fm */
3567 case 5: /* nmul: -(fn * fm) */
3571 case 6: /* add: fn + fm */
3574 case 7: /* sub: fn - fm */
3577 case 8: /* div: fn / fm */
3580 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3581 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3582 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3583 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3584 /* These are fused multiply-add, and must be done as one
3585 * floating point operation with no rounding between the
3586 * multiplication and addition steps.
3587 * NB that doing the negations here as separate steps is
3588 * correct : an input NaN should come out with its sign bit
3589 * flipped if it is a negated-input.
3591 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3599 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3601 frd
= tcg_temp_new_i64();
3602 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3605 gen_helper_vfp_negd(frd
, frd
);
3607 fpst
= get_fpstatus_ptr(0);
3608 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3609 cpu_F1d
, frd
, fpst
);
3610 tcg_temp_free_ptr(fpst
);
3611 tcg_temp_free_i64(frd
);
3617 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3619 frd
= tcg_temp_new_i32();
3620 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3622 gen_helper_vfp_negs(frd
, frd
);
3624 fpst
= get_fpstatus_ptr(0);
3625 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3626 cpu_F1s
, frd
, fpst
);
3627 tcg_temp_free_ptr(fpst
);
3628 tcg_temp_free_i32(frd
);
3631 case 14: /* fconst */
3632 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3636 n
= (insn
<< 12) & 0x80000000;
3637 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3644 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3651 tcg_gen_movi_i32(cpu_F0s
, n
);
3654 case 15: /* extension space */
3668 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3669 tmp
= gen_vfp_mrs();
3670 tcg_gen_ext16u_i32(tmp
, tmp
);
3672 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3675 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3678 tcg_temp_free_i32(tmp
);
3680 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3681 tmp
= gen_vfp_mrs();
3682 tcg_gen_shri_i32(tmp
, tmp
, 16);
3684 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3687 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3690 tcg_temp_free_i32(tmp
);
3692 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3693 tmp
= tcg_temp_new_i32();
3695 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3698 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3701 gen_mov_F0_vreg(0, rd
);
3702 tmp2
= gen_vfp_mrs();
3703 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3704 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3705 tcg_temp_free_i32(tmp2
);
3708 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3709 tmp
= tcg_temp_new_i32();
3711 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3714 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3717 tcg_gen_shli_i32(tmp
, tmp
, 16);
3718 gen_mov_F0_vreg(0, rd
);
3719 tmp2
= gen_vfp_mrs();
3720 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3721 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3722 tcg_temp_free_i32(tmp2
);
3734 case 11: /* cmpez */
3738 case 12: /* vrintr */
3740 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3742 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3744 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3746 tcg_temp_free_ptr(fpst
);
3749 case 13: /* vrintz */
3751 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3753 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3754 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3756 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3758 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3760 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3761 tcg_temp_free_i32(tcg_rmode
);
3762 tcg_temp_free_ptr(fpst
);
3765 case 14: /* vrintx */
3767 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3769 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3771 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3773 tcg_temp_free_ptr(fpst
);
3776 case 15: /* single<->double conversion */
3778 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3780 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3782 case 16: /* fuito */
3783 gen_vfp_uito(dp
, 0);
3785 case 17: /* fsito */
3786 gen_vfp_sito(dp
, 0);
3788 case 20: /* fshto */
3789 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3792 gen_vfp_shto(dp
, 16 - rm
, 0);
3794 case 21: /* fslto */
3795 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3798 gen_vfp_slto(dp
, 32 - rm
, 0);
3800 case 22: /* fuhto */
3801 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3804 gen_vfp_uhto(dp
, 16 - rm
, 0);
3806 case 23: /* fulto */
3807 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3810 gen_vfp_ulto(dp
, 32 - rm
, 0);
3812 case 24: /* ftoui */
3813 gen_vfp_toui(dp
, 0);
3815 case 25: /* ftouiz */
3816 gen_vfp_touiz(dp
, 0);
3818 case 26: /* ftosi */
3819 gen_vfp_tosi(dp
, 0);
3821 case 27: /* ftosiz */
3822 gen_vfp_tosiz(dp
, 0);
3824 case 28: /* ftosh */
3825 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3828 gen_vfp_tosh(dp
, 16 - rm
, 0);
3830 case 29: /* ftosl */
3831 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3834 gen_vfp_tosl(dp
, 32 - rm
, 0);
3836 case 30: /* ftouh */
3837 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3840 gen_vfp_touh(dp
, 16 - rm
, 0);
3842 case 31: /* ftoul */
3843 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3846 gen_vfp_toul(dp
, 32 - rm
, 0);
3848 default: /* undefined */
3852 default: /* undefined */
3856 /* Write back the result. */
3857 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3858 /* Comparison, do nothing. */
3859 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3860 (rn
& 0x1e) == 0x6)) {
3861 /* VCVT double to int: always integer result.
3862 * VCVT double to half precision is always a single
3865 gen_mov_vreg_F0(0, rd
);
3866 } else if (op
== 15 && rn
== 15) {
3868 gen_mov_vreg_F0(!dp
, rd
);
3870 gen_mov_vreg_F0(dp
, rd
);
3873 /* break out of the loop if we have finished */
3877 if (op
== 15 && delta_m
== 0) {
3878 /* single source one-many */
3880 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3882 gen_mov_vreg_F0(dp
, rd
);
3886 /* Setup the next operands. */
3888 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3892 /* One source operand. */
3893 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3895 gen_mov_F0_vreg(dp
, rm
);
3897 /* Two source operands. */
3898 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3900 gen_mov_F0_vreg(dp
, rn
);
3902 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3904 gen_mov_F1_vreg(dp
, rm
);
3912 if ((insn
& 0x03e00000) == 0x00400000) {
3913 /* two-register transfer */
3914 rn
= (insn
>> 16) & 0xf;
3915 rd
= (insn
>> 12) & 0xf;
3917 VFP_DREG_M(rm
, insn
);
3919 rm
= VFP_SREG_M(insn
);
3922 if (insn
& ARM_CP_RW_BIT
) {
3925 gen_mov_F0_vreg(0, rm
* 2);
3926 tmp
= gen_vfp_mrs();
3927 store_reg(s
, rd
, tmp
);
3928 gen_mov_F0_vreg(0, rm
* 2 + 1);
3929 tmp
= gen_vfp_mrs();
3930 store_reg(s
, rn
, tmp
);
3932 gen_mov_F0_vreg(0, rm
);
3933 tmp
= gen_vfp_mrs();
3934 store_reg(s
, rd
, tmp
);
3935 gen_mov_F0_vreg(0, rm
+ 1);
3936 tmp
= gen_vfp_mrs();
3937 store_reg(s
, rn
, tmp
);
3942 tmp
= load_reg(s
, rd
);
3944 gen_mov_vreg_F0(0, rm
* 2);
3945 tmp
= load_reg(s
, rn
);
3947 gen_mov_vreg_F0(0, rm
* 2 + 1);
3949 tmp
= load_reg(s
, rd
);
3951 gen_mov_vreg_F0(0, rm
);
3952 tmp
= load_reg(s
, rn
);
3954 gen_mov_vreg_F0(0, rm
+ 1);
3959 rn
= (insn
>> 16) & 0xf;
3961 VFP_DREG_D(rd
, insn
);
3963 rd
= VFP_SREG_D(insn
);
3964 if ((insn
& 0x01200000) == 0x01000000) {
3965 /* Single load/store */
3966 offset
= (insn
& 0xff) << 2;
3967 if ((insn
& (1 << 23)) == 0)
3969 if (s
->thumb
&& rn
== 15) {
3970 /* This is actually UNPREDICTABLE */
3971 addr
= tcg_temp_new_i32();
3972 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3974 addr
= load_reg(s
, rn
);
3976 tcg_gen_addi_i32(addr
, addr
, offset
);
3977 if (insn
& (1 << 20)) {
3978 gen_vfp_ld(s
, dp
, addr
);
3979 gen_mov_vreg_F0(dp
, rd
);
3981 gen_mov_F0_vreg(dp
, rd
);
3982 gen_vfp_st(s
, dp
, addr
);
3984 tcg_temp_free_i32(addr
);
3986 /* load/store multiple */
3987 int w
= insn
& (1 << 21);
3989 n
= (insn
>> 1) & 0x7f;
3993 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3994 /* P == U , W == 1 => UNDEF */
3997 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3998 /* UNPREDICTABLE cases for bad immediates: we choose to
3999 * UNDEF to avoid generating huge numbers of TCG ops
4003 if (rn
== 15 && w
) {
4004 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4008 if (s
->thumb
&& rn
== 15) {
4009 /* This is actually UNPREDICTABLE */
4010 addr
= tcg_temp_new_i32();
4011 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4013 addr
= load_reg(s
, rn
);
4015 if (insn
& (1 << 24)) /* pre-decrement */
4016 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4022 for (i
= 0; i
< n
; i
++) {
4023 if (insn
& ARM_CP_RW_BIT
) {
4025 gen_vfp_ld(s
, dp
, addr
);
4026 gen_mov_vreg_F0(dp
, rd
+ i
);
4029 gen_mov_F0_vreg(dp
, rd
+ i
);
4030 gen_vfp_st(s
, dp
, addr
);
4032 tcg_gen_addi_i32(addr
, addr
, offset
);
4036 if (insn
& (1 << 24))
4037 offset
= -offset
* n
;
4038 else if (dp
&& (insn
& 1))
4044 tcg_gen_addi_i32(addr
, addr
, offset
);
4045 store_reg(s
, rn
, addr
);
4047 tcg_temp_free_i32(addr
);
4053 /* Should never happen. */
4059 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4061 #ifndef CONFIG_USER_ONLY
4062 return (s
->tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4063 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4069 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4071 if (use_goto_tb(s
, dest
)) {
4073 gen_set_pc_im(s
, dest
);
4074 tcg_gen_exit_tb((uintptr_t)s
->tb
+ n
);
4076 gen_set_pc_im(s
, dest
);
4081 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4083 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
4084 /* An indirect jump so that we still trigger the debug exception. */
4089 gen_goto_tb(s
, 0, dest
);
4090 s
->is_jmp
= DISAS_TB_JUMP
;
4094 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4097 tcg_gen_sari_i32(t0
, t0
, 16);
4101 tcg_gen_sari_i32(t1
, t1
, 16);
4104 tcg_gen_mul_i32(t0
, t0
, t1
);
4107 /* Return the mask of PSR bits set by a MSR instruction. */
4108 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4113 if (flags
& (1 << 0))
4115 if (flags
& (1 << 1))
4117 if (flags
& (1 << 2))
4119 if (flags
& (1 << 3))
4122 /* Mask out undefined bits. */
4123 mask
&= ~CPSR_RESERVED
;
4124 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4127 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4128 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4130 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4131 mask
&= ~(CPSR_E
| CPSR_GE
);
4133 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4136 /* Mask out execution state and reserved bits. */
4138 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4140 /* Mask out privileged bits. */
4146 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4147 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4151 /* ??? This is also undefined in system mode. */
4155 tmp
= load_cpu_field(spsr
);
4156 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4157 tcg_gen_andi_i32(t0
, t0
, mask
);
4158 tcg_gen_or_i32(tmp
, tmp
, t0
);
4159 store_cpu_field(tmp
, spsr
);
4161 gen_set_cpsr(t0
, mask
);
4163 tcg_temp_free_i32(t0
);
4168 /* Returns nonzero if access to the PSR is not permitted. */
4169 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4172 tmp
= tcg_temp_new_i32();
4173 tcg_gen_movi_i32(tmp
, val
);
4174 return gen_set_psr(s
, mask
, spsr
, tmp
);
4177 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4178 int *tgtmode
, int *regno
)
4180 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4181 * the target mode and register number, and identify the various
4182 * unpredictable cases.
4183 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4184 * + executed in user mode
4185 * + using R15 as the src/dest register
4186 * + accessing an unimplemented register
4187 * + accessing a register that's inaccessible at current PL/security state*
4188 * + accessing a register that you could access with a different insn
4189 * We choose to UNDEF in all these cases.
4190 * Since we don't know which of the various AArch32 modes we are in
4191 * we have to defer some checks to runtime.
4192 * Accesses to Monitor mode registers from Secure EL1 (which implies
4193 * that EL3 is AArch64) must trap to EL3.
4195 * If the access checks fail this function will emit code to take
4196 * an exception and return false. Otherwise it will return true,
4197 * and set *tgtmode and *regno appropriately.
4199 int exc_target
= default_exception_el(s
);
4201 /* These instructions are present only in ARMv8, or in ARMv7 with the
4202 * Virtualization Extensions.
4204 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4205 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4209 if (IS_USER(s
) || rn
== 15) {
4213 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4214 * of registers into (r, sysm).
4217 /* SPSRs for other modes */
4219 case 0xe: /* SPSR_fiq */
4220 *tgtmode
= ARM_CPU_MODE_FIQ
;
4222 case 0x10: /* SPSR_irq */
4223 *tgtmode
= ARM_CPU_MODE_IRQ
;
4225 case 0x12: /* SPSR_svc */
4226 *tgtmode
= ARM_CPU_MODE_SVC
;
4228 case 0x14: /* SPSR_abt */
4229 *tgtmode
= ARM_CPU_MODE_ABT
;
4231 case 0x16: /* SPSR_und */
4232 *tgtmode
= ARM_CPU_MODE_UND
;
4234 case 0x1c: /* SPSR_mon */
4235 *tgtmode
= ARM_CPU_MODE_MON
;
4237 case 0x1e: /* SPSR_hyp */
4238 *tgtmode
= ARM_CPU_MODE_HYP
;
4240 default: /* unallocated */
4243 /* We arbitrarily assign SPSR a register number of 16. */
4246 /* general purpose registers for other modes */
4248 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4249 *tgtmode
= ARM_CPU_MODE_USR
;
4252 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4253 *tgtmode
= ARM_CPU_MODE_FIQ
;
4256 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4257 *tgtmode
= ARM_CPU_MODE_IRQ
;
4258 *regno
= sysm
& 1 ? 13 : 14;
4260 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4261 *tgtmode
= ARM_CPU_MODE_SVC
;
4262 *regno
= sysm
& 1 ? 13 : 14;
4264 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4265 *tgtmode
= ARM_CPU_MODE_ABT
;
4266 *regno
= sysm
& 1 ? 13 : 14;
4268 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4269 *tgtmode
= ARM_CPU_MODE_UND
;
4270 *regno
= sysm
& 1 ? 13 : 14;
4272 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4273 *tgtmode
= ARM_CPU_MODE_MON
;
4274 *regno
= sysm
& 1 ? 13 : 14;
4276 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4277 *tgtmode
= ARM_CPU_MODE_HYP
;
4278 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4279 *regno
= sysm
& 1 ? 13 : 17;
4281 default: /* unallocated */
4286 /* Catch the 'accessing inaccessible register' cases we can detect
4287 * at translate time.
4290 case ARM_CPU_MODE_MON
:
4291 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4294 if (s
->current_el
== 1) {
4295 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4296 * then accesses to Mon registers trap to EL3
4302 case ARM_CPU_MODE_HYP
:
4303 /* Note that we can forbid accesses from EL2 here because they
4304 * must be from Hyp mode itself
4306 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4317 /* If we get here then some access check did not pass */
4318 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4322 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4324 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4325 int tgtmode
= 0, regno
= 0;
4327 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4331 /* Sync state because msr_banked() can raise exceptions */
4332 gen_set_condexec(s
);
4333 gen_set_pc_im(s
, s
->pc
- 4);
4334 tcg_reg
= load_reg(s
, rn
);
4335 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4336 tcg_regno
= tcg_const_i32(regno
);
4337 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4338 tcg_temp_free_i32(tcg_tgtmode
);
4339 tcg_temp_free_i32(tcg_regno
);
4340 tcg_temp_free_i32(tcg_reg
);
4341 s
->is_jmp
= DISAS_UPDATE
;
4344 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4346 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4347 int tgtmode
= 0, regno
= 0;
4349 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4353 /* Sync state because mrs_banked() can raise exceptions */
4354 gen_set_condexec(s
);
4355 gen_set_pc_im(s
, s
->pc
- 4);
4356 tcg_reg
= tcg_temp_new_i32();
4357 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4358 tcg_regno
= tcg_const_i32(regno
);
4359 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4360 tcg_temp_free_i32(tcg_tgtmode
);
4361 tcg_temp_free_i32(tcg_regno
);
4362 store_reg(s
, rn
, tcg_reg
);
4363 s
->is_jmp
= DISAS_UPDATE
;
4366 /* Store value to PC as for an exception return (ie don't
4367 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4368 * will do the masking based on the new value of the Thumb bit.
4370 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4372 tcg_gen_mov_i32(cpu_R
[15], pc
);
4373 tcg_temp_free_i32(pc
);
4376 /* Generate a v6 exception return. Marks both values as dead. */
4377 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4379 store_pc_exc_ret(s
, pc
);
4380 /* The cpsr_write_eret helper will mask the low bits of PC
4381 * appropriately depending on the new Thumb bit, so it must
4382 * be called after storing the new PC.
4384 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4385 tcg_temp_free_i32(cpsr
);
4386 s
->is_jmp
= DISAS_JUMP
;
4389 /* Generate an old-style exception return. Marks pc as dead. */
4390 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4392 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4395 static void gen_nop_hint(DisasContext
*s
, int val
)
4399 gen_set_pc_im(s
, s
->pc
);
4400 s
->is_jmp
= DISAS_YIELD
;
4403 gen_set_pc_im(s
, s
->pc
);
4404 s
->is_jmp
= DISAS_WFI
;
4407 gen_set_pc_im(s
, s
->pc
);
4408 s
->is_jmp
= DISAS_WFE
;
4412 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4418 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4420 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4423 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4424 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4425 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4430 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4433 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4434 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4435 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4440 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4441 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4442 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4443 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4444 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4446 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4447 switch ((size << 1) | u) { \
4449 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4452 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4455 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4458 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4461 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4464 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4466 default: return 1; \
4469 #define GEN_NEON_INTEGER_OP(name) do { \
4470 switch ((size << 1) | u) { \
4472 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4475 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4478 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4481 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4484 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4487 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4489 default: return 1; \
4492 static TCGv_i32
neon_load_scratch(int scratch
)
4494 TCGv_i32 tmp
= tcg_temp_new_i32();
4495 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4499 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4501 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4502 tcg_temp_free_i32(var
);
4505 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4509 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4511 gen_neon_dup_high16(tmp
);
4513 gen_neon_dup_low16(tmp
);
4516 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4521 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4524 if (!q
&& size
== 2) {
4527 tmp
= tcg_const_i32(rd
);
4528 tmp2
= tcg_const_i32(rm
);
4532 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4535 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4538 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4546 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4549 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4555 tcg_temp_free_i32(tmp
);
4556 tcg_temp_free_i32(tmp2
);
4560 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4563 if (!q
&& size
== 2) {
4566 tmp
= tcg_const_i32(rd
);
4567 tmp2
= tcg_const_i32(rm
);
4571 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4574 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4577 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4585 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4588 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4594 tcg_temp_free_i32(tmp
);
4595 tcg_temp_free_i32(tmp2
);
4599 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4603 rd
= tcg_temp_new_i32();
4604 tmp
= tcg_temp_new_i32();
4606 tcg_gen_shli_i32(rd
, t0
, 8);
4607 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4608 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4609 tcg_gen_or_i32(rd
, rd
, tmp
);
4611 tcg_gen_shri_i32(t1
, t1
, 8);
4612 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4613 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4614 tcg_gen_or_i32(t1
, t1
, tmp
);
4615 tcg_gen_mov_i32(t0
, rd
);
4617 tcg_temp_free_i32(tmp
);
4618 tcg_temp_free_i32(rd
);
4621 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4625 rd
= tcg_temp_new_i32();
4626 tmp
= tcg_temp_new_i32();
4628 tcg_gen_shli_i32(rd
, t0
, 16);
4629 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4630 tcg_gen_or_i32(rd
, rd
, tmp
);
4631 tcg_gen_shri_i32(t1
, t1
, 16);
4632 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4633 tcg_gen_or_i32(t1
, t1
, tmp
);
4634 tcg_gen_mov_i32(t0
, rd
);
4636 tcg_temp_free_i32(tmp
);
4637 tcg_temp_free_i32(rd
);
4645 } neon_ls_element_type
[11] = {
4659 /* Translate a NEON load/store element instruction. Return nonzero if the
4660 instruction is invalid. */
4661 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4680 /* FIXME: this access check should not take precedence over UNDEF
4681 * for invalid encodings; we will generate incorrect syndrome information
4682 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4684 if (s
->fp_excp_el
) {
4685 gen_exception_insn(s
, 4, EXCP_UDEF
,
4686 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4690 if (!s
->vfp_enabled
)
4692 VFP_DREG_D(rd
, insn
);
4693 rn
= (insn
>> 16) & 0xf;
4695 load
= (insn
& (1 << 21)) != 0;
4696 if ((insn
& (1 << 23)) == 0) {
4697 /* Load store all elements. */
4698 op
= (insn
>> 8) & 0xf;
4699 size
= (insn
>> 6) & 3;
4702 /* Catch UNDEF cases for bad values of align field */
4705 if (((insn
>> 5) & 1) == 1) {
4710 if (((insn
>> 4) & 3) == 3) {
4717 nregs
= neon_ls_element_type
[op
].nregs
;
4718 interleave
= neon_ls_element_type
[op
].interleave
;
4719 spacing
= neon_ls_element_type
[op
].spacing
;
4720 if (size
== 3 && (interleave
| spacing
) != 1)
4722 addr
= tcg_temp_new_i32();
4723 load_reg_var(s
, addr
, rn
);
4724 stride
= (1 << size
) * interleave
;
4725 for (reg
= 0; reg
< nregs
; reg
++) {
4726 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4727 load_reg_var(s
, addr
, rn
);
4728 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4729 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4730 load_reg_var(s
, addr
, rn
);
4731 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4734 tmp64
= tcg_temp_new_i64();
4736 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4737 neon_store_reg64(tmp64
, rd
);
4739 neon_load_reg64(tmp64
, rd
);
4740 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4742 tcg_temp_free_i64(tmp64
);
4743 tcg_gen_addi_i32(addr
, addr
, stride
);
4745 for (pass
= 0; pass
< 2; pass
++) {
4748 tmp
= tcg_temp_new_i32();
4749 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4750 neon_store_reg(rd
, pass
, tmp
);
4752 tmp
= neon_load_reg(rd
, pass
);
4753 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4754 tcg_temp_free_i32(tmp
);
4756 tcg_gen_addi_i32(addr
, addr
, stride
);
4757 } else if (size
== 1) {
4759 tmp
= tcg_temp_new_i32();
4760 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4761 tcg_gen_addi_i32(addr
, addr
, stride
);
4762 tmp2
= tcg_temp_new_i32();
4763 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4764 tcg_gen_addi_i32(addr
, addr
, stride
);
4765 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4766 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4767 tcg_temp_free_i32(tmp2
);
4768 neon_store_reg(rd
, pass
, tmp
);
4770 tmp
= neon_load_reg(rd
, pass
);
4771 tmp2
= tcg_temp_new_i32();
4772 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4773 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4774 tcg_temp_free_i32(tmp
);
4775 tcg_gen_addi_i32(addr
, addr
, stride
);
4776 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4777 tcg_temp_free_i32(tmp2
);
4778 tcg_gen_addi_i32(addr
, addr
, stride
);
4780 } else /* size == 0 */ {
4782 TCGV_UNUSED_I32(tmp2
);
4783 for (n
= 0; n
< 4; n
++) {
4784 tmp
= tcg_temp_new_i32();
4785 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4786 tcg_gen_addi_i32(addr
, addr
, stride
);
4790 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4791 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4792 tcg_temp_free_i32(tmp
);
4795 neon_store_reg(rd
, pass
, tmp2
);
4797 tmp2
= neon_load_reg(rd
, pass
);
4798 for (n
= 0; n
< 4; n
++) {
4799 tmp
= tcg_temp_new_i32();
4801 tcg_gen_mov_i32(tmp
, tmp2
);
4803 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4805 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4806 tcg_temp_free_i32(tmp
);
4807 tcg_gen_addi_i32(addr
, addr
, stride
);
4809 tcg_temp_free_i32(tmp2
);
4816 tcg_temp_free_i32(addr
);
4819 size
= (insn
>> 10) & 3;
4821 /* Load single element to all lanes. */
4822 int a
= (insn
>> 4) & 1;
4826 size
= (insn
>> 6) & 3;
4827 nregs
= ((insn
>> 8) & 3) + 1;
4830 if (nregs
!= 4 || a
== 0) {
4833 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4836 if (nregs
== 1 && a
== 1 && size
== 0) {
4839 if (nregs
== 3 && a
== 1) {
4842 addr
= tcg_temp_new_i32();
4843 load_reg_var(s
, addr
, rn
);
4845 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4846 tmp
= gen_load_and_replicate(s
, addr
, size
);
4847 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4848 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4849 if (insn
& (1 << 5)) {
4850 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4851 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4853 tcg_temp_free_i32(tmp
);
4855 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4856 stride
= (insn
& (1 << 5)) ? 2 : 1;
4857 for (reg
= 0; reg
< nregs
; reg
++) {
4858 tmp
= gen_load_and_replicate(s
, addr
, size
);
4859 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4860 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4861 tcg_temp_free_i32(tmp
);
4862 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4866 tcg_temp_free_i32(addr
);
4867 stride
= (1 << size
) * nregs
;
4869 /* Single element. */
4870 int idx
= (insn
>> 4) & 0xf;
4871 pass
= (insn
>> 7) & 1;
4874 shift
= ((insn
>> 5) & 3) * 8;
4878 shift
= ((insn
>> 6) & 1) * 16;
4879 stride
= (insn
& (1 << 5)) ? 2 : 1;
4883 stride
= (insn
& (1 << 6)) ? 2 : 1;
4888 nregs
= ((insn
>> 8) & 3) + 1;
4889 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4892 if (((idx
& (1 << size
)) != 0) ||
4893 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4898 if ((idx
& 1) != 0) {
4903 if (size
== 2 && (idx
& 2) != 0) {
4908 if ((size
== 2) && ((idx
& 3) == 3)) {
4915 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4916 /* Attempts to write off the end of the register file
4917 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4918 * the neon_load_reg() would write off the end of the array.
4922 addr
= tcg_temp_new_i32();
4923 load_reg_var(s
, addr
, rn
);
4924 for (reg
= 0; reg
< nregs
; reg
++) {
4926 tmp
= tcg_temp_new_i32();
4929 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4932 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4935 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4937 default: /* Avoid compiler warnings. */
4941 tmp2
= neon_load_reg(rd
, pass
);
4942 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4943 shift
, size
? 16 : 8);
4944 tcg_temp_free_i32(tmp2
);
4946 neon_store_reg(rd
, pass
, tmp
);
4947 } else { /* Store */
4948 tmp
= neon_load_reg(rd
, pass
);
4950 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4953 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4956 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4959 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4962 tcg_temp_free_i32(tmp
);
4965 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4967 tcg_temp_free_i32(addr
);
4968 stride
= nregs
* (1 << size
);
4974 base
= load_reg(s
, rn
);
4976 tcg_gen_addi_i32(base
, base
, stride
);
4979 index
= load_reg(s
, rm
);
4980 tcg_gen_add_i32(base
, base
, index
);
4981 tcg_temp_free_i32(index
);
4983 store_reg(s
, rn
, base
);
4988 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4989 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4991 tcg_gen_and_i32(t
, t
, c
);
4992 tcg_gen_andc_i32(f
, f
, c
);
4993 tcg_gen_or_i32(dest
, t
, f
);
4996 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4999 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
5000 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
5001 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
5006 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5009 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
5010 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
5011 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5016 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5019 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5020 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5021 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5026 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5029 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5030 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5031 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5036 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5042 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5043 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5048 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5049 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5056 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5057 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5062 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5063 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5070 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5074 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5075 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5076 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5081 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5082 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5083 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5087 tcg_temp_free_i32(src
);
5090 static inline void gen_neon_addl(int size
)
5093 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5094 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5095 case 2: tcg_gen_add_i64(CPU_V001
); break;
5100 static inline void gen_neon_subl(int size
)
5103 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5104 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5105 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5110 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5113 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5114 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5116 tcg_gen_neg_i64(var
, var
);
5122 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5125 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5126 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5131 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5136 switch ((size
<< 1) | u
) {
5137 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5138 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5139 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5140 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5142 tmp
= gen_muls_i64_i32(a
, b
);
5143 tcg_gen_mov_i64(dest
, tmp
);
5144 tcg_temp_free_i64(tmp
);
5147 tmp
= gen_mulu_i64_i32(a
, b
);
5148 tcg_gen_mov_i64(dest
, tmp
);
5149 tcg_temp_free_i64(tmp
);
5154 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5155 Don't forget to clean them now. */
5157 tcg_temp_free_i32(a
);
5158 tcg_temp_free_i32(b
);
5162 static void gen_neon_narrow_op(int op
, int u
, int size
,
5163 TCGv_i32 dest
, TCGv_i64 src
)
5167 gen_neon_unarrow_sats(size
, dest
, src
);
5169 gen_neon_narrow(size
, dest
, src
);
5173 gen_neon_narrow_satu(size
, dest
, src
);
5175 gen_neon_narrow_sats(size
, dest
, src
);
5180 /* Symbolic constants for op fields for Neon 3-register same-length.
5181 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5184 #define NEON_3R_VHADD 0
5185 #define NEON_3R_VQADD 1
5186 #define NEON_3R_VRHADD 2
5187 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5188 #define NEON_3R_VHSUB 4
5189 #define NEON_3R_VQSUB 5
5190 #define NEON_3R_VCGT 6
5191 #define NEON_3R_VCGE 7
5192 #define NEON_3R_VSHL 8
5193 #define NEON_3R_VQSHL 9
5194 #define NEON_3R_VRSHL 10
5195 #define NEON_3R_VQRSHL 11
5196 #define NEON_3R_VMAX 12
5197 #define NEON_3R_VMIN 13
5198 #define NEON_3R_VABD 14
5199 #define NEON_3R_VABA 15
5200 #define NEON_3R_VADD_VSUB 16
5201 #define NEON_3R_VTST_VCEQ 17
5202 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5203 #define NEON_3R_VMUL 19
5204 #define NEON_3R_VPMAX 20
5205 #define NEON_3R_VPMIN 21
5206 #define NEON_3R_VQDMULH_VQRDMULH 22
5207 #define NEON_3R_VPADD 23
5208 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5209 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5210 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5211 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5212 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5213 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5214 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5215 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5217 static const uint8_t neon_3r_sizes
[] = {
5218 [NEON_3R_VHADD
] = 0x7,
5219 [NEON_3R_VQADD
] = 0xf,
5220 [NEON_3R_VRHADD
] = 0x7,
5221 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5222 [NEON_3R_VHSUB
] = 0x7,
5223 [NEON_3R_VQSUB
] = 0xf,
5224 [NEON_3R_VCGT
] = 0x7,
5225 [NEON_3R_VCGE
] = 0x7,
5226 [NEON_3R_VSHL
] = 0xf,
5227 [NEON_3R_VQSHL
] = 0xf,
5228 [NEON_3R_VRSHL
] = 0xf,
5229 [NEON_3R_VQRSHL
] = 0xf,
5230 [NEON_3R_VMAX
] = 0x7,
5231 [NEON_3R_VMIN
] = 0x7,
5232 [NEON_3R_VABD
] = 0x7,
5233 [NEON_3R_VABA
] = 0x7,
5234 [NEON_3R_VADD_VSUB
] = 0xf,
5235 [NEON_3R_VTST_VCEQ
] = 0x7,
5236 [NEON_3R_VML
] = 0x7,
5237 [NEON_3R_VMUL
] = 0x7,
5238 [NEON_3R_VPMAX
] = 0x7,
5239 [NEON_3R_VPMIN
] = 0x7,
5240 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5241 [NEON_3R_VPADD
] = 0x7,
5242 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5243 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5244 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5245 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5246 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5247 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5248 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5249 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5252 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5253 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5256 #define NEON_2RM_VREV64 0
5257 #define NEON_2RM_VREV32 1
5258 #define NEON_2RM_VREV16 2
5259 #define NEON_2RM_VPADDL 4
5260 #define NEON_2RM_VPADDL_U 5
5261 #define NEON_2RM_AESE 6 /* Includes AESD */
5262 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5263 #define NEON_2RM_VCLS 8
5264 #define NEON_2RM_VCLZ 9
5265 #define NEON_2RM_VCNT 10
5266 #define NEON_2RM_VMVN 11
5267 #define NEON_2RM_VPADAL 12
5268 #define NEON_2RM_VPADAL_U 13
5269 #define NEON_2RM_VQABS 14
5270 #define NEON_2RM_VQNEG 15
5271 #define NEON_2RM_VCGT0 16
5272 #define NEON_2RM_VCGE0 17
5273 #define NEON_2RM_VCEQ0 18
5274 #define NEON_2RM_VCLE0 19
5275 #define NEON_2RM_VCLT0 20
5276 #define NEON_2RM_SHA1H 21
5277 #define NEON_2RM_VABS 22
5278 #define NEON_2RM_VNEG 23
5279 #define NEON_2RM_VCGT0_F 24
5280 #define NEON_2RM_VCGE0_F 25
5281 #define NEON_2RM_VCEQ0_F 26
5282 #define NEON_2RM_VCLE0_F 27
5283 #define NEON_2RM_VCLT0_F 28
5284 #define NEON_2RM_VABS_F 30
5285 #define NEON_2RM_VNEG_F 31
5286 #define NEON_2RM_VSWP 32
5287 #define NEON_2RM_VTRN 33
5288 #define NEON_2RM_VUZP 34
5289 #define NEON_2RM_VZIP 35
5290 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5291 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5292 #define NEON_2RM_VSHLL 38
5293 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5294 #define NEON_2RM_VRINTN 40
5295 #define NEON_2RM_VRINTX 41
5296 #define NEON_2RM_VRINTA 42
5297 #define NEON_2RM_VRINTZ 43
5298 #define NEON_2RM_VCVT_F16_F32 44
5299 #define NEON_2RM_VRINTM 45
5300 #define NEON_2RM_VCVT_F32_F16 46
5301 #define NEON_2RM_VRINTP 47
5302 #define NEON_2RM_VCVTAU 48
5303 #define NEON_2RM_VCVTAS 49
5304 #define NEON_2RM_VCVTNU 50
5305 #define NEON_2RM_VCVTNS 51
5306 #define NEON_2RM_VCVTPU 52
5307 #define NEON_2RM_VCVTPS 53
5308 #define NEON_2RM_VCVTMU 54
5309 #define NEON_2RM_VCVTMS 55
5310 #define NEON_2RM_VRECPE 56
5311 #define NEON_2RM_VRSQRTE 57
5312 #define NEON_2RM_VRECPE_F 58
5313 #define NEON_2RM_VRSQRTE_F 59
5314 #define NEON_2RM_VCVT_FS 60
5315 #define NEON_2RM_VCVT_FU 61
5316 #define NEON_2RM_VCVT_SF 62
5317 #define NEON_2RM_VCVT_UF 63
5319 static int neon_2rm_is_float_op(int op
)
5321 /* Return true if this neon 2reg-misc op is float-to-float */
5322 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5323 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5324 op
== NEON_2RM_VRINTM
||
5325 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5326 op
>= NEON_2RM_VRECPE_F
);
5329 static bool neon_2rm_is_v8_op(int op
)
5331 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5333 case NEON_2RM_VRINTN
:
5334 case NEON_2RM_VRINTA
:
5335 case NEON_2RM_VRINTM
:
5336 case NEON_2RM_VRINTP
:
5337 case NEON_2RM_VRINTZ
:
5338 case NEON_2RM_VRINTX
:
5339 case NEON_2RM_VCVTAU
:
5340 case NEON_2RM_VCVTAS
:
5341 case NEON_2RM_VCVTNU
:
5342 case NEON_2RM_VCVTNS
:
5343 case NEON_2RM_VCVTPU
:
5344 case NEON_2RM_VCVTPS
:
5345 case NEON_2RM_VCVTMU
:
5346 case NEON_2RM_VCVTMS
:
5353 /* Each entry in this array has bit n set if the insn allows
5354 * size value n (otherwise it will UNDEF). Since unallocated
5355 * op values will have no bits set they always UNDEF.
5357 static const uint8_t neon_2rm_sizes
[] = {
5358 [NEON_2RM_VREV64
] = 0x7,
5359 [NEON_2RM_VREV32
] = 0x3,
5360 [NEON_2RM_VREV16
] = 0x1,
5361 [NEON_2RM_VPADDL
] = 0x7,
5362 [NEON_2RM_VPADDL_U
] = 0x7,
5363 [NEON_2RM_AESE
] = 0x1,
5364 [NEON_2RM_AESMC
] = 0x1,
5365 [NEON_2RM_VCLS
] = 0x7,
5366 [NEON_2RM_VCLZ
] = 0x7,
5367 [NEON_2RM_VCNT
] = 0x1,
5368 [NEON_2RM_VMVN
] = 0x1,
5369 [NEON_2RM_VPADAL
] = 0x7,
5370 [NEON_2RM_VPADAL_U
] = 0x7,
5371 [NEON_2RM_VQABS
] = 0x7,
5372 [NEON_2RM_VQNEG
] = 0x7,
5373 [NEON_2RM_VCGT0
] = 0x7,
5374 [NEON_2RM_VCGE0
] = 0x7,
5375 [NEON_2RM_VCEQ0
] = 0x7,
5376 [NEON_2RM_VCLE0
] = 0x7,
5377 [NEON_2RM_VCLT0
] = 0x7,
5378 [NEON_2RM_SHA1H
] = 0x4,
5379 [NEON_2RM_VABS
] = 0x7,
5380 [NEON_2RM_VNEG
] = 0x7,
5381 [NEON_2RM_VCGT0_F
] = 0x4,
5382 [NEON_2RM_VCGE0_F
] = 0x4,
5383 [NEON_2RM_VCEQ0_F
] = 0x4,
5384 [NEON_2RM_VCLE0_F
] = 0x4,
5385 [NEON_2RM_VCLT0_F
] = 0x4,
5386 [NEON_2RM_VABS_F
] = 0x4,
5387 [NEON_2RM_VNEG_F
] = 0x4,
5388 [NEON_2RM_VSWP
] = 0x1,
5389 [NEON_2RM_VTRN
] = 0x7,
5390 [NEON_2RM_VUZP
] = 0x7,
5391 [NEON_2RM_VZIP
] = 0x7,
5392 [NEON_2RM_VMOVN
] = 0x7,
5393 [NEON_2RM_VQMOVN
] = 0x7,
5394 [NEON_2RM_VSHLL
] = 0x7,
5395 [NEON_2RM_SHA1SU1
] = 0x4,
5396 [NEON_2RM_VRINTN
] = 0x4,
5397 [NEON_2RM_VRINTX
] = 0x4,
5398 [NEON_2RM_VRINTA
] = 0x4,
5399 [NEON_2RM_VRINTZ
] = 0x4,
5400 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5401 [NEON_2RM_VRINTM
] = 0x4,
5402 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5403 [NEON_2RM_VRINTP
] = 0x4,
5404 [NEON_2RM_VCVTAU
] = 0x4,
5405 [NEON_2RM_VCVTAS
] = 0x4,
5406 [NEON_2RM_VCVTNU
] = 0x4,
5407 [NEON_2RM_VCVTNS
] = 0x4,
5408 [NEON_2RM_VCVTPU
] = 0x4,
5409 [NEON_2RM_VCVTPS
] = 0x4,
5410 [NEON_2RM_VCVTMU
] = 0x4,
5411 [NEON_2RM_VCVTMS
] = 0x4,
5412 [NEON_2RM_VRECPE
] = 0x4,
5413 [NEON_2RM_VRSQRTE
] = 0x4,
5414 [NEON_2RM_VRECPE_F
] = 0x4,
5415 [NEON_2RM_VRSQRTE_F
] = 0x4,
5416 [NEON_2RM_VCVT_FS
] = 0x4,
5417 [NEON_2RM_VCVT_FU
] = 0x4,
5418 [NEON_2RM_VCVT_SF
] = 0x4,
5419 [NEON_2RM_VCVT_UF
] = 0x4,
5422 /* Translate a NEON data processing instruction. Return nonzero if the
5423 instruction is invalid.
5424 We process data in a mixture of 32-bit and 64-bit chunks.
5425 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5427 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5439 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5442 /* FIXME: this access check should not take precedence over UNDEF
5443 * for invalid encodings; we will generate incorrect syndrome information
5444 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5446 if (s
->fp_excp_el
) {
5447 gen_exception_insn(s
, 4, EXCP_UDEF
,
5448 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5452 if (!s
->vfp_enabled
)
5454 q
= (insn
& (1 << 6)) != 0;
5455 u
= (insn
>> 24) & 1;
5456 VFP_DREG_D(rd
, insn
);
5457 VFP_DREG_N(rn
, insn
);
5458 VFP_DREG_M(rm
, insn
);
5459 size
= (insn
>> 20) & 3;
5460 if ((insn
& (1 << 23)) == 0) {
5461 /* Three register same length. */
5462 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5463 /* Catch invalid op and bad size combinations: UNDEF */
5464 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5467 /* All insns of this form UNDEF for either this condition or the
5468 * superset of cases "Q==1"; we catch the latter later.
5470 if (q
&& ((rd
| rn
| rm
) & 1)) {
5474 * The SHA-1/SHA-256 3-register instructions require special treatment
5475 * here, as their size field is overloaded as an op type selector, and
5476 * they all consume their input in a single pass.
5478 if (op
== NEON_3R_SHA
) {
5482 if (!u
) { /* SHA-1 */
5483 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5486 tmp
= tcg_const_i32(rd
);
5487 tmp2
= tcg_const_i32(rn
);
5488 tmp3
= tcg_const_i32(rm
);
5489 tmp4
= tcg_const_i32(size
);
5490 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5491 tcg_temp_free_i32(tmp4
);
5492 } else { /* SHA-256 */
5493 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5496 tmp
= tcg_const_i32(rd
);
5497 tmp2
= tcg_const_i32(rn
);
5498 tmp3
= tcg_const_i32(rm
);
5501 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5504 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5507 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5511 tcg_temp_free_i32(tmp
);
5512 tcg_temp_free_i32(tmp2
);
5513 tcg_temp_free_i32(tmp3
);
5516 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5517 /* 64-bit element instructions. */
5518 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5519 neon_load_reg64(cpu_V0
, rn
+ pass
);
5520 neon_load_reg64(cpu_V1
, rm
+ pass
);
5524 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5527 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5533 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5536 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5542 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5544 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5549 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5552 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5558 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5560 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5563 case NEON_3R_VQRSHL
:
5565 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5568 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5572 case NEON_3R_VADD_VSUB
:
5574 tcg_gen_sub_i64(CPU_V001
);
5576 tcg_gen_add_i64(CPU_V001
);
5582 neon_store_reg64(cpu_V0
, rd
+ pass
);
5591 case NEON_3R_VQRSHL
:
5594 /* Shift instruction operands are reversed. */
5609 case NEON_3R_FLOAT_ARITH
:
5610 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5612 case NEON_3R_FLOAT_MINMAX
:
5613 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5615 case NEON_3R_FLOAT_CMP
:
5617 /* no encoding for U=0 C=1x */
5621 case NEON_3R_FLOAT_ACMP
:
5626 case NEON_3R_FLOAT_MISC
:
5627 /* VMAXNM/VMINNM in ARMv8 */
5628 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5633 if (u
&& (size
!= 0)) {
5634 /* UNDEF on invalid size for polynomial subcase */
5639 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5647 if (pairwise
&& q
) {
5648 /* All the pairwise insns UNDEF if Q is set */
5652 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5657 tmp
= neon_load_reg(rn
, 0);
5658 tmp2
= neon_load_reg(rn
, 1);
5660 tmp
= neon_load_reg(rm
, 0);
5661 tmp2
= neon_load_reg(rm
, 1);
5665 tmp
= neon_load_reg(rn
, pass
);
5666 tmp2
= neon_load_reg(rm
, pass
);
5670 GEN_NEON_INTEGER_OP(hadd
);
5673 GEN_NEON_INTEGER_OP_ENV(qadd
);
5675 case NEON_3R_VRHADD
:
5676 GEN_NEON_INTEGER_OP(rhadd
);
5678 case NEON_3R_LOGIC
: /* Logic ops. */
5679 switch ((u
<< 2) | size
) {
5681 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5684 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5687 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5690 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5693 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5696 tmp3
= neon_load_reg(rd
, pass
);
5697 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5698 tcg_temp_free_i32(tmp3
);
5701 tmp3
= neon_load_reg(rd
, pass
);
5702 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5703 tcg_temp_free_i32(tmp3
);
5706 tmp3
= neon_load_reg(rd
, pass
);
5707 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5708 tcg_temp_free_i32(tmp3
);
5713 GEN_NEON_INTEGER_OP(hsub
);
5716 GEN_NEON_INTEGER_OP_ENV(qsub
);
5719 GEN_NEON_INTEGER_OP(cgt
);
5722 GEN_NEON_INTEGER_OP(cge
);
5725 GEN_NEON_INTEGER_OP(shl
);
5728 GEN_NEON_INTEGER_OP_ENV(qshl
);
5731 GEN_NEON_INTEGER_OP(rshl
);
5733 case NEON_3R_VQRSHL
:
5734 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5737 GEN_NEON_INTEGER_OP(max
);
5740 GEN_NEON_INTEGER_OP(min
);
5743 GEN_NEON_INTEGER_OP(abd
);
5746 GEN_NEON_INTEGER_OP(abd
);
5747 tcg_temp_free_i32(tmp2
);
5748 tmp2
= neon_load_reg(rd
, pass
);
5749 gen_neon_add(size
, tmp
, tmp2
);
5751 case NEON_3R_VADD_VSUB
:
5752 if (!u
) { /* VADD */
5753 gen_neon_add(size
, tmp
, tmp2
);
5756 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5757 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5758 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5763 case NEON_3R_VTST_VCEQ
:
5764 if (!u
) { /* VTST */
5766 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5767 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5768 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5773 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5774 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5775 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5780 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5782 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5783 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5784 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5787 tcg_temp_free_i32(tmp2
);
5788 tmp2
= neon_load_reg(rd
, pass
);
5790 gen_neon_rsb(size
, tmp
, tmp2
);
5792 gen_neon_add(size
, tmp
, tmp2
);
5796 if (u
) { /* polynomial */
5797 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5798 } else { /* Integer */
5800 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5801 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5802 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5808 GEN_NEON_INTEGER_OP(pmax
);
5811 GEN_NEON_INTEGER_OP(pmin
);
5813 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5814 if (!u
) { /* VQDMULH */
5817 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5820 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5824 } else { /* VQRDMULH */
5827 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5830 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5838 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5839 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5840 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5844 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5846 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5847 switch ((u
<< 2) | size
) {
5850 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5853 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5856 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5861 tcg_temp_free_ptr(fpstatus
);
5864 case NEON_3R_FLOAT_MULTIPLY
:
5866 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5867 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5869 tcg_temp_free_i32(tmp2
);
5870 tmp2
= neon_load_reg(rd
, pass
);
5872 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5874 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5877 tcg_temp_free_ptr(fpstatus
);
5880 case NEON_3R_FLOAT_CMP
:
5882 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5884 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5887 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5889 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5892 tcg_temp_free_ptr(fpstatus
);
5895 case NEON_3R_FLOAT_ACMP
:
5897 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5899 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5901 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5903 tcg_temp_free_ptr(fpstatus
);
5906 case NEON_3R_FLOAT_MINMAX
:
5908 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5910 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5912 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5914 tcg_temp_free_ptr(fpstatus
);
5917 case NEON_3R_FLOAT_MISC
:
5920 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5922 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5924 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5926 tcg_temp_free_ptr(fpstatus
);
5929 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5931 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5937 /* VFMA, VFMS: fused multiply-add */
5938 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5939 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5942 gen_helper_vfp_negs(tmp
, tmp
);
5944 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5945 tcg_temp_free_i32(tmp3
);
5946 tcg_temp_free_ptr(fpstatus
);
5952 tcg_temp_free_i32(tmp2
);
5954 /* Save the result. For elementwise operations we can put it
5955 straight into the destination register. For pairwise operations
5956 we have to be careful to avoid clobbering the source operands. */
5957 if (pairwise
&& rd
== rm
) {
5958 neon_store_scratch(pass
, tmp
);
5960 neon_store_reg(rd
, pass
, tmp
);
5964 if (pairwise
&& rd
== rm
) {
5965 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5966 tmp
= neon_load_scratch(pass
);
5967 neon_store_reg(rd
, pass
, tmp
);
5970 /* End of 3 register same size operations. */
5971 } else if (insn
& (1 << 4)) {
5972 if ((insn
& 0x00380080) != 0) {
5973 /* Two registers and shift. */
5974 op
= (insn
>> 8) & 0xf;
5975 if (insn
& (1 << 7)) {
5983 while ((insn
& (1 << (size
+ 19))) == 0)
5986 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5987 /* To avoid excessive duplication of ops we implement shift
5988 by immediate using the variable shift operations. */
5990 /* Shift by immediate:
5991 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5992 if (q
&& ((rd
| rm
) & 1)) {
5995 if (!u
&& (op
== 4 || op
== 6)) {
5998 /* Right shifts are encoded as N - shift, where N is the
5999 element size in bits. */
6001 shift
= shift
- (1 << (size
+ 3));
6009 imm
= (uint8_t) shift
;
6014 imm
= (uint16_t) shift
;
6025 for (pass
= 0; pass
< count
; pass
++) {
6027 neon_load_reg64(cpu_V0
, rm
+ pass
);
6028 tcg_gen_movi_i64(cpu_V1
, imm
);
6033 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6035 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6040 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6042 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6045 case 5: /* VSHL, VSLI */
6046 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6048 case 6: /* VQSHLU */
6049 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6054 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6057 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6062 if (op
== 1 || op
== 3) {
6064 neon_load_reg64(cpu_V1
, rd
+ pass
);
6065 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6066 } else if (op
== 4 || (op
== 5 && u
)) {
6068 neon_load_reg64(cpu_V1
, rd
+ pass
);
6070 if (shift
< -63 || shift
> 63) {
6074 mask
= 0xffffffffffffffffull
>> -shift
;
6076 mask
= 0xffffffffffffffffull
<< shift
;
6079 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6080 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6082 neon_store_reg64(cpu_V0
, rd
+ pass
);
6083 } else { /* size < 3 */
6084 /* Operands in T0 and T1. */
6085 tmp
= neon_load_reg(rm
, pass
);
6086 tmp2
= tcg_temp_new_i32();
6087 tcg_gen_movi_i32(tmp2
, imm
);
6091 GEN_NEON_INTEGER_OP(shl
);
6095 GEN_NEON_INTEGER_OP(rshl
);
6098 case 5: /* VSHL, VSLI */
6100 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6101 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6102 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6106 case 6: /* VQSHLU */
6109 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6113 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6117 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6125 GEN_NEON_INTEGER_OP_ENV(qshl
);
6128 tcg_temp_free_i32(tmp2
);
6130 if (op
== 1 || op
== 3) {
6132 tmp2
= neon_load_reg(rd
, pass
);
6133 gen_neon_add(size
, tmp
, tmp2
);
6134 tcg_temp_free_i32(tmp2
);
6135 } else if (op
== 4 || (op
== 5 && u
)) {
6140 mask
= 0xff >> -shift
;
6142 mask
= (uint8_t)(0xff << shift
);
6148 mask
= 0xffff >> -shift
;
6150 mask
= (uint16_t)(0xffff << shift
);
6154 if (shift
< -31 || shift
> 31) {
6158 mask
= 0xffffffffu
>> -shift
;
6160 mask
= 0xffffffffu
<< shift
;
6166 tmp2
= neon_load_reg(rd
, pass
);
6167 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6168 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6169 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6170 tcg_temp_free_i32(tmp2
);
6172 neon_store_reg(rd
, pass
, tmp
);
6175 } else if (op
< 10) {
6176 /* Shift by immediate and narrow:
6177 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6178 int input_unsigned
= (op
== 8) ? !u
: u
;
6182 shift
= shift
- (1 << (size
+ 3));
6185 tmp64
= tcg_const_i64(shift
);
6186 neon_load_reg64(cpu_V0
, rm
);
6187 neon_load_reg64(cpu_V1
, rm
+ 1);
6188 for (pass
= 0; pass
< 2; pass
++) {
6196 if (input_unsigned
) {
6197 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6199 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6202 if (input_unsigned
) {
6203 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6205 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6208 tmp
= tcg_temp_new_i32();
6209 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6210 neon_store_reg(rd
, pass
, tmp
);
6212 tcg_temp_free_i64(tmp64
);
6215 imm
= (uint16_t)shift
;
6219 imm
= (uint32_t)shift
;
6221 tmp2
= tcg_const_i32(imm
);
6222 tmp4
= neon_load_reg(rm
+ 1, 0);
6223 tmp5
= neon_load_reg(rm
+ 1, 1);
6224 for (pass
= 0; pass
< 2; pass
++) {
6226 tmp
= neon_load_reg(rm
, 0);
6230 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6233 tmp3
= neon_load_reg(rm
, 1);
6237 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6239 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6240 tcg_temp_free_i32(tmp
);
6241 tcg_temp_free_i32(tmp3
);
6242 tmp
= tcg_temp_new_i32();
6243 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6244 neon_store_reg(rd
, pass
, tmp
);
6246 tcg_temp_free_i32(tmp2
);
6248 } else if (op
== 10) {
6250 if (q
|| (rd
& 1)) {
6253 tmp
= neon_load_reg(rm
, 0);
6254 tmp2
= neon_load_reg(rm
, 1);
6255 for (pass
= 0; pass
< 2; pass
++) {
6259 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6262 /* The shift is less than the width of the source
6263 type, so we can just shift the whole register. */
6264 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6265 /* Widen the result of shift: we need to clear
6266 * the potential overflow bits resulting from
6267 * left bits of the narrow input appearing as
6268 * right bits of left the neighbour narrow
6270 if (size
< 2 || !u
) {
6273 imm
= (0xffu
>> (8 - shift
));
6275 } else if (size
== 1) {
6276 imm
= 0xffff >> (16 - shift
);
6279 imm
= 0xffffffff >> (32 - shift
);
6282 imm64
= imm
| (((uint64_t)imm
) << 32);
6286 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6289 neon_store_reg64(cpu_V0
, rd
+ pass
);
6291 } else if (op
>= 14) {
6292 /* VCVT fixed-point. */
6293 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6296 /* We have already masked out the must-be-1 top bit of imm6,
6297 * hence this 32-shift where the ARM ARM has 64-imm6.
6300 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6301 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6304 gen_vfp_ulto(0, shift
, 1);
6306 gen_vfp_slto(0, shift
, 1);
6309 gen_vfp_toul(0, shift
, 1);
6311 gen_vfp_tosl(0, shift
, 1);
6313 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6318 } else { /* (insn & 0x00380080) == 0 */
6320 if (q
&& (rd
& 1)) {
6324 op
= (insn
>> 8) & 0xf;
6325 /* One register and immediate. */
6326 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6327 invert
= (insn
& (1 << 5)) != 0;
6328 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6329 * We choose to not special-case this and will behave as if a
6330 * valid constant encoding of 0 had been given.
6349 imm
= (imm
<< 8) | (imm
<< 24);
6352 imm
= (imm
<< 8) | 0xff;
6355 imm
= (imm
<< 16) | 0xffff;
6358 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6366 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6367 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6373 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6374 if (op
& 1 && op
< 12) {
6375 tmp
= neon_load_reg(rd
, pass
);
6377 /* The immediate value has already been inverted, so
6379 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6381 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6385 tmp
= tcg_temp_new_i32();
6386 if (op
== 14 && invert
) {
6390 for (n
= 0; n
< 4; n
++) {
6391 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6392 val
|= 0xff << (n
* 8);
6394 tcg_gen_movi_i32(tmp
, val
);
6396 tcg_gen_movi_i32(tmp
, imm
);
6399 neon_store_reg(rd
, pass
, tmp
);
6402 } else { /* (insn & 0x00800010 == 0x00800000) */
6404 op
= (insn
>> 8) & 0xf;
6405 if ((insn
& (1 << 6)) == 0) {
6406 /* Three registers of different lengths. */
6410 /* undefreq: bit 0 : UNDEF if size == 0
6411 * bit 1 : UNDEF if size == 1
6412 * bit 2 : UNDEF if size == 2
6413 * bit 3 : UNDEF if U == 1
6414 * Note that [2:0] set implies 'always UNDEF'
6417 /* prewiden, src1_wide, src2_wide, undefreq */
6418 static const int neon_3reg_wide
[16][4] = {
6419 {1, 0, 0, 0}, /* VADDL */
6420 {1, 1, 0, 0}, /* VADDW */
6421 {1, 0, 0, 0}, /* VSUBL */
6422 {1, 1, 0, 0}, /* VSUBW */
6423 {0, 1, 1, 0}, /* VADDHN */
6424 {0, 0, 0, 0}, /* VABAL */
6425 {0, 1, 1, 0}, /* VSUBHN */
6426 {0, 0, 0, 0}, /* VABDL */
6427 {0, 0, 0, 0}, /* VMLAL */
6428 {0, 0, 0, 9}, /* VQDMLAL */
6429 {0, 0, 0, 0}, /* VMLSL */
6430 {0, 0, 0, 9}, /* VQDMLSL */
6431 {0, 0, 0, 0}, /* Integer VMULL */
6432 {0, 0, 0, 1}, /* VQDMULL */
6433 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6434 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6437 prewiden
= neon_3reg_wide
[op
][0];
6438 src1_wide
= neon_3reg_wide
[op
][1];
6439 src2_wide
= neon_3reg_wide
[op
][2];
6440 undefreq
= neon_3reg_wide
[op
][3];
6442 if ((undefreq
& (1 << size
)) ||
6443 ((undefreq
& 8) && u
)) {
6446 if ((src1_wide
&& (rn
& 1)) ||
6447 (src2_wide
&& (rm
& 1)) ||
6448 (!src2_wide
&& (rd
& 1))) {
6452 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6453 * outside the loop below as it only performs a single pass.
6455 if (op
== 14 && size
== 2) {
6456 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6458 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6461 tcg_rn
= tcg_temp_new_i64();
6462 tcg_rm
= tcg_temp_new_i64();
6463 tcg_rd
= tcg_temp_new_i64();
6464 neon_load_reg64(tcg_rn
, rn
);
6465 neon_load_reg64(tcg_rm
, rm
);
6466 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6467 neon_store_reg64(tcg_rd
, rd
);
6468 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6469 neon_store_reg64(tcg_rd
, rd
+ 1);
6470 tcg_temp_free_i64(tcg_rn
);
6471 tcg_temp_free_i64(tcg_rm
);
6472 tcg_temp_free_i64(tcg_rd
);
6476 /* Avoid overlapping operands. Wide source operands are
6477 always aligned so will never overlap with wide
6478 destinations in problematic ways. */
6479 if (rd
== rm
&& !src2_wide
) {
6480 tmp
= neon_load_reg(rm
, 1);
6481 neon_store_scratch(2, tmp
);
6482 } else if (rd
== rn
&& !src1_wide
) {
6483 tmp
= neon_load_reg(rn
, 1);
6484 neon_store_scratch(2, tmp
);
6486 TCGV_UNUSED_I32(tmp3
);
6487 for (pass
= 0; pass
< 2; pass
++) {
6489 neon_load_reg64(cpu_V0
, rn
+ pass
);
6490 TCGV_UNUSED_I32(tmp
);
6492 if (pass
== 1 && rd
== rn
) {
6493 tmp
= neon_load_scratch(2);
6495 tmp
= neon_load_reg(rn
, pass
);
6498 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6502 neon_load_reg64(cpu_V1
, rm
+ pass
);
6503 TCGV_UNUSED_I32(tmp2
);
6505 if (pass
== 1 && rd
== rm
) {
6506 tmp2
= neon_load_scratch(2);
6508 tmp2
= neon_load_reg(rm
, pass
);
6511 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6515 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6516 gen_neon_addl(size
);
6518 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6519 gen_neon_subl(size
);
6521 case 5: case 7: /* VABAL, VABDL */
6522 switch ((size
<< 1) | u
) {
6524 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6527 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6530 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6533 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6536 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6539 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6543 tcg_temp_free_i32(tmp2
);
6544 tcg_temp_free_i32(tmp
);
6546 case 8: case 9: case 10: case 11: case 12: case 13:
6547 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6548 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6550 case 14: /* Polynomial VMULL */
6551 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6552 tcg_temp_free_i32(tmp2
);
6553 tcg_temp_free_i32(tmp
);
6555 default: /* 15 is RESERVED: caught earlier */
6560 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6561 neon_store_reg64(cpu_V0
, rd
+ pass
);
6562 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6564 neon_load_reg64(cpu_V1
, rd
+ pass
);
6566 case 10: /* VMLSL */
6567 gen_neon_negl(cpu_V0
, size
);
6569 case 5: case 8: /* VABAL, VMLAL */
6570 gen_neon_addl(size
);
6572 case 9: case 11: /* VQDMLAL, VQDMLSL */
6573 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6575 gen_neon_negl(cpu_V0
, size
);
6577 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6582 neon_store_reg64(cpu_V0
, rd
+ pass
);
6583 } else if (op
== 4 || op
== 6) {
6584 /* Narrowing operation. */
6585 tmp
= tcg_temp_new_i32();
6589 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6592 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6595 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6596 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6603 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6606 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6609 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6610 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6611 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6619 neon_store_reg(rd
, 0, tmp3
);
6620 neon_store_reg(rd
, 1, tmp
);
6623 /* Write back the result. */
6624 neon_store_reg64(cpu_V0
, rd
+ pass
);
6628 /* Two registers and a scalar. NB that for ops of this form
6629 * the ARM ARM labels bit 24 as Q, but it is in our variable
6636 case 1: /* Float VMLA scalar */
6637 case 5: /* Floating point VMLS scalar */
6638 case 9: /* Floating point VMUL scalar */
6643 case 0: /* Integer VMLA scalar */
6644 case 4: /* Integer VMLS scalar */
6645 case 8: /* Integer VMUL scalar */
6646 case 12: /* VQDMULH scalar */
6647 case 13: /* VQRDMULH scalar */
6648 if (u
&& ((rd
| rn
) & 1)) {
6651 tmp
= neon_get_scalar(size
, rm
);
6652 neon_store_scratch(0, tmp
);
6653 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6654 tmp
= neon_load_scratch(0);
6655 tmp2
= neon_load_reg(rn
, pass
);
6658 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6660 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6662 } else if (op
== 13) {
6664 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6666 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6668 } else if (op
& 1) {
6669 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6670 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6671 tcg_temp_free_ptr(fpstatus
);
6674 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6675 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6676 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6680 tcg_temp_free_i32(tmp2
);
6683 tmp2
= neon_load_reg(rd
, pass
);
6686 gen_neon_add(size
, tmp
, tmp2
);
6690 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6691 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6692 tcg_temp_free_ptr(fpstatus
);
6696 gen_neon_rsb(size
, tmp
, tmp2
);
6700 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6701 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6702 tcg_temp_free_ptr(fpstatus
);
6708 tcg_temp_free_i32(tmp2
);
6710 neon_store_reg(rd
, pass
, tmp
);
6713 case 3: /* VQDMLAL scalar */
6714 case 7: /* VQDMLSL scalar */
6715 case 11: /* VQDMULL scalar */
6720 case 2: /* VMLAL sclar */
6721 case 6: /* VMLSL scalar */
6722 case 10: /* VMULL scalar */
6726 tmp2
= neon_get_scalar(size
, rm
);
6727 /* We need a copy of tmp2 because gen_neon_mull
6728 * deletes it during pass 0. */
6729 tmp4
= tcg_temp_new_i32();
6730 tcg_gen_mov_i32(tmp4
, tmp2
);
6731 tmp3
= neon_load_reg(rn
, 1);
6733 for (pass
= 0; pass
< 2; pass
++) {
6735 tmp
= neon_load_reg(rn
, 0);
6740 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6742 neon_load_reg64(cpu_V1
, rd
+ pass
);
6746 gen_neon_negl(cpu_V0
, size
);
6749 gen_neon_addl(size
);
6752 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6754 gen_neon_negl(cpu_V0
, size
);
6756 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6762 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6767 neon_store_reg64(cpu_V0
, rd
+ pass
);
6772 default: /* 14 and 15 are RESERVED */
6776 } else { /* size == 3 */
6779 imm
= (insn
>> 8) & 0xf;
6784 if (q
&& ((rd
| rn
| rm
) & 1)) {
6789 neon_load_reg64(cpu_V0
, rn
);
6791 neon_load_reg64(cpu_V1
, rn
+ 1);
6793 } else if (imm
== 8) {
6794 neon_load_reg64(cpu_V0
, rn
+ 1);
6796 neon_load_reg64(cpu_V1
, rm
);
6799 tmp64
= tcg_temp_new_i64();
6801 neon_load_reg64(cpu_V0
, rn
);
6802 neon_load_reg64(tmp64
, rn
+ 1);
6804 neon_load_reg64(cpu_V0
, rn
+ 1);
6805 neon_load_reg64(tmp64
, rm
);
6807 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6808 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6809 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6811 neon_load_reg64(cpu_V1
, rm
);
6813 neon_load_reg64(cpu_V1
, rm
+ 1);
6816 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6817 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6818 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6819 tcg_temp_free_i64(tmp64
);
6822 neon_load_reg64(cpu_V0
, rn
);
6823 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6824 neon_load_reg64(cpu_V1
, rm
);
6825 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6826 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6828 neon_store_reg64(cpu_V0
, rd
);
6830 neon_store_reg64(cpu_V1
, rd
+ 1);
6832 } else if ((insn
& (1 << 11)) == 0) {
6833 /* Two register misc. */
6834 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6835 size
= (insn
>> 18) & 3;
6836 /* UNDEF for unknown op values and bad op-size combinations */
6837 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6840 if (neon_2rm_is_v8_op(op
) &&
6841 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6844 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6845 q
&& ((rm
| rd
) & 1)) {
6849 case NEON_2RM_VREV64
:
6850 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6851 tmp
= neon_load_reg(rm
, pass
* 2);
6852 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6854 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6855 case 1: gen_swap_half(tmp
); break;
6856 case 2: /* no-op */ break;
6859 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6861 neon_store_reg(rd
, pass
* 2, tmp2
);
6864 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6865 case 1: gen_swap_half(tmp2
); break;
6868 neon_store_reg(rd
, pass
* 2, tmp2
);
6872 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6873 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6874 for (pass
= 0; pass
< q
+ 1; pass
++) {
6875 tmp
= neon_load_reg(rm
, pass
* 2);
6876 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6877 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6878 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6880 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6881 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6882 case 2: tcg_gen_add_i64(CPU_V001
); break;
6885 if (op
>= NEON_2RM_VPADAL
) {
6887 neon_load_reg64(cpu_V1
, rd
+ pass
);
6888 gen_neon_addl(size
);
6890 neon_store_reg64(cpu_V0
, rd
+ pass
);
6896 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6897 tmp
= neon_load_reg(rm
, n
);
6898 tmp2
= neon_load_reg(rd
, n
+ 1);
6899 neon_store_reg(rm
, n
, tmp2
);
6900 neon_store_reg(rd
, n
+ 1, tmp
);
6907 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6912 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6916 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6917 /* also VQMOVUN; op field and mnemonics don't line up */
6921 TCGV_UNUSED_I32(tmp2
);
6922 for (pass
= 0; pass
< 2; pass
++) {
6923 neon_load_reg64(cpu_V0
, rm
+ pass
);
6924 tmp
= tcg_temp_new_i32();
6925 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6930 neon_store_reg(rd
, 0, tmp2
);
6931 neon_store_reg(rd
, 1, tmp
);
6935 case NEON_2RM_VSHLL
:
6936 if (q
|| (rd
& 1)) {
6939 tmp
= neon_load_reg(rm
, 0);
6940 tmp2
= neon_load_reg(rm
, 1);
6941 for (pass
= 0; pass
< 2; pass
++) {
6944 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6945 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6946 neon_store_reg64(cpu_V0
, rd
+ pass
);
6949 case NEON_2RM_VCVT_F16_F32
:
6950 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6954 tmp
= tcg_temp_new_i32();
6955 tmp2
= tcg_temp_new_i32();
6956 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6957 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6958 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6959 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6960 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6961 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6962 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6963 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6964 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6965 neon_store_reg(rd
, 0, tmp2
);
6966 tmp2
= tcg_temp_new_i32();
6967 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6968 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6969 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6970 neon_store_reg(rd
, 1, tmp2
);
6971 tcg_temp_free_i32(tmp
);
6973 case NEON_2RM_VCVT_F32_F16
:
6974 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6978 tmp3
= tcg_temp_new_i32();
6979 tmp
= neon_load_reg(rm
, 0);
6980 tmp2
= neon_load_reg(rm
, 1);
6981 tcg_gen_ext16u_i32(tmp3
, tmp
);
6982 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6983 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6984 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6985 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6986 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6987 tcg_temp_free_i32(tmp
);
6988 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6989 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6990 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6991 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6992 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6993 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6994 tcg_temp_free_i32(tmp2
);
6995 tcg_temp_free_i32(tmp3
);
6997 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6998 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6999 || ((rm
| rd
) & 1)) {
7002 tmp
= tcg_const_i32(rd
);
7003 tmp2
= tcg_const_i32(rm
);
7005 /* Bit 6 is the lowest opcode bit; it distinguishes between
7006 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7008 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
7010 if (op
== NEON_2RM_AESE
) {
7011 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
7013 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
7015 tcg_temp_free_i32(tmp
);
7016 tcg_temp_free_i32(tmp2
);
7017 tcg_temp_free_i32(tmp3
);
7019 case NEON_2RM_SHA1H
:
7020 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7021 || ((rm
| rd
) & 1)) {
7024 tmp
= tcg_const_i32(rd
);
7025 tmp2
= tcg_const_i32(rm
);
7027 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
7029 tcg_temp_free_i32(tmp
);
7030 tcg_temp_free_i32(tmp2
);
7032 case NEON_2RM_SHA1SU1
:
7033 if ((rm
| rd
) & 1) {
7036 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7038 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7041 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7044 tmp
= tcg_const_i32(rd
);
7045 tmp2
= tcg_const_i32(rm
);
7047 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
7049 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7051 tcg_temp_free_i32(tmp
);
7052 tcg_temp_free_i32(tmp2
);
7056 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7057 if (neon_2rm_is_float_op(op
)) {
7058 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7059 neon_reg_offset(rm
, pass
));
7060 TCGV_UNUSED_I32(tmp
);
7062 tmp
= neon_load_reg(rm
, pass
);
7065 case NEON_2RM_VREV32
:
7067 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7068 case 1: gen_swap_half(tmp
); break;
7072 case NEON_2RM_VREV16
:
7077 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7078 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7079 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7085 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7086 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7087 case 2: gen_helper_clz(tmp
, tmp
); break;
7092 gen_helper_neon_cnt_u8(tmp
, tmp
);
7095 tcg_gen_not_i32(tmp
, tmp
);
7097 case NEON_2RM_VQABS
:
7100 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7103 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7106 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7111 case NEON_2RM_VQNEG
:
7114 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7117 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7120 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7125 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7126 tmp2
= tcg_const_i32(0);
7128 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7129 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7130 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7133 tcg_temp_free_i32(tmp2
);
7134 if (op
== NEON_2RM_VCLE0
) {
7135 tcg_gen_not_i32(tmp
, tmp
);
7138 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7139 tmp2
= tcg_const_i32(0);
7141 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7142 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7143 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7146 tcg_temp_free_i32(tmp2
);
7147 if (op
== NEON_2RM_VCLT0
) {
7148 tcg_gen_not_i32(tmp
, tmp
);
7151 case NEON_2RM_VCEQ0
:
7152 tmp2
= tcg_const_i32(0);
7154 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7155 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7156 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7159 tcg_temp_free_i32(tmp2
);
7163 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7164 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7165 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7170 tmp2
= tcg_const_i32(0);
7171 gen_neon_rsb(size
, tmp
, tmp2
);
7172 tcg_temp_free_i32(tmp2
);
7174 case NEON_2RM_VCGT0_F
:
7176 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7177 tmp2
= tcg_const_i32(0);
7178 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7179 tcg_temp_free_i32(tmp2
);
7180 tcg_temp_free_ptr(fpstatus
);
7183 case NEON_2RM_VCGE0_F
:
7185 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7186 tmp2
= tcg_const_i32(0);
7187 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7188 tcg_temp_free_i32(tmp2
);
7189 tcg_temp_free_ptr(fpstatus
);
7192 case NEON_2RM_VCEQ0_F
:
7194 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7195 tmp2
= tcg_const_i32(0);
7196 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7197 tcg_temp_free_i32(tmp2
);
7198 tcg_temp_free_ptr(fpstatus
);
7201 case NEON_2RM_VCLE0_F
:
7203 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7204 tmp2
= tcg_const_i32(0);
7205 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7206 tcg_temp_free_i32(tmp2
);
7207 tcg_temp_free_ptr(fpstatus
);
7210 case NEON_2RM_VCLT0_F
:
7212 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7213 tmp2
= tcg_const_i32(0);
7214 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7215 tcg_temp_free_i32(tmp2
);
7216 tcg_temp_free_ptr(fpstatus
);
7219 case NEON_2RM_VABS_F
:
7222 case NEON_2RM_VNEG_F
:
7226 tmp2
= neon_load_reg(rd
, pass
);
7227 neon_store_reg(rm
, pass
, tmp2
);
7230 tmp2
= neon_load_reg(rd
, pass
);
7232 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7233 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7236 neon_store_reg(rm
, pass
, tmp2
);
7238 case NEON_2RM_VRINTN
:
7239 case NEON_2RM_VRINTA
:
7240 case NEON_2RM_VRINTM
:
7241 case NEON_2RM_VRINTP
:
7242 case NEON_2RM_VRINTZ
:
7245 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7248 if (op
== NEON_2RM_VRINTZ
) {
7249 rmode
= FPROUNDING_ZERO
;
7251 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7254 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7255 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7257 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7258 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7260 tcg_temp_free_ptr(fpstatus
);
7261 tcg_temp_free_i32(tcg_rmode
);
7264 case NEON_2RM_VRINTX
:
7266 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7267 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7268 tcg_temp_free_ptr(fpstatus
);
7271 case NEON_2RM_VCVTAU
:
7272 case NEON_2RM_VCVTAS
:
7273 case NEON_2RM_VCVTNU
:
7274 case NEON_2RM_VCVTNS
:
7275 case NEON_2RM_VCVTPU
:
7276 case NEON_2RM_VCVTPS
:
7277 case NEON_2RM_VCVTMU
:
7278 case NEON_2RM_VCVTMS
:
7280 bool is_signed
= !extract32(insn
, 7, 1);
7281 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7282 TCGv_i32 tcg_rmode
, tcg_shift
;
7283 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7285 tcg_shift
= tcg_const_i32(0);
7286 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7287 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7291 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7294 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7298 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7300 tcg_temp_free_i32(tcg_rmode
);
7301 tcg_temp_free_i32(tcg_shift
);
7302 tcg_temp_free_ptr(fpst
);
7305 case NEON_2RM_VRECPE
:
7307 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7308 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7309 tcg_temp_free_ptr(fpstatus
);
7312 case NEON_2RM_VRSQRTE
:
7314 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7315 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7316 tcg_temp_free_ptr(fpstatus
);
7319 case NEON_2RM_VRECPE_F
:
7321 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7322 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7323 tcg_temp_free_ptr(fpstatus
);
7326 case NEON_2RM_VRSQRTE_F
:
7328 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7329 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7330 tcg_temp_free_ptr(fpstatus
);
7333 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7336 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7339 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7340 gen_vfp_tosiz(0, 1);
7342 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7343 gen_vfp_touiz(0, 1);
7346 /* Reserved op values were caught by the
7347 * neon_2rm_sizes[] check earlier.
7351 if (neon_2rm_is_float_op(op
)) {
7352 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7353 neon_reg_offset(rd
, pass
));
7355 neon_store_reg(rd
, pass
, tmp
);
7360 } else if ((insn
& (1 << 10)) == 0) {
7362 int n
= ((insn
>> 8) & 3) + 1;
7363 if ((rn
+ n
) > 32) {
7364 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7365 * helper function running off the end of the register file.
7370 if (insn
& (1 << 6)) {
7371 tmp
= neon_load_reg(rd
, 0);
7373 tmp
= tcg_temp_new_i32();
7374 tcg_gen_movi_i32(tmp
, 0);
7376 tmp2
= neon_load_reg(rm
, 0);
7377 tmp4
= tcg_const_i32(rn
);
7378 tmp5
= tcg_const_i32(n
);
7379 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7380 tcg_temp_free_i32(tmp
);
7381 if (insn
& (1 << 6)) {
7382 tmp
= neon_load_reg(rd
, 1);
7384 tmp
= tcg_temp_new_i32();
7385 tcg_gen_movi_i32(tmp
, 0);
7387 tmp3
= neon_load_reg(rm
, 1);
7388 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7389 tcg_temp_free_i32(tmp5
);
7390 tcg_temp_free_i32(tmp4
);
7391 neon_store_reg(rd
, 0, tmp2
);
7392 neon_store_reg(rd
, 1, tmp3
);
7393 tcg_temp_free_i32(tmp
);
7394 } else if ((insn
& 0x380) == 0) {
7396 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7399 if (insn
& (1 << 19)) {
7400 tmp
= neon_load_reg(rm
, 1);
7402 tmp
= neon_load_reg(rm
, 0);
7404 if (insn
& (1 << 16)) {
7405 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7406 } else if (insn
& (1 << 17)) {
7407 if ((insn
>> 18) & 1)
7408 gen_neon_dup_high16(tmp
);
7410 gen_neon_dup_low16(tmp
);
7412 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7413 tmp2
= tcg_temp_new_i32();
7414 tcg_gen_mov_i32(tmp2
, tmp
);
7415 neon_store_reg(rd
, pass
, tmp2
);
7417 tcg_temp_free_i32(tmp
);
7426 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7428 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7429 const ARMCPRegInfo
*ri
;
7431 cpnum
= (insn
>> 8) & 0xf;
7433 /* First check for coprocessor space used for XScale/iwMMXt insns */
7434 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7435 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7438 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7439 return disas_iwmmxt_insn(s
, insn
);
7440 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7441 return disas_dsp_insn(s
, insn
);
7446 /* Otherwise treat as a generic register access */
7447 is64
= (insn
& (1 << 25)) == 0;
7448 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7456 opc1
= (insn
>> 4) & 0xf;
7458 rt2
= (insn
>> 16) & 0xf;
7460 crn
= (insn
>> 16) & 0xf;
7461 opc1
= (insn
>> 21) & 7;
7462 opc2
= (insn
>> 5) & 7;
7465 isread
= (insn
>> 20) & 1;
7466 rt
= (insn
>> 12) & 0xf;
7468 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7469 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7471 /* Check access permissions */
7472 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7477 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7478 /* Emit code to perform further access permissions checks at
7479 * runtime; this may result in an exception.
7480 * Note that on XScale all cp0..c13 registers do an access check
7481 * call in order to handle c15_cpar.
7484 TCGv_i32 tcg_syn
, tcg_isread
;
7487 /* Note that since we are an implementation which takes an
7488 * exception on a trapped conditional instruction only if the
7489 * instruction passes its condition code check, we can take
7490 * advantage of the clause in the ARM ARM that allows us to set
7491 * the COND field in the instruction to 0xE in all cases.
7492 * We could fish the actual condition out of the insn (ARM)
7493 * or the condexec bits (Thumb) but it isn't necessary.
7498 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7501 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7507 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7510 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7515 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7516 * so this can only happen if this is an ARMv7 or earlier CPU,
7517 * in which case the syndrome information won't actually be
7520 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7521 syndrome
= syn_uncategorized();
7525 gen_set_condexec(s
);
7526 gen_set_pc_im(s
, s
->pc
- 4);
7527 tmpptr
= tcg_const_ptr(ri
);
7528 tcg_syn
= tcg_const_i32(syndrome
);
7529 tcg_isread
= tcg_const_i32(isread
);
7530 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7532 tcg_temp_free_ptr(tmpptr
);
7533 tcg_temp_free_i32(tcg_syn
);
7534 tcg_temp_free_i32(tcg_isread
);
7537 /* Handle special cases first */
7538 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7545 gen_set_pc_im(s
, s
->pc
);
7546 s
->is_jmp
= DISAS_WFI
;
7552 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7561 if (ri
->type
& ARM_CP_CONST
) {
7562 tmp64
= tcg_const_i64(ri
->resetvalue
);
7563 } else if (ri
->readfn
) {
7565 tmp64
= tcg_temp_new_i64();
7566 tmpptr
= tcg_const_ptr(ri
);
7567 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7568 tcg_temp_free_ptr(tmpptr
);
7570 tmp64
= tcg_temp_new_i64();
7571 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7573 tmp
= tcg_temp_new_i32();
7574 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7575 store_reg(s
, rt
, tmp
);
7576 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7577 tmp
= tcg_temp_new_i32();
7578 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7579 tcg_temp_free_i64(tmp64
);
7580 store_reg(s
, rt2
, tmp
);
7583 if (ri
->type
& ARM_CP_CONST
) {
7584 tmp
= tcg_const_i32(ri
->resetvalue
);
7585 } else if (ri
->readfn
) {
7587 tmp
= tcg_temp_new_i32();
7588 tmpptr
= tcg_const_ptr(ri
);
7589 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7590 tcg_temp_free_ptr(tmpptr
);
7592 tmp
= load_cpu_offset(ri
->fieldoffset
);
7595 /* Destination register of r15 for 32 bit loads sets
7596 * the condition codes from the high 4 bits of the value
7599 tcg_temp_free_i32(tmp
);
7601 store_reg(s
, rt
, tmp
);
7606 if (ri
->type
& ARM_CP_CONST
) {
7607 /* If not forbidden by access permissions, treat as WI */
7612 TCGv_i32 tmplo
, tmphi
;
7613 TCGv_i64 tmp64
= tcg_temp_new_i64();
7614 tmplo
= load_reg(s
, rt
);
7615 tmphi
= load_reg(s
, rt2
);
7616 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7617 tcg_temp_free_i32(tmplo
);
7618 tcg_temp_free_i32(tmphi
);
7620 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7621 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7622 tcg_temp_free_ptr(tmpptr
);
7624 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7626 tcg_temp_free_i64(tmp64
);
7631 tmp
= load_reg(s
, rt
);
7632 tmpptr
= tcg_const_ptr(ri
);
7633 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7634 tcg_temp_free_ptr(tmpptr
);
7635 tcg_temp_free_i32(tmp
);
7637 TCGv_i32 tmp
= load_reg(s
, rt
);
7638 store_cpu_offset(tmp
, ri
->fieldoffset
);
7643 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7644 /* I/O operations must end the TB here (whether read or write) */
7647 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7648 /* We default to ending the TB on a coprocessor register write,
7649 * but allow this to be suppressed by the register definition
7650 * (usually only necessary to work around guest bugs).
7658 /* Unknown register; this might be a guest error or a QEMU
7659 * unimplemented feature.
7662 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7663 "64 bit system register cp:%d opc1: %d crm:%d "
7665 isread
? "read" : "write", cpnum
, opc1
, crm
,
7666 s
->ns
? "non-secure" : "secure");
7668 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7669 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7671 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7672 s
->ns
? "non-secure" : "secure");
7679 /* Store a 64-bit value to a register pair. Clobbers val. */
7680 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7683 tmp
= tcg_temp_new_i32();
7684 tcg_gen_extrl_i64_i32(tmp
, val
);
7685 store_reg(s
, rlow
, tmp
);
7686 tmp
= tcg_temp_new_i32();
7687 tcg_gen_shri_i64(val
, val
, 32);
7688 tcg_gen_extrl_i64_i32(tmp
, val
);
7689 store_reg(s
, rhigh
, tmp
);
7692 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7693 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7698 /* Load value and extend to 64 bits. */
7699 tmp
= tcg_temp_new_i64();
7700 tmp2
= load_reg(s
, rlow
);
7701 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7702 tcg_temp_free_i32(tmp2
);
7703 tcg_gen_add_i64(val
, val
, tmp
);
7704 tcg_temp_free_i64(tmp
);
7707 /* load and add a 64-bit value from a register pair. */
7708 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7714 /* Load 64-bit value rd:rn. */
7715 tmpl
= load_reg(s
, rlow
);
7716 tmph
= load_reg(s
, rhigh
);
7717 tmp
= tcg_temp_new_i64();
7718 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7719 tcg_temp_free_i32(tmpl
);
7720 tcg_temp_free_i32(tmph
);
7721 tcg_gen_add_i64(val
, val
, tmp
);
7722 tcg_temp_free_i64(tmp
);
7725 /* Set N and Z flags from hi|lo. */
7726 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7728 tcg_gen_mov_i32(cpu_NF
, hi
);
7729 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7732 /* Load/Store exclusive instructions are implemented by remembering
7733 the value/address loaded, and seeing if these are the same
7734 when the store is performed. This should be sufficient to implement
7735 the architecturally mandated semantics, and avoids having to monitor
7738 In system emulation mode only one CPU will be running at once, so
7739 this sequence is effectively atomic. In user emulation mode we
7740 throw an exception and handle the atomic operation elsewhere. */
7741 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7742 TCGv_i32 addr
, int size
)
7744 TCGv_i32 tmp
= tcg_temp_new_i32();
7750 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7753 gen_aa32_ld16ua(s
, tmp
, addr
, get_mem_index(s
));
7757 gen_aa32_ld32ua(s
, tmp
, addr
, get_mem_index(s
));
7764 TCGv_i32 tmp2
= tcg_temp_new_i32();
7765 TCGv_i32 tmp3
= tcg_temp_new_i32();
7767 tcg_gen_addi_i32(tmp2
, addr
, 4);
7768 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7769 tcg_temp_free_i32(tmp2
);
7770 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7771 store_reg(s
, rt2
, tmp3
);
7773 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7776 store_reg(s
, rt
, tmp
);
7777 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7780 static void gen_clrex(DisasContext
*s
)
7782 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7785 #ifdef CONFIG_USER_ONLY
7786 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7787 TCGv_i32 addr
, int size
)
7789 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7790 tcg_gen_movi_i32(cpu_exclusive_info
,
7791 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7792 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7795 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7796 TCGv_i32 addr
, int size
)
7799 TCGv_i64 val64
, extaddr
;
7800 TCGLabel
*done_label
;
7801 TCGLabel
*fail_label
;
7803 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7809 fail_label
= gen_new_label();
7810 done_label
= gen_new_label();
7811 extaddr
= tcg_temp_new_i64();
7812 tcg_gen_extu_i32_i64(extaddr
, addr
);
7813 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7814 tcg_temp_free_i64(extaddr
);
7816 tmp
= tcg_temp_new_i32();
7819 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7822 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
7826 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7832 val64
= tcg_temp_new_i64();
7834 TCGv_i32 tmp2
= tcg_temp_new_i32();
7835 TCGv_i32 tmp3
= tcg_temp_new_i32();
7836 tcg_gen_addi_i32(tmp2
, addr
, 4);
7837 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7838 tcg_temp_free_i32(tmp2
);
7839 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7840 tcg_temp_free_i32(tmp3
);
7842 tcg_gen_extu_i32_i64(val64
, tmp
);
7844 tcg_temp_free_i32(tmp
);
7846 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7847 tcg_temp_free_i64(val64
);
7849 tmp
= load_reg(s
, rt
);
7852 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
7855 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
7859 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7864 tcg_temp_free_i32(tmp
);
7866 tcg_gen_addi_i32(addr
, addr
, 4);
7867 tmp
= load_reg(s
, rt2
);
7868 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7869 tcg_temp_free_i32(tmp
);
7871 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7872 tcg_gen_br(done_label
);
7873 gen_set_label(fail_label
);
7874 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7875 gen_set_label(done_label
);
7876 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7883 * @mode: mode field from insn (which stack to store to)
7884 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7885 * @writeback: true if writeback bit set
7887 * Generate code for the SRS (Store Return State) insn.
7889 static void gen_srs(DisasContext
*s
,
7890 uint32_t mode
, uint32_t amode
, bool writeback
)
7897 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7898 * and specified mode is monitor mode
7899 * - UNDEFINED in Hyp mode
7900 * - UNPREDICTABLE in User or System mode
7901 * - UNPREDICTABLE if the specified mode is:
7902 * -- not implemented
7903 * -- not a valid mode number
7904 * -- a mode that's at a higher exception level
7905 * -- Monitor, if we are Non-secure
7906 * For the UNPREDICTABLE cases we choose to UNDEF.
7908 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7909 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7913 if (s
->current_el
== 0 || s
->current_el
== 2) {
7918 case ARM_CPU_MODE_USR
:
7919 case ARM_CPU_MODE_FIQ
:
7920 case ARM_CPU_MODE_IRQ
:
7921 case ARM_CPU_MODE_SVC
:
7922 case ARM_CPU_MODE_ABT
:
7923 case ARM_CPU_MODE_UND
:
7924 case ARM_CPU_MODE_SYS
:
7926 case ARM_CPU_MODE_HYP
:
7927 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7931 case ARM_CPU_MODE_MON
:
7932 /* No need to check specifically for "are we non-secure" because
7933 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7934 * so if this isn't EL3 then we must be non-secure.
7936 if (s
->current_el
!= 3) {
7945 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
7946 default_exception_el(s
));
7950 addr
= tcg_temp_new_i32();
7951 tmp
= tcg_const_i32(mode
);
7952 /* get_r13_banked() will raise an exception if called from System mode */
7953 gen_set_condexec(s
);
7954 gen_set_pc_im(s
, s
->pc
- 4);
7955 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7956 tcg_temp_free_i32(tmp
);
7973 tcg_gen_addi_i32(addr
, addr
, offset
);
7974 tmp
= load_reg(s
, 14);
7975 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7976 tcg_temp_free_i32(tmp
);
7977 tmp
= load_cpu_field(spsr
);
7978 tcg_gen_addi_i32(addr
, addr
, 4);
7979 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7980 tcg_temp_free_i32(tmp
);
7998 tcg_gen_addi_i32(addr
, addr
, offset
);
7999 tmp
= tcg_const_i32(mode
);
8000 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8001 tcg_temp_free_i32(tmp
);
8003 tcg_temp_free_i32(addr
);
8004 s
->is_jmp
= DISAS_UPDATE
;
8007 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
8009 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8016 /* M variants do not implement ARM mode. */
8017 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8022 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8023 * choose to UNDEF. In ARMv5 and above the space is used
8024 * for miscellaneous unconditional instructions.
8028 /* Unconditional instructions. */
8029 if (((insn
>> 25) & 7) == 1) {
8030 /* NEON Data processing. */
8031 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8035 if (disas_neon_data_insn(s
, insn
)) {
8040 if ((insn
& 0x0f100000) == 0x04000000) {
8041 /* NEON load/store. */
8042 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8046 if (disas_neon_ls_insn(s
, insn
)) {
8051 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8053 if (disas_vfp_insn(s
, insn
)) {
8058 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8059 ((insn
& 0x0f30f010) == 0x0710f000)) {
8060 if ((insn
& (1 << 22)) == 0) {
8062 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8066 /* Otherwise PLD; v5TE+ */
8070 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8071 ((insn
& 0x0f70f010) == 0x0650f000)) {
8073 return; /* PLI; V7 */
8075 if (((insn
& 0x0f700000) == 0x04100000) ||
8076 ((insn
& 0x0f700010) == 0x06100000)) {
8077 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8080 return; /* v7MP: Unallocated memory hint: must NOP */
8083 if ((insn
& 0x0ffffdff) == 0x01010000) {
8086 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8087 gen_helper_setend(cpu_env
);
8088 s
->is_jmp
= DISAS_UPDATE
;
8091 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8092 switch ((insn
>> 4) & 0xf) {
8100 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8103 /* We need to break the TB after this insn to execute
8104 * self-modifying code correctly and also to take
8105 * any pending interrupts immediately.
8112 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8115 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8117 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8123 rn
= (insn
>> 16) & 0xf;
8124 addr
= load_reg(s
, rn
);
8125 i
= (insn
>> 23) & 3;
8127 case 0: offset
= -4; break; /* DA */
8128 case 1: offset
= 0; break; /* IA */
8129 case 2: offset
= -8; break; /* DB */
8130 case 3: offset
= 4; break; /* IB */
8134 tcg_gen_addi_i32(addr
, addr
, offset
);
8135 /* Load PC into tmp and CPSR into tmp2. */
8136 tmp
= tcg_temp_new_i32();
8137 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8138 tcg_gen_addi_i32(addr
, addr
, 4);
8139 tmp2
= tcg_temp_new_i32();
8140 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8141 if (insn
& (1 << 21)) {
8142 /* Base writeback. */
8144 case 0: offset
= -8; break;
8145 case 1: offset
= 4; break;
8146 case 2: offset
= -4; break;
8147 case 3: offset
= 0; break;
8151 tcg_gen_addi_i32(addr
, addr
, offset
);
8152 store_reg(s
, rn
, addr
);
8154 tcg_temp_free_i32(addr
);
8156 gen_rfe(s
, tmp
, tmp2
);
8158 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8159 /* branch link and change to thumb (blx <offset>) */
8162 val
= (uint32_t)s
->pc
;
8163 tmp
= tcg_temp_new_i32();
8164 tcg_gen_movi_i32(tmp
, val
);
8165 store_reg(s
, 14, tmp
);
8166 /* Sign-extend the 24-bit offset */
8167 offset
= (((int32_t)insn
) << 8) >> 8;
8168 /* offset * 4 + bit24 * 2 + (thumb bit) */
8169 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8170 /* pipeline offset */
8172 /* protected by ARCH(5); above, near the start of uncond block */
8175 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8176 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8177 /* iWMMXt register transfer. */
8178 if (extract32(s
->c15_cpar
, 1, 1)) {
8179 if (!disas_iwmmxt_insn(s
, insn
)) {
8184 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8185 /* Coprocessor double register transfer. */
8187 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8188 /* Additional coprocessor register transfer. */
8189 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8192 /* cps (privileged) */
8196 if (insn
& (1 << 19)) {
8197 if (insn
& (1 << 8))
8199 if (insn
& (1 << 7))
8201 if (insn
& (1 << 6))
8203 if (insn
& (1 << 18))
8206 if (insn
& (1 << 17)) {
8208 val
|= (insn
& 0x1f);
8211 gen_set_psr_im(s
, mask
, 0, val
);
8218 /* if not always execute, we generate a conditional jump to
8220 s
->condlabel
= gen_new_label();
8221 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8224 if ((insn
& 0x0f900000) == 0x03000000) {
8225 if ((insn
& (1 << 21)) == 0) {
8227 rd
= (insn
>> 12) & 0xf;
8228 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8229 if ((insn
& (1 << 22)) == 0) {
8231 tmp
= tcg_temp_new_i32();
8232 tcg_gen_movi_i32(tmp
, val
);
8235 tmp
= load_reg(s
, rd
);
8236 tcg_gen_ext16u_i32(tmp
, tmp
);
8237 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8239 store_reg(s
, rd
, tmp
);
8241 if (((insn
>> 12) & 0xf) != 0xf)
8243 if (((insn
>> 16) & 0xf) == 0) {
8244 gen_nop_hint(s
, insn
& 0xff);
8246 /* CPSR = immediate */
8248 shift
= ((insn
>> 8) & 0xf) * 2;
8250 val
= (val
>> shift
) | (val
<< (32 - shift
));
8251 i
= ((insn
& (1 << 22)) != 0);
8252 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8258 } else if ((insn
& 0x0f900000) == 0x01000000
8259 && (insn
& 0x00000090) != 0x00000090) {
8260 /* miscellaneous instructions */
8261 op1
= (insn
>> 21) & 3;
8262 sh
= (insn
>> 4) & 0xf;
8265 case 0x0: /* MSR, MRS */
8266 if (insn
& (1 << 9)) {
8267 /* MSR (banked) and MRS (banked) */
8268 int sysm
= extract32(insn
, 16, 4) |
8269 (extract32(insn
, 8, 1) << 4);
8270 int r
= extract32(insn
, 22, 1);
8274 gen_msr_banked(s
, r
, sysm
, rm
);
8277 int rd
= extract32(insn
, 12, 4);
8279 gen_mrs_banked(s
, r
, sysm
, rd
);
8284 /* MSR, MRS (for PSRs) */
8287 tmp
= load_reg(s
, rm
);
8288 i
= ((op1
& 2) != 0);
8289 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8293 rd
= (insn
>> 12) & 0xf;
8297 tmp
= load_cpu_field(spsr
);
8299 tmp
= tcg_temp_new_i32();
8300 gen_helper_cpsr_read(tmp
, cpu_env
);
8302 store_reg(s
, rd
, tmp
);
8307 /* branch/exchange thumb (bx). */
8309 tmp
= load_reg(s
, rm
);
8311 } else if (op1
== 3) {
8314 rd
= (insn
>> 12) & 0xf;
8315 tmp
= load_reg(s
, rm
);
8316 gen_helper_clz(tmp
, tmp
);
8317 store_reg(s
, rd
, tmp
);
8325 /* Trivial implementation equivalent to bx. */
8326 tmp
= load_reg(s
, rm
);
8337 /* branch link/exchange thumb (blx) */
8338 tmp
= load_reg(s
, rm
);
8339 tmp2
= tcg_temp_new_i32();
8340 tcg_gen_movi_i32(tmp2
, s
->pc
);
8341 store_reg(s
, 14, tmp2
);
8347 uint32_t c
= extract32(insn
, 8, 4);
8349 /* Check this CPU supports ARMv8 CRC instructions.
8350 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8351 * Bits 8, 10 and 11 should be zero.
8353 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8358 rn
= extract32(insn
, 16, 4);
8359 rd
= extract32(insn
, 12, 4);
8361 tmp
= load_reg(s
, rn
);
8362 tmp2
= load_reg(s
, rm
);
8364 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8365 } else if (op1
== 1) {
8366 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8368 tmp3
= tcg_const_i32(1 << op1
);
8370 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8372 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8374 tcg_temp_free_i32(tmp2
);
8375 tcg_temp_free_i32(tmp3
);
8376 store_reg(s
, rd
, tmp
);
8379 case 0x5: /* saturating add/subtract */
8381 rd
= (insn
>> 12) & 0xf;
8382 rn
= (insn
>> 16) & 0xf;
8383 tmp
= load_reg(s
, rm
);
8384 tmp2
= load_reg(s
, rn
);
8386 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8388 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8390 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8391 tcg_temp_free_i32(tmp2
);
8392 store_reg(s
, rd
, tmp
);
8396 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8401 gen_exception_insn(s
, 4, EXCP_BKPT
,
8402 syn_aa32_bkpt(imm16
, false),
8403 default_exception_el(s
));
8406 /* Hypervisor call (v7) */
8414 /* Secure monitor call (v6+) */
8426 case 0x8: /* signed multiply */
8431 rs
= (insn
>> 8) & 0xf;
8432 rn
= (insn
>> 12) & 0xf;
8433 rd
= (insn
>> 16) & 0xf;
8435 /* (32 * 16) >> 16 */
8436 tmp
= load_reg(s
, rm
);
8437 tmp2
= load_reg(s
, rs
);
8439 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8442 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8443 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8444 tmp
= tcg_temp_new_i32();
8445 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8446 tcg_temp_free_i64(tmp64
);
8447 if ((sh
& 2) == 0) {
8448 tmp2
= load_reg(s
, rn
);
8449 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8450 tcg_temp_free_i32(tmp2
);
8452 store_reg(s
, rd
, tmp
);
8455 tmp
= load_reg(s
, rm
);
8456 tmp2
= load_reg(s
, rs
);
8457 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8458 tcg_temp_free_i32(tmp2
);
8460 tmp64
= tcg_temp_new_i64();
8461 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8462 tcg_temp_free_i32(tmp
);
8463 gen_addq(s
, tmp64
, rn
, rd
);
8464 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8465 tcg_temp_free_i64(tmp64
);
8468 tmp2
= load_reg(s
, rn
);
8469 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8470 tcg_temp_free_i32(tmp2
);
8472 store_reg(s
, rd
, tmp
);
8479 } else if (((insn
& 0x0e000000) == 0 &&
8480 (insn
& 0x00000090) != 0x90) ||
8481 ((insn
& 0x0e000000) == (1 << 25))) {
8482 int set_cc
, logic_cc
, shiftop
;
8484 op1
= (insn
>> 21) & 0xf;
8485 set_cc
= (insn
>> 20) & 1;
8486 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8488 /* data processing instruction */
8489 if (insn
& (1 << 25)) {
8490 /* immediate operand */
8492 shift
= ((insn
>> 8) & 0xf) * 2;
8494 val
= (val
>> shift
) | (val
<< (32 - shift
));
8496 tmp2
= tcg_temp_new_i32();
8497 tcg_gen_movi_i32(tmp2
, val
);
8498 if (logic_cc
&& shift
) {
8499 gen_set_CF_bit31(tmp2
);
8504 tmp2
= load_reg(s
, rm
);
8505 shiftop
= (insn
>> 5) & 3;
8506 if (!(insn
& (1 << 4))) {
8507 shift
= (insn
>> 7) & 0x1f;
8508 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8510 rs
= (insn
>> 8) & 0xf;
8511 tmp
= load_reg(s
, rs
);
8512 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8515 if (op1
!= 0x0f && op1
!= 0x0d) {
8516 rn
= (insn
>> 16) & 0xf;
8517 tmp
= load_reg(s
, rn
);
8519 TCGV_UNUSED_I32(tmp
);
8521 rd
= (insn
>> 12) & 0xf;
8524 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8528 store_reg_bx(s
, rd
, tmp
);
8531 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8535 store_reg_bx(s
, rd
, tmp
);
8538 if (set_cc
&& rd
== 15) {
8539 /* SUBS r15, ... is used for exception return. */
8543 gen_sub_CC(tmp
, tmp
, tmp2
);
8544 gen_exception_return(s
, tmp
);
8547 gen_sub_CC(tmp
, tmp
, tmp2
);
8549 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8551 store_reg_bx(s
, rd
, tmp
);
8556 gen_sub_CC(tmp
, tmp2
, tmp
);
8558 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8560 store_reg_bx(s
, rd
, tmp
);
8564 gen_add_CC(tmp
, tmp
, tmp2
);
8566 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8568 store_reg_bx(s
, rd
, tmp
);
8572 gen_adc_CC(tmp
, tmp
, tmp2
);
8574 gen_add_carry(tmp
, tmp
, tmp2
);
8576 store_reg_bx(s
, rd
, tmp
);
8580 gen_sbc_CC(tmp
, tmp
, tmp2
);
8582 gen_sub_carry(tmp
, tmp
, tmp2
);
8584 store_reg_bx(s
, rd
, tmp
);
8588 gen_sbc_CC(tmp
, tmp2
, tmp
);
8590 gen_sub_carry(tmp
, tmp2
, tmp
);
8592 store_reg_bx(s
, rd
, tmp
);
8596 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8599 tcg_temp_free_i32(tmp
);
8603 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8606 tcg_temp_free_i32(tmp
);
8610 gen_sub_CC(tmp
, tmp
, tmp2
);
8612 tcg_temp_free_i32(tmp
);
8616 gen_add_CC(tmp
, tmp
, tmp2
);
8618 tcg_temp_free_i32(tmp
);
8621 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8625 store_reg_bx(s
, rd
, tmp
);
8628 if (logic_cc
&& rd
== 15) {
8629 /* MOVS r15, ... is used for exception return. */
8633 gen_exception_return(s
, tmp2
);
8638 store_reg_bx(s
, rd
, tmp2
);
8642 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8646 store_reg_bx(s
, rd
, tmp
);
8650 tcg_gen_not_i32(tmp2
, tmp2
);
8654 store_reg_bx(s
, rd
, tmp2
);
8657 if (op1
!= 0x0f && op1
!= 0x0d) {
8658 tcg_temp_free_i32(tmp2
);
8661 /* other instructions */
8662 op1
= (insn
>> 24) & 0xf;
8666 /* multiplies, extra load/stores */
8667 sh
= (insn
>> 5) & 3;
8670 rd
= (insn
>> 16) & 0xf;
8671 rn
= (insn
>> 12) & 0xf;
8672 rs
= (insn
>> 8) & 0xf;
8674 op1
= (insn
>> 20) & 0xf;
8676 case 0: case 1: case 2: case 3: case 6:
8678 tmp
= load_reg(s
, rs
);
8679 tmp2
= load_reg(s
, rm
);
8680 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8681 tcg_temp_free_i32(tmp2
);
8682 if (insn
& (1 << 22)) {
8683 /* Subtract (mls) */
8685 tmp2
= load_reg(s
, rn
);
8686 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8687 tcg_temp_free_i32(tmp2
);
8688 } else if (insn
& (1 << 21)) {
8690 tmp2
= load_reg(s
, rn
);
8691 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8692 tcg_temp_free_i32(tmp2
);
8694 if (insn
& (1 << 20))
8696 store_reg(s
, rd
, tmp
);
8699 /* 64 bit mul double accumulate (UMAAL) */
8701 tmp
= load_reg(s
, rs
);
8702 tmp2
= load_reg(s
, rm
);
8703 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8704 gen_addq_lo(s
, tmp64
, rn
);
8705 gen_addq_lo(s
, tmp64
, rd
);
8706 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8707 tcg_temp_free_i64(tmp64
);
8709 case 8: case 9: case 10: case 11:
8710 case 12: case 13: case 14: case 15:
8711 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8712 tmp
= load_reg(s
, rs
);
8713 tmp2
= load_reg(s
, rm
);
8714 if (insn
& (1 << 22)) {
8715 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8717 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8719 if (insn
& (1 << 21)) { /* mult accumulate */
8720 TCGv_i32 al
= load_reg(s
, rn
);
8721 TCGv_i32 ah
= load_reg(s
, rd
);
8722 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8723 tcg_temp_free_i32(al
);
8724 tcg_temp_free_i32(ah
);
8726 if (insn
& (1 << 20)) {
8727 gen_logicq_cc(tmp
, tmp2
);
8729 store_reg(s
, rn
, tmp
);
8730 store_reg(s
, rd
, tmp2
);
8736 rn
= (insn
>> 16) & 0xf;
8737 rd
= (insn
>> 12) & 0xf;
8738 if (insn
& (1 << 23)) {
8739 /* load/store exclusive */
8740 int op2
= (insn
>> 8) & 3;
8741 op1
= (insn
>> 21) & 0x3;
8744 case 0: /* lda/stl */
8750 case 1: /* reserved */
8752 case 2: /* ldaex/stlex */
8755 case 3: /* ldrex/strex */
8764 addr
= tcg_temp_local_new_i32();
8765 load_reg_var(s
, addr
, rn
);
8767 /* Since the emulation does not have barriers,
8768 the acquire/release semantics need no special
8771 if (insn
& (1 << 20)) {
8772 tmp
= tcg_temp_new_i32();
8775 gen_aa32_ld32u(s
, tmp
, addr
,
8779 gen_aa32_ld8u(s
, tmp
, addr
,
8783 gen_aa32_ld16u(s
, tmp
, addr
,
8789 store_reg(s
, rd
, tmp
);
8792 tmp
= load_reg(s
, rm
);
8795 gen_aa32_st32(s
, tmp
, addr
,
8799 gen_aa32_st8(s
, tmp
, addr
,
8803 gen_aa32_st16(s
, tmp
, addr
,
8809 tcg_temp_free_i32(tmp
);
8811 } else if (insn
& (1 << 20)) {
8814 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8816 case 1: /* ldrexd */
8817 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8819 case 2: /* ldrexb */
8820 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8822 case 3: /* ldrexh */
8823 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8832 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8834 case 1: /* strexd */
8835 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8837 case 2: /* strexb */
8838 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8840 case 3: /* strexh */
8841 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8847 tcg_temp_free_i32(addr
);
8849 /* SWP instruction */
8852 /* ??? This is not really atomic. However we know
8853 we never have multiple CPUs running in parallel,
8854 so it is good enough. */
8855 addr
= load_reg(s
, rn
);
8856 tmp
= load_reg(s
, rm
);
8857 tmp2
= tcg_temp_new_i32();
8858 if (insn
& (1 << 22)) {
8859 gen_aa32_ld8u(s
, tmp2
, addr
, get_mem_index(s
));
8860 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
8862 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8863 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8865 tcg_temp_free_i32(tmp
);
8866 tcg_temp_free_i32(addr
);
8867 store_reg(s
, rd
, tmp2
);
8872 bool load
= insn
& (1 << 20);
8873 bool doubleword
= false;
8874 /* Misc load/store */
8875 rn
= (insn
>> 16) & 0xf;
8876 rd
= (insn
>> 12) & 0xf;
8878 if (!load
&& (sh
& 2)) {
8882 /* UNPREDICTABLE; we choose to UNDEF */
8885 load
= (sh
& 1) == 0;
8889 addr
= load_reg(s
, rn
);
8890 if (insn
& (1 << 24))
8891 gen_add_datah_offset(s
, insn
, 0, addr
);
8897 tmp
= load_reg(s
, rd
);
8898 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8899 tcg_temp_free_i32(tmp
);
8900 tcg_gen_addi_i32(addr
, addr
, 4);
8901 tmp
= load_reg(s
, rd
+ 1);
8902 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8903 tcg_temp_free_i32(tmp
);
8906 tmp
= tcg_temp_new_i32();
8907 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8908 store_reg(s
, rd
, tmp
);
8909 tcg_gen_addi_i32(addr
, addr
, 4);
8910 tmp
= tcg_temp_new_i32();
8911 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8914 address_offset
= -4;
8917 tmp
= tcg_temp_new_i32();
8920 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
8923 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
8927 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
8932 tmp
= load_reg(s
, rd
);
8933 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
8934 tcg_temp_free_i32(tmp
);
8936 /* Perform base writeback before the loaded value to
8937 ensure correct behavior with overlapping index registers.
8938 ldrd with base writeback is undefined if the
8939 destination and index registers overlap. */
8940 if (!(insn
& (1 << 24))) {
8941 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8942 store_reg(s
, rn
, addr
);
8943 } else if (insn
& (1 << 21)) {
8945 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8946 store_reg(s
, rn
, addr
);
8948 tcg_temp_free_i32(addr
);
8951 /* Complete the load. */
8952 store_reg(s
, rd
, tmp
);
8961 if (insn
& (1 << 4)) {
8963 /* Armv6 Media instructions. */
8965 rn
= (insn
>> 16) & 0xf;
8966 rd
= (insn
>> 12) & 0xf;
8967 rs
= (insn
>> 8) & 0xf;
8968 switch ((insn
>> 23) & 3) {
8969 case 0: /* Parallel add/subtract. */
8970 op1
= (insn
>> 20) & 7;
8971 tmp
= load_reg(s
, rn
);
8972 tmp2
= load_reg(s
, rm
);
8973 sh
= (insn
>> 5) & 7;
8974 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8976 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8977 tcg_temp_free_i32(tmp2
);
8978 store_reg(s
, rd
, tmp
);
8981 if ((insn
& 0x00700020) == 0) {
8982 /* Halfword pack. */
8983 tmp
= load_reg(s
, rn
);
8984 tmp2
= load_reg(s
, rm
);
8985 shift
= (insn
>> 7) & 0x1f;
8986 if (insn
& (1 << 6)) {
8990 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8991 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8992 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8996 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8997 tcg_gen_ext16u_i32(tmp
, tmp
);
8998 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9000 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9001 tcg_temp_free_i32(tmp2
);
9002 store_reg(s
, rd
, tmp
);
9003 } else if ((insn
& 0x00200020) == 0x00200000) {
9005 tmp
= load_reg(s
, rm
);
9006 shift
= (insn
>> 7) & 0x1f;
9007 if (insn
& (1 << 6)) {
9010 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9012 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9014 sh
= (insn
>> 16) & 0x1f;
9015 tmp2
= tcg_const_i32(sh
);
9016 if (insn
& (1 << 22))
9017 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9019 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9020 tcg_temp_free_i32(tmp2
);
9021 store_reg(s
, rd
, tmp
);
9022 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9024 tmp
= load_reg(s
, rm
);
9025 sh
= (insn
>> 16) & 0x1f;
9026 tmp2
= tcg_const_i32(sh
);
9027 if (insn
& (1 << 22))
9028 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9030 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9031 tcg_temp_free_i32(tmp2
);
9032 store_reg(s
, rd
, tmp
);
9033 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9035 tmp
= load_reg(s
, rn
);
9036 tmp2
= load_reg(s
, rm
);
9037 tmp3
= tcg_temp_new_i32();
9038 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9039 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9040 tcg_temp_free_i32(tmp3
);
9041 tcg_temp_free_i32(tmp2
);
9042 store_reg(s
, rd
, tmp
);
9043 } else if ((insn
& 0x000003e0) == 0x00000060) {
9044 tmp
= load_reg(s
, rm
);
9045 shift
= (insn
>> 10) & 3;
9046 /* ??? In many cases it's not necessary to do a
9047 rotate, a shift is sufficient. */
9049 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9050 op1
= (insn
>> 20) & 7;
9052 case 0: gen_sxtb16(tmp
); break;
9053 case 2: gen_sxtb(tmp
); break;
9054 case 3: gen_sxth(tmp
); break;
9055 case 4: gen_uxtb16(tmp
); break;
9056 case 6: gen_uxtb(tmp
); break;
9057 case 7: gen_uxth(tmp
); break;
9058 default: goto illegal_op
;
9061 tmp2
= load_reg(s
, rn
);
9062 if ((op1
& 3) == 0) {
9063 gen_add16(tmp
, tmp2
);
9065 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9066 tcg_temp_free_i32(tmp2
);
9069 store_reg(s
, rd
, tmp
);
9070 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9072 tmp
= load_reg(s
, rm
);
9073 if (insn
& (1 << 22)) {
9074 if (insn
& (1 << 7)) {
9078 gen_helper_rbit(tmp
, tmp
);
9081 if (insn
& (1 << 7))
9084 tcg_gen_bswap32_i32(tmp
, tmp
);
9086 store_reg(s
, rd
, tmp
);
9091 case 2: /* Multiplies (Type 3). */
9092 switch ((insn
>> 20) & 0x7) {
9094 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9095 /* op2 not 00x or 11x : UNDEF */
9098 /* Signed multiply most significant [accumulate].
9099 (SMMUL, SMMLA, SMMLS) */
9100 tmp
= load_reg(s
, rm
);
9101 tmp2
= load_reg(s
, rs
);
9102 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9105 tmp
= load_reg(s
, rd
);
9106 if (insn
& (1 << 6)) {
9107 tmp64
= gen_subq_msw(tmp64
, tmp
);
9109 tmp64
= gen_addq_msw(tmp64
, tmp
);
9112 if (insn
& (1 << 5)) {
9113 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9115 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9116 tmp
= tcg_temp_new_i32();
9117 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9118 tcg_temp_free_i64(tmp64
);
9119 store_reg(s
, rn
, tmp
);
9123 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9124 if (insn
& (1 << 7)) {
9127 tmp
= load_reg(s
, rm
);
9128 tmp2
= load_reg(s
, rs
);
9129 if (insn
& (1 << 5))
9130 gen_swap_half(tmp2
);
9131 gen_smul_dual(tmp
, tmp2
);
9132 if (insn
& (1 << 22)) {
9133 /* smlald, smlsld */
9136 tmp64
= tcg_temp_new_i64();
9137 tmp64_2
= tcg_temp_new_i64();
9138 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9139 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9140 tcg_temp_free_i32(tmp
);
9141 tcg_temp_free_i32(tmp2
);
9142 if (insn
& (1 << 6)) {
9143 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9145 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9147 tcg_temp_free_i64(tmp64_2
);
9148 gen_addq(s
, tmp64
, rd
, rn
);
9149 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9150 tcg_temp_free_i64(tmp64
);
9152 /* smuad, smusd, smlad, smlsd */
9153 if (insn
& (1 << 6)) {
9154 /* This subtraction cannot overflow. */
9155 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9157 /* This addition cannot overflow 32 bits;
9158 * however it may overflow considered as a
9159 * signed operation, in which case we must set
9162 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9164 tcg_temp_free_i32(tmp2
);
9167 tmp2
= load_reg(s
, rd
);
9168 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9169 tcg_temp_free_i32(tmp2
);
9171 store_reg(s
, rn
, tmp
);
9177 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9180 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9183 tmp
= load_reg(s
, rm
);
9184 tmp2
= load_reg(s
, rs
);
9185 if (insn
& (1 << 21)) {
9186 gen_helper_udiv(tmp
, tmp
, tmp2
);
9188 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9190 tcg_temp_free_i32(tmp2
);
9191 store_reg(s
, rn
, tmp
);
9198 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9200 case 0: /* Unsigned sum of absolute differences. */
9202 tmp
= load_reg(s
, rm
);
9203 tmp2
= load_reg(s
, rs
);
9204 gen_helper_usad8(tmp
, tmp
, tmp2
);
9205 tcg_temp_free_i32(tmp2
);
9207 tmp2
= load_reg(s
, rd
);
9208 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9209 tcg_temp_free_i32(tmp2
);
9211 store_reg(s
, rn
, tmp
);
9213 case 0x20: case 0x24: case 0x28: case 0x2c:
9214 /* Bitfield insert/clear. */
9216 shift
= (insn
>> 7) & 0x1f;
9217 i
= (insn
>> 16) & 0x1f;
9219 /* UNPREDICTABLE; we choose to UNDEF */
9224 tmp
= tcg_temp_new_i32();
9225 tcg_gen_movi_i32(tmp
, 0);
9227 tmp
= load_reg(s
, rm
);
9230 tmp2
= load_reg(s
, rd
);
9231 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9232 tcg_temp_free_i32(tmp2
);
9234 store_reg(s
, rd
, tmp
);
9236 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9237 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9239 tmp
= load_reg(s
, rm
);
9240 shift
= (insn
>> 7) & 0x1f;
9241 i
= ((insn
>> 16) & 0x1f) + 1;
9246 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
9248 gen_sbfx(tmp
, shift
, i
);
9251 store_reg(s
, rd
, tmp
);
9261 /* Check for undefined extension instructions
9262 * per the ARM Bible IE:
9263 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9265 sh
= (0xf << 20) | (0xf << 4);
9266 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9270 /* load/store byte/word */
9271 rn
= (insn
>> 16) & 0xf;
9272 rd
= (insn
>> 12) & 0xf;
9273 tmp2
= load_reg(s
, rn
);
9274 if ((insn
& 0x01200000) == 0x00200000) {
9276 i
= get_a32_user_mem_index(s
);
9278 i
= get_mem_index(s
);
9280 if (insn
& (1 << 24))
9281 gen_add_data_offset(s
, insn
, tmp2
);
9282 if (insn
& (1 << 20)) {
9284 tmp
= tcg_temp_new_i32();
9285 if (insn
& (1 << 22)) {
9286 gen_aa32_ld8u(s
, tmp
, tmp2
, i
);
9288 gen_aa32_ld32u(s
, tmp
, tmp2
, i
);
9292 tmp
= load_reg(s
, rd
);
9293 if (insn
& (1 << 22)) {
9294 gen_aa32_st8(s
, tmp
, tmp2
, i
);
9296 gen_aa32_st32(s
, tmp
, tmp2
, i
);
9298 tcg_temp_free_i32(tmp
);
9300 if (!(insn
& (1 << 24))) {
9301 gen_add_data_offset(s
, insn
, tmp2
);
9302 store_reg(s
, rn
, tmp2
);
9303 } else if (insn
& (1 << 21)) {
9304 store_reg(s
, rn
, tmp2
);
9306 tcg_temp_free_i32(tmp2
);
9308 if (insn
& (1 << 20)) {
9309 /* Complete the load. */
9310 store_reg_from_load(s
, rd
, tmp
);
9316 int j
, n
, loaded_base
;
9317 bool exc_return
= false;
9318 bool is_load
= extract32(insn
, 20, 1);
9320 TCGv_i32 loaded_var
;
9321 /* load/store multiple words */
9322 /* XXX: store correct base if write back */
9323 if (insn
& (1 << 22)) {
9324 /* LDM (user), LDM (exception return) and STM (user) */
9326 goto illegal_op
; /* only usable in supervisor mode */
9328 if (is_load
&& extract32(insn
, 15, 1)) {
9334 rn
= (insn
>> 16) & 0xf;
9335 addr
= load_reg(s
, rn
);
9337 /* compute total size */
9339 TCGV_UNUSED_I32(loaded_var
);
9342 if (insn
& (1 << i
))
9345 /* XXX: test invalid n == 0 case ? */
9346 if (insn
& (1 << 23)) {
9347 if (insn
& (1 << 24)) {
9349 tcg_gen_addi_i32(addr
, addr
, 4);
9351 /* post increment */
9354 if (insn
& (1 << 24)) {
9356 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9358 /* post decrement */
9360 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9365 if (insn
& (1 << i
)) {
9368 tmp
= tcg_temp_new_i32();
9369 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9371 tmp2
= tcg_const_i32(i
);
9372 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9373 tcg_temp_free_i32(tmp2
);
9374 tcg_temp_free_i32(tmp
);
9375 } else if (i
== rn
) {
9378 } else if (rn
== 15 && exc_return
) {
9379 store_pc_exc_ret(s
, tmp
);
9381 store_reg_from_load(s
, i
, tmp
);
9386 /* special case: r15 = PC + 8 */
9387 val
= (long)s
->pc
+ 4;
9388 tmp
= tcg_temp_new_i32();
9389 tcg_gen_movi_i32(tmp
, val
);
9391 tmp
= tcg_temp_new_i32();
9392 tmp2
= tcg_const_i32(i
);
9393 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9394 tcg_temp_free_i32(tmp2
);
9396 tmp
= load_reg(s
, i
);
9398 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9399 tcg_temp_free_i32(tmp
);
9402 /* no need to add after the last transfer */
9404 tcg_gen_addi_i32(addr
, addr
, 4);
9407 if (insn
& (1 << 21)) {
9409 if (insn
& (1 << 23)) {
9410 if (insn
& (1 << 24)) {
9413 /* post increment */
9414 tcg_gen_addi_i32(addr
, addr
, 4);
9417 if (insn
& (1 << 24)) {
9420 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9422 /* post decrement */
9423 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9426 store_reg(s
, rn
, addr
);
9428 tcg_temp_free_i32(addr
);
9431 store_reg(s
, rn
, loaded_var
);
9434 /* Restore CPSR from SPSR. */
9435 tmp
= load_cpu_field(spsr
);
9436 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9437 tcg_temp_free_i32(tmp
);
9438 s
->is_jmp
= DISAS_JUMP
;
9447 /* branch (and link) */
9448 val
= (int32_t)s
->pc
;
9449 if (insn
& (1 << 24)) {
9450 tmp
= tcg_temp_new_i32();
9451 tcg_gen_movi_i32(tmp
, val
);
9452 store_reg(s
, 14, tmp
);
9454 offset
= sextract32(insn
<< 2, 0, 26);
9462 if (((insn
>> 8) & 0xe) == 10) {
9464 if (disas_vfp_insn(s
, insn
)) {
9467 } else if (disas_coproc_insn(s
, insn
)) {
9474 gen_set_pc_im(s
, s
->pc
);
9475 s
->svc_imm
= extract32(insn
, 0, 24);
9476 s
->is_jmp
= DISAS_SWI
;
9480 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9481 default_exception_el(s
));
9487 /* Return true if this is a Thumb-2 logical op. */
9489 thumb2_logic_op(int op
)
9494 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9495 then set condition code flags based on the result of the operation.
9496 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9497 to the high bit of T1.
9498 Returns zero if the opcode is valid. */
9501 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9502 TCGv_i32 t0
, TCGv_i32 t1
)
9509 tcg_gen_and_i32(t0
, t0
, t1
);
9513 tcg_gen_andc_i32(t0
, t0
, t1
);
9517 tcg_gen_or_i32(t0
, t0
, t1
);
9521 tcg_gen_orc_i32(t0
, t0
, t1
);
9525 tcg_gen_xor_i32(t0
, t0
, t1
);
9530 gen_add_CC(t0
, t0
, t1
);
9532 tcg_gen_add_i32(t0
, t0
, t1
);
9536 gen_adc_CC(t0
, t0
, t1
);
9542 gen_sbc_CC(t0
, t0
, t1
);
9544 gen_sub_carry(t0
, t0
, t1
);
9549 gen_sub_CC(t0
, t0
, t1
);
9551 tcg_gen_sub_i32(t0
, t0
, t1
);
9555 gen_sub_CC(t0
, t1
, t0
);
9557 tcg_gen_sub_i32(t0
, t1
, t0
);
9559 default: /* 5, 6, 7, 9, 12, 15. */
9565 gen_set_CF_bit31(t1
);
9570 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9572 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9574 uint32_t insn
, imm
, shift
, offset
;
9575 uint32_t rd
, rn
, rm
, rs
;
9586 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9587 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9588 /* Thumb-1 cores may need to treat bl and blx as a pair of
9589 16-bit instructions to get correct prefetch abort behavior. */
9591 if ((insn
& (1 << 12)) == 0) {
9593 /* Second half of blx. */
9594 offset
= ((insn
& 0x7ff) << 1);
9595 tmp
= load_reg(s
, 14);
9596 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9597 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9599 tmp2
= tcg_temp_new_i32();
9600 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9601 store_reg(s
, 14, tmp2
);
9605 if (insn
& (1 << 11)) {
9606 /* Second half of bl. */
9607 offset
= ((insn
& 0x7ff) << 1) | 1;
9608 tmp
= load_reg(s
, 14);
9609 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9611 tmp2
= tcg_temp_new_i32();
9612 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9613 store_reg(s
, 14, tmp2
);
9617 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9618 /* Instruction spans a page boundary. Implement it as two
9619 16-bit instructions in case the second half causes an
9621 offset
= ((int32_t)insn
<< 21) >> 9;
9622 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9625 /* Fall through to 32-bit decode. */
9628 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9630 insn
|= (uint32_t)insn_hw1
<< 16;
9632 if ((insn
& 0xf800e800) != 0xf000e800) {
9636 rn
= (insn
>> 16) & 0xf;
9637 rs
= (insn
>> 12) & 0xf;
9638 rd
= (insn
>> 8) & 0xf;
9640 switch ((insn
>> 25) & 0xf) {
9641 case 0: case 1: case 2: case 3:
9642 /* 16-bit instructions. Should never happen. */
9645 if (insn
& (1 << 22)) {
9646 /* Other load/store, table branch. */
9647 if (insn
& 0x01200000) {
9648 /* Load/store doubleword. */
9650 addr
= tcg_temp_new_i32();
9651 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9653 addr
= load_reg(s
, rn
);
9655 offset
= (insn
& 0xff) * 4;
9656 if ((insn
& (1 << 23)) == 0)
9658 if (insn
& (1 << 24)) {
9659 tcg_gen_addi_i32(addr
, addr
, offset
);
9662 if (insn
& (1 << 20)) {
9664 tmp
= tcg_temp_new_i32();
9665 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9666 store_reg(s
, rs
, tmp
);
9667 tcg_gen_addi_i32(addr
, addr
, 4);
9668 tmp
= tcg_temp_new_i32();
9669 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9670 store_reg(s
, rd
, tmp
);
9673 tmp
= load_reg(s
, rs
);
9674 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9675 tcg_temp_free_i32(tmp
);
9676 tcg_gen_addi_i32(addr
, addr
, 4);
9677 tmp
= load_reg(s
, rd
);
9678 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9679 tcg_temp_free_i32(tmp
);
9681 if (insn
& (1 << 21)) {
9682 /* Base writeback. */
9685 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9686 store_reg(s
, rn
, addr
);
9688 tcg_temp_free_i32(addr
);
9690 } else if ((insn
& (1 << 23)) == 0) {
9691 /* Load/store exclusive word. */
9692 addr
= tcg_temp_local_new_i32();
9693 load_reg_var(s
, addr
, rn
);
9694 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9695 if (insn
& (1 << 20)) {
9696 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9698 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9700 tcg_temp_free_i32(addr
);
9701 } else if ((insn
& (7 << 5)) == 0) {
9704 addr
= tcg_temp_new_i32();
9705 tcg_gen_movi_i32(addr
, s
->pc
);
9707 addr
= load_reg(s
, rn
);
9709 tmp
= load_reg(s
, rm
);
9710 tcg_gen_add_i32(addr
, addr
, tmp
);
9711 if (insn
& (1 << 4)) {
9713 tcg_gen_add_i32(addr
, addr
, tmp
);
9714 tcg_temp_free_i32(tmp
);
9715 tmp
= tcg_temp_new_i32();
9716 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9718 tcg_temp_free_i32(tmp
);
9719 tmp
= tcg_temp_new_i32();
9720 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9722 tcg_temp_free_i32(addr
);
9723 tcg_gen_shli_i32(tmp
, tmp
, 1);
9724 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9725 store_reg(s
, 15, tmp
);
9727 int op2
= (insn
>> 6) & 0x3;
9728 op
= (insn
>> 4) & 0x3;
9733 /* Load/store exclusive byte/halfword/doubleword */
9740 /* Load-acquire/store-release */
9746 /* Load-acquire/store-release exclusive */
9750 addr
= tcg_temp_local_new_i32();
9751 load_reg_var(s
, addr
, rn
);
9753 if (insn
& (1 << 20)) {
9754 tmp
= tcg_temp_new_i32();
9757 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9760 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9763 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9768 store_reg(s
, rs
, tmp
);
9770 tmp
= load_reg(s
, rs
);
9773 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
9776 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
9779 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9784 tcg_temp_free_i32(tmp
);
9786 } else if (insn
& (1 << 20)) {
9787 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9789 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9791 tcg_temp_free_i32(addr
);
9794 /* Load/store multiple, RFE, SRS. */
9795 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9796 /* RFE, SRS: not available in user mode or on M profile */
9797 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9800 if (insn
& (1 << 20)) {
9802 addr
= load_reg(s
, rn
);
9803 if ((insn
& (1 << 24)) == 0)
9804 tcg_gen_addi_i32(addr
, addr
, -8);
9805 /* Load PC into tmp and CPSR into tmp2. */
9806 tmp
= tcg_temp_new_i32();
9807 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9808 tcg_gen_addi_i32(addr
, addr
, 4);
9809 tmp2
= tcg_temp_new_i32();
9810 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9811 if (insn
& (1 << 21)) {
9812 /* Base writeback. */
9813 if (insn
& (1 << 24)) {
9814 tcg_gen_addi_i32(addr
, addr
, 4);
9816 tcg_gen_addi_i32(addr
, addr
, -4);
9818 store_reg(s
, rn
, addr
);
9820 tcg_temp_free_i32(addr
);
9822 gen_rfe(s
, tmp
, tmp2
);
9825 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9829 int i
, loaded_base
= 0;
9830 TCGv_i32 loaded_var
;
9831 /* Load/store multiple. */
9832 addr
= load_reg(s
, rn
);
9834 for (i
= 0; i
< 16; i
++) {
9835 if (insn
& (1 << i
))
9838 if (insn
& (1 << 24)) {
9839 tcg_gen_addi_i32(addr
, addr
, -offset
);
9842 TCGV_UNUSED_I32(loaded_var
);
9843 for (i
= 0; i
< 16; i
++) {
9844 if ((insn
& (1 << i
)) == 0)
9846 if (insn
& (1 << 20)) {
9848 tmp
= tcg_temp_new_i32();
9849 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9852 } else if (i
== rn
) {
9856 store_reg(s
, i
, tmp
);
9860 tmp
= load_reg(s
, i
);
9861 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9862 tcg_temp_free_i32(tmp
);
9864 tcg_gen_addi_i32(addr
, addr
, 4);
9867 store_reg(s
, rn
, loaded_var
);
9869 if (insn
& (1 << 21)) {
9870 /* Base register writeback. */
9871 if (insn
& (1 << 24)) {
9872 tcg_gen_addi_i32(addr
, addr
, -offset
);
9874 /* Fault if writeback register is in register list. */
9875 if (insn
& (1 << rn
))
9877 store_reg(s
, rn
, addr
);
9879 tcg_temp_free_i32(addr
);
9886 op
= (insn
>> 21) & 0xf;
9888 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9891 /* Halfword pack. */
9892 tmp
= load_reg(s
, rn
);
9893 tmp2
= load_reg(s
, rm
);
9894 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9895 if (insn
& (1 << 5)) {
9899 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9900 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9901 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9905 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9906 tcg_gen_ext16u_i32(tmp
, tmp
);
9907 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9909 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9910 tcg_temp_free_i32(tmp2
);
9911 store_reg(s
, rd
, tmp
);
9913 /* Data processing register constant shift. */
9915 tmp
= tcg_temp_new_i32();
9916 tcg_gen_movi_i32(tmp
, 0);
9918 tmp
= load_reg(s
, rn
);
9920 tmp2
= load_reg(s
, rm
);
9922 shiftop
= (insn
>> 4) & 3;
9923 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9924 conds
= (insn
& (1 << 20)) != 0;
9925 logic_cc
= (conds
&& thumb2_logic_op(op
));
9926 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9927 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9929 tcg_temp_free_i32(tmp2
);
9931 store_reg(s
, rd
, tmp
);
9933 tcg_temp_free_i32(tmp
);
9937 case 13: /* Misc data processing. */
9938 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9939 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9942 case 0: /* Register controlled shift. */
9943 tmp
= load_reg(s
, rn
);
9944 tmp2
= load_reg(s
, rm
);
9945 if ((insn
& 0x70) != 0)
9947 op
= (insn
>> 21) & 3;
9948 logic_cc
= (insn
& (1 << 20)) != 0;
9949 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9952 store_reg_bx(s
, rd
, tmp
);
9954 case 1: /* Sign/zero extend. */
9955 op
= (insn
>> 20) & 7;
9957 case 0: /* SXTAH, SXTH */
9958 case 1: /* UXTAH, UXTH */
9959 case 4: /* SXTAB, SXTB */
9960 case 5: /* UXTAB, UXTB */
9962 case 2: /* SXTAB16, SXTB16 */
9963 case 3: /* UXTAB16, UXTB16 */
9964 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9972 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9976 tmp
= load_reg(s
, rm
);
9977 shift
= (insn
>> 4) & 3;
9978 /* ??? In many cases it's not necessary to do a
9979 rotate, a shift is sufficient. */
9981 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9982 op
= (insn
>> 20) & 7;
9984 case 0: gen_sxth(tmp
); break;
9985 case 1: gen_uxth(tmp
); break;
9986 case 2: gen_sxtb16(tmp
); break;
9987 case 3: gen_uxtb16(tmp
); break;
9988 case 4: gen_sxtb(tmp
); break;
9989 case 5: gen_uxtb(tmp
); break;
9991 g_assert_not_reached();
9994 tmp2
= load_reg(s
, rn
);
9995 if ((op
>> 1) == 1) {
9996 gen_add16(tmp
, tmp2
);
9998 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9999 tcg_temp_free_i32(tmp2
);
10002 store_reg(s
, rd
, tmp
);
10004 case 2: /* SIMD add/subtract. */
10005 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10008 op
= (insn
>> 20) & 7;
10009 shift
= (insn
>> 4) & 7;
10010 if ((op
& 3) == 3 || (shift
& 3) == 3)
10012 tmp
= load_reg(s
, rn
);
10013 tmp2
= load_reg(s
, rm
);
10014 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
10015 tcg_temp_free_i32(tmp2
);
10016 store_reg(s
, rd
, tmp
);
10018 case 3: /* Other data processing. */
10019 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10021 /* Saturating add/subtract. */
10022 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10025 tmp
= load_reg(s
, rn
);
10026 tmp2
= load_reg(s
, rm
);
10028 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10030 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10032 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10033 tcg_temp_free_i32(tmp2
);
10036 case 0x0a: /* rbit */
10037 case 0x08: /* rev */
10038 case 0x09: /* rev16 */
10039 case 0x0b: /* revsh */
10040 case 0x18: /* clz */
10042 case 0x10: /* sel */
10043 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10047 case 0x20: /* crc32/crc32c */
10053 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10060 tmp
= load_reg(s
, rn
);
10062 case 0x0a: /* rbit */
10063 gen_helper_rbit(tmp
, tmp
);
10065 case 0x08: /* rev */
10066 tcg_gen_bswap32_i32(tmp
, tmp
);
10068 case 0x09: /* rev16 */
10071 case 0x0b: /* revsh */
10074 case 0x10: /* sel */
10075 tmp2
= load_reg(s
, rm
);
10076 tmp3
= tcg_temp_new_i32();
10077 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10078 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10079 tcg_temp_free_i32(tmp3
);
10080 tcg_temp_free_i32(tmp2
);
10082 case 0x18: /* clz */
10083 gen_helper_clz(tmp
, tmp
);
10093 uint32_t sz
= op
& 0x3;
10094 uint32_t c
= op
& 0x8;
10096 tmp2
= load_reg(s
, rm
);
10098 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10099 } else if (sz
== 1) {
10100 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10102 tmp3
= tcg_const_i32(1 << sz
);
10104 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10106 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10108 tcg_temp_free_i32(tmp2
);
10109 tcg_temp_free_i32(tmp3
);
10113 g_assert_not_reached();
10116 store_reg(s
, rd
, tmp
);
10118 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10119 switch ((insn
>> 20) & 7) {
10120 case 0: /* 32 x 32 -> 32 */
10121 case 7: /* Unsigned sum of absolute differences. */
10123 case 1: /* 16 x 16 -> 32 */
10124 case 2: /* Dual multiply add. */
10125 case 3: /* 32 * 16 -> 32msb */
10126 case 4: /* Dual multiply subtract. */
10127 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10128 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10133 op
= (insn
>> 4) & 0xf;
10134 tmp
= load_reg(s
, rn
);
10135 tmp2
= load_reg(s
, rm
);
10136 switch ((insn
>> 20) & 7) {
10137 case 0: /* 32 x 32 -> 32 */
10138 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10139 tcg_temp_free_i32(tmp2
);
10141 tmp2
= load_reg(s
, rs
);
10143 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10145 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10146 tcg_temp_free_i32(tmp2
);
10149 case 1: /* 16 x 16 -> 32 */
10150 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10151 tcg_temp_free_i32(tmp2
);
10153 tmp2
= load_reg(s
, rs
);
10154 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10155 tcg_temp_free_i32(tmp2
);
10158 case 2: /* Dual multiply add. */
10159 case 4: /* Dual multiply subtract. */
10161 gen_swap_half(tmp2
);
10162 gen_smul_dual(tmp
, tmp2
);
10163 if (insn
& (1 << 22)) {
10164 /* This subtraction cannot overflow. */
10165 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10167 /* This addition cannot overflow 32 bits;
10168 * however it may overflow considered as a signed
10169 * operation, in which case we must set the Q flag.
10171 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10173 tcg_temp_free_i32(tmp2
);
10176 tmp2
= load_reg(s
, rs
);
10177 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10178 tcg_temp_free_i32(tmp2
);
10181 case 3: /* 32 * 16 -> 32msb */
10183 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10186 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10187 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10188 tmp
= tcg_temp_new_i32();
10189 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10190 tcg_temp_free_i64(tmp64
);
10193 tmp2
= load_reg(s
, rs
);
10194 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10195 tcg_temp_free_i32(tmp2
);
10198 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10199 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10201 tmp
= load_reg(s
, rs
);
10202 if (insn
& (1 << 20)) {
10203 tmp64
= gen_addq_msw(tmp64
, tmp
);
10205 tmp64
= gen_subq_msw(tmp64
, tmp
);
10208 if (insn
& (1 << 4)) {
10209 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10211 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10212 tmp
= tcg_temp_new_i32();
10213 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10214 tcg_temp_free_i64(tmp64
);
10216 case 7: /* Unsigned sum of absolute differences. */
10217 gen_helper_usad8(tmp
, tmp
, tmp2
);
10218 tcg_temp_free_i32(tmp2
);
10220 tmp2
= load_reg(s
, rs
);
10221 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10222 tcg_temp_free_i32(tmp2
);
10226 store_reg(s
, rd
, tmp
);
10228 case 6: case 7: /* 64-bit multiply, Divide. */
10229 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10230 tmp
= load_reg(s
, rn
);
10231 tmp2
= load_reg(s
, rm
);
10232 if ((op
& 0x50) == 0x10) {
10234 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10238 gen_helper_udiv(tmp
, tmp
, tmp2
);
10240 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10241 tcg_temp_free_i32(tmp2
);
10242 store_reg(s
, rd
, tmp
);
10243 } else if ((op
& 0xe) == 0xc) {
10244 /* Dual multiply accumulate long. */
10245 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10246 tcg_temp_free_i32(tmp
);
10247 tcg_temp_free_i32(tmp2
);
10251 gen_swap_half(tmp2
);
10252 gen_smul_dual(tmp
, tmp2
);
10254 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10256 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10258 tcg_temp_free_i32(tmp2
);
10260 tmp64
= tcg_temp_new_i64();
10261 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10262 tcg_temp_free_i32(tmp
);
10263 gen_addq(s
, tmp64
, rs
, rd
);
10264 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10265 tcg_temp_free_i64(tmp64
);
10268 /* Unsigned 64-bit multiply */
10269 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10273 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10274 tcg_temp_free_i32(tmp2
);
10275 tcg_temp_free_i32(tmp
);
10278 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10279 tcg_temp_free_i32(tmp2
);
10280 tmp64
= tcg_temp_new_i64();
10281 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10282 tcg_temp_free_i32(tmp
);
10284 /* Signed 64-bit multiply */
10285 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10290 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10291 tcg_temp_free_i64(tmp64
);
10294 gen_addq_lo(s
, tmp64
, rs
);
10295 gen_addq_lo(s
, tmp64
, rd
);
10296 } else if (op
& 0x40) {
10297 /* 64-bit accumulate. */
10298 gen_addq(s
, tmp64
, rs
, rd
);
10300 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10301 tcg_temp_free_i64(tmp64
);
10306 case 6: case 7: case 14: case 15:
10308 if (((insn
>> 24) & 3) == 3) {
10309 /* Translate into the equivalent ARM encoding. */
10310 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10311 if (disas_neon_data_insn(s
, insn
)) {
10314 } else if (((insn
>> 8) & 0xe) == 10) {
10315 if (disas_vfp_insn(s
, insn
)) {
10319 if (insn
& (1 << 28))
10321 if (disas_coproc_insn(s
, insn
)) {
10326 case 8: case 9: case 10: case 11:
10327 if (insn
& (1 << 15)) {
10328 /* Branches, misc control. */
10329 if (insn
& 0x5000) {
10330 /* Unconditional branch. */
10331 /* signextend(hw1[10:0]) -> offset[:12]. */
10332 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10333 /* hw1[10:0] -> offset[11:1]. */
10334 offset
|= (insn
& 0x7ff) << 1;
10335 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10336 offset[24:22] already have the same value because of the
10337 sign extension above. */
10338 offset
^= ((~insn
) & (1 << 13)) << 10;
10339 offset
^= ((~insn
) & (1 << 11)) << 11;
10341 if (insn
& (1 << 14)) {
10342 /* Branch and link. */
10343 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10347 if (insn
& (1 << 12)) {
10349 gen_jmp(s
, offset
);
10352 offset
&= ~(uint32_t)2;
10353 /* thumb2 bx, no need to check */
10354 gen_bx_im(s
, offset
);
10356 } else if (((insn
>> 23) & 7) == 7) {
10358 if (insn
& (1 << 13))
10361 if (insn
& (1 << 26)) {
10362 if (!(insn
& (1 << 20))) {
10363 /* Hypervisor call (v7) */
10364 int imm16
= extract32(insn
, 16, 4) << 12
10365 | extract32(insn
, 0, 12);
10372 /* Secure monitor call (v6+) */
10380 op
= (insn
>> 20) & 7;
10382 case 0: /* msr cpsr. */
10383 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10384 tmp
= load_reg(s
, rn
);
10385 addr
= tcg_const_i32(insn
& 0xff);
10386 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10387 tcg_temp_free_i32(addr
);
10388 tcg_temp_free_i32(tmp
);
10393 case 1: /* msr spsr. */
10394 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10398 if (extract32(insn
, 5, 1)) {
10400 int sysm
= extract32(insn
, 8, 4) |
10401 (extract32(insn
, 4, 1) << 4);
10404 gen_msr_banked(s
, r
, sysm
, rm
);
10408 /* MSR (for PSRs) */
10409 tmp
= load_reg(s
, rn
);
10411 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10415 case 2: /* cps, nop-hint. */
10416 if (((insn
>> 8) & 7) == 0) {
10417 gen_nop_hint(s
, insn
& 0xff);
10419 /* Implemented as NOP in user mode. */
10424 if (insn
& (1 << 10)) {
10425 if (insn
& (1 << 7))
10427 if (insn
& (1 << 6))
10429 if (insn
& (1 << 5))
10431 if (insn
& (1 << 9))
10432 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10434 if (insn
& (1 << 8)) {
10436 imm
|= (insn
& 0x1f);
10439 gen_set_psr_im(s
, offset
, 0, imm
);
10442 case 3: /* Special control operations. */
10444 op
= (insn
>> 4) & 0xf;
10446 case 2: /* clrex */
10451 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10454 /* We need to break the TB after this insn
10455 * to execute self-modifying code correctly
10456 * and also to take any pending interrupts
10466 /* Trivial implementation equivalent to bx. */
10467 tmp
= load_reg(s
, rn
);
10470 case 5: /* Exception return. */
10474 if (rn
!= 14 || rd
!= 15) {
10477 tmp
= load_reg(s
, rn
);
10478 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10479 gen_exception_return(s
, tmp
);
10482 if (extract32(insn
, 5, 1)) {
10484 int sysm
= extract32(insn
, 16, 4) |
10485 (extract32(insn
, 4, 1) << 4);
10487 gen_mrs_banked(s
, 0, sysm
, rd
);
10492 tmp
= tcg_temp_new_i32();
10493 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10494 addr
= tcg_const_i32(insn
& 0xff);
10495 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10496 tcg_temp_free_i32(addr
);
10498 gen_helper_cpsr_read(tmp
, cpu_env
);
10500 store_reg(s
, rd
, tmp
);
10503 if (extract32(insn
, 5, 1)) {
10505 int sysm
= extract32(insn
, 16, 4) |
10506 (extract32(insn
, 4, 1) << 4);
10508 gen_mrs_banked(s
, 1, sysm
, rd
);
10513 /* Not accessible in user mode. */
10514 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10517 tmp
= load_cpu_field(spsr
);
10518 store_reg(s
, rd
, tmp
);
10523 /* Conditional branch. */
10524 op
= (insn
>> 22) & 0xf;
10525 /* Generate a conditional jump to next instruction. */
10526 s
->condlabel
= gen_new_label();
10527 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10530 /* offset[11:1] = insn[10:0] */
10531 offset
= (insn
& 0x7ff) << 1;
10532 /* offset[17:12] = insn[21:16]. */
10533 offset
|= (insn
& 0x003f0000) >> 4;
10534 /* offset[31:20] = insn[26]. */
10535 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10536 /* offset[18] = insn[13]. */
10537 offset
|= (insn
& (1 << 13)) << 5;
10538 /* offset[19] = insn[11]. */
10539 offset
|= (insn
& (1 << 11)) << 8;
10541 /* jump to the offset */
10542 gen_jmp(s
, s
->pc
+ offset
);
10545 /* Data processing immediate. */
10546 if (insn
& (1 << 25)) {
10547 if (insn
& (1 << 24)) {
10548 if (insn
& (1 << 20))
10550 /* Bitfield/Saturate. */
10551 op
= (insn
>> 21) & 7;
10553 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10555 tmp
= tcg_temp_new_i32();
10556 tcg_gen_movi_i32(tmp
, 0);
10558 tmp
= load_reg(s
, rn
);
10561 case 2: /* Signed bitfield extract. */
10563 if (shift
+ imm
> 32)
10566 gen_sbfx(tmp
, shift
, imm
);
10568 case 6: /* Unsigned bitfield extract. */
10570 if (shift
+ imm
> 32)
10573 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
10575 case 3: /* Bitfield insert/clear. */
10578 imm
= imm
+ 1 - shift
;
10580 tmp2
= load_reg(s
, rd
);
10581 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10582 tcg_temp_free_i32(tmp2
);
10587 default: /* Saturate. */
10590 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10592 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10594 tmp2
= tcg_const_i32(imm
);
10597 if ((op
& 1) && shift
== 0) {
10598 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10599 tcg_temp_free_i32(tmp
);
10600 tcg_temp_free_i32(tmp2
);
10603 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10605 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10609 if ((op
& 1) && shift
== 0) {
10610 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10611 tcg_temp_free_i32(tmp
);
10612 tcg_temp_free_i32(tmp2
);
10615 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10617 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10620 tcg_temp_free_i32(tmp2
);
10623 store_reg(s
, rd
, tmp
);
10625 imm
= ((insn
& 0x04000000) >> 15)
10626 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10627 if (insn
& (1 << 22)) {
10628 /* 16-bit immediate. */
10629 imm
|= (insn
>> 4) & 0xf000;
10630 if (insn
& (1 << 23)) {
10632 tmp
= load_reg(s
, rd
);
10633 tcg_gen_ext16u_i32(tmp
, tmp
);
10634 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10637 tmp
= tcg_temp_new_i32();
10638 tcg_gen_movi_i32(tmp
, imm
);
10641 /* Add/sub 12-bit immediate. */
10643 offset
= s
->pc
& ~(uint32_t)3;
10644 if (insn
& (1 << 23))
10648 tmp
= tcg_temp_new_i32();
10649 tcg_gen_movi_i32(tmp
, offset
);
10651 tmp
= load_reg(s
, rn
);
10652 if (insn
& (1 << 23))
10653 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10655 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10658 store_reg(s
, rd
, tmp
);
10661 int shifter_out
= 0;
10662 /* modified 12-bit immediate. */
10663 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10664 imm
= (insn
& 0xff);
10667 /* Nothing to do. */
10669 case 1: /* 00XY00XY */
10672 case 2: /* XY00XY00 */
10676 case 3: /* XYXYXYXY */
10680 default: /* Rotated constant. */
10681 shift
= (shift
<< 1) | (imm
>> 7);
10683 imm
= imm
<< (32 - shift
);
10687 tmp2
= tcg_temp_new_i32();
10688 tcg_gen_movi_i32(tmp2
, imm
);
10689 rn
= (insn
>> 16) & 0xf;
10691 tmp
= tcg_temp_new_i32();
10692 tcg_gen_movi_i32(tmp
, 0);
10694 tmp
= load_reg(s
, rn
);
10696 op
= (insn
>> 21) & 0xf;
10697 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10698 shifter_out
, tmp
, tmp2
))
10700 tcg_temp_free_i32(tmp2
);
10701 rd
= (insn
>> 8) & 0xf;
10703 store_reg(s
, rd
, tmp
);
10705 tcg_temp_free_i32(tmp
);
10710 case 12: /* Load/store single data item. */
10715 if ((insn
& 0x01100000) == 0x01000000) {
10716 if (disas_neon_ls_insn(s
, insn
)) {
10721 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10723 if (!(insn
& (1 << 20))) {
10727 /* Byte or halfword load space with dest == r15 : memory hints.
10728 * Catch them early so we don't emit pointless addressing code.
10729 * This space is a mix of:
10730 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10731 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10733 * unallocated hints, which must be treated as NOPs
10734 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10735 * which is easiest for the decoding logic
10736 * Some space which must UNDEF
10738 int op1
= (insn
>> 23) & 3;
10739 int op2
= (insn
>> 6) & 0x3f;
10744 /* UNPREDICTABLE, unallocated hint or
10745 * PLD/PLDW/PLI (literal)
10750 return 0; /* PLD/PLDW/PLI or unallocated hint */
10752 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10753 return 0; /* PLD/PLDW/PLI or unallocated hint */
10755 /* UNDEF space, or an UNPREDICTABLE */
10759 memidx
= get_mem_index(s
);
10761 addr
= tcg_temp_new_i32();
10763 /* s->pc has already been incremented by 4. */
10764 imm
= s
->pc
& 0xfffffffc;
10765 if (insn
& (1 << 23))
10766 imm
+= insn
& 0xfff;
10768 imm
-= insn
& 0xfff;
10769 tcg_gen_movi_i32(addr
, imm
);
10771 addr
= load_reg(s
, rn
);
10772 if (insn
& (1 << 23)) {
10773 /* Positive offset. */
10774 imm
= insn
& 0xfff;
10775 tcg_gen_addi_i32(addr
, addr
, imm
);
10778 switch ((insn
>> 8) & 0xf) {
10779 case 0x0: /* Shifted Register. */
10780 shift
= (insn
>> 4) & 0xf;
10782 tcg_temp_free_i32(addr
);
10785 tmp
= load_reg(s
, rm
);
10787 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10788 tcg_gen_add_i32(addr
, addr
, tmp
);
10789 tcg_temp_free_i32(tmp
);
10791 case 0xc: /* Negative offset. */
10792 tcg_gen_addi_i32(addr
, addr
, -imm
);
10794 case 0xe: /* User privilege. */
10795 tcg_gen_addi_i32(addr
, addr
, imm
);
10796 memidx
= get_a32_user_mem_index(s
);
10798 case 0x9: /* Post-decrement. */
10800 /* Fall through. */
10801 case 0xb: /* Post-increment. */
10805 case 0xd: /* Pre-decrement. */
10807 /* Fall through. */
10808 case 0xf: /* Pre-increment. */
10809 tcg_gen_addi_i32(addr
, addr
, imm
);
10813 tcg_temp_free_i32(addr
);
10818 if (insn
& (1 << 20)) {
10820 tmp
= tcg_temp_new_i32();
10823 gen_aa32_ld8u(s
, tmp
, addr
, memidx
);
10826 gen_aa32_ld8s(s
, tmp
, addr
, memidx
);
10829 gen_aa32_ld16u(s
, tmp
, addr
, memidx
);
10832 gen_aa32_ld16s(s
, tmp
, addr
, memidx
);
10835 gen_aa32_ld32u(s
, tmp
, addr
, memidx
);
10838 tcg_temp_free_i32(tmp
);
10839 tcg_temp_free_i32(addr
);
10845 store_reg(s
, rs
, tmp
);
10849 tmp
= load_reg(s
, rs
);
10852 gen_aa32_st8(s
, tmp
, addr
, memidx
);
10855 gen_aa32_st16(s
, tmp
, addr
, memidx
);
10858 gen_aa32_st32(s
, tmp
, addr
, memidx
);
10861 tcg_temp_free_i32(tmp
);
10862 tcg_temp_free_i32(addr
);
10865 tcg_temp_free_i32(tmp
);
10868 tcg_gen_addi_i32(addr
, addr
, imm
);
10870 store_reg(s
, rn
, addr
);
10872 tcg_temp_free_i32(addr
);
10884 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10886 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10893 if (s
->condexec_mask
) {
10894 cond
= s
->condexec_cond
;
10895 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10896 s
->condlabel
= gen_new_label();
10897 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10902 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
10905 switch (insn
>> 12) {
10909 op
= (insn
>> 11) & 3;
10912 rn
= (insn
>> 3) & 7;
10913 tmp
= load_reg(s
, rn
);
10914 if (insn
& (1 << 10)) {
10916 tmp2
= tcg_temp_new_i32();
10917 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10920 rm
= (insn
>> 6) & 7;
10921 tmp2
= load_reg(s
, rm
);
10923 if (insn
& (1 << 9)) {
10924 if (s
->condexec_mask
)
10925 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10927 gen_sub_CC(tmp
, tmp
, tmp2
);
10929 if (s
->condexec_mask
)
10930 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10932 gen_add_CC(tmp
, tmp
, tmp2
);
10934 tcg_temp_free_i32(tmp2
);
10935 store_reg(s
, rd
, tmp
);
10937 /* shift immediate */
10938 rm
= (insn
>> 3) & 7;
10939 shift
= (insn
>> 6) & 0x1f;
10940 tmp
= load_reg(s
, rm
);
10941 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10942 if (!s
->condexec_mask
)
10944 store_reg(s
, rd
, tmp
);
10948 /* arithmetic large immediate */
10949 op
= (insn
>> 11) & 3;
10950 rd
= (insn
>> 8) & 0x7;
10951 if (op
== 0) { /* mov */
10952 tmp
= tcg_temp_new_i32();
10953 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10954 if (!s
->condexec_mask
)
10956 store_reg(s
, rd
, tmp
);
10958 tmp
= load_reg(s
, rd
);
10959 tmp2
= tcg_temp_new_i32();
10960 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10963 gen_sub_CC(tmp
, tmp
, tmp2
);
10964 tcg_temp_free_i32(tmp
);
10965 tcg_temp_free_i32(tmp2
);
10968 if (s
->condexec_mask
)
10969 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10971 gen_add_CC(tmp
, tmp
, tmp2
);
10972 tcg_temp_free_i32(tmp2
);
10973 store_reg(s
, rd
, tmp
);
10976 if (s
->condexec_mask
)
10977 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10979 gen_sub_CC(tmp
, tmp
, tmp2
);
10980 tcg_temp_free_i32(tmp2
);
10981 store_reg(s
, rd
, tmp
);
10987 if (insn
& (1 << 11)) {
10988 rd
= (insn
>> 8) & 7;
10989 /* load pc-relative. Bit 1 of PC is ignored. */
10990 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10991 val
&= ~(uint32_t)2;
10992 addr
= tcg_temp_new_i32();
10993 tcg_gen_movi_i32(addr
, val
);
10994 tmp
= tcg_temp_new_i32();
10995 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10996 tcg_temp_free_i32(addr
);
10997 store_reg(s
, rd
, tmp
);
11000 if (insn
& (1 << 10)) {
11001 /* data processing extended or blx */
11002 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11003 rm
= (insn
>> 3) & 0xf;
11004 op
= (insn
>> 8) & 3;
11007 tmp
= load_reg(s
, rd
);
11008 tmp2
= load_reg(s
, rm
);
11009 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11010 tcg_temp_free_i32(tmp2
);
11011 store_reg(s
, rd
, tmp
);
11014 tmp
= load_reg(s
, rd
);
11015 tmp2
= load_reg(s
, rm
);
11016 gen_sub_CC(tmp
, tmp
, tmp2
);
11017 tcg_temp_free_i32(tmp2
);
11018 tcg_temp_free_i32(tmp
);
11020 case 2: /* mov/cpy */
11021 tmp
= load_reg(s
, rm
);
11022 store_reg(s
, rd
, tmp
);
11024 case 3:/* branch [and link] exchange thumb register */
11025 tmp
= load_reg(s
, rm
);
11026 if (insn
& (1 << 7)) {
11028 val
= (uint32_t)s
->pc
| 1;
11029 tmp2
= tcg_temp_new_i32();
11030 tcg_gen_movi_i32(tmp2
, val
);
11031 store_reg(s
, 14, tmp2
);
11033 /* already thumb, no need to check */
11040 /* data processing register */
11042 rm
= (insn
>> 3) & 7;
11043 op
= (insn
>> 6) & 0xf;
11044 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11045 /* the shift/rotate ops want the operands backwards */
11054 if (op
== 9) { /* neg */
11055 tmp
= tcg_temp_new_i32();
11056 tcg_gen_movi_i32(tmp
, 0);
11057 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11058 tmp
= load_reg(s
, rd
);
11060 TCGV_UNUSED_I32(tmp
);
11063 tmp2
= load_reg(s
, rm
);
11065 case 0x0: /* and */
11066 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11067 if (!s
->condexec_mask
)
11070 case 0x1: /* eor */
11071 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11072 if (!s
->condexec_mask
)
11075 case 0x2: /* lsl */
11076 if (s
->condexec_mask
) {
11077 gen_shl(tmp2
, tmp2
, tmp
);
11079 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11080 gen_logic_CC(tmp2
);
11083 case 0x3: /* lsr */
11084 if (s
->condexec_mask
) {
11085 gen_shr(tmp2
, tmp2
, tmp
);
11087 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11088 gen_logic_CC(tmp2
);
11091 case 0x4: /* asr */
11092 if (s
->condexec_mask
) {
11093 gen_sar(tmp2
, tmp2
, tmp
);
11095 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11096 gen_logic_CC(tmp2
);
11099 case 0x5: /* adc */
11100 if (s
->condexec_mask
) {
11101 gen_adc(tmp
, tmp2
);
11103 gen_adc_CC(tmp
, tmp
, tmp2
);
11106 case 0x6: /* sbc */
11107 if (s
->condexec_mask
) {
11108 gen_sub_carry(tmp
, tmp
, tmp2
);
11110 gen_sbc_CC(tmp
, tmp
, tmp2
);
11113 case 0x7: /* ror */
11114 if (s
->condexec_mask
) {
11115 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11116 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11118 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11119 gen_logic_CC(tmp2
);
11122 case 0x8: /* tst */
11123 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11127 case 0x9: /* neg */
11128 if (s
->condexec_mask
)
11129 tcg_gen_neg_i32(tmp
, tmp2
);
11131 gen_sub_CC(tmp
, tmp
, tmp2
);
11133 case 0xa: /* cmp */
11134 gen_sub_CC(tmp
, tmp
, tmp2
);
11137 case 0xb: /* cmn */
11138 gen_add_CC(tmp
, tmp
, tmp2
);
11141 case 0xc: /* orr */
11142 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11143 if (!s
->condexec_mask
)
11146 case 0xd: /* mul */
11147 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11148 if (!s
->condexec_mask
)
11151 case 0xe: /* bic */
11152 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11153 if (!s
->condexec_mask
)
11156 case 0xf: /* mvn */
11157 tcg_gen_not_i32(tmp2
, tmp2
);
11158 if (!s
->condexec_mask
)
11159 gen_logic_CC(tmp2
);
11166 store_reg(s
, rm
, tmp2
);
11168 tcg_temp_free_i32(tmp
);
11170 store_reg(s
, rd
, tmp
);
11171 tcg_temp_free_i32(tmp2
);
11174 tcg_temp_free_i32(tmp
);
11175 tcg_temp_free_i32(tmp2
);
11180 /* load/store register offset. */
11182 rn
= (insn
>> 3) & 7;
11183 rm
= (insn
>> 6) & 7;
11184 op
= (insn
>> 9) & 7;
11185 addr
= load_reg(s
, rn
);
11186 tmp
= load_reg(s
, rm
);
11187 tcg_gen_add_i32(addr
, addr
, tmp
);
11188 tcg_temp_free_i32(tmp
);
11190 if (op
< 3) { /* store */
11191 tmp
= load_reg(s
, rd
);
11193 tmp
= tcg_temp_new_i32();
11198 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11201 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11204 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11206 case 3: /* ldrsb */
11207 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
11210 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11213 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11216 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11218 case 7: /* ldrsh */
11219 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
11222 if (op
>= 3) { /* load */
11223 store_reg(s
, rd
, tmp
);
11225 tcg_temp_free_i32(tmp
);
11227 tcg_temp_free_i32(addr
);
11231 /* load/store word immediate offset */
11233 rn
= (insn
>> 3) & 7;
11234 addr
= load_reg(s
, rn
);
11235 val
= (insn
>> 4) & 0x7c;
11236 tcg_gen_addi_i32(addr
, addr
, val
);
11238 if (insn
& (1 << 11)) {
11240 tmp
= tcg_temp_new_i32();
11241 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11242 store_reg(s
, rd
, tmp
);
11245 tmp
= load_reg(s
, rd
);
11246 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11247 tcg_temp_free_i32(tmp
);
11249 tcg_temp_free_i32(addr
);
11253 /* load/store byte immediate offset */
11255 rn
= (insn
>> 3) & 7;
11256 addr
= load_reg(s
, rn
);
11257 val
= (insn
>> 6) & 0x1f;
11258 tcg_gen_addi_i32(addr
, addr
, val
);
11260 if (insn
& (1 << 11)) {
11262 tmp
= tcg_temp_new_i32();
11263 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11264 store_reg(s
, rd
, tmp
);
11267 tmp
= load_reg(s
, rd
);
11268 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11269 tcg_temp_free_i32(tmp
);
11271 tcg_temp_free_i32(addr
);
11275 /* load/store halfword immediate offset */
11277 rn
= (insn
>> 3) & 7;
11278 addr
= load_reg(s
, rn
);
11279 val
= (insn
>> 5) & 0x3e;
11280 tcg_gen_addi_i32(addr
, addr
, val
);
11282 if (insn
& (1 << 11)) {
11284 tmp
= tcg_temp_new_i32();
11285 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11286 store_reg(s
, rd
, tmp
);
11289 tmp
= load_reg(s
, rd
);
11290 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11291 tcg_temp_free_i32(tmp
);
11293 tcg_temp_free_i32(addr
);
11297 /* load/store from stack */
11298 rd
= (insn
>> 8) & 7;
11299 addr
= load_reg(s
, 13);
11300 val
= (insn
& 0xff) * 4;
11301 tcg_gen_addi_i32(addr
, addr
, val
);
11303 if (insn
& (1 << 11)) {
11305 tmp
= tcg_temp_new_i32();
11306 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11307 store_reg(s
, rd
, tmp
);
11310 tmp
= load_reg(s
, rd
);
11311 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11312 tcg_temp_free_i32(tmp
);
11314 tcg_temp_free_i32(addr
);
11318 /* add to high reg */
11319 rd
= (insn
>> 8) & 7;
11320 if (insn
& (1 << 11)) {
11322 tmp
= load_reg(s
, 13);
11324 /* PC. bit 1 is ignored. */
11325 tmp
= tcg_temp_new_i32();
11326 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11328 val
= (insn
& 0xff) * 4;
11329 tcg_gen_addi_i32(tmp
, tmp
, val
);
11330 store_reg(s
, rd
, tmp
);
11335 op
= (insn
>> 8) & 0xf;
11338 /* adjust stack pointer */
11339 tmp
= load_reg(s
, 13);
11340 val
= (insn
& 0x7f) * 4;
11341 if (insn
& (1 << 7))
11342 val
= -(int32_t)val
;
11343 tcg_gen_addi_i32(tmp
, tmp
, val
);
11344 store_reg(s
, 13, tmp
);
11347 case 2: /* sign/zero extend. */
11350 rm
= (insn
>> 3) & 7;
11351 tmp
= load_reg(s
, rm
);
11352 switch ((insn
>> 6) & 3) {
11353 case 0: gen_sxth(tmp
); break;
11354 case 1: gen_sxtb(tmp
); break;
11355 case 2: gen_uxth(tmp
); break;
11356 case 3: gen_uxtb(tmp
); break;
11358 store_reg(s
, rd
, tmp
);
11360 case 4: case 5: case 0xc: case 0xd:
11362 addr
= load_reg(s
, 13);
11363 if (insn
& (1 << 8))
11367 for (i
= 0; i
< 8; i
++) {
11368 if (insn
& (1 << i
))
11371 if ((insn
& (1 << 11)) == 0) {
11372 tcg_gen_addi_i32(addr
, addr
, -offset
);
11374 for (i
= 0; i
< 8; i
++) {
11375 if (insn
& (1 << i
)) {
11376 if (insn
& (1 << 11)) {
11378 tmp
= tcg_temp_new_i32();
11379 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11380 store_reg(s
, i
, tmp
);
11383 tmp
= load_reg(s
, i
);
11384 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11385 tcg_temp_free_i32(tmp
);
11387 /* advance to the next address. */
11388 tcg_gen_addi_i32(addr
, addr
, 4);
11391 TCGV_UNUSED_I32(tmp
);
11392 if (insn
& (1 << 8)) {
11393 if (insn
& (1 << 11)) {
11395 tmp
= tcg_temp_new_i32();
11396 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11397 /* don't set the pc until the rest of the instruction
11401 tmp
= load_reg(s
, 14);
11402 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11403 tcg_temp_free_i32(tmp
);
11405 tcg_gen_addi_i32(addr
, addr
, 4);
11407 if ((insn
& (1 << 11)) == 0) {
11408 tcg_gen_addi_i32(addr
, addr
, -offset
);
11410 /* write back the new stack pointer */
11411 store_reg(s
, 13, addr
);
11412 /* set the new PC value */
11413 if ((insn
& 0x0900) == 0x0900) {
11414 store_reg_from_load(s
, 15, tmp
);
11418 case 1: case 3: case 9: case 11: /* czb */
11420 tmp
= load_reg(s
, rm
);
11421 s
->condlabel
= gen_new_label();
11423 if (insn
& (1 << 11))
11424 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11426 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11427 tcg_temp_free_i32(tmp
);
11428 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11429 val
= (uint32_t)s
->pc
+ 2;
11434 case 15: /* IT, nop-hint. */
11435 if ((insn
& 0xf) == 0) {
11436 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11440 s
->condexec_cond
= (insn
>> 4) & 0xe;
11441 s
->condexec_mask
= insn
& 0x1f;
11442 /* No actual code generated for this insn, just setup state. */
11445 case 0xe: /* bkpt */
11447 int imm8
= extract32(insn
, 0, 8);
11449 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11450 default_exception_el(s
));
11454 case 0xa: /* rev */
11456 rn
= (insn
>> 3) & 0x7;
11458 tmp
= load_reg(s
, rn
);
11459 switch ((insn
>> 6) & 3) {
11460 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11461 case 1: gen_rev16(tmp
); break;
11462 case 3: gen_revsh(tmp
); break;
11463 default: goto illegal_op
;
11465 store_reg(s
, rd
, tmp
);
11469 switch ((insn
>> 5) & 7) {
11473 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11474 gen_helper_setend(cpu_env
);
11475 s
->is_jmp
= DISAS_UPDATE
;
11484 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11485 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11488 addr
= tcg_const_i32(19);
11489 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11490 tcg_temp_free_i32(addr
);
11494 addr
= tcg_const_i32(16);
11495 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11496 tcg_temp_free_i32(addr
);
11498 tcg_temp_free_i32(tmp
);
11501 if (insn
& (1 << 4)) {
11502 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11506 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11521 /* load/store multiple */
11522 TCGv_i32 loaded_var
;
11523 TCGV_UNUSED_I32(loaded_var
);
11524 rn
= (insn
>> 8) & 0x7;
11525 addr
= load_reg(s
, rn
);
11526 for (i
= 0; i
< 8; i
++) {
11527 if (insn
& (1 << i
)) {
11528 if (insn
& (1 << 11)) {
11530 tmp
= tcg_temp_new_i32();
11531 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11535 store_reg(s
, i
, tmp
);
11539 tmp
= load_reg(s
, i
);
11540 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11541 tcg_temp_free_i32(tmp
);
11543 /* advance to the next address */
11544 tcg_gen_addi_i32(addr
, addr
, 4);
11547 if ((insn
& (1 << rn
)) == 0) {
11548 /* base reg not in list: base register writeback */
11549 store_reg(s
, rn
, addr
);
11551 /* base reg in list: if load, complete it now */
11552 if (insn
& (1 << 11)) {
11553 store_reg(s
, rn
, loaded_var
);
11555 tcg_temp_free_i32(addr
);
11560 /* conditional branch or swi */
11561 cond
= (insn
>> 8) & 0xf;
11567 gen_set_pc_im(s
, s
->pc
);
11568 s
->svc_imm
= extract32(insn
, 0, 8);
11569 s
->is_jmp
= DISAS_SWI
;
11572 /* generate a conditional jump to next instruction */
11573 s
->condlabel
= gen_new_label();
11574 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11577 /* jump to the offset */
11578 val
= (uint32_t)s
->pc
+ 2;
11579 offset
= ((int32_t)insn
<< 24) >> 24;
11580 val
+= offset
<< 1;
11585 if (insn
& (1 << 11)) {
11586 if (disas_thumb2_insn(env
, s
, insn
))
11590 /* unconditional branch */
11591 val
= (uint32_t)s
->pc
;
11592 offset
= ((int32_t)insn
<< 21) >> 21;
11593 val
+= (offset
<< 1) + 2;
11598 if (disas_thumb2_insn(env
, s
, insn
))
11604 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11605 default_exception_el(s
));
11609 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11610 default_exception_el(s
));
11613 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11615 /* Return true if the insn at dc->pc might cross a page boundary.
11616 * (False positives are OK, false negatives are not.)
11620 if ((s
->pc
& 3) == 0) {
11621 /* At a 4-aligned address we can't be crossing a page */
11625 /* This must be a Thumb insn */
11626 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11628 if ((insn
>> 11) >= 0x1d) {
11629 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11630 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11631 * end up actually treating this as two 16-bit insns (see the
11632 * code at the start of disas_thumb2_insn()) but we don't bother
11633 * to check for that as it is unlikely, and false positives here
11638 /* Definitely a 16-bit insn, can't be crossing a page. */
11642 /* generate intermediate code for basic block 'tb'. */
11643 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11645 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11646 CPUState
*cs
= CPU(cpu
);
11647 DisasContext dc1
, *dc
= &dc1
;
11648 target_ulong pc_start
;
11649 target_ulong next_page_start
;
11654 /* generate intermediate code */
11656 /* The A64 decoder has its own top level loop, because it doesn't need
11657 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11659 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11660 gen_intermediate_code_a64(cpu
, tb
);
11668 dc
->is_jmp
= DISAS_NEXT
;
11670 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11674 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11675 * there is no secure EL1, so we route exceptions to EL3.
11677 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11678 !arm_el_is_aa64(env
, 3);
11679 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11680 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(tb
->flags
);
11681 dc
->be_data
= ARM_TBFLAG_BE_DATA(tb
->flags
) ? MO_BE
: MO_LE
;
11682 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11683 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11684 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11685 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11686 #if !defined(CONFIG_USER_ONLY)
11687 dc
->user
= (dc
->current_el
== 0);
11689 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11690 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11691 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11692 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11693 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11694 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11695 dc
->cp_regs
= cpu
->cp_regs
;
11696 dc
->features
= env
->features
;
11698 /* Single step state. The code-generation logic here is:
11700 * generate code with no special handling for single-stepping (except
11701 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11702 * this happens anyway because those changes are all system register or
11704 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11705 * emit code for one insn
11706 * emit code to clear PSTATE.SS
11707 * emit code to generate software step exception for completed step
11708 * end TB (as usual for having generated an exception)
11709 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11710 * emit code to generate a software step exception
11713 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11714 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11715 dc
->is_ldex
= false;
11716 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11718 cpu_F0s
= tcg_temp_new_i32();
11719 cpu_F1s
= tcg_temp_new_i32();
11720 cpu_F0d
= tcg_temp_new_i64();
11721 cpu_F1d
= tcg_temp_new_i64();
11724 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11725 cpu_M0
= tcg_temp_new_i64();
11726 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11728 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11729 if (max_insns
== 0) {
11730 max_insns
= CF_COUNT_MASK
;
11732 if (max_insns
> TCG_MAX_INSNS
) {
11733 max_insns
= TCG_MAX_INSNS
;
11738 tcg_clear_temp_count();
11740 /* A note on handling of the condexec (IT) bits:
11742 * We want to avoid the overhead of having to write the updated condexec
11743 * bits back to the CPUARMState for every instruction in an IT block. So:
11744 * (1) if the condexec bits are not already zero then we write
11745 * zero back into the CPUARMState now. This avoids complications trying
11746 * to do it at the end of the block. (For example if we don't do this
11747 * it's hard to identify whether we can safely skip writing condexec
11748 * at the end of the TB, which we definitely want to do for the case
11749 * where a TB doesn't do anything with the IT state at all.)
11750 * (2) if we are going to leave the TB then we call gen_set_condexec()
11751 * which will write the correct value into CPUARMState if zero is wrong.
11752 * This is done both for leaving the TB at the end, and for leaving
11753 * it because of an exception we know will happen, which is done in
11754 * gen_exception_insn(). The latter is necessary because we need to
11755 * leave the TB with the PC/IT state just prior to execution of the
11756 * instruction which caused the exception.
11757 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11758 * then the CPUARMState will be wrong and we need to reset it.
11759 * This is handled in the same way as restoration of the
11760 * PC in these situations; we save the value of the condexec bits
11761 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11762 * then uses this to restore them after an exception.
11764 * Note that there are no instructions which can read the condexec
11765 * bits, and none which can write non-static values to them, so
11766 * we don't need to care about whether CPUARMState is correct in the
11770 /* Reset the conditional execution bits immediately. This avoids
11771 complications trying to do it at the end of the block. */
11772 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11774 TCGv_i32 tmp
= tcg_temp_new_i32();
11775 tcg_gen_movi_i32(tmp
, 0);
11776 store_cpu_field(tmp
, condexec_bits
);
11779 tcg_gen_insn_start(dc
->pc
,
11780 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11784 #ifdef CONFIG_USER_ONLY
11785 /* Intercept jump to the magic kernel page. */
11786 if (dc
->pc
>= 0xffff0000) {
11787 /* We always get here via a jump, so know we are not in a
11788 conditional execution block. */
11789 gen_exception_internal(EXCP_KERNEL_TRAP
);
11790 dc
->is_jmp
= DISAS_EXC
;
11794 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11795 /* We always get here via a jump, so know we are not in a
11796 conditional execution block. */
11797 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11798 dc
->is_jmp
= DISAS_EXC
;
11803 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11805 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11806 if (bp
->pc
== dc
->pc
) {
11807 if (bp
->flags
& BP_CPU
) {
11808 gen_set_condexec(dc
);
11809 gen_set_pc_im(dc
, dc
->pc
);
11810 gen_helper_check_breakpoints(cpu_env
);
11811 /* End the TB early; it's likely not going to be executed */
11812 dc
->is_jmp
= DISAS_UPDATE
;
11814 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11815 /* The address covered by the breakpoint must be
11816 included in [tb->pc, tb->pc + tb->size) in order
11817 to for it to be properly cleared -- thus we
11818 increment the PC here so that the logic setting
11819 tb->size below does the right thing. */
11820 /* TODO: Advance PC by correct instruction length to
11821 * avoid disassembler error messages */
11823 goto done_generating
;
11830 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11834 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11835 /* Singlestep state is Active-pending.
11836 * If we're in this state at the start of a TB then either
11837 * a) we just took an exception to an EL which is being debugged
11838 * and this is the first insn in the exception handler
11839 * b) debug exceptions were masked and we just unmasked them
11840 * without changing EL (eg by clearing PSTATE.D)
11841 * In either case we're going to take a swstep exception in the
11842 * "did not step an insn" case, and so the syndrome ISV and EX
11843 * bits should be zero.
11845 assert(num_insns
== 1);
11846 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11847 default_exception_el(dc
));
11848 goto done_generating
;
11852 disas_thumb_insn(env
, dc
);
11853 if (dc
->condexec_mask
) {
11854 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11855 | ((dc
->condexec_mask
>> 4) & 1);
11856 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11857 if (dc
->condexec_mask
== 0) {
11858 dc
->condexec_cond
= 0;
11862 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
11864 disas_arm_insn(dc
, insn
);
11867 if (dc
->condjmp
&& !dc
->is_jmp
) {
11868 gen_set_label(dc
->condlabel
);
11872 if (tcg_check_temp_count()) {
11873 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11877 /* Translation stops when a conditional branch is encountered.
11878 * Otherwise the subsequent code could get translated several times.
11879 * Also stop translation when a page boundary is reached. This
11880 * ensures prefetch aborts occur at the right place. */
11882 /* We want to stop the TB if the next insn starts in a new page,
11883 * or if it spans between this page and the next. This means that
11884 * if we're looking at the last halfword in the page we need to
11885 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11886 * or a 32-bit Thumb insn (which won't).
11887 * This is to avoid generating a silly TB with a single 16-bit insn
11888 * in it at the end of this page (which would execute correctly
11889 * but isn't very efficient).
11891 end_of_page
= (dc
->pc
>= next_page_start
) ||
11892 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
11894 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11895 !cs
->singlestep_enabled
&&
11899 num_insns
< max_insns
);
11901 if (tb
->cflags
& CF_LAST_IO
) {
11903 /* FIXME: This can theoretically happen with self-modifying
11905 cpu_abort(cs
, "IO on conditional branch instruction");
11910 /* At this stage dc->condjmp will only be set when the skipped
11911 instruction was a conditional branch or trap, and the PC has
11912 already been written. */
11913 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11914 /* Unconditional and "condition passed" instruction codepath. */
11915 gen_set_condexec(dc
);
11916 switch (dc
->is_jmp
) {
11918 gen_ss_advance(dc
);
11919 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11920 default_exception_el(dc
));
11923 gen_ss_advance(dc
);
11924 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11927 gen_ss_advance(dc
);
11928 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11932 gen_set_pc_im(dc
, dc
->pc
);
11935 if (dc
->ss_active
) {
11936 gen_step_complete_exception(dc
);
11938 /* FIXME: Single stepping a WFI insn will not halt
11940 gen_exception_internal(EXCP_DEBUG
);
11944 /* "Condition failed" instruction codepath. */
11945 gen_set_label(dc
->condlabel
);
11946 gen_set_condexec(dc
);
11947 gen_set_pc_im(dc
, dc
->pc
);
11948 if (dc
->ss_active
) {
11949 gen_step_complete_exception(dc
);
11951 gen_exception_internal(EXCP_DEBUG
);
11955 /* While branches must always occur at the end of an IT block,
11956 there are a few other things that can cause us to terminate
11957 the TB in the middle of an IT block:
11958 - Exception generating instructions (bkpt, swi, undefined).
11960 - Hardware watchpoints.
11961 Hardware breakpoints have already been handled and skip this code.
11963 gen_set_condexec(dc
);
11964 switch(dc
->is_jmp
) {
11966 gen_goto_tb(dc
, 1, dc
->pc
);
11969 gen_set_pc_im(dc
, dc
->pc
);
11973 /* indicate that the hash table must be used to find the next TB */
11974 tcg_gen_exit_tb(0);
11976 case DISAS_TB_JUMP
:
11977 /* nothing more to generate */
11980 gen_helper_wfi(cpu_env
);
11981 /* The helper doesn't necessarily throw an exception, but we
11982 * must go back to the main loop to check for interrupts anyway.
11984 tcg_gen_exit_tb(0);
11987 gen_helper_wfe(cpu_env
);
11990 gen_helper_yield(cpu_env
);
11993 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11994 default_exception_el(dc
));
11997 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12000 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12004 gen_set_label(dc
->condlabel
);
12005 gen_set_condexec(dc
);
12006 gen_goto_tb(dc
, 1, dc
->pc
);
12012 gen_tb_end(tb
, num_insns
);
12015 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
) &&
12016 qemu_log_in_addr_range(pc_start
)) {
12017 qemu_log("----------------\n");
12018 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
12019 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
12020 dc
->thumb
| (dc
->sctlr_b
<< 1));
12024 tb
->size
= dc
->pc
- pc_start
;
12025 tb
->icount
= num_insns
;
12028 static const char *cpu_mode_names
[16] = {
12029 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12030 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12033 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12036 ARMCPU
*cpu
= ARM_CPU(cs
);
12037 CPUARMState
*env
= &cpu
->env
;
12040 const char *ns_status
;
12043 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12047 for(i
=0;i
<16;i
++) {
12048 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12050 cpu_fprintf(f
, "\n");
12052 cpu_fprintf(f
, " ");
12054 psr
= cpsr_read(env
);
12056 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12057 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12058 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12063 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12065 psr
& (1 << 31) ? 'N' : '-',
12066 psr
& (1 << 30) ? 'Z' : '-',
12067 psr
& (1 << 29) ? 'C' : '-',
12068 psr
& (1 << 28) ? 'V' : '-',
12069 psr
& CPSR_T
? 'T' : 'A',
12071 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12073 if (flags
& CPU_DUMP_FPU
) {
12074 int numvfpregs
= 0;
12075 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12078 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12081 for (i
= 0; i
< numvfpregs
; i
++) {
12082 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12083 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12084 i
* 2, (uint32_t)v
,
12085 i
* 2 + 1, (uint32_t)(v
>> 32),
12088 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12092 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12093 target_ulong
*data
)
12097 env
->condexec_bits
= 0;
12098 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12100 env
->regs
[15] = data
[0];
12101 env
->condexec_bits
= data
[1];
12102 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;