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"
28 #include "qemu/bitops.h"
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
34 #include "trace-tcg.h"
38 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
39 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
40 /* currently all emulated v5 cores are also v5TE, so don't bother */
41 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
42 #define ENABLE_ARCH_5J 0
43 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
44 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
45 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
46 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
47 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
49 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
51 #include "translate.h"
53 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) (s->user)
60 /* We reuse the same 64-bit temporaries for efficiency. */
61 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
62 static TCGv_i32 cpu_R
[16];
63 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
64 TCGv_i64 cpu_exclusive_addr
;
65 TCGv_i64 cpu_exclusive_val
;
66 #ifdef CONFIG_USER_ONLY
67 TCGv_i64 cpu_exclusive_test
;
68 TCGv_i32 cpu_exclusive_info
;
71 /* FIXME: These should be removed. */
72 static TCGv_i32 cpu_F0s
, cpu_F1s
;
73 static TCGv_i64 cpu_F0d
, cpu_F1d
;
75 #include "exec/gen-icount.h"
77 static const char *regnames
[] =
78 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
79 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
86 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
88 for (i
= 0; i
< 16; i
++) {
89 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
90 offsetof(CPUARMState
, regs
[i
]),
93 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
94 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
95 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
96 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
98 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
99 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
100 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
101 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
102 #ifdef CONFIG_USER_ONLY
103 cpu_exclusive_test
= tcg_global_mem_new_i64(cpu_env
,
104 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
105 cpu_exclusive_info
= tcg_global_mem_new_i32(cpu_env
,
106 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
109 a64_translate_init();
112 static inline ARMMMUIdx
get_a32_user_mem_index(DisasContext
*s
)
114 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
116 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
117 * otherwise, access as if at PL0.
119 switch (s
->mmu_idx
) {
120 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
121 case ARMMMUIdx_S12NSE0
:
122 case ARMMMUIdx_S12NSE1
:
123 return ARMMMUIdx_S12NSE0
;
125 case ARMMMUIdx_S1SE0
:
126 case ARMMMUIdx_S1SE1
:
127 return ARMMMUIdx_S1SE0
;
130 g_assert_not_reached();
134 static inline TCGv_i32
load_cpu_offset(int offset
)
136 TCGv_i32 tmp
= tcg_temp_new_i32();
137 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
141 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
143 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
145 tcg_gen_st_i32(var
, cpu_env
, offset
);
146 tcg_temp_free_i32(var
);
149 #define store_cpu_field(var, name) \
150 store_cpu_offset(var, offsetof(CPUARMState, name))
152 /* Set a variable to the value of a CPU register. */
153 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
157 /* normally, since we updated PC, we need only to add one insn */
159 addr
= (long)s
->pc
+ 2;
161 addr
= (long)s
->pc
+ 4;
162 tcg_gen_movi_i32(var
, addr
);
164 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
168 /* Create a new temporary and set it to the value of a CPU register. */
169 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
171 TCGv_i32 tmp
= tcg_temp_new_i32();
172 load_reg_var(s
, tmp
, reg
);
176 /* Set a CPU register. The source must be a temporary and will be
178 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
181 tcg_gen_andi_i32(var
, var
, ~1);
182 s
->is_jmp
= DISAS_JUMP
;
184 tcg_gen_mov_i32(cpu_R
[reg
], var
);
185 tcg_temp_free_i32(var
);
188 /* Value extensions. */
189 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
190 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
191 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
192 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
194 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
195 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
198 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
200 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
201 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
202 tcg_temp_free_i32(tmp_mask
);
204 /* Set NZCV flags from the high 4 bits of var. */
205 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
207 static void gen_exception_internal(int excp
)
209 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
211 assert(excp_is_internal(excp
));
212 gen_helper_exception_internal(cpu_env
, tcg_excp
);
213 tcg_temp_free_i32(tcg_excp
);
216 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
218 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
219 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
220 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
222 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
225 tcg_temp_free_i32(tcg_el
);
226 tcg_temp_free_i32(tcg_syn
);
227 tcg_temp_free_i32(tcg_excp
);
230 static void gen_ss_advance(DisasContext
*s
)
232 /* If the singlestep state is Active-not-pending, advance to
237 gen_helper_clear_pstate_ss(cpu_env
);
241 static void gen_step_complete_exception(DisasContext
*s
)
243 /* We just completed step of an insn. Move from Active-not-pending
244 * to Active-pending, and then also take the swstep exception.
245 * This corresponds to making the (IMPDEF) choice to prioritize
246 * swstep exceptions over asynchronous exceptions taken to an exception
247 * level where debug is disabled. This choice has the advantage that
248 * we do not need to maintain internal state corresponding to the
249 * ISV/EX syndrome bits between completion of the step and generation
250 * of the exception, and our syndrome information is always correct.
253 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
254 default_exception_el(s
));
255 s
->is_jmp
= DISAS_EXC
;
258 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
260 TCGv_i32 tmp1
= tcg_temp_new_i32();
261 TCGv_i32 tmp2
= tcg_temp_new_i32();
262 tcg_gen_ext16s_i32(tmp1
, a
);
263 tcg_gen_ext16s_i32(tmp2
, b
);
264 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
265 tcg_temp_free_i32(tmp2
);
266 tcg_gen_sari_i32(a
, a
, 16);
267 tcg_gen_sari_i32(b
, b
, 16);
268 tcg_gen_mul_i32(b
, b
, a
);
269 tcg_gen_mov_i32(a
, tmp1
);
270 tcg_temp_free_i32(tmp1
);
273 /* Byteswap each halfword. */
274 static void gen_rev16(TCGv_i32 var
)
276 TCGv_i32 tmp
= tcg_temp_new_i32();
277 tcg_gen_shri_i32(tmp
, var
, 8);
278 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
279 tcg_gen_shli_i32(var
, var
, 8);
280 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
281 tcg_gen_or_i32(var
, var
, tmp
);
282 tcg_temp_free_i32(tmp
);
285 /* Byteswap low halfword and sign extend. */
286 static void gen_revsh(TCGv_i32 var
)
288 tcg_gen_ext16u_i32(var
, var
);
289 tcg_gen_bswap16_i32(var
, var
);
290 tcg_gen_ext16s_i32(var
, var
);
293 /* Unsigned bitfield extract. */
294 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
297 tcg_gen_shri_i32(var
, var
, shift
);
298 tcg_gen_andi_i32(var
, var
, mask
);
301 /* Signed bitfield extract. */
302 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
307 tcg_gen_sari_i32(var
, var
, shift
);
308 if (shift
+ width
< 32) {
309 signbit
= 1u << (width
- 1);
310 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
311 tcg_gen_xori_i32(var
, var
, signbit
);
312 tcg_gen_subi_i32(var
, var
, signbit
);
316 /* Return (b << 32) + a. Mark inputs as dead */
317 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
319 TCGv_i64 tmp64
= tcg_temp_new_i64();
321 tcg_gen_extu_i32_i64(tmp64
, b
);
322 tcg_temp_free_i32(b
);
323 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
324 tcg_gen_add_i64(a
, tmp64
, a
);
326 tcg_temp_free_i64(tmp64
);
330 /* Return (b << 32) - a. Mark inputs as dead. */
331 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
333 TCGv_i64 tmp64
= tcg_temp_new_i64();
335 tcg_gen_extu_i32_i64(tmp64
, b
);
336 tcg_temp_free_i32(b
);
337 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
338 tcg_gen_sub_i64(a
, tmp64
, a
);
340 tcg_temp_free_i64(tmp64
);
344 /* 32x32->64 multiply. Marks inputs as dead. */
345 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
347 TCGv_i32 lo
= tcg_temp_new_i32();
348 TCGv_i32 hi
= tcg_temp_new_i32();
351 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
352 tcg_temp_free_i32(a
);
353 tcg_temp_free_i32(b
);
355 ret
= tcg_temp_new_i64();
356 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
357 tcg_temp_free_i32(lo
);
358 tcg_temp_free_i32(hi
);
363 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
365 TCGv_i32 lo
= tcg_temp_new_i32();
366 TCGv_i32 hi
= tcg_temp_new_i32();
369 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
370 tcg_temp_free_i32(a
);
371 tcg_temp_free_i32(b
);
373 ret
= tcg_temp_new_i64();
374 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
375 tcg_temp_free_i32(lo
);
376 tcg_temp_free_i32(hi
);
381 /* Swap low and high halfwords. */
382 static void gen_swap_half(TCGv_i32 var
)
384 TCGv_i32 tmp
= tcg_temp_new_i32();
385 tcg_gen_shri_i32(tmp
, var
, 16);
386 tcg_gen_shli_i32(var
, var
, 16);
387 tcg_gen_or_i32(var
, var
, tmp
);
388 tcg_temp_free_i32(tmp
);
391 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
392 tmp = (t0 ^ t1) & 0x8000;
395 t0 = (t0 + t1) ^ tmp;
398 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
400 TCGv_i32 tmp
= tcg_temp_new_i32();
401 tcg_gen_xor_i32(tmp
, t0
, t1
);
402 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
403 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
404 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
405 tcg_gen_add_i32(t0
, t0
, t1
);
406 tcg_gen_xor_i32(t0
, t0
, tmp
);
407 tcg_temp_free_i32(tmp
);
408 tcg_temp_free_i32(t1
);
411 /* Set CF to the top bit of var. */
412 static void gen_set_CF_bit31(TCGv_i32 var
)
414 tcg_gen_shri_i32(cpu_CF
, var
, 31);
417 /* Set N and Z flags from var. */
418 static inline void gen_logic_CC(TCGv_i32 var
)
420 tcg_gen_mov_i32(cpu_NF
, var
);
421 tcg_gen_mov_i32(cpu_ZF
, var
);
425 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
427 tcg_gen_add_i32(t0
, t0
, t1
);
428 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
431 /* dest = T0 + T1 + CF. */
432 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
434 tcg_gen_add_i32(dest
, t0
, t1
);
435 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
438 /* dest = T0 - T1 + CF - 1. */
439 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
441 tcg_gen_sub_i32(dest
, t0
, t1
);
442 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
443 tcg_gen_subi_i32(dest
, dest
, 1);
446 /* dest = T0 + T1. Compute C, N, V and Z flags */
447 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
449 TCGv_i32 tmp
= tcg_temp_new_i32();
450 tcg_gen_movi_i32(tmp
, 0);
451 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
452 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
453 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
454 tcg_gen_xor_i32(tmp
, t0
, t1
);
455 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
456 tcg_temp_free_i32(tmp
);
457 tcg_gen_mov_i32(dest
, cpu_NF
);
460 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
461 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
463 TCGv_i32 tmp
= tcg_temp_new_i32();
464 if (TCG_TARGET_HAS_add2_i32
) {
465 tcg_gen_movi_i32(tmp
, 0);
466 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
467 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
469 TCGv_i64 q0
= tcg_temp_new_i64();
470 TCGv_i64 q1
= tcg_temp_new_i64();
471 tcg_gen_extu_i32_i64(q0
, t0
);
472 tcg_gen_extu_i32_i64(q1
, t1
);
473 tcg_gen_add_i64(q0
, q0
, q1
);
474 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
475 tcg_gen_add_i64(q0
, q0
, q1
);
476 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
477 tcg_temp_free_i64(q0
);
478 tcg_temp_free_i64(q1
);
480 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
481 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
482 tcg_gen_xor_i32(tmp
, t0
, t1
);
483 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
484 tcg_temp_free_i32(tmp
);
485 tcg_gen_mov_i32(dest
, cpu_NF
);
488 /* dest = T0 - T1. Compute C, N, V and Z flags */
489 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
492 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
493 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
494 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
495 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
496 tmp
= tcg_temp_new_i32();
497 tcg_gen_xor_i32(tmp
, t0
, t1
);
498 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
499 tcg_temp_free_i32(tmp
);
500 tcg_gen_mov_i32(dest
, cpu_NF
);
503 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
504 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
506 TCGv_i32 tmp
= tcg_temp_new_i32();
507 tcg_gen_not_i32(tmp
, t1
);
508 gen_adc_CC(dest
, t0
, tmp
);
509 tcg_temp_free_i32(tmp
);
512 #define GEN_SHIFT(name) \
513 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
515 TCGv_i32 tmp1, tmp2, tmp3; \
516 tmp1 = tcg_temp_new_i32(); \
517 tcg_gen_andi_i32(tmp1, t1, 0xff); \
518 tmp2 = tcg_const_i32(0); \
519 tmp3 = tcg_const_i32(0x1f); \
520 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
521 tcg_temp_free_i32(tmp3); \
522 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
523 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
524 tcg_temp_free_i32(tmp2); \
525 tcg_temp_free_i32(tmp1); \
531 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
534 tmp1
= tcg_temp_new_i32();
535 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
536 tmp2
= tcg_const_i32(0x1f);
537 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
538 tcg_temp_free_i32(tmp2
);
539 tcg_gen_sar_i32(dest
, t0
, tmp1
);
540 tcg_temp_free_i32(tmp1
);
543 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
545 TCGv_i32 c0
= tcg_const_i32(0);
546 TCGv_i32 tmp
= tcg_temp_new_i32();
547 tcg_gen_neg_i32(tmp
, src
);
548 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
549 tcg_temp_free_i32(c0
);
550 tcg_temp_free_i32(tmp
);
553 static void shifter_out_im(TCGv_i32 var
, int shift
)
556 tcg_gen_andi_i32(cpu_CF
, var
, 1);
558 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
560 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
565 /* Shift by immediate. Includes special handling for shift == 0. */
566 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
567 int shift
, int flags
)
573 shifter_out_im(var
, 32 - shift
);
574 tcg_gen_shli_i32(var
, var
, shift
);
580 tcg_gen_shri_i32(cpu_CF
, var
, 31);
582 tcg_gen_movi_i32(var
, 0);
585 shifter_out_im(var
, shift
- 1);
586 tcg_gen_shri_i32(var
, var
, shift
);
593 shifter_out_im(var
, shift
- 1);
596 tcg_gen_sari_i32(var
, var
, shift
);
598 case 3: /* ROR/RRX */
601 shifter_out_im(var
, shift
- 1);
602 tcg_gen_rotri_i32(var
, var
, shift
); break;
604 TCGv_i32 tmp
= tcg_temp_new_i32();
605 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
607 shifter_out_im(var
, 0);
608 tcg_gen_shri_i32(var
, var
, 1);
609 tcg_gen_or_i32(var
, var
, tmp
);
610 tcg_temp_free_i32(tmp
);
615 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
616 TCGv_i32 shift
, int flags
)
620 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
621 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
622 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
623 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
628 gen_shl(var
, var
, shift
);
631 gen_shr(var
, var
, shift
);
634 gen_sar(var
, var
, shift
);
636 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
637 tcg_gen_rotr_i32(var
, var
, shift
); break;
640 tcg_temp_free_i32(shift
);
643 #define PAS_OP(pfx) \
645 case 0: gen_pas_helper(glue(pfx,add16)); break; \
646 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
647 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
648 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
649 case 4: gen_pas_helper(glue(pfx,add8)); break; \
650 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
652 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
657 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
659 tmp
= tcg_temp_new_ptr();
660 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
662 tcg_temp_free_ptr(tmp
);
665 tmp
= tcg_temp_new_ptr();
666 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
668 tcg_temp_free_ptr(tmp
);
670 #undef gen_pas_helper
671 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
684 #undef gen_pas_helper
689 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
690 #define PAS_OP(pfx) \
692 case 0: gen_pas_helper(glue(pfx,add8)); break; \
693 case 1: gen_pas_helper(glue(pfx,add16)); break; \
694 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
695 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
696 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
697 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
699 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
704 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
706 tmp
= tcg_temp_new_ptr();
707 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
709 tcg_temp_free_ptr(tmp
);
712 tmp
= tcg_temp_new_ptr();
713 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
715 tcg_temp_free_ptr(tmp
);
717 #undef gen_pas_helper
718 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
731 #undef gen_pas_helper
737 * Generate a conditional based on ARM condition code cc.
738 * This is common between ARM and Aarch64 targets.
740 void arm_test_cc(DisasCompare
*cmp
, int cc
)
771 case 8: /* hi: C && !Z */
772 case 9: /* ls: !C || Z -> !(C && !Z) */
774 value
= tcg_temp_new_i32();
776 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
777 ZF is non-zero for !Z; so AND the two subexpressions. */
778 tcg_gen_neg_i32(value
, cpu_CF
);
779 tcg_gen_and_i32(value
, value
, cpu_ZF
);
782 case 10: /* ge: N == V -> N ^ V == 0 */
783 case 11: /* lt: N != V -> N ^ V != 0 */
784 /* Since we're only interested in the sign bit, == 0 is >= 0. */
786 value
= tcg_temp_new_i32();
788 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
791 case 12: /* gt: !Z && N == V */
792 case 13: /* le: Z || N != V */
794 value
= tcg_temp_new_i32();
796 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
797 * the sign bit then AND with ZF to yield the result. */
798 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
799 tcg_gen_sari_i32(value
, value
, 31);
800 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
803 case 14: /* always */
804 case 15: /* always */
805 /* Use the ALWAYS condition, which will fold early.
806 * It doesn't matter what we use for the value. */
807 cond
= TCG_COND_ALWAYS
;
812 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
817 cond
= tcg_invert_cond(cond
);
823 cmp
->value_global
= global
;
826 void arm_free_cc(DisasCompare
*cmp
)
828 if (!cmp
->value_global
) {
829 tcg_temp_free_i32(cmp
->value
);
833 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
835 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
838 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
841 arm_test_cc(&cmp
, cc
);
842 arm_jump_cc(&cmp
, label
);
846 static const uint8_t table_logic_cc
[16] = {
865 /* Set PC and Thumb state from an immediate address. */
866 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
870 s
->is_jmp
= DISAS_JUMP
;
871 if (s
->thumb
!= (addr
& 1)) {
872 tmp
= tcg_temp_new_i32();
873 tcg_gen_movi_i32(tmp
, addr
& 1);
874 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
875 tcg_temp_free_i32(tmp
);
877 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
880 /* Set PC and Thumb state from var. var is marked as dead. */
881 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
883 s
->is_jmp
= DISAS_JUMP
;
884 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
885 tcg_gen_andi_i32(var
, var
, 1);
886 store_cpu_field(var
, thumb
);
889 /* Variant of store_reg which uses branch&exchange logic when storing
890 to r15 in ARM architecture v7 and above. The source must be a temporary
891 and will be marked as dead. */
892 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
894 if (reg
== 15 && ENABLE_ARCH_7
) {
897 store_reg(s
, reg
, var
);
901 /* Variant of store_reg which uses branch&exchange logic when storing
902 * to r15 in ARM architecture v5T and above. This is used for storing
903 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
904 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
905 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
907 if (reg
== 15 && ENABLE_ARCH_5
) {
910 store_reg(s
, reg
, var
);
914 /* Abstractions of "generate code to do a guest load/store for
915 * AArch32", where a vaddr is always 32 bits (and is zero
916 * extended if we're a 64 bit core) and data is also
917 * 32 bits unless specifically doing a 64 bit access.
918 * These functions work like tcg_gen_qemu_{ld,st}* except
919 * that the address argument is TCGv_i32 rather than TCGv.
921 #if TARGET_LONG_BITS == 32
923 #define DO_GEN_LD(SUFF, OPC) \
924 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
925 TCGv_i32 addr, int index) \
927 tcg_gen_qemu_ld_i32(val, addr, index, (OPC)); \
930 #define DO_GEN_ST(SUFF, OPC) \
931 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
932 TCGv_i32 addr, int index) \
934 tcg_gen_qemu_st_i32(val, addr, index, (OPC)); \
937 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
938 TCGv_i32 addr
, int index
)
940 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
943 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
944 TCGv_i32 addr
, int index
)
946 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
951 #define DO_GEN_LD(SUFF, OPC) \
952 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
953 TCGv_i32 addr, int index) \
955 TCGv addr64 = tcg_temp_new(); \
956 tcg_gen_extu_i32_i64(addr64, addr); \
957 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
958 tcg_temp_free(addr64); \
961 #define DO_GEN_ST(SUFF, OPC) \
962 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
963 TCGv_i32 addr, int index) \
965 TCGv addr64 = tcg_temp_new(); \
966 tcg_gen_extu_i32_i64(addr64, addr); \
967 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
968 tcg_temp_free(addr64); \
971 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
972 TCGv_i32 addr
, int index
)
974 TCGv addr64
= tcg_temp_new();
975 tcg_gen_extu_i32_i64(addr64
, addr
);
976 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
977 tcg_temp_free(addr64
);
980 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
981 TCGv_i32 addr
, int index
)
983 TCGv addr64
= tcg_temp_new();
984 tcg_gen_extu_i32_i64(addr64
, addr
);
985 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
986 tcg_temp_free(addr64
);
993 DO_GEN_LD(16s
, MO_TESW
)
994 DO_GEN_LD(16u, MO_TEUW
)
995 DO_GEN_LD(32u, MO_TEUL
)
996 /* 'a' variants include an alignment check */
997 DO_GEN_LD(16ua
, MO_TEUW
| MO_ALIGN
)
998 DO_GEN_LD(32ua
, MO_TEUL
| MO_ALIGN
)
1000 DO_GEN_ST(16, MO_TEUW
)
1001 DO_GEN_ST(32, MO_TEUL
)
1003 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
1005 tcg_gen_movi_i32(cpu_R
[15], val
);
1008 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1010 /* The pre HVC helper handles cases when HVC gets trapped
1011 * as an undefined insn by runtime configuration (ie before
1012 * the insn really executes).
1014 gen_set_pc_im(s
, s
->pc
- 4);
1015 gen_helper_pre_hvc(cpu_env
);
1016 /* Otherwise we will treat this as a real exception which
1017 * happens after execution of the insn. (The distinction matters
1018 * for the PC value reported to the exception handler and also
1019 * for single stepping.)
1022 gen_set_pc_im(s
, s
->pc
);
1023 s
->is_jmp
= DISAS_HVC
;
1026 static inline void gen_smc(DisasContext
*s
)
1028 /* As with HVC, we may take an exception either before or after
1029 * the insn executes.
1033 gen_set_pc_im(s
, s
->pc
- 4);
1034 tmp
= tcg_const_i32(syn_aa32_smc());
1035 gen_helper_pre_smc(cpu_env
, tmp
);
1036 tcg_temp_free_i32(tmp
);
1037 gen_set_pc_im(s
, s
->pc
);
1038 s
->is_jmp
= DISAS_SMC
;
1042 gen_set_condexec (DisasContext
*s
)
1044 if (s
->condexec_mask
) {
1045 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1046 TCGv_i32 tmp
= tcg_temp_new_i32();
1047 tcg_gen_movi_i32(tmp
, val
);
1048 store_cpu_field(tmp
, condexec_bits
);
1052 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1054 gen_set_condexec(s
);
1055 gen_set_pc_im(s
, s
->pc
- offset
);
1056 gen_exception_internal(excp
);
1057 s
->is_jmp
= DISAS_JUMP
;
1060 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1061 int syn
, uint32_t target_el
)
1063 gen_set_condexec(s
);
1064 gen_set_pc_im(s
, s
->pc
- offset
);
1065 gen_exception(excp
, syn
, target_el
);
1066 s
->is_jmp
= DISAS_JUMP
;
1069 /* Force a TB lookup after an instruction that changes the CPU state. */
1070 static inline void gen_lookup_tb(DisasContext
*s
)
1072 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1073 s
->is_jmp
= DISAS_JUMP
;
1076 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1079 int val
, rm
, shift
, shiftop
;
1082 if (!(insn
& (1 << 25))) {
1085 if (!(insn
& (1 << 23)))
1088 tcg_gen_addi_i32(var
, var
, val
);
1090 /* shift/register */
1092 shift
= (insn
>> 7) & 0x1f;
1093 shiftop
= (insn
>> 5) & 3;
1094 offset
= load_reg(s
, rm
);
1095 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1096 if (!(insn
& (1 << 23)))
1097 tcg_gen_sub_i32(var
, var
, offset
);
1099 tcg_gen_add_i32(var
, var
, offset
);
1100 tcg_temp_free_i32(offset
);
1104 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1105 int extra
, TCGv_i32 var
)
1110 if (insn
& (1 << 22)) {
1112 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1113 if (!(insn
& (1 << 23)))
1117 tcg_gen_addi_i32(var
, var
, val
);
1121 tcg_gen_addi_i32(var
, var
, extra
);
1123 offset
= load_reg(s
, rm
);
1124 if (!(insn
& (1 << 23)))
1125 tcg_gen_sub_i32(var
, var
, offset
);
1127 tcg_gen_add_i32(var
, var
, offset
);
1128 tcg_temp_free_i32(offset
);
1132 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1134 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1137 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1139 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1141 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1145 #define VFP_OP2(name) \
1146 static inline void gen_vfp_##name(int dp) \
1148 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1150 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1152 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1154 tcg_temp_free_ptr(fpst); \
1164 static inline void gen_vfp_F1_mul(int dp
)
1166 /* Like gen_vfp_mul() but put result in F1 */
1167 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1169 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1171 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1173 tcg_temp_free_ptr(fpst
);
1176 static inline void gen_vfp_F1_neg(int dp
)
1178 /* Like gen_vfp_neg() but put result in F1 */
1180 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1182 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1186 static inline void gen_vfp_abs(int dp
)
1189 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1191 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1194 static inline void gen_vfp_neg(int dp
)
1197 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1199 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1202 static inline void gen_vfp_sqrt(int dp
)
1205 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1207 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1210 static inline void gen_vfp_cmp(int dp
)
1213 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1215 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1218 static inline void gen_vfp_cmpe(int dp
)
1221 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1223 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1226 static inline void gen_vfp_F1_ld0(int dp
)
1229 tcg_gen_movi_i64(cpu_F1d
, 0);
1231 tcg_gen_movi_i32(cpu_F1s
, 0);
1234 #define VFP_GEN_ITOF(name) \
1235 static inline void gen_vfp_##name(int dp, int neon) \
1237 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1239 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1241 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1243 tcg_temp_free_ptr(statusptr); \
1250 #define VFP_GEN_FTOI(name) \
1251 static inline void gen_vfp_##name(int dp, int neon) \
1253 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1255 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1257 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1259 tcg_temp_free_ptr(statusptr); \
1268 #define VFP_GEN_FIX(name, round) \
1269 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1271 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1272 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1274 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1277 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1280 tcg_temp_free_i32(tmp_shift); \
1281 tcg_temp_free_ptr(statusptr); \
1283 VFP_GEN_FIX(tosh
, _round_to_zero
)
1284 VFP_GEN_FIX(tosl
, _round_to_zero
)
1285 VFP_GEN_FIX(touh
, _round_to_zero
)
1286 VFP_GEN_FIX(toul
, _round_to_zero
)
1293 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1296 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1298 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1302 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1305 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1307 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1312 vfp_reg_offset (int dp
, int reg
)
1315 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1317 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1318 + offsetof(CPU_DoubleU
, l
.upper
);
1320 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1321 + offsetof(CPU_DoubleU
, l
.lower
);
1325 /* Return the offset of a 32-bit piece of a NEON register.
1326 zero is the least significant end of the register. */
1328 neon_reg_offset (int reg
, int n
)
1332 return vfp_reg_offset(0, sreg
);
1335 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1337 TCGv_i32 tmp
= tcg_temp_new_i32();
1338 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1342 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1344 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1345 tcg_temp_free_i32(var
);
1348 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1350 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1353 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1355 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1358 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1359 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1360 #define tcg_gen_st_f32 tcg_gen_st_i32
1361 #define tcg_gen_st_f64 tcg_gen_st_i64
1363 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1366 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1368 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1371 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1374 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1376 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1379 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1382 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1384 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1387 #define ARM_CP_RW_BIT (1 << 20)
1389 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1391 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1394 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1396 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1399 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1401 TCGv_i32 var
= tcg_temp_new_i32();
1402 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1406 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1408 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1409 tcg_temp_free_i32(var
);
1412 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1414 iwmmxt_store_reg(cpu_M0
, rn
);
1417 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1419 iwmmxt_load_reg(cpu_M0
, rn
);
1422 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1424 iwmmxt_load_reg(cpu_V1
, rn
);
1425 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1428 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1430 iwmmxt_load_reg(cpu_V1
, rn
);
1431 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1434 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1436 iwmmxt_load_reg(cpu_V1
, rn
);
1437 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1440 #define IWMMXT_OP(name) \
1441 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1443 iwmmxt_load_reg(cpu_V1, rn); \
1444 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1447 #define IWMMXT_OP_ENV(name) \
1448 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1450 iwmmxt_load_reg(cpu_V1, rn); \
1451 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1454 #define IWMMXT_OP_ENV_SIZE(name) \
1455 IWMMXT_OP_ENV(name##b) \
1456 IWMMXT_OP_ENV(name##w) \
1457 IWMMXT_OP_ENV(name##l)
1459 #define IWMMXT_OP_ENV1(name) \
1460 static inline void gen_op_iwmmxt_##name##_M0(void) \
1462 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1476 IWMMXT_OP_ENV_SIZE(unpackl
)
1477 IWMMXT_OP_ENV_SIZE(unpackh
)
1479 IWMMXT_OP_ENV1(unpacklub
)
1480 IWMMXT_OP_ENV1(unpackluw
)
1481 IWMMXT_OP_ENV1(unpacklul
)
1482 IWMMXT_OP_ENV1(unpackhub
)
1483 IWMMXT_OP_ENV1(unpackhuw
)
1484 IWMMXT_OP_ENV1(unpackhul
)
1485 IWMMXT_OP_ENV1(unpacklsb
)
1486 IWMMXT_OP_ENV1(unpacklsw
)
1487 IWMMXT_OP_ENV1(unpacklsl
)
1488 IWMMXT_OP_ENV1(unpackhsb
)
1489 IWMMXT_OP_ENV1(unpackhsw
)
1490 IWMMXT_OP_ENV1(unpackhsl
)
1492 IWMMXT_OP_ENV_SIZE(cmpeq
)
1493 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1494 IWMMXT_OP_ENV_SIZE(cmpgts
)
1496 IWMMXT_OP_ENV_SIZE(mins
)
1497 IWMMXT_OP_ENV_SIZE(minu
)
1498 IWMMXT_OP_ENV_SIZE(maxs
)
1499 IWMMXT_OP_ENV_SIZE(maxu
)
1501 IWMMXT_OP_ENV_SIZE(subn
)
1502 IWMMXT_OP_ENV_SIZE(addn
)
1503 IWMMXT_OP_ENV_SIZE(subu
)
1504 IWMMXT_OP_ENV_SIZE(addu
)
1505 IWMMXT_OP_ENV_SIZE(subs
)
1506 IWMMXT_OP_ENV_SIZE(adds
)
1508 IWMMXT_OP_ENV(avgb0
)
1509 IWMMXT_OP_ENV(avgb1
)
1510 IWMMXT_OP_ENV(avgw0
)
1511 IWMMXT_OP_ENV(avgw1
)
1513 IWMMXT_OP_ENV(packuw
)
1514 IWMMXT_OP_ENV(packul
)
1515 IWMMXT_OP_ENV(packuq
)
1516 IWMMXT_OP_ENV(packsw
)
1517 IWMMXT_OP_ENV(packsl
)
1518 IWMMXT_OP_ENV(packsq
)
1520 static void gen_op_iwmmxt_set_mup(void)
1523 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1524 tcg_gen_ori_i32(tmp
, tmp
, 2);
1525 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1528 static void gen_op_iwmmxt_set_cup(void)
1531 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1532 tcg_gen_ori_i32(tmp
, tmp
, 1);
1533 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1536 static void gen_op_iwmmxt_setpsr_nz(void)
1538 TCGv_i32 tmp
= tcg_temp_new_i32();
1539 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1540 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1543 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1545 iwmmxt_load_reg(cpu_V1
, rn
);
1546 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1547 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1550 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1557 rd
= (insn
>> 16) & 0xf;
1558 tmp
= load_reg(s
, rd
);
1560 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1561 if (insn
& (1 << 24)) {
1563 if (insn
& (1 << 23))
1564 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1566 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1567 tcg_gen_mov_i32(dest
, tmp
);
1568 if (insn
& (1 << 21))
1569 store_reg(s
, rd
, tmp
);
1571 tcg_temp_free_i32(tmp
);
1572 } else if (insn
& (1 << 21)) {
1574 tcg_gen_mov_i32(dest
, tmp
);
1575 if (insn
& (1 << 23))
1576 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1578 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1579 store_reg(s
, rd
, tmp
);
1580 } else if (!(insn
& (1 << 23)))
1585 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1587 int rd
= (insn
>> 0) & 0xf;
1590 if (insn
& (1 << 8)) {
1591 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1594 tmp
= iwmmxt_load_creg(rd
);
1597 tmp
= tcg_temp_new_i32();
1598 iwmmxt_load_reg(cpu_V0
, rd
);
1599 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1601 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1602 tcg_gen_mov_i32(dest
, tmp
);
1603 tcg_temp_free_i32(tmp
);
1607 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1608 (ie. an undefined instruction). */
1609 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1612 int rdhi
, rdlo
, rd0
, rd1
, i
;
1614 TCGv_i32 tmp
, tmp2
, tmp3
;
1616 if ((insn
& 0x0e000e00) == 0x0c000000) {
1617 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1619 rdlo
= (insn
>> 12) & 0xf;
1620 rdhi
= (insn
>> 16) & 0xf;
1621 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1622 iwmmxt_load_reg(cpu_V0
, wrd
);
1623 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1624 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1625 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1626 } else { /* TMCRR */
1627 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1628 iwmmxt_store_reg(cpu_V0
, wrd
);
1629 gen_op_iwmmxt_set_mup();
1634 wrd
= (insn
>> 12) & 0xf;
1635 addr
= tcg_temp_new_i32();
1636 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1637 tcg_temp_free_i32(addr
);
1640 if (insn
& ARM_CP_RW_BIT
) {
1641 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1642 tmp
= tcg_temp_new_i32();
1643 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1644 iwmmxt_store_creg(wrd
, tmp
);
1647 if (insn
& (1 << 8)) {
1648 if (insn
& (1 << 22)) { /* WLDRD */
1649 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1651 } else { /* WLDRW wRd */
1652 tmp
= tcg_temp_new_i32();
1653 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1656 tmp
= tcg_temp_new_i32();
1657 if (insn
& (1 << 22)) { /* WLDRH */
1658 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1659 } else { /* WLDRB */
1660 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1664 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1665 tcg_temp_free_i32(tmp
);
1667 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1670 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1671 tmp
= iwmmxt_load_creg(wrd
);
1672 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1674 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1675 tmp
= tcg_temp_new_i32();
1676 if (insn
& (1 << 8)) {
1677 if (insn
& (1 << 22)) { /* WSTRD */
1678 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1679 } else { /* WSTRW wRd */
1680 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1681 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1684 if (insn
& (1 << 22)) { /* WSTRH */
1685 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1686 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1687 } else { /* WSTRB */
1688 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1689 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1693 tcg_temp_free_i32(tmp
);
1695 tcg_temp_free_i32(addr
);
1699 if ((insn
& 0x0f000000) != 0x0e000000)
1702 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1703 case 0x000: /* WOR */
1704 wrd
= (insn
>> 12) & 0xf;
1705 rd0
= (insn
>> 0) & 0xf;
1706 rd1
= (insn
>> 16) & 0xf;
1707 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1708 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1709 gen_op_iwmmxt_setpsr_nz();
1710 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1711 gen_op_iwmmxt_set_mup();
1712 gen_op_iwmmxt_set_cup();
1714 case 0x011: /* TMCR */
1717 rd
= (insn
>> 12) & 0xf;
1718 wrd
= (insn
>> 16) & 0xf;
1720 case ARM_IWMMXT_wCID
:
1721 case ARM_IWMMXT_wCASF
:
1723 case ARM_IWMMXT_wCon
:
1724 gen_op_iwmmxt_set_cup();
1726 case ARM_IWMMXT_wCSSF
:
1727 tmp
= iwmmxt_load_creg(wrd
);
1728 tmp2
= load_reg(s
, rd
);
1729 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1730 tcg_temp_free_i32(tmp2
);
1731 iwmmxt_store_creg(wrd
, tmp
);
1733 case ARM_IWMMXT_wCGR0
:
1734 case ARM_IWMMXT_wCGR1
:
1735 case ARM_IWMMXT_wCGR2
:
1736 case ARM_IWMMXT_wCGR3
:
1737 gen_op_iwmmxt_set_cup();
1738 tmp
= load_reg(s
, rd
);
1739 iwmmxt_store_creg(wrd
, tmp
);
1745 case 0x100: /* WXOR */
1746 wrd
= (insn
>> 12) & 0xf;
1747 rd0
= (insn
>> 0) & 0xf;
1748 rd1
= (insn
>> 16) & 0xf;
1749 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1750 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1751 gen_op_iwmmxt_setpsr_nz();
1752 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1753 gen_op_iwmmxt_set_mup();
1754 gen_op_iwmmxt_set_cup();
1756 case 0x111: /* TMRC */
1759 rd
= (insn
>> 12) & 0xf;
1760 wrd
= (insn
>> 16) & 0xf;
1761 tmp
= iwmmxt_load_creg(wrd
);
1762 store_reg(s
, rd
, tmp
);
1764 case 0x300: /* WANDN */
1765 wrd
= (insn
>> 12) & 0xf;
1766 rd0
= (insn
>> 0) & 0xf;
1767 rd1
= (insn
>> 16) & 0xf;
1768 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1769 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1770 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1771 gen_op_iwmmxt_setpsr_nz();
1772 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1773 gen_op_iwmmxt_set_mup();
1774 gen_op_iwmmxt_set_cup();
1776 case 0x200: /* WAND */
1777 wrd
= (insn
>> 12) & 0xf;
1778 rd0
= (insn
>> 0) & 0xf;
1779 rd1
= (insn
>> 16) & 0xf;
1780 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1781 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1782 gen_op_iwmmxt_setpsr_nz();
1783 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1784 gen_op_iwmmxt_set_mup();
1785 gen_op_iwmmxt_set_cup();
1787 case 0x810: case 0xa10: /* WMADD */
1788 wrd
= (insn
>> 12) & 0xf;
1789 rd0
= (insn
>> 0) & 0xf;
1790 rd1
= (insn
>> 16) & 0xf;
1791 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1792 if (insn
& (1 << 21))
1793 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1795 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1796 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1797 gen_op_iwmmxt_set_mup();
1799 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1800 wrd
= (insn
>> 12) & 0xf;
1801 rd0
= (insn
>> 16) & 0xf;
1802 rd1
= (insn
>> 0) & 0xf;
1803 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1804 switch ((insn
>> 22) & 3) {
1806 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1809 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1812 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1817 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1818 gen_op_iwmmxt_set_mup();
1819 gen_op_iwmmxt_set_cup();
1821 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1822 wrd
= (insn
>> 12) & 0xf;
1823 rd0
= (insn
>> 16) & 0xf;
1824 rd1
= (insn
>> 0) & 0xf;
1825 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1826 switch ((insn
>> 22) & 3) {
1828 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1831 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1834 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1839 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1840 gen_op_iwmmxt_set_mup();
1841 gen_op_iwmmxt_set_cup();
1843 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1844 wrd
= (insn
>> 12) & 0xf;
1845 rd0
= (insn
>> 16) & 0xf;
1846 rd1
= (insn
>> 0) & 0xf;
1847 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1848 if (insn
& (1 << 22))
1849 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1851 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1852 if (!(insn
& (1 << 20)))
1853 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1854 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1855 gen_op_iwmmxt_set_mup();
1857 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1858 wrd
= (insn
>> 12) & 0xf;
1859 rd0
= (insn
>> 16) & 0xf;
1860 rd1
= (insn
>> 0) & 0xf;
1861 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1862 if (insn
& (1 << 21)) {
1863 if (insn
& (1 << 20))
1864 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1866 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1868 if (insn
& (1 << 20))
1869 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1871 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1873 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1874 gen_op_iwmmxt_set_mup();
1876 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1877 wrd
= (insn
>> 12) & 0xf;
1878 rd0
= (insn
>> 16) & 0xf;
1879 rd1
= (insn
>> 0) & 0xf;
1880 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1881 if (insn
& (1 << 21))
1882 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1884 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1885 if (!(insn
& (1 << 20))) {
1886 iwmmxt_load_reg(cpu_V1
, wrd
);
1887 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1889 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1890 gen_op_iwmmxt_set_mup();
1892 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
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_cmpeqb_M0_wRn(rd1
);
1902 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1905 gen_op_iwmmxt_cmpeql_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 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
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 if (insn
& (1 << 20))
1921 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1923 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1925 if (insn
& (1 << 20))
1926 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1928 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1930 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1931 gen_op_iwmmxt_set_mup();
1932 gen_op_iwmmxt_set_cup();
1934 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1935 wrd
= (insn
>> 12) & 0xf;
1936 rd0
= (insn
>> 16) & 0xf;
1937 rd1
= (insn
>> 0) & 0xf;
1938 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1939 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1940 tcg_gen_andi_i32(tmp
, tmp
, 7);
1941 iwmmxt_load_reg(cpu_V1
, rd1
);
1942 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1943 tcg_temp_free_i32(tmp
);
1944 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1945 gen_op_iwmmxt_set_mup();
1947 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1948 if (((insn
>> 6) & 3) == 3)
1950 rd
= (insn
>> 12) & 0xf;
1951 wrd
= (insn
>> 16) & 0xf;
1952 tmp
= load_reg(s
, rd
);
1953 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1954 switch ((insn
>> 6) & 3) {
1956 tmp2
= tcg_const_i32(0xff);
1957 tmp3
= tcg_const_i32((insn
& 7) << 3);
1960 tmp2
= tcg_const_i32(0xffff);
1961 tmp3
= tcg_const_i32((insn
& 3) << 4);
1964 tmp2
= tcg_const_i32(0xffffffff);
1965 tmp3
= tcg_const_i32((insn
& 1) << 5);
1968 TCGV_UNUSED_I32(tmp2
);
1969 TCGV_UNUSED_I32(tmp3
);
1971 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1972 tcg_temp_free_i32(tmp3
);
1973 tcg_temp_free_i32(tmp2
);
1974 tcg_temp_free_i32(tmp
);
1975 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1976 gen_op_iwmmxt_set_mup();
1978 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1979 rd
= (insn
>> 12) & 0xf;
1980 wrd
= (insn
>> 16) & 0xf;
1981 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1983 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1984 tmp
= tcg_temp_new_i32();
1985 switch ((insn
>> 22) & 3) {
1987 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1988 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1990 tcg_gen_ext8s_i32(tmp
, tmp
);
1992 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1996 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1997 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1999 tcg_gen_ext16s_i32(tmp
, tmp
);
2001 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2005 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2006 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2009 store_reg(s
, rd
, tmp
);
2011 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2012 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2014 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2015 switch ((insn
>> 22) & 3) {
2017 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2020 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2023 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2026 tcg_gen_shli_i32(tmp
, tmp
, 28);
2028 tcg_temp_free_i32(tmp
);
2030 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2031 if (((insn
>> 6) & 3) == 3)
2033 rd
= (insn
>> 12) & 0xf;
2034 wrd
= (insn
>> 16) & 0xf;
2035 tmp
= load_reg(s
, rd
);
2036 switch ((insn
>> 6) & 3) {
2038 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2041 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2044 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2047 tcg_temp_free_i32(tmp
);
2048 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2049 gen_op_iwmmxt_set_mup();
2051 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2052 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2054 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2055 tmp2
= tcg_temp_new_i32();
2056 tcg_gen_mov_i32(tmp2
, tmp
);
2057 switch ((insn
>> 22) & 3) {
2059 for (i
= 0; i
< 7; i
++) {
2060 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2061 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2065 for (i
= 0; i
< 3; i
++) {
2066 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2067 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2071 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2072 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2076 tcg_temp_free_i32(tmp2
);
2077 tcg_temp_free_i32(tmp
);
2079 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2080 wrd
= (insn
>> 12) & 0xf;
2081 rd0
= (insn
>> 16) & 0xf;
2082 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2083 switch ((insn
>> 22) & 3) {
2085 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2088 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2091 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2096 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2097 gen_op_iwmmxt_set_mup();
2099 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2100 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2102 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2103 tmp2
= tcg_temp_new_i32();
2104 tcg_gen_mov_i32(tmp2
, tmp
);
2105 switch ((insn
>> 22) & 3) {
2107 for (i
= 0; i
< 7; i
++) {
2108 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2109 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2113 for (i
= 0; i
< 3; i
++) {
2114 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2115 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2119 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2120 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2124 tcg_temp_free_i32(tmp2
);
2125 tcg_temp_free_i32(tmp
);
2127 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2128 rd
= (insn
>> 12) & 0xf;
2129 rd0
= (insn
>> 16) & 0xf;
2130 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2132 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2133 tmp
= tcg_temp_new_i32();
2134 switch ((insn
>> 22) & 3) {
2136 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2139 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2142 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2145 store_reg(s
, rd
, tmp
);
2147 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2148 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2149 wrd
= (insn
>> 12) & 0xf;
2150 rd0
= (insn
>> 16) & 0xf;
2151 rd1
= (insn
>> 0) & 0xf;
2152 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2153 switch ((insn
>> 22) & 3) {
2155 if (insn
& (1 << 21))
2156 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2158 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2161 if (insn
& (1 << 21))
2162 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2164 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2167 if (insn
& (1 << 21))
2168 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2170 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2175 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2176 gen_op_iwmmxt_set_mup();
2177 gen_op_iwmmxt_set_cup();
2179 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2180 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2181 wrd
= (insn
>> 12) & 0xf;
2182 rd0
= (insn
>> 16) & 0xf;
2183 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2184 switch ((insn
>> 22) & 3) {
2186 if (insn
& (1 << 21))
2187 gen_op_iwmmxt_unpacklsb_M0();
2189 gen_op_iwmmxt_unpacklub_M0();
2192 if (insn
& (1 << 21))
2193 gen_op_iwmmxt_unpacklsw_M0();
2195 gen_op_iwmmxt_unpackluw_M0();
2198 if (insn
& (1 << 21))
2199 gen_op_iwmmxt_unpacklsl_M0();
2201 gen_op_iwmmxt_unpacklul_M0();
2206 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2207 gen_op_iwmmxt_set_mup();
2208 gen_op_iwmmxt_set_cup();
2210 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2211 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2212 wrd
= (insn
>> 12) & 0xf;
2213 rd0
= (insn
>> 16) & 0xf;
2214 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2215 switch ((insn
>> 22) & 3) {
2217 if (insn
& (1 << 21))
2218 gen_op_iwmmxt_unpackhsb_M0();
2220 gen_op_iwmmxt_unpackhub_M0();
2223 if (insn
& (1 << 21))
2224 gen_op_iwmmxt_unpackhsw_M0();
2226 gen_op_iwmmxt_unpackhuw_M0();
2229 if (insn
& (1 << 21))
2230 gen_op_iwmmxt_unpackhsl_M0();
2232 gen_op_iwmmxt_unpackhul_M0();
2237 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2238 gen_op_iwmmxt_set_mup();
2239 gen_op_iwmmxt_set_cup();
2241 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2242 case 0x214: case 0x614: case 0xa14: case 0xe14:
2243 if (((insn
>> 22) & 3) == 0)
2245 wrd
= (insn
>> 12) & 0xf;
2246 rd0
= (insn
>> 16) & 0xf;
2247 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2248 tmp
= tcg_temp_new_i32();
2249 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2250 tcg_temp_free_i32(tmp
);
2253 switch ((insn
>> 22) & 3) {
2255 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2258 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2261 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2264 tcg_temp_free_i32(tmp
);
2265 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2266 gen_op_iwmmxt_set_mup();
2267 gen_op_iwmmxt_set_cup();
2269 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2270 case 0x014: case 0x414: case 0x814: case 0xc14:
2271 if (((insn
>> 22) & 3) == 0)
2273 wrd
= (insn
>> 12) & 0xf;
2274 rd0
= (insn
>> 16) & 0xf;
2275 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2276 tmp
= tcg_temp_new_i32();
2277 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2278 tcg_temp_free_i32(tmp
);
2281 switch ((insn
>> 22) & 3) {
2283 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2286 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2289 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2292 tcg_temp_free_i32(tmp
);
2293 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2294 gen_op_iwmmxt_set_mup();
2295 gen_op_iwmmxt_set_cup();
2297 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2298 case 0x114: case 0x514: case 0x914: case 0xd14:
2299 if (((insn
>> 22) & 3) == 0)
2301 wrd
= (insn
>> 12) & 0xf;
2302 rd0
= (insn
>> 16) & 0xf;
2303 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2304 tmp
= tcg_temp_new_i32();
2305 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2306 tcg_temp_free_i32(tmp
);
2309 switch ((insn
>> 22) & 3) {
2311 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2314 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2317 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2320 tcg_temp_free_i32(tmp
);
2321 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2322 gen_op_iwmmxt_set_mup();
2323 gen_op_iwmmxt_set_cup();
2325 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2326 case 0x314: case 0x714: case 0xb14: case 0xf14:
2327 if (((insn
>> 22) & 3) == 0)
2329 wrd
= (insn
>> 12) & 0xf;
2330 rd0
= (insn
>> 16) & 0xf;
2331 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2332 tmp
= tcg_temp_new_i32();
2333 switch ((insn
>> 22) & 3) {
2335 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2336 tcg_temp_free_i32(tmp
);
2339 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2342 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2343 tcg_temp_free_i32(tmp
);
2346 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2349 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2350 tcg_temp_free_i32(tmp
);
2353 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2356 tcg_temp_free_i32(tmp
);
2357 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2358 gen_op_iwmmxt_set_mup();
2359 gen_op_iwmmxt_set_cup();
2361 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2362 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2363 wrd
= (insn
>> 12) & 0xf;
2364 rd0
= (insn
>> 16) & 0xf;
2365 rd1
= (insn
>> 0) & 0xf;
2366 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2367 switch ((insn
>> 22) & 3) {
2369 if (insn
& (1 << 21))
2370 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2372 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2375 if (insn
& (1 << 21))
2376 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2378 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2381 if (insn
& (1 << 21))
2382 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2384 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2389 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2390 gen_op_iwmmxt_set_mup();
2392 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2393 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2394 wrd
= (insn
>> 12) & 0xf;
2395 rd0
= (insn
>> 16) & 0xf;
2396 rd1
= (insn
>> 0) & 0xf;
2397 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2398 switch ((insn
>> 22) & 3) {
2400 if (insn
& (1 << 21))
2401 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2403 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2406 if (insn
& (1 << 21))
2407 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2409 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2412 if (insn
& (1 << 21))
2413 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2415 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2420 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2421 gen_op_iwmmxt_set_mup();
2423 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2424 case 0x402: case 0x502: case 0x602: case 0x702:
2425 wrd
= (insn
>> 12) & 0xf;
2426 rd0
= (insn
>> 16) & 0xf;
2427 rd1
= (insn
>> 0) & 0xf;
2428 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2429 tmp
= tcg_const_i32((insn
>> 20) & 3);
2430 iwmmxt_load_reg(cpu_V1
, rd1
);
2431 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2432 tcg_temp_free_i32(tmp
);
2433 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2434 gen_op_iwmmxt_set_mup();
2436 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2437 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2438 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2439 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2440 wrd
= (insn
>> 12) & 0xf;
2441 rd0
= (insn
>> 16) & 0xf;
2442 rd1
= (insn
>> 0) & 0xf;
2443 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2444 switch ((insn
>> 20) & 0xf) {
2446 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2449 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2452 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2455 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2458 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2461 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2464 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2467 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2470 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2475 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2476 gen_op_iwmmxt_set_mup();
2477 gen_op_iwmmxt_set_cup();
2479 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2480 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2481 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2482 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2483 wrd
= (insn
>> 12) & 0xf;
2484 rd0
= (insn
>> 16) & 0xf;
2485 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2486 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2487 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2488 tcg_temp_free_i32(tmp
);
2489 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2490 gen_op_iwmmxt_set_mup();
2491 gen_op_iwmmxt_set_cup();
2493 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2494 case 0x418: case 0x518: case 0x618: case 0x718:
2495 case 0x818: case 0x918: case 0xa18: case 0xb18:
2496 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2497 wrd
= (insn
>> 12) & 0xf;
2498 rd0
= (insn
>> 16) & 0xf;
2499 rd1
= (insn
>> 0) & 0xf;
2500 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2501 switch ((insn
>> 20) & 0xf) {
2503 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2506 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2509 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2512 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2515 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2518 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2521 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2524 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2527 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2532 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2533 gen_op_iwmmxt_set_mup();
2534 gen_op_iwmmxt_set_cup();
2536 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2537 case 0x408: case 0x508: case 0x608: case 0x708:
2538 case 0x808: case 0x908: case 0xa08: case 0xb08:
2539 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2540 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2542 wrd
= (insn
>> 12) & 0xf;
2543 rd0
= (insn
>> 16) & 0xf;
2544 rd1
= (insn
>> 0) & 0xf;
2545 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2546 switch ((insn
>> 22) & 3) {
2548 if (insn
& (1 << 21))
2549 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2551 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2554 if (insn
& (1 << 21))
2555 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2557 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2560 if (insn
& (1 << 21))
2561 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2563 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2566 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2567 gen_op_iwmmxt_set_mup();
2568 gen_op_iwmmxt_set_cup();
2570 case 0x201: case 0x203: case 0x205: case 0x207:
2571 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2572 case 0x211: case 0x213: case 0x215: case 0x217:
2573 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2574 wrd
= (insn
>> 5) & 0xf;
2575 rd0
= (insn
>> 12) & 0xf;
2576 rd1
= (insn
>> 0) & 0xf;
2577 if (rd0
== 0xf || rd1
== 0xf)
2579 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2580 tmp
= load_reg(s
, rd0
);
2581 tmp2
= load_reg(s
, rd1
);
2582 switch ((insn
>> 16) & 0xf) {
2583 case 0x0: /* TMIA */
2584 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2586 case 0x8: /* TMIAPH */
2587 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2589 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2590 if (insn
& (1 << 16))
2591 tcg_gen_shri_i32(tmp
, tmp
, 16);
2592 if (insn
& (1 << 17))
2593 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2594 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2597 tcg_temp_free_i32(tmp2
);
2598 tcg_temp_free_i32(tmp
);
2601 tcg_temp_free_i32(tmp2
);
2602 tcg_temp_free_i32(tmp
);
2603 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2604 gen_op_iwmmxt_set_mup();
2613 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2614 (ie. an undefined instruction). */
2615 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2617 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2620 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2621 /* Multiply with Internal Accumulate Format */
2622 rd0
= (insn
>> 12) & 0xf;
2624 acc
= (insn
>> 5) & 7;
2629 tmp
= load_reg(s
, rd0
);
2630 tmp2
= load_reg(s
, rd1
);
2631 switch ((insn
>> 16) & 0xf) {
2633 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2635 case 0x8: /* MIAPH */
2636 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2638 case 0xc: /* MIABB */
2639 case 0xd: /* MIABT */
2640 case 0xe: /* MIATB */
2641 case 0xf: /* MIATT */
2642 if (insn
& (1 << 16))
2643 tcg_gen_shri_i32(tmp
, tmp
, 16);
2644 if (insn
& (1 << 17))
2645 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2646 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2651 tcg_temp_free_i32(tmp2
);
2652 tcg_temp_free_i32(tmp
);
2654 gen_op_iwmmxt_movq_wRn_M0(acc
);
2658 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2659 /* Internal Accumulator Access Format */
2660 rdhi
= (insn
>> 16) & 0xf;
2661 rdlo
= (insn
>> 12) & 0xf;
2667 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2668 iwmmxt_load_reg(cpu_V0
, acc
);
2669 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2670 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2671 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2672 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2674 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2675 iwmmxt_store_reg(cpu_V0
, acc
);
2683 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2684 #define VFP_SREG(insn, bigbit, smallbit) \
2685 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2686 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2687 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2688 reg = (((insn) >> (bigbit)) & 0x0f) \
2689 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2691 if (insn & (1 << (smallbit))) \
2693 reg = ((insn) >> (bigbit)) & 0x0f; \
2696 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2697 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2698 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2699 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2700 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2701 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2703 /* Move between integer and VFP cores. */
2704 static TCGv_i32
gen_vfp_mrs(void)
2706 TCGv_i32 tmp
= tcg_temp_new_i32();
2707 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2711 static void gen_vfp_msr(TCGv_i32 tmp
)
2713 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2714 tcg_temp_free_i32(tmp
);
2717 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2719 TCGv_i32 tmp
= tcg_temp_new_i32();
2721 tcg_gen_shri_i32(var
, var
, shift
);
2722 tcg_gen_ext8u_i32(var
, var
);
2723 tcg_gen_shli_i32(tmp
, var
, 8);
2724 tcg_gen_or_i32(var
, var
, tmp
);
2725 tcg_gen_shli_i32(tmp
, var
, 16);
2726 tcg_gen_or_i32(var
, var
, tmp
);
2727 tcg_temp_free_i32(tmp
);
2730 static void gen_neon_dup_low16(TCGv_i32 var
)
2732 TCGv_i32 tmp
= tcg_temp_new_i32();
2733 tcg_gen_ext16u_i32(var
, var
);
2734 tcg_gen_shli_i32(tmp
, var
, 16);
2735 tcg_gen_or_i32(var
, var
, tmp
);
2736 tcg_temp_free_i32(tmp
);
2739 static void gen_neon_dup_high16(TCGv_i32 var
)
2741 TCGv_i32 tmp
= tcg_temp_new_i32();
2742 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2743 tcg_gen_shri_i32(tmp
, var
, 16);
2744 tcg_gen_or_i32(var
, var
, tmp
);
2745 tcg_temp_free_i32(tmp
);
2748 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2750 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2751 TCGv_i32 tmp
= tcg_temp_new_i32();
2754 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2755 gen_neon_dup_u8(tmp
, 0);
2758 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2759 gen_neon_dup_low16(tmp
);
2762 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2764 default: /* Avoid compiler warnings. */
2770 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2773 uint32_t cc
= extract32(insn
, 20, 2);
2776 TCGv_i64 frn
, frm
, dest
;
2777 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2779 zero
= tcg_const_i64(0);
2781 frn
= tcg_temp_new_i64();
2782 frm
= tcg_temp_new_i64();
2783 dest
= tcg_temp_new_i64();
2785 zf
= tcg_temp_new_i64();
2786 nf
= tcg_temp_new_i64();
2787 vf
= tcg_temp_new_i64();
2789 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2790 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2791 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2793 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2794 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2797 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2801 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2804 case 2: /* ge: N == V -> N ^ V == 0 */
2805 tmp
= tcg_temp_new_i64();
2806 tcg_gen_xor_i64(tmp
, vf
, nf
);
2807 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2809 tcg_temp_free_i64(tmp
);
2811 case 3: /* gt: !Z && N == V */
2812 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2814 tmp
= tcg_temp_new_i64();
2815 tcg_gen_xor_i64(tmp
, vf
, nf
);
2816 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2818 tcg_temp_free_i64(tmp
);
2821 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2822 tcg_temp_free_i64(frn
);
2823 tcg_temp_free_i64(frm
);
2824 tcg_temp_free_i64(dest
);
2826 tcg_temp_free_i64(zf
);
2827 tcg_temp_free_i64(nf
);
2828 tcg_temp_free_i64(vf
);
2830 tcg_temp_free_i64(zero
);
2832 TCGv_i32 frn
, frm
, dest
;
2835 zero
= tcg_const_i32(0);
2837 frn
= tcg_temp_new_i32();
2838 frm
= tcg_temp_new_i32();
2839 dest
= tcg_temp_new_i32();
2840 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2841 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2844 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2848 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2851 case 2: /* ge: N == V -> N ^ V == 0 */
2852 tmp
= tcg_temp_new_i32();
2853 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2854 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2856 tcg_temp_free_i32(tmp
);
2858 case 3: /* gt: !Z && N == V */
2859 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2861 tmp
= tcg_temp_new_i32();
2862 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2863 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2865 tcg_temp_free_i32(tmp
);
2868 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2869 tcg_temp_free_i32(frn
);
2870 tcg_temp_free_i32(frm
);
2871 tcg_temp_free_i32(dest
);
2873 tcg_temp_free_i32(zero
);
2879 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2880 uint32_t rm
, uint32_t dp
)
2882 uint32_t vmin
= extract32(insn
, 6, 1);
2883 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2886 TCGv_i64 frn
, frm
, dest
;
2888 frn
= tcg_temp_new_i64();
2889 frm
= tcg_temp_new_i64();
2890 dest
= tcg_temp_new_i64();
2892 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2893 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2895 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2897 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2899 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2900 tcg_temp_free_i64(frn
);
2901 tcg_temp_free_i64(frm
);
2902 tcg_temp_free_i64(dest
);
2904 TCGv_i32 frn
, frm
, dest
;
2906 frn
= tcg_temp_new_i32();
2907 frm
= tcg_temp_new_i32();
2908 dest
= tcg_temp_new_i32();
2910 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2911 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2913 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2915 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2917 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2918 tcg_temp_free_i32(frn
);
2919 tcg_temp_free_i32(frm
);
2920 tcg_temp_free_i32(dest
);
2923 tcg_temp_free_ptr(fpst
);
2927 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2930 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2933 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2934 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2939 tcg_op
= tcg_temp_new_i64();
2940 tcg_res
= tcg_temp_new_i64();
2941 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2942 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2943 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2944 tcg_temp_free_i64(tcg_op
);
2945 tcg_temp_free_i64(tcg_res
);
2949 tcg_op
= tcg_temp_new_i32();
2950 tcg_res
= tcg_temp_new_i32();
2951 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2952 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2953 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2954 tcg_temp_free_i32(tcg_op
);
2955 tcg_temp_free_i32(tcg_res
);
2958 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2959 tcg_temp_free_i32(tcg_rmode
);
2961 tcg_temp_free_ptr(fpst
);
2965 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2968 bool is_signed
= extract32(insn
, 7, 1);
2969 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2970 TCGv_i32 tcg_rmode
, tcg_shift
;
2972 tcg_shift
= tcg_const_i32(0);
2974 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2975 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2978 TCGv_i64 tcg_double
, tcg_res
;
2980 /* Rd is encoded as a single precision register even when the source
2981 * is double precision.
2983 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2984 tcg_double
= tcg_temp_new_i64();
2985 tcg_res
= tcg_temp_new_i64();
2986 tcg_tmp
= tcg_temp_new_i32();
2987 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2989 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2991 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2993 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
2994 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2995 tcg_temp_free_i32(tcg_tmp
);
2996 tcg_temp_free_i64(tcg_res
);
2997 tcg_temp_free_i64(tcg_double
);
2999 TCGv_i32 tcg_single
, tcg_res
;
3000 tcg_single
= tcg_temp_new_i32();
3001 tcg_res
= tcg_temp_new_i32();
3002 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3004 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3006 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3008 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3009 tcg_temp_free_i32(tcg_res
);
3010 tcg_temp_free_i32(tcg_single
);
3013 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3014 tcg_temp_free_i32(tcg_rmode
);
3016 tcg_temp_free_i32(tcg_shift
);
3018 tcg_temp_free_ptr(fpst
);
3023 /* Table for converting the most common AArch32 encoding of
3024 * rounding mode to arm_fprounding order (which matches the
3025 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3027 static const uint8_t fp_decode_rm
[] = {
3034 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3036 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3038 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3043 VFP_DREG_D(rd
, insn
);
3044 VFP_DREG_N(rn
, insn
);
3045 VFP_DREG_M(rm
, insn
);
3047 rd
= VFP_SREG_D(insn
);
3048 rn
= VFP_SREG_N(insn
);
3049 rm
= VFP_SREG_M(insn
);
3052 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3053 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3054 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3055 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3056 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3057 /* VRINTA, VRINTN, VRINTP, VRINTM */
3058 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3059 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3060 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3061 /* VCVTA, VCVTN, VCVTP, VCVTM */
3062 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3063 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3068 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3069 (ie. an undefined instruction). */
3070 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3072 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3078 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3082 /* FIXME: this access check should not take precedence over UNDEF
3083 * for invalid encodings; we will generate incorrect syndrome information
3084 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3086 if (s
->fp_excp_el
) {
3087 gen_exception_insn(s
, 4, EXCP_UDEF
,
3088 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3092 if (!s
->vfp_enabled
) {
3093 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3094 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3096 rn
= (insn
>> 16) & 0xf;
3097 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3098 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3103 if (extract32(insn
, 28, 4) == 0xf) {
3104 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3105 * only used in v8 and above.
3107 return disas_vfp_v8_insn(s
, insn
);
3110 dp
= ((insn
& 0xf00) == 0xb00);
3111 switch ((insn
>> 24) & 0xf) {
3113 if (insn
& (1 << 4)) {
3114 /* single register transfer */
3115 rd
= (insn
>> 12) & 0xf;
3120 VFP_DREG_N(rn
, insn
);
3123 if (insn
& 0x00c00060
3124 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3128 pass
= (insn
>> 21) & 1;
3129 if (insn
& (1 << 22)) {
3131 offset
= ((insn
>> 5) & 3) * 8;
3132 } else if (insn
& (1 << 5)) {
3134 offset
= (insn
& (1 << 6)) ? 16 : 0;
3139 if (insn
& ARM_CP_RW_BIT
) {
3141 tmp
= neon_load_reg(rn
, pass
);
3145 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3146 if (insn
& (1 << 23))
3152 if (insn
& (1 << 23)) {
3154 tcg_gen_shri_i32(tmp
, tmp
, 16);
3160 tcg_gen_sari_i32(tmp
, tmp
, 16);
3169 store_reg(s
, rd
, tmp
);
3172 tmp
= load_reg(s
, rd
);
3173 if (insn
& (1 << 23)) {
3176 gen_neon_dup_u8(tmp
, 0);
3177 } else if (size
== 1) {
3178 gen_neon_dup_low16(tmp
);
3180 for (n
= 0; n
<= pass
* 2; n
++) {
3181 tmp2
= tcg_temp_new_i32();
3182 tcg_gen_mov_i32(tmp2
, tmp
);
3183 neon_store_reg(rn
, n
, tmp2
);
3185 neon_store_reg(rn
, n
, tmp
);
3190 tmp2
= neon_load_reg(rn
, pass
);
3191 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3192 tcg_temp_free_i32(tmp2
);
3195 tmp2
= neon_load_reg(rn
, pass
);
3196 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3197 tcg_temp_free_i32(tmp2
);
3202 neon_store_reg(rn
, pass
, tmp
);
3206 if ((insn
& 0x6f) != 0x00)
3208 rn
= VFP_SREG_N(insn
);
3209 if (insn
& ARM_CP_RW_BIT
) {
3211 if (insn
& (1 << 21)) {
3212 /* system register */
3217 /* VFP2 allows access to FSID from userspace.
3218 VFP3 restricts all id registers to privileged
3221 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3224 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3229 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3231 case ARM_VFP_FPINST
:
3232 case ARM_VFP_FPINST2
:
3233 /* Not present in VFP3. */
3235 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3238 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3242 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3243 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3245 tmp
= tcg_temp_new_i32();
3246 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3250 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3257 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3260 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3266 gen_mov_F0_vreg(0, rn
);
3267 tmp
= gen_vfp_mrs();
3270 /* Set the 4 flag bits in the CPSR. */
3272 tcg_temp_free_i32(tmp
);
3274 store_reg(s
, rd
, tmp
);
3278 if (insn
& (1 << 21)) {
3280 /* system register */
3285 /* Writes are ignored. */
3288 tmp
= load_reg(s
, rd
);
3289 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3290 tcg_temp_free_i32(tmp
);
3296 /* TODO: VFP subarchitecture support.
3297 * For now, keep the EN bit only */
3298 tmp
= load_reg(s
, rd
);
3299 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3300 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3303 case ARM_VFP_FPINST
:
3304 case ARM_VFP_FPINST2
:
3308 tmp
= load_reg(s
, rd
);
3309 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3315 tmp
= load_reg(s
, rd
);
3317 gen_mov_vreg_F0(0, rn
);
3322 /* data processing */
3323 /* The opcode is in bits 23, 21, 20 and 6. */
3324 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3328 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3330 /* rn is register number */
3331 VFP_DREG_N(rn
, insn
);
3334 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3335 ((rn
& 0x1e) == 0x6))) {
3336 /* Integer or single/half precision destination. */
3337 rd
= VFP_SREG_D(insn
);
3339 VFP_DREG_D(rd
, insn
);
3342 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3343 ((rn
& 0x1e) == 0x4))) {
3344 /* VCVT from int or half precision is always from S reg
3345 * regardless of dp bit. VCVT with immediate frac_bits
3346 * has same format as SREG_M.
3348 rm
= VFP_SREG_M(insn
);
3350 VFP_DREG_M(rm
, insn
);
3353 rn
= VFP_SREG_N(insn
);
3354 if (op
== 15 && rn
== 15) {
3355 /* Double precision destination. */
3356 VFP_DREG_D(rd
, insn
);
3358 rd
= VFP_SREG_D(insn
);
3360 /* NB that we implicitly rely on the encoding for the frac_bits
3361 * in VCVT of fixed to float being the same as that of an SREG_M
3363 rm
= VFP_SREG_M(insn
);
3366 veclen
= s
->vec_len
;
3367 if (op
== 15 && rn
> 3)
3370 /* Shut up compiler warnings. */
3381 /* Figure out what type of vector operation this is. */
3382 if ((rd
& bank_mask
) == 0) {
3387 delta_d
= (s
->vec_stride
>> 1) + 1;
3389 delta_d
= s
->vec_stride
+ 1;
3391 if ((rm
& bank_mask
) == 0) {
3392 /* mixed scalar/vector */
3401 /* Load the initial operands. */
3406 /* Integer source */
3407 gen_mov_F0_vreg(0, rm
);
3412 gen_mov_F0_vreg(dp
, rd
);
3413 gen_mov_F1_vreg(dp
, rm
);
3417 /* Compare with zero */
3418 gen_mov_F0_vreg(dp
, rd
);
3429 /* Source and destination the same. */
3430 gen_mov_F0_vreg(dp
, rd
);
3436 /* VCVTB, VCVTT: only present with the halfprec extension
3437 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3438 * (we choose to UNDEF)
3440 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3441 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3444 if (!extract32(rn
, 1, 1)) {
3445 /* Half precision source. */
3446 gen_mov_F0_vreg(0, rm
);
3449 /* Otherwise fall through */
3451 /* One source operand. */
3452 gen_mov_F0_vreg(dp
, rm
);
3456 /* Two source operands. */
3457 gen_mov_F0_vreg(dp
, rn
);
3458 gen_mov_F1_vreg(dp
, rm
);
3462 /* Perform the calculation. */
3464 case 0: /* VMLA: fd + (fn * fm) */
3465 /* Note that order of inputs to the add matters for NaNs */
3467 gen_mov_F0_vreg(dp
, rd
);
3470 case 1: /* VMLS: fd + -(fn * fm) */
3473 gen_mov_F0_vreg(dp
, rd
);
3476 case 2: /* VNMLS: -fd + (fn * fm) */
3477 /* Note that it isn't valid to replace (-A + B) with (B - A)
3478 * or similar plausible looking simplifications
3479 * because this will give wrong results for NaNs.
3482 gen_mov_F0_vreg(dp
, rd
);
3486 case 3: /* VNMLA: -fd + -(fn * fm) */
3489 gen_mov_F0_vreg(dp
, rd
);
3493 case 4: /* mul: fn * fm */
3496 case 5: /* nmul: -(fn * fm) */
3500 case 6: /* add: fn + fm */
3503 case 7: /* sub: fn - fm */
3506 case 8: /* div: fn / fm */
3509 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3510 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3511 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3512 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3513 /* These are fused multiply-add, and must be done as one
3514 * floating point operation with no rounding between the
3515 * multiplication and addition steps.
3516 * NB that doing the negations here as separate steps is
3517 * correct : an input NaN should come out with its sign bit
3518 * flipped if it is a negated-input.
3520 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3528 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3530 frd
= tcg_temp_new_i64();
3531 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3534 gen_helper_vfp_negd(frd
, frd
);
3536 fpst
= get_fpstatus_ptr(0);
3537 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3538 cpu_F1d
, frd
, fpst
);
3539 tcg_temp_free_ptr(fpst
);
3540 tcg_temp_free_i64(frd
);
3546 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3548 frd
= tcg_temp_new_i32();
3549 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3551 gen_helper_vfp_negs(frd
, frd
);
3553 fpst
= get_fpstatus_ptr(0);
3554 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3555 cpu_F1s
, frd
, fpst
);
3556 tcg_temp_free_ptr(fpst
);
3557 tcg_temp_free_i32(frd
);
3560 case 14: /* fconst */
3561 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3565 n
= (insn
<< 12) & 0x80000000;
3566 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3573 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3580 tcg_gen_movi_i32(cpu_F0s
, n
);
3583 case 15: /* extension space */
3597 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3598 tmp
= gen_vfp_mrs();
3599 tcg_gen_ext16u_i32(tmp
, tmp
);
3601 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3604 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3607 tcg_temp_free_i32(tmp
);
3609 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3610 tmp
= gen_vfp_mrs();
3611 tcg_gen_shri_i32(tmp
, tmp
, 16);
3613 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3616 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3619 tcg_temp_free_i32(tmp
);
3621 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3622 tmp
= tcg_temp_new_i32();
3624 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3627 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3630 gen_mov_F0_vreg(0, rd
);
3631 tmp2
= gen_vfp_mrs();
3632 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3633 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3634 tcg_temp_free_i32(tmp2
);
3637 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3638 tmp
= tcg_temp_new_i32();
3640 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3643 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3646 tcg_gen_shli_i32(tmp
, tmp
, 16);
3647 gen_mov_F0_vreg(0, rd
);
3648 tmp2
= gen_vfp_mrs();
3649 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3650 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3651 tcg_temp_free_i32(tmp2
);
3663 case 11: /* cmpez */
3667 case 12: /* vrintr */
3669 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3671 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3673 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3675 tcg_temp_free_ptr(fpst
);
3678 case 13: /* vrintz */
3680 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3682 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3683 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3685 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3687 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3689 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3690 tcg_temp_free_i32(tcg_rmode
);
3691 tcg_temp_free_ptr(fpst
);
3694 case 14: /* vrintx */
3696 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3698 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3700 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3702 tcg_temp_free_ptr(fpst
);
3705 case 15: /* single<->double conversion */
3707 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3709 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3711 case 16: /* fuito */
3712 gen_vfp_uito(dp
, 0);
3714 case 17: /* fsito */
3715 gen_vfp_sito(dp
, 0);
3717 case 20: /* fshto */
3718 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3721 gen_vfp_shto(dp
, 16 - rm
, 0);
3723 case 21: /* fslto */
3724 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3727 gen_vfp_slto(dp
, 32 - rm
, 0);
3729 case 22: /* fuhto */
3730 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3733 gen_vfp_uhto(dp
, 16 - rm
, 0);
3735 case 23: /* fulto */
3736 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3739 gen_vfp_ulto(dp
, 32 - rm
, 0);
3741 case 24: /* ftoui */
3742 gen_vfp_toui(dp
, 0);
3744 case 25: /* ftouiz */
3745 gen_vfp_touiz(dp
, 0);
3747 case 26: /* ftosi */
3748 gen_vfp_tosi(dp
, 0);
3750 case 27: /* ftosiz */
3751 gen_vfp_tosiz(dp
, 0);
3753 case 28: /* ftosh */
3754 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3757 gen_vfp_tosh(dp
, 16 - rm
, 0);
3759 case 29: /* ftosl */
3760 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3763 gen_vfp_tosl(dp
, 32 - rm
, 0);
3765 case 30: /* ftouh */
3766 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3769 gen_vfp_touh(dp
, 16 - rm
, 0);
3771 case 31: /* ftoul */
3772 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3775 gen_vfp_toul(dp
, 32 - rm
, 0);
3777 default: /* undefined */
3781 default: /* undefined */
3785 /* Write back the result. */
3786 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3787 /* Comparison, do nothing. */
3788 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3789 (rn
& 0x1e) == 0x6)) {
3790 /* VCVT double to int: always integer result.
3791 * VCVT double to half precision is always a single
3794 gen_mov_vreg_F0(0, rd
);
3795 } else if (op
== 15 && rn
== 15) {
3797 gen_mov_vreg_F0(!dp
, rd
);
3799 gen_mov_vreg_F0(dp
, rd
);
3802 /* break out of the loop if we have finished */
3806 if (op
== 15 && delta_m
== 0) {
3807 /* single source one-many */
3809 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3811 gen_mov_vreg_F0(dp
, rd
);
3815 /* Setup the next operands. */
3817 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3821 /* One source operand. */
3822 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3824 gen_mov_F0_vreg(dp
, rm
);
3826 /* Two source operands. */
3827 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3829 gen_mov_F0_vreg(dp
, rn
);
3831 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3833 gen_mov_F1_vreg(dp
, rm
);
3841 if ((insn
& 0x03e00000) == 0x00400000) {
3842 /* two-register transfer */
3843 rn
= (insn
>> 16) & 0xf;
3844 rd
= (insn
>> 12) & 0xf;
3846 VFP_DREG_M(rm
, insn
);
3848 rm
= VFP_SREG_M(insn
);
3851 if (insn
& ARM_CP_RW_BIT
) {
3854 gen_mov_F0_vreg(0, rm
* 2);
3855 tmp
= gen_vfp_mrs();
3856 store_reg(s
, rd
, tmp
);
3857 gen_mov_F0_vreg(0, rm
* 2 + 1);
3858 tmp
= gen_vfp_mrs();
3859 store_reg(s
, rn
, tmp
);
3861 gen_mov_F0_vreg(0, rm
);
3862 tmp
= gen_vfp_mrs();
3863 store_reg(s
, rd
, tmp
);
3864 gen_mov_F0_vreg(0, rm
+ 1);
3865 tmp
= gen_vfp_mrs();
3866 store_reg(s
, rn
, tmp
);
3871 tmp
= load_reg(s
, rd
);
3873 gen_mov_vreg_F0(0, rm
* 2);
3874 tmp
= load_reg(s
, rn
);
3876 gen_mov_vreg_F0(0, rm
* 2 + 1);
3878 tmp
= load_reg(s
, rd
);
3880 gen_mov_vreg_F0(0, rm
);
3881 tmp
= load_reg(s
, rn
);
3883 gen_mov_vreg_F0(0, rm
+ 1);
3888 rn
= (insn
>> 16) & 0xf;
3890 VFP_DREG_D(rd
, insn
);
3892 rd
= VFP_SREG_D(insn
);
3893 if ((insn
& 0x01200000) == 0x01000000) {
3894 /* Single load/store */
3895 offset
= (insn
& 0xff) << 2;
3896 if ((insn
& (1 << 23)) == 0)
3898 if (s
->thumb
&& rn
== 15) {
3899 /* This is actually UNPREDICTABLE */
3900 addr
= tcg_temp_new_i32();
3901 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3903 addr
= load_reg(s
, rn
);
3905 tcg_gen_addi_i32(addr
, addr
, offset
);
3906 if (insn
& (1 << 20)) {
3907 gen_vfp_ld(s
, dp
, addr
);
3908 gen_mov_vreg_F0(dp
, rd
);
3910 gen_mov_F0_vreg(dp
, rd
);
3911 gen_vfp_st(s
, dp
, addr
);
3913 tcg_temp_free_i32(addr
);
3915 /* load/store multiple */
3916 int w
= insn
& (1 << 21);
3918 n
= (insn
>> 1) & 0x7f;
3922 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3923 /* P == U , W == 1 => UNDEF */
3926 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3927 /* UNPREDICTABLE cases for bad immediates: we choose to
3928 * UNDEF to avoid generating huge numbers of TCG ops
3932 if (rn
== 15 && w
) {
3933 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3937 if (s
->thumb
&& rn
== 15) {
3938 /* This is actually UNPREDICTABLE */
3939 addr
= tcg_temp_new_i32();
3940 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3942 addr
= load_reg(s
, rn
);
3944 if (insn
& (1 << 24)) /* pre-decrement */
3945 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3951 for (i
= 0; i
< n
; i
++) {
3952 if (insn
& ARM_CP_RW_BIT
) {
3954 gen_vfp_ld(s
, dp
, addr
);
3955 gen_mov_vreg_F0(dp
, rd
+ i
);
3958 gen_mov_F0_vreg(dp
, rd
+ i
);
3959 gen_vfp_st(s
, dp
, addr
);
3961 tcg_gen_addi_i32(addr
, addr
, offset
);
3965 if (insn
& (1 << 24))
3966 offset
= -offset
* n
;
3967 else if (dp
&& (insn
& 1))
3973 tcg_gen_addi_i32(addr
, addr
, offset
);
3974 store_reg(s
, rn
, addr
);
3976 tcg_temp_free_i32(addr
);
3982 /* Should never happen. */
3988 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3990 TranslationBlock
*tb
;
3993 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3995 gen_set_pc_im(s
, dest
);
3996 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3998 gen_set_pc_im(s
, dest
);
4003 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4005 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
4006 /* An indirect jump so that we still trigger the debug exception. */
4011 gen_goto_tb(s
, 0, dest
);
4012 s
->is_jmp
= DISAS_TB_JUMP
;
4016 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4019 tcg_gen_sari_i32(t0
, t0
, 16);
4023 tcg_gen_sari_i32(t1
, t1
, 16);
4026 tcg_gen_mul_i32(t0
, t0
, t1
);
4029 /* Return the mask of PSR bits set by a MSR instruction. */
4030 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4035 if (flags
& (1 << 0))
4037 if (flags
& (1 << 1))
4039 if (flags
& (1 << 2))
4041 if (flags
& (1 << 3))
4044 /* Mask out undefined bits. */
4045 mask
&= ~CPSR_RESERVED
;
4046 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4049 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4050 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4052 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4053 mask
&= ~(CPSR_E
| CPSR_GE
);
4055 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4058 /* Mask out execution state and reserved bits. */
4060 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4062 /* Mask out privileged bits. */
4068 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4069 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4073 /* ??? This is also undefined in system mode. */
4077 tmp
= load_cpu_field(spsr
);
4078 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4079 tcg_gen_andi_i32(t0
, t0
, mask
);
4080 tcg_gen_or_i32(tmp
, tmp
, t0
);
4081 store_cpu_field(tmp
, spsr
);
4083 gen_set_cpsr(t0
, mask
);
4085 tcg_temp_free_i32(t0
);
4090 /* Returns nonzero if access to the PSR is not permitted. */
4091 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4094 tmp
= tcg_temp_new_i32();
4095 tcg_gen_movi_i32(tmp
, val
);
4096 return gen_set_psr(s
, mask
, spsr
, tmp
);
4099 /* Generate an old-style exception return. Marks pc as dead. */
4100 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4103 store_reg(s
, 15, pc
);
4104 tmp
= load_cpu_field(spsr
);
4105 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
4106 tcg_temp_free_i32(tmp
);
4107 s
->is_jmp
= DISAS_JUMP
;
4110 /* Generate a v6 exception return. Marks both values as dead. */
4111 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4113 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4114 tcg_temp_free_i32(cpsr
);
4115 store_reg(s
, 15, pc
);
4116 s
->is_jmp
= DISAS_JUMP
;
4119 static void gen_nop_hint(DisasContext
*s
, int val
)
4123 gen_set_pc_im(s
, s
->pc
);
4124 s
->is_jmp
= DISAS_YIELD
;
4127 gen_set_pc_im(s
, s
->pc
);
4128 s
->is_jmp
= DISAS_WFI
;
4131 gen_set_pc_im(s
, s
->pc
);
4132 s
->is_jmp
= DISAS_WFE
;
4136 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4142 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4144 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4147 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4148 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4149 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4154 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4157 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4158 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4159 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4164 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4165 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4166 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4167 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4168 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4170 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4171 switch ((size << 1) | u) { \
4173 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4176 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4179 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4182 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4185 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4188 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4190 default: return 1; \
4193 #define GEN_NEON_INTEGER_OP(name) do { \
4194 switch ((size << 1) | u) { \
4196 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4199 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4202 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4205 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4208 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4211 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4213 default: return 1; \
4216 static TCGv_i32
neon_load_scratch(int scratch
)
4218 TCGv_i32 tmp
= tcg_temp_new_i32();
4219 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4223 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4225 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4226 tcg_temp_free_i32(var
);
4229 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4233 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4235 gen_neon_dup_high16(tmp
);
4237 gen_neon_dup_low16(tmp
);
4240 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4245 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4248 if (!q
&& size
== 2) {
4251 tmp
= tcg_const_i32(rd
);
4252 tmp2
= tcg_const_i32(rm
);
4256 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4259 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4262 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4270 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4273 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4279 tcg_temp_free_i32(tmp
);
4280 tcg_temp_free_i32(tmp2
);
4284 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4287 if (!q
&& size
== 2) {
4290 tmp
= tcg_const_i32(rd
);
4291 tmp2
= tcg_const_i32(rm
);
4295 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4298 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4301 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4309 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4312 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4318 tcg_temp_free_i32(tmp
);
4319 tcg_temp_free_i32(tmp2
);
4323 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4327 rd
= tcg_temp_new_i32();
4328 tmp
= tcg_temp_new_i32();
4330 tcg_gen_shli_i32(rd
, t0
, 8);
4331 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4332 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4333 tcg_gen_or_i32(rd
, rd
, tmp
);
4335 tcg_gen_shri_i32(t1
, t1
, 8);
4336 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4337 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4338 tcg_gen_or_i32(t1
, t1
, tmp
);
4339 tcg_gen_mov_i32(t0
, rd
);
4341 tcg_temp_free_i32(tmp
);
4342 tcg_temp_free_i32(rd
);
4345 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4349 rd
= tcg_temp_new_i32();
4350 tmp
= tcg_temp_new_i32();
4352 tcg_gen_shli_i32(rd
, t0
, 16);
4353 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4354 tcg_gen_or_i32(rd
, rd
, tmp
);
4355 tcg_gen_shri_i32(t1
, t1
, 16);
4356 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4357 tcg_gen_or_i32(t1
, t1
, tmp
);
4358 tcg_gen_mov_i32(t0
, rd
);
4360 tcg_temp_free_i32(tmp
);
4361 tcg_temp_free_i32(rd
);
4369 } neon_ls_element_type
[11] = {
4383 /* Translate a NEON load/store element instruction. Return nonzero if the
4384 instruction is invalid. */
4385 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4404 /* FIXME: this access check should not take precedence over UNDEF
4405 * for invalid encodings; we will generate incorrect syndrome information
4406 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4408 if (s
->fp_excp_el
) {
4409 gen_exception_insn(s
, 4, EXCP_UDEF
,
4410 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4414 if (!s
->vfp_enabled
)
4416 VFP_DREG_D(rd
, insn
);
4417 rn
= (insn
>> 16) & 0xf;
4419 load
= (insn
& (1 << 21)) != 0;
4420 if ((insn
& (1 << 23)) == 0) {
4421 /* Load store all elements. */
4422 op
= (insn
>> 8) & 0xf;
4423 size
= (insn
>> 6) & 3;
4426 /* Catch UNDEF cases for bad values of align field */
4429 if (((insn
>> 5) & 1) == 1) {
4434 if (((insn
>> 4) & 3) == 3) {
4441 nregs
= neon_ls_element_type
[op
].nregs
;
4442 interleave
= neon_ls_element_type
[op
].interleave
;
4443 spacing
= neon_ls_element_type
[op
].spacing
;
4444 if (size
== 3 && (interleave
| spacing
) != 1)
4446 addr
= tcg_temp_new_i32();
4447 load_reg_var(s
, addr
, rn
);
4448 stride
= (1 << size
) * interleave
;
4449 for (reg
= 0; reg
< nregs
; reg
++) {
4450 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4451 load_reg_var(s
, addr
, rn
);
4452 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4453 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4454 load_reg_var(s
, addr
, rn
);
4455 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4458 tmp64
= tcg_temp_new_i64();
4460 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4461 neon_store_reg64(tmp64
, rd
);
4463 neon_load_reg64(tmp64
, rd
);
4464 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4466 tcg_temp_free_i64(tmp64
);
4467 tcg_gen_addi_i32(addr
, addr
, stride
);
4469 for (pass
= 0; pass
< 2; pass
++) {
4472 tmp
= tcg_temp_new_i32();
4473 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4474 neon_store_reg(rd
, pass
, tmp
);
4476 tmp
= neon_load_reg(rd
, pass
);
4477 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4478 tcg_temp_free_i32(tmp
);
4480 tcg_gen_addi_i32(addr
, addr
, stride
);
4481 } else if (size
== 1) {
4483 tmp
= tcg_temp_new_i32();
4484 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4485 tcg_gen_addi_i32(addr
, addr
, stride
);
4486 tmp2
= tcg_temp_new_i32();
4487 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4488 tcg_gen_addi_i32(addr
, addr
, stride
);
4489 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4490 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4491 tcg_temp_free_i32(tmp2
);
4492 neon_store_reg(rd
, pass
, tmp
);
4494 tmp
= neon_load_reg(rd
, pass
);
4495 tmp2
= tcg_temp_new_i32();
4496 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4497 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4498 tcg_temp_free_i32(tmp
);
4499 tcg_gen_addi_i32(addr
, addr
, stride
);
4500 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4501 tcg_temp_free_i32(tmp2
);
4502 tcg_gen_addi_i32(addr
, addr
, stride
);
4504 } else /* size == 0 */ {
4506 TCGV_UNUSED_I32(tmp2
);
4507 for (n
= 0; n
< 4; n
++) {
4508 tmp
= tcg_temp_new_i32();
4509 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4510 tcg_gen_addi_i32(addr
, addr
, stride
);
4514 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4515 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4516 tcg_temp_free_i32(tmp
);
4519 neon_store_reg(rd
, pass
, tmp2
);
4521 tmp2
= neon_load_reg(rd
, pass
);
4522 for (n
= 0; n
< 4; n
++) {
4523 tmp
= tcg_temp_new_i32();
4525 tcg_gen_mov_i32(tmp
, tmp2
);
4527 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4529 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4530 tcg_temp_free_i32(tmp
);
4531 tcg_gen_addi_i32(addr
, addr
, stride
);
4533 tcg_temp_free_i32(tmp2
);
4540 tcg_temp_free_i32(addr
);
4543 size
= (insn
>> 10) & 3;
4545 /* Load single element to all lanes. */
4546 int a
= (insn
>> 4) & 1;
4550 size
= (insn
>> 6) & 3;
4551 nregs
= ((insn
>> 8) & 3) + 1;
4554 if (nregs
!= 4 || a
== 0) {
4557 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4560 if (nregs
== 1 && a
== 1 && size
== 0) {
4563 if (nregs
== 3 && a
== 1) {
4566 addr
= tcg_temp_new_i32();
4567 load_reg_var(s
, addr
, rn
);
4569 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4570 tmp
= gen_load_and_replicate(s
, addr
, size
);
4571 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4572 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4573 if (insn
& (1 << 5)) {
4574 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4575 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4577 tcg_temp_free_i32(tmp
);
4579 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4580 stride
= (insn
& (1 << 5)) ? 2 : 1;
4581 for (reg
= 0; reg
< nregs
; reg
++) {
4582 tmp
= gen_load_and_replicate(s
, addr
, size
);
4583 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4584 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4585 tcg_temp_free_i32(tmp
);
4586 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4590 tcg_temp_free_i32(addr
);
4591 stride
= (1 << size
) * nregs
;
4593 /* Single element. */
4594 int idx
= (insn
>> 4) & 0xf;
4595 pass
= (insn
>> 7) & 1;
4598 shift
= ((insn
>> 5) & 3) * 8;
4602 shift
= ((insn
>> 6) & 1) * 16;
4603 stride
= (insn
& (1 << 5)) ? 2 : 1;
4607 stride
= (insn
& (1 << 6)) ? 2 : 1;
4612 nregs
= ((insn
>> 8) & 3) + 1;
4613 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4616 if (((idx
& (1 << size
)) != 0) ||
4617 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4622 if ((idx
& 1) != 0) {
4627 if (size
== 2 && (idx
& 2) != 0) {
4632 if ((size
== 2) && ((idx
& 3) == 3)) {
4639 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4640 /* Attempts to write off the end of the register file
4641 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4642 * the neon_load_reg() would write off the end of the array.
4646 addr
= tcg_temp_new_i32();
4647 load_reg_var(s
, addr
, rn
);
4648 for (reg
= 0; reg
< nregs
; reg
++) {
4650 tmp
= tcg_temp_new_i32();
4653 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4656 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4659 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4661 default: /* Avoid compiler warnings. */
4665 tmp2
= neon_load_reg(rd
, pass
);
4666 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4667 shift
, size
? 16 : 8);
4668 tcg_temp_free_i32(tmp2
);
4670 neon_store_reg(rd
, pass
, tmp
);
4671 } else { /* Store */
4672 tmp
= neon_load_reg(rd
, pass
);
4674 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4677 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4680 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4683 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4686 tcg_temp_free_i32(tmp
);
4689 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4691 tcg_temp_free_i32(addr
);
4692 stride
= nregs
* (1 << size
);
4698 base
= load_reg(s
, rn
);
4700 tcg_gen_addi_i32(base
, base
, stride
);
4703 index
= load_reg(s
, rm
);
4704 tcg_gen_add_i32(base
, base
, index
);
4705 tcg_temp_free_i32(index
);
4707 store_reg(s
, rn
, base
);
4712 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4713 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4715 tcg_gen_and_i32(t
, t
, c
);
4716 tcg_gen_andc_i32(f
, f
, c
);
4717 tcg_gen_or_i32(dest
, t
, f
);
4720 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4723 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4724 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4725 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4730 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4733 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4734 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4735 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4740 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4743 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4744 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4745 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4750 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4753 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4754 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4755 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4760 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4766 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4767 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4772 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4773 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4780 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4781 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4786 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4787 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4794 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4798 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4799 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4800 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4805 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4806 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4807 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4811 tcg_temp_free_i32(src
);
4814 static inline void gen_neon_addl(int size
)
4817 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4818 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4819 case 2: tcg_gen_add_i64(CPU_V001
); break;
4824 static inline void gen_neon_subl(int size
)
4827 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4828 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4829 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4834 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4837 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4838 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4840 tcg_gen_neg_i64(var
, var
);
4846 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4849 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4850 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4855 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4860 switch ((size
<< 1) | u
) {
4861 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4862 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4863 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4864 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4866 tmp
= gen_muls_i64_i32(a
, b
);
4867 tcg_gen_mov_i64(dest
, tmp
);
4868 tcg_temp_free_i64(tmp
);
4871 tmp
= gen_mulu_i64_i32(a
, b
);
4872 tcg_gen_mov_i64(dest
, tmp
);
4873 tcg_temp_free_i64(tmp
);
4878 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4879 Don't forget to clean them now. */
4881 tcg_temp_free_i32(a
);
4882 tcg_temp_free_i32(b
);
4886 static void gen_neon_narrow_op(int op
, int u
, int size
,
4887 TCGv_i32 dest
, TCGv_i64 src
)
4891 gen_neon_unarrow_sats(size
, dest
, src
);
4893 gen_neon_narrow(size
, dest
, src
);
4897 gen_neon_narrow_satu(size
, dest
, src
);
4899 gen_neon_narrow_sats(size
, dest
, src
);
4904 /* Symbolic constants for op fields for Neon 3-register same-length.
4905 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4908 #define NEON_3R_VHADD 0
4909 #define NEON_3R_VQADD 1
4910 #define NEON_3R_VRHADD 2
4911 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4912 #define NEON_3R_VHSUB 4
4913 #define NEON_3R_VQSUB 5
4914 #define NEON_3R_VCGT 6
4915 #define NEON_3R_VCGE 7
4916 #define NEON_3R_VSHL 8
4917 #define NEON_3R_VQSHL 9
4918 #define NEON_3R_VRSHL 10
4919 #define NEON_3R_VQRSHL 11
4920 #define NEON_3R_VMAX 12
4921 #define NEON_3R_VMIN 13
4922 #define NEON_3R_VABD 14
4923 #define NEON_3R_VABA 15
4924 #define NEON_3R_VADD_VSUB 16
4925 #define NEON_3R_VTST_VCEQ 17
4926 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4927 #define NEON_3R_VMUL 19
4928 #define NEON_3R_VPMAX 20
4929 #define NEON_3R_VPMIN 21
4930 #define NEON_3R_VQDMULH_VQRDMULH 22
4931 #define NEON_3R_VPADD 23
4932 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4933 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4934 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4935 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4936 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4937 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4938 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4939 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4941 static const uint8_t neon_3r_sizes
[] = {
4942 [NEON_3R_VHADD
] = 0x7,
4943 [NEON_3R_VQADD
] = 0xf,
4944 [NEON_3R_VRHADD
] = 0x7,
4945 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4946 [NEON_3R_VHSUB
] = 0x7,
4947 [NEON_3R_VQSUB
] = 0xf,
4948 [NEON_3R_VCGT
] = 0x7,
4949 [NEON_3R_VCGE
] = 0x7,
4950 [NEON_3R_VSHL
] = 0xf,
4951 [NEON_3R_VQSHL
] = 0xf,
4952 [NEON_3R_VRSHL
] = 0xf,
4953 [NEON_3R_VQRSHL
] = 0xf,
4954 [NEON_3R_VMAX
] = 0x7,
4955 [NEON_3R_VMIN
] = 0x7,
4956 [NEON_3R_VABD
] = 0x7,
4957 [NEON_3R_VABA
] = 0x7,
4958 [NEON_3R_VADD_VSUB
] = 0xf,
4959 [NEON_3R_VTST_VCEQ
] = 0x7,
4960 [NEON_3R_VML
] = 0x7,
4961 [NEON_3R_VMUL
] = 0x7,
4962 [NEON_3R_VPMAX
] = 0x7,
4963 [NEON_3R_VPMIN
] = 0x7,
4964 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4965 [NEON_3R_VPADD
] = 0x7,
4966 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4967 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4968 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4969 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4970 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4971 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4972 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4973 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4976 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4977 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4980 #define NEON_2RM_VREV64 0
4981 #define NEON_2RM_VREV32 1
4982 #define NEON_2RM_VREV16 2
4983 #define NEON_2RM_VPADDL 4
4984 #define NEON_2RM_VPADDL_U 5
4985 #define NEON_2RM_AESE 6 /* Includes AESD */
4986 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4987 #define NEON_2RM_VCLS 8
4988 #define NEON_2RM_VCLZ 9
4989 #define NEON_2RM_VCNT 10
4990 #define NEON_2RM_VMVN 11
4991 #define NEON_2RM_VPADAL 12
4992 #define NEON_2RM_VPADAL_U 13
4993 #define NEON_2RM_VQABS 14
4994 #define NEON_2RM_VQNEG 15
4995 #define NEON_2RM_VCGT0 16
4996 #define NEON_2RM_VCGE0 17
4997 #define NEON_2RM_VCEQ0 18
4998 #define NEON_2RM_VCLE0 19
4999 #define NEON_2RM_VCLT0 20
5000 #define NEON_2RM_SHA1H 21
5001 #define NEON_2RM_VABS 22
5002 #define NEON_2RM_VNEG 23
5003 #define NEON_2RM_VCGT0_F 24
5004 #define NEON_2RM_VCGE0_F 25
5005 #define NEON_2RM_VCEQ0_F 26
5006 #define NEON_2RM_VCLE0_F 27
5007 #define NEON_2RM_VCLT0_F 28
5008 #define NEON_2RM_VABS_F 30
5009 #define NEON_2RM_VNEG_F 31
5010 #define NEON_2RM_VSWP 32
5011 #define NEON_2RM_VTRN 33
5012 #define NEON_2RM_VUZP 34
5013 #define NEON_2RM_VZIP 35
5014 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5015 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5016 #define NEON_2RM_VSHLL 38
5017 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5018 #define NEON_2RM_VRINTN 40
5019 #define NEON_2RM_VRINTX 41
5020 #define NEON_2RM_VRINTA 42
5021 #define NEON_2RM_VRINTZ 43
5022 #define NEON_2RM_VCVT_F16_F32 44
5023 #define NEON_2RM_VRINTM 45
5024 #define NEON_2RM_VCVT_F32_F16 46
5025 #define NEON_2RM_VRINTP 47
5026 #define NEON_2RM_VCVTAU 48
5027 #define NEON_2RM_VCVTAS 49
5028 #define NEON_2RM_VCVTNU 50
5029 #define NEON_2RM_VCVTNS 51
5030 #define NEON_2RM_VCVTPU 52
5031 #define NEON_2RM_VCVTPS 53
5032 #define NEON_2RM_VCVTMU 54
5033 #define NEON_2RM_VCVTMS 55
5034 #define NEON_2RM_VRECPE 56
5035 #define NEON_2RM_VRSQRTE 57
5036 #define NEON_2RM_VRECPE_F 58
5037 #define NEON_2RM_VRSQRTE_F 59
5038 #define NEON_2RM_VCVT_FS 60
5039 #define NEON_2RM_VCVT_FU 61
5040 #define NEON_2RM_VCVT_SF 62
5041 #define NEON_2RM_VCVT_UF 63
5043 static int neon_2rm_is_float_op(int op
)
5045 /* Return true if this neon 2reg-misc op is float-to-float */
5046 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5047 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5048 op
== NEON_2RM_VRINTM
||
5049 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5050 op
>= NEON_2RM_VRECPE_F
);
5053 /* Each entry in this array has bit n set if the insn allows
5054 * size value n (otherwise it will UNDEF). Since unallocated
5055 * op values will have no bits set they always UNDEF.
5057 static const uint8_t neon_2rm_sizes
[] = {
5058 [NEON_2RM_VREV64
] = 0x7,
5059 [NEON_2RM_VREV32
] = 0x3,
5060 [NEON_2RM_VREV16
] = 0x1,
5061 [NEON_2RM_VPADDL
] = 0x7,
5062 [NEON_2RM_VPADDL_U
] = 0x7,
5063 [NEON_2RM_AESE
] = 0x1,
5064 [NEON_2RM_AESMC
] = 0x1,
5065 [NEON_2RM_VCLS
] = 0x7,
5066 [NEON_2RM_VCLZ
] = 0x7,
5067 [NEON_2RM_VCNT
] = 0x1,
5068 [NEON_2RM_VMVN
] = 0x1,
5069 [NEON_2RM_VPADAL
] = 0x7,
5070 [NEON_2RM_VPADAL_U
] = 0x7,
5071 [NEON_2RM_VQABS
] = 0x7,
5072 [NEON_2RM_VQNEG
] = 0x7,
5073 [NEON_2RM_VCGT0
] = 0x7,
5074 [NEON_2RM_VCGE0
] = 0x7,
5075 [NEON_2RM_VCEQ0
] = 0x7,
5076 [NEON_2RM_VCLE0
] = 0x7,
5077 [NEON_2RM_VCLT0
] = 0x7,
5078 [NEON_2RM_SHA1H
] = 0x4,
5079 [NEON_2RM_VABS
] = 0x7,
5080 [NEON_2RM_VNEG
] = 0x7,
5081 [NEON_2RM_VCGT0_F
] = 0x4,
5082 [NEON_2RM_VCGE0_F
] = 0x4,
5083 [NEON_2RM_VCEQ0_F
] = 0x4,
5084 [NEON_2RM_VCLE0_F
] = 0x4,
5085 [NEON_2RM_VCLT0_F
] = 0x4,
5086 [NEON_2RM_VABS_F
] = 0x4,
5087 [NEON_2RM_VNEG_F
] = 0x4,
5088 [NEON_2RM_VSWP
] = 0x1,
5089 [NEON_2RM_VTRN
] = 0x7,
5090 [NEON_2RM_VUZP
] = 0x7,
5091 [NEON_2RM_VZIP
] = 0x7,
5092 [NEON_2RM_VMOVN
] = 0x7,
5093 [NEON_2RM_VQMOVN
] = 0x7,
5094 [NEON_2RM_VSHLL
] = 0x7,
5095 [NEON_2RM_SHA1SU1
] = 0x4,
5096 [NEON_2RM_VRINTN
] = 0x4,
5097 [NEON_2RM_VRINTX
] = 0x4,
5098 [NEON_2RM_VRINTA
] = 0x4,
5099 [NEON_2RM_VRINTZ
] = 0x4,
5100 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5101 [NEON_2RM_VRINTM
] = 0x4,
5102 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5103 [NEON_2RM_VRINTP
] = 0x4,
5104 [NEON_2RM_VCVTAU
] = 0x4,
5105 [NEON_2RM_VCVTAS
] = 0x4,
5106 [NEON_2RM_VCVTNU
] = 0x4,
5107 [NEON_2RM_VCVTNS
] = 0x4,
5108 [NEON_2RM_VCVTPU
] = 0x4,
5109 [NEON_2RM_VCVTPS
] = 0x4,
5110 [NEON_2RM_VCVTMU
] = 0x4,
5111 [NEON_2RM_VCVTMS
] = 0x4,
5112 [NEON_2RM_VRECPE
] = 0x4,
5113 [NEON_2RM_VRSQRTE
] = 0x4,
5114 [NEON_2RM_VRECPE_F
] = 0x4,
5115 [NEON_2RM_VRSQRTE_F
] = 0x4,
5116 [NEON_2RM_VCVT_FS
] = 0x4,
5117 [NEON_2RM_VCVT_FU
] = 0x4,
5118 [NEON_2RM_VCVT_SF
] = 0x4,
5119 [NEON_2RM_VCVT_UF
] = 0x4,
5122 /* Translate a NEON data processing instruction. Return nonzero if the
5123 instruction is invalid.
5124 We process data in a mixture of 32-bit and 64-bit chunks.
5125 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5127 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5139 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5142 /* FIXME: this access check should not take precedence over UNDEF
5143 * for invalid encodings; we will generate incorrect syndrome information
5144 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5146 if (s
->fp_excp_el
) {
5147 gen_exception_insn(s
, 4, EXCP_UDEF
,
5148 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5152 if (!s
->vfp_enabled
)
5154 q
= (insn
& (1 << 6)) != 0;
5155 u
= (insn
>> 24) & 1;
5156 VFP_DREG_D(rd
, insn
);
5157 VFP_DREG_N(rn
, insn
);
5158 VFP_DREG_M(rm
, insn
);
5159 size
= (insn
>> 20) & 3;
5160 if ((insn
& (1 << 23)) == 0) {
5161 /* Three register same length. */
5162 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5163 /* Catch invalid op and bad size combinations: UNDEF */
5164 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5167 /* All insns of this form UNDEF for either this condition or the
5168 * superset of cases "Q==1"; we catch the latter later.
5170 if (q
&& ((rd
| rn
| rm
) & 1)) {
5174 * The SHA-1/SHA-256 3-register instructions require special treatment
5175 * here, as their size field is overloaded as an op type selector, and
5176 * they all consume their input in a single pass.
5178 if (op
== NEON_3R_SHA
) {
5182 if (!u
) { /* SHA-1 */
5183 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5186 tmp
= tcg_const_i32(rd
);
5187 tmp2
= tcg_const_i32(rn
);
5188 tmp3
= tcg_const_i32(rm
);
5189 tmp4
= tcg_const_i32(size
);
5190 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5191 tcg_temp_free_i32(tmp4
);
5192 } else { /* SHA-256 */
5193 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5196 tmp
= tcg_const_i32(rd
);
5197 tmp2
= tcg_const_i32(rn
);
5198 tmp3
= tcg_const_i32(rm
);
5201 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5204 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5207 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5211 tcg_temp_free_i32(tmp
);
5212 tcg_temp_free_i32(tmp2
);
5213 tcg_temp_free_i32(tmp3
);
5216 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5217 /* 64-bit element instructions. */
5218 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5219 neon_load_reg64(cpu_V0
, rn
+ pass
);
5220 neon_load_reg64(cpu_V1
, rm
+ pass
);
5224 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5227 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5233 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5236 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5242 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5244 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5249 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5252 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5258 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5260 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5263 case NEON_3R_VQRSHL
:
5265 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5268 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5272 case NEON_3R_VADD_VSUB
:
5274 tcg_gen_sub_i64(CPU_V001
);
5276 tcg_gen_add_i64(CPU_V001
);
5282 neon_store_reg64(cpu_V0
, rd
+ pass
);
5291 case NEON_3R_VQRSHL
:
5294 /* Shift instruction operands are reversed. */
5309 case NEON_3R_FLOAT_ARITH
:
5310 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5312 case NEON_3R_FLOAT_MINMAX
:
5313 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5315 case NEON_3R_FLOAT_CMP
:
5317 /* no encoding for U=0 C=1x */
5321 case NEON_3R_FLOAT_ACMP
:
5326 case NEON_3R_FLOAT_MISC
:
5327 /* VMAXNM/VMINNM in ARMv8 */
5328 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5333 if (u
&& (size
!= 0)) {
5334 /* UNDEF on invalid size for polynomial subcase */
5339 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5347 if (pairwise
&& q
) {
5348 /* All the pairwise insns UNDEF if Q is set */
5352 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5357 tmp
= neon_load_reg(rn
, 0);
5358 tmp2
= neon_load_reg(rn
, 1);
5360 tmp
= neon_load_reg(rm
, 0);
5361 tmp2
= neon_load_reg(rm
, 1);
5365 tmp
= neon_load_reg(rn
, pass
);
5366 tmp2
= neon_load_reg(rm
, pass
);
5370 GEN_NEON_INTEGER_OP(hadd
);
5373 GEN_NEON_INTEGER_OP_ENV(qadd
);
5375 case NEON_3R_VRHADD
:
5376 GEN_NEON_INTEGER_OP(rhadd
);
5378 case NEON_3R_LOGIC
: /* Logic ops. */
5379 switch ((u
<< 2) | size
) {
5381 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5384 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5387 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5390 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5393 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5396 tmp3
= neon_load_reg(rd
, pass
);
5397 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5398 tcg_temp_free_i32(tmp3
);
5401 tmp3
= neon_load_reg(rd
, pass
);
5402 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5403 tcg_temp_free_i32(tmp3
);
5406 tmp3
= neon_load_reg(rd
, pass
);
5407 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5408 tcg_temp_free_i32(tmp3
);
5413 GEN_NEON_INTEGER_OP(hsub
);
5416 GEN_NEON_INTEGER_OP_ENV(qsub
);
5419 GEN_NEON_INTEGER_OP(cgt
);
5422 GEN_NEON_INTEGER_OP(cge
);
5425 GEN_NEON_INTEGER_OP(shl
);
5428 GEN_NEON_INTEGER_OP_ENV(qshl
);
5431 GEN_NEON_INTEGER_OP(rshl
);
5433 case NEON_3R_VQRSHL
:
5434 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5437 GEN_NEON_INTEGER_OP(max
);
5440 GEN_NEON_INTEGER_OP(min
);
5443 GEN_NEON_INTEGER_OP(abd
);
5446 GEN_NEON_INTEGER_OP(abd
);
5447 tcg_temp_free_i32(tmp2
);
5448 tmp2
= neon_load_reg(rd
, pass
);
5449 gen_neon_add(size
, tmp
, tmp2
);
5451 case NEON_3R_VADD_VSUB
:
5452 if (!u
) { /* VADD */
5453 gen_neon_add(size
, tmp
, tmp2
);
5456 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5457 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5458 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5463 case NEON_3R_VTST_VCEQ
:
5464 if (!u
) { /* VTST */
5466 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5467 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5468 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5473 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5474 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5475 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5480 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5482 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5483 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5484 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5487 tcg_temp_free_i32(tmp2
);
5488 tmp2
= neon_load_reg(rd
, pass
);
5490 gen_neon_rsb(size
, tmp
, tmp2
);
5492 gen_neon_add(size
, tmp
, tmp2
);
5496 if (u
) { /* polynomial */
5497 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5498 } else { /* Integer */
5500 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5501 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5502 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5508 GEN_NEON_INTEGER_OP(pmax
);
5511 GEN_NEON_INTEGER_OP(pmin
);
5513 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5514 if (!u
) { /* VQDMULH */
5517 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5520 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5524 } else { /* VQRDMULH */
5527 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5530 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5538 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5539 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5540 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5544 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5546 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5547 switch ((u
<< 2) | size
) {
5550 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5553 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5556 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5561 tcg_temp_free_ptr(fpstatus
);
5564 case NEON_3R_FLOAT_MULTIPLY
:
5566 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5567 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5569 tcg_temp_free_i32(tmp2
);
5570 tmp2
= neon_load_reg(rd
, pass
);
5572 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5574 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5577 tcg_temp_free_ptr(fpstatus
);
5580 case NEON_3R_FLOAT_CMP
:
5582 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5584 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5587 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5589 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5592 tcg_temp_free_ptr(fpstatus
);
5595 case NEON_3R_FLOAT_ACMP
:
5597 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5599 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5601 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5603 tcg_temp_free_ptr(fpstatus
);
5606 case NEON_3R_FLOAT_MINMAX
:
5608 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5610 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5612 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5614 tcg_temp_free_ptr(fpstatus
);
5617 case NEON_3R_FLOAT_MISC
:
5620 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5622 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5624 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5626 tcg_temp_free_ptr(fpstatus
);
5629 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5631 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5637 /* VFMA, VFMS: fused multiply-add */
5638 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5639 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5642 gen_helper_vfp_negs(tmp
, tmp
);
5644 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5645 tcg_temp_free_i32(tmp3
);
5646 tcg_temp_free_ptr(fpstatus
);
5652 tcg_temp_free_i32(tmp2
);
5654 /* Save the result. For elementwise operations we can put it
5655 straight into the destination register. For pairwise operations
5656 we have to be careful to avoid clobbering the source operands. */
5657 if (pairwise
&& rd
== rm
) {
5658 neon_store_scratch(pass
, tmp
);
5660 neon_store_reg(rd
, pass
, tmp
);
5664 if (pairwise
&& rd
== rm
) {
5665 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5666 tmp
= neon_load_scratch(pass
);
5667 neon_store_reg(rd
, pass
, tmp
);
5670 /* End of 3 register same size operations. */
5671 } else if (insn
& (1 << 4)) {
5672 if ((insn
& 0x00380080) != 0) {
5673 /* Two registers and shift. */
5674 op
= (insn
>> 8) & 0xf;
5675 if (insn
& (1 << 7)) {
5683 while ((insn
& (1 << (size
+ 19))) == 0)
5686 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5687 /* To avoid excessive duplication of ops we implement shift
5688 by immediate using the variable shift operations. */
5690 /* Shift by immediate:
5691 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5692 if (q
&& ((rd
| rm
) & 1)) {
5695 if (!u
&& (op
== 4 || op
== 6)) {
5698 /* Right shifts are encoded as N - shift, where N is the
5699 element size in bits. */
5701 shift
= shift
- (1 << (size
+ 3));
5709 imm
= (uint8_t) shift
;
5714 imm
= (uint16_t) shift
;
5725 for (pass
= 0; pass
< count
; pass
++) {
5727 neon_load_reg64(cpu_V0
, rm
+ pass
);
5728 tcg_gen_movi_i64(cpu_V1
, imm
);
5733 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5735 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5740 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5742 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5745 case 5: /* VSHL, VSLI */
5746 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5748 case 6: /* VQSHLU */
5749 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5754 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5757 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5762 if (op
== 1 || op
== 3) {
5764 neon_load_reg64(cpu_V1
, rd
+ pass
);
5765 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5766 } else if (op
== 4 || (op
== 5 && u
)) {
5768 neon_load_reg64(cpu_V1
, rd
+ pass
);
5770 if (shift
< -63 || shift
> 63) {
5774 mask
= 0xffffffffffffffffull
>> -shift
;
5776 mask
= 0xffffffffffffffffull
<< shift
;
5779 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5780 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5782 neon_store_reg64(cpu_V0
, rd
+ pass
);
5783 } else { /* size < 3 */
5784 /* Operands in T0 and T1. */
5785 tmp
= neon_load_reg(rm
, pass
);
5786 tmp2
= tcg_temp_new_i32();
5787 tcg_gen_movi_i32(tmp2
, imm
);
5791 GEN_NEON_INTEGER_OP(shl
);
5795 GEN_NEON_INTEGER_OP(rshl
);
5798 case 5: /* VSHL, VSLI */
5800 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5801 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5802 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5806 case 6: /* VQSHLU */
5809 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5813 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5817 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5825 GEN_NEON_INTEGER_OP_ENV(qshl
);
5828 tcg_temp_free_i32(tmp2
);
5830 if (op
== 1 || op
== 3) {
5832 tmp2
= neon_load_reg(rd
, pass
);
5833 gen_neon_add(size
, tmp
, tmp2
);
5834 tcg_temp_free_i32(tmp2
);
5835 } else if (op
== 4 || (op
== 5 && u
)) {
5840 mask
= 0xff >> -shift
;
5842 mask
= (uint8_t)(0xff << shift
);
5848 mask
= 0xffff >> -shift
;
5850 mask
= (uint16_t)(0xffff << shift
);
5854 if (shift
< -31 || shift
> 31) {
5858 mask
= 0xffffffffu
>> -shift
;
5860 mask
= 0xffffffffu
<< shift
;
5866 tmp2
= neon_load_reg(rd
, pass
);
5867 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5868 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5869 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5870 tcg_temp_free_i32(tmp2
);
5872 neon_store_reg(rd
, pass
, tmp
);
5875 } else if (op
< 10) {
5876 /* Shift by immediate and narrow:
5877 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5878 int input_unsigned
= (op
== 8) ? !u
: u
;
5882 shift
= shift
- (1 << (size
+ 3));
5885 tmp64
= tcg_const_i64(shift
);
5886 neon_load_reg64(cpu_V0
, rm
);
5887 neon_load_reg64(cpu_V1
, rm
+ 1);
5888 for (pass
= 0; pass
< 2; pass
++) {
5896 if (input_unsigned
) {
5897 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5899 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5902 if (input_unsigned
) {
5903 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5905 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5908 tmp
= tcg_temp_new_i32();
5909 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5910 neon_store_reg(rd
, pass
, tmp
);
5912 tcg_temp_free_i64(tmp64
);
5915 imm
= (uint16_t)shift
;
5919 imm
= (uint32_t)shift
;
5921 tmp2
= tcg_const_i32(imm
);
5922 tmp4
= neon_load_reg(rm
+ 1, 0);
5923 tmp5
= neon_load_reg(rm
+ 1, 1);
5924 for (pass
= 0; pass
< 2; pass
++) {
5926 tmp
= neon_load_reg(rm
, 0);
5930 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5933 tmp3
= neon_load_reg(rm
, 1);
5937 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5939 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5940 tcg_temp_free_i32(tmp
);
5941 tcg_temp_free_i32(tmp3
);
5942 tmp
= tcg_temp_new_i32();
5943 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5944 neon_store_reg(rd
, pass
, tmp
);
5946 tcg_temp_free_i32(tmp2
);
5948 } else if (op
== 10) {
5950 if (q
|| (rd
& 1)) {
5953 tmp
= neon_load_reg(rm
, 0);
5954 tmp2
= neon_load_reg(rm
, 1);
5955 for (pass
= 0; pass
< 2; pass
++) {
5959 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5962 /* The shift is less than the width of the source
5963 type, so we can just shift the whole register. */
5964 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5965 /* Widen the result of shift: we need to clear
5966 * the potential overflow bits resulting from
5967 * left bits of the narrow input appearing as
5968 * right bits of left the neighbour narrow
5970 if (size
< 2 || !u
) {
5973 imm
= (0xffu
>> (8 - shift
));
5975 } else if (size
== 1) {
5976 imm
= 0xffff >> (16 - shift
);
5979 imm
= 0xffffffff >> (32 - shift
);
5982 imm64
= imm
| (((uint64_t)imm
) << 32);
5986 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5989 neon_store_reg64(cpu_V0
, rd
+ pass
);
5991 } else if (op
>= 14) {
5992 /* VCVT fixed-point. */
5993 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5996 /* We have already masked out the must-be-1 top bit of imm6,
5997 * hence this 32-shift where the ARM ARM has 64-imm6.
6000 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6001 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6004 gen_vfp_ulto(0, shift
, 1);
6006 gen_vfp_slto(0, shift
, 1);
6009 gen_vfp_toul(0, shift
, 1);
6011 gen_vfp_tosl(0, shift
, 1);
6013 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6018 } else { /* (insn & 0x00380080) == 0 */
6020 if (q
&& (rd
& 1)) {
6024 op
= (insn
>> 8) & 0xf;
6025 /* One register and immediate. */
6026 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6027 invert
= (insn
& (1 << 5)) != 0;
6028 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6029 * We choose to not special-case this and will behave as if a
6030 * valid constant encoding of 0 had been given.
6049 imm
= (imm
<< 8) | (imm
<< 24);
6052 imm
= (imm
<< 8) | 0xff;
6055 imm
= (imm
<< 16) | 0xffff;
6058 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6066 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6067 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6073 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6074 if (op
& 1 && op
< 12) {
6075 tmp
= neon_load_reg(rd
, pass
);
6077 /* The immediate value has already been inverted, so
6079 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6081 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6085 tmp
= tcg_temp_new_i32();
6086 if (op
== 14 && invert
) {
6090 for (n
= 0; n
< 4; n
++) {
6091 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6092 val
|= 0xff << (n
* 8);
6094 tcg_gen_movi_i32(tmp
, val
);
6096 tcg_gen_movi_i32(tmp
, imm
);
6099 neon_store_reg(rd
, pass
, tmp
);
6102 } else { /* (insn & 0x00800010 == 0x00800000) */
6104 op
= (insn
>> 8) & 0xf;
6105 if ((insn
& (1 << 6)) == 0) {
6106 /* Three registers of different lengths. */
6110 /* undefreq: bit 0 : UNDEF if size == 0
6111 * bit 1 : UNDEF if size == 1
6112 * bit 2 : UNDEF if size == 2
6113 * bit 3 : UNDEF if U == 1
6114 * Note that [2:0] set implies 'always UNDEF'
6117 /* prewiden, src1_wide, src2_wide, undefreq */
6118 static const int neon_3reg_wide
[16][4] = {
6119 {1, 0, 0, 0}, /* VADDL */
6120 {1, 1, 0, 0}, /* VADDW */
6121 {1, 0, 0, 0}, /* VSUBL */
6122 {1, 1, 0, 0}, /* VSUBW */
6123 {0, 1, 1, 0}, /* VADDHN */
6124 {0, 0, 0, 0}, /* VABAL */
6125 {0, 1, 1, 0}, /* VSUBHN */
6126 {0, 0, 0, 0}, /* VABDL */
6127 {0, 0, 0, 0}, /* VMLAL */
6128 {0, 0, 0, 9}, /* VQDMLAL */
6129 {0, 0, 0, 0}, /* VMLSL */
6130 {0, 0, 0, 9}, /* VQDMLSL */
6131 {0, 0, 0, 0}, /* Integer VMULL */
6132 {0, 0, 0, 1}, /* VQDMULL */
6133 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6134 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6137 prewiden
= neon_3reg_wide
[op
][0];
6138 src1_wide
= neon_3reg_wide
[op
][1];
6139 src2_wide
= neon_3reg_wide
[op
][2];
6140 undefreq
= neon_3reg_wide
[op
][3];
6142 if ((undefreq
& (1 << size
)) ||
6143 ((undefreq
& 8) && u
)) {
6146 if ((src1_wide
&& (rn
& 1)) ||
6147 (src2_wide
&& (rm
& 1)) ||
6148 (!src2_wide
&& (rd
& 1))) {
6152 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6153 * outside the loop below as it only performs a single pass.
6155 if (op
== 14 && size
== 2) {
6156 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6158 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6161 tcg_rn
= tcg_temp_new_i64();
6162 tcg_rm
= tcg_temp_new_i64();
6163 tcg_rd
= tcg_temp_new_i64();
6164 neon_load_reg64(tcg_rn
, rn
);
6165 neon_load_reg64(tcg_rm
, rm
);
6166 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6167 neon_store_reg64(tcg_rd
, rd
);
6168 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6169 neon_store_reg64(tcg_rd
, rd
+ 1);
6170 tcg_temp_free_i64(tcg_rn
);
6171 tcg_temp_free_i64(tcg_rm
);
6172 tcg_temp_free_i64(tcg_rd
);
6176 /* Avoid overlapping operands. Wide source operands are
6177 always aligned so will never overlap with wide
6178 destinations in problematic ways. */
6179 if (rd
== rm
&& !src2_wide
) {
6180 tmp
= neon_load_reg(rm
, 1);
6181 neon_store_scratch(2, tmp
);
6182 } else if (rd
== rn
&& !src1_wide
) {
6183 tmp
= neon_load_reg(rn
, 1);
6184 neon_store_scratch(2, tmp
);
6186 TCGV_UNUSED_I32(tmp3
);
6187 for (pass
= 0; pass
< 2; pass
++) {
6189 neon_load_reg64(cpu_V0
, rn
+ pass
);
6190 TCGV_UNUSED_I32(tmp
);
6192 if (pass
== 1 && rd
== rn
) {
6193 tmp
= neon_load_scratch(2);
6195 tmp
= neon_load_reg(rn
, pass
);
6198 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6202 neon_load_reg64(cpu_V1
, rm
+ pass
);
6203 TCGV_UNUSED_I32(tmp2
);
6205 if (pass
== 1 && rd
== rm
) {
6206 tmp2
= neon_load_scratch(2);
6208 tmp2
= neon_load_reg(rm
, pass
);
6211 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6215 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6216 gen_neon_addl(size
);
6218 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6219 gen_neon_subl(size
);
6221 case 5: case 7: /* VABAL, VABDL */
6222 switch ((size
<< 1) | u
) {
6224 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6227 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6230 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6233 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6236 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6239 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6243 tcg_temp_free_i32(tmp2
);
6244 tcg_temp_free_i32(tmp
);
6246 case 8: case 9: case 10: case 11: case 12: case 13:
6247 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6248 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6250 case 14: /* Polynomial VMULL */
6251 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6252 tcg_temp_free_i32(tmp2
);
6253 tcg_temp_free_i32(tmp
);
6255 default: /* 15 is RESERVED: caught earlier */
6260 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6261 neon_store_reg64(cpu_V0
, rd
+ pass
);
6262 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6264 neon_load_reg64(cpu_V1
, rd
+ pass
);
6266 case 10: /* VMLSL */
6267 gen_neon_negl(cpu_V0
, size
);
6269 case 5: case 8: /* VABAL, VMLAL */
6270 gen_neon_addl(size
);
6272 case 9: case 11: /* VQDMLAL, VQDMLSL */
6273 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6275 gen_neon_negl(cpu_V0
, size
);
6277 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6282 neon_store_reg64(cpu_V0
, rd
+ pass
);
6283 } else if (op
== 4 || op
== 6) {
6284 /* Narrowing operation. */
6285 tmp
= tcg_temp_new_i32();
6289 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6292 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6295 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6296 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6303 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6306 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6309 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6310 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6311 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6319 neon_store_reg(rd
, 0, tmp3
);
6320 neon_store_reg(rd
, 1, tmp
);
6323 /* Write back the result. */
6324 neon_store_reg64(cpu_V0
, rd
+ pass
);
6328 /* Two registers and a scalar. NB that for ops of this form
6329 * the ARM ARM labels bit 24 as Q, but it is in our variable
6336 case 1: /* Float VMLA scalar */
6337 case 5: /* Floating point VMLS scalar */
6338 case 9: /* Floating point VMUL scalar */
6343 case 0: /* Integer VMLA scalar */
6344 case 4: /* Integer VMLS scalar */
6345 case 8: /* Integer VMUL scalar */
6346 case 12: /* VQDMULH scalar */
6347 case 13: /* VQRDMULH scalar */
6348 if (u
&& ((rd
| rn
) & 1)) {
6351 tmp
= neon_get_scalar(size
, rm
);
6352 neon_store_scratch(0, tmp
);
6353 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6354 tmp
= neon_load_scratch(0);
6355 tmp2
= neon_load_reg(rn
, pass
);
6358 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6360 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6362 } else if (op
== 13) {
6364 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6366 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6368 } else if (op
& 1) {
6369 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6370 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6371 tcg_temp_free_ptr(fpstatus
);
6374 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6375 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6376 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6380 tcg_temp_free_i32(tmp2
);
6383 tmp2
= neon_load_reg(rd
, pass
);
6386 gen_neon_add(size
, tmp
, tmp2
);
6390 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6391 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6392 tcg_temp_free_ptr(fpstatus
);
6396 gen_neon_rsb(size
, tmp
, tmp2
);
6400 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6401 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6402 tcg_temp_free_ptr(fpstatus
);
6408 tcg_temp_free_i32(tmp2
);
6410 neon_store_reg(rd
, pass
, tmp
);
6413 case 3: /* VQDMLAL scalar */
6414 case 7: /* VQDMLSL scalar */
6415 case 11: /* VQDMULL scalar */
6420 case 2: /* VMLAL sclar */
6421 case 6: /* VMLSL scalar */
6422 case 10: /* VMULL scalar */
6426 tmp2
= neon_get_scalar(size
, rm
);
6427 /* We need a copy of tmp2 because gen_neon_mull
6428 * deletes it during pass 0. */
6429 tmp4
= tcg_temp_new_i32();
6430 tcg_gen_mov_i32(tmp4
, tmp2
);
6431 tmp3
= neon_load_reg(rn
, 1);
6433 for (pass
= 0; pass
< 2; pass
++) {
6435 tmp
= neon_load_reg(rn
, 0);
6440 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6442 neon_load_reg64(cpu_V1
, rd
+ pass
);
6446 gen_neon_negl(cpu_V0
, size
);
6449 gen_neon_addl(size
);
6452 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6454 gen_neon_negl(cpu_V0
, size
);
6456 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6462 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6467 neon_store_reg64(cpu_V0
, rd
+ pass
);
6472 default: /* 14 and 15 are RESERVED */
6476 } else { /* size == 3 */
6479 imm
= (insn
>> 8) & 0xf;
6484 if (q
&& ((rd
| rn
| rm
) & 1)) {
6489 neon_load_reg64(cpu_V0
, rn
);
6491 neon_load_reg64(cpu_V1
, rn
+ 1);
6493 } else if (imm
== 8) {
6494 neon_load_reg64(cpu_V0
, rn
+ 1);
6496 neon_load_reg64(cpu_V1
, rm
);
6499 tmp64
= tcg_temp_new_i64();
6501 neon_load_reg64(cpu_V0
, rn
);
6502 neon_load_reg64(tmp64
, rn
+ 1);
6504 neon_load_reg64(cpu_V0
, rn
+ 1);
6505 neon_load_reg64(tmp64
, rm
);
6507 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6508 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6509 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6511 neon_load_reg64(cpu_V1
, rm
);
6513 neon_load_reg64(cpu_V1
, rm
+ 1);
6516 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6517 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6518 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6519 tcg_temp_free_i64(tmp64
);
6522 neon_load_reg64(cpu_V0
, rn
);
6523 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6524 neon_load_reg64(cpu_V1
, rm
);
6525 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6526 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6528 neon_store_reg64(cpu_V0
, rd
);
6530 neon_store_reg64(cpu_V1
, rd
+ 1);
6532 } else if ((insn
& (1 << 11)) == 0) {
6533 /* Two register misc. */
6534 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6535 size
= (insn
>> 18) & 3;
6536 /* UNDEF for unknown op values and bad op-size combinations */
6537 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6540 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6541 q
&& ((rm
| rd
) & 1)) {
6545 case NEON_2RM_VREV64
:
6546 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6547 tmp
= neon_load_reg(rm
, pass
* 2);
6548 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6550 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6551 case 1: gen_swap_half(tmp
); break;
6552 case 2: /* no-op */ break;
6555 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6557 neon_store_reg(rd
, pass
* 2, tmp2
);
6560 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6561 case 1: gen_swap_half(tmp2
); break;
6564 neon_store_reg(rd
, pass
* 2, tmp2
);
6568 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6569 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6570 for (pass
= 0; pass
< q
+ 1; pass
++) {
6571 tmp
= neon_load_reg(rm
, pass
* 2);
6572 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6573 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6574 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6576 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6577 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6578 case 2: tcg_gen_add_i64(CPU_V001
); break;
6581 if (op
>= NEON_2RM_VPADAL
) {
6583 neon_load_reg64(cpu_V1
, rd
+ pass
);
6584 gen_neon_addl(size
);
6586 neon_store_reg64(cpu_V0
, rd
+ pass
);
6592 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6593 tmp
= neon_load_reg(rm
, n
);
6594 tmp2
= neon_load_reg(rd
, n
+ 1);
6595 neon_store_reg(rm
, n
, tmp2
);
6596 neon_store_reg(rd
, n
+ 1, tmp
);
6603 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6608 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6612 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6613 /* also VQMOVUN; op field and mnemonics don't line up */
6617 TCGV_UNUSED_I32(tmp2
);
6618 for (pass
= 0; pass
< 2; pass
++) {
6619 neon_load_reg64(cpu_V0
, rm
+ pass
);
6620 tmp
= tcg_temp_new_i32();
6621 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6626 neon_store_reg(rd
, 0, tmp2
);
6627 neon_store_reg(rd
, 1, tmp
);
6631 case NEON_2RM_VSHLL
:
6632 if (q
|| (rd
& 1)) {
6635 tmp
= neon_load_reg(rm
, 0);
6636 tmp2
= neon_load_reg(rm
, 1);
6637 for (pass
= 0; pass
< 2; pass
++) {
6640 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6641 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6642 neon_store_reg64(cpu_V0
, rd
+ pass
);
6645 case NEON_2RM_VCVT_F16_F32
:
6646 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6650 tmp
= tcg_temp_new_i32();
6651 tmp2
= tcg_temp_new_i32();
6652 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6653 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6654 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6655 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6656 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6657 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6658 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6659 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6660 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6661 neon_store_reg(rd
, 0, tmp2
);
6662 tmp2
= tcg_temp_new_i32();
6663 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6664 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6665 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6666 neon_store_reg(rd
, 1, tmp2
);
6667 tcg_temp_free_i32(tmp
);
6669 case NEON_2RM_VCVT_F32_F16
:
6670 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6674 tmp3
= tcg_temp_new_i32();
6675 tmp
= neon_load_reg(rm
, 0);
6676 tmp2
= neon_load_reg(rm
, 1);
6677 tcg_gen_ext16u_i32(tmp3
, tmp
);
6678 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6679 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6680 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6681 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6682 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6683 tcg_temp_free_i32(tmp
);
6684 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6685 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6686 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6687 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6688 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6689 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6690 tcg_temp_free_i32(tmp2
);
6691 tcg_temp_free_i32(tmp3
);
6693 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6694 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6695 || ((rm
| rd
) & 1)) {
6698 tmp
= tcg_const_i32(rd
);
6699 tmp2
= tcg_const_i32(rm
);
6701 /* Bit 6 is the lowest opcode bit; it distinguishes between
6702 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6704 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6706 if (op
== NEON_2RM_AESE
) {
6707 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6709 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6711 tcg_temp_free_i32(tmp
);
6712 tcg_temp_free_i32(tmp2
);
6713 tcg_temp_free_i32(tmp3
);
6715 case NEON_2RM_SHA1H
:
6716 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
6717 || ((rm
| rd
) & 1)) {
6720 tmp
= tcg_const_i32(rd
);
6721 tmp2
= tcg_const_i32(rm
);
6723 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6725 tcg_temp_free_i32(tmp
);
6726 tcg_temp_free_i32(tmp2
);
6728 case NEON_2RM_SHA1SU1
:
6729 if ((rm
| rd
) & 1) {
6732 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6734 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
6737 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
6740 tmp
= tcg_const_i32(rd
);
6741 tmp2
= tcg_const_i32(rm
);
6743 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6745 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6747 tcg_temp_free_i32(tmp
);
6748 tcg_temp_free_i32(tmp2
);
6752 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6753 if (neon_2rm_is_float_op(op
)) {
6754 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6755 neon_reg_offset(rm
, pass
));
6756 TCGV_UNUSED_I32(tmp
);
6758 tmp
= neon_load_reg(rm
, pass
);
6761 case NEON_2RM_VREV32
:
6763 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6764 case 1: gen_swap_half(tmp
); break;
6768 case NEON_2RM_VREV16
:
6773 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6774 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6775 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6781 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6782 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6783 case 2: gen_helper_clz(tmp
, tmp
); break;
6788 gen_helper_neon_cnt_u8(tmp
, tmp
);
6791 tcg_gen_not_i32(tmp
, tmp
);
6793 case NEON_2RM_VQABS
:
6796 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6799 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6802 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6807 case NEON_2RM_VQNEG
:
6810 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6813 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6816 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6821 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6822 tmp2
= tcg_const_i32(0);
6824 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6825 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6826 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6829 tcg_temp_free_i32(tmp2
);
6830 if (op
== NEON_2RM_VCLE0
) {
6831 tcg_gen_not_i32(tmp
, tmp
);
6834 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6835 tmp2
= tcg_const_i32(0);
6837 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6838 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6839 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6842 tcg_temp_free_i32(tmp2
);
6843 if (op
== NEON_2RM_VCLT0
) {
6844 tcg_gen_not_i32(tmp
, tmp
);
6847 case NEON_2RM_VCEQ0
:
6848 tmp2
= tcg_const_i32(0);
6850 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6851 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6852 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6855 tcg_temp_free_i32(tmp2
);
6859 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6860 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6861 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6866 tmp2
= tcg_const_i32(0);
6867 gen_neon_rsb(size
, tmp
, tmp2
);
6868 tcg_temp_free_i32(tmp2
);
6870 case NEON_2RM_VCGT0_F
:
6872 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6873 tmp2
= tcg_const_i32(0);
6874 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6875 tcg_temp_free_i32(tmp2
);
6876 tcg_temp_free_ptr(fpstatus
);
6879 case NEON_2RM_VCGE0_F
:
6881 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6882 tmp2
= tcg_const_i32(0);
6883 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6884 tcg_temp_free_i32(tmp2
);
6885 tcg_temp_free_ptr(fpstatus
);
6888 case NEON_2RM_VCEQ0_F
:
6890 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6891 tmp2
= tcg_const_i32(0);
6892 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6893 tcg_temp_free_i32(tmp2
);
6894 tcg_temp_free_ptr(fpstatus
);
6897 case NEON_2RM_VCLE0_F
:
6899 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6900 tmp2
= tcg_const_i32(0);
6901 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6902 tcg_temp_free_i32(tmp2
);
6903 tcg_temp_free_ptr(fpstatus
);
6906 case NEON_2RM_VCLT0_F
:
6908 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6909 tmp2
= tcg_const_i32(0);
6910 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6911 tcg_temp_free_i32(tmp2
);
6912 tcg_temp_free_ptr(fpstatus
);
6915 case NEON_2RM_VABS_F
:
6918 case NEON_2RM_VNEG_F
:
6922 tmp2
= neon_load_reg(rd
, pass
);
6923 neon_store_reg(rm
, pass
, tmp2
);
6926 tmp2
= neon_load_reg(rd
, pass
);
6928 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6929 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6932 neon_store_reg(rm
, pass
, tmp2
);
6934 case NEON_2RM_VRINTN
:
6935 case NEON_2RM_VRINTA
:
6936 case NEON_2RM_VRINTM
:
6937 case NEON_2RM_VRINTP
:
6938 case NEON_2RM_VRINTZ
:
6941 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6944 if (op
== NEON_2RM_VRINTZ
) {
6945 rmode
= FPROUNDING_ZERO
;
6947 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6950 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6951 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6953 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6954 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6956 tcg_temp_free_ptr(fpstatus
);
6957 tcg_temp_free_i32(tcg_rmode
);
6960 case NEON_2RM_VRINTX
:
6962 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6963 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6964 tcg_temp_free_ptr(fpstatus
);
6967 case NEON_2RM_VCVTAU
:
6968 case NEON_2RM_VCVTAS
:
6969 case NEON_2RM_VCVTNU
:
6970 case NEON_2RM_VCVTNS
:
6971 case NEON_2RM_VCVTPU
:
6972 case NEON_2RM_VCVTPS
:
6973 case NEON_2RM_VCVTMU
:
6974 case NEON_2RM_VCVTMS
:
6976 bool is_signed
= !extract32(insn
, 7, 1);
6977 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6978 TCGv_i32 tcg_rmode
, tcg_shift
;
6979 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6981 tcg_shift
= tcg_const_i32(0);
6982 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6983 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6987 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6990 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6994 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6996 tcg_temp_free_i32(tcg_rmode
);
6997 tcg_temp_free_i32(tcg_shift
);
6998 tcg_temp_free_ptr(fpst
);
7001 case NEON_2RM_VRECPE
:
7003 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7004 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7005 tcg_temp_free_ptr(fpstatus
);
7008 case NEON_2RM_VRSQRTE
:
7010 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7011 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7012 tcg_temp_free_ptr(fpstatus
);
7015 case NEON_2RM_VRECPE_F
:
7017 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7018 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7019 tcg_temp_free_ptr(fpstatus
);
7022 case NEON_2RM_VRSQRTE_F
:
7024 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7025 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7026 tcg_temp_free_ptr(fpstatus
);
7029 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7032 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7035 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7036 gen_vfp_tosiz(0, 1);
7038 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7039 gen_vfp_touiz(0, 1);
7042 /* Reserved op values were caught by the
7043 * neon_2rm_sizes[] check earlier.
7047 if (neon_2rm_is_float_op(op
)) {
7048 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7049 neon_reg_offset(rd
, pass
));
7051 neon_store_reg(rd
, pass
, tmp
);
7056 } else if ((insn
& (1 << 10)) == 0) {
7058 int n
= ((insn
>> 8) & 3) + 1;
7059 if ((rn
+ n
) > 32) {
7060 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7061 * helper function running off the end of the register file.
7066 if (insn
& (1 << 6)) {
7067 tmp
= neon_load_reg(rd
, 0);
7069 tmp
= tcg_temp_new_i32();
7070 tcg_gen_movi_i32(tmp
, 0);
7072 tmp2
= neon_load_reg(rm
, 0);
7073 tmp4
= tcg_const_i32(rn
);
7074 tmp5
= tcg_const_i32(n
);
7075 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7076 tcg_temp_free_i32(tmp
);
7077 if (insn
& (1 << 6)) {
7078 tmp
= neon_load_reg(rd
, 1);
7080 tmp
= tcg_temp_new_i32();
7081 tcg_gen_movi_i32(tmp
, 0);
7083 tmp3
= neon_load_reg(rm
, 1);
7084 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7085 tcg_temp_free_i32(tmp5
);
7086 tcg_temp_free_i32(tmp4
);
7087 neon_store_reg(rd
, 0, tmp2
);
7088 neon_store_reg(rd
, 1, tmp3
);
7089 tcg_temp_free_i32(tmp
);
7090 } else if ((insn
& 0x380) == 0) {
7092 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7095 if (insn
& (1 << 19)) {
7096 tmp
= neon_load_reg(rm
, 1);
7098 tmp
= neon_load_reg(rm
, 0);
7100 if (insn
& (1 << 16)) {
7101 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7102 } else if (insn
& (1 << 17)) {
7103 if ((insn
>> 18) & 1)
7104 gen_neon_dup_high16(tmp
);
7106 gen_neon_dup_low16(tmp
);
7108 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7109 tmp2
= tcg_temp_new_i32();
7110 tcg_gen_mov_i32(tmp2
, tmp
);
7111 neon_store_reg(rd
, pass
, tmp2
);
7113 tcg_temp_free_i32(tmp
);
7122 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7124 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7125 const ARMCPRegInfo
*ri
;
7127 cpnum
= (insn
>> 8) & 0xf;
7129 /* First check for coprocessor space used for XScale/iwMMXt insns */
7130 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7131 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7134 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7135 return disas_iwmmxt_insn(s
, insn
);
7136 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7137 return disas_dsp_insn(s
, insn
);
7142 /* Otherwise treat as a generic register access */
7143 is64
= (insn
& (1 << 25)) == 0;
7144 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7152 opc1
= (insn
>> 4) & 0xf;
7154 rt2
= (insn
>> 16) & 0xf;
7156 crn
= (insn
>> 16) & 0xf;
7157 opc1
= (insn
>> 21) & 7;
7158 opc2
= (insn
>> 5) & 7;
7161 isread
= (insn
>> 20) & 1;
7162 rt
= (insn
>> 12) & 0xf;
7164 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7165 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7167 /* Check access permissions */
7168 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7173 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7174 /* Emit code to perform further access permissions checks at
7175 * runtime; this may result in an exception.
7176 * Note that on XScale all cp0..c13 registers do an access check
7177 * call in order to handle c15_cpar.
7180 TCGv_i32 tcg_syn
, tcg_isread
;
7183 /* Note that since we are an implementation which takes an
7184 * exception on a trapped conditional instruction only if the
7185 * instruction passes its condition code check, we can take
7186 * advantage of the clause in the ARM ARM that allows us to set
7187 * the COND field in the instruction to 0xE in all cases.
7188 * We could fish the actual condition out of the insn (ARM)
7189 * or the condexec bits (Thumb) but it isn't necessary.
7194 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7197 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7203 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7206 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7211 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7212 * so this can only happen if this is an ARMv7 or earlier CPU,
7213 * in which case the syndrome information won't actually be
7216 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7217 syndrome
= syn_uncategorized();
7221 gen_set_condexec(s
);
7222 gen_set_pc_im(s
, s
->pc
- 4);
7223 tmpptr
= tcg_const_ptr(ri
);
7224 tcg_syn
= tcg_const_i32(syndrome
);
7225 tcg_isread
= tcg_const_i32(isread
);
7226 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7228 tcg_temp_free_ptr(tmpptr
);
7229 tcg_temp_free_i32(tcg_syn
);
7230 tcg_temp_free_i32(tcg_isread
);
7233 /* Handle special cases first */
7234 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7241 gen_set_pc_im(s
, s
->pc
);
7242 s
->is_jmp
= DISAS_WFI
;
7248 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7257 if (ri
->type
& ARM_CP_CONST
) {
7258 tmp64
= tcg_const_i64(ri
->resetvalue
);
7259 } else if (ri
->readfn
) {
7261 tmp64
= tcg_temp_new_i64();
7262 tmpptr
= tcg_const_ptr(ri
);
7263 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7264 tcg_temp_free_ptr(tmpptr
);
7266 tmp64
= tcg_temp_new_i64();
7267 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7269 tmp
= tcg_temp_new_i32();
7270 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7271 store_reg(s
, rt
, tmp
);
7272 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7273 tmp
= tcg_temp_new_i32();
7274 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7275 tcg_temp_free_i64(tmp64
);
7276 store_reg(s
, rt2
, tmp
);
7279 if (ri
->type
& ARM_CP_CONST
) {
7280 tmp
= tcg_const_i32(ri
->resetvalue
);
7281 } else if (ri
->readfn
) {
7283 tmp
= tcg_temp_new_i32();
7284 tmpptr
= tcg_const_ptr(ri
);
7285 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7286 tcg_temp_free_ptr(tmpptr
);
7288 tmp
= load_cpu_offset(ri
->fieldoffset
);
7291 /* Destination register of r15 for 32 bit loads sets
7292 * the condition codes from the high 4 bits of the value
7295 tcg_temp_free_i32(tmp
);
7297 store_reg(s
, rt
, tmp
);
7302 if (ri
->type
& ARM_CP_CONST
) {
7303 /* If not forbidden by access permissions, treat as WI */
7308 TCGv_i32 tmplo
, tmphi
;
7309 TCGv_i64 tmp64
= tcg_temp_new_i64();
7310 tmplo
= load_reg(s
, rt
);
7311 tmphi
= load_reg(s
, rt2
);
7312 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7313 tcg_temp_free_i32(tmplo
);
7314 tcg_temp_free_i32(tmphi
);
7316 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7317 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7318 tcg_temp_free_ptr(tmpptr
);
7320 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7322 tcg_temp_free_i64(tmp64
);
7327 tmp
= load_reg(s
, rt
);
7328 tmpptr
= tcg_const_ptr(ri
);
7329 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7330 tcg_temp_free_ptr(tmpptr
);
7331 tcg_temp_free_i32(tmp
);
7333 TCGv_i32 tmp
= load_reg(s
, rt
);
7334 store_cpu_offset(tmp
, ri
->fieldoffset
);
7339 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7340 /* I/O operations must end the TB here (whether read or write) */
7343 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7344 /* We default to ending the TB on a coprocessor register write,
7345 * but allow this to be suppressed by the register definition
7346 * (usually only necessary to work around guest bugs).
7354 /* Unknown register; this might be a guest error or a QEMU
7355 * unimplemented feature.
7358 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7359 "64 bit system register cp:%d opc1: %d crm:%d "
7361 isread
? "read" : "write", cpnum
, opc1
, crm
,
7362 s
->ns
? "non-secure" : "secure");
7364 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7365 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7367 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7368 s
->ns
? "non-secure" : "secure");
7375 /* Store a 64-bit value to a register pair. Clobbers val. */
7376 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7379 tmp
= tcg_temp_new_i32();
7380 tcg_gen_extrl_i64_i32(tmp
, val
);
7381 store_reg(s
, rlow
, tmp
);
7382 tmp
= tcg_temp_new_i32();
7383 tcg_gen_shri_i64(val
, val
, 32);
7384 tcg_gen_extrl_i64_i32(tmp
, val
);
7385 store_reg(s
, rhigh
, tmp
);
7388 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7389 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7394 /* Load value and extend to 64 bits. */
7395 tmp
= tcg_temp_new_i64();
7396 tmp2
= load_reg(s
, rlow
);
7397 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7398 tcg_temp_free_i32(tmp2
);
7399 tcg_gen_add_i64(val
, val
, tmp
);
7400 tcg_temp_free_i64(tmp
);
7403 /* load and add a 64-bit value from a register pair. */
7404 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7410 /* Load 64-bit value rd:rn. */
7411 tmpl
= load_reg(s
, rlow
);
7412 tmph
= load_reg(s
, rhigh
);
7413 tmp
= tcg_temp_new_i64();
7414 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7415 tcg_temp_free_i32(tmpl
);
7416 tcg_temp_free_i32(tmph
);
7417 tcg_gen_add_i64(val
, val
, tmp
);
7418 tcg_temp_free_i64(tmp
);
7421 /* Set N and Z flags from hi|lo. */
7422 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7424 tcg_gen_mov_i32(cpu_NF
, hi
);
7425 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7428 /* Load/Store exclusive instructions are implemented by remembering
7429 the value/address loaded, and seeing if these are the same
7430 when the store is performed. This should be sufficient to implement
7431 the architecturally mandated semantics, and avoids having to monitor
7434 In system emulation mode only one CPU will be running at once, so
7435 this sequence is effectively atomic. In user emulation mode we
7436 throw an exception and handle the atomic operation elsewhere. */
7437 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7438 TCGv_i32 addr
, int size
)
7440 TCGv_i32 tmp
= tcg_temp_new_i32();
7446 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7449 gen_aa32_ld16ua(s
, tmp
, addr
, get_mem_index(s
));
7453 gen_aa32_ld32ua(s
, tmp
, addr
, get_mem_index(s
));
7460 TCGv_i32 tmp2
= tcg_temp_new_i32();
7461 TCGv_i32 tmp3
= tcg_temp_new_i32();
7463 tcg_gen_addi_i32(tmp2
, addr
, 4);
7464 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7465 tcg_temp_free_i32(tmp2
);
7466 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7467 store_reg(s
, rt2
, tmp3
);
7469 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7472 store_reg(s
, rt
, tmp
);
7473 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7476 static void gen_clrex(DisasContext
*s
)
7478 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7481 #ifdef CONFIG_USER_ONLY
7482 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7483 TCGv_i32 addr
, int size
)
7485 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7486 tcg_gen_movi_i32(cpu_exclusive_info
,
7487 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7488 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7491 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7492 TCGv_i32 addr
, int size
)
7495 TCGv_i64 val64
, extaddr
;
7496 TCGLabel
*done_label
;
7497 TCGLabel
*fail_label
;
7499 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7505 fail_label
= gen_new_label();
7506 done_label
= gen_new_label();
7507 extaddr
= tcg_temp_new_i64();
7508 tcg_gen_extu_i32_i64(extaddr
, addr
);
7509 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7510 tcg_temp_free_i64(extaddr
);
7512 tmp
= tcg_temp_new_i32();
7515 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7518 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
7522 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7528 val64
= tcg_temp_new_i64();
7530 TCGv_i32 tmp2
= tcg_temp_new_i32();
7531 TCGv_i32 tmp3
= tcg_temp_new_i32();
7532 tcg_gen_addi_i32(tmp2
, addr
, 4);
7533 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7534 tcg_temp_free_i32(tmp2
);
7535 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7536 tcg_temp_free_i32(tmp3
);
7538 tcg_gen_extu_i32_i64(val64
, tmp
);
7540 tcg_temp_free_i32(tmp
);
7542 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7543 tcg_temp_free_i64(val64
);
7545 tmp
= load_reg(s
, rt
);
7548 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
7551 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
7555 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7560 tcg_temp_free_i32(tmp
);
7562 tcg_gen_addi_i32(addr
, addr
, 4);
7563 tmp
= load_reg(s
, rt2
);
7564 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7565 tcg_temp_free_i32(tmp
);
7567 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7568 tcg_gen_br(done_label
);
7569 gen_set_label(fail_label
);
7570 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7571 gen_set_label(done_label
);
7572 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7579 * @mode: mode field from insn (which stack to store to)
7580 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7581 * @writeback: true if writeback bit set
7583 * Generate code for the SRS (Store Return State) insn.
7585 static void gen_srs(DisasContext
*s
,
7586 uint32_t mode
, uint32_t amode
, bool writeback
)
7593 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7594 * - UNDEFINED in Hyp mode
7595 * - UNPREDICTABLE in User or System mode
7596 * - UNPREDICTABLE if the specified mode is:
7597 * -- not implemented
7598 * -- not a valid mode number
7599 * -- a mode that's at a higher exception level
7600 * -- Monitor, if we are Non-secure
7601 * For the UNPREDICTABLE cases we choose to UNDEF.
7603 if (s
->current_el
== 1 && !s
->ns
) {
7604 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7608 if (s
->current_el
== 0 || s
->current_el
== 2) {
7613 case ARM_CPU_MODE_USR
:
7614 case ARM_CPU_MODE_FIQ
:
7615 case ARM_CPU_MODE_IRQ
:
7616 case ARM_CPU_MODE_SVC
:
7617 case ARM_CPU_MODE_ABT
:
7618 case ARM_CPU_MODE_UND
:
7619 case ARM_CPU_MODE_SYS
:
7621 case ARM_CPU_MODE_HYP
:
7622 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7626 case ARM_CPU_MODE_MON
:
7627 /* No need to check specifically for "are we non-secure" because
7628 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7629 * so if this isn't EL3 then we must be non-secure.
7631 if (s
->current_el
!= 3) {
7640 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
7641 default_exception_el(s
));
7645 addr
= tcg_temp_new_i32();
7646 tmp
= tcg_const_i32(mode
);
7647 /* get_r13_banked() will raise an exception if called from System mode */
7648 gen_set_condexec(s
);
7649 gen_set_pc_im(s
, s
->pc
- 4);
7650 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7651 tcg_temp_free_i32(tmp
);
7668 tcg_gen_addi_i32(addr
, addr
, offset
);
7669 tmp
= load_reg(s
, 14);
7670 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7671 tcg_temp_free_i32(tmp
);
7672 tmp
= load_cpu_field(spsr
);
7673 tcg_gen_addi_i32(addr
, addr
, 4);
7674 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7675 tcg_temp_free_i32(tmp
);
7693 tcg_gen_addi_i32(addr
, addr
, offset
);
7694 tmp
= tcg_const_i32(mode
);
7695 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7696 tcg_temp_free_i32(tmp
);
7698 tcg_temp_free_i32(addr
);
7699 s
->is_jmp
= DISAS_UPDATE
;
7702 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7704 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7711 /* M variants do not implement ARM mode. */
7712 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7717 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7718 * choose to UNDEF. In ARMv5 and above the space is used
7719 * for miscellaneous unconditional instructions.
7723 /* Unconditional instructions. */
7724 if (((insn
>> 25) & 7) == 1) {
7725 /* NEON Data processing. */
7726 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7730 if (disas_neon_data_insn(s
, insn
)) {
7735 if ((insn
& 0x0f100000) == 0x04000000) {
7736 /* NEON load/store. */
7737 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7741 if (disas_neon_ls_insn(s
, insn
)) {
7746 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7748 if (disas_vfp_insn(s
, insn
)) {
7753 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7754 ((insn
& 0x0f30f010) == 0x0710f000)) {
7755 if ((insn
& (1 << 22)) == 0) {
7757 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7761 /* Otherwise PLD; v5TE+ */
7765 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7766 ((insn
& 0x0f70f010) == 0x0650f000)) {
7768 return; /* PLI; V7 */
7770 if (((insn
& 0x0f700000) == 0x04100000) ||
7771 ((insn
& 0x0f700010) == 0x06100000)) {
7772 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7775 return; /* v7MP: Unallocated memory hint: must NOP */
7778 if ((insn
& 0x0ffffdff) == 0x01010000) {
7781 if (((insn
>> 9) & 1) != bswap_code(s
->sctlr_b
)) {
7782 /* Dynamic endianness switching not implemented. */
7783 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7787 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7788 switch ((insn
>> 4) & 0xf) {
7796 /* We don't emulate caches so these are a no-op. */
7799 /* We need to break the TB after this insn to execute
7800 * self-modifying code correctly and also to take
7801 * any pending interrupts immediately.
7808 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7811 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7813 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7819 rn
= (insn
>> 16) & 0xf;
7820 addr
= load_reg(s
, rn
);
7821 i
= (insn
>> 23) & 3;
7823 case 0: offset
= -4; break; /* DA */
7824 case 1: offset
= 0; break; /* IA */
7825 case 2: offset
= -8; break; /* DB */
7826 case 3: offset
= 4; break; /* IB */
7830 tcg_gen_addi_i32(addr
, addr
, offset
);
7831 /* Load PC into tmp and CPSR into tmp2. */
7832 tmp
= tcg_temp_new_i32();
7833 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7834 tcg_gen_addi_i32(addr
, addr
, 4);
7835 tmp2
= tcg_temp_new_i32();
7836 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
7837 if (insn
& (1 << 21)) {
7838 /* Base writeback. */
7840 case 0: offset
= -8; break;
7841 case 1: offset
= 4; break;
7842 case 2: offset
= -4; break;
7843 case 3: offset
= 0; break;
7847 tcg_gen_addi_i32(addr
, addr
, offset
);
7848 store_reg(s
, rn
, addr
);
7850 tcg_temp_free_i32(addr
);
7852 gen_rfe(s
, tmp
, tmp2
);
7854 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7855 /* branch link and change to thumb (blx <offset>) */
7858 val
= (uint32_t)s
->pc
;
7859 tmp
= tcg_temp_new_i32();
7860 tcg_gen_movi_i32(tmp
, val
);
7861 store_reg(s
, 14, tmp
);
7862 /* Sign-extend the 24-bit offset */
7863 offset
= (((int32_t)insn
) << 8) >> 8;
7864 /* offset * 4 + bit24 * 2 + (thumb bit) */
7865 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7866 /* pipeline offset */
7868 /* protected by ARCH(5); above, near the start of uncond block */
7871 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7872 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7873 /* iWMMXt register transfer. */
7874 if (extract32(s
->c15_cpar
, 1, 1)) {
7875 if (!disas_iwmmxt_insn(s
, insn
)) {
7880 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7881 /* Coprocessor double register transfer. */
7883 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7884 /* Additional coprocessor register transfer. */
7885 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7888 /* cps (privileged) */
7892 if (insn
& (1 << 19)) {
7893 if (insn
& (1 << 8))
7895 if (insn
& (1 << 7))
7897 if (insn
& (1 << 6))
7899 if (insn
& (1 << 18))
7902 if (insn
& (1 << 17)) {
7904 val
|= (insn
& 0x1f);
7907 gen_set_psr_im(s
, mask
, 0, val
);
7914 /* if not always execute, we generate a conditional jump to
7916 s
->condlabel
= gen_new_label();
7917 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7920 if ((insn
& 0x0f900000) == 0x03000000) {
7921 if ((insn
& (1 << 21)) == 0) {
7923 rd
= (insn
>> 12) & 0xf;
7924 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7925 if ((insn
& (1 << 22)) == 0) {
7927 tmp
= tcg_temp_new_i32();
7928 tcg_gen_movi_i32(tmp
, val
);
7931 tmp
= load_reg(s
, rd
);
7932 tcg_gen_ext16u_i32(tmp
, tmp
);
7933 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7935 store_reg(s
, rd
, tmp
);
7937 if (((insn
>> 12) & 0xf) != 0xf)
7939 if (((insn
>> 16) & 0xf) == 0) {
7940 gen_nop_hint(s
, insn
& 0xff);
7942 /* CPSR = immediate */
7944 shift
= ((insn
>> 8) & 0xf) * 2;
7946 val
= (val
>> shift
) | (val
<< (32 - shift
));
7947 i
= ((insn
& (1 << 22)) != 0);
7948 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
7954 } else if ((insn
& 0x0f900000) == 0x01000000
7955 && (insn
& 0x00000090) != 0x00000090) {
7956 /* miscellaneous instructions */
7957 op1
= (insn
>> 21) & 3;
7958 sh
= (insn
>> 4) & 0xf;
7961 case 0x0: /* move program status register */
7964 tmp
= load_reg(s
, rm
);
7965 i
= ((op1
& 2) != 0);
7966 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7970 rd
= (insn
>> 12) & 0xf;
7974 tmp
= load_cpu_field(spsr
);
7976 tmp
= tcg_temp_new_i32();
7977 gen_helper_cpsr_read(tmp
, cpu_env
);
7979 store_reg(s
, rd
, tmp
);
7984 /* branch/exchange thumb (bx). */
7986 tmp
= load_reg(s
, rm
);
7988 } else if (op1
== 3) {
7991 rd
= (insn
>> 12) & 0xf;
7992 tmp
= load_reg(s
, rm
);
7993 gen_helper_clz(tmp
, tmp
);
7994 store_reg(s
, rd
, tmp
);
8002 /* Trivial implementation equivalent to bx. */
8003 tmp
= load_reg(s
, rm
);
8014 /* branch link/exchange thumb (blx) */
8015 tmp
= load_reg(s
, rm
);
8016 tmp2
= tcg_temp_new_i32();
8017 tcg_gen_movi_i32(tmp2
, s
->pc
);
8018 store_reg(s
, 14, tmp2
);
8024 uint32_t c
= extract32(insn
, 8, 4);
8026 /* Check this CPU supports ARMv8 CRC instructions.
8027 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8028 * Bits 8, 10 and 11 should be zero.
8030 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8035 rn
= extract32(insn
, 16, 4);
8036 rd
= extract32(insn
, 12, 4);
8038 tmp
= load_reg(s
, rn
);
8039 tmp2
= load_reg(s
, rm
);
8041 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8042 } else if (op1
== 1) {
8043 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8045 tmp3
= tcg_const_i32(1 << op1
);
8047 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8049 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8051 tcg_temp_free_i32(tmp2
);
8052 tcg_temp_free_i32(tmp3
);
8053 store_reg(s
, rd
, tmp
);
8056 case 0x5: /* saturating add/subtract */
8058 rd
= (insn
>> 12) & 0xf;
8059 rn
= (insn
>> 16) & 0xf;
8060 tmp
= load_reg(s
, rm
);
8061 tmp2
= load_reg(s
, rn
);
8063 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8065 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8067 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8068 tcg_temp_free_i32(tmp2
);
8069 store_reg(s
, rd
, tmp
);
8073 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8078 gen_exception_insn(s
, 4, EXCP_BKPT
,
8079 syn_aa32_bkpt(imm16
, false),
8080 default_exception_el(s
));
8083 /* Hypervisor call (v7) */
8091 /* Secure monitor call (v6+) */
8103 case 0x8: /* signed multiply */
8108 rs
= (insn
>> 8) & 0xf;
8109 rn
= (insn
>> 12) & 0xf;
8110 rd
= (insn
>> 16) & 0xf;
8112 /* (32 * 16) >> 16 */
8113 tmp
= load_reg(s
, rm
);
8114 tmp2
= load_reg(s
, rs
);
8116 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8119 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8120 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8121 tmp
= tcg_temp_new_i32();
8122 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8123 tcg_temp_free_i64(tmp64
);
8124 if ((sh
& 2) == 0) {
8125 tmp2
= load_reg(s
, rn
);
8126 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8127 tcg_temp_free_i32(tmp2
);
8129 store_reg(s
, rd
, tmp
);
8132 tmp
= load_reg(s
, rm
);
8133 tmp2
= load_reg(s
, rs
);
8134 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8135 tcg_temp_free_i32(tmp2
);
8137 tmp64
= tcg_temp_new_i64();
8138 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8139 tcg_temp_free_i32(tmp
);
8140 gen_addq(s
, tmp64
, rn
, rd
);
8141 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8142 tcg_temp_free_i64(tmp64
);
8145 tmp2
= load_reg(s
, rn
);
8146 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8147 tcg_temp_free_i32(tmp2
);
8149 store_reg(s
, rd
, tmp
);
8156 } else if (((insn
& 0x0e000000) == 0 &&
8157 (insn
& 0x00000090) != 0x90) ||
8158 ((insn
& 0x0e000000) == (1 << 25))) {
8159 int set_cc
, logic_cc
, shiftop
;
8161 op1
= (insn
>> 21) & 0xf;
8162 set_cc
= (insn
>> 20) & 1;
8163 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8165 /* data processing instruction */
8166 if (insn
& (1 << 25)) {
8167 /* immediate operand */
8169 shift
= ((insn
>> 8) & 0xf) * 2;
8171 val
= (val
>> shift
) | (val
<< (32 - shift
));
8173 tmp2
= tcg_temp_new_i32();
8174 tcg_gen_movi_i32(tmp2
, val
);
8175 if (logic_cc
&& shift
) {
8176 gen_set_CF_bit31(tmp2
);
8181 tmp2
= load_reg(s
, rm
);
8182 shiftop
= (insn
>> 5) & 3;
8183 if (!(insn
& (1 << 4))) {
8184 shift
= (insn
>> 7) & 0x1f;
8185 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8187 rs
= (insn
>> 8) & 0xf;
8188 tmp
= load_reg(s
, rs
);
8189 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8192 if (op1
!= 0x0f && op1
!= 0x0d) {
8193 rn
= (insn
>> 16) & 0xf;
8194 tmp
= load_reg(s
, rn
);
8196 TCGV_UNUSED_I32(tmp
);
8198 rd
= (insn
>> 12) & 0xf;
8201 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8205 store_reg_bx(s
, rd
, tmp
);
8208 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8212 store_reg_bx(s
, rd
, tmp
);
8215 if (set_cc
&& rd
== 15) {
8216 /* SUBS r15, ... is used for exception return. */
8220 gen_sub_CC(tmp
, tmp
, tmp2
);
8221 gen_exception_return(s
, tmp
);
8224 gen_sub_CC(tmp
, tmp
, tmp2
);
8226 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8228 store_reg_bx(s
, rd
, tmp
);
8233 gen_sub_CC(tmp
, tmp2
, tmp
);
8235 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8237 store_reg_bx(s
, rd
, tmp
);
8241 gen_add_CC(tmp
, tmp
, tmp2
);
8243 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8245 store_reg_bx(s
, rd
, tmp
);
8249 gen_adc_CC(tmp
, tmp
, tmp2
);
8251 gen_add_carry(tmp
, tmp
, tmp2
);
8253 store_reg_bx(s
, rd
, tmp
);
8257 gen_sbc_CC(tmp
, tmp
, tmp2
);
8259 gen_sub_carry(tmp
, tmp
, tmp2
);
8261 store_reg_bx(s
, rd
, tmp
);
8265 gen_sbc_CC(tmp
, tmp2
, tmp
);
8267 gen_sub_carry(tmp
, tmp2
, tmp
);
8269 store_reg_bx(s
, rd
, tmp
);
8273 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8276 tcg_temp_free_i32(tmp
);
8280 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8283 tcg_temp_free_i32(tmp
);
8287 gen_sub_CC(tmp
, tmp
, tmp2
);
8289 tcg_temp_free_i32(tmp
);
8293 gen_add_CC(tmp
, tmp
, tmp2
);
8295 tcg_temp_free_i32(tmp
);
8298 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8302 store_reg_bx(s
, rd
, tmp
);
8305 if (logic_cc
&& rd
== 15) {
8306 /* MOVS r15, ... is used for exception return. */
8310 gen_exception_return(s
, tmp2
);
8315 store_reg_bx(s
, rd
, tmp2
);
8319 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8323 store_reg_bx(s
, rd
, tmp
);
8327 tcg_gen_not_i32(tmp2
, tmp2
);
8331 store_reg_bx(s
, rd
, tmp2
);
8334 if (op1
!= 0x0f && op1
!= 0x0d) {
8335 tcg_temp_free_i32(tmp2
);
8338 /* other instructions */
8339 op1
= (insn
>> 24) & 0xf;
8343 /* multiplies, extra load/stores */
8344 sh
= (insn
>> 5) & 3;
8347 rd
= (insn
>> 16) & 0xf;
8348 rn
= (insn
>> 12) & 0xf;
8349 rs
= (insn
>> 8) & 0xf;
8351 op1
= (insn
>> 20) & 0xf;
8353 case 0: case 1: case 2: case 3: case 6:
8355 tmp
= load_reg(s
, rs
);
8356 tmp2
= load_reg(s
, rm
);
8357 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8358 tcg_temp_free_i32(tmp2
);
8359 if (insn
& (1 << 22)) {
8360 /* Subtract (mls) */
8362 tmp2
= load_reg(s
, rn
);
8363 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8364 tcg_temp_free_i32(tmp2
);
8365 } else if (insn
& (1 << 21)) {
8367 tmp2
= load_reg(s
, rn
);
8368 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8369 tcg_temp_free_i32(tmp2
);
8371 if (insn
& (1 << 20))
8373 store_reg(s
, rd
, tmp
);
8376 /* 64 bit mul double accumulate (UMAAL) */
8378 tmp
= load_reg(s
, rs
);
8379 tmp2
= load_reg(s
, rm
);
8380 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8381 gen_addq_lo(s
, tmp64
, rn
);
8382 gen_addq_lo(s
, tmp64
, rd
);
8383 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8384 tcg_temp_free_i64(tmp64
);
8386 case 8: case 9: case 10: case 11:
8387 case 12: case 13: case 14: case 15:
8388 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8389 tmp
= load_reg(s
, rs
);
8390 tmp2
= load_reg(s
, rm
);
8391 if (insn
& (1 << 22)) {
8392 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8394 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8396 if (insn
& (1 << 21)) { /* mult accumulate */
8397 TCGv_i32 al
= load_reg(s
, rn
);
8398 TCGv_i32 ah
= load_reg(s
, rd
);
8399 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8400 tcg_temp_free_i32(al
);
8401 tcg_temp_free_i32(ah
);
8403 if (insn
& (1 << 20)) {
8404 gen_logicq_cc(tmp
, tmp2
);
8406 store_reg(s
, rn
, tmp
);
8407 store_reg(s
, rd
, tmp2
);
8413 rn
= (insn
>> 16) & 0xf;
8414 rd
= (insn
>> 12) & 0xf;
8415 if (insn
& (1 << 23)) {
8416 /* load/store exclusive */
8417 int op2
= (insn
>> 8) & 3;
8418 op1
= (insn
>> 21) & 0x3;
8421 case 0: /* lda/stl */
8427 case 1: /* reserved */
8429 case 2: /* ldaex/stlex */
8432 case 3: /* ldrex/strex */
8441 addr
= tcg_temp_local_new_i32();
8442 load_reg_var(s
, addr
, rn
);
8444 /* Since the emulation does not have barriers,
8445 the acquire/release semantics need no special
8448 if (insn
& (1 << 20)) {
8449 tmp
= tcg_temp_new_i32();
8452 gen_aa32_ld32u(s
, tmp
, addr
,
8456 gen_aa32_ld8u(s
, tmp
, addr
,
8460 gen_aa32_ld16u(s
, tmp
, addr
,
8466 store_reg(s
, rd
, tmp
);
8469 tmp
= load_reg(s
, rm
);
8472 gen_aa32_st32(s
, tmp
, addr
,
8476 gen_aa32_st8(s
, tmp
, addr
,
8480 gen_aa32_st16(s
, tmp
, addr
,
8486 tcg_temp_free_i32(tmp
);
8488 } else if (insn
& (1 << 20)) {
8491 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8493 case 1: /* ldrexd */
8494 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8496 case 2: /* ldrexb */
8497 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8499 case 3: /* ldrexh */
8500 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8509 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8511 case 1: /* strexd */
8512 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8514 case 2: /* strexb */
8515 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8517 case 3: /* strexh */
8518 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8524 tcg_temp_free_i32(addr
);
8526 /* SWP instruction */
8529 /* ??? This is not really atomic. However we know
8530 we never have multiple CPUs running in parallel,
8531 so it is good enough. */
8532 addr
= load_reg(s
, rn
);
8533 tmp
= load_reg(s
, rm
);
8534 tmp2
= tcg_temp_new_i32();
8535 if (insn
& (1 << 22)) {
8536 gen_aa32_ld8u(s
, tmp2
, addr
, get_mem_index(s
));
8537 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
8539 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8540 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8542 tcg_temp_free_i32(tmp
);
8543 tcg_temp_free_i32(addr
);
8544 store_reg(s
, rd
, tmp2
);
8549 bool load
= insn
& (1 << 20);
8550 bool doubleword
= false;
8551 /* Misc load/store */
8552 rn
= (insn
>> 16) & 0xf;
8553 rd
= (insn
>> 12) & 0xf;
8555 if (!load
&& (sh
& 2)) {
8559 /* UNPREDICTABLE; we choose to UNDEF */
8562 load
= (sh
& 1) == 0;
8566 addr
= load_reg(s
, rn
);
8567 if (insn
& (1 << 24))
8568 gen_add_datah_offset(s
, insn
, 0, addr
);
8574 tmp
= load_reg(s
, rd
);
8575 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8576 tcg_temp_free_i32(tmp
);
8577 tcg_gen_addi_i32(addr
, addr
, 4);
8578 tmp
= load_reg(s
, rd
+ 1);
8579 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8580 tcg_temp_free_i32(tmp
);
8583 tmp
= tcg_temp_new_i32();
8584 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8585 store_reg(s
, rd
, tmp
);
8586 tcg_gen_addi_i32(addr
, addr
, 4);
8587 tmp
= tcg_temp_new_i32();
8588 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8591 address_offset
= -4;
8594 tmp
= tcg_temp_new_i32();
8597 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
8600 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
8604 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
8609 tmp
= load_reg(s
, rd
);
8610 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
8611 tcg_temp_free_i32(tmp
);
8613 /* Perform base writeback before the loaded value to
8614 ensure correct behavior with overlapping index registers.
8615 ldrd with base writeback is undefined if the
8616 destination and index registers overlap. */
8617 if (!(insn
& (1 << 24))) {
8618 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8619 store_reg(s
, rn
, addr
);
8620 } else if (insn
& (1 << 21)) {
8622 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8623 store_reg(s
, rn
, addr
);
8625 tcg_temp_free_i32(addr
);
8628 /* Complete the load. */
8629 store_reg(s
, rd
, tmp
);
8638 if (insn
& (1 << 4)) {
8640 /* Armv6 Media instructions. */
8642 rn
= (insn
>> 16) & 0xf;
8643 rd
= (insn
>> 12) & 0xf;
8644 rs
= (insn
>> 8) & 0xf;
8645 switch ((insn
>> 23) & 3) {
8646 case 0: /* Parallel add/subtract. */
8647 op1
= (insn
>> 20) & 7;
8648 tmp
= load_reg(s
, rn
);
8649 tmp2
= load_reg(s
, rm
);
8650 sh
= (insn
>> 5) & 7;
8651 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8653 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8654 tcg_temp_free_i32(tmp2
);
8655 store_reg(s
, rd
, tmp
);
8658 if ((insn
& 0x00700020) == 0) {
8659 /* Halfword pack. */
8660 tmp
= load_reg(s
, rn
);
8661 tmp2
= load_reg(s
, rm
);
8662 shift
= (insn
>> 7) & 0x1f;
8663 if (insn
& (1 << 6)) {
8667 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8668 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8669 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8673 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8674 tcg_gen_ext16u_i32(tmp
, tmp
);
8675 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8677 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8678 tcg_temp_free_i32(tmp2
);
8679 store_reg(s
, rd
, tmp
);
8680 } else if ((insn
& 0x00200020) == 0x00200000) {
8682 tmp
= load_reg(s
, rm
);
8683 shift
= (insn
>> 7) & 0x1f;
8684 if (insn
& (1 << 6)) {
8687 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8689 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8691 sh
= (insn
>> 16) & 0x1f;
8692 tmp2
= tcg_const_i32(sh
);
8693 if (insn
& (1 << 22))
8694 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8696 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8697 tcg_temp_free_i32(tmp2
);
8698 store_reg(s
, rd
, tmp
);
8699 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8701 tmp
= load_reg(s
, rm
);
8702 sh
= (insn
>> 16) & 0x1f;
8703 tmp2
= tcg_const_i32(sh
);
8704 if (insn
& (1 << 22))
8705 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8707 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8708 tcg_temp_free_i32(tmp2
);
8709 store_reg(s
, rd
, tmp
);
8710 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8712 tmp
= load_reg(s
, rn
);
8713 tmp2
= load_reg(s
, rm
);
8714 tmp3
= tcg_temp_new_i32();
8715 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8716 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8717 tcg_temp_free_i32(tmp3
);
8718 tcg_temp_free_i32(tmp2
);
8719 store_reg(s
, rd
, tmp
);
8720 } else if ((insn
& 0x000003e0) == 0x00000060) {
8721 tmp
= load_reg(s
, rm
);
8722 shift
= (insn
>> 10) & 3;
8723 /* ??? In many cases it's not necessary to do a
8724 rotate, a shift is sufficient. */
8726 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8727 op1
= (insn
>> 20) & 7;
8729 case 0: gen_sxtb16(tmp
); break;
8730 case 2: gen_sxtb(tmp
); break;
8731 case 3: gen_sxth(tmp
); break;
8732 case 4: gen_uxtb16(tmp
); break;
8733 case 6: gen_uxtb(tmp
); break;
8734 case 7: gen_uxth(tmp
); break;
8735 default: goto illegal_op
;
8738 tmp2
= load_reg(s
, rn
);
8739 if ((op1
& 3) == 0) {
8740 gen_add16(tmp
, tmp2
);
8742 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8743 tcg_temp_free_i32(tmp2
);
8746 store_reg(s
, rd
, tmp
);
8747 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8749 tmp
= load_reg(s
, rm
);
8750 if (insn
& (1 << 22)) {
8751 if (insn
& (1 << 7)) {
8755 gen_helper_rbit(tmp
, tmp
);
8758 if (insn
& (1 << 7))
8761 tcg_gen_bswap32_i32(tmp
, tmp
);
8763 store_reg(s
, rd
, tmp
);
8768 case 2: /* Multiplies (Type 3). */
8769 switch ((insn
>> 20) & 0x7) {
8771 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8772 /* op2 not 00x or 11x : UNDEF */
8775 /* Signed multiply most significant [accumulate].
8776 (SMMUL, SMMLA, SMMLS) */
8777 tmp
= load_reg(s
, rm
);
8778 tmp2
= load_reg(s
, rs
);
8779 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8782 tmp
= load_reg(s
, rd
);
8783 if (insn
& (1 << 6)) {
8784 tmp64
= gen_subq_msw(tmp64
, tmp
);
8786 tmp64
= gen_addq_msw(tmp64
, tmp
);
8789 if (insn
& (1 << 5)) {
8790 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8792 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8793 tmp
= tcg_temp_new_i32();
8794 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8795 tcg_temp_free_i64(tmp64
);
8796 store_reg(s
, rn
, tmp
);
8800 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8801 if (insn
& (1 << 7)) {
8804 tmp
= load_reg(s
, rm
);
8805 tmp2
= load_reg(s
, rs
);
8806 if (insn
& (1 << 5))
8807 gen_swap_half(tmp2
);
8808 gen_smul_dual(tmp
, tmp2
);
8809 if (insn
& (1 << 22)) {
8810 /* smlald, smlsld */
8813 tmp64
= tcg_temp_new_i64();
8814 tmp64_2
= tcg_temp_new_i64();
8815 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8816 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8817 tcg_temp_free_i32(tmp
);
8818 tcg_temp_free_i32(tmp2
);
8819 if (insn
& (1 << 6)) {
8820 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8822 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8824 tcg_temp_free_i64(tmp64_2
);
8825 gen_addq(s
, tmp64
, rd
, rn
);
8826 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8827 tcg_temp_free_i64(tmp64
);
8829 /* smuad, smusd, smlad, smlsd */
8830 if (insn
& (1 << 6)) {
8831 /* This subtraction cannot overflow. */
8832 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8834 /* This addition cannot overflow 32 bits;
8835 * however it may overflow considered as a
8836 * signed operation, in which case we must set
8839 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8841 tcg_temp_free_i32(tmp2
);
8844 tmp2
= load_reg(s
, rd
);
8845 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8846 tcg_temp_free_i32(tmp2
);
8848 store_reg(s
, rn
, tmp
);
8854 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
8857 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8860 tmp
= load_reg(s
, rm
);
8861 tmp2
= load_reg(s
, rs
);
8862 if (insn
& (1 << 21)) {
8863 gen_helper_udiv(tmp
, tmp
, tmp2
);
8865 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8867 tcg_temp_free_i32(tmp2
);
8868 store_reg(s
, rn
, tmp
);
8875 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8877 case 0: /* Unsigned sum of absolute differences. */
8879 tmp
= load_reg(s
, rm
);
8880 tmp2
= load_reg(s
, rs
);
8881 gen_helper_usad8(tmp
, tmp
, tmp2
);
8882 tcg_temp_free_i32(tmp2
);
8884 tmp2
= load_reg(s
, rd
);
8885 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8886 tcg_temp_free_i32(tmp2
);
8888 store_reg(s
, rn
, tmp
);
8890 case 0x20: case 0x24: case 0x28: case 0x2c:
8891 /* Bitfield insert/clear. */
8893 shift
= (insn
>> 7) & 0x1f;
8894 i
= (insn
>> 16) & 0x1f;
8896 /* UNPREDICTABLE; we choose to UNDEF */
8901 tmp
= tcg_temp_new_i32();
8902 tcg_gen_movi_i32(tmp
, 0);
8904 tmp
= load_reg(s
, rm
);
8907 tmp2
= load_reg(s
, rd
);
8908 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8909 tcg_temp_free_i32(tmp2
);
8911 store_reg(s
, rd
, tmp
);
8913 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8914 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8916 tmp
= load_reg(s
, rm
);
8917 shift
= (insn
>> 7) & 0x1f;
8918 i
= ((insn
>> 16) & 0x1f) + 1;
8923 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8925 gen_sbfx(tmp
, shift
, i
);
8928 store_reg(s
, rd
, tmp
);
8938 /* Check for undefined extension instructions
8939 * per the ARM Bible IE:
8940 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8942 sh
= (0xf << 20) | (0xf << 4);
8943 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8947 /* load/store byte/word */
8948 rn
= (insn
>> 16) & 0xf;
8949 rd
= (insn
>> 12) & 0xf;
8950 tmp2
= load_reg(s
, rn
);
8951 if ((insn
& 0x01200000) == 0x00200000) {
8953 i
= get_a32_user_mem_index(s
);
8955 i
= get_mem_index(s
);
8957 if (insn
& (1 << 24))
8958 gen_add_data_offset(s
, insn
, tmp2
);
8959 if (insn
& (1 << 20)) {
8961 tmp
= tcg_temp_new_i32();
8962 if (insn
& (1 << 22)) {
8963 gen_aa32_ld8u(s
, tmp
, tmp2
, i
);
8965 gen_aa32_ld32u(s
, tmp
, tmp2
, i
);
8969 tmp
= load_reg(s
, rd
);
8970 if (insn
& (1 << 22)) {
8971 gen_aa32_st8(s
, tmp
, tmp2
, i
);
8973 gen_aa32_st32(s
, tmp
, tmp2
, i
);
8975 tcg_temp_free_i32(tmp
);
8977 if (!(insn
& (1 << 24))) {
8978 gen_add_data_offset(s
, insn
, tmp2
);
8979 store_reg(s
, rn
, tmp2
);
8980 } else if (insn
& (1 << 21)) {
8981 store_reg(s
, rn
, tmp2
);
8983 tcg_temp_free_i32(tmp2
);
8985 if (insn
& (1 << 20)) {
8986 /* Complete the load. */
8987 store_reg_from_load(s
, rd
, tmp
);
8993 int j
, n
, loaded_base
;
8994 bool exc_return
= false;
8995 bool is_load
= extract32(insn
, 20, 1);
8997 TCGv_i32 loaded_var
;
8998 /* load/store multiple words */
8999 /* XXX: store correct base if write back */
9000 if (insn
& (1 << 22)) {
9001 /* LDM (user), LDM (exception return) and STM (user) */
9003 goto illegal_op
; /* only usable in supervisor mode */
9005 if (is_load
&& extract32(insn
, 15, 1)) {
9011 rn
= (insn
>> 16) & 0xf;
9012 addr
= load_reg(s
, rn
);
9014 /* compute total size */
9016 TCGV_UNUSED_I32(loaded_var
);
9019 if (insn
& (1 << i
))
9022 /* XXX: test invalid n == 0 case ? */
9023 if (insn
& (1 << 23)) {
9024 if (insn
& (1 << 24)) {
9026 tcg_gen_addi_i32(addr
, addr
, 4);
9028 /* post increment */
9031 if (insn
& (1 << 24)) {
9033 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9035 /* post decrement */
9037 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9042 if (insn
& (1 << i
)) {
9045 tmp
= tcg_temp_new_i32();
9046 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9048 tmp2
= tcg_const_i32(i
);
9049 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9050 tcg_temp_free_i32(tmp2
);
9051 tcg_temp_free_i32(tmp
);
9052 } else if (i
== rn
) {
9056 store_reg_from_load(s
, i
, tmp
);
9061 /* special case: r15 = PC + 8 */
9062 val
= (long)s
->pc
+ 4;
9063 tmp
= tcg_temp_new_i32();
9064 tcg_gen_movi_i32(tmp
, val
);
9066 tmp
= tcg_temp_new_i32();
9067 tmp2
= tcg_const_i32(i
);
9068 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9069 tcg_temp_free_i32(tmp2
);
9071 tmp
= load_reg(s
, i
);
9073 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9074 tcg_temp_free_i32(tmp
);
9077 /* no need to add after the last transfer */
9079 tcg_gen_addi_i32(addr
, addr
, 4);
9082 if (insn
& (1 << 21)) {
9084 if (insn
& (1 << 23)) {
9085 if (insn
& (1 << 24)) {
9088 /* post increment */
9089 tcg_gen_addi_i32(addr
, addr
, 4);
9092 if (insn
& (1 << 24)) {
9095 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9097 /* post decrement */
9098 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9101 store_reg(s
, rn
, addr
);
9103 tcg_temp_free_i32(addr
);
9106 store_reg(s
, rn
, loaded_var
);
9109 /* Restore CPSR from SPSR. */
9110 tmp
= load_cpu_field(spsr
);
9111 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9112 tcg_temp_free_i32(tmp
);
9113 s
->is_jmp
= DISAS_JUMP
;
9122 /* branch (and link) */
9123 val
= (int32_t)s
->pc
;
9124 if (insn
& (1 << 24)) {
9125 tmp
= tcg_temp_new_i32();
9126 tcg_gen_movi_i32(tmp
, val
);
9127 store_reg(s
, 14, tmp
);
9129 offset
= sextract32(insn
<< 2, 0, 26);
9137 if (((insn
>> 8) & 0xe) == 10) {
9139 if (disas_vfp_insn(s
, insn
)) {
9142 } else if (disas_coproc_insn(s
, insn
)) {
9149 gen_set_pc_im(s
, s
->pc
);
9150 s
->svc_imm
= extract32(insn
, 0, 24);
9151 s
->is_jmp
= DISAS_SWI
;
9155 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9156 default_exception_el(s
));
9162 /* Return true if this is a Thumb-2 logical op. */
9164 thumb2_logic_op(int op
)
9169 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9170 then set condition code flags based on the result of the operation.
9171 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9172 to the high bit of T1.
9173 Returns zero if the opcode is valid. */
9176 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9177 TCGv_i32 t0
, TCGv_i32 t1
)
9184 tcg_gen_and_i32(t0
, t0
, t1
);
9188 tcg_gen_andc_i32(t0
, t0
, t1
);
9192 tcg_gen_or_i32(t0
, t0
, t1
);
9196 tcg_gen_orc_i32(t0
, t0
, t1
);
9200 tcg_gen_xor_i32(t0
, t0
, t1
);
9205 gen_add_CC(t0
, t0
, t1
);
9207 tcg_gen_add_i32(t0
, t0
, t1
);
9211 gen_adc_CC(t0
, t0
, t1
);
9217 gen_sbc_CC(t0
, t0
, t1
);
9219 gen_sub_carry(t0
, t0
, t1
);
9224 gen_sub_CC(t0
, t0
, t1
);
9226 tcg_gen_sub_i32(t0
, t0
, t1
);
9230 gen_sub_CC(t0
, t1
, t0
);
9232 tcg_gen_sub_i32(t0
, t1
, t0
);
9234 default: /* 5, 6, 7, 9, 12, 15. */
9240 gen_set_CF_bit31(t1
);
9245 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9247 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9249 uint32_t insn
, imm
, shift
, offset
;
9250 uint32_t rd
, rn
, rm
, rs
;
9261 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9262 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9263 /* Thumb-1 cores may need to treat bl and blx as a pair of
9264 16-bit instructions to get correct prefetch abort behavior. */
9266 if ((insn
& (1 << 12)) == 0) {
9268 /* Second half of blx. */
9269 offset
= ((insn
& 0x7ff) << 1);
9270 tmp
= load_reg(s
, 14);
9271 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9272 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9274 tmp2
= tcg_temp_new_i32();
9275 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9276 store_reg(s
, 14, tmp2
);
9280 if (insn
& (1 << 11)) {
9281 /* Second half of bl. */
9282 offset
= ((insn
& 0x7ff) << 1) | 1;
9283 tmp
= load_reg(s
, 14);
9284 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9286 tmp2
= tcg_temp_new_i32();
9287 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9288 store_reg(s
, 14, tmp2
);
9292 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9293 /* Instruction spans a page boundary. Implement it as two
9294 16-bit instructions in case the second half causes an
9296 offset
= ((int32_t)insn
<< 21) >> 9;
9297 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9300 /* Fall through to 32-bit decode. */
9303 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9305 insn
|= (uint32_t)insn_hw1
<< 16;
9307 if ((insn
& 0xf800e800) != 0xf000e800) {
9311 rn
= (insn
>> 16) & 0xf;
9312 rs
= (insn
>> 12) & 0xf;
9313 rd
= (insn
>> 8) & 0xf;
9315 switch ((insn
>> 25) & 0xf) {
9316 case 0: case 1: case 2: case 3:
9317 /* 16-bit instructions. Should never happen. */
9320 if (insn
& (1 << 22)) {
9321 /* Other load/store, table branch. */
9322 if (insn
& 0x01200000) {
9323 /* Load/store doubleword. */
9325 addr
= tcg_temp_new_i32();
9326 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9328 addr
= load_reg(s
, rn
);
9330 offset
= (insn
& 0xff) * 4;
9331 if ((insn
& (1 << 23)) == 0)
9333 if (insn
& (1 << 24)) {
9334 tcg_gen_addi_i32(addr
, addr
, offset
);
9337 if (insn
& (1 << 20)) {
9339 tmp
= tcg_temp_new_i32();
9340 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9341 store_reg(s
, rs
, tmp
);
9342 tcg_gen_addi_i32(addr
, addr
, 4);
9343 tmp
= tcg_temp_new_i32();
9344 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9345 store_reg(s
, rd
, tmp
);
9348 tmp
= load_reg(s
, rs
);
9349 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9350 tcg_temp_free_i32(tmp
);
9351 tcg_gen_addi_i32(addr
, addr
, 4);
9352 tmp
= load_reg(s
, rd
);
9353 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9354 tcg_temp_free_i32(tmp
);
9356 if (insn
& (1 << 21)) {
9357 /* Base writeback. */
9360 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9361 store_reg(s
, rn
, addr
);
9363 tcg_temp_free_i32(addr
);
9365 } else if ((insn
& (1 << 23)) == 0) {
9366 /* Load/store exclusive word. */
9367 addr
= tcg_temp_local_new_i32();
9368 load_reg_var(s
, addr
, rn
);
9369 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9370 if (insn
& (1 << 20)) {
9371 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9373 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9375 tcg_temp_free_i32(addr
);
9376 } else if ((insn
& (7 << 5)) == 0) {
9379 addr
= tcg_temp_new_i32();
9380 tcg_gen_movi_i32(addr
, s
->pc
);
9382 addr
= load_reg(s
, rn
);
9384 tmp
= load_reg(s
, rm
);
9385 tcg_gen_add_i32(addr
, addr
, tmp
);
9386 if (insn
& (1 << 4)) {
9388 tcg_gen_add_i32(addr
, addr
, tmp
);
9389 tcg_temp_free_i32(tmp
);
9390 tmp
= tcg_temp_new_i32();
9391 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9393 tcg_temp_free_i32(tmp
);
9394 tmp
= tcg_temp_new_i32();
9395 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9397 tcg_temp_free_i32(addr
);
9398 tcg_gen_shli_i32(tmp
, tmp
, 1);
9399 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9400 store_reg(s
, 15, tmp
);
9402 int op2
= (insn
>> 6) & 0x3;
9403 op
= (insn
>> 4) & 0x3;
9408 /* Load/store exclusive byte/halfword/doubleword */
9415 /* Load-acquire/store-release */
9421 /* Load-acquire/store-release exclusive */
9425 addr
= tcg_temp_local_new_i32();
9426 load_reg_var(s
, addr
, rn
);
9428 if (insn
& (1 << 20)) {
9429 tmp
= tcg_temp_new_i32();
9432 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9435 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9438 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9443 store_reg(s
, rs
, tmp
);
9445 tmp
= load_reg(s
, rs
);
9448 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
9451 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
9454 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9459 tcg_temp_free_i32(tmp
);
9461 } else if (insn
& (1 << 20)) {
9462 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9464 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9466 tcg_temp_free_i32(addr
);
9469 /* Load/store multiple, RFE, SRS. */
9470 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9471 /* RFE, SRS: not available in user mode or on M profile */
9472 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9475 if (insn
& (1 << 20)) {
9477 addr
= load_reg(s
, rn
);
9478 if ((insn
& (1 << 24)) == 0)
9479 tcg_gen_addi_i32(addr
, addr
, -8);
9480 /* Load PC into tmp and CPSR into tmp2. */
9481 tmp
= tcg_temp_new_i32();
9482 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9483 tcg_gen_addi_i32(addr
, addr
, 4);
9484 tmp2
= tcg_temp_new_i32();
9485 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9486 if (insn
& (1 << 21)) {
9487 /* Base writeback. */
9488 if (insn
& (1 << 24)) {
9489 tcg_gen_addi_i32(addr
, addr
, 4);
9491 tcg_gen_addi_i32(addr
, addr
, -4);
9493 store_reg(s
, rn
, addr
);
9495 tcg_temp_free_i32(addr
);
9497 gen_rfe(s
, tmp
, tmp2
);
9500 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9504 int i
, loaded_base
= 0;
9505 TCGv_i32 loaded_var
;
9506 /* Load/store multiple. */
9507 addr
= load_reg(s
, rn
);
9509 for (i
= 0; i
< 16; i
++) {
9510 if (insn
& (1 << i
))
9513 if (insn
& (1 << 24)) {
9514 tcg_gen_addi_i32(addr
, addr
, -offset
);
9517 TCGV_UNUSED_I32(loaded_var
);
9518 for (i
= 0; i
< 16; i
++) {
9519 if ((insn
& (1 << i
)) == 0)
9521 if (insn
& (1 << 20)) {
9523 tmp
= tcg_temp_new_i32();
9524 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9527 } else if (i
== rn
) {
9531 store_reg(s
, i
, tmp
);
9535 tmp
= load_reg(s
, i
);
9536 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9537 tcg_temp_free_i32(tmp
);
9539 tcg_gen_addi_i32(addr
, addr
, 4);
9542 store_reg(s
, rn
, loaded_var
);
9544 if (insn
& (1 << 21)) {
9545 /* Base register writeback. */
9546 if (insn
& (1 << 24)) {
9547 tcg_gen_addi_i32(addr
, addr
, -offset
);
9549 /* Fault if writeback register is in register list. */
9550 if (insn
& (1 << rn
))
9552 store_reg(s
, rn
, addr
);
9554 tcg_temp_free_i32(addr
);
9561 op
= (insn
>> 21) & 0xf;
9563 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9566 /* Halfword pack. */
9567 tmp
= load_reg(s
, rn
);
9568 tmp2
= load_reg(s
, rm
);
9569 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9570 if (insn
& (1 << 5)) {
9574 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9575 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9576 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9580 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9581 tcg_gen_ext16u_i32(tmp
, tmp
);
9582 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9584 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9585 tcg_temp_free_i32(tmp2
);
9586 store_reg(s
, rd
, tmp
);
9588 /* Data processing register constant shift. */
9590 tmp
= tcg_temp_new_i32();
9591 tcg_gen_movi_i32(tmp
, 0);
9593 tmp
= load_reg(s
, rn
);
9595 tmp2
= load_reg(s
, rm
);
9597 shiftop
= (insn
>> 4) & 3;
9598 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9599 conds
= (insn
& (1 << 20)) != 0;
9600 logic_cc
= (conds
&& thumb2_logic_op(op
));
9601 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9602 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9604 tcg_temp_free_i32(tmp2
);
9606 store_reg(s
, rd
, tmp
);
9608 tcg_temp_free_i32(tmp
);
9612 case 13: /* Misc data processing. */
9613 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9614 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9617 case 0: /* Register controlled shift. */
9618 tmp
= load_reg(s
, rn
);
9619 tmp2
= load_reg(s
, rm
);
9620 if ((insn
& 0x70) != 0)
9622 op
= (insn
>> 21) & 3;
9623 logic_cc
= (insn
& (1 << 20)) != 0;
9624 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9627 store_reg_bx(s
, rd
, tmp
);
9629 case 1: /* Sign/zero extend. */
9630 op
= (insn
>> 20) & 7;
9632 case 0: /* SXTAH, SXTH */
9633 case 1: /* UXTAH, UXTH */
9634 case 4: /* SXTAB, SXTB */
9635 case 5: /* UXTAB, UXTB */
9637 case 2: /* SXTAB16, SXTB16 */
9638 case 3: /* UXTAB16, UXTB16 */
9639 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9647 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9651 tmp
= load_reg(s
, rm
);
9652 shift
= (insn
>> 4) & 3;
9653 /* ??? In many cases it's not necessary to do a
9654 rotate, a shift is sufficient. */
9656 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9657 op
= (insn
>> 20) & 7;
9659 case 0: gen_sxth(tmp
); break;
9660 case 1: gen_uxth(tmp
); break;
9661 case 2: gen_sxtb16(tmp
); break;
9662 case 3: gen_uxtb16(tmp
); break;
9663 case 4: gen_sxtb(tmp
); break;
9664 case 5: gen_uxtb(tmp
); break;
9666 g_assert_not_reached();
9669 tmp2
= load_reg(s
, rn
);
9670 if ((op
>> 1) == 1) {
9671 gen_add16(tmp
, tmp2
);
9673 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9674 tcg_temp_free_i32(tmp2
);
9677 store_reg(s
, rd
, tmp
);
9679 case 2: /* SIMD add/subtract. */
9680 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9683 op
= (insn
>> 20) & 7;
9684 shift
= (insn
>> 4) & 7;
9685 if ((op
& 3) == 3 || (shift
& 3) == 3)
9687 tmp
= load_reg(s
, rn
);
9688 tmp2
= load_reg(s
, rm
);
9689 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9690 tcg_temp_free_i32(tmp2
);
9691 store_reg(s
, rd
, tmp
);
9693 case 3: /* Other data processing. */
9694 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9696 /* Saturating add/subtract. */
9697 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9700 tmp
= load_reg(s
, rn
);
9701 tmp2
= load_reg(s
, rm
);
9703 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9705 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9707 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9708 tcg_temp_free_i32(tmp2
);
9711 case 0x0a: /* rbit */
9712 case 0x08: /* rev */
9713 case 0x09: /* rev16 */
9714 case 0x0b: /* revsh */
9715 case 0x18: /* clz */
9717 case 0x10: /* sel */
9718 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9722 case 0x20: /* crc32/crc32c */
9728 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
9735 tmp
= load_reg(s
, rn
);
9737 case 0x0a: /* rbit */
9738 gen_helper_rbit(tmp
, tmp
);
9740 case 0x08: /* rev */
9741 tcg_gen_bswap32_i32(tmp
, tmp
);
9743 case 0x09: /* rev16 */
9746 case 0x0b: /* revsh */
9749 case 0x10: /* sel */
9750 tmp2
= load_reg(s
, rm
);
9751 tmp3
= tcg_temp_new_i32();
9752 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9753 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9754 tcg_temp_free_i32(tmp3
);
9755 tcg_temp_free_i32(tmp2
);
9757 case 0x18: /* clz */
9758 gen_helper_clz(tmp
, tmp
);
9768 uint32_t sz
= op
& 0x3;
9769 uint32_t c
= op
& 0x8;
9771 tmp2
= load_reg(s
, rm
);
9773 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9774 } else if (sz
== 1) {
9775 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9777 tmp3
= tcg_const_i32(1 << sz
);
9779 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9781 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9783 tcg_temp_free_i32(tmp2
);
9784 tcg_temp_free_i32(tmp3
);
9788 g_assert_not_reached();
9791 store_reg(s
, rd
, tmp
);
9793 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9794 switch ((insn
>> 20) & 7) {
9795 case 0: /* 32 x 32 -> 32 */
9796 case 7: /* Unsigned sum of absolute differences. */
9798 case 1: /* 16 x 16 -> 32 */
9799 case 2: /* Dual multiply add. */
9800 case 3: /* 32 * 16 -> 32msb */
9801 case 4: /* Dual multiply subtract. */
9802 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9803 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9808 op
= (insn
>> 4) & 0xf;
9809 tmp
= load_reg(s
, rn
);
9810 tmp2
= load_reg(s
, rm
);
9811 switch ((insn
>> 20) & 7) {
9812 case 0: /* 32 x 32 -> 32 */
9813 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9814 tcg_temp_free_i32(tmp2
);
9816 tmp2
= load_reg(s
, rs
);
9818 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9820 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9821 tcg_temp_free_i32(tmp2
);
9824 case 1: /* 16 x 16 -> 32 */
9825 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9826 tcg_temp_free_i32(tmp2
);
9828 tmp2
= load_reg(s
, rs
);
9829 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9830 tcg_temp_free_i32(tmp2
);
9833 case 2: /* Dual multiply add. */
9834 case 4: /* Dual multiply subtract. */
9836 gen_swap_half(tmp2
);
9837 gen_smul_dual(tmp
, tmp2
);
9838 if (insn
& (1 << 22)) {
9839 /* This subtraction cannot overflow. */
9840 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9842 /* This addition cannot overflow 32 bits;
9843 * however it may overflow considered as a signed
9844 * operation, in which case we must set the Q flag.
9846 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9848 tcg_temp_free_i32(tmp2
);
9851 tmp2
= load_reg(s
, rs
);
9852 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9853 tcg_temp_free_i32(tmp2
);
9856 case 3: /* 32 * 16 -> 32msb */
9858 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9861 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9862 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9863 tmp
= tcg_temp_new_i32();
9864 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9865 tcg_temp_free_i64(tmp64
);
9868 tmp2
= load_reg(s
, rs
);
9869 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9870 tcg_temp_free_i32(tmp2
);
9873 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9874 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9876 tmp
= load_reg(s
, rs
);
9877 if (insn
& (1 << 20)) {
9878 tmp64
= gen_addq_msw(tmp64
, tmp
);
9880 tmp64
= gen_subq_msw(tmp64
, tmp
);
9883 if (insn
& (1 << 4)) {
9884 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9886 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9887 tmp
= tcg_temp_new_i32();
9888 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9889 tcg_temp_free_i64(tmp64
);
9891 case 7: /* Unsigned sum of absolute differences. */
9892 gen_helper_usad8(tmp
, tmp
, tmp2
);
9893 tcg_temp_free_i32(tmp2
);
9895 tmp2
= load_reg(s
, rs
);
9896 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9897 tcg_temp_free_i32(tmp2
);
9901 store_reg(s
, rd
, tmp
);
9903 case 6: case 7: /* 64-bit multiply, Divide. */
9904 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9905 tmp
= load_reg(s
, rn
);
9906 tmp2
= load_reg(s
, rm
);
9907 if ((op
& 0x50) == 0x10) {
9909 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
9913 gen_helper_udiv(tmp
, tmp
, tmp2
);
9915 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9916 tcg_temp_free_i32(tmp2
);
9917 store_reg(s
, rd
, tmp
);
9918 } else if ((op
& 0xe) == 0xc) {
9919 /* Dual multiply accumulate long. */
9920 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9921 tcg_temp_free_i32(tmp
);
9922 tcg_temp_free_i32(tmp2
);
9926 gen_swap_half(tmp2
);
9927 gen_smul_dual(tmp
, tmp2
);
9929 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9931 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9933 tcg_temp_free_i32(tmp2
);
9935 tmp64
= tcg_temp_new_i64();
9936 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9937 tcg_temp_free_i32(tmp
);
9938 gen_addq(s
, tmp64
, rs
, rd
);
9939 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9940 tcg_temp_free_i64(tmp64
);
9943 /* Unsigned 64-bit multiply */
9944 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9948 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9949 tcg_temp_free_i32(tmp2
);
9950 tcg_temp_free_i32(tmp
);
9953 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9954 tcg_temp_free_i32(tmp2
);
9955 tmp64
= tcg_temp_new_i64();
9956 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9957 tcg_temp_free_i32(tmp
);
9959 /* Signed 64-bit multiply */
9960 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9965 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9966 tcg_temp_free_i64(tmp64
);
9969 gen_addq_lo(s
, tmp64
, rs
);
9970 gen_addq_lo(s
, tmp64
, rd
);
9971 } else if (op
& 0x40) {
9972 /* 64-bit accumulate. */
9973 gen_addq(s
, tmp64
, rs
, rd
);
9975 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9976 tcg_temp_free_i64(tmp64
);
9981 case 6: case 7: case 14: case 15:
9983 if (((insn
>> 24) & 3) == 3) {
9984 /* Translate into the equivalent ARM encoding. */
9985 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9986 if (disas_neon_data_insn(s
, insn
)) {
9989 } else if (((insn
>> 8) & 0xe) == 10) {
9990 if (disas_vfp_insn(s
, insn
)) {
9994 if (insn
& (1 << 28))
9996 if (disas_coproc_insn(s
, insn
)) {
10001 case 8: case 9: case 10: case 11:
10002 if (insn
& (1 << 15)) {
10003 /* Branches, misc control. */
10004 if (insn
& 0x5000) {
10005 /* Unconditional branch. */
10006 /* signextend(hw1[10:0]) -> offset[:12]. */
10007 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10008 /* hw1[10:0] -> offset[11:1]. */
10009 offset
|= (insn
& 0x7ff) << 1;
10010 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10011 offset[24:22] already have the same value because of the
10012 sign extension above. */
10013 offset
^= ((~insn
) & (1 << 13)) << 10;
10014 offset
^= ((~insn
) & (1 << 11)) << 11;
10016 if (insn
& (1 << 14)) {
10017 /* Branch and link. */
10018 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10022 if (insn
& (1 << 12)) {
10024 gen_jmp(s
, offset
);
10027 offset
&= ~(uint32_t)2;
10028 /* thumb2 bx, no need to check */
10029 gen_bx_im(s
, offset
);
10031 } else if (((insn
>> 23) & 7) == 7) {
10033 if (insn
& (1 << 13))
10036 if (insn
& (1 << 26)) {
10037 if (!(insn
& (1 << 20))) {
10038 /* Hypervisor call (v7) */
10039 int imm16
= extract32(insn
, 16, 4) << 12
10040 | extract32(insn
, 0, 12);
10047 /* Secure monitor call (v6+) */
10055 op
= (insn
>> 20) & 7;
10057 case 0: /* msr cpsr. */
10058 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10059 tmp
= load_reg(s
, rn
);
10060 addr
= tcg_const_i32(insn
& 0xff);
10061 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10062 tcg_temp_free_i32(addr
);
10063 tcg_temp_free_i32(tmp
);
10068 case 1: /* msr spsr. */
10069 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10072 tmp
= load_reg(s
, rn
);
10074 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10078 case 2: /* cps, nop-hint. */
10079 if (((insn
>> 8) & 7) == 0) {
10080 gen_nop_hint(s
, insn
& 0xff);
10082 /* Implemented as NOP in user mode. */
10087 if (insn
& (1 << 10)) {
10088 if (insn
& (1 << 7))
10090 if (insn
& (1 << 6))
10092 if (insn
& (1 << 5))
10094 if (insn
& (1 << 9))
10095 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10097 if (insn
& (1 << 8)) {
10099 imm
|= (insn
& 0x1f);
10102 gen_set_psr_im(s
, offset
, 0, imm
);
10105 case 3: /* Special control operations. */
10107 op
= (insn
>> 4) & 0xf;
10109 case 2: /* clrex */
10114 /* These execute as NOPs. */
10117 /* We need to break the TB after this insn
10118 * to execute self-modifying code correctly
10119 * and also to take any pending interrupts
10129 /* Trivial implementation equivalent to bx. */
10130 tmp
= load_reg(s
, rn
);
10133 case 5: /* Exception return. */
10137 if (rn
!= 14 || rd
!= 15) {
10140 tmp
= load_reg(s
, rn
);
10141 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10142 gen_exception_return(s
, tmp
);
10144 case 6: /* mrs cpsr. */
10145 tmp
= tcg_temp_new_i32();
10146 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10147 addr
= tcg_const_i32(insn
& 0xff);
10148 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10149 tcg_temp_free_i32(addr
);
10151 gen_helper_cpsr_read(tmp
, cpu_env
);
10153 store_reg(s
, rd
, tmp
);
10155 case 7: /* mrs spsr. */
10156 /* Not accessible in user mode. */
10157 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10160 tmp
= load_cpu_field(spsr
);
10161 store_reg(s
, rd
, tmp
);
10166 /* Conditional branch. */
10167 op
= (insn
>> 22) & 0xf;
10168 /* Generate a conditional jump to next instruction. */
10169 s
->condlabel
= gen_new_label();
10170 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10173 /* offset[11:1] = insn[10:0] */
10174 offset
= (insn
& 0x7ff) << 1;
10175 /* offset[17:12] = insn[21:16]. */
10176 offset
|= (insn
& 0x003f0000) >> 4;
10177 /* offset[31:20] = insn[26]. */
10178 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10179 /* offset[18] = insn[13]. */
10180 offset
|= (insn
& (1 << 13)) << 5;
10181 /* offset[19] = insn[11]. */
10182 offset
|= (insn
& (1 << 11)) << 8;
10184 /* jump to the offset */
10185 gen_jmp(s
, s
->pc
+ offset
);
10188 /* Data processing immediate. */
10189 if (insn
& (1 << 25)) {
10190 if (insn
& (1 << 24)) {
10191 if (insn
& (1 << 20))
10193 /* Bitfield/Saturate. */
10194 op
= (insn
>> 21) & 7;
10196 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10198 tmp
= tcg_temp_new_i32();
10199 tcg_gen_movi_i32(tmp
, 0);
10201 tmp
= load_reg(s
, rn
);
10204 case 2: /* Signed bitfield extract. */
10206 if (shift
+ imm
> 32)
10209 gen_sbfx(tmp
, shift
, imm
);
10211 case 6: /* Unsigned bitfield extract. */
10213 if (shift
+ imm
> 32)
10216 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
10218 case 3: /* Bitfield insert/clear. */
10221 imm
= imm
+ 1 - shift
;
10223 tmp2
= load_reg(s
, rd
);
10224 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10225 tcg_temp_free_i32(tmp2
);
10230 default: /* Saturate. */
10233 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10235 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10237 tmp2
= tcg_const_i32(imm
);
10240 if ((op
& 1) && shift
== 0) {
10241 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10242 tcg_temp_free_i32(tmp
);
10243 tcg_temp_free_i32(tmp2
);
10246 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10248 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10252 if ((op
& 1) && shift
== 0) {
10253 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10254 tcg_temp_free_i32(tmp
);
10255 tcg_temp_free_i32(tmp2
);
10258 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10260 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10263 tcg_temp_free_i32(tmp2
);
10266 store_reg(s
, rd
, tmp
);
10268 imm
= ((insn
& 0x04000000) >> 15)
10269 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10270 if (insn
& (1 << 22)) {
10271 /* 16-bit immediate. */
10272 imm
|= (insn
>> 4) & 0xf000;
10273 if (insn
& (1 << 23)) {
10275 tmp
= load_reg(s
, rd
);
10276 tcg_gen_ext16u_i32(tmp
, tmp
);
10277 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10280 tmp
= tcg_temp_new_i32();
10281 tcg_gen_movi_i32(tmp
, imm
);
10284 /* Add/sub 12-bit immediate. */
10286 offset
= s
->pc
& ~(uint32_t)3;
10287 if (insn
& (1 << 23))
10291 tmp
= tcg_temp_new_i32();
10292 tcg_gen_movi_i32(tmp
, offset
);
10294 tmp
= load_reg(s
, rn
);
10295 if (insn
& (1 << 23))
10296 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10298 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10301 store_reg(s
, rd
, tmp
);
10304 int shifter_out
= 0;
10305 /* modified 12-bit immediate. */
10306 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10307 imm
= (insn
& 0xff);
10310 /* Nothing to do. */
10312 case 1: /* 00XY00XY */
10315 case 2: /* XY00XY00 */
10319 case 3: /* XYXYXYXY */
10323 default: /* Rotated constant. */
10324 shift
= (shift
<< 1) | (imm
>> 7);
10326 imm
= imm
<< (32 - shift
);
10330 tmp2
= tcg_temp_new_i32();
10331 tcg_gen_movi_i32(tmp2
, imm
);
10332 rn
= (insn
>> 16) & 0xf;
10334 tmp
= tcg_temp_new_i32();
10335 tcg_gen_movi_i32(tmp
, 0);
10337 tmp
= load_reg(s
, rn
);
10339 op
= (insn
>> 21) & 0xf;
10340 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10341 shifter_out
, tmp
, tmp2
))
10343 tcg_temp_free_i32(tmp2
);
10344 rd
= (insn
>> 8) & 0xf;
10346 store_reg(s
, rd
, tmp
);
10348 tcg_temp_free_i32(tmp
);
10353 case 12: /* Load/store single data item. */
10358 if ((insn
& 0x01100000) == 0x01000000) {
10359 if (disas_neon_ls_insn(s
, insn
)) {
10364 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10366 if (!(insn
& (1 << 20))) {
10370 /* Byte or halfword load space with dest == r15 : memory hints.
10371 * Catch them early so we don't emit pointless addressing code.
10372 * This space is a mix of:
10373 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10374 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10376 * unallocated hints, which must be treated as NOPs
10377 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10378 * which is easiest for the decoding logic
10379 * Some space which must UNDEF
10381 int op1
= (insn
>> 23) & 3;
10382 int op2
= (insn
>> 6) & 0x3f;
10387 /* UNPREDICTABLE, unallocated hint or
10388 * PLD/PLDW/PLI (literal)
10393 return 0; /* PLD/PLDW/PLI or unallocated hint */
10395 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10396 return 0; /* PLD/PLDW/PLI or unallocated hint */
10398 /* UNDEF space, or an UNPREDICTABLE */
10402 memidx
= get_mem_index(s
);
10404 addr
= tcg_temp_new_i32();
10406 /* s->pc has already been incremented by 4. */
10407 imm
= s
->pc
& 0xfffffffc;
10408 if (insn
& (1 << 23))
10409 imm
+= insn
& 0xfff;
10411 imm
-= insn
& 0xfff;
10412 tcg_gen_movi_i32(addr
, imm
);
10414 addr
= load_reg(s
, rn
);
10415 if (insn
& (1 << 23)) {
10416 /* Positive offset. */
10417 imm
= insn
& 0xfff;
10418 tcg_gen_addi_i32(addr
, addr
, imm
);
10421 switch ((insn
>> 8) & 0xf) {
10422 case 0x0: /* Shifted Register. */
10423 shift
= (insn
>> 4) & 0xf;
10425 tcg_temp_free_i32(addr
);
10428 tmp
= load_reg(s
, rm
);
10430 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10431 tcg_gen_add_i32(addr
, addr
, tmp
);
10432 tcg_temp_free_i32(tmp
);
10434 case 0xc: /* Negative offset. */
10435 tcg_gen_addi_i32(addr
, addr
, -imm
);
10437 case 0xe: /* User privilege. */
10438 tcg_gen_addi_i32(addr
, addr
, imm
);
10439 memidx
= get_a32_user_mem_index(s
);
10441 case 0x9: /* Post-decrement. */
10443 /* Fall through. */
10444 case 0xb: /* Post-increment. */
10448 case 0xd: /* Pre-decrement. */
10450 /* Fall through. */
10451 case 0xf: /* Pre-increment. */
10452 tcg_gen_addi_i32(addr
, addr
, imm
);
10456 tcg_temp_free_i32(addr
);
10461 if (insn
& (1 << 20)) {
10463 tmp
= tcg_temp_new_i32();
10466 gen_aa32_ld8u(s
, tmp
, addr
, memidx
);
10469 gen_aa32_ld8s(s
, tmp
, addr
, memidx
);
10472 gen_aa32_ld16u(s
, tmp
, addr
, memidx
);
10475 gen_aa32_ld16s(s
, tmp
, addr
, memidx
);
10478 gen_aa32_ld32u(s
, tmp
, addr
, memidx
);
10481 tcg_temp_free_i32(tmp
);
10482 tcg_temp_free_i32(addr
);
10488 store_reg(s
, rs
, tmp
);
10492 tmp
= load_reg(s
, rs
);
10495 gen_aa32_st8(s
, tmp
, addr
, memidx
);
10498 gen_aa32_st16(s
, tmp
, addr
, memidx
);
10501 gen_aa32_st32(s
, tmp
, addr
, memidx
);
10504 tcg_temp_free_i32(tmp
);
10505 tcg_temp_free_i32(addr
);
10508 tcg_temp_free_i32(tmp
);
10511 tcg_gen_addi_i32(addr
, addr
, imm
);
10513 store_reg(s
, rn
, addr
);
10515 tcg_temp_free_i32(addr
);
10527 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10529 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10536 if (s
->condexec_mask
) {
10537 cond
= s
->condexec_cond
;
10538 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10539 s
->condlabel
= gen_new_label();
10540 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10545 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
10548 switch (insn
>> 12) {
10552 op
= (insn
>> 11) & 3;
10555 rn
= (insn
>> 3) & 7;
10556 tmp
= load_reg(s
, rn
);
10557 if (insn
& (1 << 10)) {
10559 tmp2
= tcg_temp_new_i32();
10560 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10563 rm
= (insn
>> 6) & 7;
10564 tmp2
= load_reg(s
, rm
);
10566 if (insn
& (1 << 9)) {
10567 if (s
->condexec_mask
)
10568 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10570 gen_sub_CC(tmp
, tmp
, tmp2
);
10572 if (s
->condexec_mask
)
10573 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10575 gen_add_CC(tmp
, tmp
, tmp2
);
10577 tcg_temp_free_i32(tmp2
);
10578 store_reg(s
, rd
, tmp
);
10580 /* shift immediate */
10581 rm
= (insn
>> 3) & 7;
10582 shift
= (insn
>> 6) & 0x1f;
10583 tmp
= load_reg(s
, rm
);
10584 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10585 if (!s
->condexec_mask
)
10587 store_reg(s
, rd
, tmp
);
10591 /* arithmetic large immediate */
10592 op
= (insn
>> 11) & 3;
10593 rd
= (insn
>> 8) & 0x7;
10594 if (op
== 0) { /* mov */
10595 tmp
= tcg_temp_new_i32();
10596 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10597 if (!s
->condexec_mask
)
10599 store_reg(s
, rd
, tmp
);
10601 tmp
= load_reg(s
, rd
);
10602 tmp2
= tcg_temp_new_i32();
10603 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10606 gen_sub_CC(tmp
, tmp
, tmp2
);
10607 tcg_temp_free_i32(tmp
);
10608 tcg_temp_free_i32(tmp2
);
10611 if (s
->condexec_mask
)
10612 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10614 gen_add_CC(tmp
, tmp
, tmp2
);
10615 tcg_temp_free_i32(tmp2
);
10616 store_reg(s
, rd
, tmp
);
10619 if (s
->condexec_mask
)
10620 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10622 gen_sub_CC(tmp
, tmp
, tmp2
);
10623 tcg_temp_free_i32(tmp2
);
10624 store_reg(s
, rd
, tmp
);
10630 if (insn
& (1 << 11)) {
10631 rd
= (insn
>> 8) & 7;
10632 /* load pc-relative. Bit 1 of PC is ignored. */
10633 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10634 val
&= ~(uint32_t)2;
10635 addr
= tcg_temp_new_i32();
10636 tcg_gen_movi_i32(addr
, val
);
10637 tmp
= tcg_temp_new_i32();
10638 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10639 tcg_temp_free_i32(addr
);
10640 store_reg(s
, rd
, tmp
);
10643 if (insn
& (1 << 10)) {
10644 /* data processing extended or blx */
10645 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10646 rm
= (insn
>> 3) & 0xf;
10647 op
= (insn
>> 8) & 3;
10650 tmp
= load_reg(s
, rd
);
10651 tmp2
= load_reg(s
, rm
);
10652 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10653 tcg_temp_free_i32(tmp2
);
10654 store_reg(s
, rd
, tmp
);
10657 tmp
= load_reg(s
, rd
);
10658 tmp2
= load_reg(s
, rm
);
10659 gen_sub_CC(tmp
, tmp
, tmp2
);
10660 tcg_temp_free_i32(tmp2
);
10661 tcg_temp_free_i32(tmp
);
10663 case 2: /* mov/cpy */
10664 tmp
= load_reg(s
, rm
);
10665 store_reg(s
, rd
, tmp
);
10667 case 3:/* branch [and link] exchange thumb register */
10668 tmp
= load_reg(s
, rm
);
10669 if (insn
& (1 << 7)) {
10671 val
= (uint32_t)s
->pc
| 1;
10672 tmp2
= tcg_temp_new_i32();
10673 tcg_gen_movi_i32(tmp2
, val
);
10674 store_reg(s
, 14, tmp2
);
10676 /* already thumb, no need to check */
10683 /* data processing register */
10685 rm
= (insn
>> 3) & 7;
10686 op
= (insn
>> 6) & 0xf;
10687 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10688 /* the shift/rotate ops want the operands backwards */
10697 if (op
== 9) { /* neg */
10698 tmp
= tcg_temp_new_i32();
10699 tcg_gen_movi_i32(tmp
, 0);
10700 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10701 tmp
= load_reg(s
, rd
);
10703 TCGV_UNUSED_I32(tmp
);
10706 tmp2
= load_reg(s
, rm
);
10708 case 0x0: /* and */
10709 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10710 if (!s
->condexec_mask
)
10713 case 0x1: /* eor */
10714 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10715 if (!s
->condexec_mask
)
10718 case 0x2: /* lsl */
10719 if (s
->condexec_mask
) {
10720 gen_shl(tmp2
, tmp2
, tmp
);
10722 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10723 gen_logic_CC(tmp2
);
10726 case 0x3: /* lsr */
10727 if (s
->condexec_mask
) {
10728 gen_shr(tmp2
, tmp2
, tmp
);
10730 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10731 gen_logic_CC(tmp2
);
10734 case 0x4: /* asr */
10735 if (s
->condexec_mask
) {
10736 gen_sar(tmp2
, tmp2
, tmp
);
10738 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10739 gen_logic_CC(tmp2
);
10742 case 0x5: /* adc */
10743 if (s
->condexec_mask
) {
10744 gen_adc(tmp
, tmp2
);
10746 gen_adc_CC(tmp
, tmp
, tmp2
);
10749 case 0x6: /* sbc */
10750 if (s
->condexec_mask
) {
10751 gen_sub_carry(tmp
, tmp
, tmp2
);
10753 gen_sbc_CC(tmp
, tmp
, tmp2
);
10756 case 0x7: /* ror */
10757 if (s
->condexec_mask
) {
10758 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10759 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10761 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10762 gen_logic_CC(tmp2
);
10765 case 0x8: /* tst */
10766 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10770 case 0x9: /* neg */
10771 if (s
->condexec_mask
)
10772 tcg_gen_neg_i32(tmp
, tmp2
);
10774 gen_sub_CC(tmp
, tmp
, tmp2
);
10776 case 0xa: /* cmp */
10777 gen_sub_CC(tmp
, tmp
, tmp2
);
10780 case 0xb: /* cmn */
10781 gen_add_CC(tmp
, tmp
, tmp2
);
10784 case 0xc: /* orr */
10785 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10786 if (!s
->condexec_mask
)
10789 case 0xd: /* mul */
10790 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10791 if (!s
->condexec_mask
)
10794 case 0xe: /* bic */
10795 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10796 if (!s
->condexec_mask
)
10799 case 0xf: /* mvn */
10800 tcg_gen_not_i32(tmp2
, tmp2
);
10801 if (!s
->condexec_mask
)
10802 gen_logic_CC(tmp2
);
10809 store_reg(s
, rm
, tmp2
);
10811 tcg_temp_free_i32(tmp
);
10813 store_reg(s
, rd
, tmp
);
10814 tcg_temp_free_i32(tmp2
);
10817 tcg_temp_free_i32(tmp
);
10818 tcg_temp_free_i32(tmp2
);
10823 /* load/store register offset. */
10825 rn
= (insn
>> 3) & 7;
10826 rm
= (insn
>> 6) & 7;
10827 op
= (insn
>> 9) & 7;
10828 addr
= load_reg(s
, rn
);
10829 tmp
= load_reg(s
, rm
);
10830 tcg_gen_add_i32(addr
, addr
, tmp
);
10831 tcg_temp_free_i32(tmp
);
10833 if (op
< 3) { /* store */
10834 tmp
= load_reg(s
, rd
);
10836 tmp
= tcg_temp_new_i32();
10841 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10844 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
10847 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
10849 case 3: /* ldrsb */
10850 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
10853 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10856 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
10859 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
10861 case 7: /* ldrsh */
10862 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
10865 if (op
>= 3) { /* load */
10866 store_reg(s
, rd
, tmp
);
10868 tcg_temp_free_i32(tmp
);
10870 tcg_temp_free_i32(addr
);
10874 /* load/store word immediate offset */
10876 rn
= (insn
>> 3) & 7;
10877 addr
= load_reg(s
, rn
);
10878 val
= (insn
>> 4) & 0x7c;
10879 tcg_gen_addi_i32(addr
, addr
, val
);
10881 if (insn
& (1 << 11)) {
10883 tmp
= tcg_temp_new_i32();
10884 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10885 store_reg(s
, rd
, tmp
);
10888 tmp
= load_reg(s
, rd
);
10889 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10890 tcg_temp_free_i32(tmp
);
10892 tcg_temp_free_i32(addr
);
10896 /* load/store byte immediate offset */
10898 rn
= (insn
>> 3) & 7;
10899 addr
= load_reg(s
, rn
);
10900 val
= (insn
>> 6) & 0x1f;
10901 tcg_gen_addi_i32(addr
, addr
, val
);
10903 if (insn
& (1 << 11)) {
10905 tmp
= tcg_temp_new_i32();
10906 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
10907 store_reg(s
, rd
, tmp
);
10910 tmp
= load_reg(s
, rd
);
10911 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
10912 tcg_temp_free_i32(tmp
);
10914 tcg_temp_free_i32(addr
);
10918 /* load/store halfword immediate offset */
10920 rn
= (insn
>> 3) & 7;
10921 addr
= load_reg(s
, rn
);
10922 val
= (insn
>> 5) & 0x3e;
10923 tcg_gen_addi_i32(addr
, addr
, val
);
10925 if (insn
& (1 << 11)) {
10927 tmp
= tcg_temp_new_i32();
10928 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
10929 store_reg(s
, rd
, tmp
);
10932 tmp
= load_reg(s
, rd
);
10933 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
10934 tcg_temp_free_i32(tmp
);
10936 tcg_temp_free_i32(addr
);
10940 /* load/store from stack */
10941 rd
= (insn
>> 8) & 7;
10942 addr
= load_reg(s
, 13);
10943 val
= (insn
& 0xff) * 4;
10944 tcg_gen_addi_i32(addr
, addr
, val
);
10946 if (insn
& (1 << 11)) {
10948 tmp
= tcg_temp_new_i32();
10949 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10950 store_reg(s
, rd
, tmp
);
10953 tmp
= load_reg(s
, rd
);
10954 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10955 tcg_temp_free_i32(tmp
);
10957 tcg_temp_free_i32(addr
);
10961 /* add to high reg */
10962 rd
= (insn
>> 8) & 7;
10963 if (insn
& (1 << 11)) {
10965 tmp
= load_reg(s
, 13);
10967 /* PC. bit 1 is ignored. */
10968 tmp
= tcg_temp_new_i32();
10969 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10971 val
= (insn
& 0xff) * 4;
10972 tcg_gen_addi_i32(tmp
, tmp
, val
);
10973 store_reg(s
, rd
, tmp
);
10978 op
= (insn
>> 8) & 0xf;
10981 /* adjust stack pointer */
10982 tmp
= load_reg(s
, 13);
10983 val
= (insn
& 0x7f) * 4;
10984 if (insn
& (1 << 7))
10985 val
= -(int32_t)val
;
10986 tcg_gen_addi_i32(tmp
, tmp
, val
);
10987 store_reg(s
, 13, tmp
);
10990 case 2: /* sign/zero extend. */
10993 rm
= (insn
>> 3) & 7;
10994 tmp
= load_reg(s
, rm
);
10995 switch ((insn
>> 6) & 3) {
10996 case 0: gen_sxth(tmp
); break;
10997 case 1: gen_sxtb(tmp
); break;
10998 case 2: gen_uxth(tmp
); break;
10999 case 3: gen_uxtb(tmp
); break;
11001 store_reg(s
, rd
, tmp
);
11003 case 4: case 5: case 0xc: case 0xd:
11005 addr
= load_reg(s
, 13);
11006 if (insn
& (1 << 8))
11010 for (i
= 0; i
< 8; i
++) {
11011 if (insn
& (1 << i
))
11014 if ((insn
& (1 << 11)) == 0) {
11015 tcg_gen_addi_i32(addr
, addr
, -offset
);
11017 for (i
= 0; i
< 8; i
++) {
11018 if (insn
& (1 << i
)) {
11019 if (insn
& (1 << 11)) {
11021 tmp
= tcg_temp_new_i32();
11022 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11023 store_reg(s
, i
, tmp
);
11026 tmp
= load_reg(s
, i
);
11027 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11028 tcg_temp_free_i32(tmp
);
11030 /* advance to the next address. */
11031 tcg_gen_addi_i32(addr
, addr
, 4);
11034 TCGV_UNUSED_I32(tmp
);
11035 if (insn
& (1 << 8)) {
11036 if (insn
& (1 << 11)) {
11038 tmp
= tcg_temp_new_i32();
11039 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11040 /* don't set the pc until the rest of the instruction
11044 tmp
= load_reg(s
, 14);
11045 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11046 tcg_temp_free_i32(tmp
);
11048 tcg_gen_addi_i32(addr
, addr
, 4);
11050 if ((insn
& (1 << 11)) == 0) {
11051 tcg_gen_addi_i32(addr
, addr
, -offset
);
11053 /* write back the new stack pointer */
11054 store_reg(s
, 13, addr
);
11055 /* set the new PC value */
11056 if ((insn
& 0x0900) == 0x0900) {
11057 store_reg_from_load(s
, 15, tmp
);
11061 case 1: case 3: case 9: case 11: /* czb */
11063 tmp
= load_reg(s
, rm
);
11064 s
->condlabel
= gen_new_label();
11066 if (insn
& (1 << 11))
11067 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11069 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11070 tcg_temp_free_i32(tmp
);
11071 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11072 val
= (uint32_t)s
->pc
+ 2;
11077 case 15: /* IT, nop-hint. */
11078 if ((insn
& 0xf) == 0) {
11079 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11083 s
->condexec_cond
= (insn
>> 4) & 0xe;
11084 s
->condexec_mask
= insn
& 0x1f;
11085 /* No actual code generated for this insn, just setup state. */
11088 case 0xe: /* bkpt */
11090 int imm8
= extract32(insn
, 0, 8);
11092 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11093 default_exception_el(s
));
11097 case 0xa: /* rev */
11099 rn
= (insn
>> 3) & 0x7;
11101 tmp
= load_reg(s
, rn
);
11102 switch ((insn
>> 6) & 3) {
11103 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11104 case 1: gen_rev16(tmp
); break;
11105 case 3: gen_revsh(tmp
); break;
11106 default: goto illegal_op
;
11108 store_reg(s
, rd
, tmp
);
11112 switch ((insn
>> 5) & 7) {
11116 if (((insn
>> 3) & 1) != bswap_code(s
->sctlr_b
)) {
11117 /* Dynamic endianness switching not implemented. */
11118 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
11128 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11129 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11132 addr
= tcg_const_i32(19);
11133 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11134 tcg_temp_free_i32(addr
);
11138 addr
= tcg_const_i32(16);
11139 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11140 tcg_temp_free_i32(addr
);
11142 tcg_temp_free_i32(tmp
);
11145 if (insn
& (1 << 4)) {
11146 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11150 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11165 /* load/store multiple */
11166 TCGv_i32 loaded_var
;
11167 TCGV_UNUSED_I32(loaded_var
);
11168 rn
= (insn
>> 8) & 0x7;
11169 addr
= load_reg(s
, rn
);
11170 for (i
= 0; i
< 8; i
++) {
11171 if (insn
& (1 << i
)) {
11172 if (insn
& (1 << 11)) {
11174 tmp
= tcg_temp_new_i32();
11175 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11179 store_reg(s
, i
, tmp
);
11183 tmp
= load_reg(s
, i
);
11184 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11185 tcg_temp_free_i32(tmp
);
11187 /* advance to the next address */
11188 tcg_gen_addi_i32(addr
, addr
, 4);
11191 if ((insn
& (1 << rn
)) == 0) {
11192 /* base reg not in list: base register writeback */
11193 store_reg(s
, rn
, addr
);
11195 /* base reg in list: if load, complete it now */
11196 if (insn
& (1 << 11)) {
11197 store_reg(s
, rn
, loaded_var
);
11199 tcg_temp_free_i32(addr
);
11204 /* conditional branch or swi */
11205 cond
= (insn
>> 8) & 0xf;
11211 gen_set_pc_im(s
, s
->pc
);
11212 s
->svc_imm
= extract32(insn
, 0, 8);
11213 s
->is_jmp
= DISAS_SWI
;
11216 /* generate a conditional jump to next instruction */
11217 s
->condlabel
= gen_new_label();
11218 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11221 /* jump to the offset */
11222 val
= (uint32_t)s
->pc
+ 2;
11223 offset
= ((int32_t)insn
<< 24) >> 24;
11224 val
+= offset
<< 1;
11229 if (insn
& (1 << 11)) {
11230 if (disas_thumb2_insn(env
, s
, insn
))
11234 /* unconditional branch */
11235 val
= (uint32_t)s
->pc
;
11236 offset
= ((int32_t)insn
<< 21) >> 21;
11237 val
+= (offset
<< 1) + 2;
11242 if (disas_thumb2_insn(env
, s
, insn
))
11248 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11249 default_exception_el(s
));
11253 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11254 default_exception_el(s
));
11257 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11259 /* Return true if the insn at dc->pc might cross a page boundary.
11260 * (False positives are OK, false negatives are not.)
11264 if ((s
->pc
& 3) == 0) {
11265 /* At a 4-aligned address we can't be crossing a page */
11269 /* This must be a Thumb insn */
11270 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11272 if ((insn
>> 11) >= 0x1d) {
11273 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11274 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11275 * end up actually treating this as two 16-bit insns (see the
11276 * code at the start of disas_thumb2_insn()) but we don't bother
11277 * to check for that as it is unlikely, and false positives here
11282 /* Definitely a 16-bit insn, can't be crossing a page. */
11286 /* generate intermediate code for basic block 'tb'. */
11287 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11289 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11290 CPUState
*cs
= CPU(cpu
);
11291 DisasContext dc1
, *dc
= &dc1
;
11292 target_ulong pc_start
;
11293 target_ulong next_page_start
;
11298 /* generate intermediate code */
11300 /* The A64 decoder has its own top level loop, because it doesn't need
11301 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11303 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11304 gen_intermediate_code_a64(cpu
, tb
);
11312 dc
->is_jmp
= DISAS_NEXT
;
11314 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11318 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11319 * there is no secure EL1, so we route exceptions to EL3.
11321 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11322 !arm_el_is_aa64(env
, 3);
11323 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11324 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(tb
->flags
);
11325 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11326 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11327 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11328 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11329 #if !defined(CONFIG_USER_ONLY)
11330 dc
->user
= (dc
->current_el
== 0);
11332 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11333 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11334 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11335 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11336 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11337 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11338 dc
->cp_regs
= cpu
->cp_regs
;
11339 dc
->features
= env
->features
;
11341 /* Single step state. The code-generation logic here is:
11343 * generate code with no special handling for single-stepping (except
11344 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11345 * this happens anyway because those changes are all system register or
11347 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11348 * emit code for one insn
11349 * emit code to clear PSTATE.SS
11350 * emit code to generate software step exception for completed step
11351 * end TB (as usual for having generated an exception)
11352 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11353 * emit code to generate a software step exception
11356 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11357 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11358 dc
->is_ldex
= false;
11359 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11361 cpu_F0s
= tcg_temp_new_i32();
11362 cpu_F1s
= tcg_temp_new_i32();
11363 cpu_F0d
= tcg_temp_new_i64();
11364 cpu_F1d
= tcg_temp_new_i64();
11367 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11368 cpu_M0
= tcg_temp_new_i64();
11369 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11371 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11372 if (max_insns
== 0) {
11373 max_insns
= CF_COUNT_MASK
;
11375 if (max_insns
> TCG_MAX_INSNS
) {
11376 max_insns
= TCG_MAX_INSNS
;
11381 tcg_clear_temp_count();
11383 /* A note on handling of the condexec (IT) bits:
11385 * We want to avoid the overhead of having to write the updated condexec
11386 * bits back to the CPUARMState for every instruction in an IT block. So:
11387 * (1) if the condexec bits are not already zero then we write
11388 * zero back into the CPUARMState now. This avoids complications trying
11389 * to do it at the end of the block. (For example if we don't do this
11390 * it's hard to identify whether we can safely skip writing condexec
11391 * at the end of the TB, which we definitely want to do for the case
11392 * where a TB doesn't do anything with the IT state at all.)
11393 * (2) if we are going to leave the TB then we call gen_set_condexec()
11394 * which will write the correct value into CPUARMState if zero is wrong.
11395 * This is done both for leaving the TB at the end, and for leaving
11396 * it because of an exception we know will happen, which is done in
11397 * gen_exception_insn(). The latter is necessary because we need to
11398 * leave the TB with the PC/IT state just prior to execution of the
11399 * instruction which caused the exception.
11400 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11401 * then the CPUARMState will be wrong and we need to reset it.
11402 * This is handled in the same way as restoration of the
11403 * PC in these situations; we save the value of the condexec bits
11404 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11405 * then uses this to restore them after an exception.
11407 * Note that there are no instructions which can read the condexec
11408 * bits, and none which can write non-static values to them, so
11409 * we don't need to care about whether CPUARMState is correct in the
11413 /* Reset the conditional execution bits immediately. This avoids
11414 complications trying to do it at the end of the block. */
11415 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11417 TCGv_i32 tmp
= tcg_temp_new_i32();
11418 tcg_gen_movi_i32(tmp
, 0);
11419 store_cpu_field(tmp
, condexec_bits
);
11422 tcg_gen_insn_start(dc
->pc
,
11423 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1));
11426 #ifdef CONFIG_USER_ONLY
11427 /* Intercept jump to the magic kernel page. */
11428 if (dc
->pc
>= 0xffff0000) {
11429 /* We always get here via a jump, so know we are not in a
11430 conditional execution block. */
11431 gen_exception_internal(EXCP_KERNEL_TRAP
);
11432 dc
->is_jmp
= DISAS_EXC
;
11436 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11437 /* We always get here via a jump, so know we are not in a
11438 conditional execution block. */
11439 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11440 dc
->is_jmp
= DISAS_EXC
;
11445 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11447 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11448 if (bp
->pc
== dc
->pc
) {
11449 if (bp
->flags
& BP_CPU
) {
11450 gen_set_condexec(dc
);
11451 gen_set_pc_im(dc
, dc
->pc
);
11452 gen_helper_check_breakpoints(cpu_env
);
11453 /* End the TB early; it's likely not going to be executed */
11454 dc
->is_jmp
= DISAS_UPDATE
;
11456 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11457 /* The address covered by the breakpoint must be
11458 included in [tb->pc, tb->pc + tb->size) in order
11459 to for it to be properly cleared -- thus we
11460 increment the PC here so that the logic setting
11461 tb->size below does the right thing. */
11462 /* TODO: Advance PC by correct instruction length to
11463 * avoid disassembler error messages */
11465 goto done_generating
;
11472 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11476 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11477 /* Singlestep state is Active-pending.
11478 * If we're in this state at the start of a TB then either
11479 * a) we just took an exception to an EL which is being debugged
11480 * and this is the first insn in the exception handler
11481 * b) debug exceptions were masked and we just unmasked them
11482 * without changing EL (eg by clearing PSTATE.D)
11483 * In either case we're going to take a swstep exception in the
11484 * "did not step an insn" case, and so the syndrome ISV and EX
11485 * bits should be zero.
11487 assert(num_insns
== 1);
11488 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11489 default_exception_el(dc
));
11490 goto done_generating
;
11494 disas_thumb_insn(env
, dc
);
11495 if (dc
->condexec_mask
) {
11496 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11497 | ((dc
->condexec_mask
>> 4) & 1);
11498 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11499 if (dc
->condexec_mask
== 0) {
11500 dc
->condexec_cond
= 0;
11504 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
11506 disas_arm_insn(dc
, insn
);
11509 if (dc
->condjmp
&& !dc
->is_jmp
) {
11510 gen_set_label(dc
->condlabel
);
11514 if (tcg_check_temp_count()) {
11515 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11519 /* Translation stops when a conditional branch is encountered.
11520 * Otherwise the subsequent code could get translated several times.
11521 * Also stop translation when a page boundary is reached. This
11522 * ensures prefetch aborts occur at the right place. */
11524 /* We want to stop the TB if the next insn starts in a new page,
11525 * or if it spans between this page and the next. This means that
11526 * if we're looking at the last halfword in the page we need to
11527 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11528 * or a 32-bit Thumb insn (which won't).
11529 * This is to avoid generating a silly TB with a single 16-bit insn
11530 * in it at the end of this page (which would execute correctly
11531 * but isn't very efficient).
11533 end_of_page
= (dc
->pc
>= next_page_start
) ||
11534 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
11536 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11537 !cs
->singlestep_enabled
&&
11541 num_insns
< max_insns
);
11543 if (tb
->cflags
& CF_LAST_IO
) {
11545 /* FIXME: This can theoretically happen with self-modifying
11547 cpu_abort(cs
, "IO on conditional branch instruction");
11552 /* At this stage dc->condjmp will only be set when the skipped
11553 instruction was a conditional branch or trap, and the PC has
11554 already been written. */
11555 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11556 /* Unconditional and "condition passed" instruction codepath. */
11557 gen_set_condexec(dc
);
11558 switch (dc
->is_jmp
) {
11560 gen_ss_advance(dc
);
11561 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11562 default_exception_el(dc
));
11565 gen_ss_advance(dc
);
11566 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11569 gen_ss_advance(dc
);
11570 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11574 gen_set_pc_im(dc
, dc
->pc
);
11577 if (dc
->ss_active
) {
11578 gen_step_complete_exception(dc
);
11580 /* FIXME: Single stepping a WFI insn will not halt
11582 gen_exception_internal(EXCP_DEBUG
);
11586 /* "Condition failed" instruction codepath. */
11587 gen_set_label(dc
->condlabel
);
11588 gen_set_condexec(dc
);
11589 gen_set_pc_im(dc
, dc
->pc
);
11590 if (dc
->ss_active
) {
11591 gen_step_complete_exception(dc
);
11593 gen_exception_internal(EXCP_DEBUG
);
11597 /* While branches must always occur at the end of an IT block,
11598 there are a few other things that can cause us to terminate
11599 the TB in the middle of an IT block:
11600 - Exception generating instructions (bkpt, swi, undefined).
11602 - Hardware watchpoints.
11603 Hardware breakpoints have already been handled and skip this code.
11605 gen_set_condexec(dc
);
11606 switch(dc
->is_jmp
) {
11608 gen_goto_tb(dc
, 1, dc
->pc
);
11611 gen_set_pc_im(dc
, dc
->pc
);
11615 /* indicate that the hash table must be used to find the next TB */
11616 tcg_gen_exit_tb(0);
11618 case DISAS_TB_JUMP
:
11619 /* nothing more to generate */
11622 gen_helper_wfi(cpu_env
);
11623 /* The helper doesn't necessarily throw an exception, but we
11624 * must go back to the main loop to check for interrupts anyway.
11626 tcg_gen_exit_tb(0);
11629 gen_helper_wfe(cpu_env
);
11632 gen_helper_yield(cpu_env
);
11635 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11636 default_exception_el(dc
));
11639 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11642 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11646 gen_set_label(dc
->condlabel
);
11647 gen_set_condexec(dc
);
11648 gen_goto_tb(dc
, 1, dc
->pc
);
11654 gen_tb_end(tb
, num_insns
);
11657 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11658 qemu_log("----------------\n");
11659 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11660 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
11661 dc
->thumb
| (dc
->sctlr_b
<< 1));
11665 tb
->size
= dc
->pc
- pc_start
;
11666 tb
->icount
= num_insns
;
11669 static const char *cpu_mode_names
[16] = {
11670 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11671 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11674 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11677 ARMCPU
*cpu
= ARM_CPU(cs
);
11678 CPUARMState
*env
= &cpu
->env
;
11681 const char *ns_status
;
11684 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11688 for(i
=0;i
<16;i
++) {
11689 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11691 cpu_fprintf(f
, "\n");
11693 cpu_fprintf(f
, " ");
11695 psr
= cpsr_read(env
);
11697 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
11698 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
11699 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
11704 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
11706 psr
& (1 << 31) ? 'N' : '-',
11707 psr
& (1 << 30) ? 'Z' : '-',
11708 psr
& (1 << 29) ? 'C' : '-',
11709 psr
& (1 << 28) ? 'V' : '-',
11710 psr
& CPSR_T
? 'T' : 'A',
11712 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11714 if (flags
& CPU_DUMP_FPU
) {
11715 int numvfpregs
= 0;
11716 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11719 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11722 for (i
= 0; i
< numvfpregs
; i
++) {
11723 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11724 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11725 i
* 2, (uint32_t)v
,
11726 i
* 2 + 1, (uint32_t)(v
>> 32),
11729 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11733 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
11734 target_ulong
*data
)
11738 env
->condexec_bits
= 0;
11740 env
->regs
[15] = data
[0];
11741 env
->condexec_bits
= data
[1];