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/>.
22 #include "qemu-common.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"
37 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
38 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
39 /* currently all emulated v5 cores are also v5TE, so don't bother */
40 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
41 #define ENABLE_ARCH_5J 0
42 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
43 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
44 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
45 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
46 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
48 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50 #include "translate.h"
51 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
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(TCG_AREG0
,
90 offsetof(CPUARMState
, regs
[i
]),
93 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
94 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
95 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
96 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
98 cpu_exclusive_addr
= tcg_global_mem_new_i64(TCG_AREG0
,
99 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
100 cpu_exclusive_val
= tcg_global_mem_new_i64(TCG_AREG0
,
101 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
102 #ifdef CONFIG_USER_ONLY
103 cpu_exclusive_test
= tcg_global_mem_new_i64(TCG_AREG0
,
104 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
105 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
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_UPDATE
;
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_UPDATE
;
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(TCGv_i32 val, TCGv_i32 addr, int index) \
926 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
929 #define DO_GEN_ST(SUFF, OPC) \
930 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
932 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
935 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
937 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
940 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
942 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
947 #define DO_GEN_LD(SUFF, OPC) \
948 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
950 TCGv addr64 = tcg_temp_new(); \
951 tcg_gen_extu_i32_i64(addr64, addr); \
952 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
953 tcg_temp_free(addr64); \
956 #define DO_GEN_ST(SUFF, OPC) \
957 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
959 TCGv addr64 = tcg_temp_new(); \
960 tcg_gen_extu_i32_i64(addr64, addr); \
961 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
962 tcg_temp_free(addr64); \
965 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
967 TCGv addr64
= tcg_temp_new();
968 tcg_gen_extu_i32_i64(addr64
, addr
);
969 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
970 tcg_temp_free(addr64
);
973 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
975 TCGv addr64
= tcg_temp_new();
976 tcg_gen_extu_i32_i64(addr64
, addr
);
977 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
978 tcg_temp_free(addr64
);
985 DO_GEN_LD(16s
, MO_TESW
)
986 DO_GEN_LD(16u, MO_TEUW
)
987 DO_GEN_LD(32u, MO_TEUL
)
989 DO_GEN_ST(16, MO_TEUW
)
990 DO_GEN_ST(32, MO_TEUL
)
992 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
994 tcg_gen_movi_i32(cpu_R
[15], val
);
997 static inline void gen_hvc(DisasContext
*s
, int imm16
)
999 /* The pre HVC helper handles cases when HVC gets trapped
1000 * as an undefined insn by runtime configuration (ie before
1001 * the insn really executes).
1003 gen_set_pc_im(s
, s
->pc
- 4);
1004 gen_helper_pre_hvc(cpu_env
);
1005 /* Otherwise we will treat this as a real exception which
1006 * happens after execution of the insn. (The distinction matters
1007 * for the PC value reported to the exception handler and also
1008 * for single stepping.)
1011 gen_set_pc_im(s
, s
->pc
);
1012 s
->is_jmp
= DISAS_HVC
;
1015 static inline void gen_smc(DisasContext
*s
)
1017 /* As with HVC, we may take an exception either before or after
1018 * the insn executes.
1022 gen_set_pc_im(s
, s
->pc
- 4);
1023 tmp
= tcg_const_i32(syn_aa32_smc());
1024 gen_helper_pre_smc(cpu_env
, tmp
);
1025 tcg_temp_free_i32(tmp
);
1026 gen_set_pc_im(s
, s
->pc
);
1027 s
->is_jmp
= DISAS_SMC
;
1031 gen_set_condexec (DisasContext
*s
)
1033 if (s
->condexec_mask
) {
1034 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1035 TCGv_i32 tmp
= tcg_temp_new_i32();
1036 tcg_gen_movi_i32(tmp
, val
);
1037 store_cpu_field(tmp
, condexec_bits
);
1041 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1043 gen_set_condexec(s
);
1044 gen_set_pc_im(s
, s
->pc
- offset
);
1045 gen_exception_internal(excp
);
1046 s
->is_jmp
= DISAS_JUMP
;
1049 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1050 int syn
, uint32_t target_el
)
1052 gen_set_condexec(s
);
1053 gen_set_pc_im(s
, s
->pc
- offset
);
1054 gen_exception(excp
, syn
, target_el
);
1055 s
->is_jmp
= DISAS_JUMP
;
1058 /* Force a TB lookup after an instruction that changes the CPU state. */
1059 static inline void gen_lookup_tb(DisasContext
*s
)
1061 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1062 s
->is_jmp
= DISAS_UPDATE
;
1065 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1068 int val
, rm
, shift
, shiftop
;
1071 if (!(insn
& (1 << 25))) {
1074 if (!(insn
& (1 << 23)))
1077 tcg_gen_addi_i32(var
, var
, val
);
1079 /* shift/register */
1081 shift
= (insn
>> 7) & 0x1f;
1082 shiftop
= (insn
>> 5) & 3;
1083 offset
= load_reg(s
, rm
);
1084 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1085 if (!(insn
& (1 << 23)))
1086 tcg_gen_sub_i32(var
, var
, offset
);
1088 tcg_gen_add_i32(var
, var
, offset
);
1089 tcg_temp_free_i32(offset
);
1093 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1094 int extra
, TCGv_i32 var
)
1099 if (insn
& (1 << 22)) {
1101 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1102 if (!(insn
& (1 << 23)))
1106 tcg_gen_addi_i32(var
, var
, val
);
1110 tcg_gen_addi_i32(var
, var
, extra
);
1112 offset
= load_reg(s
, rm
);
1113 if (!(insn
& (1 << 23)))
1114 tcg_gen_sub_i32(var
, var
, offset
);
1116 tcg_gen_add_i32(var
, var
, offset
);
1117 tcg_temp_free_i32(offset
);
1121 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1123 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1126 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1128 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1130 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1134 #define VFP_OP2(name) \
1135 static inline void gen_vfp_##name(int dp) \
1137 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1139 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1141 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1143 tcg_temp_free_ptr(fpst); \
1153 static inline void gen_vfp_F1_mul(int dp
)
1155 /* Like gen_vfp_mul() but put result in F1 */
1156 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1158 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1160 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1162 tcg_temp_free_ptr(fpst
);
1165 static inline void gen_vfp_F1_neg(int dp
)
1167 /* Like gen_vfp_neg() but put result in F1 */
1169 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1171 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1175 static inline void gen_vfp_abs(int dp
)
1178 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1180 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1183 static inline void gen_vfp_neg(int dp
)
1186 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1188 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1191 static inline void gen_vfp_sqrt(int dp
)
1194 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1196 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1199 static inline void gen_vfp_cmp(int dp
)
1202 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1204 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1207 static inline void gen_vfp_cmpe(int dp
)
1210 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1212 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1215 static inline void gen_vfp_F1_ld0(int dp
)
1218 tcg_gen_movi_i64(cpu_F1d
, 0);
1220 tcg_gen_movi_i32(cpu_F1s
, 0);
1223 #define VFP_GEN_ITOF(name) \
1224 static inline void gen_vfp_##name(int dp, int neon) \
1226 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1228 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1230 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1232 tcg_temp_free_ptr(statusptr); \
1239 #define VFP_GEN_FTOI(name) \
1240 static inline void gen_vfp_##name(int dp, int neon) \
1242 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1244 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1246 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1248 tcg_temp_free_ptr(statusptr); \
1257 #define VFP_GEN_FIX(name, round) \
1258 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1260 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1261 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1263 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1266 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1269 tcg_temp_free_i32(tmp_shift); \
1270 tcg_temp_free_ptr(statusptr); \
1272 VFP_GEN_FIX(tosh
, _round_to_zero
)
1273 VFP_GEN_FIX(tosl
, _round_to_zero
)
1274 VFP_GEN_FIX(touh
, _round_to_zero
)
1275 VFP_GEN_FIX(toul
, _round_to_zero
)
1282 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1285 gen_aa32_ld64(cpu_F0d
, addr
, get_mem_index(s
));
1287 gen_aa32_ld32u(cpu_F0s
, addr
, get_mem_index(s
));
1291 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1294 gen_aa32_st64(cpu_F0d
, addr
, get_mem_index(s
));
1296 gen_aa32_st32(cpu_F0s
, addr
, get_mem_index(s
));
1301 vfp_reg_offset (int dp
, int reg
)
1304 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1306 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1307 + offsetof(CPU_DoubleU
, l
.upper
);
1309 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1310 + offsetof(CPU_DoubleU
, l
.lower
);
1314 /* Return the offset of a 32-bit piece of a NEON register.
1315 zero is the least significant end of the register. */
1317 neon_reg_offset (int reg
, int n
)
1321 return vfp_reg_offset(0, sreg
);
1324 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1326 TCGv_i32 tmp
= tcg_temp_new_i32();
1327 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1331 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1333 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1334 tcg_temp_free_i32(var
);
1337 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1339 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1342 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1344 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1347 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1348 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1349 #define tcg_gen_st_f32 tcg_gen_st_i32
1350 #define tcg_gen_st_f64 tcg_gen_st_i64
1352 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1355 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1357 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1360 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1363 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1365 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1368 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1371 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1373 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1376 #define ARM_CP_RW_BIT (1 << 20)
1378 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1380 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1383 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1385 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1388 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1390 TCGv_i32 var
= tcg_temp_new_i32();
1391 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1395 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1397 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1398 tcg_temp_free_i32(var
);
1401 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1403 iwmmxt_store_reg(cpu_M0
, rn
);
1406 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1408 iwmmxt_load_reg(cpu_M0
, rn
);
1411 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1413 iwmmxt_load_reg(cpu_V1
, rn
);
1414 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1417 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1419 iwmmxt_load_reg(cpu_V1
, rn
);
1420 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1423 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1425 iwmmxt_load_reg(cpu_V1
, rn
);
1426 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1429 #define IWMMXT_OP(name) \
1430 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1432 iwmmxt_load_reg(cpu_V1, rn); \
1433 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1436 #define IWMMXT_OP_ENV(name) \
1437 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1439 iwmmxt_load_reg(cpu_V1, rn); \
1440 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1443 #define IWMMXT_OP_ENV_SIZE(name) \
1444 IWMMXT_OP_ENV(name##b) \
1445 IWMMXT_OP_ENV(name##w) \
1446 IWMMXT_OP_ENV(name##l)
1448 #define IWMMXT_OP_ENV1(name) \
1449 static inline void gen_op_iwmmxt_##name##_M0(void) \
1451 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1465 IWMMXT_OP_ENV_SIZE(unpackl
)
1466 IWMMXT_OP_ENV_SIZE(unpackh
)
1468 IWMMXT_OP_ENV1(unpacklub
)
1469 IWMMXT_OP_ENV1(unpackluw
)
1470 IWMMXT_OP_ENV1(unpacklul
)
1471 IWMMXT_OP_ENV1(unpackhub
)
1472 IWMMXT_OP_ENV1(unpackhuw
)
1473 IWMMXT_OP_ENV1(unpackhul
)
1474 IWMMXT_OP_ENV1(unpacklsb
)
1475 IWMMXT_OP_ENV1(unpacklsw
)
1476 IWMMXT_OP_ENV1(unpacklsl
)
1477 IWMMXT_OP_ENV1(unpackhsb
)
1478 IWMMXT_OP_ENV1(unpackhsw
)
1479 IWMMXT_OP_ENV1(unpackhsl
)
1481 IWMMXT_OP_ENV_SIZE(cmpeq
)
1482 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1483 IWMMXT_OP_ENV_SIZE(cmpgts
)
1485 IWMMXT_OP_ENV_SIZE(mins
)
1486 IWMMXT_OP_ENV_SIZE(minu
)
1487 IWMMXT_OP_ENV_SIZE(maxs
)
1488 IWMMXT_OP_ENV_SIZE(maxu
)
1490 IWMMXT_OP_ENV_SIZE(subn
)
1491 IWMMXT_OP_ENV_SIZE(addn
)
1492 IWMMXT_OP_ENV_SIZE(subu
)
1493 IWMMXT_OP_ENV_SIZE(addu
)
1494 IWMMXT_OP_ENV_SIZE(subs
)
1495 IWMMXT_OP_ENV_SIZE(adds
)
1497 IWMMXT_OP_ENV(avgb0
)
1498 IWMMXT_OP_ENV(avgb1
)
1499 IWMMXT_OP_ENV(avgw0
)
1500 IWMMXT_OP_ENV(avgw1
)
1502 IWMMXT_OP_ENV(packuw
)
1503 IWMMXT_OP_ENV(packul
)
1504 IWMMXT_OP_ENV(packuq
)
1505 IWMMXT_OP_ENV(packsw
)
1506 IWMMXT_OP_ENV(packsl
)
1507 IWMMXT_OP_ENV(packsq
)
1509 static void gen_op_iwmmxt_set_mup(void)
1512 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1513 tcg_gen_ori_i32(tmp
, tmp
, 2);
1514 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1517 static void gen_op_iwmmxt_set_cup(void)
1520 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1521 tcg_gen_ori_i32(tmp
, tmp
, 1);
1522 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1525 static void gen_op_iwmmxt_setpsr_nz(void)
1527 TCGv_i32 tmp
= tcg_temp_new_i32();
1528 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1529 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1532 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1534 iwmmxt_load_reg(cpu_V1
, rn
);
1535 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1536 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1539 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1546 rd
= (insn
>> 16) & 0xf;
1547 tmp
= load_reg(s
, rd
);
1549 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1550 if (insn
& (1 << 24)) {
1552 if (insn
& (1 << 23))
1553 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1555 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1556 tcg_gen_mov_i32(dest
, tmp
);
1557 if (insn
& (1 << 21))
1558 store_reg(s
, rd
, tmp
);
1560 tcg_temp_free_i32(tmp
);
1561 } else if (insn
& (1 << 21)) {
1563 tcg_gen_mov_i32(dest
, tmp
);
1564 if (insn
& (1 << 23))
1565 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1567 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1568 store_reg(s
, rd
, tmp
);
1569 } else if (!(insn
& (1 << 23)))
1574 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1576 int rd
= (insn
>> 0) & 0xf;
1579 if (insn
& (1 << 8)) {
1580 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1583 tmp
= iwmmxt_load_creg(rd
);
1586 tmp
= tcg_temp_new_i32();
1587 iwmmxt_load_reg(cpu_V0
, rd
);
1588 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1590 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1591 tcg_gen_mov_i32(dest
, tmp
);
1592 tcg_temp_free_i32(tmp
);
1596 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1597 (ie. an undefined instruction). */
1598 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1601 int rdhi
, rdlo
, rd0
, rd1
, i
;
1603 TCGv_i32 tmp
, tmp2
, tmp3
;
1605 if ((insn
& 0x0e000e00) == 0x0c000000) {
1606 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1608 rdlo
= (insn
>> 12) & 0xf;
1609 rdhi
= (insn
>> 16) & 0xf;
1610 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1611 iwmmxt_load_reg(cpu_V0
, wrd
);
1612 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1613 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1614 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1615 } else { /* TMCRR */
1616 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1617 iwmmxt_store_reg(cpu_V0
, wrd
);
1618 gen_op_iwmmxt_set_mup();
1623 wrd
= (insn
>> 12) & 0xf;
1624 addr
= tcg_temp_new_i32();
1625 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1626 tcg_temp_free_i32(addr
);
1629 if (insn
& ARM_CP_RW_BIT
) {
1630 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1631 tmp
= tcg_temp_new_i32();
1632 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1633 iwmmxt_store_creg(wrd
, tmp
);
1636 if (insn
& (1 << 8)) {
1637 if (insn
& (1 << 22)) { /* WLDRD */
1638 gen_aa32_ld64(cpu_M0
, addr
, get_mem_index(s
));
1640 } else { /* WLDRW wRd */
1641 tmp
= tcg_temp_new_i32();
1642 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1645 tmp
= tcg_temp_new_i32();
1646 if (insn
& (1 << 22)) { /* WLDRH */
1647 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
1648 } else { /* WLDRB */
1649 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
1653 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1654 tcg_temp_free_i32(tmp
);
1656 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1659 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1660 tmp
= iwmmxt_load_creg(wrd
);
1661 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1663 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1664 tmp
= tcg_temp_new_i32();
1665 if (insn
& (1 << 8)) {
1666 if (insn
& (1 << 22)) { /* WSTRD */
1667 gen_aa32_st64(cpu_M0
, addr
, get_mem_index(s
));
1668 } else { /* WSTRW wRd */
1669 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1670 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1673 if (insn
& (1 << 22)) { /* WSTRH */
1674 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1675 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
1676 } else { /* WSTRB */
1677 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1678 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
1682 tcg_temp_free_i32(tmp
);
1684 tcg_temp_free_i32(addr
);
1688 if ((insn
& 0x0f000000) != 0x0e000000)
1691 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1692 case 0x000: /* WOR */
1693 wrd
= (insn
>> 12) & 0xf;
1694 rd0
= (insn
>> 0) & 0xf;
1695 rd1
= (insn
>> 16) & 0xf;
1696 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1697 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1698 gen_op_iwmmxt_setpsr_nz();
1699 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1700 gen_op_iwmmxt_set_mup();
1701 gen_op_iwmmxt_set_cup();
1703 case 0x011: /* TMCR */
1706 rd
= (insn
>> 12) & 0xf;
1707 wrd
= (insn
>> 16) & 0xf;
1709 case ARM_IWMMXT_wCID
:
1710 case ARM_IWMMXT_wCASF
:
1712 case ARM_IWMMXT_wCon
:
1713 gen_op_iwmmxt_set_cup();
1715 case ARM_IWMMXT_wCSSF
:
1716 tmp
= iwmmxt_load_creg(wrd
);
1717 tmp2
= load_reg(s
, rd
);
1718 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1719 tcg_temp_free_i32(tmp2
);
1720 iwmmxt_store_creg(wrd
, tmp
);
1722 case ARM_IWMMXT_wCGR0
:
1723 case ARM_IWMMXT_wCGR1
:
1724 case ARM_IWMMXT_wCGR2
:
1725 case ARM_IWMMXT_wCGR3
:
1726 gen_op_iwmmxt_set_cup();
1727 tmp
= load_reg(s
, rd
);
1728 iwmmxt_store_creg(wrd
, tmp
);
1734 case 0x100: /* WXOR */
1735 wrd
= (insn
>> 12) & 0xf;
1736 rd0
= (insn
>> 0) & 0xf;
1737 rd1
= (insn
>> 16) & 0xf;
1738 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1739 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1740 gen_op_iwmmxt_setpsr_nz();
1741 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1742 gen_op_iwmmxt_set_mup();
1743 gen_op_iwmmxt_set_cup();
1745 case 0x111: /* TMRC */
1748 rd
= (insn
>> 12) & 0xf;
1749 wrd
= (insn
>> 16) & 0xf;
1750 tmp
= iwmmxt_load_creg(wrd
);
1751 store_reg(s
, rd
, tmp
);
1753 case 0x300: /* WANDN */
1754 wrd
= (insn
>> 12) & 0xf;
1755 rd0
= (insn
>> 0) & 0xf;
1756 rd1
= (insn
>> 16) & 0xf;
1757 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1758 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1759 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1760 gen_op_iwmmxt_setpsr_nz();
1761 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1762 gen_op_iwmmxt_set_mup();
1763 gen_op_iwmmxt_set_cup();
1765 case 0x200: /* WAND */
1766 wrd
= (insn
>> 12) & 0xf;
1767 rd0
= (insn
>> 0) & 0xf;
1768 rd1
= (insn
>> 16) & 0xf;
1769 gen_op_iwmmxt_movq_M0_wRn(rd0
);
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 0x810: case 0xa10: /* WMADD */
1777 wrd
= (insn
>> 12) & 0xf;
1778 rd0
= (insn
>> 0) & 0xf;
1779 rd1
= (insn
>> 16) & 0xf;
1780 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1781 if (insn
& (1 << 21))
1782 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1784 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1785 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1786 gen_op_iwmmxt_set_mup();
1788 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1789 wrd
= (insn
>> 12) & 0xf;
1790 rd0
= (insn
>> 16) & 0xf;
1791 rd1
= (insn
>> 0) & 0xf;
1792 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1793 switch ((insn
>> 22) & 3) {
1795 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1798 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1801 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1806 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1807 gen_op_iwmmxt_set_mup();
1808 gen_op_iwmmxt_set_cup();
1810 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1811 wrd
= (insn
>> 12) & 0xf;
1812 rd0
= (insn
>> 16) & 0xf;
1813 rd1
= (insn
>> 0) & 0xf;
1814 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1815 switch ((insn
>> 22) & 3) {
1817 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1820 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1823 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1828 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1829 gen_op_iwmmxt_set_mup();
1830 gen_op_iwmmxt_set_cup();
1832 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1833 wrd
= (insn
>> 12) & 0xf;
1834 rd0
= (insn
>> 16) & 0xf;
1835 rd1
= (insn
>> 0) & 0xf;
1836 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1837 if (insn
& (1 << 22))
1838 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1840 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1841 if (!(insn
& (1 << 20)))
1842 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1843 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1844 gen_op_iwmmxt_set_mup();
1846 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1847 wrd
= (insn
>> 12) & 0xf;
1848 rd0
= (insn
>> 16) & 0xf;
1849 rd1
= (insn
>> 0) & 0xf;
1850 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1851 if (insn
& (1 << 21)) {
1852 if (insn
& (1 << 20))
1853 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1855 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1857 if (insn
& (1 << 20))
1858 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1860 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1862 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1863 gen_op_iwmmxt_set_mup();
1865 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1866 wrd
= (insn
>> 12) & 0xf;
1867 rd0
= (insn
>> 16) & 0xf;
1868 rd1
= (insn
>> 0) & 0xf;
1869 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1870 if (insn
& (1 << 21))
1871 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1873 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1874 if (!(insn
& (1 << 20))) {
1875 iwmmxt_load_reg(cpu_V1
, wrd
);
1876 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1878 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1879 gen_op_iwmmxt_set_mup();
1881 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1882 wrd
= (insn
>> 12) & 0xf;
1883 rd0
= (insn
>> 16) & 0xf;
1884 rd1
= (insn
>> 0) & 0xf;
1885 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1886 switch ((insn
>> 22) & 3) {
1888 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1891 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1894 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1899 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1900 gen_op_iwmmxt_set_mup();
1901 gen_op_iwmmxt_set_cup();
1903 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1904 wrd
= (insn
>> 12) & 0xf;
1905 rd0
= (insn
>> 16) & 0xf;
1906 rd1
= (insn
>> 0) & 0xf;
1907 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1908 if (insn
& (1 << 22)) {
1909 if (insn
& (1 << 20))
1910 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1912 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1914 if (insn
& (1 << 20))
1915 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1917 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1919 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1920 gen_op_iwmmxt_set_mup();
1921 gen_op_iwmmxt_set_cup();
1923 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1924 wrd
= (insn
>> 12) & 0xf;
1925 rd0
= (insn
>> 16) & 0xf;
1926 rd1
= (insn
>> 0) & 0xf;
1927 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1928 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1929 tcg_gen_andi_i32(tmp
, tmp
, 7);
1930 iwmmxt_load_reg(cpu_V1
, rd1
);
1931 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1932 tcg_temp_free_i32(tmp
);
1933 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1934 gen_op_iwmmxt_set_mup();
1936 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1937 if (((insn
>> 6) & 3) == 3)
1939 rd
= (insn
>> 12) & 0xf;
1940 wrd
= (insn
>> 16) & 0xf;
1941 tmp
= load_reg(s
, rd
);
1942 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1943 switch ((insn
>> 6) & 3) {
1945 tmp2
= tcg_const_i32(0xff);
1946 tmp3
= tcg_const_i32((insn
& 7) << 3);
1949 tmp2
= tcg_const_i32(0xffff);
1950 tmp3
= tcg_const_i32((insn
& 3) << 4);
1953 tmp2
= tcg_const_i32(0xffffffff);
1954 tmp3
= tcg_const_i32((insn
& 1) << 5);
1957 TCGV_UNUSED_I32(tmp2
);
1958 TCGV_UNUSED_I32(tmp3
);
1960 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1961 tcg_temp_free_i32(tmp3
);
1962 tcg_temp_free_i32(tmp2
);
1963 tcg_temp_free_i32(tmp
);
1964 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1965 gen_op_iwmmxt_set_mup();
1967 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1968 rd
= (insn
>> 12) & 0xf;
1969 wrd
= (insn
>> 16) & 0xf;
1970 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1972 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1973 tmp
= tcg_temp_new_i32();
1974 switch ((insn
>> 22) & 3) {
1976 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1977 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1979 tcg_gen_ext8s_i32(tmp
, tmp
);
1981 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1985 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1986 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1988 tcg_gen_ext16s_i32(tmp
, tmp
);
1990 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1994 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1995 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1998 store_reg(s
, rd
, tmp
);
2000 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2001 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2003 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2004 switch ((insn
>> 22) & 3) {
2006 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2009 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2012 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2015 tcg_gen_shli_i32(tmp
, tmp
, 28);
2017 tcg_temp_free_i32(tmp
);
2019 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2020 if (((insn
>> 6) & 3) == 3)
2022 rd
= (insn
>> 12) & 0xf;
2023 wrd
= (insn
>> 16) & 0xf;
2024 tmp
= load_reg(s
, rd
);
2025 switch ((insn
>> 6) & 3) {
2027 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2030 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2033 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2036 tcg_temp_free_i32(tmp
);
2037 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2038 gen_op_iwmmxt_set_mup();
2040 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2041 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2043 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2044 tmp2
= tcg_temp_new_i32();
2045 tcg_gen_mov_i32(tmp2
, tmp
);
2046 switch ((insn
>> 22) & 3) {
2048 for (i
= 0; i
< 7; i
++) {
2049 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2050 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2054 for (i
= 0; i
< 3; i
++) {
2055 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2056 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2060 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2061 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2065 tcg_temp_free_i32(tmp2
);
2066 tcg_temp_free_i32(tmp
);
2068 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2069 wrd
= (insn
>> 12) & 0xf;
2070 rd0
= (insn
>> 16) & 0xf;
2071 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2072 switch ((insn
>> 22) & 3) {
2074 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2077 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2080 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2085 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2086 gen_op_iwmmxt_set_mup();
2088 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2089 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2091 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2092 tmp2
= tcg_temp_new_i32();
2093 tcg_gen_mov_i32(tmp2
, tmp
);
2094 switch ((insn
>> 22) & 3) {
2096 for (i
= 0; i
< 7; i
++) {
2097 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2098 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2102 for (i
= 0; i
< 3; i
++) {
2103 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2104 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2108 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2109 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2113 tcg_temp_free_i32(tmp2
);
2114 tcg_temp_free_i32(tmp
);
2116 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2117 rd
= (insn
>> 12) & 0xf;
2118 rd0
= (insn
>> 16) & 0xf;
2119 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2121 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2122 tmp
= tcg_temp_new_i32();
2123 switch ((insn
>> 22) & 3) {
2125 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2128 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2131 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2134 store_reg(s
, rd
, tmp
);
2136 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2137 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2138 wrd
= (insn
>> 12) & 0xf;
2139 rd0
= (insn
>> 16) & 0xf;
2140 rd1
= (insn
>> 0) & 0xf;
2141 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2142 switch ((insn
>> 22) & 3) {
2144 if (insn
& (1 << 21))
2145 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2147 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2150 if (insn
& (1 << 21))
2151 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2153 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2156 if (insn
& (1 << 21))
2157 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2159 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2164 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2165 gen_op_iwmmxt_set_mup();
2166 gen_op_iwmmxt_set_cup();
2168 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2169 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2170 wrd
= (insn
>> 12) & 0xf;
2171 rd0
= (insn
>> 16) & 0xf;
2172 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2173 switch ((insn
>> 22) & 3) {
2175 if (insn
& (1 << 21))
2176 gen_op_iwmmxt_unpacklsb_M0();
2178 gen_op_iwmmxt_unpacklub_M0();
2181 if (insn
& (1 << 21))
2182 gen_op_iwmmxt_unpacklsw_M0();
2184 gen_op_iwmmxt_unpackluw_M0();
2187 if (insn
& (1 << 21))
2188 gen_op_iwmmxt_unpacklsl_M0();
2190 gen_op_iwmmxt_unpacklul_M0();
2195 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2196 gen_op_iwmmxt_set_mup();
2197 gen_op_iwmmxt_set_cup();
2199 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2200 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2201 wrd
= (insn
>> 12) & 0xf;
2202 rd0
= (insn
>> 16) & 0xf;
2203 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2204 switch ((insn
>> 22) & 3) {
2206 if (insn
& (1 << 21))
2207 gen_op_iwmmxt_unpackhsb_M0();
2209 gen_op_iwmmxt_unpackhub_M0();
2212 if (insn
& (1 << 21))
2213 gen_op_iwmmxt_unpackhsw_M0();
2215 gen_op_iwmmxt_unpackhuw_M0();
2218 if (insn
& (1 << 21))
2219 gen_op_iwmmxt_unpackhsl_M0();
2221 gen_op_iwmmxt_unpackhul_M0();
2226 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2227 gen_op_iwmmxt_set_mup();
2228 gen_op_iwmmxt_set_cup();
2230 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2231 case 0x214: case 0x614: case 0xa14: case 0xe14:
2232 if (((insn
>> 22) & 3) == 0)
2234 wrd
= (insn
>> 12) & 0xf;
2235 rd0
= (insn
>> 16) & 0xf;
2236 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2237 tmp
= tcg_temp_new_i32();
2238 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2239 tcg_temp_free_i32(tmp
);
2242 switch ((insn
>> 22) & 3) {
2244 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2247 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2250 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2253 tcg_temp_free_i32(tmp
);
2254 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2255 gen_op_iwmmxt_set_mup();
2256 gen_op_iwmmxt_set_cup();
2258 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2259 case 0x014: case 0x414: case 0x814: case 0xc14:
2260 if (((insn
>> 22) & 3) == 0)
2262 wrd
= (insn
>> 12) & 0xf;
2263 rd0
= (insn
>> 16) & 0xf;
2264 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2265 tmp
= tcg_temp_new_i32();
2266 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2267 tcg_temp_free_i32(tmp
);
2270 switch ((insn
>> 22) & 3) {
2272 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2275 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2278 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2281 tcg_temp_free_i32(tmp
);
2282 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2283 gen_op_iwmmxt_set_mup();
2284 gen_op_iwmmxt_set_cup();
2286 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2287 case 0x114: case 0x514: case 0x914: case 0xd14:
2288 if (((insn
>> 22) & 3) == 0)
2290 wrd
= (insn
>> 12) & 0xf;
2291 rd0
= (insn
>> 16) & 0xf;
2292 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2293 tmp
= tcg_temp_new_i32();
2294 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2295 tcg_temp_free_i32(tmp
);
2298 switch ((insn
>> 22) & 3) {
2300 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2303 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2306 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2309 tcg_temp_free_i32(tmp
);
2310 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2311 gen_op_iwmmxt_set_mup();
2312 gen_op_iwmmxt_set_cup();
2314 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2315 case 0x314: case 0x714: case 0xb14: case 0xf14:
2316 if (((insn
>> 22) & 3) == 0)
2318 wrd
= (insn
>> 12) & 0xf;
2319 rd0
= (insn
>> 16) & 0xf;
2320 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2321 tmp
= tcg_temp_new_i32();
2322 switch ((insn
>> 22) & 3) {
2324 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2325 tcg_temp_free_i32(tmp
);
2328 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2331 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2332 tcg_temp_free_i32(tmp
);
2335 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2338 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2339 tcg_temp_free_i32(tmp
);
2342 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2345 tcg_temp_free_i32(tmp
);
2346 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2347 gen_op_iwmmxt_set_mup();
2348 gen_op_iwmmxt_set_cup();
2350 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2351 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2352 wrd
= (insn
>> 12) & 0xf;
2353 rd0
= (insn
>> 16) & 0xf;
2354 rd1
= (insn
>> 0) & 0xf;
2355 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2356 switch ((insn
>> 22) & 3) {
2358 if (insn
& (1 << 21))
2359 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2361 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2364 if (insn
& (1 << 21))
2365 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2367 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2370 if (insn
& (1 << 21))
2371 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2373 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2378 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2379 gen_op_iwmmxt_set_mup();
2381 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2382 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2383 wrd
= (insn
>> 12) & 0xf;
2384 rd0
= (insn
>> 16) & 0xf;
2385 rd1
= (insn
>> 0) & 0xf;
2386 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2387 switch ((insn
>> 22) & 3) {
2389 if (insn
& (1 << 21))
2390 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2392 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2395 if (insn
& (1 << 21))
2396 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2398 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2401 if (insn
& (1 << 21))
2402 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2404 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2409 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2410 gen_op_iwmmxt_set_mup();
2412 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2413 case 0x402: case 0x502: case 0x602: case 0x702:
2414 wrd
= (insn
>> 12) & 0xf;
2415 rd0
= (insn
>> 16) & 0xf;
2416 rd1
= (insn
>> 0) & 0xf;
2417 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2418 tmp
= tcg_const_i32((insn
>> 20) & 3);
2419 iwmmxt_load_reg(cpu_V1
, rd1
);
2420 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2421 tcg_temp_free_i32(tmp
);
2422 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2423 gen_op_iwmmxt_set_mup();
2425 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2426 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2427 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2428 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2429 wrd
= (insn
>> 12) & 0xf;
2430 rd0
= (insn
>> 16) & 0xf;
2431 rd1
= (insn
>> 0) & 0xf;
2432 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2433 switch ((insn
>> 20) & 0xf) {
2435 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2438 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2441 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2444 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2447 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2450 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2453 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2456 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2459 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2464 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2465 gen_op_iwmmxt_set_mup();
2466 gen_op_iwmmxt_set_cup();
2468 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2469 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2470 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2471 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2472 wrd
= (insn
>> 12) & 0xf;
2473 rd0
= (insn
>> 16) & 0xf;
2474 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2475 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2476 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2477 tcg_temp_free_i32(tmp
);
2478 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2479 gen_op_iwmmxt_set_mup();
2480 gen_op_iwmmxt_set_cup();
2482 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2483 case 0x418: case 0x518: case 0x618: case 0x718:
2484 case 0x818: case 0x918: case 0xa18: case 0xb18:
2485 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2486 wrd
= (insn
>> 12) & 0xf;
2487 rd0
= (insn
>> 16) & 0xf;
2488 rd1
= (insn
>> 0) & 0xf;
2489 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2490 switch ((insn
>> 20) & 0xf) {
2492 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2495 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2498 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2501 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2504 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2507 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2510 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2513 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2516 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2521 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2522 gen_op_iwmmxt_set_mup();
2523 gen_op_iwmmxt_set_cup();
2525 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2526 case 0x408: case 0x508: case 0x608: case 0x708:
2527 case 0x808: case 0x908: case 0xa08: case 0xb08:
2528 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2529 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2531 wrd
= (insn
>> 12) & 0xf;
2532 rd0
= (insn
>> 16) & 0xf;
2533 rd1
= (insn
>> 0) & 0xf;
2534 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2535 switch ((insn
>> 22) & 3) {
2537 if (insn
& (1 << 21))
2538 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2540 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2543 if (insn
& (1 << 21))
2544 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2546 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2549 if (insn
& (1 << 21))
2550 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2552 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2555 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2556 gen_op_iwmmxt_set_mup();
2557 gen_op_iwmmxt_set_cup();
2559 case 0x201: case 0x203: case 0x205: case 0x207:
2560 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2561 case 0x211: case 0x213: case 0x215: case 0x217:
2562 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2563 wrd
= (insn
>> 5) & 0xf;
2564 rd0
= (insn
>> 12) & 0xf;
2565 rd1
= (insn
>> 0) & 0xf;
2566 if (rd0
== 0xf || rd1
== 0xf)
2568 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2569 tmp
= load_reg(s
, rd0
);
2570 tmp2
= load_reg(s
, rd1
);
2571 switch ((insn
>> 16) & 0xf) {
2572 case 0x0: /* TMIA */
2573 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2575 case 0x8: /* TMIAPH */
2576 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2578 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2579 if (insn
& (1 << 16))
2580 tcg_gen_shri_i32(tmp
, tmp
, 16);
2581 if (insn
& (1 << 17))
2582 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2583 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2586 tcg_temp_free_i32(tmp2
);
2587 tcg_temp_free_i32(tmp
);
2590 tcg_temp_free_i32(tmp2
);
2591 tcg_temp_free_i32(tmp
);
2592 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2593 gen_op_iwmmxt_set_mup();
2602 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2603 (ie. an undefined instruction). */
2604 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2606 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2609 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2610 /* Multiply with Internal Accumulate Format */
2611 rd0
= (insn
>> 12) & 0xf;
2613 acc
= (insn
>> 5) & 7;
2618 tmp
= load_reg(s
, rd0
);
2619 tmp2
= load_reg(s
, rd1
);
2620 switch ((insn
>> 16) & 0xf) {
2622 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2624 case 0x8: /* MIAPH */
2625 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2627 case 0xc: /* MIABB */
2628 case 0xd: /* MIABT */
2629 case 0xe: /* MIATB */
2630 case 0xf: /* MIATT */
2631 if (insn
& (1 << 16))
2632 tcg_gen_shri_i32(tmp
, tmp
, 16);
2633 if (insn
& (1 << 17))
2634 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2635 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2640 tcg_temp_free_i32(tmp2
);
2641 tcg_temp_free_i32(tmp
);
2643 gen_op_iwmmxt_movq_wRn_M0(acc
);
2647 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2648 /* Internal Accumulator Access Format */
2649 rdhi
= (insn
>> 16) & 0xf;
2650 rdlo
= (insn
>> 12) & 0xf;
2656 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2657 iwmmxt_load_reg(cpu_V0
, acc
);
2658 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2659 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2660 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2661 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2663 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2664 iwmmxt_store_reg(cpu_V0
, acc
);
2672 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2673 #define VFP_SREG(insn, bigbit, smallbit) \
2674 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2675 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2676 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2677 reg = (((insn) >> (bigbit)) & 0x0f) \
2678 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2680 if (insn & (1 << (smallbit))) \
2682 reg = ((insn) >> (bigbit)) & 0x0f; \
2685 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2686 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2687 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2688 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2689 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2690 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2692 /* Move between integer and VFP cores. */
2693 static TCGv_i32
gen_vfp_mrs(void)
2695 TCGv_i32 tmp
= tcg_temp_new_i32();
2696 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2700 static void gen_vfp_msr(TCGv_i32 tmp
)
2702 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2703 tcg_temp_free_i32(tmp
);
2706 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2708 TCGv_i32 tmp
= tcg_temp_new_i32();
2710 tcg_gen_shri_i32(var
, var
, shift
);
2711 tcg_gen_ext8u_i32(var
, var
);
2712 tcg_gen_shli_i32(tmp
, var
, 8);
2713 tcg_gen_or_i32(var
, var
, tmp
);
2714 tcg_gen_shli_i32(tmp
, var
, 16);
2715 tcg_gen_or_i32(var
, var
, tmp
);
2716 tcg_temp_free_i32(tmp
);
2719 static void gen_neon_dup_low16(TCGv_i32 var
)
2721 TCGv_i32 tmp
= tcg_temp_new_i32();
2722 tcg_gen_ext16u_i32(var
, var
);
2723 tcg_gen_shli_i32(tmp
, var
, 16);
2724 tcg_gen_or_i32(var
, var
, tmp
);
2725 tcg_temp_free_i32(tmp
);
2728 static void gen_neon_dup_high16(TCGv_i32 var
)
2730 TCGv_i32 tmp
= tcg_temp_new_i32();
2731 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2732 tcg_gen_shri_i32(tmp
, var
, 16);
2733 tcg_gen_or_i32(var
, var
, tmp
);
2734 tcg_temp_free_i32(tmp
);
2737 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2739 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2740 TCGv_i32 tmp
= tcg_temp_new_i32();
2743 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
2744 gen_neon_dup_u8(tmp
, 0);
2747 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
2748 gen_neon_dup_low16(tmp
);
2751 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
2753 default: /* Avoid compiler warnings. */
2759 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2762 uint32_t cc
= extract32(insn
, 20, 2);
2765 TCGv_i64 frn
, frm
, dest
;
2766 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2768 zero
= tcg_const_i64(0);
2770 frn
= tcg_temp_new_i64();
2771 frm
= tcg_temp_new_i64();
2772 dest
= tcg_temp_new_i64();
2774 zf
= tcg_temp_new_i64();
2775 nf
= tcg_temp_new_i64();
2776 vf
= tcg_temp_new_i64();
2778 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2779 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2780 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2782 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2783 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2786 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2790 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2793 case 2: /* ge: N == V -> N ^ V == 0 */
2794 tmp
= tcg_temp_new_i64();
2795 tcg_gen_xor_i64(tmp
, vf
, nf
);
2796 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2798 tcg_temp_free_i64(tmp
);
2800 case 3: /* gt: !Z && N == V */
2801 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2803 tmp
= tcg_temp_new_i64();
2804 tcg_gen_xor_i64(tmp
, vf
, nf
);
2805 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2807 tcg_temp_free_i64(tmp
);
2810 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2811 tcg_temp_free_i64(frn
);
2812 tcg_temp_free_i64(frm
);
2813 tcg_temp_free_i64(dest
);
2815 tcg_temp_free_i64(zf
);
2816 tcg_temp_free_i64(nf
);
2817 tcg_temp_free_i64(vf
);
2819 tcg_temp_free_i64(zero
);
2821 TCGv_i32 frn
, frm
, dest
;
2824 zero
= tcg_const_i32(0);
2826 frn
= tcg_temp_new_i32();
2827 frm
= tcg_temp_new_i32();
2828 dest
= tcg_temp_new_i32();
2829 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2830 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2833 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2837 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2840 case 2: /* ge: N == V -> N ^ V == 0 */
2841 tmp
= tcg_temp_new_i32();
2842 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2843 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2845 tcg_temp_free_i32(tmp
);
2847 case 3: /* gt: !Z && N == V */
2848 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2850 tmp
= tcg_temp_new_i32();
2851 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2852 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2854 tcg_temp_free_i32(tmp
);
2857 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2858 tcg_temp_free_i32(frn
);
2859 tcg_temp_free_i32(frm
);
2860 tcg_temp_free_i32(dest
);
2862 tcg_temp_free_i32(zero
);
2868 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2869 uint32_t rm
, uint32_t dp
)
2871 uint32_t vmin
= extract32(insn
, 6, 1);
2872 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2875 TCGv_i64 frn
, frm
, dest
;
2877 frn
= tcg_temp_new_i64();
2878 frm
= tcg_temp_new_i64();
2879 dest
= tcg_temp_new_i64();
2881 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2882 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2884 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2886 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2888 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2889 tcg_temp_free_i64(frn
);
2890 tcg_temp_free_i64(frm
);
2891 tcg_temp_free_i64(dest
);
2893 TCGv_i32 frn
, frm
, dest
;
2895 frn
= tcg_temp_new_i32();
2896 frm
= tcg_temp_new_i32();
2897 dest
= tcg_temp_new_i32();
2899 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2900 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2902 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2904 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2906 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2907 tcg_temp_free_i32(frn
);
2908 tcg_temp_free_i32(frm
);
2909 tcg_temp_free_i32(dest
);
2912 tcg_temp_free_ptr(fpst
);
2916 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2919 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2922 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2923 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2928 tcg_op
= tcg_temp_new_i64();
2929 tcg_res
= tcg_temp_new_i64();
2930 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2931 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2932 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2933 tcg_temp_free_i64(tcg_op
);
2934 tcg_temp_free_i64(tcg_res
);
2938 tcg_op
= tcg_temp_new_i32();
2939 tcg_res
= tcg_temp_new_i32();
2940 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2941 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2942 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2943 tcg_temp_free_i32(tcg_op
);
2944 tcg_temp_free_i32(tcg_res
);
2947 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2948 tcg_temp_free_i32(tcg_rmode
);
2950 tcg_temp_free_ptr(fpst
);
2954 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2957 bool is_signed
= extract32(insn
, 7, 1);
2958 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2959 TCGv_i32 tcg_rmode
, tcg_shift
;
2961 tcg_shift
= tcg_const_i32(0);
2963 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2964 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2967 TCGv_i64 tcg_double
, tcg_res
;
2969 /* Rd is encoded as a single precision register even when the source
2970 * is double precision.
2972 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2973 tcg_double
= tcg_temp_new_i64();
2974 tcg_res
= tcg_temp_new_i64();
2975 tcg_tmp
= tcg_temp_new_i32();
2976 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2978 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2980 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2982 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
2983 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2984 tcg_temp_free_i32(tcg_tmp
);
2985 tcg_temp_free_i64(tcg_res
);
2986 tcg_temp_free_i64(tcg_double
);
2988 TCGv_i32 tcg_single
, tcg_res
;
2989 tcg_single
= tcg_temp_new_i32();
2990 tcg_res
= tcg_temp_new_i32();
2991 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2993 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2995 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2997 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
2998 tcg_temp_free_i32(tcg_res
);
2999 tcg_temp_free_i32(tcg_single
);
3002 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3003 tcg_temp_free_i32(tcg_rmode
);
3005 tcg_temp_free_i32(tcg_shift
);
3007 tcg_temp_free_ptr(fpst
);
3012 /* Table for converting the most common AArch32 encoding of
3013 * rounding mode to arm_fprounding order (which matches the
3014 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3016 static const uint8_t fp_decode_rm
[] = {
3023 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3025 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3027 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3032 VFP_DREG_D(rd
, insn
);
3033 VFP_DREG_N(rn
, insn
);
3034 VFP_DREG_M(rm
, insn
);
3036 rd
= VFP_SREG_D(insn
);
3037 rn
= VFP_SREG_N(insn
);
3038 rm
= VFP_SREG_M(insn
);
3041 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3042 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3043 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3044 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3045 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3046 /* VRINTA, VRINTN, VRINTP, VRINTM */
3047 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3048 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3049 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3050 /* VCVTA, VCVTN, VCVTP, VCVTM */
3051 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3052 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3057 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3058 (ie. an undefined instruction). */
3059 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3061 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3067 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3071 /* FIXME: this access check should not take precedence over UNDEF
3072 * for invalid encodings; we will generate incorrect syndrome information
3073 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3075 if (s
->fp_excp_el
) {
3076 gen_exception_insn(s
, 4, EXCP_UDEF
,
3077 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
3081 if (!s
->vfp_enabled
) {
3082 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3083 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3085 rn
= (insn
>> 16) & 0xf;
3086 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3087 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3092 if (extract32(insn
, 28, 4) == 0xf) {
3093 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3094 * only used in v8 and above.
3096 return disas_vfp_v8_insn(s
, insn
);
3099 dp
= ((insn
& 0xf00) == 0xb00);
3100 switch ((insn
>> 24) & 0xf) {
3102 if (insn
& (1 << 4)) {
3103 /* single register transfer */
3104 rd
= (insn
>> 12) & 0xf;
3109 VFP_DREG_N(rn
, insn
);
3112 if (insn
& 0x00c00060
3113 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3117 pass
= (insn
>> 21) & 1;
3118 if (insn
& (1 << 22)) {
3120 offset
= ((insn
>> 5) & 3) * 8;
3121 } else if (insn
& (1 << 5)) {
3123 offset
= (insn
& (1 << 6)) ? 16 : 0;
3128 if (insn
& ARM_CP_RW_BIT
) {
3130 tmp
= neon_load_reg(rn
, pass
);
3134 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3135 if (insn
& (1 << 23))
3141 if (insn
& (1 << 23)) {
3143 tcg_gen_shri_i32(tmp
, tmp
, 16);
3149 tcg_gen_sari_i32(tmp
, tmp
, 16);
3158 store_reg(s
, rd
, tmp
);
3161 tmp
= load_reg(s
, rd
);
3162 if (insn
& (1 << 23)) {
3165 gen_neon_dup_u8(tmp
, 0);
3166 } else if (size
== 1) {
3167 gen_neon_dup_low16(tmp
);
3169 for (n
= 0; n
<= pass
* 2; n
++) {
3170 tmp2
= tcg_temp_new_i32();
3171 tcg_gen_mov_i32(tmp2
, tmp
);
3172 neon_store_reg(rn
, n
, tmp2
);
3174 neon_store_reg(rn
, n
, tmp
);
3179 tmp2
= neon_load_reg(rn
, pass
);
3180 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3181 tcg_temp_free_i32(tmp2
);
3184 tmp2
= neon_load_reg(rn
, pass
);
3185 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3186 tcg_temp_free_i32(tmp2
);
3191 neon_store_reg(rn
, pass
, tmp
);
3195 if ((insn
& 0x6f) != 0x00)
3197 rn
= VFP_SREG_N(insn
);
3198 if (insn
& ARM_CP_RW_BIT
) {
3200 if (insn
& (1 << 21)) {
3201 /* system register */
3206 /* VFP2 allows access to FSID from userspace.
3207 VFP3 restricts all id registers to privileged
3210 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3213 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3218 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3220 case ARM_VFP_FPINST
:
3221 case ARM_VFP_FPINST2
:
3222 /* Not present in VFP3. */
3224 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3227 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3231 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3232 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3234 tmp
= tcg_temp_new_i32();
3235 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3239 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3246 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3249 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3255 gen_mov_F0_vreg(0, rn
);
3256 tmp
= gen_vfp_mrs();
3259 /* Set the 4 flag bits in the CPSR. */
3261 tcg_temp_free_i32(tmp
);
3263 store_reg(s
, rd
, tmp
);
3267 if (insn
& (1 << 21)) {
3269 /* system register */
3274 /* Writes are ignored. */
3277 tmp
= load_reg(s
, rd
);
3278 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3279 tcg_temp_free_i32(tmp
);
3285 /* TODO: VFP subarchitecture support.
3286 * For now, keep the EN bit only */
3287 tmp
= load_reg(s
, rd
);
3288 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3289 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3292 case ARM_VFP_FPINST
:
3293 case ARM_VFP_FPINST2
:
3297 tmp
= load_reg(s
, rd
);
3298 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3304 tmp
= load_reg(s
, rd
);
3306 gen_mov_vreg_F0(0, rn
);
3311 /* data processing */
3312 /* The opcode is in bits 23, 21, 20 and 6. */
3313 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3317 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3319 /* rn is register number */
3320 VFP_DREG_N(rn
, insn
);
3323 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3324 ((rn
& 0x1e) == 0x6))) {
3325 /* Integer or single/half precision destination. */
3326 rd
= VFP_SREG_D(insn
);
3328 VFP_DREG_D(rd
, insn
);
3331 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3332 ((rn
& 0x1e) == 0x4))) {
3333 /* VCVT from int or half precision is always from S reg
3334 * regardless of dp bit. VCVT with immediate frac_bits
3335 * has same format as SREG_M.
3337 rm
= VFP_SREG_M(insn
);
3339 VFP_DREG_M(rm
, insn
);
3342 rn
= VFP_SREG_N(insn
);
3343 if (op
== 15 && rn
== 15) {
3344 /* Double precision destination. */
3345 VFP_DREG_D(rd
, insn
);
3347 rd
= VFP_SREG_D(insn
);
3349 /* NB that we implicitly rely on the encoding for the frac_bits
3350 * in VCVT of fixed to float being the same as that of an SREG_M
3352 rm
= VFP_SREG_M(insn
);
3355 veclen
= s
->vec_len
;
3356 if (op
== 15 && rn
> 3)
3359 /* Shut up compiler warnings. */
3370 /* Figure out what type of vector operation this is. */
3371 if ((rd
& bank_mask
) == 0) {
3376 delta_d
= (s
->vec_stride
>> 1) + 1;
3378 delta_d
= s
->vec_stride
+ 1;
3380 if ((rm
& bank_mask
) == 0) {
3381 /* mixed scalar/vector */
3390 /* Load the initial operands. */
3395 /* Integer source */
3396 gen_mov_F0_vreg(0, rm
);
3401 gen_mov_F0_vreg(dp
, rd
);
3402 gen_mov_F1_vreg(dp
, rm
);
3406 /* Compare with zero */
3407 gen_mov_F0_vreg(dp
, rd
);
3418 /* Source and destination the same. */
3419 gen_mov_F0_vreg(dp
, rd
);
3425 /* VCVTB, VCVTT: only present with the halfprec extension
3426 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3427 * (we choose to UNDEF)
3429 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3430 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3433 if (!extract32(rn
, 1, 1)) {
3434 /* Half precision source. */
3435 gen_mov_F0_vreg(0, rm
);
3438 /* Otherwise fall through */
3440 /* One source operand. */
3441 gen_mov_F0_vreg(dp
, rm
);
3445 /* Two source operands. */
3446 gen_mov_F0_vreg(dp
, rn
);
3447 gen_mov_F1_vreg(dp
, rm
);
3451 /* Perform the calculation. */
3453 case 0: /* VMLA: fd + (fn * fm) */
3454 /* Note that order of inputs to the add matters for NaNs */
3456 gen_mov_F0_vreg(dp
, rd
);
3459 case 1: /* VMLS: fd + -(fn * fm) */
3462 gen_mov_F0_vreg(dp
, rd
);
3465 case 2: /* VNMLS: -fd + (fn * fm) */
3466 /* Note that it isn't valid to replace (-A + B) with (B - A)
3467 * or similar plausible looking simplifications
3468 * because this will give wrong results for NaNs.
3471 gen_mov_F0_vreg(dp
, rd
);
3475 case 3: /* VNMLA: -fd + -(fn * fm) */
3478 gen_mov_F0_vreg(dp
, rd
);
3482 case 4: /* mul: fn * fm */
3485 case 5: /* nmul: -(fn * fm) */
3489 case 6: /* add: fn + fm */
3492 case 7: /* sub: fn - fm */
3495 case 8: /* div: fn / fm */
3498 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3499 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3500 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3501 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3502 /* These are fused multiply-add, and must be done as one
3503 * floating point operation with no rounding between the
3504 * multiplication and addition steps.
3505 * NB that doing the negations here as separate steps is
3506 * correct : an input NaN should come out with its sign bit
3507 * flipped if it is a negated-input.
3509 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3517 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3519 frd
= tcg_temp_new_i64();
3520 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3523 gen_helper_vfp_negd(frd
, frd
);
3525 fpst
= get_fpstatus_ptr(0);
3526 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3527 cpu_F1d
, frd
, fpst
);
3528 tcg_temp_free_ptr(fpst
);
3529 tcg_temp_free_i64(frd
);
3535 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3537 frd
= tcg_temp_new_i32();
3538 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3540 gen_helper_vfp_negs(frd
, frd
);
3542 fpst
= get_fpstatus_ptr(0);
3543 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3544 cpu_F1s
, frd
, fpst
);
3545 tcg_temp_free_ptr(fpst
);
3546 tcg_temp_free_i32(frd
);
3549 case 14: /* fconst */
3550 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3554 n
= (insn
<< 12) & 0x80000000;
3555 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3562 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3569 tcg_gen_movi_i32(cpu_F0s
, n
);
3572 case 15: /* extension space */
3586 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3587 tmp
= gen_vfp_mrs();
3588 tcg_gen_ext16u_i32(tmp
, tmp
);
3590 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3593 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3596 tcg_temp_free_i32(tmp
);
3598 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3599 tmp
= gen_vfp_mrs();
3600 tcg_gen_shri_i32(tmp
, tmp
, 16);
3602 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3605 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3608 tcg_temp_free_i32(tmp
);
3610 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3611 tmp
= tcg_temp_new_i32();
3613 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3616 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3619 gen_mov_F0_vreg(0, rd
);
3620 tmp2
= gen_vfp_mrs();
3621 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3622 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3623 tcg_temp_free_i32(tmp2
);
3626 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3627 tmp
= tcg_temp_new_i32();
3629 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3632 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3635 tcg_gen_shli_i32(tmp
, tmp
, 16);
3636 gen_mov_F0_vreg(0, rd
);
3637 tmp2
= gen_vfp_mrs();
3638 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3639 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3640 tcg_temp_free_i32(tmp2
);
3652 case 11: /* cmpez */
3656 case 12: /* vrintr */
3658 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3660 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3662 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3664 tcg_temp_free_ptr(fpst
);
3667 case 13: /* vrintz */
3669 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3671 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3672 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3674 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3676 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3678 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3679 tcg_temp_free_i32(tcg_rmode
);
3680 tcg_temp_free_ptr(fpst
);
3683 case 14: /* vrintx */
3685 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3687 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3689 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3691 tcg_temp_free_ptr(fpst
);
3694 case 15: /* single<->double conversion */
3696 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3698 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3700 case 16: /* fuito */
3701 gen_vfp_uito(dp
, 0);
3703 case 17: /* fsito */
3704 gen_vfp_sito(dp
, 0);
3706 case 20: /* fshto */
3707 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3710 gen_vfp_shto(dp
, 16 - rm
, 0);
3712 case 21: /* fslto */
3713 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3716 gen_vfp_slto(dp
, 32 - rm
, 0);
3718 case 22: /* fuhto */
3719 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3722 gen_vfp_uhto(dp
, 16 - rm
, 0);
3724 case 23: /* fulto */
3725 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3728 gen_vfp_ulto(dp
, 32 - rm
, 0);
3730 case 24: /* ftoui */
3731 gen_vfp_toui(dp
, 0);
3733 case 25: /* ftouiz */
3734 gen_vfp_touiz(dp
, 0);
3736 case 26: /* ftosi */
3737 gen_vfp_tosi(dp
, 0);
3739 case 27: /* ftosiz */
3740 gen_vfp_tosiz(dp
, 0);
3742 case 28: /* ftosh */
3743 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3746 gen_vfp_tosh(dp
, 16 - rm
, 0);
3748 case 29: /* ftosl */
3749 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3752 gen_vfp_tosl(dp
, 32 - rm
, 0);
3754 case 30: /* ftouh */
3755 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3758 gen_vfp_touh(dp
, 16 - rm
, 0);
3760 case 31: /* ftoul */
3761 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3764 gen_vfp_toul(dp
, 32 - rm
, 0);
3766 default: /* undefined */
3770 default: /* undefined */
3774 /* Write back the result. */
3775 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3776 /* Comparison, do nothing. */
3777 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3778 (rn
& 0x1e) == 0x6)) {
3779 /* VCVT double to int: always integer result.
3780 * VCVT double to half precision is always a single
3783 gen_mov_vreg_F0(0, rd
);
3784 } else if (op
== 15 && rn
== 15) {
3786 gen_mov_vreg_F0(!dp
, rd
);
3788 gen_mov_vreg_F0(dp
, rd
);
3791 /* break out of the loop if we have finished */
3795 if (op
== 15 && delta_m
== 0) {
3796 /* single source one-many */
3798 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3800 gen_mov_vreg_F0(dp
, rd
);
3804 /* Setup the next operands. */
3806 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3810 /* One source operand. */
3811 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3813 gen_mov_F0_vreg(dp
, rm
);
3815 /* Two source operands. */
3816 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3818 gen_mov_F0_vreg(dp
, rn
);
3820 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3822 gen_mov_F1_vreg(dp
, rm
);
3830 if ((insn
& 0x03e00000) == 0x00400000) {
3831 /* two-register transfer */
3832 rn
= (insn
>> 16) & 0xf;
3833 rd
= (insn
>> 12) & 0xf;
3835 VFP_DREG_M(rm
, insn
);
3837 rm
= VFP_SREG_M(insn
);
3840 if (insn
& ARM_CP_RW_BIT
) {
3843 gen_mov_F0_vreg(0, rm
* 2);
3844 tmp
= gen_vfp_mrs();
3845 store_reg(s
, rd
, tmp
);
3846 gen_mov_F0_vreg(0, rm
* 2 + 1);
3847 tmp
= gen_vfp_mrs();
3848 store_reg(s
, rn
, tmp
);
3850 gen_mov_F0_vreg(0, rm
);
3851 tmp
= gen_vfp_mrs();
3852 store_reg(s
, rd
, tmp
);
3853 gen_mov_F0_vreg(0, rm
+ 1);
3854 tmp
= gen_vfp_mrs();
3855 store_reg(s
, rn
, tmp
);
3860 tmp
= load_reg(s
, rd
);
3862 gen_mov_vreg_F0(0, rm
* 2);
3863 tmp
= load_reg(s
, rn
);
3865 gen_mov_vreg_F0(0, rm
* 2 + 1);
3867 tmp
= load_reg(s
, rd
);
3869 gen_mov_vreg_F0(0, rm
);
3870 tmp
= load_reg(s
, rn
);
3872 gen_mov_vreg_F0(0, rm
+ 1);
3877 rn
= (insn
>> 16) & 0xf;
3879 VFP_DREG_D(rd
, insn
);
3881 rd
= VFP_SREG_D(insn
);
3882 if ((insn
& 0x01200000) == 0x01000000) {
3883 /* Single load/store */
3884 offset
= (insn
& 0xff) << 2;
3885 if ((insn
& (1 << 23)) == 0)
3887 if (s
->thumb
&& rn
== 15) {
3888 /* This is actually UNPREDICTABLE */
3889 addr
= tcg_temp_new_i32();
3890 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3892 addr
= load_reg(s
, rn
);
3894 tcg_gen_addi_i32(addr
, addr
, offset
);
3895 if (insn
& (1 << 20)) {
3896 gen_vfp_ld(s
, dp
, addr
);
3897 gen_mov_vreg_F0(dp
, rd
);
3899 gen_mov_F0_vreg(dp
, rd
);
3900 gen_vfp_st(s
, dp
, addr
);
3902 tcg_temp_free_i32(addr
);
3904 /* load/store multiple */
3905 int w
= insn
& (1 << 21);
3907 n
= (insn
>> 1) & 0x7f;
3911 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3912 /* P == U , W == 1 => UNDEF */
3915 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3916 /* UNPREDICTABLE cases for bad immediates: we choose to
3917 * UNDEF to avoid generating huge numbers of TCG ops
3921 if (rn
== 15 && w
) {
3922 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3926 if (s
->thumb
&& rn
== 15) {
3927 /* This is actually UNPREDICTABLE */
3928 addr
= tcg_temp_new_i32();
3929 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3931 addr
= load_reg(s
, rn
);
3933 if (insn
& (1 << 24)) /* pre-decrement */
3934 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3940 for (i
= 0; i
< n
; i
++) {
3941 if (insn
& ARM_CP_RW_BIT
) {
3943 gen_vfp_ld(s
, dp
, addr
);
3944 gen_mov_vreg_F0(dp
, rd
+ i
);
3947 gen_mov_F0_vreg(dp
, rd
+ i
);
3948 gen_vfp_st(s
, dp
, addr
);
3950 tcg_gen_addi_i32(addr
, addr
, offset
);
3954 if (insn
& (1 << 24))
3955 offset
= -offset
* n
;
3956 else if (dp
&& (insn
& 1))
3962 tcg_gen_addi_i32(addr
, addr
, offset
);
3963 store_reg(s
, rn
, addr
);
3965 tcg_temp_free_i32(addr
);
3971 /* Should never happen. */
3977 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3979 TranslationBlock
*tb
;
3982 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3984 gen_set_pc_im(s
, dest
);
3985 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3987 gen_set_pc_im(s
, dest
);
3992 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3994 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
3995 /* An indirect jump so that we still trigger the debug exception. */
4000 gen_goto_tb(s
, 0, dest
);
4001 s
->is_jmp
= DISAS_TB_JUMP
;
4005 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4008 tcg_gen_sari_i32(t0
, t0
, 16);
4012 tcg_gen_sari_i32(t1
, t1
, 16);
4015 tcg_gen_mul_i32(t0
, t0
, t1
);
4018 /* Return the mask of PSR bits set by a MSR instruction. */
4019 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4024 if (flags
& (1 << 0))
4026 if (flags
& (1 << 1))
4028 if (flags
& (1 << 2))
4030 if (flags
& (1 << 3))
4033 /* Mask out undefined bits. */
4034 mask
&= ~CPSR_RESERVED
;
4035 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4038 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4039 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4041 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4042 mask
&= ~(CPSR_E
| CPSR_GE
);
4044 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4047 /* Mask out execution state and reserved bits. */
4049 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4051 /* Mask out privileged bits. */
4057 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4058 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4062 /* ??? This is also undefined in system mode. */
4066 tmp
= load_cpu_field(spsr
);
4067 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4068 tcg_gen_andi_i32(t0
, t0
, mask
);
4069 tcg_gen_or_i32(tmp
, tmp
, t0
);
4070 store_cpu_field(tmp
, spsr
);
4072 gen_set_cpsr(t0
, mask
);
4074 tcg_temp_free_i32(t0
);
4079 /* Returns nonzero if access to the PSR is not permitted. */
4080 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4083 tmp
= tcg_temp_new_i32();
4084 tcg_gen_movi_i32(tmp
, val
);
4085 return gen_set_psr(s
, mask
, spsr
, tmp
);
4088 /* Generate an old-style exception return. Marks pc as dead. */
4089 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4092 store_reg(s
, 15, pc
);
4093 tmp
= load_cpu_field(spsr
);
4094 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
4095 tcg_temp_free_i32(tmp
);
4096 s
->is_jmp
= DISAS_UPDATE
;
4099 /* Generate a v6 exception return. Marks both values as dead. */
4100 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4102 gen_set_cpsr(cpsr
, CPSR_ERET_MASK
);
4103 tcg_temp_free_i32(cpsr
);
4104 store_reg(s
, 15, pc
);
4105 s
->is_jmp
= DISAS_UPDATE
;
4108 static void gen_nop_hint(DisasContext
*s
, int val
)
4112 gen_set_pc_im(s
, s
->pc
);
4113 s
->is_jmp
= DISAS_YIELD
;
4116 gen_set_pc_im(s
, s
->pc
);
4117 s
->is_jmp
= DISAS_WFI
;
4120 gen_set_pc_im(s
, s
->pc
);
4121 s
->is_jmp
= DISAS_WFE
;
4125 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4131 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4133 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4136 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4137 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4138 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4143 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4146 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4147 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4148 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4153 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4154 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4155 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4156 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4157 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4159 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4160 switch ((size << 1) | u) { \
4162 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4165 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4168 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4171 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4174 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4177 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4179 default: return 1; \
4182 #define GEN_NEON_INTEGER_OP(name) do { \
4183 switch ((size << 1) | u) { \
4185 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4188 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4191 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4194 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4197 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4200 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4202 default: return 1; \
4205 static TCGv_i32
neon_load_scratch(int scratch
)
4207 TCGv_i32 tmp
= tcg_temp_new_i32();
4208 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4212 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4214 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4215 tcg_temp_free_i32(var
);
4218 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4222 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4224 gen_neon_dup_high16(tmp
);
4226 gen_neon_dup_low16(tmp
);
4229 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4234 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4237 if (!q
&& size
== 2) {
4240 tmp
= tcg_const_i32(rd
);
4241 tmp2
= tcg_const_i32(rm
);
4245 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4248 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4251 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4259 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4262 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4268 tcg_temp_free_i32(tmp
);
4269 tcg_temp_free_i32(tmp2
);
4273 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4276 if (!q
&& size
== 2) {
4279 tmp
= tcg_const_i32(rd
);
4280 tmp2
= tcg_const_i32(rm
);
4284 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4287 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4290 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4298 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4301 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4307 tcg_temp_free_i32(tmp
);
4308 tcg_temp_free_i32(tmp2
);
4312 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4316 rd
= tcg_temp_new_i32();
4317 tmp
= tcg_temp_new_i32();
4319 tcg_gen_shli_i32(rd
, t0
, 8);
4320 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4321 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4322 tcg_gen_or_i32(rd
, rd
, tmp
);
4324 tcg_gen_shri_i32(t1
, t1
, 8);
4325 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4326 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4327 tcg_gen_or_i32(t1
, t1
, tmp
);
4328 tcg_gen_mov_i32(t0
, rd
);
4330 tcg_temp_free_i32(tmp
);
4331 tcg_temp_free_i32(rd
);
4334 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4338 rd
= tcg_temp_new_i32();
4339 tmp
= tcg_temp_new_i32();
4341 tcg_gen_shli_i32(rd
, t0
, 16);
4342 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4343 tcg_gen_or_i32(rd
, rd
, tmp
);
4344 tcg_gen_shri_i32(t1
, t1
, 16);
4345 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4346 tcg_gen_or_i32(t1
, t1
, tmp
);
4347 tcg_gen_mov_i32(t0
, rd
);
4349 tcg_temp_free_i32(tmp
);
4350 tcg_temp_free_i32(rd
);
4358 } neon_ls_element_type
[11] = {
4372 /* Translate a NEON load/store element instruction. Return nonzero if the
4373 instruction is invalid. */
4374 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4393 /* FIXME: this access check should not take precedence over UNDEF
4394 * for invalid encodings; we will generate incorrect syndrome information
4395 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4397 if (s
->fp_excp_el
) {
4398 gen_exception_insn(s
, 4, EXCP_UDEF
,
4399 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
4403 if (!s
->vfp_enabled
)
4405 VFP_DREG_D(rd
, insn
);
4406 rn
= (insn
>> 16) & 0xf;
4408 load
= (insn
& (1 << 21)) != 0;
4409 if ((insn
& (1 << 23)) == 0) {
4410 /* Load store all elements. */
4411 op
= (insn
>> 8) & 0xf;
4412 size
= (insn
>> 6) & 3;
4415 /* Catch UNDEF cases for bad values of align field */
4418 if (((insn
>> 5) & 1) == 1) {
4423 if (((insn
>> 4) & 3) == 3) {
4430 nregs
= neon_ls_element_type
[op
].nregs
;
4431 interleave
= neon_ls_element_type
[op
].interleave
;
4432 spacing
= neon_ls_element_type
[op
].spacing
;
4433 if (size
== 3 && (interleave
| spacing
) != 1)
4435 addr
= tcg_temp_new_i32();
4436 load_reg_var(s
, addr
, rn
);
4437 stride
= (1 << size
) * interleave
;
4438 for (reg
= 0; reg
< nregs
; reg
++) {
4439 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4440 load_reg_var(s
, addr
, rn
);
4441 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4442 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4443 load_reg_var(s
, addr
, rn
);
4444 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4447 tmp64
= tcg_temp_new_i64();
4449 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4450 neon_store_reg64(tmp64
, rd
);
4452 neon_load_reg64(tmp64
, rd
);
4453 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4455 tcg_temp_free_i64(tmp64
);
4456 tcg_gen_addi_i32(addr
, addr
, stride
);
4458 for (pass
= 0; pass
< 2; pass
++) {
4461 tmp
= tcg_temp_new_i32();
4462 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4463 neon_store_reg(rd
, pass
, tmp
);
4465 tmp
= neon_load_reg(rd
, pass
);
4466 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4467 tcg_temp_free_i32(tmp
);
4469 tcg_gen_addi_i32(addr
, addr
, stride
);
4470 } else if (size
== 1) {
4472 tmp
= tcg_temp_new_i32();
4473 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4474 tcg_gen_addi_i32(addr
, addr
, stride
);
4475 tmp2
= tcg_temp_new_i32();
4476 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4477 tcg_gen_addi_i32(addr
, addr
, stride
);
4478 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4479 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4480 tcg_temp_free_i32(tmp2
);
4481 neon_store_reg(rd
, pass
, tmp
);
4483 tmp
= neon_load_reg(rd
, pass
);
4484 tmp2
= tcg_temp_new_i32();
4485 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4486 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4487 tcg_temp_free_i32(tmp
);
4488 tcg_gen_addi_i32(addr
, addr
, stride
);
4489 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4490 tcg_temp_free_i32(tmp2
);
4491 tcg_gen_addi_i32(addr
, addr
, stride
);
4493 } else /* size == 0 */ {
4495 TCGV_UNUSED_I32(tmp2
);
4496 for (n
= 0; n
< 4; n
++) {
4497 tmp
= tcg_temp_new_i32();
4498 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4499 tcg_gen_addi_i32(addr
, addr
, stride
);
4503 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4504 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4505 tcg_temp_free_i32(tmp
);
4508 neon_store_reg(rd
, pass
, tmp2
);
4510 tmp2
= neon_load_reg(rd
, pass
);
4511 for (n
= 0; n
< 4; n
++) {
4512 tmp
= tcg_temp_new_i32();
4514 tcg_gen_mov_i32(tmp
, tmp2
);
4516 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4518 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4519 tcg_temp_free_i32(tmp
);
4520 tcg_gen_addi_i32(addr
, addr
, stride
);
4522 tcg_temp_free_i32(tmp2
);
4529 tcg_temp_free_i32(addr
);
4532 size
= (insn
>> 10) & 3;
4534 /* Load single element to all lanes. */
4535 int a
= (insn
>> 4) & 1;
4539 size
= (insn
>> 6) & 3;
4540 nregs
= ((insn
>> 8) & 3) + 1;
4543 if (nregs
!= 4 || a
== 0) {
4546 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4549 if (nregs
== 1 && a
== 1 && size
== 0) {
4552 if (nregs
== 3 && a
== 1) {
4555 addr
= tcg_temp_new_i32();
4556 load_reg_var(s
, addr
, rn
);
4558 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4559 tmp
= gen_load_and_replicate(s
, addr
, size
);
4560 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4561 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4562 if (insn
& (1 << 5)) {
4563 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4564 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4566 tcg_temp_free_i32(tmp
);
4568 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4569 stride
= (insn
& (1 << 5)) ? 2 : 1;
4570 for (reg
= 0; reg
< nregs
; reg
++) {
4571 tmp
= gen_load_and_replicate(s
, addr
, size
);
4572 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4573 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4574 tcg_temp_free_i32(tmp
);
4575 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4579 tcg_temp_free_i32(addr
);
4580 stride
= (1 << size
) * nregs
;
4582 /* Single element. */
4583 int idx
= (insn
>> 4) & 0xf;
4584 pass
= (insn
>> 7) & 1;
4587 shift
= ((insn
>> 5) & 3) * 8;
4591 shift
= ((insn
>> 6) & 1) * 16;
4592 stride
= (insn
& (1 << 5)) ? 2 : 1;
4596 stride
= (insn
& (1 << 6)) ? 2 : 1;
4601 nregs
= ((insn
>> 8) & 3) + 1;
4602 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4605 if (((idx
& (1 << size
)) != 0) ||
4606 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4611 if ((idx
& 1) != 0) {
4616 if (size
== 2 && (idx
& 2) != 0) {
4621 if ((size
== 2) && ((idx
& 3) == 3)) {
4628 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4629 /* Attempts to write off the end of the register file
4630 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4631 * the neon_load_reg() would write off the end of the array.
4635 addr
= tcg_temp_new_i32();
4636 load_reg_var(s
, addr
, rn
);
4637 for (reg
= 0; reg
< nregs
; reg
++) {
4639 tmp
= tcg_temp_new_i32();
4642 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4645 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4648 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4650 default: /* Avoid compiler warnings. */
4654 tmp2
= neon_load_reg(rd
, pass
);
4655 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4656 shift
, size
? 16 : 8);
4657 tcg_temp_free_i32(tmp2
);
4659 neon_store_reg(rd
, pass
, tmp
);
4660 } else { /* Store */
4661 tmp
= neon_load_reg(rd
, pass
);
4663 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4666 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4669 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4672 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4675 tcg_temp_free_i32(tmp
);
4678 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4680 tcg_temp_free_i32(addr
);
4681 stride
= nregs
* (1 << size
);
4687 base
= load_reg(s
, rn
);
4689 tcg_gen_addi_i32(base
, base
, stride
);
4692 index
= load_reg(s
, rm
);
4693 tcg_gen_add_i32(base
, base
, index
);
4694 tcg_temp_free_i32(index
);
4696 store_reg(s
, rn
, base
);
4701 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4702 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4704 tcg_gen_and_i32(t
, t
, c
);
4705 tcg_gen_andc_i32(f
, f
, c
);
4706 tcg_gen_or_i32(dest
, t
, f
);
4709 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4712 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4713 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4714 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4719 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4722 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4723 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4724 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4729 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4732 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4733 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4734 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4739 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4742 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4743 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4744 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4749 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4755 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4756 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4761 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4762 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4769 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4770 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4775 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4776 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4783 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4787 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4788 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4789 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4794 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4795 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4796 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4800 tcg_temp_free_i32(src
);
4803 static inline void gen_neon_addl(int size
)
4806 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4807 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4808 case 2: tcg_gen_add_i64(CPU_V001
); break;
4813 static inline void gen_neon_subl(int size
)
4816 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4817 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4818 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4823 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4826 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4827 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4829 tcg_gen_neg_i64(var
, var
);
4835 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4838 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4839 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4844 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4849 switch ((size
<< 1) | u
) {
4850 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4851 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4852 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4853 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4855 tmp
= gen_muls_i64_i32(a
, b
);
4856 tcg_gen_mov_i64(dest
, tmp
);
4857 tcg_temp_free_i64(tmp
);
4860 tmp
= gen_mulu_i64_i32(a
, b
);
4861 tcg_gen_mov_i64(dest
, tmp
);
4862 tcg_temp_free_i64(tmp
);
4867 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4868 Don't forget to clean them now. */
4870 tcg_temp_free_i32(a
);
4871 tcg_temp_free_i32(b
);
4875 static void gen_neon_narrow_op(int op
, int u
, int size
,
4876 TCGv_i32 dest
, TCGv_i64 src
)
4880 gen_neon_unarrow_sats(size
, dest
, src
);
4882 gen_neon_narrow(size
, dest
, src
);
4886 gen_neon_narrow_satu(size
, dest
, src
);
4888 gen_neon_narrow_sats(size
, dest
, src
);
4893 /* Symbolic constants for op fields for Neon 3-register same-length.
4894 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4897 #define NEON_3R_VHADD 0
4898 #define NEON_3R_VQADD 1
4899 #define NEON_3R_VRHADD 2
4900 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4901 #define NEON_3R_VHSUB 4
4902 #define NEON_3R_VQSUB 5
4903 #define NEON_3R_VCGT 6
4904 #define NEON_3R_VCGE 7
4905 #define NEON_3R_VSHL 8
4906 #define NEON_3R_VQSHL 9
4907 #define NEON_3R_VRSHL 10
4908 #define NEON_3R_VQRSHL 11
4909 #define NEON_3R_VMAX 12
4910 #define NEON_3R_VMIN 13
4911 #define NEON_3R_VABD 14
4912 #define NEON_3R_VABA 15
4913 #define NEON_3R_VADD_VSUB 16
4914 #define NEON_3R_VTST_VCEQ 17
4915 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4916 #define NEON_3R_VMUL 19
4917 #define NEON_3R_VPMAX 20
4918 #define NEON_3R_VPMIN 21
4919 #define NEON_3R_VQDMULH_VQRDMULH 22
4920 #define NEON_3R_VPADD 23
4921 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4922 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4923 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4924 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4925 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4926 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4927 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4928 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4930 static const uint8_t neon_3r_sizes
[] = {
4931 [NEON_3R_VHADD
] = 0x7,
4932 [NEON_3R_VQADD
] = 0xf,
4933 [NEON_3R_VRHADD
] = 0x7,
4934 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4935 [NEON_3R_VHSUB
] = 0x7,
4936 [NEON_3R_VQSUB
] = 0xf,
4937 [NEON_3R_VCGT
] = 0x7,
4938 [NEON_3R_VCGE
] = 0x7,
4939 [NEON_3R_VSHL
] = 0xf,
4940 [NEON_3R_VQSHL
] = 0xf,
4941 [NEON_3R_VRSHL
] = 0xf,
4942 [NEON_3R_VQRSHL
] = 0xf,
4943 [NEON_3R_VMAX
] = 0x7,
4944 [NEON_3R_VMIN
] = 0x7,
4945 [NEON_3R_VABD
] = 0x7,
4946 [NEON_3R_VABA
] = 0x7,
4947 [NEON_3R_VADD_VSUB
] = 0xf,
4948 [NEON_3R_VTST_VCEQ
] = 0x7,
4949 [NEON_3R_VML
] = 0x7,
4950 [NEON_3R_VMUL
] = 0x7,
4951 [NEON_3R_VPMAX
] = 0x7,
4952 [NEON_3R_VPMIN
] = 0x7,
4953 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4954 [NEON_3R_VPADD
] = 0x7,
4955 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4956 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4957 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4958 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4959 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4960 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4961 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4962 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4965 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4966 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4969 #define NEON_2RM_VREV64 0
4970 #define NEON_2RM_VREV32 1
4971 #define NEON_2RM_VREV16 2
4972 #define NEON_2RM_VPADDL 4
4973 #define NEON_2RM_VPADDL_U 5
4974 #define NEON_2RM_AESE 6 /* Includes AESD */
4975 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4976 #define NEON_2RM_VCLS 8
4977 #define NEON_2RM_VCLZ 9
4978 #define NEON_2RM_VCNT 10
4979 #define NEON_2RM_VMVN 11
4980 #define NEON_2RM_VPADAL 12
4981 #define NEON_2RM_VPADAL_U 13
4982 #define NEON_2RM_VQABS 14
4983 #define NEON_2RM_VQNEG 15
4984 #define NEON_2RM_VCGT0 16
4985 #define NEON_2RM_VCGE0 17
4986 #define NEON_2RM_VCEQ0 18
4987 #define NEON_2RM_VCLE0 19
4988 #define NEON_2RM_VCLT0 20
4989 #define NEON_2RM_SHA1H 21
4990 #define NEON_2RM_VABS 22
4991 #define NEON_2RM_VNEG 23
4992 #define NEON_2RM_VCGT0_F 24
4993 #define NEON_2RM_VCGE0_F 25
4994 #define NEON_2RM_VCEQ0_F 26
4995 #define NEON_2RM_VCLE0_F 27
4996 #define NEON_2RM_VCLT0_F 28
4997 #define NEON_2RM_VABS_F 30
4998 #define NEON_2RM_VNEG_F 31
4999 #define NEON_2RM_VSWP 32
5000 #define NEON_2RM_VTRN 33
5001 #define NEON_2RM_VUZP 34
5002 #define NEON_2RM_VZIP 35
5003 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5004 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5005 #define NEON_2RM_VSHLL 38
5006 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5007 #define NEON_2RM_VRINTN 40
5008 #define NEON_2RM_VRINTX 41
5009 #define NEON_2RM_VRINTA 42
5010 #define NEON_2RM_VRINTZ 43
5011 #define NEON_2RM_VCVT_F16_F32 44
5012 #define NEON_2RM_VRINTM 45
5013 #define NEON_2RM_VCVT_F32_F16 46
5014 #define NEON_2RM_VRINTP 47
5015 #define NEON_2RM_VCVTAU 48
5016 #define NEON_2RM_VCVTAS 49
5017 #define NEON_2RM_VCVTNU 50
5018 #define NEON_2RM_VCVTNS 51
5019 #define NEON_2RM_VCVTPU 52
5020 #define NEON_2RM_VCVTPS 53
5021 #define NEON_2RM_VCVTMU 54
5022 #define NEON_2RM_VCVTMS 55
5023 #define NEON_2RM_VRECPE 56
5024 #define NEON_2RM_VRSQRTE 57
5025 #define NEON_2RM_VRECPE_F 58
5026 #define NEON_2RM_VRSQRTE_F 59
5027 #define NEON_2RM_VCVT_FS 60
5028 #define NEON_2RM_VCVT_FU 61
5029 #define NEON_2RM_VCVT_SF 62
5030 #define NEON_2RM_VCVT_UF 63
5032 static int neon_2rm_is_float_op(int op
)
5034 /* Return true if this neon 2reg-misc op is float-to-float */
5035 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5036 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5037 op
== NEON_2RM_VRINTM
||
5038 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5039 op
>= NEON_2RM_VRECPE_F
);
5042 /* Each entry in this array has bit n set if the insn allows
5043 * size value n (otherwise it will UNDEF). Since unallocated
5044 * op values will have no bits set they always UNDEF.
5046 static const uint8_t neon_2rm_sizes
[] = {
5047 [NEON_2RM_VREV64
] = 0x7,
5048 [NEON_2RM_VREV32
] = 0x3,
5049 [NEON_2RM_VREV16
] = 0x1,
5050 [NEON_2RM_VPADDL
] = 0x7,
5051 [NEON_2RM_VPADDL_U
] = 0x7,
5052 [NEON_2RM_AESE
] = 0x1,
5053 [NEON_2RM_AESMC
] = 0x1,
5054 [NEON_2RM_VCLS
] = 0x7,
5055 [NEON_2RM_VCLZ
] = 0x7,
5056 [NEON_2RM_VCNT
] = 0x1,
5057 [NEON_2RM_VMVN
] = 0x1,
5058 [NEON_2RM_VPADAL
] = 0x7,
5059 [NEON_2RM_VPADAL_U
] = 0x7,
5060 [NEON_2RM_VQABS
] = 0x7,
5061 [NEON_2RM_VQNEG
] = 0x7,
5062 [NEON_2RM_VCGT0
] = 0x7,
5063 [NEON_2RM_VCGE0
] = 0x7,
5064 [NEON_2RM_VCEQ0
] = 0x7,
5065 [NEON_2RM_VCLE0
] = 0x7,
5066 [NEON_2RM_VCLT0
] = 0x7,
5067 [NEON_2RM_SHA1H
] = 0x4,
5068 [NEON_2RM_VABS
] = 0x7,
5069 [NEON_2RM_VNEG
] = 0x7,
5070 [NEON_2RM_VCGT0_F
] = 0x4,
5071 [NEON_2RM_VCGE0_F
] = 0x4,
5072 [NEON_2RM_VCEQ0_F
] = 0x4,
5073 [NEON_2RM_VCLE0_F
] = 0x4,
5074 [NEON_2RM_VCLT0_F
] = 0x4,
5075 [NEON_2RM_VABS_F
] = 0x4,
5076 [NEON_2RM_VNEG_F
] = 0x4,
5077 [NEON_2RM_VSWP
] = 0x1,
5078 [NEON_2RM_VTRN
] = 0x7,
5079 [NEON_2RM_VUZP
] = 0x7,
5080 [NEON_2RM_VZIP
] = 0x7,
5081 [NEON_2RM_VMOVN
] = 0x7,
5082 [NEON_2RM_VQMOVN
] = 0x7,
5083 [NEON_2RM_VSHLL
] = 0x7,
5084 [NEON_2RM_SHA1SU1
] = 0x4,
5085 [NEON_2RM_VRINTN
] = 0x4,
5086 [NEON_2RM_VRINTX
] = 0x4,
5087 [NEON_2RM_VRINTA
] = 0x4,
5088 [NEON_2RM_VRINTZ
] = 0x4,
5089 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5090 [NEON_2RM_VRINTM
] = 0x4,
5091 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5092 [NEON_2RM_VRINTP
] = 0x4,
5093 [NEON_2RM_VCVTAU
] = 0x4,
5094 [NEON_2RM_VCVTAS
] = 0x4,
5095 [NEON_2RM_VCVTNU
] = 0x4,
5096 [NEON_2RM_VCVTNS
] = 0x4,
5097 [NEON_2RM_VCVTPU
] = 0x4,
5098 [NEON_2RM_VCVTPS
] = 0x4,
5099 [NEON_2RM_VCVTMU
] = 0x4,
5100 [NEON_2RM_VCVTMS
] = 0x4,
5101 [NEON_2RM_VRECPE
] = 0x4,
5102 [NEON_2RM_VRSQRTE
] = 0x4,
5103 [NEON_2RM_VRECPE_F
] = 0x4,
5104 [NEON_2RM_VRSQRTE_F
] = 0x4,
5105 [NEON_2RM_VCVT_FS
] = 0x4,
5106 [NEON_2RM_VCVT_FU
] = 0x4,
5107 [NEON_2RM_VCVT_SF
] = 0x4,
5108 [NEON_2RM_VCVT_UF
] = 0x4,
5111 /* Translate a NEON data processing instruction. Return nonzero if the
5112 instruction is invalid.
5113 We process data in a mixture of 32-bit and 64-bit chunks.
5114 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5116 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5128 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5131 /* FIXME: this access check should not take precedence over UNDEF
5132 * for invalid encodings; we will generate incorrect syndrome information
5133 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5135 if (s
->fp_excp_el
) {
5136 gen_exception_insn(s
, 4, EXCP_UDEF
,
5137 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
5141 if (!s
->vfp_enabled
)
5143 q
= (insn
& (1 << 6)) != 0;
5144 u
= (insn
>> 24) & 1;
5145 VFP_DREG_D(rd
, insn
);
5146 VFP_DREG_N(rn
, insn
);
5147 VFP_DREG_M(rm
, insn
);
5148 size
= (insn
>> 20) & 3;
5149 if ((insn
& (1 << 23)) == 0) {
5150 /* Three register same length. */
5151 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5152 /* Catch invalid op and bad size combinations: UNDEF */
5153 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5156 /* All insns of this form UNDEF for either this condition or the
5157 * superset of cases "Q==1"; we catch the latter later.
5159 if (q
&& ((rd
| rn
| rm
) & 1)) {
5163 * The SHA-1/SHA-256 3-register instructions require special treatment
5164 * here, as their size field is overloaded as an op type selector, and
5165 * they all consume their input in a single pass.
5167 if (op
== NEON_3R_SHA
) {
5171 if (!u
) { /* SHA-1 */
5172 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5175 tmp
= tcg_const_i32(rd
);
5176 tmp2
= tcg_const_i32(rn
);
5177 tmp3
= tcg_const_i32(rm
);
5178 tmp4
= tcg_const_i32(size
);
5179 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5180 tcg_temp_free_i32(tmp4
);
5181 } else { /* SHA-256 */
5182 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5185 tmp
= tcg_const_i32(rd
);
5186 tmp2
= tcg_const_i32(rn
);
5187 tmp3
= tcg_const_i32(rm
);
5190 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5193 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5196 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5200 tcg_temp_free_i32(tmp
);
5201 tcg_temp_free_i32(tmp2
);
5202 tcg_temp_free_i32(tmp3
);
5205 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5206 /* 64-bit element instructions. */
5207 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5208 neon_load_reg64(cpu_V0
, rn
+ pass
);
5209 neon_load_reg64(cpu_V1
, rm
+ pass
);
5213 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5216 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5222 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5225 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5231 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5233 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5238 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5241 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5247 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5249 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5252 case NEON_3R_VQRSHL
:
5254 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5257 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5261 case NEON_3R_VADD_VSUB
:
5263 tcg_gen_sub_i64(CPU_V001
);
5265 tcg_gen_add_i64(CPU_V001
);
5271 neon_store_reg64(cpu_V0
, rd
+ pass
);
5280 case NEON_3R_VQRSHL
:
5283 /* Shift instruction operands are reversed. */
5298 case NEON_3R_FLOAT_ARITH
:
5299 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5301 case NEON_3R_FLOAT_MINMAX
:
5302 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5304 case NEON_3R_FLOAT_CMP
:
5306 /* no encoding for U=0 C=1x */
5310 case NEON_3R_FLOAT_ACMP
:
5315 case NEON_3R_FLOAT_MISC
:
5316 /* VMAXNM/VMINNM in ARMv8 */
5317 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5322 if (u
&& (size
!= 0)) {
5323 /* UNDEF on invalid size for polynomial subcase */
5328 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5336 if (pairwise
&& q
) {
5337 /* All the pairwise insns UNDEF if Q is set */
5341 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5346 tmp
= neon_load_reg(rn
, 0);
5347 tmp2
= neon_load_reg(rn
, 1);
5349 tmp
= neon_load_reg(rm
, 0);
5350 tmp2
= neon_load_reg(rm
, 1);
5354 tmp
= neon_load_reg(rn
, pass
);
5355 tmp2
= neon_load_reg(rm
, pass
);
5359 GEN_NEON_INTEGER_OP(hadd
);
5362 GEN_NEON_INTEGER_OP_ENV(qadd
);
5364 case NEON_3R_VRHADD
:
5365 GEN_NEON_INTEGER_OP(rhadd
);
5367 case NEON_3R_LOGIC
: /* Logic ops. */
5368 switch ((u
<< 2) | size
) {
5370 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5373 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5376 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5379 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5382 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5385 tmp3
= neon_load_reg(rd
, pass
);
5386 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5387 tcg_temp_free_i32(tmp3
);
5390 tmp3
= neon_load_reg(rd
, pass
);
5391 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5392 tcg_temp_free_i32(tmp3
);
5395 tmp3
= neon_load_reg(rd
, pass
);
5396 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5397 tcg_temp_free_i32(tmp3
);
5402 GEN_NEON_INTEGER_OP(hsub
);
5405 GEN_NEON_INTEGER_OP_ENV(qsub
);
5408 GEN_NEON_INTEGER_OP(cgt
);
5411 GEN_NEON_INTEGER_OP(cge
);
5414 GEN_NEON_INTEGER_OP(shl
);
5417 GEN_NEON_INTEGER_OP_ENV(qshl
);
5420 GEN_NEON_INTEGER_OP(rshl
);
5422 case NEON_3R_VQRSHL
:
5423 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5426 GEN_NEON_INTEGER_OP(max
);
5429 GEN_NEON_INTEGER_OP(min
);
5432 GEN_NEON_INTEGER_OP(abd
);
5435 GEN_NEON_INTEGER_OP(abd
);
5436 tcg_temp_free_i32(tmp2
);
5437 tmp2
= neon_load_reg(rd
, pass
);
5438 gen_neon_add(size
, tmp
, tmp2
);
5440 case NEON_3R_VADD_VSUB
:
5441 if (!u
) { /* VADD */
5442 gen_neon_add(size
, tmp
, tmp2
);
5445 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5446 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5447 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5452 case NEON_3R_VTST_VCEQ
:
5453 if (!u
) { /* VTST */
5455 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5456 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5457 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5462 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5463 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5464 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5469 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5471 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5472 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5473 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5476 tcg_temp_free_i32(tmp2
);
5477 tmp2
= neon_load_reg(rd
, pass
);
5479 gen_neon_rsb(size
, tmp
, tmp2
);
5481 gen_neon_add(size
, tmp
, tmp2
);
5485 if (u
) { /* polynomial */
5486 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5487 } else { /* Integer */
5489 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5490 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5491 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5497 GEN_NEON_INTEGER_OP(pmax
);
5500 GEN_NEON_INTEGER_OP(pmin
);
5502 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5503 if (!u
) { /* VQDMULH */
5506 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5509 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5513 } else { /* VQRDMULH */
5516 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5519 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5527 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5528 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5529 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5533 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5535 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5536 switch ((u
<< 2) | size
) {
5539 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5542 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5545 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5550 tcg_temp_free_ptr(fpstatus
);
5553 case NEON_3R_FLOAT_MULTIPLY
:
5555 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5556 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5558 tcg_temp_free_i32(tmp2
);
5559 tmp2
= neon_load_reg(rd
, pass
);
5561 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5563 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5566 tcg_temp_free_ptr(fpstatus
);
5569 case NEON_3R_FLOAT_CMP
:
5571 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5573 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5576 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5578 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5581 tcg_temp_free_ptr(fpstatus
);
5584 case NEON_3R_FLOAT_ACMP
:
5586 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5588 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5590 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5592 tcg_temp_free_ptr(fpstatus
);
5595 case NEON_3R_FLOAT_MINMAX
:
5597 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5599 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5601 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5603 tcg_temp_free_ptr(fpstatus
);
5606 case NEON_3R_FLOAT_MISC
:
5609 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5611 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5613 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5615 tcg_temp_free_ptr(fpstatus
);
5618 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5620 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5626 /* VFMA, VFMS: fused multiply-add */
5627 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5628 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5631 gen_helper_vfp_negs(tmp
, tmp
);
5633 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5634 tcg_temp_free_i32(tmp3
);
5635 tcg_temp_free_ptr(fpstatus
);
5641 tcg_temp_free_i32(tmp2
);
5643 /* Save the result. For elementwise operations we can put it
5644 straight into the destination register. For pairwise operations
5645 we have to be careful to avoid clobbering the source operands. */
5646 if (pairwise
&& rd
== rm
) {
5647 neon_store_scratch(pass
, tmp
);
5649 neon_store_reg(rd
, pass
, tmp
);
5653 if (pairwise
&& rd
== rm
) {
5654 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5655 tmp
= neon_load_scratch(pass
);
5656 neon_store_reg(rd
, pass
, tmp
);
5659 /* End of 3 register same size operations. */
5660 } else if (insn
& (1 << 4)) {
5661 if ((insn
& 0x00380080) != 0) {
5662 /* Two registers and shift. */
5663 op
= (insn
>> 8) & 0xf;
5664 if (insn
& (1 << 7)) {
5672 while ((insn
& (1 << (size
+ 19))) == 0)
5675 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5676 /* To avoid excessive duplication of ops we implement shift
5677 by immediate using the variable shift operations. */
5679 /* Shift by immediate:
5680 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5681 if (q
&& ((rd
| rm
) & 1)) {
5684 if (!u
&& (op
== 4 || op
== 6)) {
5687 /* Right shifts are encoded as N - shift, where N is the
5688 element size in bits. */
5690 shift
= shift
- (1 << (size
+ 3));
5698 imm
= (uint8_t) shift
;
5703 imm
= (uint16_t) shift
;
5714 for (pass
= 0; pass
< count
; pass
++) {
5716 neon_load_reg64(cpu_V0
, rm
+ pass
);
5717 tcg_gen_movi_i64(cpu_V1
, imm
);
5722 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5724 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5729 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5731 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5734 case 5: /* VSHL, VSLI */
5735 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5737 case 6: /* VQSHLU */
5738 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5743 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5746 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5751 if (op
== 1 || op
== 3) {
5753 neon_load_reg64(cpu_V1
, rd
+ pass
);
5754 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5755 } else if (op
== 4 || (op
== 5 && u
)) {
5757 neon_load_reg64(cpu_V1
, rd
+ pass
);
5759 if (shift
< -63 || shift
> 63) {
5763 mask
= 0xffffffffffffffffull
>> -shift
;
5765 mask
= 0xffffffffffffffffull
<< shift
;
5768 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5769 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5771 neon_store_reg64(cpu_V0
, rd
+ pass
);
5772 } else { /* size < 3 */
5773 /* Operands in T0 and T1. */
5774 tmp
= neon_load_reg(rm
, pass
);
5775 tmp2
= tcg_temp_new_i32();
5776 tcg_gen_movi_i32(tmp2
, imm
);
5780 GEN_NEON_INTEGER_OP(shl
);
5784 GEN_NEON_INTEGER_OP(rshl
);
5787 case 5: /* VSHL, VSLI */
5789 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5790 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5791 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5795 case 6: /* VQSHLU */
5798 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5802 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5806 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5814 GEN_NEON_INTEGER_OP_ENV(qshl
);
5817 tcg_temp_free_i32(tmp2
);
5819 if (op
== 1 || op
== 3) {
5821 tmp2
= neon_load_reg(rd
, pass
);
5822 gen_neon_add(size
, tmp
, tmp2
);
5823 tcg_temp_free_i32(tmp2
);
5824 } else if (op
== 4 || (op
== 5 && u
)) {
5829 mask
= 0xff >> -shift
;
5831 mask
= (uint8_t)(0xff << shift
);
5837 mask
= 0xffff >> -shift
;
5839 mask
= (uint16_t)(0xffff << shift
);
5843 if (shift
< -31 || shift
> 31) {
5847 mask
= 0xffffffffu
>> -shift
;
5849 mask
= 0xffffffffu
<< shift
;
5855 tmp2
= neon_load_reg(rd
, pass
);
5856 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5857 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5858 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5859 tcg_temp_free_i32(tmp2
);
5861 neon_store_reg(rd
, pass
, tmp
);
5864 } else if (op
< 10) {
5865 /* Shift by immediate and narrow:
5866 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5867 int input_unsigned
= (op
== 8) ? !u
: u
;
5871 shift
= shift
- (1 << (size
+ 3));
5874 tmp64
= tcg_const_i64(shift
);
5875 neon_load_reg64(cpu_V0
, rm
);
5876 neon_load_reg64(cpu_V1
, rm
+ 1);
5877 for (pass
= 0; pass
< 2; pass
++) {
5885 if (input_unsigned
) {
5886 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5888 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5891 if (input_unsigned
) {
5892 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5894 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5897 tmp
= tcg_temp_new_i32();
5898 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5899 neon_store_reg(rd
, pass
, tmp
);
5901 tcg_temp_free_i64(tmp64
);
5904 imm
= (uint16_t)shift
;
5908 imm
= (uint32_t)shift
;
5910 tmp2
= tcg_const_i32(imm
);
5911 tmp4
= neon_load_reg(rm
+ 1, 0);
5912 tmp5
= neon_load_reg(rm
+ 1, 1);
5913 for (pass
= 0; pass
< 2; pass
++) {
5915 tmp
= neon_load_reg(rm
, 0);
5919 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5922 tmp3
= neon_load_reg(rm
, 1);
5926 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5928 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5929 tcg_temp_free_i32(tmp
);
5930 tcg_temp_free_i32(tmp3
);
5931 tmp
= tcg_temp_new_i32();
5932 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5933 neon_store_reg(rd
, pass
, tmp
);
5935 tcg_temp_free_i32(tmp2
);
5937 } else if (op
== 10) {
5939 if (q
|| (rd
& 1)) {
5942 tmp
= neon_load_reg(rm
, 0);
5943 tmp2
= neon_load_reg(rm
, 1);
5944 for (pass
= 0; pass
< 2; pass
++) {
5948 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5951 /* The shift is less than the width of the source
5952 type, so we can just shift the whole register. */
5953 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5954 /* Widen the result of shift: we need to clear
5955 * the potential overflow bits resulting from
5956 * left bits of the narrow input appearing as
5957 * right bits of left the neighbour narrow
5959 if (size
< 2 || !u
) {
5962 imm
= (0xffu
>> (8 - shift
));
5964 } else if (size
== 1) {
5965 imm
= 0xffff >> (16 - shift
);
5968 imm
= 0xffffffff >> (32 - shift
);
5971 imm64
= imm
| (((uint64_t)imm
) << 32);
5975 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5978 neon_store_reg64(cpu_V0
, rd
+ pass
);
5980 } else if (op
>= 14) {
5981 /* VCVT fixed-point. */
5982 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5985 /* We have already masked out the must-be-1 top bit of imm6,
5986 * hence this 32-shift where the ARM ARM has 64-imm6.
5989 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5990 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5993 gen_vfp_ulto(0, shift
, 1);
5995 gen_vfp_slto(0, shift
, 1);
5998 gen_vfp_toul(0, shift
, 1);
6000 gen_vfp_tosl(0, shift
, 1);
6002 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6007 } else { /* (insn & 0x00380080) == 0 */
6009 if (q
&& (rd
& 1)) {
6013 op
= (insn
>> 8) & 0xf;
6014 /* One register and immediate. */
6015 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6016 invert
= (insn
& (1 << 5)) != 0;
6017 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6018 * We choose to not special-case this and will behave as if a
6019 * valid constant encoding of 0 had been given.
6038 imm
= (imm
<< 8) | (imm
<< 24);
6041 imm
= (imm
<< 8) | 0xff;
6044 imm
= (imm
<< 16) | 0xffff;
6047 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6055 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6056 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6062 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6063 if (op
& 1 && op
< 12) {
6064 tmp
= neon_load_reg(rd
, pass
);
6066 /* The immediate value has already been inverted, so
6068 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6070 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6074 tmp
= tcg_temp_new_i32();
6075 if (op
== 14 && invert
) {
6079 for (n
= 0; n
< 4; n
++) {
6080 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6081 val
|= 0xff << (n
* 8);
6083 tcg_gen_movi_i32(tmp
, val
);
6085 tcg_gen_movi_i32(tmp
, imm
);
6088 neon_store_reg(rd
, pass
, tmp
);
6091 } else { /* (insn & 0x00800010 == 0x00800000) */
6093 op
= (insn
>> 8) & 0xf;
6094 if ((insn
& (1 << 6)) == 0) {
6095 /* Three registers of different lengths. */
6099 /* undefreq: bit 0 : UNDEF if size == 0
6100 * bit 1 : UNDEF if size == 1
6101 * bit 2 : UNDEF if size == 2
6102 * bit 3 : UNDEF if U == 1
6103 * Note that [2:0] set implies 'always UNDEF'
6106 /* prewiden, src1_wide, src2_wide, undefreq */
6107 static const int neon_3reg_wide
[16][4] = {
6108 {1, 0, 0, 0}, /* VADDL */
6109 {1, 1, 0, 0}, /* VADDW */
6110 {1, 0, 0, 0}, /* VSUBL */
6111 {1, 1, 0, 0}, /* VSUBW */
6112 {0, 1, 1, 0}, /* VADDHN */
6113 {0, 0, 0, 0}, /* VABAL */
6114 {0, 1, 1, 0}, /* VSUBHN */
6115 {0, 0, 0, 0}, /* VABDL */
6116 {0, 0, 0, 0}, /* VMLAL */
6117 {0, 0, 0, 9}, /* VQDMLAL */
6118 {0, 0, 0, 0}, /* VMLSL */
6119 {0, 0, 0, 9}, /* VQDMLSL */
6120 {0, 0, 0, 0}, /* Integer VMULL */
6121 {0, 0, 0, 1}, /* VQDMULL */
6122 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6123 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6126 prewiden
= neon_3reg_wide
[op
][0];
6127 src1_wide
= neon_3reg_wide
[op
][1];
6128 src2_wide
= neon_3reg_wide
[op
][2];
6129 undefreq
= neon_3reg_wide
[op
][3];
6131 if ((undefreq
& (1 << size
)) ||
6132 ((undefreq
& 8) && u
)) {
6135 if ((src1_wide
&& (rn
& 1)) ||
6136 (src2_wide
&& (rm
& 1)) ||
6137 (!src2_wide
&& (rd
& 1))) {
6141 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6142 * outside the loop below as it only performs a single pass.
6144 if (op
== 14 && size
== 2) {
6145 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6147 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6150 tcg_rn
= tcg_temp_new_i64();
6151 tcg_rm
= tcg_temp_new_i64();
6152 tcg_rd
= tcg_temp_new_i64();
6153 neon_load_reg64(tcg_rn
, rn
);
6154 neon_load_reg64(tcg_rm
, rm
);
6155 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6156 neon_store_reg64(tcg_rd
, rd
);
6157 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6158 neon_store_reg64(tcg_rd
, rd
+ 1);
6159 tcg_temp_free_i64(tcg_rn
);
6160 tcg_temp_free_i64(tcg_rm
);
6161 tcg_temp_free_i64(tcg_rd
);
6165 /* Avoid overlapping operands. Wide source operands are
6166 always aligned so will never overlap with wide
6167 destinations in problematic ways. */
6168 if (rd
== rm
&& !src2_wide
) {
6169 tmp
= neon_load_reg(rm
, 1);
6170 neon_store_scratch(2, tmp
);
6171 } else if (rd
== rn
&& !src1_wide
) {
6172 tmp
= neon_load_reg(rn
, 1);
6173 neon_store_scratch(2, tmp
);
6175 TCGV_UNUSED_I32(tmp3
);
6176 for (pass
= 0; pass
< 2; pass
++) {
6178 neon_load_reg64(cpu_V0
, rn
+ pass
);
6179 TCGV_UNUSED_I32(tmp
);
6181 if (pass
== 1 && rd
== rn
) {
6182 tmp
= neon_load_scratch(2);
6184 tmp
= neon_load_reg(rn
, pass
);
6187 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6191 neon_load_reg64(cpu_V1
, rm
+ pass
);
6192 TCGV_UNUSED_I32(tmp2
);
6194 if (pass
== 1 && rd
== rm
) {
6195 tmp2
= neon_load_scratch(2);
6197 tmp2
= neon_load_reg(rm
, pass
);
6200 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6204 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6205 gen_neon_addl(size
);
6207 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6208 gen_neon_subl(size
);
6210 case 5: case 7: /* VABAL, VABDL */
6211 switch ((size
<< 1) | u
) {
6213 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6216 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6219 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6222 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6225 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6228 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6232 tcg_temp_free_i32(tmp2
);
6233 tcg_temp_free_i32(tmp
);
6235 case 8: case 9: case 10: case 11: case 12: case 13:
6236 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6237 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6239 case 14: /* Polynomial VMULL */
6240 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6241 tcg_temp_free_i32(tmp2
);
6242 tcg_temp_free_i32(tmp
);
6244 default: /* 15 is RESERVED: caught earlier */
6249 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6250 neon_store_reg64(cpu_V0
, rd
+ pass
);
6251 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6253 neon_load_reg64(cpu_V1
, rd
+ pass
);
6255 case 10: /* VMLSL */
6256 gen_neon_negl(cpu_V0
, size
);
6258 case 5: case 8: /* VABAL, VMLAL */
6259 gen_neon_addl(size
);
6261 case 9: case 11: /* VQDMLAL, VQDMLSL */
6262 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6264 gen_neon_negl(cpu_V0
, size
);
6266 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6271 neon_store_reg64(cpu_V0
, rd
+ pass
);
6272 } else if (op
== 4 || op
== 6) {
6273 /* Narrowing operation. */
6274 tmp
= tcg_temp_new_i32();
6278 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6281 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6284 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6285 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6292 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6295 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6298 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6299 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6300 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6308 neon_store_reg(rd
, 0, tmp3
);
6309 neon_store_reg(rd
, 1, tmp
);
6312 /* Write back the result. */
6313 neon_store_reg64(cpu_V0
, rd
+ pass
);
6317 /* Two registers and a scalar. NB that for ops of this form
6318 * the ARM ARM labels bit 24 as Q, but it is in our variable
6325 case 1: /* Float VMLA scalar */
6326 case 5: /* Floating point VMLS scalar */
6327 case 9: /* Floating point VMUL scalar */
6332 case 0: /* Integer VMLA scalar */
6333 case 4: /* Integer VMLS scalar */
6334 case 8: /* Integer VMUL scalar */
6335 case 12: /* VQDMULH scalar */
6336 case 13: /* VQRDMULH scalar */
6337 if (u
&& ((rd
| rn
) & 1)) {
6340 tmp
= neon_get_scalar(size
, rm
);
6341 neon_store_scratch(0, tmp
);
6342 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6343 tmp
= neon_load_scratch(0);
6344 tmp2
= neon_load_reg(rn
, pass
);
6347 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6349 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6351 } else if (op
== 13) {
6353 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6355 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6357 } else if (op
& 1) {
6358 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6359 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6360 tcg_temp_free_ptr(fpstatus
);
6363 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6364 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6365 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6369 tcg_temp_free_i32(tmp2
);
6372 tmp2
= neon_load_reg(rd
, pass
);
6375 gen_neon_add(size
, tmp
, tmp2
);
6379 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6380 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6381 tcg_temp_free_ptr(fpstatus
);
6385 gen_neon_rsb(size
, tmp
, tmp2
);
6389 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6390 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6391 tcg_temp_free_ptr(fpstatus
);
6397 tcg_temp_free_i32(tmp2
);
6399 neon_store_reg(rd
, pass
, tmp
);
6402 case 3: /* VQDMLAL scalar */
6403 case 7: /* VQDMLSL scalar */
6404 case 11: /* VQDMULL scalar */
6409 case 2: /* VMLAL sclar */
6410 case 6: /* VMLSL scalar */
6411 case 10: /* VMULL scalar */
6415 tmp2
= neon_get_scalar(size
, rm
);
6416 /* We need a copy of tmp2 because gen_neon_mull
6417 * deletes it during pass 0. */
6418 tmp4
= tcg_temp_new_i32();
6419 tcg_gen_mov_i32(tmp4
, tmp2
);
6420 tmp3
= neon_load_reg(rn
, 1);
6422 for (pass
= 0; pass
< 2; pass
++) {
6424 tmp
= neon_load_reg(rn
, 0);
6429 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6431 neon_load_reg64(cpu_V1
, rd
+ pass
);
6435 gen_neon_negl(cpu_V0
, size
);
6438 gen_neon_addl(size
);
6441 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6443 gen_neon_negl(cpu_V0
, size
);
6445 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6451 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6456 neon_store_reg64(cpu_V0
, rd
+ pass
);
6461 default: /* 14 and 15 are RESERVED */
6465 } else { /* size == 3 */
6468 imm
= (insn
>> 8) & 0xf;
6473 if (q
&& ((rd
| rn
| rm
) & 1)) {
6478 neon_load_reg64(cpu_V0
, rn
);
6480 neon_load_reg64(cpu_V1
, rn
+ 1);
6482 } else if (imm
== 8) {
6483 neon_load_reg64(cpu_V0
, rn
+ 1);
6485 neon_load_reg64(cpu_V1
, rm
);
6488 tmp64
= tcg_temp_new_i64();
6490 neon_load_reg64(cpu_V0
, rn
);
6491 neon_load_reg64(tmp64
, rn
+ 1);
6493 neon_load_reg64(cpu_V0
, rn
+ 1);
6494 neon_load_reg64(tmp64
, rm
);
6496 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6497 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6498 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6500 neon_load_reg64(cpu_V1
, rm
);
6502 neon_load_reg64(cpu_V1
, rm
+ 1);
6505 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6506 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6507 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6508 tcg_temp_free_i64(tmp64
);
6511 neon_load_reg64(cpu_V0
, rn
);
6512 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6513 neon_load_reg64(cpu_V1
, rm
);
6514 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6515 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6517 neon_store_reg64(cpu_V0
, rd
);
6519 neon_store_reg64(cpu_V1
, rd
+ 1);
6521 } else if ((insn
& (1 << 11)) == 0) {
6522 /* Two register misc. */
6523 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6524 size
= (insn
>> 18) & 3;
6525 /* UNDEF for unknown op values and bad op-size combinations */
6526 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6529 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6530 q
&& ((rm
| rd
) & 1)) {
6534 case NEON_2RM_VREV64
:
6535 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6536 tmp
= neon_load_reg(rm
, pass
* 2);
6537 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6539 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6540 case 1: gen_swap_half(tmp
); break;
6541 case 2: /* no-op */ break;
6544 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6546 neon_store_reg(rd
, pass
* 2, tmp2
);
6549 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6550 case 1: gen_swap_half(tmp2
); break;
6553 neon_store_reg(rd
, pass
* 2, tmp2
);
6557 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6558 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6559 for (pass
= 0; pass
< q
+ 1; pass
++) {
6560 tmp
= neon_load_reg(rm
, pass
* 2);
6561 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6562 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6563 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6565 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6566 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6567 case 2: tcg_gen_add_i64(CPU_V001
); break;
6570 if (op
>= NEON_2RM_VPADAL
) {
6572 neon_load_reg64(cpu_V1
, rd
+ pass
);
6573 gen_neon_addl(size
);
6575 neon_store_reg64(cpu_V0
, rd
+ pass
);
6581 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6582 tmp
= neon_load_reg(rm
, n
);
6583 tmp2
= neon_load_reg(rd
, n
+ 1);
6584 neon_store_reg(rm
, n
, tmp2
);
6585 neon_store_reg(rd
, n
+ 1, tmp
);
6592 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6597 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6601 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6602 /* also VQMOVUN; op field and mnemonics don't line up */
6606 TCGV_UNUSED_I32(tmp2
);
6607 for (pass
= 0; pass
< 2; pass
++) {
6608 neon_load_reg64(cpu_V0
, rm
+ pass
);
6609 tmp
= tcg_temp_new_i32();
6610 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6615 neon_store_reg(rd
, 0, tmp2
);
6616 neon_store_reg(rd
, 1, tmp
);
6620 case NEON_2RM_VSHLL
:
6621 if (q
|| (rd
& 1)) {
6624 tmp
= neon_load_reg(rm
, 0);
6625 tmp2
= neon_load_reg(rm
, 1);
6626 for (pass
= 0; pass
< 2; pass
++) {
6629 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6630 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6631 neon_store_reg64(cpu_V0
, rd
+ pass
);
6634 case NEON_2RM_VCVT_F16_F32
:
6635 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6639 tmp
= tcg_temp_new_i32();
6640 tmp2
= tcg_temp_new_i32();
6641 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6642 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6643 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6644 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6645 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6646 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6647 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6648 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6649 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6650 neon_store_reg(rd
, 0, tmp2
);
6651 tmp2
= tcg_temp_new_i32();
6652 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6653 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6654 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6655 neon_store_reg(rd
, 1, tmp2
);
6656 tcg_temp_free_i32(tmp
);
6658 case NEON_2RM_VCVT_F32_F16
:
6659 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6663 tmp3
= tcg_temp_new_i32();
6664 tmp
= neon_load_reg(rm
, 0);
6665 tmp2
= neon_load_reg(rm
, 1);
6666 tcg_gen_ext16u_i32(tmp3
, tmp
);
6667 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6668 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6669 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6670 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6671 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6672 tcg_temp_free_i32(tmp
);
6673 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6674 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6675 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6676 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6677 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6678 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6679 tcg_temp_free_i32(tmp2
);
6680 tcg_temp_free_i32(tmp3
);
6682 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6683 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6684 || ((rm
| rd
) & 1)) {
6687 tmp
= tcg_const_i32(rd
);
6688 tmp2
= tcg_const_i32(rm
);
6690 /* Bit 6 is the lowest opcode bit; it distinguishes between
6691 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6693 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6695 if (op
== NEON_2RM_AESE
) {
6696 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6698 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6700 tcg_temp_free_i32(tmp
);
6701 tcg_temp_free_i32(tmp2
);
6702 tcg_temp_free_i32(tmp3
);
6704 case NEON_2RM_SHA1H
:
6705 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
6706 || ((rm
| rd
) & 1)) {
6709 tmp
= tcg_const_i32(rd
);
6710 tmp2
= tcg_const_i32(rm
);
6712 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6714 tcg_temp_free_i32(tmp
);
6715 tcg_temp_free_i32(tmp2
);
6717 case NEON_2RM_SHA1SU1
:
6718 if ((rm
| rd
) & 1) {
6721 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6723 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
6726 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
6729 tmp
= tcg_const_i32(rd
);
6730 tmp2
= tcg_const_i32(rm
);
6732 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6734 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6736 tcg_temp_free_i32(tmp
);
6737 tcg_temp_free_i32(tmp2
);
6741 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6742 if (neon_2rm_is_float_op(op
)) {
6743 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6744 neon_reg_offset(rm
, pass
));
6745 TCGV_UNUSED_I32(tmp
);
6747 tmp
= neon_load_reg(rm
, pass
);
6750 case NEON_2RM_VREV32
:
6752 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6753 case 1: gen_swap_half(tmp
); break;
6757 case NEON_2RM_VREV16
:
6762 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6763 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6764 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6770 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6771 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6772 case 2: gen_helper_clz(tmp
, tmp
); break;
6777 gen_helper_neon_cnt_u8(tmp
, tmp
);
6780 tcg_gen_not_i32(tmp
, tmp
);
6782 case NEON_2RM_VQABS
:
6785 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6788 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6791 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6796 case NEON_2RM_VQNEG
:
6799 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6802 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6805 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6810 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6811 tmp2
= tcg_const_i32(0);
6813 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6814 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6815 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6818 tcg_temp_free_i32(tmp2
);
6819 if (op
== NEON_2RM_VCLE0
) {
6820 tcg_gen_not_i32(tmp
, tmp
);
6823 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6824 tmp2
= tcg_const_i32(0);
6826 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6827 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6828 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6831 tcg_temp_free_i32(tmp2
);
6832 if (op
== NEON_2RM_VCLT0
) {
6833 tcg_gen_not_i32(tmp
, tmp
);
6836 case NEON_2RM_VCEQ0
:
6837 tmp2
= tcg_const_i32(0);
6839 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6840 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6841 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6844 tcg_temp_free_i32(tmp2
);
6848 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6849 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6850 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6855 tmp2
= tcg_const_i32(0);
6856 gen_neon_rsb(size
, tmp
, tmp2
);
6857 tcg_temp_free_i32(tmp2
);
6859 case NEON_2RM_VCGT0_F
:
6861 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6862 tmp2
= tcg_const_i32(0);
6863 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6864 tcg_temp_free_i32(tmp2
);
6865 tcg_temp_free_ptr(fpstatus
);
6868 case NEON_2RM_VCGE0_F
:
6870 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6871 tmp2
= tcg_const_i32(0);
6872 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6873 tcg_temp_free_i32(tmp2
);
6874 tcg_temp_free_ptr(fpstatus
);
6877 case NEON_2RM_VCEQ0_F
:
6879 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6880 tmp2
= tcg_const_i32(0);
6881 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6882 tcg_temp_free_i32(tmp2
);
6883 tcg_temp_free_ptr(fpstatus
);
6886 case NEON_2RM_VCLE0_F
:
6888 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6889 tmp2
= tcg_const_i32(0);
6890 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6891 tcg_temp_free_i32(tmp2
);
6892 tcg_temp_free_ptr(fpstatus
);
6895 case NEON_2RM_VCLT0_F
:
6897 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6898 tmp2
= tcg_const_i32(0);
6899 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6900 tcg_temp_free_i32(tmp2
);
6901 tcg_temp_free_ptr(fpstatus
);
6904 case NEON_2RM_VABS_F
:
6907 case NEON_2RM_VNEG_F
:
6911 tmp2
= neon_load_reg(rd
, pass
);
6912 neon_store_reg(rm
, pass
, tmp2
);
6915 tmp2
= neon_load_reg(rd
, pass
);
6917 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6918 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6921 neon_store_reg(rm
, pass
, tmp2
);
6923 case NEON_2RM_VRINTN
:
6924 case NEON_2RM_VRINTA
:
6925 case NEON_2RM_VRINTM
:
6926 case NEON_2RM_VRINTP
:
6927 case NEON_2RM_VRINTZ
:
6930 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6933 if (op
== NEON_2RM_VRINTZ
) {
6934 rmode
= FPROUNDING_ZERO
;
6936 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6939 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6940 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6942 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6943 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6945 tcg_temp_free_ptr(fpstatus
);
6946 tcg_temp_free_i32(tcg_rmode
);
6949 case NEON_2RM_VRINTX
:
6951 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6952 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6953 tcg_temp_free_ptr(fpstatus
);
6956 case NEON_2RM_VCVTAU
:
6957 case NEON_2RM_VCVTAS
:
6958 case NEON_2RM_VCVTNU
:
6959 case NEON_2RM_VCVTNS
:
6960 case NEON_2RM_VCVTPU
:
6961 case NEON_2RM_VCVTPS
:
6962 case NEON_2RM_VCVTMU
:
6963 case NEON_2RM_VCVTMS
:
6965 bool is_signed
= !extract32(insn
, 7, 1);
6966 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6967 TCGv_i32 tcg_rmode
, tcg_shift
;
6968 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6970 tcg_shift
= tcg_const_i32(0);
6971 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6972 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6976 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6979 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6983 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6985 tcg_temp_free_i32(tcg_rmode
);
6986 tcg_temp_free_i32(tcg_shift
);
6987 tcg_temp_free_ptr(fpst
);
6990 case NEON_2RM_VRECPE
:
6992 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6993 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6994 tcg_temp_free_ptr(fpstatus
);
6997 case NEON_2RM_VRSQRTE
:
6999 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7000 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7001 tcg_temp_free_ptr(fpstatus
);
7004 case NEON_2RM_VRECPE_F
:
7006 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7007 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7008 tcg_temp_free_ptr(fpstatus
);
7011 case NEON_2RM_VRSQRTE_F
:
7013 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7014 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7015 tcg_temp_free_ptr(fpstatus
);
7018 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7021 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7024 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7025 gen_vfp_tosiz(0, 1);
7027 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7028 gen_vfp_touiz(0, 1);
7031 /* Reserved op values were caught by the
7032 * neon_2rm_sizes[] check earlier.
7036 if (neon_2rm_is_float_op(op
)) {
7037 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7038 neon_reg_offset(rd
, pass
));
7040 neon_store_reg(rd
, pass
, tmp
);
7045 } else if ((insn
& (1 << 10)) == 0) {
7047 int n
= ((insn
>> 8) & 3) + 1;
7048 if ((rn
+ n
) > 32) {
7049 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7050 * helper function running off the end of the register file.
7055 if (insn
& (1 << 6)) {
7056 tmp
= neon_load_reg(rd
, 0);
7058 tmp
= tcg_temp_new_i32();
7059 tcg_gen_movi_i32(tmp
, 0);
7061 tmp2
= neon_load_reg(rm
, 0);
7062 tmp4
= tcg_const_i32(rn
);
7063 tmp5
= tcg_const_i32(n
);
7064 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7065 tcg_temp_free_i32(tmp
);
7066 if (insn
& (1 << 6)) {
7067 tmp
= neon_load_reg(rd
, 1);
7069 tmp
= tcg_temp_new_i32();
7070 tcg_gen_movi_i32(tmp
, 0);
7072 tmp3
= neon_load_reg(rm
, 1);
7073 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7074 tcg_temp_free_i32(tmp5
);
7075 tcg_temp_free_i32(tmp4
);
7076 neon_store_reg(rd
, 0, tmp2
);
7077 neon_store_reg(rd
, 1, tmp3
);
7078 tcg_temp_free_i32(tmp
);
7079 } else if ((insn
& 0x380) == 0) {
7081 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7084 if (insn
& (1 << 19)) {
7085 tmp
= neon_load_reg(rm
, 1);
7087 tmp
= neon_load_reg(rm
, 0);
7089 if (insn
& (1 << 16)) {
7090 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7091 } else if (insn
& (1 << 17)) {
7092 if ((insn
>> 18) & 1)
7093 gen_neon_dup_high16(tmp
);
7095 gen_neon_dup_low16(tmp
);
7097 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7098 tmp2
= tcg_temp_new_i32();
7099 tcg_gen_mov_i32(tmp2
, tmp
);
7100 neon_store_reg(rd
, pass
, tmp2
);
7102 tcg_temp_free_i32(tmp
);
7111 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7113 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7114 const ARMCPRegInfo
*ri
;
7116 cpnum
= (insn
>> 8) & 0xf;
7118 /* First check for coprocessor space used for XScale/iwMMXt insns */
7119 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7120 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7123 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7124 return disas_iwmmxt_insn(s
, insn
);
7125 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7126 return disas_dsp_insn(s
, insn
);
7131 /* Otherwise treat as a generic register access */
7132 is64
= (insn
& (1 << 25)) == 0;
7133 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7141 opc1
= (insn
>> 4) & 0xf;
7143 rt2
= (insn
>> 16) & 0xf;
7145 crn
= (insn
>> 16) & 0xf;
7146 opc1
= (insn
>> 21) & 7;
7147 opc2
= (insn
>> 5) & 7;
7150 isread
= (insn
>> 20) & 1;
7151 rt
= (insn
>> 12) & 0xf;
7153 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7154 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7156 /* Check access permissions */
7157 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7162 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7163 /* Emit code to perform further access permissions checks at
7164 * runtime; this may result in an exception.
7165 * Note that on XScale all cp0..c13 registers do an access check
7166 * call in order to handle c15_cpar.
7172 /* Note that since we are an implementation which takes an
7173 * exception on a trapped conditional instruction only if the
7174 * instruction passes its condition code check, we can take
7175 * advantage of the clause in the ARM ARM that allows us to set
7176 * the COND field in the instruction to 0xE in all cases.
7177 * We could fish the actual condition out of the insn (ARM)
7178 * or the condexec bits (Thumb) but it isn't necessary.
7183 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7186 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7187 rt
, isread
, s
->thumb
);
7192 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7195 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7196 rt
, isread
, s
->thumb
);
7200 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7201 * so this can only happen if this is an ARMv7 or earlier CPU,
7202 * in which case the syndrome information won't actually be
7205 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7206 syndrome
= syn_uncategorized();
7210 gen_set_pc_im(s
, s
->pc
- 4);
7211 tmpptr
= tcg_const_ptr(ri
);
7212 tcg_syn
= tcg_const_i32(syndrome
);
7213 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7214 tcg_temp_free_ptr(tmpptr
);
7215 tcg_temp_free_i32(tcg_syn
);
7218 /* Handle special cases first */
7219 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7226 gen_set_pc_im(s
, s
->pc
);
7227 s
->is_jmp
= DISAS_WFI
;
7233 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7242 if (ri
->type
& ARM_CP_CONST
) {
7243 tmp64
= tcg_const_i64(ri
->resetvalue
);
7244 } else if (ri
->readfn
) {
7246 tmp64
= tcg_temp_new_i64();
7247 tmpptr
= tcg_const_ptr(ri
);
7248 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7249 tcg_temp_free_ptr(tmpptr
);
7251 tmp64
= tcg_temp_new_i64();
7252 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7254 tmp
= tcg_temp_new_i32();
7255 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7256 store_reg(s
, rt
, tmp
);
7257 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7258 tmp
= tcg_temp_new_i32();
7259 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7260 tcg_temp_free_i64(tmp64
);
7261 store_reg(s
, rt2
, tmp
);
7264 if (ri
->type
& ARM_CP_CONST
) {
7265 tmp
= tcg_const_i32(ri
->resetvalue
);
7266 } else if (ri
->readfn
) {
7268 tmp
= tcg_temp_new_i32();
7269 tmpptr
= tcg_const_ptr(ri
);
7270 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7271 tcg_temp_free_ptr(tmpptr
);
7273 tmp
= load_cpu_offset(ri
->fieldoffset
);
7276 /* Destination register of r15 for 32 bit loads sets
7277 * the condition codes from the high 4 bits of the value
7280 tcg_temp_free_i32(tmp
);
7282 store_reg(s
, rt
, tmp
);
7287 if (ri
->type
& ARM_CP_CONST
) {
7288 /* If not forbidden by access permissions, treat as WI */
7293 TCGv_i32 tmplo
, tmphi
;
7294 TCGv_i64 tmp64
= tcg_temp_new_i64();
7295 tmplo
= load_reg(s
, rt
);
7296 tmphi
= load_reg(s
, rt2
);
7297 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7298 tcg_temp_free_i32(tmplo
);
7299 tcg_temp_free_i32(tmphi
);
7301 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7302 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7303 tcg_temp_free_ptr(tmpptr
);
7305 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7307 tcg_temp_free_i64(tmp64
);
7312 tmp
= load_reg(s
, rt
);
7313 tmpptr
= tcg_const_ptr(ri
);
7314 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7315 tcg_temp_free_ptr(tmpptr
);
7316 tcg_temp_free_i32(tmp
);
7318 TCGv_i32 tmp
= load_reg(s
, rt
);
7319 store_cpu_offset(tmp
, ri
->fieldoffset
);
7324 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7325 /* I/O operations must end the TB here (whether read or write) */
7328 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7329 /* We default to ending the TB on a coprocessor register write,
7330 * but allow this to be suppressed by the register definition
7331 * (usually only necessary to work around guest bugs).
7339 /* Unknown register; this might be a guest error or a QEMU
7340 * unimplemented feature.
7343 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7344 "64 bit system register cp:%d opc1: %d crm:%d "
7346 isread
? "read" : "write", cpnum
, opc1
, crm
,
7347 s
->ns
? "non-secure" : "secure");
7349 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7350 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7352 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7353 s
->ns
? "non-secure" : "secure");
7360 /* Store a 64-bit value to a register pair. Clobbers val. */
7361 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7364 tmp
= tcg_temp_new_i32();
7365 tcg_gen_extrl_i64_i32(tmp
, val
);
7366 store_reg(s
, rlow
, tmp
);
7367 tmp
= tcg_temp_new_i32();
7368 tcg_gen_shri_i64(val
, val
, 32);
7369 tcg_gen_extrl_i64_i32(tmp
, val
);
7370 store_reg(s
, rhigh
, tmp
);
7373 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7374 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7379 /* Load value and extend to 64 bits. */
7380 tmp
= tcg_temp_new_i64();
7381 tmp2
= load_reg(s
, rlow
);
7382 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7383 tcg_temp_free_i32(tmp2
);
7384 tcg_gen_add_i64(val
, val
, tmp
);
7385 tcg_temp_free_i64(tmp
);
7388 /* load and add a 64-bit value from a register pair. */
7389 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7395 /* Load 64-bit value rd:rn. */
7396 tmpl
= load_reg(s
, rlow
);
7397 tmph
= load_reg(s
, rhigh
);
7398 tmp
= tcg_temp_new_i64();
7399 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7400 tcg_temp_free_i32(tmpl
);
7401 tcg_temp_free_i32(tmph
);
7402 tcg_gen_add_i64(val
, val
, tmp
);
7403 tcg_temp_free_i64(tmp
);
7406 /* Set N and Z flags from hi|lo. */
7407 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7409 tcg_gen_mov_i32(cpu_NF
, hi
);
7410 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7413 /* Load/Store exclusive instructions are implemented by remembering
7414 the value/address loaded, and seeing if these are the same
7415 when the store is performed. This should be sufficient to implement
7416 the architecturally mandated semantics, and avoids having to monitor
7419 In system emulation mode only one CPU will be running at once, so
7420 this sequence is effectively atomic. In user emulation mode we
7421 throw an exception and handle the atomic operation elsewhere. */
7422 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7423 TCGv_i32 addr
, int size
)
7425 TCGv_i32 tmp
= tcg_temp_new_i32();
7431 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7434 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7438 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7445 TCGv_i32 tmp2
= tcg_temp_new_i32();
7446 TCGv_i32 tmp3
= tcg_temp_new_i32();
7448 tcg_gen_addi_i32(tmp2
, addr
, 4);
7449 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7450 tcg_temp_free_i32(tmp2
);
7451 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7452 store_reg(s
, rt2
, tmp3
);
7454 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7457 store_reg(s
, rt
, tmp
);
7458 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7461 static void gen_clrex(DisasContext
*s
)
7463 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7466 #ifdef CONFIG_USER_ONLY
7467 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7468 TCGv_i32 addr
, int size
)
7470 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7471 tcg_gen_movi_i32(cpu_exclusive_info
,
7472 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7473 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7476 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7477 TCGv_i32 addr
, int size
)
7480 TCGv_i64 val64
, extaddr
;
7481 TCGLabel
*done_label
;
7482 TCGLabel
*fail_label
;
7484 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7490 fail_label
= gen_new_label();
7491 done_label
= gen_new_label();
7492 extaddr
= tcg_temp_new_i64();
7493 tcg_gen_extu_i32_i64(extaddr
, addr
);
7494 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7495 tcg_temp_free_i64(extaddr
);
7497 tmp
= tcg_temp_new_i32();
7500 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7503 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7507 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7513 val64
= tcg_temp_new_i64();
7515 TCGv_i32 tmp2
= tcg_temp_new_i32();
7516 TCGv_i32 tmp3
= tcg_temp_new_i32();
7517 tcg_gen_addi_i32(tmp2
, addr
, 4);
7518 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7519 tcg_temp_free_i32(tmp2
);
7520 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7521 tcg_temp_free_i32(tmp3
);
7523 tcg_gen_extu_i32_i64(val64
, tmp
);
7525 tcg_temp_free_i32(tmp
);
7527 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7528 tcg_temp_free_i64(val64
);
7530 tmp
= load_reg(s
, rt
);
7533 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7536 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7540 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7545 tcg_temp_free_i32(tmp
);
7547 tcg_gen_addi_i32(addr
, addr
, 4);
7548 tmp
= load_reg(s
, rt2
);
7549 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7550 tcg_temp_free_i32(tmp
);
7552 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7553 tcg_gen_br(done_label
);
7554 gen_set_label(fail_label
);
7555 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7556 gen_set_label(done_label
);
7557 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7564 * @mode: mode field from insn (which stack to store to)
7565 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7566 * @writeback: true if writeback bit set
7568 * Generate code for the SRS (Store Return State) insn.
7570 static void gen_srs(DisasContext
*s
,
7571 uint32_t mode
, uint32_t amode
, bool writeback
)
7574 TCGv_i32 addr
= tcg_temp_new_i32();
7575 TCGv_i32 tmp
= tcg_const_i32(mode
);
7576 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7577 tcg_temp_free_i32(tmp
);
7594 tcg_gen_addi_i32(addr
, addr
, offset
);
7595 tmp
= load_reg(s
, 14);
7596 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7597 tcg_temp_free_i32(tmp
);
7598 tmp
= load_cpu_field(spsr
);
7599 tcg_gen_addi_i32(addr
, addr
, 4);
7600 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7601 tcg_temp_free_i32(tmp
);
7619 tcg_gen_addi_i32(addr
, addr
, offset
);
7620 tmp
= tcg_const_i32(mode
);
7621 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7622 tcg_temp_free_i32(tmp
);
7624 tcg_temp_free_i32(addr
);
7627 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7629 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7636 /* M variants do not implement ARM mode. */
7637 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7642 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7643 * choose to UNDEF. In ARMv5 and above the space is used
7644 * for miscellaneous unconditional instructions.
7648 /* Unconditional instructions. */
7649 if (((insn
>> 25) & 7) == 1) {
7650 /* NEON Data processing. */
7651 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7655 if (disas_neon_data_insn(s
, insn
)) {
7660 if ((insn
& 0x0f100000) == 0x04000000) {
7661 /* NEON load/store. */
7662 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7666 if (disas_neon_ls_insn(s
, insn
)) {
7671 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7673 if (disas_vfp_insn(s
, insn
)) {
7678 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7679 ((insn
& 0x0f30f010) == 0x0710f000)) {
7680 if ((insn
& (1 << 22)) == 0) {
7682 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7686 /* Otherwise PLD; v5TE+ */
7690 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7691 ((insn
& 0x0f70f010) == 0x0650f000)) {
7693 return; /* PLI; V7 */
7695 if (((insn
& 0x0f700000) == 0x04100000) ||
7696 ((insn
& 0x0f700010) == 0x06100000)) {
7697 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7700 return; /* v7MP: Unallocated memory hint: must NOP */
7703 if ((insn
& 0x0ffffdff) == 0x01010000) {
7706 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7707 /* Dynamic endianness switching not implemented. */
7708 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7709 g_assert_not_reached();
7712 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7713 switch ((insn
>> 4) & 0xf) {
7722 /* We don't emulate caches so these are a no-op. */
7727 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7733 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7735 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7741 rn
= (insn
>> 16) & 0xf;
7742 addr
= load_reg(s
, rn
);
7743 i
= (insn
>> 23) & 3;
7745 case 0: offset
= -4; break; /* DA */
7746 case 1: offset
= 0; break; /* IA */
7747 case 2: offset
= -8; break; /* DB */
7748 case 3: offset
= 4; break; /* IB */
7752 tcg_gen_addi_i32(addr
, addr
, offset
);
7753 /* Load PC into tmp and CPSR into tmp2. */
7754 tmp
= tcg_temp_new_i32();
7755 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7756 tcg_gen_addi_i32(addr
, addr
, 4);
7757 tmp2
= tcg_temp_new_i32();
7758 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7759 if (insn
& (1 << 21)) {
7760 /* Base writeback. */
7762 case 0: offset
= -8; break;
7763 case 1: offset
= 4; break;
7764 case 2: offset
= -4; break;
7765 case 3: offset
= 0; break;
7769 tcg_gen_addi_i32(addr
, addr
, offset
);
7770 store_reg(s
, rn
, addr
);
7772 tcg_temp_free_i32(addr
);
7774 gen_rfe(s
, tmp
, tmp2
);
7776 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7777 /* branch link and change to thumb (blx <offset>) */
7780 val
= (uint32_t)s
->pc
;
7781 tmp
= tcg_temp_new_i32();
7782 tcg_gen_movi_i32(tmp
, val
);
7783 store_reg(s
, 14, tmp
);
7784 /* Sign-extend the 24-bit offset */
7785 offset
= (((int32_t)insn
) << 8) >> 8;
7786 /* offset * 4 + bit24 * 2 + (thumb bit) */
7787 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7788 /* pipeline offset */
7790 /* protected by ARCH(5); above, near the start of uncond block */
7793 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7794 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7795 /* iWMMXt register transfer. */
7796 if (extract32(s
->c15_cpar
, 1, 1)) {
7797 if (!disas_iwmmxt_insn(s
, insn
)) {
7802 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7803 /* Coprocessor double register transfer. */
7805 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7806 /* Additional coprocessor register transfer. */
7807 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7810 /* cps (privileged) */
7814 if (insn
& (1 << 19)) {
7815 if (insn
& (1 << 8))
7817 if (insn
& (1 << 7))
7819 if (insn
& (1 << 6))
7821 if (insn
& (1 << 18))
7824 if (insn
& (1 << 17)) {
7826 val
|= (insn
& 0x1f);
7829 gen_set_psr_im(s
, mask
, 0, val
);
7836 /* if not always execute, we generate a conditional jump to
7838 s
->condlabel
= gen_new_label();
7839 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7842 if ((insn
& 0x0f900000) == 0x03000000) {
7843 if ((insn
& (1 << 21)) == 0) {
7845 rd
= (insn
>> 12) & 0xf;
7846 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7847 if ((insn
& (1 << 22)) == 0) {
7849 tmp
= tcg_temp_new_i32();
7850 tcg_gen_movi_i32(tmp
, val
);
7853 tmp
= load_reg(s
, rd
);
7854 tcg_gen_ext16u_i32(tmp
, tmp
);
7855 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7857 store_reg(s
, rd
, tmp
);
7859 if (((insn
>> 12) & 0xf) != 0xf)
7861 if (((insn
>> 16) & 0xf) == 0) {
7862 gen_nop_hint(s
, insn
& 0xff);
7864 /* CPSR = immediate */
7866 shift
= ((insn
>> 8) & 0xf) * 2;
7868 val
= (val
>> shift
) | (val
<< (32 - shift
));
7869 i
= ((insn
& (1 << 22)) != 0);
7870 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
7876 } else if ((insn
& 0x0f900000) == 0x01000000
7877 && (insn
& 0x00000090) != 0x00000090) {
7878 /* miscellaneous instructions */
7879 op1
= (insn
>> 21) & 3;
7880 sh
= (insn
>> 4) & 0xf;
7883 case 0x0: /* move program status register */
7886 tmp
= load_reg(s
, rm
);
7887 i
= ((op1
& 2) != 0);
7888 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7892 rd
= (insn
>> 12) & 0xf;
7896 tmp
= load_cpu_field(spsr
);
7898 tmp
= tcg_temp_new_i32();
7899 gen_helper_cpsr_read(tmp
, cpu_env
);
7901 store_reg(s
, rd
, tmp
);
7906 /* branch/exchange thumb (bx). */
7908 tmp
= load_reg(s
, rm
);
7910 } else if (op1
== 3) {
7913 rd
= (insn
>> 12) & 0xf;
7914 tmp
= load_reg(s
, rm
);
7915 gen_helper_clz(tmp
, tmp
);
7916 store_reg(s
, rd
, tmp
);
7924 /* Trivial implementation equivalent to bx. */
7925 tmp
= load_reg(s
, rm
);
7936 /* branch link/exchange thumb (blx) */
7937 tmp
= load_reg(s
, rm
);
7938 tmp2
= tcg_temp_new_i32();
7939 tcg_gen_movi_i32(tmp2
, s
->pc
);
7940 store_reg(s
, 14, tmp2
);
7946 uint32_t c
= extract32(insn
, 8, 4);
7948 /* Check this CPU supports ARMv8 CRC instructions.
7949 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7950 * Bits 8, 10 and 11 should be zero.
7952 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7957 rn
= extract32(insn
, 16, 4);
7958 rd
= extract32(insn
, 12, 4);
7960 tmp
= load_reg(s
, rn
);
7961 tmp2
= load_reg(s
, rm
);
7963 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7964 } else if (op1
== 1) {
7965 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7967 tmp3
= tcg_const_i32(1 << op1
);
7969 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7971 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7973 tcg_temp_free_i32(tmp2
);
7974 tcg_temp_free_i32(tmp3
);
7975 store_reg(s
, rd
, tmp
);
7978 case 0x5: /* saturating add/subtract */
7980 rd
= (insn
>> 12) & 0xf;
7981 rn
= (insn
>> 16) & 0xf;
7982 tmp
= load_reg(s
, rm
);
7983 tmp2
= load_reg(s
, rn
);
7985 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7987 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7989 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7990 tcg_temp_free_i32(tmp2
);
7991 store_reg(s
, rd
, tmp
);
7995 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8000 gen_exception_insn(s
, 4, EXCP_BKPT
,
8001 syn_aa32_bkpt(imm16
, false),
8002 default_exception_el(s
));
8005 /* Hypervisor call (v7) */
8013 /* Secure monitor call (v6+) */
8025 case 0x8: /* signed multiply */
8030 rs
= (insn
>> 8) & 0xf;
8031 rn
= (insn
>> 12) & 0xf;
8032 rd
= (insn
>> 16) & 0xf;
8034 /* (32 * 16) >> 16 */
8035 tmp
= load_reg(s
, rm
);
8036 tmp2
= load_reg(s
, rs
);
8038 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8041 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8042 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8043 tmp
= tcg_temp_new_i32();
8044 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8045 tcg_temp_free_i64(tmp64
);
8046 if ((sh
& 2) == 0) {
8047 tmp2
= load_reg(s
, rn
);
8048 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8049 tcg_temp_free_i32(tmp2
);
8051 store_reg(s
, rd
, tmp
);
8054 tmp
= load_reg(s
, rm
);
8055 tmp2
= load_reg(s
, rs
);
8056 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8057 tcg_temp_free_i32(tmp2
);
8059 tmp64
= tcg_temp_new_i64();
8060 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8061 tcg_temp_free_i32(tmp
);
8062 gen_addq(s
, tmp64
, rn
, rd
);
8063 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8064 tcg_temp_free_i64(tmp64
);
8067 tmp2
= load_reg(s
, rn
);
8068 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8069 tcg_temp_free_i32(tmp2
);
8071 store_reg(s
, rd
, tmp
);
8078 } else if (((insn
& 0x0e000000) == 0 &&
8079 (insn
& 0x00000090) != 0x90) ||
8080 ((insn
& 0x0e000000) == (1 << 25))) {
8081 int set_cc
, logic_cc
, shiftop
;
8083 op1
= (insn
>> 21) & 0xf;
8084 set_cc
= (insn
>> 20) & 1;
8085 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8087 /* data processing instruction */
8088 if (insn
& (1 << 25)) {
8089 /* immediate operand */
8091 shift
= ((insn
>> 8) & 0xf) * 2;
8093 val
= (val
>> shift
) | (val
<< (32 - shift
));
8095 tmp2
= tcg_temp_new_i32();
8096 tcg_gen_movi_i32(tmp2
, val
);
8097 if (logic_cc
&& shift
) {
8098 gen_set_CF_bit31(tmp2
);
8103 tmp2
= load_reg(s
, rm
);
8104 shiftop
= (insn
>> 5) & 3;
8105 if (!(insn
& (1 << 4))) {
8106 shift
= (insn
>> 7) & 0x1f;
8107 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8109 rs
= (insn
>> 8) & 0xf;
8110 tmp
= load_reg(s
, rs
);
8111 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8114 if (op1
!= 0x0f && op1
!= 0x0d) {
8115 rn
= (insn
>> 16) & 0xf;
8116 tmp
= load_reg(s
, rn
);
8118 TCGV_UNUSED_I32(tmp
);
8120 rd
= (insn
>> 12) & 0xf;
8123 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8127 store_reg_bx(s
, rd
, tmp
);
8130 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8134 store_reg_bx(s
, rd
, tmp
);
8137 if (set_cc
&& rd
== 15) {
8138 /* SUBS r15, ... is used for exception return. */
8142 gen_sub_CC(tmp
, tmp
, tmp2
);
8143 gen_exception_return(s
, tmp
);
8146 gen_sub_CC(tmp
, tmp
, tmp2
);
8148 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8150 store_reg_bx(s
, rd
, tmp
);
8155 gen_sub_CC(tmp
, tmp2
, tmp
);
8157 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8159 store_reg_bx(s
, rd
, tmp
);
8163 gen_add_CC(tmp
, tmp
, tmp2
);
8165 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8167 store_reg_bx(s
, rd
, tmp
);
8171 gen_adc_CC(tmp
, tmp
, tmp2
);
8173 gen_add_carry(tmp
, tmp
, tmp2
);
8175 store_reg_bx(s
, rd
, tmp
);
8179 gen_sbc_CC(tmp
, tmp
, tmp2
);
8181 gen_sub_carry(tmp
, tmp
, tmp2
);
8183 store_reg_bx(s
, rd
, tmp
);
8187 gen_sbc_CC(tmp
, tmp2
, tmp
);
8189 gen_sub_carry(tmp
, tmp2
, tmp
);
8191 store_reg_bx(s
, rd
, tmp
);
8195 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8198 tcg_temp_free_i32(tmp
);
8202 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8205 tcg_temp_free_i32(tmp
);
8209 gen_sub_CC(tmp
, tmp
, tmp2
);
8211 tcg_temp_free_i32(tmp
);
8215 gen_add_CC(tmp
, tmp
, tmp2
);
8217 tcg_temp_free_i32(tmp
);
8220 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8224 store_reg_bx(s
, rd
, tmp
);
8227 if (logic_cc
&& rd
== 15) {
8228 /* MOVS r15, ... is used for exception return. */
8232 gen_exception_return(s
, tmp2
);
8237 store_reg_bx(s
, rd
, tmp2
);
8241 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8245 store_reg_bx(s
, rd
, tmp
);
8249 tcg_gen_not_i32(tmp2
, tmp2
);
8253 store_reg_bx(s
, rd
, tmp2
);
8256 if (op1
!= 0x0f && op1
!= 0x0d) {
8257 tcg_temp_free_i32(tmp2
);
8260 /* other instructions */
8261 op1
= (insn
>> 24) & 0xf;
8265 /* multiplies, extra load/stores */
8266 sh
= (insn
>> 5) & 3;
8269 rd
= (insn
>> 16) & 0xf;
8270 rn
= (insn
>> 12) & 0xf;
8271 rs
= (insn
>> 8) & 0xf;
8273 op1
= (insn
>> 20) & 0xf;
8275 case 0: case 1: case 2: case 3: case 6:
8277 tmp
= load_reg(s
, rs
);
8278 tmp2
= load_reg(s
, rm
);
8279 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8280 tcg_temp_free_i32(tmp2
);
8281 if (insn
& (1 << 22)) {
8282 /* Subtract (mls) */
8284 tmp2
= load_reg(s
, rn
);
8285 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8286 tcg_temp_free_i32(tmp2
);
8287 } else if (insn
& (1 << 21)) {
8289 tmp2
= load_reg(s
, rn
);
8290 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8291 tcg_temp_free_i32(tmp2
);
8293 if (insn
& (1 << 20))
8295 store_reg(s
, rd
, tmp
);
8298 /* 64 bit mul double accumulate (UMAAL) */
8300 tmp
= load_reg(s
, rs
);
8301 tmp2
= load_reg(s
, rm
);
8302 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8303 gen_addq_lo(s
, tmp64
, rn
);
8304 gen_addq_lo(s
, tmp64
, rd
);
8305 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8306 tcg_temp_free_i64(tmp64
);
8308 case 8: case 9: case 10: case 11:
8309 case 12: case 13: case 14: case 15:
8310 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8311 tmp
= load_reg(s
, rs
);
8312 tmp2
= load_reg(s
, rm
);
8313 if (insn
& (1 << 22)) {
8314 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8316 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8318 if (insn
& (1 << 21)) { /* mult accumulate */
8319 TCGv_i32 al
= load_reg(s
, rn
);
8320 TCGv_i32 ah
= load_reg(s
, rd
);
8321 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8322 tcg_temp_free_i32(al
);
8323 tcg_temp_free_i32(ah
);
8325 if (insn
& (1 << 20)) {
8326 gen_logicq_cc(tmp
, tmp2
);
8328 store_reg(s
, rn
, tmp
);
8329 store_reg(s
, rd
, tmp2
);
8335 rn
= (insn
>> 16) & 0xf;
8336 rd
= (insn
>> 12) & 0xf;
8337 if (insn
& (1 << 23)) {
8338 /* load/store exclusive */
8339 int op2
= (insn
>> 8) & 3;
8340 op1
= (insn
>> 21) & 0x3;
8343 case 0: /* lda/stl */
8349 case 1: /* reserved */
8351 case 2: /* ldaex/stlex */
8354 case 3: /* ldrex/strex */
8363 addr
= tcg_temp_local_new_i32();
8364 load_reg_var(s
, addr
, rn
);
8366 /* Since the emulation does not have barriers,
8367 the acquire/release semantics need no special
8370 if (insn
& (1 << 20)) {
8371 tmp
= tcg_temp_new_i32();
8374 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8377 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8380 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8385 store_reg(s
, rd
, tmp
);
8388 tmp
= load_reg(s
, rm
);
8391 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8394 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8397 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8402 tcg_temp_free_i32(tmp
);
8404 } else if (insn
& (1 << 20)) {
8407 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8409 case 1: /* ldrexd */
8410 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8412 case 2: /* ldrexb */
8413 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8415 case 3: /* ldrexh */
8416 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8425 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8427 case 1: /* strexd */
8428 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8430 case 2: /* strexb */
8431 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8433 case 3: /* strexh */
8434 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8440 tcg_temp_free_i32(addr
);
8442 /* SWP instruction */
8445 /* ??? This is not really atomic. However we know
8446 we never have multiple CPUs running in parallel,
8447 so it is good enough. */
8448 addr
= load_reg(s
, rn
);
8449 tmp
= load_reg(s
, rm
);
8450 tmp2
= tcg_temp_new_i32();
8451 if (insn
& (1 << 22)) {
8452 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8453 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8455 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8456 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8458 tcg_temp_free_i32(tmp
);
8459 tcg_temp_free_i32(addr
);
8460 store_reg(s
, rd
, tmp2
);
8465 bool load
= insn
& (1 << 20);
8466 bool doubleword
= false;
8467 /* Misc load/store */
8468 rn
= (insn
>> 16) & 0xf;
8469 rd
= (insn
>> 12) & 0xf;
8471 if (!load
&& (sh
& 2)) {
8475 /* UNPREDICTABLE; we choose to UNDEF */
8478 load
= (sh
& 1) == 0;
8482 addr
= load_reg(s
, rn
);
8483 if (insn
& (1 << 24))
8484 gen_add_datah_offset(s
, insn
, 0, addr
);
8490 tmp
= load_reg(s
, rd
);
8491 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8492 tcg_temp_free_i32(tmp
);
8493 tcg_gen_addi_i32(addr
, addr
, 4);
8494 tmp
= load_reg(s
, rd
+ 1);
8495 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8496 tcg_temp_free_i32(tmp
);
8499 tmp
= tcg_temp_new_i32();
8500 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8501 store_reg(s
, rd
, tmp
);
8502 tcg_gen_addi_i32(addr
, addr
, 4);
8503 tmp
= tcg_temp_new_i32();
8504 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8507 address_offset
= -4;
8510 tmp
= tcg_temp_new_i32();
8513 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8516 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8520 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8525 tmp
= load_reg(s
, rd
);
8526 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8527 tcg_temp_free_i32(tmp
);
8529 /* Perform base writeback before the loaded value to
8530 ensure correct behavior with overlapping index registers.
8531 ldrd with base writeback is undefined if the
8532 destination and index registers overlap. */
8533 if (!(insn
& (1 << 24))) {
8534 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8535 store_reg(s
, rn
, addr
);
8536 } else if (insn
& (1 << 21)) {
8538 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8539 store_reg(s
, rn
, addr
);
8541 tcg_temp_free_i32(addr
);
8544 /* Complete the load. */
8545 store_reg(s
, rd
, tmp
);
8554 if (insn
& (1 << 4)) {
8556 /* Armv6 Media instructions. */
8558 rn
= (insn
>> 16) & 0xf;
8559 rd
= (insn
>> 12) & 0xf;
8560 rs
= (insn
>> 8) & 0xf;
8561 switch ((insn
>> 23) & 3) {
8562 case 0: /* Parallel add/subtract. */
8563 op1
= (insn
>> 20) & 7;
8564 tmp
= load_reg(s
, rn
);
8565 tmp2
= load_reg(s
, rm
);
8566 sh
= (insn
>> 5) & 7;
8567 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8569 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8570 tcg_temp_free_i32(tmp2
);
8571 store_reg(s
, rd
, tmp
);
8574 if ((insn
& 0x00700020) == 0) {
8575 /* Halfword pack. */
8576 tmp
= load_reg(s
, rn
);
8577 tmp2
= load_reg(s
, rm
);
8578 shift
= (insn
>> 7) & 0x1f;
8579 if (insn
& (1 << 6)) {
8583 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8584 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8585 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8589 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8590 tcg_gen_ext16u_i32(tmp
, tmp
);
8591 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8593 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8594 tcg_temp_free_i32(tmp2
);
8595 store_reg(s
, rd
, tmp
);
8596 } else if ((insn
& 0x00200020) == 0x00200000) {
8598 tmp
= load_reg(s
, rm
);
8599 shift
= (insn
>> 7) & 0x1f;
8600 if (insn
& (1 << 6)) {
8603 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8605 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8607 sh
= (insn
>> 16) & 0x1f;
8608 tmp2
= tcg_const_i32(sh
);
8609 if (insn
& (1 << 22))
8610 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8612 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8613 tcg_temp_free_i32(tmp2
);
8614 store_reg(s
, rd
, tmp
);
8615 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8617 tmp
= load_reg(s
, rm
);
8618 sh
= (insn
>> 16) & 0x1f;
8619 tmp2
= tcg_const_i32(sh
);
8620 if (insn
& (1 << 22))
8621 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8623 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8624 tcg_temp_free_i32(tmp2
);
8625 store_reg(s
, rd
, tmp
);
8626 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8628 tmp
= load_reg(s
, rn
);
8629 tmp2
= load_reg(s
, rm
);
8630 tmp3
= tcg_temp_new_i32();
8631 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8632 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8633 tcg_temp_free_i32(tmp3
);
8634 tcg_temp_free_i32(tmp2
);
8635 store_reg(s
, rd
, tmp
);
8636 } else if ((insn
& 0x000003e0) == 0x00000060) {
8637 tmp
= load_reg(s
, rm
);
8638 shift
= (insn
>> 10) & 3;
8639 /* ??? In many cases it's not necessary to do a
8640 rotate, a shift is sufficient. */
8642 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8643 op1
= (insn
>> 20) & 7;
8645 case 0: gen_sxtb16(tmp
); break;
8646 case 2: gen_sxtb(tmp
); break;
8647 case 3: gen_sxth(tmp
); break;
8648 case 4: gen_uxtb16(tmp
); break;
8649 case 6: gen_uxtb(tmp
); break;
8650 case 7: gen_uxth(tmp
); break;
8651 default: goto illegal_op
;
8654 tmp2
= load_reg(s
, rn
);
8655 if ((op1
& 3) == 0) {
8656 gen_add16(tmp
, tmp2
);
8658 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8659 tcg_temp_free_i32(tmp2
);
8662 store_reg(s
, rd
, tmp
);
8663 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8665 tmp
= load_reg(s
, rm
);
8666 if (insn
& (1 << 22)) {
8667 if (insn
& (1 << 7)) {
8671 gen_helper_rbit(tmp
, tmp
);
8674 if (insn
& (1 << 7))
8677 tcg_gen_bswap32_i32(tmp
, tmp
);
8679 store_reg(s
, rd
, tmp
);
8684 case 2: /* Multiplies (Type 3). */
8685 switch ((insn
>> 20) & 0x7) {
8687 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8688 /* op2 not 00x or 11x : UNDEF */
8691 /* Signed multiply most significant [accumulate].
8692 (SMMUL, SMMLA, SMMLS) */
8693 tmp
= load_reg(s
, rm
);
8694 tmp2
= load_reg(s
, rs
);
8695 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8698 tmp
= load_reg(s
, rd
);
8699 if (insn
& (1 << 6)) {
8700 tmp64
= gen_subq_msw(tmp64
, tmp
);
8702 tmp64
= gen_addq_msw(tmp64
, tmp
);
8705 if (insn
& (1 << 5)) {
8706 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8708 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8709 tmp
= tcg_temp_new_i32();
8710 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8711 tcg_temp_free_i64(tmp64
);
8712 store_reg(s
, rn
, tmp
);
8716 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8717 if (insn
& (1 << 7)) {
8720 tmp
= load_reg(s
, rm
);
8721 tmp2
= load_reg(s
, rs
);
8722 if (insn
& (1 << 5))
8723 gen_swap_half(tmp2
);
8724 gen_smul_dual(tmp
, tmp2
);
8725 if (insn
& (1 << 22)) {
8726 /* smlald, smlsld */
8729 tmp64
= tcg_temp_new_i64();
8730 tmp64_2
= tcg_temp_new_i64();
8731 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8732 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8733 tcg_temp_free_i32(tmp
);
8734 tcg_temp_free_i32(tmp2
);
8735 if (insn
& (1 << 6)) {
8736 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8738 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8740 tcg_temp_free_i64(tmp64_2
);
8741 gen_addq(s
, tmp64
, rd
, rn
);
8742 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8743 tcg_temp_free_i64(tmp64
);
8745 /* smuad, smusd, smlad, smlsd */
8746 if (insn
& (1 << 6)) {
8747 /* This subtraction cannot overflow. */
8748 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8750 /* This addition cannot overflow 32 bits;
8751 * however it may overflow considered as a
8752 * signed operation, in which case we must set
8755 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8757 tcg_temp_free_i32(tmp2
);
8760 tmp2
= load_reg(s
, rd
);
8761 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8762 tcg_temp_free_i32(tmp2
);
8764 store_reg(s
, rn
, tmp
);
8770 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
8773 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8776 tmp
= load_reg(s
, rm
);
8777 tmp2
= load_reg(s
, rs
);
8778 if (insn
& (1 << 21)) {
8779 gen_helper_udiv(tmp
, tmp
, tmp2
);
8781 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8783 tcg_temp_free_i32(tmp2
);
8784 store_reg(s
, rn
, tmp
);
8791 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8793 case 0: /* Unsigned sum of absolute differences. */
8795 tmp
= load_reg(s
, rm
);
8796 tmp2
= load_reg(s
, rs
);
8797 gen_helper_usad8(tmp
, tmp
, tmp2
);
8798 tcg_temp_free_i32(tmp2
);
8800 tmp2
= load_reg(s
, rd
);
8801 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8802 tcg_temp_free_i32(tmp2
);
8804 store_reg(s
, rn
, tmp
);
8806 case 0x20: case 0x24: case 0x28: case 0x2c:
8807 /* Bitfield insert/clear. */
8809 shift
= (insn
>> 7) & 0x1f;
8810 i
= (insn
>> 16) & 0x1f;
8812 /* UNPREDICTABLE; we choose to UNDEF */
8817 tmp
= tcg_temp_new_i32();
8818 tcg_gen_movi_i32(tmp
, 0);
8820 tmp
= load_reg(s
, rm
);
8823 tmp2
= load_reg(s
, rd
);
8824 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8825 tcg_temp_free_i32(tmp2
);
8827 store_reg(s
, rd
, tmp
);
8829 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8830 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8832 tmp
= load_reg(s
, rm
);
8833 shift
= (insn
>> 7) & 0x1f;
8834 i
= ((insn
>> 16) & 0x1f) + 1;
8839 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8841 gen_sbfx(tmp
, shift
, i
);
8844 store_reg(s
, rd
, tmp
);
8854 /* Check for undefined extension instructions
8855 * per the ARM Bible IE:
8856 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8858 sh
= (0xf << 20) | (0xf << 4);
8859 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8863 /* load/store byte/word */
8864 rn
= (insn
>> 16) & 0xf;
8865 rd
= (insn
>> 12) & 0xf;
8866 tmp2
= load_reg(s
, rn
);
8867 if ((insn
& 0x01200000) == 0x00200000) {
8869 i
= get_a32_user_mem_index(s
);
8871 i
= get_mem_index(s
);
8873 if (insn
& (1 << 24))
8874 gen_add_data_offset(s
, insn
, tmp2
);
8875 if (insn
& (1 << 20)) {
8877 tmp
= tcg_temp_new_i32();
8878 if (insn
& (1 << 22)) {
8879 gen_aa32_ld8u(tmp
, tmp2
, i
);
8881 gen_aa32_ld32u(tmp
, tmp2
, i
);
8885 tmp
= load_reg(s
, rd
);
8886 if (insn
& (1 << 22)) {
8887 gen_aa32_st8(tmp
, tmp2
, i
);
8889 gen_aa32_st32(tmp
, tmp2
, i
);
8891 tcg_temp_free_i32(tmp
);
8893 if (!(insn
& (1 << 24))) {
8894 gen_add_data_offset(s
, insn
, tmp2
);
8895 store_reg(s
, rn
, tmp2
);
8896 } else if (insn
& (1 << 21)) {
8897 store_reg(s
, rn
, tmp2
);
8899 tcg_temp_free_i32(tmp2
);
8901 if (insn
& (1 << 20)) {
8902 /* Complete the load. */
8903 store_reg_from_load(s
, rd
, tmp
);
8909 int j
, n
, loaded_base
;
8910 bool exc_return
= false;
8911 bool is_load
= extract32(insn
, 20, 1);
8913 TCGv_i32 loaded_var
;
8914 /* load/store multiple words */
8915 /* XXX: store correct base if write back */
8916 if (insn
& (1 << 22)) {
8917 /* LDM (user), LDM (exception return) and STM (user) */
8919 goto illegal_op
; /* only usable in supervisor mode */
8921 if (is_load
&& extract32(insn
, 15, 1)) {
8927 rn
= (insn
>> 16) & 0xf;
8928 addr
= load_reg(s
, rn
);
8930 /* compute total size */
8932 TCGV_UNUSED_I32(loaded_var
);
8935 if (insn
& (1 << i
))
8938 /* XXX: test invalid n == 0 case ? */
8939 if (insn
& (1 << 23)) {
8940 if (insn
& (1 << 24)) {
8942 tcg_gen_addi_i32(addr
, addr
, 4);
8944 /* post increment */
8947 if (insn
& (1 << 24)) {
8949 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8951 /* post decrement */
8953 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8958 if (insn
& (1 << i
)) {
8961 tmp
= tcg_temp_new_i32();
8962 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8964 tmp2
= tcg_const_i32(i
);
8965 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8966 tcg_temp_free_i32(tmp2
);
8967 tcg_temp_free_i32(tmp
);
8968 } else if (i
== rn
) {
8972 store_reg_from_load(s
, i
, tmp
);
8977 /* special case: r15 = PC + 8 */
8978 val
= (long)s
->pc
+ 4;
8979 tmp
= tcg_temp_new_i32();
8980 tcg_gen_movi_i32(tmp
, val
);
8982 tmp
= tcg_temp_new_i32();
8983 tmp2
= tcg_const_i32(i
);
8984 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8985 tcg_temp_free_i32(tmp2
);
8987 tmp
= load_reg(s
, i
);
8989 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8990 tcg_temp_free_i32(tmp
);
8993 /* no need to add after the last transfer */
8995 tcg_gen_addi_i32(addr
, addr
, 4);
8998 if (insn
& (1 << 21)) {
9000 if (insn
& (1 << 23)) {
9001 if (insn
& (1 << 24)) {
9004 /* post increment */
9005 tcg_gen_addi_i32(addr
, addr
, 4);
9008 if (insn
& (1 << 24)) {
9011 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9013 /* post decrement */
9014 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9017 store_reg(s
, rn
, addr
);
9019 tcg_temp_free_i32(addr
);
9022 store_reg(s
, rn
, loaded_var
);
9025 /* Restore CPSR from SPSR. */
9026 tmp
= load_cpu_field(spsr
);
9027 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
9028 tcg_temp_free_i32(tmp
);
9029 s
->is_jmp
= DISAS_UPDATE
;
9038 /* branch (and link) */
9039 val
= (int32_t)s
->pc
;
9040 if (insn
& (1 << 24)) {
9041 tmp
= tcg_temp_new_i32();
9042 tcg_gen_movi_i32(tmp
, val
);
9043 store_reg(s
, 14, tmp
);
9045 offset
= sextract32(insn
<< 2, 0, 26);
9053 if (((insn
>> 8) & 0xe) == 10) {
9055 if (disas_vfp_insn(s
, insn
)) {
9058 } else if (disas_coproc_insn(s
, insn
)) {
9065 gen_set_pc_im(s
, s
->pc
);
9066 s
->svc_imm
= extract32(insn
, 0, 24);
9067 s
->is_jmp
= DISAS_SWI
;
9071 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9072 default_exception_el(s
));
9078 /* Return true if this is a Thumb-2 logical op. */
9080 thumb2_logic_op(int op
)
9085 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9086 then set condition code flags based on the result of the operation.
9087 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9088 to the high bit of T1.
9089 Returns zero if the opcode is valid. */
9092 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9093 TCGv_i32 t0
, TCGv_i32 t1
)
9100 tcg_gen_and_i32(t0
, t0
, t1
);
9104 tcg_gen_andc_i32(t0
, t0
, t1
);
9108 tcg_gen_or_i32(t0
, t0
, t1
);
9112 tcg_gen_orc_i32(t0
, t0
, t1
);
9116 tcg_gen_xor_i32(t0
, t0
, t1
);
9121 gen_add_CC(t0
, t0
, t1
);
9123 tcg_gen_add_i32(t0
, t0
, t1
);
9127 gen_adc_CC(t0
, t0
, t1
);
9133 gen_sbc_CC(t0
, t0
, t1
);
9135 gen_sub_carry(t0
, t0
, t1
);
9140 gen_sub_CC(t0
, t0
, t1
);
9142 tcg_gen_sub_i32(t0
, t0
, t1
);
9146 gen_sub_CC(t0
, t1
, t0
);
9148 tcg_gen_sub_i32(t0
, t1
, t0
);
9150 default: /* 5, 6, 7, 9, 12, 15. */
9156 gen_set_CF_bit31(t1
);
9161 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9163 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9165 uint32_t insn
, imm
, shift
, offset
;
9166 uint32_t rd
, rn
, rm
, rs
;
9177 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9178 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9179 /* Thumb-1 cores may need to treat bl and blx as a pair of
9180 16-bit instructions to get correct prefetch abort behavior. */
9182 if ((insn
& (1 << 12)) == 0) {
9184 /* Second half of blx. */
9185 offset
= ((insn
& 0x7ff) << 1);
9186 tmp
= load_reg(s
, 14);
9187 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9188 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9190 tmp2
= tcg_temp_new_i32();
9191 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9192 store_reg(s
, 14, tmp2
);
9196 if (insn
& (1 << 11)) {
9197 /* Second half of bl. */
9198 offset
= ((insn
& 0x7ff) << 1) | 1;
9199 tmp
= load_reg(s
, 14);
9200 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9202 tmp2
= tcg_temp_new_i32();
9203 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9204 store_reg(s
, 14, tmp2
);
9208 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9209 /* Instruction spans a page boundary. Implement it as two
9210 16-bit instructions in case the second half causes an
9212 offset
= ((int32_t)insn
<< 21) >> 9;
9213 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9216 /* Fall through to 32-bit decode. */
9219 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9221 insn
|= (uint32_t)insn_hw1
<< 16;
9223 if ((insn
& 0xf800e800) != 0xf000e800) {
9227 rn
= (insn
>> 16) & 0xf;
9228 rs
= (insn
>> 12) & 0xf;
9229 rd
= (insn
>> 8) & 0xf;
9231 switch ((insn
>> 25) & 0xf) {
9232 case 0: case 1: case 2: case 3:
9233 /* 16-bit instructions. Should never happen. */
9236 if (insn
& (1 << 22)) {
9237 /* Other load/store, table branch. */
9238 if (insn
& 0x01200000) {
9239 ARCH(5); /* Load/store doubleword. */
9241 addr
= tcg_temp_new_i32();
9242 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9244 addr
= load_reg(s
, rn
);
9246 offset
= (insn
& 0xff) * 4;
9247 if ((insn
& (1 << 23)) == 0)
9249 if (insn
& (1 << 24)) {
9250 tcg_gen_addi_i32(addr
, addr
, offset
);
9253 if (insn
& (1 << 20)) {
9255 tmp
= tcg_temp_new_i32();
9256 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9257 store_reg(s
, rs
, tmp
);
9258 tcg_gen_addi_i32(addr
, addr
, 4);
9259 tmp
= tcg_temp_new_i32();
9260 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9261 store_reg(s
, rd
, tmp
);
9264 tmp
= load_reg(s
, rs
);
9265 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9266 tcg_temp_free_i32(tmp
);
9267 tcg_gen_addi_i32(addr
, addr
, 4);
9268 tmp
= load_reg(s
, rd
);
9269 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9270 tcg_temp_free_i32(tmp
);
9272 if (insn
& (1 << 21)) {
9273 /* Base writeback. */
9276 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9277 store_reg(s
, rn
, addr
);
9279 tcg_temp_free_i32(addr
);
9281 } else if ((insn
& (1 << 23)) == 0) {
9282 /* Load/store exclusive word. */
9283 addr
= tcg_temp_local_new_i32();
9284 load_reg_var(s
, addr
, rn
);
9285 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9286 if (insn
& (1 << 20)) {
9287 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9289 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9291 tcg_temp_free_i32(addr
);
9292 } else if ((insn
& (7 << 5)) == 0) {
9295 addr
= tcg_temp_new_i32();
9296 tcg_gen_movi_i32(addr
, s
->pc
);
9298 addr
= load_reg(s
, rn
);
9300 tmp
= load_reg(s
, rm
);
9301 tcg_gen_add_i32(addr
, addr
, tmp
);
9302 if (insn
& (1 << 4)) {
9304 tcg_gen_add_i32(addr
, addr
, tmp
);
9305 tcg_temp_free_i32(tmp
);
9306 tmp
= tcg_temp_new_i32();
9307 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9309 tcg_temp_free_i32(tmp
);
9310 tmp
= tcg_temp_new_i32();
9311 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9313 tcg_temp_free_i32(addr
);
9314 tcg_gen_shli_i32(tmp
, tmp
, 1);
9315 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9316 store_reg(s
, 15, tmp
);
9318 int op2
= (insn
>> 6) & 0x3;
9319 op
= (insn
>> 4) & 0x3;
9324 /* Load/store exclusive byte/halfword/doubleword */
9331 /* Load-acquire/store-release */
9337 /* Load-acquire/store-release exclusive */
9341 addr
= tcg_temp_local_new_i32();
9342 load_reg_var(s
, addr
, rn
);
9344 if (insn
& (1 << 20)) {
9345 tmp
= tcg_temp_new_i32();
9348 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9351 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9354 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9359 store_reg(s
, rs
, tmp
);
9361 tmp
= load_reg(s
, rs
);
9364 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9367 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9370 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9375 tcg_temp_free_i32(tmp
);
9377 } else if (insn
& (1 << 20)) {
9378 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9380 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9382 tcg_temp_free_i32(addr
);
9385 /* Load/store multiple, RFE, SRS. */
9386 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9387 /* RFE, SRS: not available in user mode or on M profile */
9388 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9391 if (insn
& (1 << 20)) {
9393 addr
= load_reg(s
, rn
);
9394 if ((insn
& (1 << 24)) == 0)
9395 tcg_gen_addi_i32(addr
, addr
, -8);
9396 /* Load PC into tmp and CPSR into tmp2. */
9397 tmp
= tcg_temp_new_i32();
9398 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9399 tcg_gen_addi_i32(addr
, addr
, 4);
9400 tmp2
= tcg_temp_new_i32();
9401 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9402 if (insn
& (1 << 21)) {
9403 /* Base writeback. */
9404 if (insn
& (1 << 24)) {
9405 tcg_gen_addi_i32(addr
, addr
, 4);
9407 tcg_gen_addi_i32(addr
, addr
, -4);
9409 store_reg(s
, rn
, addr
);
9411 tcg_temp_free_i32(addr
);
9413 gen_rfe(s
, tmp
, tmp2
);
9416 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9420 int i
, loaded_base
= 0;
9421 TCGv_i32 loaded_var
;
9422 /* Load/store multiple. */
9423 addr
= load_reg(s
, rn
);
9425 for (i
= 0; i
< 16; i
++) {
9426 if (insn
& (1 << i
))
9429 if (insn
& (1 << 24)) {
9430 tcg_gen_addi_i32(addr
, addr
, -offset
);
9433 TCGV_UNUSED_I32(loaded_var
);
9434 for (i
= 0; i
< 16; i
++) {
9435 if ((insn
& (1 << i
)) == 0)
9437 if (insn
& (1 << 20)) {
9439 tmp
= tcg_temp_new_i32();
9440 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9443 } else if (i
== rn
) {
9447 store_reg(s
, i
, tmp
);
9451 tmp
= load_reg(s
, i
);
9452 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9453 tcg_temp_free_i32(tmp
);
9455 tcg_gen_addi_i32(addr
, addr
, 4);
9458 store_reg(s
, rn
, loaded_var
);
9460 if (insn
& (1 << 21)) {
9461 /* Base register writeback. */
9462 if (insn
& (1 << 24)) {
9463 tcg_gen_addi_i32(addr
, addr
, -offset
);
9465 /* Fault if writeback register is in register list. */
9466 if (insn
& (1 << rn
))
9468 store_reg(s
, rn
, addr
);
9470 tcg_temp_free_i32(addr
);
9477 op
= (insn
>> 21) & 0xf;
9479 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9482 /* Halfword pack. */
9483 tmp
= load_reg(s
, rn
);
9484 tmp2
= load_reg(s
, rm
);
9485 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9486 if (insn
& (1 << 5)) {
9490 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9491 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9492 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9496 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9497 tcg_gen_ext16u_i32(tmp
, tmp
);
9498 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9500 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9501 tcg_temp_free_i32(tmp2
);
9502 store_reg(s
, rd
, tmp
);
9504 /* Data processing register constant shift. */
9506 tmp
= tcg_temp_new_i32();
9507 tcg_gen_movi_i32(tmp
, 0);
9509 tmp
= load_reg(s
, rn
);
9511 tmp2
= load_reg(s
, rm
);
9513 shiftop
= (insn
>> 4) & 3;
9514 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9515 conds
= (insn
& (1 << 20)) != 0;
9516 logic_cc
= (conds
&& thumb2_logic_op(op
));
9517 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9518 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9520 tcg_temp_free_i32(tmp2
);
9522 store_reg(s
, rd
, tmp
);
9524 tcg_temp_free_i32(tmp
);
9528 case 13: /* Misc data processing. */
9529 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9530 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9533 case 0: /* Register controlled shift. */
9534 tmp
= load_reg(s
, rn
);
9535 tmp2
= load_reg(s
, rm
);
9536 if ((insn
& 0x70) != 0)
9538 op
= (insn
>> 21) & 3;
9539 logic_cc
= (insn
& (1 << 20)) != 0;
9540 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9543 store_reg_bx(s
, rd
, tmp
);
9545 case 1: /* Sign/zero extend. */
9546 op
= (insn
>> 20) & 7;
9548 case 0: /* SXTAH, SXTH */
9549 case 1: /* UXTAH, UXTH */
9550 case 4: /* SXTAB, SXTB */
9551 case 5: /* UXTAB, UXTB */
9553 case 2: /* SXTAB16, SXTB16 */
9554 case 3: /* UXTAB16, UXTB16 */
9555 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9563 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9567 tmp
= load_reg(s
, rm
);
9568 shift
= (insn
>> 4) & 3;
9569 /* ??? In many cases it's not necessary to do a
9570 rotate, a shift is sufficient. */
9572 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9573 op
= (insn
>> 20) & 7;
9575 case 0: gen_sxth(tmp
); break;
9576 case 1: gen_uxth(tmp
); break;
9577 case 2: gen_sxtb16(tmp
); break;
9578 case 3: gen_uxtb16(tmp
); break;
9579 case 4: gen_sxtb(tmp
); break;
9580 case 5: gen_uxtb(tmp
); break;
9582 g_assert_not_reached();
9585 tmp2
= load_reg(s
, rn
);
9586 if ((op
>> 1) == 1) {
9587 gen_add16(tmp
, tmp2
);
9589 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9590 tcg_temp_free_i32(tmp2
);
9593 store_reg(s
, rd
, tmp
);
9595 case 2: /* SIMD add/subtract. */
9596 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9599 op
= (insn
>> 20) & 7;
9600 shift
= (insn
>> 4) & 7;
9601 if ((op
& 3) == 3 || (shift
& 3) == 3)
9603 tmp
= load_reg(s
, rn
);
9604 tmp2
= load_reg(s
, rm
);
9605 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9606 tcg_temp_free_i32(tmp2
);
9607 store_reg(s
, rd
, tmp
);
9609 case 3: /* Other data processing. */
9610 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9612 /* Saturating add/subtract. */
9613 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9616 tmp
= load_reg(s
, rn
);
9617 tmp2
= load_reg(s
, rm
);
9619 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9621 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9623 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9624 tcg_temp_free_i32(tmp2
);
9627 case 0x0a: /* rbit */
9628 case 0x08: /* rev */
9629 case 0x09: /* rev16 */
9630 case 0x0b: /* revsh */
9631 case 0x18: /* clz */
9633 case 0x10: /* sel */
9634 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9638 case 0x20: /* crc32/crc32c */
9644 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
9651 tmp
= load_reg(s
, rn
);
9653 case 0x0a: /* rbit */
9654 gen_helper_rbit(tmp
, tmp
);
9656 case 0x08: /* rev */
9657 tcg_gen_bswap32_i32(tmp
, tmp
);
9659 case 0x09: /* rev16 */
9662 case 0x0b: /* revsh */
9665 case 0x10: /* sel */
9666 tmp2
= load_reg(s
, rm
);
9667 tmp3
= tcg_temp_new_i32();
9668 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9669 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9670 tcg_temp_free_i32(tmp3
);
9671 tcg_temp_free_i32(tmp2
);
9673 case 0x18: /* clz */
9674 gen_helper_clz(tmp
, tmp
);
9684 uint32_t sz
= op
& 0x3;
9685 uint32_t c
= op
& 0x8;
9687 tmp2
= load_reg(s
, rm
);
9689 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9690 } else if (sz
== 1) {
9691 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9693 tmp3
= tcg_const_i32(1 << sz
);
9695 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9697 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9699 tcg_temp_free_i32(tmp2
);
9700 tcg_temp_free_i32(tmp3
);
9704 g_assert_not_reached();
9707 store_reg(s
, rd
, tmp
);
9709 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9710 switch ((insn
>> 20) & 7) {
9711 case 0: /* 32 x 32 -> 32 */
9712 case 7: /* Unsigned sum of absolute differences. */
9714 case 1: /* 16 x 16 -> 32 */
9715 case 2: /* Dual multiply add. */
9716 case 3: /* 32 * 16 -> 32msb */
9717 case 4: /* Dual multiply subtract. */
9718 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9719 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9724 op
= (insn
>> 4) & 0xf;
9725 tmp
= load_reg(s
, rn
);
9726 tmp2
= load_reg(s
, rm
);
9727 switch ((insn
>> 20) & 7) {
9728 case 0: /* 32 x 32 -> 32 */
9729 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9730 tcg_temp_free_i32(tmp2
);
9732 tmp2
= load_reg(s
, rs
);
9734 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9736 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9737 tcg_temp_free_i32(tmp2
);
9740 case 1: /* 16 x 16 -> 32 */
9741 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9742 tcg_temp_free_i32(tmp2
);
9744 tmp2
= load_reg(s
, rs
);
9745 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9746 tcg_temp_free_i32(tmp2
);
9749 case 2: /* Dual multiply add. */
9750 case 4: /* Dual multiply subtract. */
9752 gen_swap_half(tmp2
);
9753 gen_smul_dual(tmp
, tmp2
);
9754 if (insn
& (1 << 22)) {
9755 /* This subtraction cannot overflow. */
9756 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9758 /* This addition cannot overflow 32 bits;
9759 * however it may overflow considered as a signed
9760 * operation, in which case we must set the Q flag.
9762 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9764 tcg_temp_free_i32(tmp2
);
9767 tmp2
= load_reg(s
, rs
);
9768 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9769 tcg_temp_free_i32(tmp2
);
9772 case 3: /* 32 * 16 -> 32msb */
9774 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9777 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9778 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9779 tmp
= tcg_temp_new_i32();
9780 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9781 tcg_temp_free_i64(tmp64
);
9784 tmp2
= load_reg(s
, rs
);
9785 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9786 tcg_temp_free_i32(tmp2
);
9789 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9790 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9792 tmp
= load_reg(s
, rs
);
9793 if (insn
& (1 << 20)) {
9794 tmp64
= gen_addq_msw(tmp64
, tmp
);
9796 tmp64
= gen_subq_msw(tmp64
, tmp
);
9799 if (insn
& (1 << 4)) {
9800 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9802 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9803 tmp
= tcg_temp_new_i32();
9804 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9805 tcg_temp_free_i64(tmp64
);
9807 case 7: /* Unsigned sum of absolute differences. */
9808 gen_helper_usad8(tmp
, tmp
, tmp2
);
9809 tcg_temp_free_i32(tmp2
);
9811 tmp2
= load_reg(s
, rs
);
9812 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9813 tcg_temp_free_i32(tmp2
);
9817 store_reg(s
, rd
, tmp
);
9819 case 6: case 7: /* 64-bit multiply, Divide. */
9820 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9821 tmp
= load_reg(s
, rn
);
9822 tmp2
= load_reg(s
, rm
);
9823 if ((op
& 0x50) == 0x10) {
9825 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
9829 gen_helper_udiv(tmp
, tmp
, tmp2
);
9831 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9832 tcg_temp_free_i32(tmp2
);
9833 store_reg(s
, rd
, tmp
);
9834 } else if ((op
& 0xe) == 0xc) {
9835 /* Dual multiply accumulate long. */
9836 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9837 tcg_temp_free_i32(tmp
);
9838 tcg_temp_free_i32(tmp2
);
9842 gen_swap_half(tmp2
);
9843 gen_smul_dual(tmp
, tmp2
);
9845 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9847 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9849 tcg_temp_free_i32(tmp2
);
9851 tmp64
= tcg_temp_new_i64();
9852 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9853 tcg_temp_free_i32(tmp
);
9854 gen_addq(s
, tmp64
, rs
, rd
);
9855 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9856 tcg_temp_free_i64(tmp64
);
9859 /* Unsigned 64-bit multiply */
9860 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9864 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9865 tcg_temp_free_i32(tmp2
);
9866 tcg_temp_free_i32(tmp
);
9869 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9870 tcg_temp_free_i32(tmp2
);
9871 tmp64
= tcg_temp_new_i64();
9872 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9873 tcg_temp_free_i32(tmp
);
9875 /* Signed 64-bit multiply */
9876 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9881 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9882 tcg_temp_free_i64(tmp64
);
9885 gen_addq_lo(s
, tmp64
, rs
);
9886 gen_addq_lo(s
, tmp64
, rd
);
9887 } else if (op
& 0x40) {
9888 /* 64-bit accumulate. */
9889 gen_addq(s
, tmp64
, rs
, rd
);
9891 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9892 tcg_temp_free_i64(tmp64
);
9897 case 6: case 7: case 14: case 15:
9899 if (((insn
>> 24) & 3) == 3) {
9900 /* Translate into the equivalent ARM encoding. */
9901 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9902 if (disas_neon_data_insn(s
, insn
)) {
9905 } else if (((insn
>> 8) & 0xe) == 10) {
9906 if (disas_vfp_insn(s
, insn
)) {
9910 if (insn
& (1 << 28))
9912 if (disas_coproc_insn(s
, insn
)) {
9917 case 8: case 9: case 10: case 11:
9918 if (insn
& (1 << 15)) {
9919 /* Branches, misc control. */
9920 if (insn
& 0x5000) {
9921 /* Unconditional branch. */
9922 /* signextend(hw1[10:0]) -> offset[:12]. */
9923 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9924 /* hw1[10:0] -> offset[11:1]. */
9925 offset
|= (insn
& 0x7ff) << 1;
9926 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9927 offset[24:22] already have the same value because of the
9928 sign extension above. */
9929 offset
^= ((~insn
) & (1 << 13)) << 10;
9930 offset
^= ((~insn
) & (1 << 11)) << 11;
9932 if (insn
& (1 << 14)) {
9933 /* Branch and link. */
9934 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9938 if (insn
& (1 << 12)) {
9943 offset
&= ~(uint32_t)2;
9944 /* thumb2 bx, no need to check */
9945 gen_bx_im(s
, offset
);
9947 } else if (((insn
>> 23) & 7) == 7) {
9949 if (insn
& (1 << 13))
9952 if (insn
& (1 << 26)) {
9953 if (!(insn
& (1 << 20))) {
9954 /* Hypervisor call (v7) */
9955 int imm16
= extract32(insn
, 16, 4) << 12
9956 | extract32(insn
, 0, 12);
9963 /* Secure monitor call (v6+) */
9971 op
= (insn
>> 20) & 7;
9973 case 0: /* msr cpsr. */
9974 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9975 tmp
= load_reg(s
, rn
);
9976 addr
= tcg_const_i32(insn
& 0xff);
9977 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9978 tcg_temp_free_i32(addr
);
9979 tcg_temp_free_i32(tmp
);
9984 case 1: /* msr spsr. */
9985 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9988 tmp
= load_reg(s
, rn
);
9990 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
9994 case 2: /* cps, nop-hint. */
9995 if (((insn
>> 8) & 7) == 0) {
9996 gen_nop_hint(s
, insn
& 0xff);
9998 /* Implemented as NOP in user mode. */
10003 if (insn
& (1 << 10)) {
10004 if (insn
& (1 << 7))
10006 if (insn
& (1 << 6))
10008 if (insn
& (1 << 5))
10010 if (insn
& (1 << 9))
10011 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10013 if (insn
& (1 << 8)) {
10015 imm
|= (insn
& 0x1f);
10018 gen_set_psr_im(s
, offset
, 0, imm
);
10021 case 3: /* Special control operations. */
10023 op
= (insn
>> 4) & 0xf;
10025 case 2: /* clrex */
10031 /* These execute as NOPs. */
10038 /* Trivial implementation equivalent to bx. */
10039 tmp
= load_reg(s
, rn
);
10042 case 5: /* Exception return. */
10046 if (rn
!= 14 || rd
!= 15) {
10049 tmp
= load_reg(s
, rn
);
10050 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10051 gen_exception_return(s
, tmp
);
10053 case 6: /* mrs cpsr. */
10054 tmp
= tcg_temp_new_i32();
10055 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10056 addr
= tcg_const_i32(insn
& 0xff);
10057 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10058 tcg_temp_free_i32(addr
);
10060 gen_helper_cpsr_read(tmp
, cpu_env
);
10062 store_reg(s
, rd
, tmp
);
10064 case 7: /* mrs spsr. */
10065 /* Not accessible in user mode. */
10066 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10069 tmp
= load_cpu_field(spsr
);
10070 store_reg(s
, rd
, tmp
);
10075 /* Conditional branch. */
10076 op
= (insn
>> 22) & 0xf;
10077 /* Generate a conditional jump to next instruction. */
10078 s
->condlabel
= gen_new_label();
10079 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10082 /* offset[11:1] = insn[10:0] */
10083 offset
= (insn
& 0x7ff) << 1;
10084 /* offset[17:12] = insn[21:16]. */
10085 offset
|= (insn
& 0x003f0000) >> 4;
10086 /* offset[31:20] = insn[26]. */
10087 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10088 /* offset[18] = insn[13]. */
10089 offset
|= (insn
& (1 << 13)) << 5;
10090 /* offset[19] = insn[11]. */
10091 offset
|= (insn
& (1 << 11)) << 8;
10093 /* jump to the offset */
10094 gen_jmp(s
, s
->pc
+ offset
);
10097 /* Data processing immediate. */
10098 if (insn
& (1 << 25)) {
10099 if (insn
& (1 << 24)) {
10100 if (insn
& (1 << 20))
10102 /* Bitfield/Saturate. */
10103 op
= (insn
>> 21) & 7;
10105 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10107 tmp
= tcg_temp_new_i32();
10108 tcg_gen_movi_i32(tmp
, 0);
10110 tmp
= load_reg(s
, rn
);
10113 case 2: /* Signed bitfield extract. */
10115 if (shift
+ imm
> 32)
10118 gen_sbfx(tmp
, shift
, imm
);
10120 case 6: /* Unsigned bitfield extract. */
10122 if (shift
+ imm
> 32)
10125 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
10127 case 3: /* Bitfield insert/clear. */
10130 imm
= imm
+ 1 - shift
;
10132 tmp2
= load_reg(s
, rd
);
10133 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10134 tcg_temp_free_i32(tmp2
);
10139 default: /* Saturate. */
10142 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10144 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10146 tmp2
= tcg_const_i32(imm
);
10149 if ((op
& 1) && shift
== 0) {
10150 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10151 tcg_temp_free_i32(tmp
);
10152 tcg_temp_free_i32(tmp2
);
10155 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10157 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10161 if ((op
& 1) && shift
== 0) {
10162 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10163 tcg_temp_free_i32(tmp
);
10164 tcg_temp_free_i32(tmp2
);
10167 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10169 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10172 tcg_temp_free_i32(tmp2
);
10175 store_reg(s
, rd
, tmp
);
10177 imm
= ((insn
& 0x04000000) >> 15)
10178 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10179 if (insn
& (1 << 22)) {
10180 /* 16-bit immediate. */
10181 imm
|= (insn
>> 4) & 0xf000;
10182 if (insn
& (1 << 23)) {
10184 tmp
= load_reg(s
, rd
);
10185 tcg_gen_ext16u_i32(tmp
, tmp
);
10186 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10189 tmp
= tcg_temp_new_i32();
10190 tcg_gen_movi_i32(tmp
, imm
);
10193 /* Add/sub 12-bit immediate. */
10195 offset
= s
->pc
& ~(uint32_t)3;
10196 if (insn
& (1 << 23))
10200 tmp
= tcg_temp_new_i32();
10201 tcg_gen_movi_i32(tmp
, offset
);
10203 tmp
= load_reg(s
, rn
);
10204 if (insn
& (1 << 23))
10205 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10207 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10210 store_reg(s
, rd
, tmp
);
10213 int shifter_out
= 0;
10214 /* modified 12-bit immediate. */
10215 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10216 imm
= (insn
& 0xff);
10219 /* Nothing to do. */
10221 case 1: /* 00XY00XY */
10224 case 2: /* XY00XY00 */
10228 case 3: /* XYXYXYXY */
10232 default: /* Rotated constant. */
10233 shift
= (shift
<< 1) | (imm
>> 7);
10235 imm
= imm
<< (32 - shift
);
10239 tmp2
= tcg_temp_new_i32();
10240 tcg_gen_movi_i32(tmp2
, imm
);
10241 rn
= (insn
>> 16) & 0xf;
10243 tmp
= tcg_temp_new_i32();
10244 tcg_gen_movi_i32(tmp
, 0);
10246 tmp
= load_reg(s
, rn
);
10248 op
= (insn
>> 21) & 0xf;
10249 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10250 shifter_out
, tmp
, tmp2
))
10252 tcg_temp_free_i32(tmp2
);
10253 rd
= (insn
>> 8) & 0xf;
10255 store_reg(s
, rd
, tmp
);
10257 tcg_temp_free_i32(tmp
);
10262 case 12: /* Load/store single data item. */
10267 if ((insn
& 0x01100000) == 0x01000000) {
10268 if (disas_neon_ls_insn(s
, insn
)) {
10273 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10275 if (!(insn
& (1 << 20))) {
10279 /* Byte or halfword load space with dest == r15 : memory hints.
10280 * Catch them early so we don't emit pointless addressing code.
10281 * This space is a mix of:
10282 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10283 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10285 * unallocated hints, which must be treated as NOPs
10286 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10287 * which is easiest for the decoding logic
10288 * Some space which must UNDEF
10290 int op1
= (insn
>> 23) & 3;
10291 int op2
= (insn
>> 6) & 0x3f;
10296 /* UNPREDICTABLE, unallocated hint or
10297 * PLD/PLDW/PLI (literal)
10302 return 0; /* PLD/PLDW/PLI or unallocated hint */
10304 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10305 return 0; /* PLD/PLDW/PLI or unallocated hint */
10307 /* UNDEF space, or an UNPREDICTABLE */
10311 memidx
= get_mem_index(s
);
10313 addr
= tcg_temp_new_i32();
10315 /* s->pc has already been incremented by 4. */
10316 imm
= s
->pc
& 0xfffffffc;
10317 if (insn
& (1 << 23))
10318 imm
+= insn
& 0xfff;
10320 imm
-= insn
& 0xfff;
10321 tcg_gen_movi_i32(addr
, imm
);
10323 addr
= load_reg(s
, rn
);
10324 if (insn
& (1 << 23)) {
10325 /* Positive offset. */
10326 imm
= insn
& 0xfff;
10327 tcg_gen_addi_i32(addr
, addr
, imm
);
10330 switch ((insn
>> 8) & 0xf) {
10331 case 0x0: /* Shifted Register. */
10332 shift
= (insn
>> 4) & 0xf;
10334 tcg_temp_free_i32(addr
);
10337 tmp
= load_reg(s
, rm
);
10339 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10340 tcg_gen_add_i32(addr
, addr
, tmp
);
10341 tcg_temp_free_i32(tmp
);
10343 case 0xc: /* Negative offset. */
10344 tcg_gen_addi_i32(addr
, addr
, -imm
);
10346 case 0xe: /* User privilege. */
10347 tcg_gen_addi_i32(addr
, addr
, imm
);
10348 memidx
= get_a32_user_mem_index(s
);
10350 case 0x9: /* Post-decrement. */
10352 /* Fall through. */
10353 case 0xb: /* Post-increment. */
10357 case 0xd: /* Pre-decrement. */
10359 /* Fall through. */
10360 case 0xf: /* Pre-increment. */
10361 tcg_gen_addi_i32(addr
, addr
, imm
);
10365 tcg_temp_free_i32(addr
);
10370 if (insn
& (1 << 20)) {
10372 tmp
= tcg_temp_new_i32();
10375 gen_aa32_ld8u(tmp
, addr
, memidx
);
10378 gen_aa32_ld8s(tmp
, addr
, memidx
);
10381 gen_aa32_ld16u(tmp
, addr
, memidx
);
10384 gen_aa32_ld16s(tmp
, addr
, memidx
);
10387 gen_aa32_ld32u(tmp
, addr
, memidx
);
10390 tcg_temp_free_i32(tmp
);
10391 tcg_temp_free_i32(addr
);
10397 store_reg(s
, rs
, tmp
);
10401 tmp
= load_reg(s
, rs
);
10404 gen_aa32_st8(tmp
, addr
, memidx
);
10407 gen_aa32_st16(tmp
, addr
, memidx
);
10410 gen_aa32_st32(tmp
, addr
, memidx
);
10413 tcg_temp_free_i32(tmp
);
10414 tcg_temp_free_i32(addr
);
10417 tcg_temp_free_i32(tmp
);
10420 tcg_gen_addi_i32(addr
, addr
, imm
);
10422 store_reg(s
, rn
, addr
);
10424 tcg_temp_free_i32(addr
);
10436 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10438 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10445 if (s
->condexec_mask
) {
10446 cond
= s
->condexec_cond
;
10447 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10448 s
->condlabel
= gen_new_label();
10449 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10454 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10457 switch (insn
>> 12) {
10461 op
= (insn
>> 11) & 3;
10464 rn
= (insn
>> 3) & 7;
10465 tmp
= load_reg(s
, rn
);
10466 if (insn
& (1 << 10)) {
10468 tmp2
= tcg_temp_new_i32();
10469 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10472 rm
= (insn
>> 6) & 7;
10473 tmp2
= load_reg(s
, rm
);
10475 if (insn
& (1 << 9)) {
10476 if (s
->condexec_mask
)
10477 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10479 gen_sub_CC(tmp
, tmp
, tmp2
);
10481 if (s
->condexec_mask
)
10482 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10484 gen_add_CC(tmp
, tmp
, tmp2
);
10486 tcg_temp_free_i32(tmp2
);
10487 store_reg(s
, rd
, tmp
);
10489 /* shift immediate */
10490 rm
= (insn
>> 3) & 7;
10491 shift
= (insn
>> 6) & 0x1f;
10492 tmp
= load_reg(s
, rm
);
10493 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10494 if (!s
->condexec_mask
)
10496 store_reg(s
, rd
, tmp
);
10500 /* arithmetic large immediate */
10501 op
= (insn
>> 11) & 3;
10502 rd
= (insn
>> 8) & 0x7;
10503 if (op
== 0) { /* mov */
10504 tmp
= tcg_temp_new_i32();
10505 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10506 if (!s
->condexec_mask
)
10508 store_reg(s
, rd
, tmp
);
10510 tmp
= load_reg(s
, rd
);
10511 tmp2
= tcg_temp_new_i32();
10512 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10515 gen_sub_CC(tmp
, tmp
, tmp2
);
10516 tcg_temp_free_i32(tmp
);
10517 tcg_temp_free_i32(tmp2
);
10520 if (s
->condexec_mask
)
10521 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10523 gen_add_CC(tmp
, tmp
, tmp2
);
10524 tcg_temp_free_i32(tmp2
);
10525 store_reg(s
, rd
, tmp
);
10528 if (s
->condexec_mask
)
10529 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10531 gen_sub_CC(tmp
, tmp
, tmp2
);
10532 tcg_temp_free_i32(tmp2
);
10533 store_reg(s
, rd
, tmp
);
10539 if (insn
& (1 << 11)) {
10540 rd
= (insn
>> 8) & 7;
10541 /* load pc-relative. Bit 1 of PC is ignored. */
10542 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10543 val
&= ~(uint32_t)2;
10544 addr
= tcg_temp_new_i32();
10545 tcg_gen_movi_i32(addr
, val
);
10546 tmp
= tcg_temp_new_i32();
10547 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10548 tcg_temp_free_i32(addr
);
10549 store_reg(s
, rd
, tmp
);
10552 if (insn
& (1 << 10)) {
10553 /* data processing extended or blx */
10554 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10555 rm
= (insn
>> 3) & 0xf;
10556 op
= (insn
>> 8) & 3;
10559 tmp
= load_reg(s
, rd
);
10560 tmp2
= load_reg(s
, rm
);
10561 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10562 tcg_temp_free_i32(tmp2
);
10563 store_reg(s
, rd
, tmp
);
10566 tmp
= load_reg(s
, rd
);
10567 tmp2
= load_reg(s
, rm
);
10568 gen_sub_CC(tmp
, tmp
, tmp2
);
10569 tcg_temp_free_i32(tmp2
);
10570 tcg_temp_free_i32(tmp
);
10572 case 2: /* mov/cpy */
10573 tmp
= load_reg(s
, rm
);
10574 store_reg(s
, rd
, tmp
);
10576 case 3:/* branch [and link] exchange thumb register */
10577 tmp
= load_reg(s
, rm
);
10578 if (insn
& (1 << 7)) {
10580 val
= (uint32_t)s
->pc
| 1;
10581 tmp2
= tcg_temp_new_i32();
10582 tcg_gen_movi_i32(tmp2
, val
);
10583 store_reg(s
, 14, tmp2
);
10585 /* already thumb, no need to check */
10592 /* data processing register */
10594 rm
= (insn
>> 3) & 7;
10595 op
= (insn
>> 6) & 0xf;
10596 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10597 /* the shift/rotate ops want the operands backwards */
10606 if (op
== 9) { /* neg */
10607 tmp
= tcg_temp_new_i32();
10608 tcg_gen_movi_i32(tmp
, 0);
10609 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10610 tmp
= load_reg(s
, rd
);
10612 TCGV_UNUSED_I32(tmp
);
10615 tmp2
= load_reg(s
, rm
);
10617 case 0x0: /* and */
10618 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10619 if (!s
->condexec_mask
)
10622 case 0x1: /* eor */
10623 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10624 if (!s
->condexec_mask
)
10627 case 0x2: /* lsl */
10628 if (s
->condexec_mask
) {
10629 gen_shl(tmp2
, tmp2
, tmp
);
10631 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10632 gen_logic_CC(tmp2
);
10635 case 0x3: /* lsr */
10636 if (s
->condexec_mask
) {
10637 gen_shr(tmp2
, tmp2
, tmp
);
10639 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10640 gen_logic_CC(tmp2
);
10643 case 0x4: /* asr */
10644 if (s
->condexec_mask
) {
10645 gen_sar(tmp2
, tmp2
, tmp
);
10647 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10648 gen_logic_CC(tmp2
);
10651 case 0x5: /* adc */
10652 if (s
->condexec_mask
) {
10653 gen_adc(tmp
, tmp2
);
10655 gen_adc_CC(tmp
, tmp
, tmp2
);
10658 case 0x6: /* sbc */
10659 if (s
->condexec_mask
) {
10660 gen_sub_carry(tmp
, tmp
, tmp2
);
10662 gen_sbc_CC(tmp
, tmp
, tmp2
);
10665 case 0x7: /* ror */
10666 if (s
->condexec_mask
) {
10667 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10668 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10670 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10671 gen_logic_CC(tmp2
);
10674 case 0x8: /* tst */
10675 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10679 case 0x9: /* neg */
10680 if (s
->condexec_mask
)
10681 tcg_gen_neg_i32(tmp
, tmp2
);
10683 gen_sub_CC(tmp
, tmp
, tmp2
);
10685 case 0xa: /* cmp */
10686 gen_sub_CC(tmp
, tmp
, tmp2
);
10689 case 0xb: /* cmn */
10690 gen_add_CC(tmp
, tmp
, tmp2
);
10693 case 0xc: /* orr */
10694 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10695 if (!s
->condexec_mask
)
10698 case 0xd: /* mul */
10699 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10700 if (!s
->condexec_mask
)
10703 case 0xe: /* bic */
10704 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10705 if (!s
->condexec_mask
)
10708 case 0xf: /* mvn */
10709 tcg_gen_not_i32(tmp2
, tmp2
);
10710 if (!s
->condexec_mask
)
10711 gen_logic_CC(tmp2
);
10718 store_reg(s
, rm
, tmp2
);
10720 tcg_temp_free_i32(tmp
);
10722 store_reg(s
, rd
, tmp
);
10723 tcg_temp_free_i32(tmp2
);
10726 tcg_temp_free_i32(tmp
);
10727 tcg_temp_free_i32(tmp2
);
10732 /* load/store register offset. */
10734 rn
= (insn
>> 3) & 7;
10735 rm
= (insn
>> 6) & 7;
10736 op
= (insn
>> 9) & 7;
10737 addr
= load_reg(s
, rn
);
10738 tmp
= load_reg(s
, rm
);
10739 tcg_gen_add_i32(addr
, addr
, tmp
);
10740 tcg_temp_free_i32(tmp
);
10742 if (op
< 3) { /* store */
10743 tmp
= load_reg(s
, rd
);
10745 tmp
= tcg_temp_new_i32();
10750 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10753 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10756 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10758 case 3: /* ldrsb */
10759 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10762 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10765 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10768 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10770 case 7: /* ldrsh */
10771 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10774 if (op
>= 3) { /* load */
10775 store_reg(s
, rd
, tmp
);
10777 tcg_temp_free_i32(tmp
);
10779 tcg_temp_free_i32(addr
);
10783 /* load/store word immediate offset */
10785 rn
= (insn
>> 3) & 7;
10786 addr
= load_reg(s
, rn
);
10787 val
= (insn
>> 4) & 0x7c;
10788 tcg_gen_addi_i32(addr
, addr
, val
);
10790 if (insn
& (1 << 11)) {
10792 tmp
= tcg_temp_new_i32();
10793 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10794 store_reg(s
, rd
, tmp
);
10797 tmp
= load_reg(s
, rd
);
10798 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10799 tcg_temp_free_i32(tmp
);
10801 tcg_temp_free_i32(addr
);
10805 /* load/store byte immediate offset */
10807 rn
= (insn
>> 3) & 7;
10808 addr
= load_reg(s
, rn
);
10809 val
= (insn
>> 6) & 0x1f;
10810 tcg_gen_addi_i32(addr
, addr
, val
);
10812 if (insn
& (1 << 11)) {
10814 tmp
= tcg_temp_new_i32();
10815 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10816 store_reg(s
, rd
, tmp
);
10819 tmp
= load_reg(s
, rd
);
10820 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10821 tcg_temp_free_i32(tmp
);
10823 tcg_temp_free_i32(addr
);
10827 /* load/store halfword immediate offset */
10829 rn
= (insn
>> 3) & 7;
10830 addr
= load_reg(s
, rn
);
10831 val
= (insn
>> 5) & 0x3e;
10832 tcg_gen_addi_i32(addr
, addr
, val
);
10834 if (insn
& (1 << 11)) {
10836 tmp
= tcg_temp_new_i32();
10837 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10838 store_reg(s
, rd
, tmp
);
10841 tmp
= load_reg(s
, rd
);
10842 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10843 tcg_temp_free_i32(tmp
);
10845 tcg_temp_free_i32(addr
);
10849 /* load/store from stack */
10850 rd
= (insn
>> 8) & 7;
10851 addr
= load_reg(s
, 13);
10852 val
= (insn
& 0xff) * 4;
10853 tcg_gen_addi_i32(addr
, addr
, val
);
10855 if (insn
& (1 << 11)) {
10857 tmp
= tcg_temp_new_i32();
10858 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10859 store_reg(s
, rd
, tmp
);
10862 tmp
= load_reg(s
, rd
);
10863 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10864 tcg_temp_free_i32(tmp
);
10866 tcg_temp_free_i32(addr
);
10870 /* add to high reg */
10871 rd
= (insn
>> 8) & 7;
10872 if (insn
& (1 << 11)) {
10874 tmp
= load_reg(s
, 13);
10876 /* PC. bit 1 is ignored. */
10877 tmp
= tcg_temp_new_i32();
10878 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10880 val
= (insn
& 0xff) * 4;
10881 tcg_gen_addi_i32(tmp
, tmp
, val
);
10882 store_reg(s
, rd
, tmp
);
10887 op
= (insn
>> 8) & 0xf;
10890 /* adjust stack pointer */
10891 tmp
= load_reg(s
, 13);
10892 val
= (insn
& 0x7f) * 4;
10893 if (insn
& (1 << 7))
10894 val
= -(int32_t)val
;
10895 tcg_gen_addi_i32(tmp
, tmp
, val
);
10896 store_reg(s
, 13, tmp
);
10899 case 2: /* sign/zero extend. */
10902 rm
= (insn
>> 3) & 7;
10903 tmp
= load_reg(s
, rm
);
10904 switch ((insn
>> 6) & 3) {
10905 case 0: gen_sxth(tmp
); break;
10906 case 1: gen_sxtb(tmp
); break;
10907 case 2: gen_uxth(tmp
); break;
10908 case 3: gen_uxtb(tmp
); break;
10910 store_reg(s
, rd
, tmp
);
10912 case 4: case 5: case 0xc: case 0xd:
10914 addr
= load_reg(s
, 13);
10915 if (insn
& (1 << 8))
10919 for (i
= 0; i
< 8; i
++) {
10920 if (insn
& (1 << i
))
10923 if ((insn
& (1 << 11)) == 0) {
10924 tcg_gen_addi_i32(addr
, addr
, -offset
);
10926 for (i
= 0; i
< 8; i
++) {
10927 if (insn
& (1 << i
)) {
10928 if (insn
& (1 << 11)) {
10930 tmp
= tcg_temp_new_i32();
10931 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10932 store_reg(s
, i
, tmp
);
10935 tmp
= load_reg(s
, i
);
10936 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10937 tcg_temp_free_i32(tmp
);
10939 /* advance to the next address. */
10940 tcg_gen_addi_i32(addr
, addr
, 4);
10943 TCGV_UNUSED_I32(tmp
);
10944 if (insn
& (1 << 8)) {
10945 if (insn
& (1 << 11)) {
10947 tmp
= tcg_temp_new_i32();
10948 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10949 /* don't set the pc until the rest of the instruction
10953 tmp
= load_reg(s
, 14);
10954 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10955 tcg_temp_free_i32(tmp
);
10957 tcg_gen_addi_i32(addr
, addr
, 4);
10959 if ((insn
& (1 << 11)) == 0) {
10960 tcg_gen_addi_i32(addr
, addr
, -offset
);
10962 /* write back the new stack pointer */
10963 store_reg(s
, 13, addr
);
10964 /* set the new PC value */
10965 if ((insn
& 0x0900) == 0x0900) {
10966 store_reg_from_load(s
, 15, tmp
);
10970 case 1: case 3: case 9: case 11: /* czb */
10972 tmp
= load_reg(s
, rm
);
10973 s
->condlabel
= gen_new_label();
10975 if (insn
& (1 << 11))
10976 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10978 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10979 tcg_temp_free_i32(tmp
);
10980 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10981 val
= (uint32_t)s
->pc
+ 2;
10986 case 15: /* IT, nop-hint. */
10987 if ((insn
& 0xf) == 0) {
10988 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10992 s
->condexec_cond
= (insn
>> 4) & 0xe;
10993 s
->condexec_mask
= insn
& 0x1f;
10994 /* No actual code generated for this insn, just setup state. */
10997 case 0xe: /* bkpt */
10999 int imm8
= extract32(insn
, 0, 8);
11001 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11002 default_exception_el(s
));
11006 case 0xa: /* rev */
11008 rn
= (insn
>> 3) & 0x7;
11010 tmp
= load_reg(s
, rn
);
11011 switch ((insn
>> 6) & 3) {
11012 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11013 case 1: gen_rev16(tmp
); break;
11014 case 3: gen_revsh(tmp
); break;
11015 default: goto illegal_op
;
11017 store_reg(s
, rd
, tmp
);
11021 switch ((insn
>> 5) & 7) {
11025 if (((insn
>> 3) & 1) != s
->bswap_code
) {
11026 /* Dynamic endianness switching not implemented. */
11027 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
11028 g_assert_not_reached();
11037 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11038 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11041 addr
= tcg_const_i32(19);
11042 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11043 tcg_temp_free_i32(addr
);
11047 addr
= tcg_const_i32(16);
11048 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11049 tcg_temp_free_i32(addr
);
11051 tcg_temp_free_i32(tmp
);
11054 if (insn
& (1 << 4)) {
11055 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11059 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11074 /* load/store multiple */
11075 TCGv_i32 loaded_var
;
11076 TCGV_UNUSED_I32(loaded_var
);
11077 rn
= (insn
>> 8) & 0x7;
11078 addr
= load_reg(s
, rn
);
11079 for (i
= 0; i
< 8; i
++) {
11080 if (insn
& (1 << i
)) {
11081 if (insn
& (1 << 11)) {
11083 tmp
= tcg_temp_new_i32();
11084 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
11088 store_reg(s
, i
, tmp
);
11092 tmp
= load_reg(s
, i
);
11093 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
11094 tcg_temp_free_i32(tmp
);
11096 /* advance to the next address */
11097 tcg_gen_addi_i32(addr
, addr
, 4);
11100 if ((insn
& (1 << rn
)) == 0) {
11101 /* base reg not in list: base register writeback */
11102 store_reg(s
, rn
, addr
);
11104 /* base reg in list: if load, complete it now */
11105 if (insn
& (1 << 11)) {
11106 store_reg(s
, rn
, loaded_var
);
11108 tcg_temp_free_i32(addr
);
11113 /* conditional branch or swi */
11114 cond
= (insn
>> 8) & 0xf;
11120 gen_set_pc_im(s
, s
->pc
);
11121 s
->svc_imm
= extract32(insn
, 0, 8);
11122 s
->is_jmp
= DISAS_SWI
;
11125 /* generate a conditional jump to next instruction */
11126 s
->condlabel
= gen_new_label();
11127 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11130 /* jump to the offset */
11131 val
= (uint32_t)s
->pc
+ 2;
11132 offset
= ((int32_t)insn
<< 24) >> 24;
11133 val
+= offset
<< 1;
11138 if (insn
& (1 << 11)) {
11139 if (disas_thumb2_insn(env
, s
, insn
))
11143 /* unconditional branch */
11144 val
= (uint32_t)s
->pc
;
11145 offset
= ((int32_t)insn
<< 21) >> 21;
11146 val
+= (offset
<< 1) + 2;
11151 if (disas_thumb2_insn(env
, s
, insn
))
11157 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11158 default_exception_el(s
));
11162 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11163 default_exception_el(s
));
11166 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
11167 basic block 'tb'. If search_pc is TRUE, also generate PC
11168 information for each intermediate instruction. */
11169 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
11170 TranslationBlock
*tb
,
11173 CPUState
*cs
= CPU(cpu
);
11174 CPUARMState
*env
= &cpu
->env
;
11175 DisasContext dc1
, *dc
= &dc1
;
11178 target_ulong pc_start
;
11179 target_ulong next_page_start
;
11183 /* generate intermediate code */
11185 /* The A64 decoder has its own top level loop, because it doesn't need
11186 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11188 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11189 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
11197 dc
->is_jmp
= DISAS_NEXT
;
11199 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11203 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11204 * there is no secure EL1, so we route exceptions to EL3.
11206 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11207 !arm_el_is_aa64(env
, 3);
11208 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11209 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
11210 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11211 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11212 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11213 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11214 #if !defined(CONFIG_USER_ONLY)
11215 dc
->user
= (dc
->current_el
== 0);
11217 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11218 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11219 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11220 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11221 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11222 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11223 dc
->cp_regs
= cpu
->cp_regs
;
11224 dc
->features
= env
->features
;
11226 /* Single step state. The code-generation logic here is:
11228 * generate code with no special handling for single-stepping (except
11229 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11230 * this happens anyway because those changes are all system register or
11232 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11233 * emit code for one insn
11234 * emit code to clear PSTATE.SS
11235 * emit code to generate software step exception for completed step
11236 * end TB (as usual for having generated an exception)
11237 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11238 * emit code to generate a software step exception
11241 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11242 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11243 dc
->is_ldex
= false;
11244 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11246 cpu_F0s
= tcg_temp_new_i32();
11247 cpu_F1s
= tcg_temp_new_i32();
11248 cpu_F0d
= tcg_temp_new_i64();
11249 cpu_F1d
= tcg_temp_new_i64();
11252 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11253 cpu_M0
= tcg_temp_new_i64();
11254 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11257 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11258 if (max_insns
== 0)
11259 max_insns
= CF_COUNT_MASK
;
11263 tcg_clear_temp_count();
11265 /* A note on handling of the condexec (IT) bits:
11267 * We want to avoid the overhead of having to write the updated condexec
11268 * bits back to the CPUARMState for every instruction in an IT block. So:
11269 * (1) if the condexec bits are not already zero then we write
11270 * zero back into the CPUARMState now. This avoids complications trying
11271 * to do it at the end of the block. (For example if we don't do this
11272 * it's hard to identify whether we can safely skip writing condexec
11273 * at the end of the TB, which we definitely want to do for the case
11274 * where a TB doesn't do anything with the IT state at all.)
11275 * (2) if we are going to leave the TB then we call gen_set_condexec()
11276 * which will write the correct value into CPUARMState if zero is wrong.
11277 * This is done both for leaving the TB at the end, and for leaving
11278 * it because of an exception we know will happen, which is done in
11279 * gen_exception_insn(). The latter is necessary because we need to
11280 * leave the TB with the PC/IT state just prior to execution of the
11281 * instruction which caused the exception.
11282 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11283 * then the CPUARMState will be wrong and we need to reset it.
11284 * This is handled in the same way as restoration of the
11285 * PC in these situations: we will be called again with search_pc=1
11286 * and generate a mapping of the condexec bits for each PC in
11287 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11288 * this to restore the condexec bits.
11290 * Note that there are no instructions which can read the condexec
11291 * bits, and none which can write non-static values to them, so
11292 * we don't need to care about whether CPUARMState is correct in the
11296 /* Reset the conditional execution bits immediately. This avoids
11297 complications trying to do it at the end of the block. */
11298 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11300 TCGv_i32 tmp
= tcg_temp_new_i32();
11301 tcg_gen_movi_i32(tmp
, 0);
11302 store_cpu_field(tmp
, condexec_bits
);
11305 #ifdef CONFIG_USER_ONLY
11306 /* Intercept jump to the magic kernel page. */
11307 if (dc
->pc
>= 0xffff0000) {
11308 /* We always get here via a jump, so know we are not in a
11309 conditional execution block. */
11310 gen_exception_internal(EXCP_KERNEL_TRAP
);
11311 dc
->is_jmp
= DISAS_UPDATE
;
11315 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11316 /* We always get here via a jump, so know we are not in a
11317 conditional execution block. */
11318 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11319 dc
->is_jmp
= DISAS_UPDATE
;
11324 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11325 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11326 if (bp
->pc
== dc
->pc
) {
11327 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11328 /* Advance PC so that clearing the breakpoint will
11329 invalidate this TB. */
11331 goto done_generating
;
11336 j
= tcg_op_buf_count();
11340 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11342 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
11343 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
11344 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
11345 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
11348 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
11351 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
11352 tcg_gen_debug_insn_start(dc
->pc
);
11355 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11356 /* Singlestep state is Active-pending.
11357 * If we're in this state at the start of a TB then either
11358 * a) we just took an exception to an EL which is being debugged
11359 * and this is the first insn in the exception handler
11360 * b) debug exceptions were masked and we just unmasked them
11361 * without changing EL (eg by clearing PSTATE.D)
11362 * In either case we're going to take a swstep exception in the
11363 * "did not step an insn" case, and so the syndrome ISV and EX
11364 * bits should be zero.
11366 assert(num_insns
== 0);
11367 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11368 default_exception_el(dc
));
11369 goto done_generating
;
11373 disas_thumb_insn(env
, dc
);
11374 if (dc
->condexec_mask
) {
11375 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11376 | ((dc
->condexec_mask
>> 4) & 1);
11377 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11378 if (dc
->condexec_mask
== 0) {
11379 dc
->condexec_cond
= 0;
11383 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->bswap_code
);
11385 disas_arm_insn(dc
, insn
);
11388 if (dc
->condjmp
&& !dc
->is_jmp
) {
11389 gen_set_label(dc
->condlabel
);
11393 if (tcg_check_temp_count()) {
11394 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11398 /* Translation stops when a conditional branch is encountered.
11399 * Otherwise the subsequent code could get translated several times.
11400 * Also stop translation when a page boundary is reached. This
11401 * ensures prefetch aborts occur at the right place. */
11403 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11404 !cs
->singlestep_enabled
&&
11407 dc
->pc
< next_page_start
&&
11408 num_insns
< max_insns
);
11410 if (tb
->cflags
& CF_LAST_IO
) {
11412 /* FIXME: This can theoretically happen with self-modifying
11414 cpu_abort(cs
, "IO on conditional branch instruction");
11419 /* At this stage dc->condjmp will only be set when the skipped
11420 instruction was a conditional branch or trap, and the PC has
11421 already been written. */
11422 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11423 /* Make sure the pc is updated, and raise a debug exception. */
11425 gen_set_condexec(dc
);
11426 if (dc
->is_jmp
== DISAS_SWI
) {
11427 gen_ss_advance(dc
);
11428 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11429 default_exception_el(dc
));
11430 } else if (dc
->is_jmp
== DISAS_HVC
) {
11431 gen_ss_advance(dc
);
11432 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11433 } else if (dc
->is_jmp
== DISAS_SMC
) {
11434 gen_ss_advance(dc
);
11435 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11436 } else if (dc
->ss_active
) {
11437 gen_step_complete_exception(dc
);
11439 gen_exception_internal(EXCP_DEBUG
);
11441 gen_set_label(dc
->condlabel
);
11443 if (dc
->condjmp
|| !dc
->is_jmp
) {
11444 gen_set_pc_im(dc
, dc
->pc
);
11447 gen_set_condexec(dc
);
11448 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11449 gen_ss_advance(dc
);
11450 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11451 default_exception_el(dc
));
11452 } else if (dc
->is_jmp
== DISAS_HVC
&& !dc
->condjmp
) {
11453 gen_ss_advance(dc
);
11454 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11455 } else if (dc
->is_jmp
== DISAS_SMC
&& !dc
->condjmp
) {
11456 gen_ss_advance(dc
);
11457 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11458 } else if (dc
->ss_active
) {
11459 gen_step_complete_exception(dc
);
11461 /* FIXME: Single stepping a WFI insn will not halt
11463 gen_exception_internal(EXCP_DEBUG
);
11466 /* While branches must always occur at the end of an IT block,
11467 there are a few other things that can cause us to terminate
11468 the TB in the middle of an IT block:
11469 - Exception generating instructions (bkpt, swi, undefined).
11471 - Hardware watchpoints.
11472 Hardware breakpoints have already been handled and skip this code.
11474 gen_set_condexec(dc
);
11475 switch(dc
->is_jmp
) {
11477 gen_goto_tb(dc
, 1, dc
->pc
);
11482 /* indicate that the hash table must be used to find the next TB */
11483 tcg_gen_exit_tb(0);
11485 case DISAS_TB_JUMP
:
11486 /* nothing more to generate */
11489 gen_helper_wfi(cpu_env
);
11490 /* The helper doesn't necessarily throw an exception, but we
11491 * must go back to the main loop to check for interrupts anyway.
11493 tcg_gen_exit_tb(0);
11496 gen_helper_wfe(cpu_env
);
11499 gen_helper_yield(cpu_env
);
11502 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11503 default_exception_el(dc
));
11506 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11509 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11513 gen_set_label(dc
->condlabel
);
11514 gen_set_condexec(dc
);
11515 gen_goto_tb(dc
, 1, dc
->pc
);
11521 gen_tb_end(tb
, num_insns
);
11524 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11525 qemu_log("----------------\n");
11526 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11527 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
11528 dc
->thumb
| (dc
->bswap_code
<< 1));
11533 j
= tcg_op_buf_count();
11536 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11538 tb
->size
= dc
->pc
- pc_start
;
11539 tb
->icount
= num_insns
;
11543 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11545 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11548 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11550 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11553 static const char *cpu_mode_names
[16] = {
11554 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11555 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11558 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11561 ARMCPU
*cpu
= ARM_CPU(cs
);
11562 CPUARMState
*env
= &cpu
->env
;
11567 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11571 for(i
=0;i
<16;i
++) {
11572 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11574 cpu_fprintf(f
, "\n");
11576 cpu_fprintf(f
, " ");
11578 psr
= cpsr_read(env
);
11579 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11581 psr
& (1 << 31) ? 'N' : '-',
11582 psr
& (1 << 30) ? 'Z' : '-',
11583 psr
& (1 << 29) ? 'C' : '-',
11584 psr
& (1 << 28) ? 'V' : '-',
11585 psr
& CPSR_T
? 'T' : 'A',
11586 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11588 if (flags
& CPU_DUMP_FPU
) {
11589 int numvfpregs
= 0;
11590 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11593 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11596 for (i
= 0; i
< numvfpregs
; i
++) {
11597 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11598 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11599 i
* 2, (uint32_t)v
,
11600 i
* 2 + 1, (uint32_t)(v
>> 32),
11603 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11607 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11610 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11611 env
->condexec_bits
= 0;
11613 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11614 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];