4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
24 #include "internals.h"
25 #include "disas/disas.h"
28 #include "qemu/bitops.h"
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
34 #include "trace-tcg.h"
38 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
39 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
40 /* currently all emulated v5 cores are also v5TE, so don't bother */
41 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
42 #define ENABLE_ARCH_5J 0
43 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
44 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
45 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
46 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
47 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
49 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
51 #include "translate.h"
53 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) (s->user)
60 /* We reuse the same 64-bit temporaries for efficiency. */
61 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
62 static TCGv_i32 cpu_R
[16];
63 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
64 TCGv_i64 cpu_exclusive_addr
;
65 TCGv_i64 cpu_exclusive_val
;
66 #ifdef CONFIG_USER_ONLY
67 TCGv_i64 cpu_exclusive_test
;
68 TCGv_i32 cpu_exclusive_info
;
71 /* FIXME: These should be removed. */
72 static TCGv_i32 cpu_F0s
, cpu_F1s
;
73 static TCGv_i64 cpu_F0d
, cpu_F1d
;
75 #include "exec/gen-icount.h"
77 static const char *regnames
[] =
78 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
79 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
86 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
88 for (i
= 0; i
< 16; i
++) {
89 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
90 offsetof(CPUARMState
, regs
[i
]),
93 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
94 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
95 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
96 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
98 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
99 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
100 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
101 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
102 #ifdef CONFIG_USER_ONLY
103 cpu_exclusive_test
= tcg_global_mem_new_i64(cpu_env
,
104 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
105 cpu_exclusive_info
= tcg_global_mem_new_i32(cpu_env
,
106 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
109 a64_translate_init();
112 static inline ARMMMUIdx
get_a32_user_mem_index(DisasContext
*s
)
114 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
116 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
117 * otherwise, access as if at PL0.
119 switch (s
->mmu_idx
) {
120 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
121 case ARMMMUIdx_S12NSE0
:
122 case ARMMMUIdx_S12NSE1
:
123 return ARMMMUIdx_S12NSE0
;
125 case ARMMMUIdx_S1SE0
:
126 case ARMMMUIdx_S1SE1
:
127 return ARMMMUIdx_S1SE0
;
130 g_assert_not_reached();
134 static inline TCGv_i32
load_cpu_offset(int offset
)
136 TCGv_i32 tmp
= tcg_temp_new_i32();
137 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
141 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
143 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
145 tcg_gen_st_i32(var
, cpu_env
, offset
);
146 tcg_temp_free_i32(var
);
149 #define store_cpu_field(var, name) \
150 store_cpu_offset(var, offsetof(CPUARMState, name))
152 /* Set a variable to the value of a CPU register. */
153 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
157 /* normally, since we updated PC, we need only to add one insn */
159 addr
= (long)s
->pc
+ 2;
161 addr
= (long)s
->pc
+ 4;
162 tcg_gen_movi_i32(var
, addr
);
164 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
168 /* Create a new temporary and set it to the value of a CPU register. */
169 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
171 TCGv_i32 tmp
= tcg_temp_new_i32();
172 load_reg_var(s
, tmp
, reg
);
176 /* Set a CPU register. The source must be a temporary and will be
178 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
181 tcg_gen_andi_i32(var
, var
, ~1);
182 s
->is_jmp
= DISAS_JUMP
;
184 tcg_gen_mov_i32(cpu_R
[reg
], var
);
185 tcg_temp_free_i32(var
);
188 /* Value extensions. */
189 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
190 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
191 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
192 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
194 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
195 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
198 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
200 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
201 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
202 tcg_temp_free_i32(tmp_mask
);
204 /* Set NZCV flags from the high 4 bits of var. */
205 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
207 static void gen_exception_internal(int excp
)
209 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
211 assert(excp_is_internal(excp
));
212 gen_helper_exception_internal(cpu_env
, tcg_excp
);
213 tcg_temp_free_i32(tcg_excp
);
216 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
218 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
219 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
220 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
222 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
225 tcg_temp_free_i32(tcg_el
);
226 tcg_temp_free_i32(tcg_syn
);
227 tcg_temp_free_i32(tcg_excp
);
230 static void gen_ss_advance(DisasContext
*s
)
232 /* If the singlestep state is Active-not-pending, advance to
237 gen_helper_clear_pstate_ss(cpu_env
);
241 static void gen_step_complete_exception(DisasContext
*s
)
243 /* We just completed step of an insn. Move from Active-not-pending
244 * to Active-pending, and then also take the swstep exception.
245 * This corresponds to making the (IMPDEF) choice to prioritize
246 * swstep exceptions over asynchronous exceptions taken to an exception
247 * level where debug is disabled. This choice has the advantage that
248 * we do not need to maintain internal state corresponding to the
249 * ISV/EX syndrome bits between completion of the step and generation
250 * of the exception, and our syndrome information is always correct.
253 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
254 default_exception_el(s
));
255 s
->is_jmp
= DISAS_EXC
;
258 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
260 TCGv_i32 tmp1
= tcg_temp_new_i32();
261 TCGv_i32 tmp2
= tcg_temp_new_i32();
262 tcg_gen_ext16s_i32(tmp1
, a
);
263 tcg_gen_ext16s_i32(tmp2
, b
);
264 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
265 tcg_temp_free_i32(tmp2
);
266 tcg_gen_sari_i32(a
, a
, 16);
267 tcg_gen_sari_i32(b
, b
, 16);
268 tcg_gen_mul_i32(b
, b
, a
);
269 tcg_gen_mov_i32(a
, tmp1
);
270 tcg_temp_free_i32(tmp1
);
273 /* Byteswap each halfword. */
274 static void gen_rev16(TCGv_i32 var
)
276 TCGv_i32 tmp
= tcg_temp_new_i32();
277 tcg_gen_shri_i32(tmp
, var
, 8);
278 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
279 tcg_gen_shli_i32(var
, var
, 8);
280 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
281 tcg_gen_or_i32(var
, var
, tmp
);
282 tcg_temp_free_i32(tmp
);
285 /* Byteswap low halfword and sign extend. */
286 static void gen_revsh(TCGv_i32 var
)
288 tcg_gen_ext16u_i32(var
, var
);
289 tcg_gen_bswap16_i32(var
, var
);
290 tcg_gen_ext16s_i32(var
, var
);
293 /* Unsigned bitfield extract. */
294 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
297 tcg_gen_shri_i32(var
, var
, shift
);
298 tcg_gen_andi_i32(var
, var
, mask
);
301 /* Signed bitfield extract. */
302 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
307 tcg_gen_sari_i32(var
, var
, shift
);
308 if (shift
+ width
< 32) {
309 signbit
= 1u << (width
- 1);
310 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
311 tcg_gen_xori_i32(var
, var
, signbit
);
312 tcg_gen_subi_i32(var
, var
, signbit
);
316 /* Return (b << 32) + a. Mark inputs as dead */
317 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
319 TCGv_i64 tmp64
= tcg_temp_new_i64();
321 tcg_gen_extu_i32_i64(tmp64
, b
);
322 tcg_temp_free_i32(b
);
323 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
324 tcg_gen_add_i64(a
, tmp64
, a
);
326 tcg_temp_free_i64(tmp64
);
330 /* Return (b << 32) - a. Mark inputs as dead. */
331 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
333 TCGv_i64 tmp64
= tcg_temp_new_i64();
335 tcg_gen_extu_i32_i64(tmp64
, b
);
336 tcg_temp_free_i32(b
);
337 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
338 tcg_gen_sub_i64(a
, tmp64
, a
);
340 tcg_temp_free_i64(tmp64
);
344 /* 32x32->64 multiply. Marks inputs as dead. */
345 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
347 TCGv_i32 lo
= tcg_temp_new_i32();
348 TCGv_i32 hi
= tcg_temp_new_i32();
351 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
352 tcg_temp_free_i32(a
);
353 tcg_temp_free_i32(b
);
355 ret
= tcg_temp_new_i64();
356 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
357 tcg_temp_free_i32(lo
);
358 tcg_temp_free_i32(hi
);
363 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
365 TCGv_i32 lo
= tcg_temp_new_i32();
366 TCGv_i32 hi
= tcg_temp_new_i32();
369 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
370 tcg_temp_free_i32(a
);
371 tcg_temp_free_i32(b
);
373 ret
= tcg_temp_new_i64();
374 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
375 tcg_temp_free_i32(lo
);
376 tcg_temp_free_i32(hi
);
381 /* Swap low and high halfwords. */
382 static void gen_swap_half(TCGv_i32 var
)
384 TCGv_i32 tmp
= tcg_temp_new_i32();
385 tcg_gen_shri_i32(tmp
, var
, 16);
386 tcg_gen_shli_i32(var
, var
, 16);
387 tcg_gen_or_i32(var
, var
, tmp
);
388 tcg_temp_free_i32(tmp
);
391 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
392 tmp = (t0 ^ t1) & 0x8000;
395 t0 = (t0 + t1) ^ tmp;
398 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
400 TCGv_i32 tmp
= tcg_temp_new_i32();
401 tcg_gen_xor_i32(tmp
, t0
, t1
);
402 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
403 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
404 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
405 tcg_gen_add_i32(t0
, t0
, t1
);
406 tcg_gen_xor_i32(t0
, t0
, tmp
);
407 tcg_temp_free_i32(tmp
);
408 tcg_temp_free_i32(t1
);
411 /* Set CF to the top bit of var. */
412 static void gen_set_CF_bit31(TCGv_i32 var
)
414 tcg_gen_shri_i32(cpu_CF
, var
, 31);
417 /* Set N and Z flags from var. */
418 static inline void gen_logic_CC(TCGv_i32 var
)
420 tcg_gen_mov_i32(cpu_NF
, var
);
421 tcg_gen_mov_i32(cpu_ZF
, var
);
425 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
427 tcg_gen_add_i32(t0
, t0
, t1
);
428 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
431 /* dest = T0 + T1 + CF. */
432 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
434 tcg_gen_add_i32(dest
, t0
, t1
);
435 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
438 /* dest = T0 - T1 + CF - 1. */
439 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
441 tcg_gen_sub_i32(dest
, t0
, t1
);
442 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
443 tcg_gen_subi_i32(dest
, dest
, 1);
446 /* dest = T0 + T1. Compute C, N, V and Z flags */
447 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
449 TCGv_i32 tmp
= tcg_temp_new_i32();
450 tcg_gen_movi_i32(tmp
, 0);
451 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
452 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
453 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
454 tcg_gen_xor_i32(tmp
, t0
, t1
);
455 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
456 tcg_temp_free_i32(tmp
);
457 tcg_gen_mov_i32(dest
, cpu_NF
);
460 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
461 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
463 TCGv_i32 tmp
= tcg_temp_new_i32();
464 if (TCG_TARGET_HAS_add2_i32
) {
465 tcg_gen_movi_i32(tmp
, 0);
466 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
467 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
469 TCGv_i64 q0
= tcg_temp_new_i64();
470 TCGv_i64 q1
= tcg_temp_new_i64();
471 tcg_gen_extu_i32_i64(q0
, t0
);
472 tcg_gen_extu_i32_i64(q1
, t1
);
473 tcg_gen_add_i64(q0
, q0
, q1
);
474 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
475 tcg_gen_add_i64(q0
, q0
, q1
);
476 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
477 tcg_temp_free_i64(q0
);
478 tcg_temp_free_i64(q1
);
480 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
481 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
482 tcg_gen_xor_i32(tmp
, t0
, t1
);
483 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
484 tcg_temp_free_i32(tmp
);
485 tcg_gen_mov_i32(dest
, cpu_NF
);
488 /* dest = T0 - T1. Compute C, N, V and Z flags */
489 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
492 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
493 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
494 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
495 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
496 tmp
= tcg_temp_new_i32();
497 tcg_gen_xor_i32(tmp
, t0
, t1
);
498 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
499 tcg_temp_free_i32(tmp
);
500 tcg_gen_mov_i32(dest
, cpu_NF
);
503 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
504 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
506 TCGv_i32 tmp
= tcg_temp_new_i32();
507 tcg_gen_not_i32(tmp
, t1
);
508 gen_adc_CC(dest
, t0
, tmp
);
509 tcg_temp_free_i32(tmp
);
512 #define GEN_SHIFT(name) \
513 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
515 TCGv_i32 tmp1, tmp2, tmp3; \
516 tmp1 = tcg_temp_new_i32(); \
517 tcg_gen_andi_i32(tmp1, t1, 0xff); \
518 tmp2 = tcg_const_i32(0); \
519 tmp3 = tcg_const_i32(0x1f); \
520 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
521 tcg_temp_free_i32(tmp3); \
522 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
523 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
524 tcg_temp_free_i32(tmp2); \
525 tcg_temp_free_i32(tmp1); \
531 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
534 tmp1
= tcg_temp_new_i32();
535 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
536 tmp2
= tcg_const_i32(0x1f);
537 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
538 tcg_temp_free_i32(tmp2
);
539 tcg_gen_sar_i32(dest
, t0
, tmp1
);
540 tcg_temp_free_i32(tmp1
);
543 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
545 TCGv_i32 c0
= tcg_const_i32(0);
546 TCGv_i32 tmp
= tcg_temp_new_i32();
547 tcg_gen_neg_i32(tmp
, src
);
548 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
549 tcg_temp_free_i32(c0
);
550 tcg_temp_free_i32(tmp
);
553 static void shifter_out_im(TCGv_i32 var
, int shift
)
556 tcg_gen_andi_i32(cpu_CF
, var
, 1);
558 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
560 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
565 /* Shift by immediate. Includes special handling for shift == 0. */
566 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
567 int shift
, int flags
)
573 shifter_out_im(var
, 32 - shift
);
574 tcg_gen_shli_i32(var
, var
, shift
);
580 tcg_gen_shri_i32(cpu_CF
, var
, 31);
582 tcg_gen_movi_i32(var
, 0);
585 shifter_out_im(var
, shift
- 1);
586 tcg_gen_shri_i32(var
, var
, shift
);
593 shifter_out_im(var
, shift
- 1);
596 tcg_gen_sari_i32(var
, var
, shift
);
598 case 3: /* ROR/RRX */
601 shifter_out_im(var
, shift
- 1);
602 tcg_gen_rotri_i32(var
, var
, shift
); break;
604 TCGv_i32 tmp
= tcg_temp_new_i32();
605 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
607 shifter_out_im(var
, 0);
608 tcg_gen_shri_i32(var
, var
, 1);
609 tcg_gen_or_i32(var
, var
, tmp
);
610 tcg_temp_free_i32(tmp
);
615 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
616 TCGv_i32 shift
, int flags
)
620 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
621 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
622 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
623 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
628 gen_shl(var
, var
, shift
);
631 gen_shr(var
, var
, shift
);
634 gen_sar(var
, var
, shift
);
636 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
637 tcg_gen_rotr_i32(var
, var
, shift
); break;
640 tcg_temp_free_i32(shift
);
643 #define PAS_OP(pfx) \
645 case 0: gen_pas_helper(glue(pfx,add16)); break; \
646 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
647 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
648 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
649 case 4: gen_pas_helper(glue(pfx,add8)); break; \
650 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
652 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
657 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
659 tmp
= tcg_temp_new_ptr();
660 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
662 tcg_temp_free_ptr(tmp
);
665 tmp
= tcg_temp_new_ptr();
666 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
668 tcg_temp_free_ptr(tmp
);
670 #undef gen_pas_helper
671 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
684 #undef gen_pas_helper
689 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
690 #define PAS_OP(pfx) \
692 case 0: gen_pas_helper(glue(pfx,add8)); break; \
693 case 1: gen_pas_helper(glue(pfx,add16)); break; \
694 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
695 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
696 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
697 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
699 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
704 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
706 tmp
= tcg_temp_new_ptr();
707 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
709 tcg_temp_free_ptr(tmp
);
712 tmp
= tcg_temp_new_ptr();
713 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
715 tcg_temp_free_ptr(tmp
);
717 #undef gen_pas_helper
718 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
731 #undef gen_pas_helper
737 * Generate a conditional based on ARM condition code cc.
738 * This is common between ARM and Aarch64 targets.
740 void arm_test_cc(DisasCompare
*cmp
, int cc
)
771 case 8: /* hi: C && !Z */
772 case 9: /* ls: !C || Z -> !(C && !Z) */
774 value
= tcg_temp_new_i32();
776 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
777 ZF is non-zero for !Z; so AND the two subexpressions. */
778 tcg_gen_neg_i32(value
, cpu_CF
);
779 tcg_gen_and_i32(value
, value
, cpu_ZF
);
782 case 10: /* ge: N == V -> N ^ V == 0 */
783 case 11: /* lt: N != V -> N ^ V != 0 */
784 /* Since we're only interested in the sign bit, == 0 is >= 0. */
786 value
= tcg_temp_new_i32();
788 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
791 case 12: /* gt: !Z && N == V */
792 case 13: /* le: Z || N != V */
794 value
= tcg_temp_new_i32();
796 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
797 * the sign bit then AND with ZF to yield the result. */
798 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
799 tcg_gen_sari_i32(value
, value
, 31);
800 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
803 case 14: /* always */
804 case 15: /* always */
805 /* Use the ALWAYS condition, which will fold early.
806 * It doesn't matter what we use for the value. */
807 cond
= TCG_COND_ALWAYS
;
812 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
817 cond
= tcg_invert_cond(cond
);
823 cmp
->value_global
= global
;
826 void arm_free_cc(DisasCompare
*cmp
)
828 if (!cmp
->value_global
) {
829 tcg_temp_free_i32(cmp
->value
);
833 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
835 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
838 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
841 arm_test_cc(&cmp
, cc
);
842 arm_jump_cc(&cmp
, label
);
846 static const uint8_t table_logic_cc
[16] = {
865 /* Set PC and Thumb state from an immediate address. */
866 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
870 s
->is_jmp
= DISAS_JUMP
;
871 if (s
->thumb
!= (addr
& 1)) {
872 tmp
= tcg_temp_new_i32();
873 tcg_gen_movi_i32(tmp
, addr
& 1);
874 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
875 tcg_temp_free_i32(tmp
);
877 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
880 /* Set PC and Thumb state from var. var is marked as dead. */
881 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
883 s
->is_jmp
= DISAS_JUMP
;
884 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
885 tcg_gen_andi_i32(var
, var
, 1);
886 store_cpu_field(var
, thumb
);
889 /* Variant of store_reg which uses branch&exchange logic when storing
890 to r15 in ARM architecture v7 and above. The source must be a temporary
891 and will be marked as dead. */
892 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
894 if (reg
== 15 && ENABLE_ARCH_7
) {
897 store_reg(s
, reg
, var
);
901 /* Variant of store_reg which uses branch&exchange logic when storing
902 * to r15 in ARM architecture v5T and above. This is used for storing
903 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
904 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
905 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
907 if (reg
== 15 && ENABLE_ARCH_5
) {
910 store_reg(s
, reg
, var
);
914 #ifdef CONFIG_USER_ONLY
915 #define IS_USER_ONLY 1
917 #define IS_USER_ONLY 0
920 /* Abstractions of "generate code to do a guest load/store for
921 * AArch32", where a vaddr is always 32 bits (and is zero
922 * extended if we're a 64 bit core) and data is also
923 * 32 bits unless specifically doing a 64 bit access.
924 * These functions work like tcg_gen_qemu_{ld,st}* except
925 * that the address argument is TCGv_i32 rather than TCGv.
927 #if TARGET_LONG_BITS == 32
929 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
930 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
931 TCGv_i32 addr, int index) \
933 TCGMemOp opc = (OPC) | s->be_data; \
934 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
935 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
936 TCGv addr_be = tcg_temp_new(); \
937 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
938 tcg_gen_qemu_ld_i32(val, addr_be, index, opc); \
939 tcg_temp_free(addr_be); \
942 tcg_gen_qemu_ld_i32(val, addr, index, opc); \
945 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
946 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
947 TCGv_i32 addr, int index) \
949 TCGMemOp opc = (OPC) | s->be_data; \
950 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
951 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
952 TCGv addr_be = tcg_temp_new(); \
953 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
954 tcg_gen_qemu_st_i32(val, addr_be, index, opc); \
955 tcg_temp_free(addr_be); \
958 tcg_gen_qemu_st_i32(val, addr, index, opc); \
961 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
962 TCGv_i32 addr
, int index
)
964 TCGMemOp opc
= MO_Q
| s
->be_data
;
965 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
966 /* Not needed for user-mode BE32, where we use MO_BE instead. */
967 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
968 tcg_gen_rotri_i64(val
, val
, 32);
972 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
973 TCGv_i32 addr
, int index
)
975 TCGMemOp opc
= MO_Q
| s
->be_data
;
976 /* Not needed for user-mode BE32, where we use MO_BE instead. */
977 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
978 TCGv_i64 tmp
= tcg_temp_new_i64();
979 tcg_gen_rotri_i64(tmp
, val
, 32);
980 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
981 tcg_temp_free_i64(tmp
);
984 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
989 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
990 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
991 TCGv_i32 addr, int index) \
993 TCGMemOp opc = (OPC) | s->be_data; \
994 TCGv addr64 = tcg_temp_new(); \
995 tcg_gen_extu_i32_i64(addr64, addr); \
996 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
997 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
998 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1000 tcg_gen_qemu_ld_i32(val, addr64, index, opc); \
1001 tcg_temp_free(addr64); \
1004 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
1005 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1006 TCGv_i32 addr, int index) \
1008 TCGMemOp opc = (OPC) | s->be_data; \
1009 TCGv addr64 = tcg_temp_new(); \
1010 tcg_gen_extu_i32_i64(addr64, addr); \
1011 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
1012 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
1013 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1015 tcg_gen_qemu_st_i32(val, addr64, index, opc); \
1016 tcg_temp_free(addr64); \
1019 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1020 TCGv_i32 addr
, int index
)
1022 TCGMemOp opc
= MO_Q
| s
->be_data
;
1023 TCGv addr64
= tcg_temp_new();
1024 tcg_gen_extu_i32_i64(addr64
, addr
);
1025 tcg_gen_qemu_ld_i64(val
, addr64
, index
, opc
);
1027 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1028 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1029 tcg_gen_rotri_i64(val
, val
, 32);
1031 tcg_temp_free(addr64
);
1034 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1035 TCGv_i32 addr
, int index
)
1037 TCGMemOp opc
= MO_Q
| s
->be_data
;
1038 TCGv addr64
= tcg_temp_new();
1039 tcg_gen_extu_i32_i64(addr64
, addr
);
1041 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1042 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1043 TCGv tmp
= tcg_temp_new();
1044 tcg_gen_rotri_i64(tmp
, val
, 32);
1045 tcg_gen_qemu_st_i64(tmp
, addr64
, index
, opc
);
1048 tcg_gen_qemu_st_i64(val
, addr64
, index
, opc
);
1050 tcg_temp_free(addr64
);
1055 DO_GEN_LD(8s
, MO_SB
, 3)
1056 DO_GEN_LD(8u, MO_UB
, 3)
1057 DO_GEN_LD(16s
, MO_SW
, 2)
1058 DO_GEN_LD(16u, MO_UW
, 2)
1059 DO_GEN_LD(32u, MO_UL
, 0)
1060 /* 'a' variants include an alignment check */
1061 DO_GEN_LD(16ua
, MO_UW
| MO_ALIGN
, 2)
1062 DO_GEN_LD(32ua
, MO_UL
| MO_ALIGN
, 0)
1063 DO_GEN_ST(8, MO_UB
, 3)
1064 DO_GEN_ST(16, MO_UW
, 2)
1065 DO_GEN_ST(32, MO_UL
, 0)
1067 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
1069 tcg_gen_movi_i32(cpu_R
[15], val
);
1072 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1074 /* The pre HVC helper handles cases when HVC gets trapped
1075 * as an undefined insn by runtime configuration (ie before
1076 * the insn really executes).
1078 gen_set_pc_im(s
, s
->pc
- 4);
1079 gen_helper_pre_hvc(cpu_env
);
1080 /* Otherwise we will treat this as a real exception which
1081 * happens after execution of the insn. (The distinction matters
1082 * for the PC value reported to the exception handler and also
1083 * for single stepping.)
1086 gen_set_pc_im(s
, s
->pc
);
1087 s
->is_jmp
= DISAS_HVC
;
1090 static inline void gen_smc(DisasContext
*s
)
1092 /* As with HVC, we may take an exception either before or after
1093 * the insn executes.
1097 gen_set_pc_im(s
, s
->pc
- 4);
1098 tmp
= tcg_const_i32(syn_aa32_smc());
1099 gen_helper_pre_smc(cpu_env
, tmp
);
1100 tcg_temp_free_i32(tmp
);
1101 gen_set_pc_im(s
, s
->pc
);
1102 s
->is_jmp
= DISAS_SMC
;
1106 gen_set_condexec (DisasContext
*s
)
1108 if (s
->condexec_mask
) {
1109 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1110 TCGv_i32 tmp
= tcg_temp_new_i32();
1111 tcg_gen_movi_i32(tmp
, val
);
1112 store_cpu_field(tmp
, condexec_bits
);
1116 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1118 gen_set_condexec(s
);
1119 gen_set_pc_im(s
, s
->pc
- offset
);
1120 gen_exception_internal(excp
);
1121 s
->is_jmp
= DISAS_JUMP
;
1124 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1125 int syn
, uint32_t target_el
)
1127 gen_set_condexec(s
);
1128 gen_set_pc_im(s
, s
->pc
- offset
);
1129 gen_exception(excp
, syn
, target_el
);
1130 s
->is_jmp
= DISAS_JUMP
;
1133 /* Force a TB lookup after an instruction that changes the CPU state. */
1134 static inline void gen_lookup_tb(DisasContext
*s
)
1136 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1137 s
->is_jmp
= DISAS_JUMP
;
1140 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1143 int val
, rm
, shift
, shiftop
;
1146 if (!(insn
& (1 << 25))) {
1149 if (!(insn
& (1 << 23)))
1152 tcg_gen_addi_i32(var
, var
, val
);
1154 /* shift/register */
1156 shift
= (insn
>> 7) & 0x1f;
1157 shiftop
= (insn
>> 5) & 3;
1158 offset
= load_reg(s
, rm
);
1159 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1160 if (!(insn
& (1 << 23)))
1161 tcg_gen_sub_i32(var
, var
, offset
);
1163 tcg_gen_add_i32(var
, var
, offset
);
1164 tcg_temp_free_i32(offset
);
1168 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1169 int extra
, TCGv_i32 var
)
1174 if (insn
& (1 << 22)) {
1176 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1177 if (!(insn
& (1 << 23)))
1181 tcg_gen_addi_i32(var
, var
, val
);
1185 tcg_gen_addi_i32(var
, var
, extra
);
1187 offset
= load_reg(s
, rm
);
1188 if (!(insn
& (1 << 23)))
1189 tcg_gen_sub_i32(var
, var
, offset
);
1191 tcg_gen_add_i32(var
, var
, offset
);
1192 tcg_temp_free_i32(offset
);
1196 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1198 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1201 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1203 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1205 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1209 #define VFP_OP2(name) \
1210 static inline void gen_vfp_##name(int dp) \
1212 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1214 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1216 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1218 tcg_temp_free_ptr(fpst); \
1228 static inline void gen_vfp_F1_mul(int dp
)
1230 /* Like gen_vfp_mul() but put result in F1 */
1231 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1233 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1235 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1237 tcg_temp_free_ptr(fpst
);
1240 static inline void gen_vfp_F1_neg(int dp
)
1242 /* Like gen_vfp_neg() but put result in F1 */
1244 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1246 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1250 static inline void gen_vfp_abs(int dp
)
1253 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1255 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1258 static inline void gen_vfp_neg(int dp
)
1261 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1263 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1266 static inline void gen_vfp_sqrt(int dp
)
1269 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1271 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1274 static inline void gen_vfp_cmp(int dp
)
1277 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1279 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1282 static inline void gen_vfp_cmpe(int dp
)
1285 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1287 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1290 static inline void gen_vfp_F1_ld0(int dp
)
1293 tcg_gen_movi_i64(cpu_F1d
, 0);
1295 tcg_gen_movi_i32(cpu_F1s
, 0);
1298 #define VFP_GEN_ITOF(name) \
1299 static inline void gen_vfp_##name(int dp, int neon) \
1301 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1303 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1305 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1307 tcg_temp_free_ptr(statusptr); \
1314 #define VFP_GEN_FTOI(name) \
1315 static inline void gen_vfp_##name(int dp, int neon) \
1317 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1319 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1321 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1323 tcg_temp_free_ptr(statusptr); \
1332 #define VFP_GEN_FIX(name, round) \
1333 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1335 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1336 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1338 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1341 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1344 tcg_temp_free_i32(tmp_shift); \
1345 tcg_temp_free_ptr(statusptr); \
1347 VFP_GEN_FIX(tosh
, _round_to_zero
)
1348 VFP_GEN_FIX(tosl
, _round_to_zero
)
1349 VFP_GEN_FIX(touh
, _round_to_zero
)
1350 VFP_GEN_FIX(toul
, _round_to_zero
)
1357 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1360 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1362 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1366 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1369 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1371 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1376 vfp_reg_offset (int dp
, int reg
)
1379 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1381 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1382 + offsetof(CPU_DoubleU
, l
.upper
);
1384 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1385 + offsetof(CPU_DoubleU
, l
.lower
);
1389 /* Return the offset of a 32-bit piece of a NEON register.
1390 zero is the least significant end of the register. */
1392 neon_reg_offset (int reg
, int n
)
1396 return vfp_reg_offset(0, sreg
);
1399 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1401 TCGv_i32 tmp
= tcg_temp_new_i32();
1402 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1406 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1408 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1409 tcg_temp_free_i32(var
);
1412 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1414 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1417 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1419 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1422 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1423 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1424 #define tcg_gen_st_f32 tcg_gen_st_i32
1425 #define tcg_gen_st_f64 tcg_gen_st_i64
1427 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1430 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1432 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1435 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1438 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1440 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1443 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1446 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1448 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1451 #define ARM_CP_RW_BIT (1 << 20)
1453 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1455 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1458 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1460 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1463 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1465 TCGv_i32 var
= tcg_temp_new_i32();
1466 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1470 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1472 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1473 tcg_temp_free_i32(var
);
1476 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1478 iwmmxt_store_reg(cpu_M0
, rn
);
1481 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1483 iwmmxt_load_reg(cpu_M0
, rn
);
1486 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1488 iwmmxt_load_reg(cpu_V1
, rn
);
1489 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1492 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1494 iwmmxt_load_reg(cpu_V1
, rn
);
1495 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1498 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1500 iwmmxt_load_reg(cpu_V1
, rn
);
1501 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1504 #define IWMMXT_OP(name) \
1505 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1507 iwmmxt_load_reg(cpu_V1, rn); \
1508 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1511 #define IWMMXT_OP_ENV(name) \
1512 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1514 iwmmxt_load_reg(cpu_V1, rn); \
1515 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1518 #define IWMMXT_OP_ENV_SIZE(name) \
1519 IWMMXT_OP_ENV(name##b) \
1520 IWMMXT_OP_ENV(name##w) \
1521 IWMMXT_OP_ENV(name##l)
1523 #define IWMMXT_OP_ENV1(name) \
1524 static inline void gen_op_iwmmxt_##name##_M0(void) \
1526 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1540 IWMMXT_OP_ENV_SIZE(unpackl
)
1541 IWMMXT_OP_ENV_SIZE(unpackh
)
1543 IWMMXT_OP_ENV1(unpacklub
)
1544 IWMMXT_OP_ENV1(unpackluw
)
1545 IWMMXT_OP_ENV1(unpacklul
)
1546 IWMMXT_OP_ENV1(unpackhub
)
1547 IWMMXT_OP_ENV1(unpackhuw
)
1548 IWMMXT_OP_ENV1(unpackhul
)
1549 IWMMXT_OP_ENV1(unpacklsb
)
1550 IWMMXT_OP_ENV1(unpacklsw
)
1551 IWMMXT_OP_ENV1(unpacklsl
)
1552 IWMMXT_OP_ENV1(unpackhsb
)
1553 IWMMXT_OP_ENV1(unpackhsw
)
1554 IWMMXT_OP_ENV1(unpackhsl
)
1556 IWMMXT_OP_ENV_SIZE(cmpeq
)
1557 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1558 IWMMXT_OP_ENV_SIZE(cmpgts
)
1560 IWMMXT_OP_ENV_SIZE(mins
)
1561 IWMMXT_OP_ENV_SIZE(minu
)
1562 IWMMXT_OP_ENV_SIZE(maxs
)
1563 IWMMXT_OP_ENV_SIZE(maxu
)
1565 IWMMXT_OP_ENV_SIZE(subn
)
1566 IWMMXT_OP_ENV_SIZE(addn
)
1567 IWMMXT_OP_ENV_SIZE(subu
)
1568 IWMMXT_OP_ENV_SIZE(addu
)
1569 IWMMXT_OP_ENV_SIZE(subs
)
1570 IWMMXT_OP_ENV_SIZE(adds
)
1572 IWMMXT_OP_ENV(avgb0
)
1573 IWMMXT_OP_ENV(avgb1
)
1574 IWMMXT_OP_ENV(avgw0
)
1575 IWMMXT_OP_ENV(avgw1
)
1577 IWMMXT_OP_ENV(packuw
)
1578 IWMMXT_OP_ENV(packul
)
1579 IWMMXT_OP_ENV(packuq
)
1580 IWMMXT_OP_ENV(packsw
)
1581 IWMMXT_OP_ENV(packsl
)
1582 IWMMXT_OP_ENV(packsq
)
1584 static void gen_op_iwmmxt_set_mup(void)
1587 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1588 tcg_gen_ori_i32(tmp
, tmp
, 2);
1589 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1592 static void gen_op_iwmmxt_set_cup(void)
1595 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1596 tcg_gen_ori_i32(tmp
, tmp
, 1);
1597 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1600 static void gen_op_iwmmxt_setpsr_nz(void)
1602 TCGv_i32 tmp
= tcg_temp_new_i32();
1603 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1604 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1607 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1609 iwmmxt_load_reg(cpu_V1
, rn
);
1610 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1611 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1614 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1621 rd
= (insn
>> 16) & 0xf;
1622 tmp
= load_reg(s
, rd
);
1624 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1625 if (insn
& (1 << 24)) {
1627 if (insn
& (1 << 23))
1628 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1630 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1631 tcg_gen_mov_i32(dest
, tmp
);
1632 if (insn
& (1 << 21))
1633 store_reg(s
, rd
, tmp
);
1635 tcg_temp_free_i32(tmp
);
1636 } else if (insn
& (1 << 21)) {
1638 tcg_gen_mov_i32(dest
, tmp
);
1639 if (insn
& (1 << 23))
1640 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1642 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1643 store_reg(s
, rd
, tmp
);
1644 } else if (!(insn
& (1 << 23)))
1649 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1651 int rd
= (insn
>> 0) & 0xf;
1654 if (insn
& (1 << 8)) {
1655 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1658 tmp
= iwmmxt_load_creg(rd
);
1661 tmp
= tcg_temp_new_i32();
1662 iwmmxt_load_reg(cpu_V0
, rd
);
1663 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1665 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1666 tcg_gen_mov_i32(dest
, tmp
);
1667 tcg_temp_free_i32(tmp
);
1671 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1672 (ie. an undefined instruction). */
1673 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1676 int rdhi
, rdlo
, rd0
, rd1
, i
;
1678 TCGv_i32 tmp
, tmp2
, tmp3
;
1680 if ((insn
& 0x0e000e00) == 0x0c000000) {
1681 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1683 rdlo
= (insn
>> 12) & 0xf;
1684 rdhi
= (insn
>> 16) & 0xf;
1685 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1686 iwmmxt_load_reg(cpu_V0
, wrd
);
1687 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1688 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1689 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1690 } else { /* TMCRR */
1691 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1692 iwmmxt_store_reg(cpu_V0
, wrd
);
1693 gen_op_iwmmxt_set_mup();
1698 wrd
= (insn
>> 12) & 0xf;
1699 addr
= tcg_temp_new_i32();
1700 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1701 tcg_temp_free_i32(addr
);
1704 if (insn
& ARM_CP_RW_BIT
) {
1705 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1706 tmp
= tcg_temp_new_i32();
1707 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1708 iwmmxt_store_creg(wrd
, tmp
);
1711 if (insn
& (1 << 8)) {
1712 if (insn
& (1 << 22)) { /* WLDRD */
1713 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1715 } else { /* WLDRW wRd */
1716 tmp
= tcg_temp_new_i32();
1717 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1720 tmp
= tcg_temp_new_i32();
1721 if (insn
& (1 << 22)) { /* WLDRH */
1722 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1723 } else { /* WLDRB */
1724 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1728 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1729 tcg_temp_free_i32(tmp
);
1731 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1734 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1735 tmp
= iwmmxt_load_creg(wrd
);
1736 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1738 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1739 tmp
= tcg_temp_new_i32();
1740 if (insn
& (1 << 8)) {
1741 if (insn
& (1 << 22)) { /* WSTRD */
1742 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1743 } else { /* WSTRW wRd */
1744 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1745 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1748 if (insn
& (1 << 22)) { /* WSTRH */
1749 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1750 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1751 } else { /* WSTRB */
1752 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1753 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1757 tcg_temp_free_i32(tmp
);
1759 tcg_temp_free_i32(addr
);
1763 if ((insn
& 0x0f000000) != 0x0e000000)
1766 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1767 case 0x000: /* WOR */
1768 wrd
= (insn
>> 12) & 0xf;
1769 rd0
= (insn
>> 0) & 0xf;
1770 rd1
= (insn
>> 16) & 0xf;
1771 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1772 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1773 gen_op_iwmmxt_setpsr_nz();
1774 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1775 gen_op_iwmmxt_set_mup();
1776 gen_op_iwmmxt_set_cup();
1778 case 0x011: /* TMCR */
1781 rd
= (insn
>> 12) & 0xf;
1782 wrd
= (insn
>> 16) & 0xf;
1784 case ARM_IWMMXT_wCID
:
1785 case ARM_IWMMXT_wCASF
:
1787 case ARM_IWMMXT_wCon
:
1788 gen_op_iwmmxt_set_cup();
1790 case ARM_IWMMXT_wCSSF
:
1791 tmp
= iwmmxt_load_creg(wrd
);
1792 tmp2
= load_reg(s
, rd
);
1793 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1794 tcg_temp_free_i32(tmp2
);
1795 iwmmxt_store_creg(wrd
, tmp
);
1797 case ARM_IWMMXT_wCGR0
:
1798 case ARM_IWMMXT_wCGR1
:
1799 case ARM_IWMMXT_wCGR2
:
1800 case ARM_IWMMXT_wCGR3
:
1801 gen_op_iwmmxt_set_cup();
1802 tmp
= load_reg(s
, rd
);
1803 iwmmxt_store_creg(wrd
, tmp
);
1809 case 0x100: /* WXOR */
1810 wrd
= (insn
>> 12) & 0xf;
1811 rd0
= (insn
>> 0) & 0xf;
1812 rd1
= (insn
>> 16) & 0xf;
1813 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1814 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1815 gen_op_iwmmxt_setpsr_nz();
1816 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1817 gen_op_iwmmxt_set_mup();
1818 gen_op_iwmmxt_set_cup();
1820 case 0x111: /* TMRC */
1823 rd
= (insn
>> 12) & 0xf;
1824 wrd
= (insn
>> 16) & 0xf;
1825 tmp
= iwmmxt_load_creg(wrd
);
1826 store_reg(s
, rd
, tmp
);
1828 case 0x300: /* WANDN */
1829 wrd
= (insn
>> 12) & 0xf;
1830 rd0
= (insn
>> 0) & 0xf;
1831 rd1
= (insn
>> 16) & 0xf;
1832 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1833 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1834 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1835 gen_op_iwmmxt_setpsr_nz();
1836 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1837 gen_op_iwmmxt_set_mup();
1838 gen_op_iwmmxt_set_cup();
1840 case 0x200: /* WAND */
1841 wrd
= (insn
>> 12) & 0xf;
1842 rd0
= (insn
>> 0) & 0xf;
1843 rd1
= (insn
>> 16) & 0xf;
1844 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1845 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1846 gen_op_iwmmxt_setpsr_nz();
1847 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1848 gen_op_iwmmxt_set_mup();
1849 gen_op_iwmmxt_set_cup();
1851 case 0x810: case 0xa10: /* WMADD */
1852 wrd
= (insn
>> 12) & 0xf;
1853 rd0
= (insn
>> 0) & 0xf;
1854 rd1
= (insn
>> 16) & 0xf;
1855 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1856 if (insn
& (1 << 21))
1857 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1859 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1860 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1861 gen_op_iwmmxt_set_mup();
1863 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1864 wrd
= (insn
>> 12) & 0xf;
1865 rd0
= (insn
>> 16) & 0xf;
1866 rd1
= (insn
>> 0) & 0xf;
1867 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1868 switch ((insn
>> 22) & 3) {
1870 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1873 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1876 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1881 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1882 gen_op_iwmmxt_set_mup();
1883 gen_op_iwmmxt_set_cup();
1885 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1886 wrd
= (insn
>> 12) & 0xf;
1887 rd0
= (insn
>> 16) & 0xf;
1888 rd1
= (insn
>> 0) & 0xf;
1889 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1890 switch ((insn
>> 22) & 3) {
1892 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1895 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1898 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1903 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1904 gen_op_iwmmxt_set_mup();
1905 gen_op_iwmmxt_set_cup();
1907 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1908 wrd
= (insn
>> 12) & 0xf;
1909 rd0
= (insn
>> 16) & 0xf;
1910 rd1
= (insn
>> 0) & 0xf;
1911 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1912 if (insn
& (1 << 22))
1913 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1915 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1916 if (!(insn
& (1 << 20)))
1917 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1918 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1919 gen_op_iwmmxt_set_mup();
1921 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1922 wrd
= (insn
>> 12) & 0xf;
1923 rd0
= (insn
>> 16) & 0xf;
1924 rd1
= (insn
>> 0) & 0xf;
1925 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1926 if (insn
& (1 << 21)) {
1927 if (insn
& (1 << 20))
1928 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1930 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1932 if (insn
& (1 << 20))
1933 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1935 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1937 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1938 gen_op_iwmmxt_set_mup();
1940 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1941 wrd
= (insn
>> 12) & 0xf;
1942 rd0
= (insn
>> 16) & 0xf;
1943 rd1
= (insn
>> 0) & 0xf;
1944 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1945 if (insn
& (1 << 21))
1946 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1948 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1949 if (!(insn
& (1 << 20))) {
1950 iwmmxt_load_reg(cpu_V1
, wrd
);
1951 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1953 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1954 gen_op_iwmmxt_set_mup();
1956 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1957 wrd
= (insn
>> 12) & 0xf;
1958 rd0
= (insn
>> 16) & 0xf;
1959 rd1
= (insn
>> 0) & 0xf;
1960 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1961 switch ((insn
>> 22) & 3) {
1963 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1966 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1969 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1974 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1975 gen_op_iwmmxt_set_mup();
1976 gen_op_iwmmxt_set_cup();
1978 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1979 wrd
= (insn
>> 12) & 0xf;
1980 rd0
= (insn
>> 16) & 0xf;
1981 rd1
= (insn
>> 0) & 0xf;
1982 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1983 if (insn
& (1 << 22)) {
1984 if (insn
& (1 << 20))
1985 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1987 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1989 if (insn
& (1 << 20))
1990 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1992 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1994 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1995 gen_op_iwmmxt_set_mup();
1996 gen_op_iwmmxt_set_cup();
1998 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1999 wrd
= (insn
>> 12) & 0xf;
2000 rd0
= (insn
>> 16) & 0xf;
2001 rd1
= (insn
>> 0) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2003 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2004 tcg_gen_andi_i32(tmp
, tmp
, 7);
2005 iwmmxt_load_reg(cpu_V1
, rd1
);
2006 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2007 tcg_temp_free_i32(tmp
);
2008 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2009 gen_op_iwmmxt_set_mup();
2011 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2012 if (((insn
>> 6) & 3) == 3)
2014 rd
= (insn
>> 12) & 0xf;
2015 wrd
= (insn
>> 16) & 0xf;
2016 tmp
= load_reg(s
, rd
);
2017 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2018 switch ((insn
>> 6) & 3) {
2020 tmp2
= tcg_const_i32(0xff);
2021 tmp3
= tcg_const_i32((insn
& 7) << 3);
2024 tmp2
= tcg_const_i32(0xffff);
2025 tmp3
= tcg_const_i32((insn
& 3) << 4);
2028 tmp2
= tcg_const_i32(0xffffffff);
2029 tmp3
= tcg_const_i32((insn
& 1) << 5);
2032 TCGV_UNUSED_I32(tmp2
);
2033 TCGV_UNUSED_I32(tmp3
);
2035 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2036 tcg_temp_free_i32(tmp3
);
2037 tcg_temp_free_i32(tmp2
);
2038 tcg_temp_free_i32(tmp
);
2039 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2040 gen_op_iwmmxt_set_mup();
2042 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2043 rd
= (insn
>> 12) & 0xf;
2044 wrd
= (insn
>> 16) & 0xf;
2045 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2047 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2048 tmp
= tcg_temp_new_i32();
2049 switch ((insn
>> 22) & 3) {
2051 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2052 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2054 tcg_gen_ext8s_i32(tmp
, tmp
);
2056 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2060 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2061 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2063 tcg_gen_ext16s_i32(tmp
, tmp
);
2065 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2069 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2070 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2073 store_reg(s
, rd
, tmp
);
2075 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2076 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2078 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2079 switch ((insn
>> 22) & 3) {
2081 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2084 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2087 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2090 tcg_gen_shli_i32(tmp
, tmp
, 28);
2092 tcg_temp_free_i32(tmp
);
2094 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2095 if (((insn
>> 6) & 3) == 3)
2097 rd
= (insn
>> 12) & 0xf;
2098 wrd
= (insn
>> 16) & 0xf;
2099 tmp
= load_reg(s
, rd
);
2100 switch ((insn
>> 6) & 3) {
2102 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2105 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2108 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2111 tcg_temp_free_i32(tmp
);
2112 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2113 gen_op_iwmmxt_set_mup();
2115 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2116 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2118 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2119 tmp2
= tcg_temp_new_i32();
2120 tcg_gen_mov_i32(tmp2
, tmp
);
2121 switch ((insn
>> 22) & 3) {
2123 for (i
= 0; i
< 7; i
++) {
2124 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2125 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2129 for (i
= 0; i
< 3; i
++) {
2130 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2131 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2135 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2136 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2140 tcg_temp_free_i32(tmp2
);
2141 tcg_temp_free_i32(tmp
);
2143 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2144 wrd
= (insn
>> 12) & 0xf;
2145 rd0
= (insn
>> 16) & 0xf;
2146 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2147 switch ((insn
>> 22) & 3) {
2149 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2152 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2155 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2160 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2161 gen_op_iwmmxt_set_mup();
2163 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2164 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2166 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2167 tmp2
= tcg_temp_new_i32();
2168 tcg_gen_mov_i32(tmp2
, tmp
);
2169 switch ((insn
>> 22) & 3) {
2171 for (i
= 0; i
< 7; i
++) {
2172 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2173 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2177 for (i
= 0; i
< 3; i
++) {
2178 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2179 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2183 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2184 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2188 tcg_temp_free_i32(tmp2
);
2189 tcg_temp_free_i32(tmp
);
2191 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2192 rd
= (insn
>> 12) & 0xf;
2193 rd0
= (insn
>> 16) & 0xf;
2194 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2196 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2197 tmp
= tcg_temp_new_i32();
2198 switch ((insn
>> 22) & 3) {
2200 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2203 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2206 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2209 store_reg(s
, rd
, tmp
);
2211 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2212 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2213 wrd
= (insn
>> 12) & 0xf;
2214 rd0
= (insn
>> 16) & 0xf;
2215 rd1
= (insn
>> 0) & 0xf;
2216 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2217 switch ((insn
>> 22) & 3) {
2219 if (insn
& (1 << 21))
2220 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2222 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2225 if (insn
& (1 << 21))
2226 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2228 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2231 if (insn
& (1 << 21))
2232 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2234 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2239 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2240 gen_op_iwmmxt_set_mup();
2241 gen_op_iwmmxt_set_cup();
2243 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2244 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2245 wrd
= (insn
>> 12) & 0xf;
2246 rd0
= (insn
>> 16) & 0xf;
2247 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2248 switch ((insn
>> 22) & 3) {
2250 if (insn
& (1 << 21))
2251 gen_op_iwmmxt_unpacklsb_M0();
2253 gen_op_iwmmxt_unpacklub_M0();
2256 if (insn
& (1 << 21))
2257 gen_op_iwmmxt_unpacklsw_M0();
2259 gen_op_iwmmxt_unpackluw_M0();
2262 if (insn
& (1 << 21))
2263 gen_op_iwmmxt_unpacklsl_M0();
2265 gen_op_iwmmxt_unpacklul_M0();
2270 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2271 gen_op_iwmmxt_set_mup();
2272 gen_op_iwmmxt_set_cup();
2274 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2275 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2276 wrd
= (insn
>> 12) & 0xf;
2277 rd0
= (insn
>> 16) & 0xf;
2278 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2279 switch ((insn
>> 22) & 3) {
2281 if (insn
& (1 << 21))
2282 gen_op_iwmmxt_unpackhsb_M0();
2284 gen_op_iwmmxt_unpackhub_M0();
2287 if (insn
& (1 << 21))
2288 gen_op_iwmmxt_unpackhsw_M0();
2290 gen_op_iwmmxt_unpackhuw_M0();
2293 if (insn
& (1 << 21))
2294 gen_op_iwmmxt_unpackhsl_M0();
2296 gen_op_iwmmxt_unpackhul_M0();
2301 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2302 gen_op_iwmmxt_set_mup();
2303 gen_op_iwmmxt_set_cup();
2305 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2306 case 0x214: case 0x614: case 0xa14: case 0xe14:
2307 if (((insn
>> 22) & 3) == 0)
2309 wrd
= (insn
>> 12) & 0xf;
2310 rd0
= (insn
>> 16) & 0xf;
2311 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2312 tmp
= tcg_temp_new_i32();
2313 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2314 tcg_temp_free_i32(tmp
);
2317 switch ((insn
>> 22) & 3) {
2319 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2322 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2325 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2328 tcg_temp_free_i32(tmp
);
2329 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2330 gen_op_iwmmxt_set_mup();
2331 gen_op_iwmmxt_set_cup();
2333 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2334 case 0x014: case 0x414: case 0x814: case 0xc14:
2335 if (((insn
>> 22) & 3) == 0)
2337 wrd
= (insn
>> 12) & 0xf;
2338 rd0
= (insn
>> 16) & 0xf;
2339 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2340 tmp
= tcg_temp_new_i32();
2341 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2342 tcg_temp_free_i32(tmp
);
2345 switch ((insn
>> 22) & 3) {
2347 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2350 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2353 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2356 tcg_temp_free_i32(tmp
);
2357 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2358 gen_op_iwmmxt_set_mup();
2359 gen_op_iwmmxt_set_cup();
2361 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2362 case 0x114: case 0x514: case 0x914: case 0xd14:
2363 if (((insn
>> 22) & 3) == 0)
2365 wrd
= (insn
>> 12) & 0xf;
2366 rd0
= (insn
>> 16) & 0xf;
2367 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2368 tmp
= tcg_temp_new_i32();
2369 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2370 tcg_temp_free_i32(tmp
);
2373 switch ((insn
>> 22) & 3) {
2375 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2378 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2381 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2384 tcg_temp_free_i32(tmp
);
2385 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2386 gen_op_iwmmxt_set_mup();
2387 gen_op_iwmmxt_set_cup();
2389 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2390 case 0x314: case 0x714: case 0xb14: case 0xf14:
2391 if (((insn
>> 22) & 3) == 0)
2393 wrd
= (insn
>> 12) & 0xf;
2394 rd0
= (insn
>> 16) & 0xf;
2395 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2396 tmp
= tcg_temp_new_i32();
2397 switch ((insn
>> 22) & 3) {
2399 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2400 tcg_temp_free_i32(tmp
);
2403 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2406 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2407 tcg_temp_free_i32(tmp
);
2410 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2413 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2414 tcg_temp_free_i32(tmp
);
2417 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2420 tcg_temp_free_i32(tmp
);
2421 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2422 gen_op_iwmmxt_set_mup();
2423 gen_op_iwmmxt_set_cup();
2425 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2426 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2427 wrd
= (insn
>> 12) & 0xf;
2428 rd0
= (insn
>> 16) & 0xf;
2429 rd1
= (insn
>> 0) & 0xf;
2430 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2431 switch ((insn
>> 22) & 3) {
2433 if (insn
& (1 << 21))
2434 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2436 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2439 if (insn
& (1 << 21))
2440 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2442 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2445 if (insn
& (1 << 21))
2446 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2448 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2453 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2454 gen_op_iwmmxt_set_mup();
2456 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2457 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2458 wrd
= (insn
>> 12) & 0xf;
2459 rd0
= (insn
>> 16) & 0xf;
2460 rd1
= (insn
>> 0) & 0xf;
2461 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2462 switch ((insn
>> 22) & 3) {
2464 if (insn
& (1 << 21))
2465 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2467 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2470 if (insn
& (1 << 21))
2471 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2473 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2476 if (insn
& (1 << 21))
2477 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2479 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2484 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2485 gen_op_iwmmxt_set_mup();
2487 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2488 case 0x402: case 0x502: case 0x602: case 0x702:
2489 wrd
= (insn
>> 12) & 0xf;
2490 rd0
= (insn
>> 16) & 0xf;
2491 rd1
= (insn
>> 0) & 0xf;
2492 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2493 tmp
= tcg_const_i32((insn
>> 20) & 3);
2494 iwmmxt_load_reg(cpu_V1
, rd1
);
2495 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2496 tcg_temp_free_i32(tmp
);
2497 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2498 gen_op_iwmmxt_set_mup();
2500 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2501 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2502 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2503 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2504 wrd
= (insn
>> 12) & 0xf;
2505 rd0
= (insn
>> 16) & 0xf;
2506 rd1
= (insn
>> 0) & 0xf;
2507 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2508 switch ((insn
>> 20) & 0xf) {
2510 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2513 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2516 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2519 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2522 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2525 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2528 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2531 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2534 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2539 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2540 gen_op_iwmmxt_set_mup();
2541 gen_op_iwmmxt_set_cup();
2543 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2544 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2545 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2546 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2547 wrd
= (insn
>> 12) & 0xf;
2548 rd0
= (insn
>> 16) & 0xf;
2549 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2550 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2551 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2552 tcg_temp_free_i32(tmp
);
2553 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2554 gen_op_iwmmxt_set_mup();
2555 gen_op_iwmmxt_set_cup();
2557 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2558 case 0x418: case 0x518: case 0x618: case 0x718:
2559 case 0x818: case 0x918: case 0xa18: case 0xb18:
2560 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2561 wrd
= (insn
>> 12) & 0xf;
2562 rd0
= (insn
>> 16) & 0xf;
2563 rd1
= (insn
>> 0) & 0xf;
2564 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2565 switch ((insn
>> 20) & 0xf) {
2567 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2570 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2573 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2576 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2579 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2582 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2585 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2588 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2591 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2596 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2597 gen_op_iwmmxt_set_mup();
2598 gen_op_iwmmxt_set_cup();
2600 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2601 case 0x408: case 0x508: case 0x608: case 0x708:
2602 case 0x808: case 0x908: case 0xa08: case 0xb08:
2603 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2604 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2606 wrd
= (insn
>> 12) & 0xf;
2607 rd0
= (insn
>> 16) & 0xf;
2608 rd1
= (insn
>> 0) & 0xf;
2609 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2610 switch ((insn
>> 22) & 3) {
2612 if (insn
& (1 << 21))
2613 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2615 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2618 if (insn
& (1 << 21))
2619 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2621 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2624 if (insn
& (1 << 21))
2625 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2627 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2630 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2631 gen_op_iwmmxt_set_mup();
2632 gen_op_iwmmxt_set_cup();
2634 case 0x201: case 0x203: case 0x205: case 0x207:
2635 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2636 case 0x211: case 0x213: case 0x215: case 0x217:
2637 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2638 wrd
= (insn
>> 5) & 0xf;
2639 rd0
= (insn
>> 12) & 0xf;
2640 rd1
= (insn
>> 0) & 0xf;
2641 if (rd0
== 0xf || rd1
== 0xf)
2643 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2644 tmp
= load_reg(s
, rd0
);
2645 tmp2
= load_reg(s
, rd1
);
2646 switch ((insn
>> 16) & 0xf) {
2647 case 0x0: /* TMIA */
2648 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2650 case 0x8: /* TMIAPH */
2651 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2653 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2654 if (insn
& (1 << 16))
2655 tcg_gen_shri_i32(tmp
, tmp
, 16);
2656 if (insn
& (1 << 17))
2657 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2658 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2661 tcg_temp_free_i32(tmp2
);
2662 tcg_temp_free_i32(tmp
);
2665 tcg_temp_free_i32(tmp2
);
2666 tcg_temp_free_i32(tmp
);
2667 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2668 gen_op_iwmmxt_set_mup();
2677 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2678 (ie. an undefined instruction). */
2679 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2681 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2684 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2685 /* Multiply with Internal Accumulate Format */
2686 rd0
= (insn
>> 12) & 0xf;
2688 acc
= (insn
>> 5) & 7;
2693 tmp
= load_reg(s
, rd0
);
2694 tmp2
= load_reg(s
, rd1
);
2695 switch ((insn
>> 16) & 0xf) {
2697 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2699 case 0x8: /* MIAPH */
2700 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2702 case 0xc: /* MIABB */
2703 case 0xd: /* MIABT */
2704 case 0xe: /* MIATB */
2705 case 0xf: /* MIATT */
2706 if (insn
& (1 << 16))
2707 tcg_gen_shri_i32(tmp
, tmp
, 16);
2708 if (insn
& (1 << 17))
2709 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2710 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2715 tcg_temp_free_i32(tmp2
);
2716 tcg_temp_free_i32(tmp
);
2718 gen_op_iwmmxt_movq_wRn_M0(acc
);
2722 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2723 /* Internal Accumulator Access Format */
2724 rdhi
= (insn
>> 16) & 0xf;
2725 rdlo
= (insn
>> 12) & 0xf;
2731 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2732 iwmmxt_load_reg(cpu_V0
, acc
);
2733 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2734 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2735 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2736 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2738 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2739 iwmmxt_store_reg(cpu_V0
, acc
);
2747 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2748 #define VFP_SREG(insn, bigbit, smallbit) \
2749 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2750 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2751 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2752 reg = (((insn) >> (bigbit)) & 0x0f) \
2753 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2755 if (insn & (1 << (smallbit))) \
2757 reg = ((insn) >> (bigbit)) & 0x0f; \
2760 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2761 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2762 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2763 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2764 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2765 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2767 /* Move between integer and VFP cores. */
2768 static TCGv_i32
gen_vfp_mrs(void)
2770 TCGv_i32 tmp
= tcg_temp_new_i32();
2771 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2775 static void gen_vfp_msr(TCGv_i32 tmp
)
2777 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2778 tcg_temp_free_i32(tmp
);
2781 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2783 TCGv_i32 tmp
= tcg_temp_new_i32();
2785 tcg_gen_shri_i32(var
, var
, shift
);
2786 tcg_gen_ext8u_i32(var
, var
);
2787 tcg_gen_shli_i32(tmp
, var
, 8);
2788 tcg_gen_or_i32(var
, var
, tmp
);
2789 tcg_gen_shli_i32(tmp
, var
, 16);
2790 tcg_gen_or_i32(var
, var
, tmp
);
2791 tcg_temp_free_i32(tmp
);
2794 static void gen_neon_dup_low16(TCGv_i32 var
)
2796 TCGv_i32 tmp
= tcg_temp_new_i32();
2797 tcg_gen_ext16u_i32(var
, var
);
2798 tcg_gen_shli_i32(tmp
, var
, 16);
2799 tcg_gen_or_i32(var
, var
, tmp
);
2800 tcg_temp_free_i32(tmp
);
2803 static void gen_neon_dup_high16(TCGv_i32 var
)
2805 TCGv_i32 tmp
= tcg_temp_new_i32();
2806 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2807 tcg_gen_shri_i32(tmp
, var
, 16);
2808 tcg_gen_or_i32(var
, var
, tmp
);
2809 tcg_temp_free_i32(tmp
);
2812 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2814 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2815 TCGv_i32 tmp
= tcg_temp_new_i32();
2818 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2819 gen_neon_dup_u8(tmp
, 0);
2822 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2823 gen_neon_dup_low16(tmp
);
2826 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2828 default: /* Avoid compiler warnings. */
2834 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2837 uint32_t cc
= extract32(insn
, 20, 2);
2840 TCGv_i64 frn
, frm
, dest
;
2841 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2843 zero
= tcg_const_i64(0);
2845 frn
= tcg_temp_new_i64();
2846 frm
= tcg_temp_new_i64();
2847 dest
= tcg_temp_new_i64();
2849 zf
= tcg_temp_new_i64();
2850 nf
= tcg_temp_new_i64();
2851 vf
= tcg_temp_new_i64();
2853 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2854 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2855 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2857 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2858 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2861 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2865 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2868 case 2: /* ge: N == V -> N ^ V == 0 */
2869 tmp
= tcg_temp_new_i64();
2870 tcg_gen_xor_i64(tmp
, vf
, nf
);
2871 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2873 tcg_temp_free_i64(tmp
);
2875 case 3: /* gt: !Z && N == V */
2876 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2878 tmp
= tcg_temp_new_i64();
2879 tcg_gen_xor_i64(tmp
, vf
, nf
);
2880 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2882 tcg_temp_free_i64(tmp
);
2885 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2886 tcg_temp_free_i64(frn
);
2887 tcg_temp_free_i64(frm
);
2888 tcg_temp_free_i64(dest
);
2890 tcg_temp_free_i64(zf
);
2891 tcg_temp_free_i64(nf
);
2892 tcg_temp_free_i64(vf
);
2894 tcg_temp_free_i64(zero
);
2896 TCGv_i32 frn
, frm
, dest
;
2899 zero
= tcg_const_i32(0);
2901 frn
= tcg_temp_new_i32();
2902 frm
= tcg_temp_new_i32();
2903 dest
= tcg_temp_new_i32();
2904 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2905 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2908 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2912 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2915 case 2: /* ge: N == V -> N ^ V == 0 */
2916 tmp
= tcg_temp_new_i32();
2917 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2918 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2920 tcg_temp_free_i32(tmp
);
2922 case 3: /* gt: !Z && N == V */
2923 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2925 tmp
= tcg_temp_new_i32();
2926 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2927 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2929 tcg_temp_free_i32(tmp
);
2932 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2933 tcg_temp_free_i32(frn
);
2934 tcg_temp_free_i32(frm
);
2935 tcg_temp_free_i32(dest
);
2937 tcg_temp_free_i32(zero
);
2943 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2944 uint32_t rm
, uint32_t dp
)
2946 uint32_t vmin
= extract32(insn
, 6, 1);
2947 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2950 TCGv_i64 frn
, frm
, dest
;
2952 frn
= tcg_temp_new_i64();
2953 frm
= tcg_temp_new_i64();
2954 dest
= tcg_temp_new_i64();
2956 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2957 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2959 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2961 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2963 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2964 tcg_temp_free_i64(frn
);
2965 tcg_temp_free_i64(frm
);
2966 tcg_temp_free_i64(dest
);
2968 TCGv_i32 frn
, frm
, dest
;
2970 frn
= tcg_temp_new_i32();
2971 frm
= tcg_temp_new_i32();
2972 dest
= tcg_temp_new_i32();
2974 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2975 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2977 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2979 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2981 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2982 tcg_temp_free_i32(frn
);
2983 tcg_temp_free_i32(frm
);
2984 tcg_temp_free_i32(dest
);
2987 tcg_temp_free_ptr(fpst
);
2991 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2994 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2997 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2998 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3003 tcg_op
= tcg_temp_new_i64();
3004 tcg_res
= tcg_temp_new_i64();
3005 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3006 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
3007 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3008 tcg_temp_free_i64(tcg_op
);
3009 tcg_temp_free_i64(tcg_res
);
3013 tcg_op
= tcg_temp_new_i32();
3014 tcg_res
= tcg_temp_new_i32();
3015 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3016 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
3017 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3018 tcg_temp_free_i32(tcg_op
);
3019 tcg_temp_free_i32(tcg_res
);
3022 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3023 tcg_temp_free_i32(tcg_rmode
);
3025 tcg_temp_free_ptr(fpst
);
3029 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3032 bool is_signed
= extract32(insn
, 7, 1);
3033 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3034 TCGv_i32 tcg_rmode
, tcg_shift
;
3036 tcg_shift
= tcg_const_i32(0);
3038 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3039 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3042 TCGv_i64 tcg_double
, tcg_res
;
3044 /* Rd is encoded as a single precision register even when the source
3045 * is double precision.
3047 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3048 tcg_double
= tcg_temp_new_i64();
3049 tcg_res
= tcg_temp_new_i64();
3050 tcg_tmp
= tcg_temp_new_i32();
3051 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3053 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3055 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3057 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3058 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3059 tcg_temp_free_i32(tcg_tmp
);
3060 tcg_temp_free_i64(tcg_res
);
3061 tcg_temp_free_i64(tcg_double
);
3063 TCGv_i32 tcg_single
, tcg_res
;
3064 tcg_single
= tcg_temp_new_i32();
3065 tcg_res
= tcg_temp_new_i32();
3066 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3068 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3070 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3072 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3073 tcg_temp_free_i32(tcg_res
);
3074 tcg_temp_free_i32(tcg_single
);
3077 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3078 tcg_temp_free_i32(tcg_rmode
);
3080 tcg_temp_free_i32(tcg_shift
);
3082 tcg_temp_free_ptr(fpst
);
3087 /* Table for converting the most common AArch32 encoding of
3088 * rounding mode to arm_fprounding order (which matches the
3089 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3091 static const uint8_t fp_decode_rm
[] = {
3098 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3100 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3102 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3107 VFP_DREG_D(rd
, insn
);
3108 VFP_DREG_N(rn
, insn
);
3109 VFP_DREG_M(rm
, insn
);
3111 rd
= VFP_SREG_D(insn
);
3112 rn
= VFP_SREG_N(insn
);
3113 rm
= VFP_SREG_M(insn
);
3116 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3117 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3118 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3119 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3120 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3121 /* VRINTA, VRINTN, VRINTP, VRINTM */
3122 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3123 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3124 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3125 /* VCVTA, VCVTN, VCVTP, VCVTM */
3126 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3127 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3132 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3133 (ie. an undefined instruction). */
3134 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3136 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3142 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3146 /* FIXME: this access check should not take precedence over UNDEF
3147 * for invalid encodings; we will generate incorrect syndrome information
3148 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3150 if (s
->fp_excp_el
) {
3151 gen_exception_insn(s
, 4, EXCP_UDEF
,
3152 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3156 if (!s
->vfp_enabled
) {
3157 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3158 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3160 rn
= (insn
>> 16) & 0xf;
3161 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3162 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3167 if (extract32(insn
, 28, 4) == 0xf) {
3168 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3169 * only used in v8 and above.
3171 return disas_vfp_v8_insn(s
, insn
);
3174 dp
= ((insn
& 0xf00) == 0xb00);
3175 switch ((insn
>> 24) & 0xf) {
3177 if (insn
& (1 << 4)) {
3178 /* single register transfer */
3179 rd
= (insn
>> 12) & 0xf;
3184 VFP_DREG_N(rn
, insn
);
3187 if (insn
& 0x00c00060
3188 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3192 pass
= (insn
>> 21) & 1;
3193 if (insn
& (1 << 22)) {
3195 offset
= ((insn
>> 5) & 3) * 8;
3196 } else if (insn
& (1 << 5)) {
3198 offset
= (insn
& (1 << 6)) ? 16 : 0;
3203 if (insn
& ARM_CP_RW_BIT
) {
3205 tmp
= neon_load_reg(rn
, pass
);
3209 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3210 if (insn
& (1 << 23))
3216 if (insn
& (1 << 23)) {
3218 tcg_gen_shri_i32(tmp
, tmp
, 16);
3224 tcg_gen_sari_i32(tmp
, tmp
, 16);
3233 store_reg(s
, rd
, tmp
);
3236 tmp
= load_reg(s
, rd
);
3237 if (insn
& (1 << 23)) {
3240 gen_neon_dup_u8(tmp
, 0);
3241 } else if (size
== 1) {
3242 gen_neon_dup_low16(tmp
);
3244 for (n
= 0; n
<= pass
* 2; n
++) {
3245 tmp2
= tcg_temp_new_i32();
3246 tcg_gen_mov_i32(tmp2
, tmp
);
3247 neon_store_reg(rn
, n
, tmp2
);
3249 neon_store_reg(rn
, n
, tmp
);
3254 tmp2
= neon_load_reg(rn
, pass
);
3255 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3256 tcg_temp_free_i32(tmp2
);
3259 tmp2
= neon_load_reg(rn
, pass
);
3260 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3261 tcg_temp_free_i32(tmp2
);
3266 neon_store_reg(rn
, pass
, tmp
);
3270 if ((insn
& 0x6f) != 0x00)
3272 rn
= VFP_SREG_N(insn
);
3273 if (insn
& ARM_CP_RW_BIT
) {
3275 if (insn
& (1 << 21)) {
3276 /* system register */
3281 /* VFP2 allows access to FSID from userspace.
3282 VFP3 restricts all id registers to privileged
3285 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3288 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3293 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3295 case ARM_VFP_FPINST
:
3296 case ARM_VFP_FPINST2
:
3297 /* Not present in VFP3. */
3299 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3302 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3306 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3307 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3309 tmp
= tcg_temp_new_i32();
3310 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3314 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3321 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3324 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3330 gen_mov_F0_vreg(0, rn
);
3331 tmp
= gen_vfp_mrs();
3334 /* Set the 4 flag bits in the CPSR. */
3336 tcg_temp_free_i32(tmp
);
3338 store_reg(s
, rd
, tmp
);
3342 if (insn
& (1 << 21)) {
3344 /* system register */
3349 /* Writes are ignored. */
3352 tmp
= load_reg(s
, rd
);
3353 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3354 tcg_temp_free_i32(tmp
);
3360 /* TODO: VFP subarchitecture support.
3361 * For now, keep the EN bit only */
3362 tmp
= load_reg(s
, rd
);
3363 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3364 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3367 case ARM_VFP_FPINST
:
3368 case ARM_VFP_FPINST2
:
3372 tmp
= load_reg(s
, rd
);
3373 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3379 tmp
= load_reg(s
, rd
);
3381 gen_mov_vreg_F0(0, rn
);
3386 /* data processing */
3387 /* The opcode is in bits 23, 21, 20 and 6. */
3388 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3392 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3394 /* rn is register number */
3395 VFP_DREG_N(rn
, insn
);
3398 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3399 ((rn
& 0x1e) == 0x6))) {
3400 /* Integer or single/half precision destination. */
3401 rd
= VFP_SREG_D(insn
);
3403 VFP_DREG_D(rd
, insn
);
3406 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3407 ((rn
& 0x1e) == 0x4))) {
3408 /* VCVT from int or half precision is always from S reg
3409 * regardless of dp bit. VCVT with immediate frac_bits
3410 * has same format as SREG_M.
3412 rm
= VFP_SREG_M(insn
);
3414 VFP_DREG_M(rm
, insn
);
3417 rn
= VFP_SREG_N(insn
);
3418 if (op
== 15 && rn
== 15) {
3419 /* Double precision destination. */
3420 VFP_DREG_D(rd
, insn
);
3422 rd
= VFP_SREG_D(insn
);
3424 /* NB that we implicitly rely on the encoding for the frac_bits
3425 * in VCVT of fixed to float being the same as that of an SREG_M
3427 rm
= VFP_SREG_M(insn
);
3430 veclen
= s
->vec_len
;
3431 if (op
== 15 && rn
> 3)
3434 /* Shut up compiler warnings. */
3445 /* Figure out what type of vector operation this is. */
3446 if ((rd
& bank_mask
) == 0) {
3451 delta_d
= (s
->vec_stride
>> 1) + 1;
3453 delta_d
= s
->vec_stride
+ 1;
3455 if ((rm
& bank_mask
) == 0) {
3456 /* mixed scalar/vector */
3465 /* Load the initial operands. */
3470 /* Integer source */
3471 gen_mov_F0_vreg(0, rm
);
3476 gen_mov_F0_vreg(dp
, rd
);
3477 gen_mov_F1_vreg(dp
, rm
);
3481 /* Compare with zero */
3482 gen_mov_F0_vreg(dp
, rd
);
3493 /* Source and destination the same. */
3494 gen_mov_F0_vreg(dp
, rd
);
3500 /* VCVTB, VCVTT: only present with the halfprec extension
3501 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3502 * (we choose to UNDEF)
3504 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3505 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3508 if (!extract32(rn
, 1, 1)) {
3509 /* Half precision source. */
3510 gen_mov_F0_vreg(0, rm
);
3513 /* Otherwise fall through */
3515 /* One source operand. */
3516 gen_mov_F0_vreg(dp
, rm
);
3520 /* Two source operands. */
3521 gen_mov_F0_vreg(dp
, rn
);
3522 gen_mov_F1_vreg(dp
, rm
);
3526 /* Perform the calculation. */
3528 case 0: /* VMLA: fd + (fn * fm) */
3529 /* Note that order of inputs to the add matters for NaNs */
3531 gen_mov_F0_vreg(dp
, rd
);
3534 case 1: /* VMLS: fd + -(fn * fm) */
3537 gen_mov_F0_vreg(dp
, rd
);
3540 case 2: /* VNMLS: -fd + (fn * fm) */
3541 /* Note that it isn't valid to replace (-A + B) with (B - A)
3542 * or similar plausible looking simplifications
3543 * because this will give wrong results for NaNs.
3546 gen_mov_F0_vreg(dp
, rd
);
3550 case 3: /* VNMLA: -fd + -(fn * fm) */
3553 gen_mov_F0_vreg(dp
, rd
);
3557 case 4: /* mul: fn * fm */
3560 case 5: /* nmul: -(fn * fm) */
3564 case 6: /* add: fn + fm */
3567 case 7: /* sub: fn - fm */
3570 case 8: /* div: fn / fm */
3573 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3574 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3575 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3576 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3577 /* These are fused multiply-add, and must be done as one
3578 * floating point operation with no rounding between the
3579 * multiplication and addition steps.
3580 * NB that doing the negations here as separate steps is
3581 * correct : an input NaN should come out with its sign bit
3582 * flipped if it is a negated-input.
3584 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3592 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3594 frd
= tcg_temp_new_i64();
3595 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3598 gen_helper_vfp_negd(frd
, frd
);
3600 fpst
= get_fpstatus_ptr(0);
3601 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3602 cpu_F1d
, frd
, fpst
);
3603 tcg_temp_free_ptr(fpst
);
3604 tcg_temp_free_i64(frd
);
3610 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3612 frd
= tcg_temp_new_i32();
3613 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3615 gen_helper_vfp_negs(frd
, frd
);
3617 fpst
= get_fpstatus_ptr(0);
3618 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3619 cpu_F1s
, frd
, fpst
);
3620 tcg_temp_free_ptr(fpst
);
3621 tcg_temp_free_i32(frd
);
3624 case 14: /* fconst */
3625 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3629 n
= (insn
<< 12) & 0x80000000;
3630 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3637 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3644 tcg_gen_movi_i32(cpu_F0s
, n
);
3647 case 15: /* extension space */
3661 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3662 tmp
= gen_vfp_mrs();
3663 tcg_gen_ext16u_i32(tmp
, tmp
);
3665 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3668 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3671 tcg_temp_free_i32(tmp
);
3673 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3674 tmp
= gen_vfp_mrs();
3675 tcg_gen_shri_i32(tmp
, tmp
, 16);
3677 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3680 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3683 tcg_temp_free_i32(tmp
);
3685 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3686 tmp
= tcg_temp_new_i32();
3688 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3691 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3694 gen_mov_F0_vreg(0, rd
);
3695 tmp2
= gen_vfp_mrs();
3696 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3697 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3698 tcg_temp_free_i32(tmp2
);
3701 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3702 tmp
= tcg_temp_new_i32();
3704 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3707 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3710 tcg_gen_shli_i32(tmp
, tmp
, 16);
3711 gen_mov_F0_vreg(0, rd
);
3712 tmp2
= gen_vfp_mrs();
3713 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3714 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3715 tcg_temp_free_i32(tmp2
);
3727 case 11: /* cmpez */
3731 case 12: /* vrintr */
3733 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3735 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3737 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3739 tcg_temp_free_ptr(fpst
);
3742 case 13: /* vrintz */
3744 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3746 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3747 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3749 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3751 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3753 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3754 tcg_temp_free_i32(tcg_rmode
);
3755 tcg_temp_free_ptr(fpst
);
3758 case 14: /* vrintx */
3760 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3762 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3764 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3766 tcg_temp_free_ptr(fpst
);
3769 case 15: /* single<->double conversion */
3771 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3773 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3775 case 16: /* fuito */
3776 gen_vfp_uito(dp
, 0);
3778 case 17: /* fsito */
3779 gen_vfp_sito(dp
, 0);
3781 case 20: /* fshto */
3782 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3785 gen_vfp_shto(dp
, 16 - rm
, 0);
3787 case 21: /* fslto */
3788 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3791 gen_vfp_slto(dp
, 32 - rm
, 0);
3793 case 22: /* fuhto */
3794 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3797 gen_vfp_uhto(dp
, 16 - rm
, 0);
3799 case 23: /* fulto */
3800 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3803 gen_vfp_ulto(dp
, 32 - rm
, 0);
3805 case 24: /* ftoui */
3806 gen_vfp_toui(dp
, 0);
3808 case 25: /* ftouiz */
3809 gen_vfp_touiz(dp
, 0);
3811 case 26: /* ftosi */
3812 gen_vfp_tosi(dp
, 0);
3814 case 27: /* ftosiz */
3815 gen_vfp_tosiz(dp
, 0);
3817 case 28: /* ftosh */
3818 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3821 gen_vfp_tosh(dp
, 16 - rm
, 0);
3823 case 29: /* ftosl */
3824 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3827 gen_vfp_tosl(dp
, 32 - rm
, 0);
3829 case 30: /* ftouh */
3830 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3833 gen_vfp_touh(dp
, 16 - rm
, 0);
3835 case 31: /* ftoul */
3836 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3839 gen_vfp_toul(dp
, 32 - rm
, 0);
3841 default: /* undefined */
3845 default: /* undefined */
3849 /* Write back the result. */
3850 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3851 /* Comparison, do nothing. */
3852 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3853 (rn
& 0x1e) == 0x6)) {
3854 /* VCVT double to int: always integer result.
3855 * VCVT double to half precision is always a single
3858 gen_mov_vreg_F0(0, rd
);
3859 } else if (op
== 15 && rn
== 15) {
3861 gen_mov_vreg_F0(!dp
, rd
);
3863 gen_mov_vreg_F0(dp
, rd
);
3866 /* break out of the loop if we have finished */
3870 if (op
== 15 && delta_m
== 0) {
3871 /* single source one-many */
3873 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3875 gen_mov_vreg_F0(dp
, rd
);
3879 /* Setup the next operands. */
3881 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3885 /* One source operand. */
3886 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3888 gen_mov_F0_vreg(dp
, rm
);
3890 /* Two source operands. */
3891 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3893 gen_mov_F0_vreg(dp
, rn
);
3895 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3897 gen_mov_F1_vreg(dp
, rm
);
3905 if ((insn
& 0x03e00000) == 0x00400000) {
3906 /* two-register transfer */
3907 rn
= (insn
>> 16) & 0xf;
3908 rd
= (insn
>> 12) & 0xf;
3910 VFP_DREG_M(rm
, insn
);
3912 rm
= VFP_SREG_M(insn
);
3915 if (insn
& ARM_CP_RW_BIT
) {
3918 gen_mov_F0_vreg(0, rm
* 2);
3919 tmp
= gen_vfp_mrs();
3920 store_reg(s
, rd
, tmp
);
3921 gen_mov_F0_vreg(0, rm
* 2 + 1);
3922 tmp
= gen_vfp_mrs();
3923 store_reg(s
, rn
, tmp
);
3925 gen_mov_F0_vreg(0, rm
);
3926 tmp
= gen_vfp_mrs();
3927 store_reg(s
, rd
, tmp
);
3928 gen_mov_F0_vreg(0, rm
+ 1);
3929 tmp
= gen_vfp_mrs();
3930 store_reg(s
, rn
, tmp
);
3935 tmp
= load_reg(s
, rd
);
3937 gen_mov_vreg_F0(0, rm
* 2);
3938 tmp
= load_reg(s
, rn
);
3940 gen_mov_vreg_F0(0, rm
* 2 + 1);
3942 tmp
= load_reg(s
, rd
);
3944 gen_mov_vreg_F0(0, rm
);
3945 tmp
= load_reg(s
, rn
);
3947 gen_mov_vreg_F0(0, rm
+ 1);
3952 rn
= (insn
>> 16) & 0xf;
3954 VFP_DREG_D(rd
, insn
);
3956 rd
= VFP_SREG_D(insn
);
3957 if ((insn
& 0x01200000) == 0x01000000) {
3958 /* Single load/store */
3959 offset
= (insn
& 0xff) << 2;
3960 if ((insn
& (1 << 23)) == 0)
3962 if (s
->thumb
&& rn
== 15) {
3963 /* This is actually UNPREDICTABLE */
3964 addr
= tcg_temp_new_i32();
3965 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3967 addr
= load_reg(s
, rn
);
3969 tcg_gen_addi_i32(addr
, addr
, offset
);
3970 if (insn
& (1 << 20)) {
3971 gen_vfp_ld(s
, dp
, addr
);
3972 gen_mov_vreg_F0(dp
, rd
);
3974 gen_mov_F0_vreg(dp
, rd
);
3975 gen_vfp_st(s
, dp
, addr
);
3977 tcg_temp_free_i32(addr
);
3979 /* load/store multiple */
3980 int w
= insn
& (1 << 21);
3982 n
= (insn
>> 1) & 0x7f;
3986 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3987 /* P == U , W == 1 => UNDEF */
3990 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3991 /* UNPREDICTABLE cases for bad immediates: we choose to
3992 * UNDEF to avoid generating huge numbers of TCG ops
3996 if (rn
== 15 && w
) {
3997 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4001 if (s
->thumb
&& rn
== 15) {
4002 /* This is actually UNPREDICTABLE */
4003 addr
= tcg_temp_new_i32();
4004 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4006 addr
= load_reg(s
, rn
);
4008 if (insn
& (1 << 24)) /* pre-decrement */
4009 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4015 for (i
= 0; i
< n
; i
++) {
4016 if (insn
& ARM_CP_RW_BIT
) {
4018 gen_vfp_ld(s
, dp
, addr
);
4019 gen_mov_vreg_F0(dp
, rd
+ i
);
4022 gen_mov_F0_vreg(dp
, rd
+ i
);
4023 gen_vfp_st(s
, dp
, addr
);
4025 tcg_gen_addi_i32(addr
, addr
, offset
);
4029 if (insn
& (1 << 24))
4030 offset
= -offset
* n
;
4031 else if (dp
&& (insn
& 1))
4037 tcg_gen_addi_i32(addr
, addr
, offset
);
4038 store_reg(s
, rn
, addr
);
4040 tcg_temp_free_i32(addr
);
4046 /* Should never happen. */
4052 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4054 TranslationBlock
*tb
;
4057 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
4059 gen_set_pc_im(s
, dest
);
4060 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
4062 gen_set_pc_im(s
, dest
);
4067 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4069 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
4070 /* An indirect jump so that we still trigger the debug exception. */
4075 gen_goto_tb(s
, 0, dest
);
4076 s
->is_jmp
= DISAS_TB_JUMP
;
4080 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4083 tcg_gen_sari_i32(t0
, t0
, 16);
4087 tcg_gen_sari_i32(t1
, t1
, 16);
4090 tcg_gen_mul_i32(t0
, t0
, t1
);
4093 /* Return the mask of PSR bits set by a MSR instruction. */
4094 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4099 if (flags
& (1 << 0))
4101 if (flags
& (1 << 1))
4103 if (flags
& (1 << 2))
4105 if (flags
& (1 << 3))
4108 /* Mask out undefined bits. */
4109 mask
&= ~CPSR_RESERVED
;
4110 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4113 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4114 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4116 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4117 mask
&= ~(CPSR_E
| CPSR_GE
);
4119 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4122 /* Mask out execution state and reserved bits. */
4124 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4126 /* Mask out privileged bits. */
4132 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4133 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4137 /* ??? This is also undefined in system mode. */
4141 tmp
= load_cpu_field(spsr
);
4142 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4143 tcg_gen_andi_i32(t0
, t0
, mask
);
4144 tcg_gen_or_i32(tmp
, tmp
, t0
);
4145 store_cpu_field(tmp
, spsr
);
4147 gen_set_cpsr(t0
, mask
);
4149 tcg_temp_free_i32(t0
);
4154 /* Returns nonzero if access to the PSR is not permitted. */
4155 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4158 tmp
= tcg_temp_new_i32();
4159 tcg_gen_movi_i32(tmp
, val
);
4160 return gen_set_psr(s
, mask
, spsr
, tmp
);
4163 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4164 int *tgtmode
, int *regno
)
4166 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4167 * the target mode and register number, and identify the various
4168 * unpredictable cases.
4169 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4170 * + executed in user mode
4171 * + using R15 as the src/dest register
4172 * + accessing an unimplemented register
4173 * + accessing a register that's inaccessible at current PL/security state*
4174 * + accessing a register that you could access with a different insn
4175 * We choose to UNDEF in all these cases.
4176 * Since we don't know which of the various AArch32 modes we are in
4177 * we have to defer some checks to runtime.
4178 * Accesses to Monitor mode registers from Secure EL1 (which implies
4179 * that EL3 is AArch64) must trap to EL3.
4181 * If the access checks fail this function will emit code to take
4182 * an exception and return false. Otherwise it will return true,
4183 * and set *tgtmode and *regno appropriately.
4185 int exc_target
= default_exception_el(s
);
4187 /* These instructions are present only in ARMv8, or in ARMv7 with the
4188 * Virtualization Extensions.
4190 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4191 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4195 if (IS_USER(s
) || rn
== 15) {
4199 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4200 * of registers into (r, sysm).
4203 /* SPSRs for other modes */
4205 case 0xe: /* SPSR_fiq */
4206 *tgtmode
= ARM_CPU_MODE_FIQ
;
4208 case 0x10: /* SPSR_irq */
4209 *tgtmode
= ARM_CPU_MODE_IRQ
;
4211 case 0x12: /* SPSR_svc */
4212 *tgtmode
= ARM_CPU_MODE_SVC
;
4214 case 0x14: /* SPSR_abt */
4215 *tgtmode
= ARM_CPU_MODE_ABT
;
4217 case 0x16: /* SPSR_und */
4218 *tgtmode
= ARM_CPU_MODE_UND
;
4220 case 0x1c: /* SPSR_mon */
4221 *tgtmode
= ARM_CPU_MODE_MON
;
4223 case 0x1e: /* SPSR_hyp */
4224 *tgtmode
= ARM_CPU_MODE_HYP
;
4226 default: /* unallocated */
4229 /* We arbitrarily assign SPSR a register number of 16. */
4232 /* general purpose registers for other modes */
4234 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4235 *tgtmode
= ARM_CPU_MODE_USR
;
4238 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4239 *tgtmode
= ARM_CPU_MODE_FIQ
;
4242 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4243 *tgtmode
= ARM_CPU_MODE_IRQ
;
4244 *regno
= sysm
& 1 ? 13 : 14;
4246 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4247 *tgtmode
= ARM_CPU_MODE_SVC
;
4248 *regno
= sysm
& 1 ? 13 : 14;
4250 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4251 *tgtmode
= ARM_CPU_MODE_ABT
;
4252 *regno
= sysm
& 1 ? 13 : 14;
4254 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4255 *tgtmode
= ARM_CPU_MODE_UND
;
4256 *regno
= sysm
& 1 ? 13 : 14;
4258 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4259 *tgtmode
= ARM_CPU_MODE_MON
;
4260 *regno
= sysm
& 1 ? 13 : 14;
4262 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4263 *tgtmode
= ARM_CPU_MODE_HYP
;
4264 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4265 *regno
= sysm
& 1 ? 13 : 17;
4267 default: /* unallocated */
4272 /* Catch the 'accessing inaccessible register' cases we can detect
4273 * at translate time.
4276 case ARM_CPU_MODE_MON
:
4277 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4280 if (s
->current_el
== 1) {
4281 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4282 * then accesses to Mon registers trap to EL3
4288 case ARM_CPU_MODE_HYP
:
4289 /* Note that we can forbid accesses from EL2 here because they
4290 * must be from Hyp mode itself
4292 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4303 /* If we get here then some access check did not pass */
4304 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4308 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4310 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4311 int tgtmode
= 0, regno
= 0;
4313 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4317 /* Sync state because msr_banked() can raise exceptions */
4318 gen_set_condexec(s
);
4319 gen_set_pc_im(s
, s
->pc
- 4);
4320 tcg_reg
= load_reg(s
, rn
);
4321 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4322 tcg_regno
= tcg_const_i32(regno
);
4323 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4324 tcg_temp_free_i32(tcg_tgtmode
);
4325 tcg_temp_free_i32(tcg_regno
);
4326 tcg_temp_free_i32(tcg_reg
);
4327 s
->is_jmp
= DISAS_UPDATE
;
4330 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4332 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4333 int tgtmode
= 0, regno
= 0;
4335 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4339 /* Sync state because mrs_banked() can raise exceptions */
4340 gen_set_condexec(s
);
4341 gen_set_pc_im(s
, s
->pc
- 4);
4342 tcg_reg
= tcg_temp_new_i32();
4343 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4344 tcg_regno
= tcg_const_i32(regno
);
4345 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4346 tcg_temp_free_i32(tcg_tgtmode
);
4347 tcg_temp_free_i32(tcg_regno
);
4348 store_reg(s
, rn
, tcg_reg
);
4349 s
->is_jmp
= DISAS_UPDATE
;
4352 /* Generate an old-style exception return. Marks pc as dead. */
4353 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4356 store_reg(s
, 15, pc
);
4357 tmp
= load_cpu_field(spsr
);
4358 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
4359 tcg_temp_free_i32(tmp
);
4360 s
->is_jmp
= DISAS_JUMP
;
4363 /* Generate a v6 exception return. Marks both values as dead. */
4364 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4366 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4367 tcg_temp_free_i32(cpsr
);
4368 store_reg(s
, 15, pc
);
4369 s
->is_jmp
= DISAS_JUMP
;
4372 static void gen_nop_hint(DisasContext
*s
, int val
)
4376 gen_set_pc_im(s
, s
->pc
);
4377 s
->is_jmp
= DISAS_YIELD
;
4380 gen_set_pc_im(s
, s
->pc
);
4381 s
->is_jmp
= DISAS_WFI
;
4384 gen_set_pc_im(s
, s
->pc
);
4385 s
->is_jmp
= DISAS_WFE
;
4389 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4395 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4397 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4400 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4401 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4402 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4407 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4410 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4411 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4412 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4417 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4418 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4419 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4420 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4421 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4423 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4424 switch ((size << 1) | u) { \
4426 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4429 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4432 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4435 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4438 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4441 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4443 default: return 1; \
4446 #define GEN_NEON_INTEGER_OP(name) do { \
4447 switch ((size << 1) | u) { \
4449 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4452 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4455 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4458 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4461 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4464 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4466 default: return 1; \
4469 static TCGv_i32
neon_load_scratch(int scratch
)
4471 TCGv_i32 tmp
= tcg_temp_new_i32();
4472 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4476 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4478 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4479 tcg_temp_free_i32(var
);
4482 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4486 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4488 gen_neon_dup_high16(tmp
);
4490 gen_neon_dup_low16(tmp
);
4493 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4498 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4501 if (!q
&& size
== 2) {
4504 tmp
= tcg_const_i32(rd
);
4505 tmp2
= tcg_const_i32(rm
);
4509 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4512 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4515 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4523 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4526 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4532 tcg_temp_free_i32(tmp
);
4533 tcg_temp_free_i32(tmp2
);
4537 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4540 if (!q
&& size
== 2) {
4543 tmp
= tcg_const_i32(rd
);
4544 tmp2
= tcg_const_i32(rm
);
4548 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4551 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4554 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4562 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4565 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4571 tcg_temp_free_i32(tmp
);
4572 tcg_temp_free_i32(tmp2
);
4576 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4580 rd
= tcg_temp_new_i32();
4581 tmp
= tcg_temp_new_i32();
4583 tcg_gen_shli_i32(rd
, t0
, 8);
4584 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4585 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4586 tcg_gen_or_i32(rd
, rd
, tmp
);
4588 tcg_gen_shri_i32(t1
, t1
, 8);
4589 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4590 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4591 tcg_gen_or_i32(t1
, t1
, tmp
);
4592 tcg_gen_mov_i32(t0
, rd
);
4594 tcg_temp_free_i32(tmp
);
4595 tcg_temp_free_i32(rd
);
4598 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4602 rd
= tcg_temp_new_i32();
4603 tmp
= tcg_temp_new_i32();
4605 tcg_gen_shli_i32(rd
, t0
, 16);
4606 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4607 tcg_gen_or_i32(rd
, rd
, tmp
);
4608 tcg_gen_shri_i32(t1
, t1
, 16);
4609 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4610 tcg_gen_or_i32(t1
, t1
, tmp
);
4611 tcg_gen_mov_i32(t0
, rd
);
4613 tcg_temp_free_i32(tmp
);
4614 tcg_temp_free_i32(rd
);
4622 } neon_ls_element_type
[11] = {
4636 /* Translate a NEON load/store element instruction. Return nonzero if the
4637 instruction is invalid. */
4638 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4657 /* FIXME: this access check should not take precedence over UNDEF
4658 * for invalid encodings; we will generate incorrect syndrome information
4659 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4661 if (s
->fp_excp_el
) {
4662 gen_exception_insn(s
, 4, EXCP_UDEF
,
4663 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4667 if (!s
->vfp_enabled
)
4669 VFP_DREG_D(rd
, insn
);
4670 rn
= (insn
>> 16) & 0xf;
4672 load
= (insn
& (1 << 21)) != 0;
4673 if ((insn
& (1 << 23)) == 0) {
4674 /* Load store all elements. */
4675 op
= (insn
>> 8) & 0xf;
4676 size
= (insn
>> 6) & 3;
4679 /* Catch UNDEF cases for bad values of align field */
4682 if (((insn
>> 5) & 1) == 1) {
4687 if (((insn
>> 4) & 3) == 3) {
4694 nregs
= neon_ls_element_type
[op
].nregs
;
4695 interleave
= neon_ls_element_type
[op
].interleave
;
4696 spacing
= neon_ls_element_type
[op
].spacing
;
4697 if (size
== 3 && (interleave
| spacing
) != 1)
4699 addr
= tcg_temp_new_i32();
4700 load_reg_var(s
, addr
, rn
);
4701 stride
= (1 << size
) * interleave
;
4702 for (reg
= 0; reg
< nregs
; reg
++) {
4703 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4704 load_reg_var(s
, addr
, rn
);
4705 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4706 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4707 load_reg_var(s
, addr
, rn
);
4708 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4711 tmp64
= tcg_temp_new_i64();
4713 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4714 neon_store_reg64(tmp64
, rd
);
4716 neon_load_reg64(tmp64
, rd
);
4717 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4719 tcg_temp_free_i64(tmp64
);
4720 tcg_gen_addi_i32(addr
, addr
, stride
);
4722 for (pass
= 0; pass
< 2; pass
++) {
4725 tmp
= tcg_temp_new_i32();
4726 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4727 neon_store_reg(rd
, pass
, tmp
);
4729 tmp
= neon_load_reg(rd
, pass
);
4730 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4731 tcg_temp_free_i32(tmp
);
4733 tcg_gen_addi_i32(addr
, addr
, stride
);
4734 } else if (size
== 1) {
4736 tmp
= tcg_temp_new_i32();
4737 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4738 tcg_gen_addi_i32(addr
, addr
, stride
);
4739 tmp2
= tcg_temp_new_i32();
4740 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4741 tcg_gen_addi_i32(addr
, addr
, stride
);
4742 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4743 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4744 tcg_temp_free_i32(tmp2
);
4745 neon_store_reg(rd
, pass
, tmp
);
4747 tmp
= neon_load_reg(rd
, pass
);
4748 tmp2
= tcg_temp_new_i32();
4749 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4750 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4751 tcg_temp_free_i32(tmp
);
4752 tcg_gen_addi_i32(addr
, addr
, stride
);
4753 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4754 tcg_temp_free_i32(tmp2
);
4755 tcg_gen_addi_i32(addr
, addr
, stride
);
4757 } else /* size == 0 */ {
4759 TCGV_UNUSED_I32(tmp2
);
4760 for (n
= 0; n
< 4; n
++) {
4761 tmp
= tcg_temp_new_i32();
4762 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4763 tcg_gen_addi_i32(addr
, addr
, stride
);
4767 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4768 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4769 tcg_temp_free_i32(tmp
);
4772 neon_store_reg(rd
, pass
, tmp2
);
4774 tmp2
= neon_load_reg(rd
, pass
);
4775 for (n
= 0; n
< 4; n
++) {
4776 tmp
= tcg_temp_new_i32();
4778 tcg_gen_mov_i32(tmp
, tmp2
);
4780 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4782 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4783 tcg_temp_free_i32(tmp
);
4784 tcg_gen_addi_i32(addr
, addr
, stride
);
4786 tcg_temp_free_i32(tmp2
);
4793 tcg_temp_free_i32(addr
);
4796 size
= (insn
>> 10) & 3;
4798 /* Load single element to all lanes. */
4799 int a
= (insn
>> 4) & 1;
4803 size
= (insn
>> 6) & 3;
4804 nregs
= ((insn
>> 8) & 3) + 1;
4807 if (nregs
!= 4 || a
== 0) {
4810 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4813 if (nregs
== 1 && a
== 1 && size
== 0) {
4816 if (nregs
== 3 && a
== 1) {
4819 addr
= tcg_temp_new_i32();
4820 load_reg_var(s
, addr
, rn
);
4822 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4823 tmp
= gen_load_and_replicate(s
, addr
, size
);
4824 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4825 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4826 if (insn
& (1 << 5)) {
4827 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4828 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4830 tcg_temp_free_i32(tmp
);
4832 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4833 stride
= (insn
& (1 << 5)) ? 2 : 1;
4834 for (reg
= 0; reg
< nregs
; reg
++) {
4835 tmp
= gen_load_and_replicate(s
, addr
, size
);
4836 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4837 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4838 tcg_temp_free_i32(tmp
);
4839 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4843 tcg_temp_free_i32(addr
);
4844 stride
= (1 << size
) * nregs
;
4846 /* Single element. */
4847 int idx
= (insn
>> 4) & 0xf;
4848 pass
= (insn
>> 7) & 1;
4851 shift
= ((insn
>> 5) & 3) * 8;
4855 shift
= ((insn
>> 6) & 1) * 16;
4856 stride
= (insn
& (1 << 5)) ? 2 : 1;
4860 stride
= (insn
& (1 << 6)) ? 2 : 1;
4865 nregs
= ((insn
>> 8) & 3) + 1;
4866 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4869 if (((idx
& (1 << size
)) != 0) ||
4870 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4875 if ((idx
& 1) != 0) {
4880 if (size
== 2 && (idx
& 2) != 0) {
4885 if ((size
== 2) && ((idx
& 3) == 3)) {
4892 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4893 /* Attempts to write off the end of the register file
4894 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4895 * the neon_load_reg() would write off the end of the array.
4899 addr
= tcg_temp_new_i32();
4900 load_reg_var(s
, addr
, rn
);
4901 for (reg
= 0; reg
< nregs
; reg
++) {
4903 tmp
= tcg_temp_new_i32();
4906 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4909 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4912 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4914 default: /* Avoid compiler warnings. */
4918 tmp2
= neon_load_reg(rd
, pass
);
4919 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4920 shift
, size
? 16 : 8);
4921 tcg_temp_free_i32(tmp2
);
4923 neon_store_reg(rd
, pass
, tmp
);
4924 } else { /* Store */
4925 tmp
= neon_load_reg(rd
, pass
);
4927 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4930 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4933 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4936 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4939 tcg_temp_free_i32(tmp
);
4942 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4944 tcg_temp_free_i32(addr
);
4945 stride
= nregs
* (1 << size
);
4951 base
= load_reg(s
, rn
);
4953 tcg_gen_addi_i32(base
, base
, stride
);
4956 index
= load_reg(s
, rm
);
4957 tcg_gen_add_i32(base
, base
, index
);
4958 tcg_temp_free_i32(index
);
4960 store_reg(s
, rn
, base
);
4965 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4966 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4968 tcg_gen_and_i32(t
, t
, c
);
4969 tcg_gen_andc_i32(f
, f
, c
);
4970 tcg_gen_or_i32(dest
, t
, f
);
4973 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4976 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4977 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4978 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4983 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4986 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4987 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4988 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4993 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4996 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4997 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4998 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5003 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5006 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5007 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5008 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5013 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5019 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5020 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5025 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5026 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5033 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5034 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5039 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5040 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5047 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5051 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5052 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5053 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5058 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5059 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5060 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5064 tcg_temp_free_i32(src
);
5067 static inline void gen_neon_addl(int size
)
5070 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5071 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5072 case 2: tcg_gen_add_i64(CPU_V001
); break;
5077 static inline void gen_neon_subl(int size
)
5080 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5081 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5082 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5087 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5090 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5091 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5093 tcg_gen_neg_i64(var
, var
);
5099 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5102 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5103 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5108 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5113 switch ((size
<< 1) | u
) {
5114 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5115 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5116 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5117 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5119 tmp
= gen_muls_i64_i32(a
, b
);
5120 tcg_gen_mov_i64(dest
, tmp
);
5121 tcg_temp_free_i64(tmp
);
5124 tmp
= gen_mulu_i64_i32(a
, b
);
5125 tcg_gen_mov_i64(dest
, tmp
);
5126 tcg_temp_free_i64(tmp
);
5131 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5132 Don't forget to clean them now. */
5134 tcg_temp_free_i32(a
);
5135 tcg_temp_free_i32(b
);
5139 static void gen_neon_narrow_op(int op
, int u
, int size
,
5140 TCGv_i32 dest
, TCGv_i64 src
)
5144 gen_neon_unarrow_sats(size
, dest
, src
);
5146 gen_neon_narrow(size
, dest
, src
);
5150 gen_neon_narrow_satu(size
, dest
, src
);
5152 gen_neon_narrow_sats(size
, dest
, src
);
5157 /* Symbolic constants for op fields for Neon 3-register same-length.
5158 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5161 #define NEON_3R_VHADD 0
5162 #define NEON_3R_VQADD 1
5163 #define NEON_3R_VRHADD 2
5164 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5165 #define NEON_3R_VHSUB 4
5166 #define NEON_3R_VQSUB 5
5167 #define NEON_3R_VCGT 6
5168 #define NEON_3R_VCGE 7
5169 #define NEON_3R_VSHL 8
5170 #define NEON_3R_VQSHL 9
5171 #define NEON_3R_VRSHL 10
5172 #define NEON_3R_VQRSHL 11
5173 #define NEON_3R_VMAX 12
5174 #define NEON_3R_VMIN 13
5175 #define NEON_3R_VABD 14
5176 #define NEON_3R_VABA 15
5177 #define NEON_3R_VADD_VSUB 16
5178 #define NEON_3R_VTST_VCEQ 17
5179 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5180 #define NEON_3R_VMUL 19
5181 #define NEON_3R_VPMAX 20
5182 #define NEON_3R_VPMIN 21
5183 #define NEON_3R_VQDMULH_VQRDMULH 22
5184 #define NEON_3R_VPADD 23
5185 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5186 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5187 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5188 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5189 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5190 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5191 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5192 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5194 static const uint8_t neon_3r_sizes
[] = {
5195 [NEON_3R_VHADD
] = 0x7,
5196 [NEON_3R_VQADD
] = 0xf,
5197 [NEON_3R_VRHADD
] = 0x7,
5198 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5199 [NEON_3R_VHSUB
] = 0x7,
5200 [NEON_3R_VQSUB
] = 0xf,
5201 [NEON_3R_VCGT
] = 0x7,
5202 [NEON_3R_VCGE
] = 0x7,
5203 [NEON_3R_VSHL
] = 0xf,
5204 [NEON_3R_VQSHL
] = 0xf,
5205 [NEON_3R_VRSHL
] = 0xf,
5206 [NEON_3R_VQRSHL
] = 0xf,
5207 [NEON_3R_VMAX
] = 0x7,
5208 [NEON_3R_VMIN
] = 0x7,
5209 [NEON_3R_VABD
] = 0x7,
5210 [NEON_3R_VABA
] = 0x7,
5211 [NEON_3R_VADD_VSUB
] = 0xf,
5212 [NEON_3R_VTST_VCEQ
] = 0x7,
5213 [NEON_3R_VML
] = 0x7,
5214 [NEON_3R_VMUL
] = 0x7,
5215 [NEON_3R_VPMAX
] = 0x7,
5216 [NEON_3R_VPMIN
] = 0x7,
5217 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5218 [NEON_3R_VPADD
] = 0x7,
5219 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5220 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5221 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5222 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5223 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5224 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5225 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5226 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5229 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5230 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5233 #define NEON_2RM_VREV64 0
5234 #define NEON_2RM_VREV32 1
5235 #define NEON_2RM_VREV16 2
5236 #define NEON_2RM_VPADDL 4
5237 #define NEON_2RM_VPADDL_U 5
5238 #define NEON_2RM_AESE 6 /* Includes AESD */
5239 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5240 #define NEON_2RM_VCLS 8
5241 #define NEON_2RM_VCLZ 9
5242 #define NEON_2RM_VCNT 10
5243 #define NEON_2RM_VMVN 11
5244 #define NEON_2RM_VPADAL 12
5245 #define NEON_2RM_VPADAL_U 13
5246 #define NEON_2RM_VQABS 14
5247 #define NEON_2RM_VQNEG 15
5248 #define NEON_2RM_VCGT0 16
5249 #define NEON_2RM_VCGE0 17
5250 #define NEON_2RM_VCEQ0 18
5251 #define NEON_2RM_VCLE0 19
5252 #define NEON_2RM_VCLT0 20
5253 #define NEON_2RM_SHA1H 21
5254 #define NEON_2RM_VABS 22
5255 #define NEON_2RM_VNEG 23
5256 #define NEON_2RM_VCGT0_F 24
5257 #define NEON_2RM_VCGE0_F 25
5258 #define NEON_2RM_VCEQ0_F 26
5259 #define NEON_2RM_VCLE0_F 27
5260 #define NEON_2RM_VCLT0_F 28
5261 #define NEON_2RM_VABS_F 30
5262 #define NEON_2RM_VNEG_F 31
5263 #define NEON_2RM_VSWP 32
5264 #define NEON_2RM_VTRN 33
5265 #define NEON_2RM_VUZP 34
5266 #define NEON_2RM_VZIP 35
5267 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5268 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5269 #define NEON_2RM_VSHLL 38
5270 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5271 #define NEON_2RM_VRINTN 40
5272 #define NEON_2RM_VRINTX 41
5273 #define NEON_2RM_VRINTA 42
5274 #define NEON_2RM_VRINTZ 43
5275 #define NEON_2RM_VCVT_F16_F32 44
5276 #define NEON_2RM_VRINTM 45
5277 #define NEON_2RM_VCVT_F32_F16 46
5278 #define NEON_2RM_VRINTP 47
5279 #define NEON_2RM_VCVTAU 48
5280 #define NEON_2RM_VCVTAS 49
5281 #define NEON_2RM_VCVTNU 50
5282 #define NEON_2RM_VCVTNS 51
5283 #define NEON_2RM_VCVTPU 52
5284 #define NEON_2RM_VCVTPS 53
5285 #define NEON_2RM_VCVTMU 54
5286 #define NEON_2RM_VCVTMS 55
5287 #define NEON_2RM_VRECPE 56
5288 #define NEON_2RM_VRSQRTE 57
5289 #define NEON_2RM_VRECPE_F 58
5290 #define NEON_2RM_VRSQRTE_F 59
5291 #define NEON_2RM_VCVT_FS 60
5292 #define NEON_2RM_VCVT_FU 61
5293 #define NEON_2RM_VCVT_SF 62
5294 #define NEON_2RM_VCVT_UF 63
5296 static int neon_2rm_is_float_op(int op
)
5298 /* Return true if this neon 2reg-misc op is float-to-float */
5299 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5300 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5301 op
== NEON_2RM_VRINTM
||
5302 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5303 op
>= NEON_2RM_VRECPE_F
);
5306 /* Each entry in this array has bit n set if the insn allows
5307 * size value n (otherwise it will UNDEF). Since unallocated
5308 * op values will have no bits set they always UNDEF.
5310 static const uint8_t neon_2rm_sizes
[] = {
5311 [NEON_2RM_VREV64
] = 0x7,
5312 [NEON_2RM_VREV32
] = 0x3,
5313 [NEON_2RM_VREV16
] = 0x1,
5314 [NEON_2RM_VPADDL
] = 0x7,
5315 [NEON_2RM_VPADDL_U
] = 0x7,
5316 [NEON_2RM_AESE
] = 0x1,
5317 [NEON_2RM_AESMC
] = 0x1,
5318 [NEON_2RM_VCLS
] = 0x7,
5319 [NEON_2RM_VCLZ
] = 0x7,
5320 [NEON_2RM_VCNT
] = 0x1,
5321 [NEON_2RM_VMVN
] = 0x1,
5322 [NEON_2RM_VPADAL
] = 0x7,
5323 [NEON_2RM_VPADAL_U
] = 0x7,
5324 [NEON_2RM_VQABS
] = 0x7,
5325 [NEON_2RM_VQNEG
] = 0x7,
5326 [NEON_2RM_VCGT0
] = 0x7,
5327 [NEON_2RM_VCGE0
] = 0x7,
5328 [NEON_2RM_VCEQ0
] = 0x7,
5329 [NEON_2RM_VCLE0
] = 0x7,
5330 [NEON_2RM_VCLT0
] = 0x7,
5331 [NEON_2RM_SHA1H
] = 0x4,
5332 [NEON_2RM_VABS
] = 0x7,
5333 [NEON_2RM_VNEG
] = 0x7,
5334 [NEON_2RM_VCGT0_F
] = 0x4,
5335 [NEON_2RM_VCGE0_F
] = 0x4,
5336 [NEON_2RM_VCEQ0_F
] = 0x4,
5337 [NEON_2RM_VCLE0_F
] = 0x4,
5338 [NEON_2RM_VCLT0_F
] = 0x4,
5339 [NEON_2RM_VABS_F
] = 0x4,
5340 [NEON_2RM_VNEG_F
] = 0x4,
5341 [NEON_2RM_VSWP
] = 0x1,
5342 [NEON_2RM_VTRN
] = 0x7,
5343 [NEON_2RM_VUZP
] = 0x7,
5344 [NEON_2RM_VZIP
] = 0x7,
5345 [NEON_2RM_VMOVN
] = 0x7,
5346 [NEON_2RM_VQMOVN
] = 0x7,
5347 [NEON_2RM_VSHLL
] = 0x7,
5348 [NEON_2RM_SHA1SU1
] = 0x4,
5349 [NEON_2RM_VRINTN
] = 0x4,
5350 [NEON_2RM_VRINTX
] = 0x4,
5351 [NEON_2RM_VRINTA
] = 0x4,
5352 [NEON_2RM_VRINTZ
] = 0x4,
5353 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5354 [NEON_2RM_VRINTM
] = 0x4,
5355 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5356 [NEON_2RM_VRINTP
] = 0x4,
5357 [NEON_2RM_VCVTAU
] = 0x4,
5358 [NEON_2RM_VCVTAS
] = 0x4,
5359 [NEON_2RM_VCVTNU
] = 0x4,
5360 [NEON_2RM_VCVTNS
] = 0x4,
5361 [NEON_2RM_VCVTPU
] = 0x4,
5362 [NEON_2RM_VCVTPS
] = 0x4,
5363 [NEON_2RM_VCVTMU
] = 0x4,
5364 [NEON_2RM_VCVTMS
] = 0x4,
5365 [NEON_2RM_VRECPE
] = 0x4,
5366 [NEON_2RM_VRSQRTE
] = 0x4,
5367 [NEON_2RM_VRECPE_F
] = 0x4,
5368 [NEON_2RM_VRSQRTE_F
] = 0x4,
5369 [NEON_2RM_VCVT_FS
] = 0x4,
5370 [NEON_2RM_VCVT_FU
] = 0x4,
5371 [NEON_2RM_VCVT_SF
] = 0x4,
5372 [NEON_2RM_VCVT_UF
] = 0x4,
5375 /* Translate a NEON data processing instruction. Return nonzero if the
5376 instruction is invalid.
5377 We process data in a mixture of 32-bit and 64-bit chunks.
5378 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5380 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5392 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5395 /* FIXME: this access check should not take precedence over UNDEF
5396 * for invalid encodings; we will generate incorrect syndrome information
5397 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5399 if (s
->fp_excp_el
) {
5400 gen_exception_insn(s
, 4, EXCP_UDEF
,
5401 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5405 if (!s
->vfp_enabled
)
5407 q
= (insn
& (1 << 6)) != 0;
5408 u
= (insn
>> 24) & 1;
5409 VFP_DREG_D(rd
, insn
);
5410 VFP_DREG_N(rn
, insn
);
5411 VFP_DREG_M(rm
, insn
);
5412 size
= (insn
>> 20) & 3;
5413 if ((insn
& (1 << 23)) == 0) {
5414 /* Three register same length. */
5415 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5416 /* Catch invalid op and bad size combinations: UNDEF */
5417 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5420 /* All insns of this form UNDEF for either this condition or the
5421 * superset of cases "Q==1"; we catch the latter later.
5423 if (q
&& ((rd
| rn
| rm
) & 1)) {
5427 * The SHA-1/SHA-256 3-register instructions require special treatment
5428 * here, as their size field is overloaded as an op type selector, and
5429 * they all consume their input in a single pass.
5431 if (op
== NEON_3R_SHA
) {
5435 if (!u
) { /* SHA-1 */
5436 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5439 tmp
= tcg_const_i32(rd
);
5440 tmp2
= tcg_const_i32(rn
);
5441 tmp3
= tcg_const_i32(rm
);
5442 tmp4
= tcg_const_i32(size
);
5443 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5444 tcg_temp_free_i32(tmp4
);
5445 } else { /* SHA-256 */
5446 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5449 tmp
= tcg_const_i32(rd
);
5450 tmp2
= tcg_const_i32(rn
);
5451 tmp3
= tcg_const_i32(rm
);
5454 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5457 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5460 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5464 tcg_temp_free_i32(tmp
);
5465 tcg_temp_free_i32(tmp2
);
5466 tcg_temp_free_i32(tmp3
);
5469 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5470 /* 64-bit element instructions. */
5471 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5472 neon_load_reg64(cpu_V0
, rn
+ pass
);
5473 neon_load_reg64(cpu_V1
, rm
+ pass
);
5477 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5480 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5486 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5489 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5495 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5497 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5502 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5505 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5511 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5513 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5516 case NEON_3R_VQRSHL
:
5518 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5521 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5525 case NEON_3R_VADD_VSUB
:
5527 tcg_gen_sub_i64(CPU_V001
);
5529 tcg_gen_add_i64(CPU_V001
);
5535 neon_store_reg64(cpu_V0
, rd
+ pass
);
5544 case NEON_3R_VQRSHL
:
5547 /* Shift instruction operands are reversed. */
5562 case NEON_3R_FLOAT_ARITH
:
5563 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5565 case NEON_3R_FLOAT_MINMAX
:
5566 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5568 case NEON_3R_FLOAT_CMP
:
5570 /* no encoding for U=0 C=1x */
5574 case NEON_3R_FLOAT_ACMP
:
5579 case NEON_3R_FLOAT_MISC
:
5580 /* VMAXNM/VMINNM in ARMv8 */
5581 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5586 if (u
&& (size
!= 0)) {
5587 /* UNDEF on invalid size for polynomial subcase */
5592 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5600 if (pairwise
&& q
) {
5601 /* All the pairwise insns UNDEF if Q is set */
5605 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5610 tmp
= neon_load_reg(rn
, 0);
5611 tmp2
= neon_load_reg(rn
, 1);
5613 tmp
= neon_load_reg(rm
, 0);
5614 tmp2
= neon_load_reg(rm
, 1);
5618 tmp
= neon_load_reg(rn
, pass
);
5619 tmp2
= neon_load_reg(rm
, pass
);
5623 GEN_NEON_INTEGER_OP(hadd
);
5626 GEN_NEON_INTEGER_OP_ENV(qadd
);
5628 case NEON_3R_VRHADD
:
5629 GEN_NEON_INTEGER_OP(rhadd
);
5631 case NEON_3R_LOGIC
: /* Logic ops. */
5632 switch ((u
<< 2) | size
) {
5634 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5637 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5640 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5643 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5646 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5649 tmp3
= neon_load_reg(rd
, pass
);
5650 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5651 tcg_temp_free_i32(tmp3
);
5654 tmp3
= neon_load_reg(rd
, pass
);
5655 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5656 tcg_temp_free_i32(tmp3
);
5659 tmp3
= neon_load_reg(rd
, pass
);
5660 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5661 tcg_temp_free_i32(tmp3
);
5666 GEN_NEON_INTEGER_OP(hsub
);
5669 GEN_NEON_INTEGER_OP_ENV(qsub
);
5672 GEN_NEON_INTEGER_OP(cgt
);
5675 GEN_NEON_INTEGER_OP(cge
);
5678 GEN_NEON_INTEGER_OP(shl
);
5681 GEN_NEON_INTEGER_OP_ENV(qshl
);
5684 GEN_NEON_INTEGER_OP(rshl
);
5686 case NEON_3R_VQRSHL
:
5687 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5690 GEN_NEON_INTEGER_OP(max
);
5693 GEN_NEON_INTEGER_OP(min
);
5696 GEN_NEON_INTEGER_OP(abd
);
5699 GEN_NEON_INTEGER_OP(abd
);
5700 tcg_temp_free_i32(tmp2
);
5701 tmp2
= neon_load_reg(rd
, pass
);
5702 gen_neon_add(size
, tmp
, tmp2
);
5704 case NEON_3R_VADD_VSUB
:
5705 if (!u
) { /* VADD */
5706 gen_neon_add(size
, tmp
, tmp2
);
5709 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5710 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5711 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5716 case NEON_3R_VTST_VCEQ
:
5717 if (!u
) { /* VTST */
5719 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5720 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5721 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5726 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5727 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5728 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5733 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5735 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5736 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5737 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5740 tcg_temp_free_i32(tmp2
);
5741 tmp2
= neon_load_reg(rd
, pass
);
5743 gen_neon_rsb(size
, tmp
, tmp2
);
5745 gen_neon_add(size
, tmp
, tmp2
);
5749 if (u
) { /* polynomial */
5750 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5751 } else { /* Integer */
5753 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5754 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5755 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5761 GEN_NEON_INTEGER_OP(pmax
);
5764 GEN_NEON_INTEGER_OP(pmin
);
5766 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5767 if (!u
) { /* VQDMULH */
5770 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5773 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5777 } else { /* VQRDMULH */
5780 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5783 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5791 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5792 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5793 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5797 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5799 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5800 switch ((u
<< 2) | size
) {
5803 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5806 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5809 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5814 tcg_temp_free_ptr(fpstatus
);
5817 case NEON_3R_FLOAT_MULTIPLY
:
5819 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5820 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5822 tcg_temp_free_i32(tmp2
);
5823 tmp2
= neon_load_reg(rd
, pass
);
5825 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5827 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5830 tcg_temp_free_ptr(fpstatus
);
5833 case NEON_3R_FLOAT_CMP
:
5835 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5837 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5840 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5842 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5845 tcg_temp_free_ptr(fpstatus
);
5848 case NEON_3R_FLOAT_ACMP
:
5850 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5852 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5854 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5856 tcg_temp_free_ptr(fpstatus
);
5859 case NEON_3R_FLOAT_MINMAX
:
5861 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5863 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5865 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5867 tcg_temp_free_ptr(fpstatus
);
5870 case NEON_3R_FLOAT_MISC
:
5873 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5875 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5877 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5879 tcg_temp_free_ptr(fpstatus
);
5882 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5884 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5890 /* VFMA, VFMS: fused multiply-add */
5891 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5892 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5895 gen_helper_vfp_negs(tmp
, tmp
);
5897 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5898 tcg_temp_free_i32(tmp3
);
5899 tcg_temp_free_ptr(fpstatus
);
5905 tcg_temp_free_i32(tmp2
);
5907 /* Save the result. For elementwise operations we can put it
5908 straight into the destination register. For pairwise operations
5909 we have to be careful to avoid clobbering the source operands. */
5910 if (pairwise
&& rd
== rm
) {
5911 neon_store_scratch(pass
, tmp
);
5913 neon_store_reg(rd
, pass
, tmp
);
5917 if (pairwise
&& rd
== rm
) {
5918 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5919 tmp
= neon_load_scratch(pass
);
5920 neon_store_reg(rd
, pass
, tmp
);
5923 /* End of 3 register same size operations. */
5924 } else if (insn
& (1 << 4)) {
5925 if ((insn
& 0x00380080) != 0) {
5926 /* Two registers and shift. */
5927 op
= (insn
>> 8) & 0xf;
5928 if (insn
& (1 << 7)) {
5936 while ((insn
& (1 << (size
+ 19))) == 0)
5939 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5940 /* To avoid excessive duplication of ops we implement shift
5941 by immediate using the variable shift operations. */
5943 /* Shift by immediate:
5944 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5945 if (q
&& ((rd
| rm
) & 1)) {
5948 if (!u
&& (op
== 4 || op
== 6)) {
5951 /* Right shifts are encoded as N - shift, where N is the
5952 element size in bits. */
5954 shift
= shift
- (1 << (size
+ 3));
5962 imm
= (uint8_t) shift
;
5967 imm
= (uint16_t) shift
;
5978 for (pass
= 0; pass
< count
; pass
++) {
5980 neon_load_reg64(cpu_V0
, rm
+ pass
);
5981 tcg_gen_movi_i64(cpu_V1
, imm
);
5986 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5988 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5993 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5995 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5998 case 5: /* VSHL, VSLI */
5999 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6001 case 6: /* VQSHLU */
6002 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6007 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6010 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6015 if (op
== 1 || op
== 3) {
6017 neon_load_reg64(cpu_V1
, rd
+ pass
);
6018 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6019 } else if (op
== 4 || (op
== 5 && u
)) {
6021 neon_load_reg64(cpu_V1
, rd
+ pass
);
6023 if (shift
< -63 || shift
> 63) {
6027 mask
= 0xffffffffffffffffull
>> -shift
;
6029 mask
= 0xffffffffffffffffull
<< shift
;
6032 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6033 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6035 neon_store_reg64(cpu_V0
, rd
+ pass
);
6036 } else { /* size < 3 */
6037 /* Operands in T0 and T1. */
6038 tmp
= neon_load_reg(rm
, pass
);
6039 tmp2
= tcg_temp_new_i32();
6040 tcg_gen_movi_i32(tmp2
, imm
);
6044 GEN_NEON_INTEGER_OP(shl
);
6048 GEN_NEON_INTEGER_OP(rshl
);
6051 case 5: /* VSHL, VSLI */
6053 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6054 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6055 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6059 case 6: /* VQSHLU */
6062 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6066 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6070 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6078 GEN_NEON_INTEGER_OP_ENV(qshl
);
6081 tcg_temp_free_i32(tmp2
);
6083 if (op
== 1 || op
== 3) {
6085 tmp2
= neon_load_reg(rd
, pass
);
6086 gen_neon_add(size
, tmp
, tmp2
);
6087 tcg_temp_free_i32(tmp2
);
6088 } else if (op
== 4 || (op
== 5 && u
)) {
6093 mask
= 0xff >> -shift
;
6095 mask
= (uint8_t)(0xff << shift
);
6101 mask
= 0xffff >> -shift
;
6103 mask
= (uint16_t)(0xffff << shift
);
6107 if (shift
< -31 || shift
> 31) {
6111 mask
= 0xffffffffu
>> -shift
;
6113 mask
= 0xffffffffu
<< shift
;
6119 tmp2
= neon_load_reg(rd
, pass
);
6120 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6121 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6122 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6123 tcg_temp_free_i32(tmp2
);
6125 neon_store_reg(rd
, pass
, tmp
);
6128 } else if (op
< 10) {
6129 /* Shift by immediate and narrow:
6130 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6131 int input_unsigned
= (op
== 8) ? !u
: u
;
6135 shift
= shift
- (1 << (size
+ 3));
6138 tmp64
= tcg_const_i64(shift
);
6139 neon_load_reg64(cpu_V0
, rm
);
6140 neon_load_reg64(cpu_V1
, rm
+ 1);
6141 for (pass
= 0; pass
< 2; pass
++) {
6149 if (input_unsigned
) {
6150 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6152 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6155 if (input_unsigned
) {
6156 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6158 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6161 tmp
= tcg_temp_new_i32();
6162 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6163 neon_store_reg(rd
, pass
, tmp
);
6165 tcg_temp_free_i64(tmp64
);
6168 imm
= (uint16_t)shift
;
6172 imm
= (uint32_t)shift
;
6174 tmp2
= tcg_const_i32(imm
);
6175 tmp4
= neon_load_reg(rm
+ 1, 0);
6176 tmp5
= neon_load_reg(rm
+ 1, 1);
6177 for (pass
= 0; pass
< 2; pass
++) {
6179 tmp
= neon_load_reg(rm
, 0);
6183 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6186 tmp3
= neon_load_reg(rm
, 1);
6190 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6192 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6193 tcg_temp_free_i32(tmp
);
6194 tcg_temp_free_i32(tmp3
);
6195 tmp
= tcg_temp_new_i32();
6196 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6197 neon_store_reg(rd
, pass
, tmp
);
6199 tcg_temp_free_i32(tmp2
);
6201 } else if (op
== 10) {
6203 if (q
|| (rd
& 1)) {
6206 tmp
= neon_load_reg(rm
, 0);
6207 tmp2
= neon_load_reg(rm
, 1);
6208 for (pass
= 0; pass
< 2; pass
++) {
6212 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6215 /* The shift is less than the width of the source
6216 type, so we can just shift the whole register. */
6217 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6218 /* Widen the result of shift: we need to clear
6219 * the potential overflow bits resulting from
6220 * left bits of the narrow input appearing as
6221 * right bits of left the neighbour narrow
6223 if (size
< 2 || !u
) {
6226 imm
= (0xffu
>> (8 - shift
));
6228 } else if (size
== 1) {
6229 imm
= 0xffff >> (16 - shift
);
6232 imm
= 0xffffffff >> (32 - shift
);
6235 imm64
= imm
| (((uint64_t)imm
) << 32);
6239 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6242 neon_store_reg64(cpu_V0
, rd
+ pass
);
6244 } else if (op
>= 14) {
6245 /* VCVT fixed-point. */
6246 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6249 /* We have already masked out the must-be-1 top bit of imm6,
6250 * hence this 32-shift where the ARM ARM has 64-imm6.
6253 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6254 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6257 gen_vfp_ulto(0, shift
, 1);
6259 gen_vfp_slto(0, shift
, 1);
6262 gen_vfp_toul(0, shift
, 1);
6264 gen_vfp_tosl(0, shift
, 1);
6266 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6271 } else { /* (insn & 0x00380080) == 0 */
6273 if (q
&& (rd
& 1)) {
6277 op
= (insn
>> 8) & 0xf;
6278 /* One register and immediate. */
6279 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6280 invert
= (insn
& (1 << 5)) != 0;
6281 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6282 * We choose to not special-case this and will behave as if a
6283 * valid constant encoding of 0 had been given.
6302 imm
= (imm
<< 8) | (imm
<< 24);
6305 imm
= (imm
<< 8) | 0xff;
6308 imm
= (imm
<< 16) | 0xffff;
6311 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6319 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6320 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6326 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6327 if (op
& 1 && op
< 12) {
6328 tmp
= neon_load_reg(rd
, pass
);
6330 /* The immediate value has already been inverted, so
6332 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6334 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6338 tmp
= tcg_temp_new_i32();
6339 if (op
== 14 && invert
) {
6343 for (n
= 0; n
< 4; n
++) {
6344 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6345 val
|= 0xff << (n
* 8);
6347 tcg_gen_movi_i32(tmp
, val
);
6349 tcg_gen_movi_i32(tmp
, imm
);
6352 neon_store_reg(rd
, pass
, tmp
);
6355 } else { /* (insn & 0x00800010 == 0x00800000) */
6357 op
= (insn
>> 8) & 0xf;
6358 if ((insn
& (1 << 6)) == 0) {
6359 /* Three registers of different lengths. */
6363 /* undefreq: bit 0 : UNDEF if size == 0
6364 * bit 1 : UNDEF if size == 1
6365 * bit 2 : UNDEF if size == 2
6366 * bit 3 : UNDEF if U == 1
6367 * Note that [2:0] set implies 'always UNDEF'
6370 /* prewiden, src1_wide, src2_wide, undefreq */
6371 static const int neon_3reg_wide
[16][4] = {
6372 {1, 0, 0, 0}, /* VADDL */
6373 {1, 1, 0, 0}, /* VADDW */
6374 {1, 0, 0, 0}, /* VSUBL */
6375 {1, 1, 0, 0}, /* VSUBW */
6376 {0, 1, 1, 0}, /* VADDHN */
6377 {0, 0, 0, 0}, /* VABAL */
6378 {0, 1, 1, 0}, /* VSUBHN */
6379 {0, 0, 0, 0}, /* VABDL */
6380 {0, 0, 0, 0}, /* VMLAL */
6381 {0, 0, 0, 9}, /* VQDMLAL */
6382 {0, 0, 0, 0}, /* VMLSL */
6383 {0, 0, 0, 9}, /* VQDMLSL */
6384 {0, 0, 0, 0}, /* Integer VMULL */
6385 {0, 0, 0, 1}, /* VQDMULL */
6386 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6387 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6390 prewiden
= neon_3reg_wide
[op
][0];
6391 src1_wide
= neon_3reg_wide
[op
][1];
6392 src2_wide
= neon_3reg_wide
[op
][2];
6393 undefreq
= neon_3reg_wide
[op
][3];
6395 if ((undefreq
& (1 << size
)) ||
6396 ((undefreq
& 8) && u
)) {
6399 if ((src1_wide
&& (rn
& 1)) ||
6400 (src2_wide
&& (rm
& 1)) ||
6401 (!src2_wide
&& (rd
& 1))) {
6405 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6406 * outside the loop below as it only performs a single pass.
6408 if (op
== 14 && size
== 2) {
6409 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6411 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6414 tcg_rn
= tcg_temp_new_i64();
6415 tcg_rm
= tcg_temp_new_i64();
6416 tcg_rd
= tcg_temp_new_i64();
6417 neon_load_reg64(tcg_rn
, rn
);
6418 neon_load_reg64(tcg_rm
, rm
);
6419 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6420 neon_store_reg64(tcg_rd
, rd
);
6421 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6422 neon_store_reg64(tcg_rd
, rd
+ 1);
6423 tcg_temp_free_i64(tcg_rn
);
6424 tcg_temp_free_i64(tcg_rm
);
6425 tcg_temp_free_i64(tcg_rd
);
6429 /* Avoid overlapping operands. Wide source operands are
6430 always aligned so will never overlap with wide
6431 destinations in problematic ways. */
6432 if (rd
== rm
&& !src2_wide
) {
6433 tmp
= neon_load_reg(rm
, 1);
6434 neon_store_scratch(2, tmp
);
6435 } else if (rd
== rn
&& !src1_wide
) {
6436 tmp
= neon_load_reg(rn
, 1);
6437 neon_store_scratch(2, tmp
);
6439 TCGV_UNUSED_I32(tmp3
);
6440 for (pass
= 0; pass
< 2; pass
++) {
6442 neon_load_reg64(cpu_V0
, rn
+ pass
);
6443 TCGV_UNUSED_I32(tmp
);
6445 if (pass
== 1 && rd
== rn
) {
6446 tmp
= neon_load_scratch(2);
6448 tmp
= neon_load_reg(rn
, pass
);
6451 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6455 neon_load_reg64(cpu_V1
, rm
+ pass
);
6456 TCGV_UNUSED_I32(tmp2
);
6458 if (pass
== 1 && rd
== rm
) {
6459 tmp2
= neon_load_scratch(2);
6461 tmp2
= neon_load_reg(rm
, pass
);
6464 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6468 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6469 gen_neon_addl(size
);
6471 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6472 gen_neon_subl(size
);
6474 case 5: case 7: /* VABAL, VABDL */
6475 switch ((size
<< 1) | u
) {
6477 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6480 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6483 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6486 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6489 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6492 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6496 tcg_temp_free_i32(tmp2
);
6497 tcg_temp_free_i32(tmp
);
6499 case 8: case 9: case 10: case 11: case 12: case 13:
6500 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6501 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6503 case 14: /* Polynomial VMULL */
6504 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6505 tcg_temp_free_i32(tmp2
);
6506 tcg_temp_free_i32(tmp
);
6508 default: /* 15 is RESERVED: caught earlier */
6513 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6514 neon_store_reg64(cpu_V0
, rd
+ pass
);
6515 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6517 neon_load_reg64(cpu_V1
, rd
+ pass
);
6519 case 10: /* VMLSL */
6520 gen_neon_negl(cpu_V0
, size
);
6522 case 5: case 8: /* VABAL, VMLAL */
6523 gen_neon_addl(size
);
6525 case 9: case 11: /* VQDMLAL, VQDMLSL */
6526 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6528 gen_neon_negl(cpu_V0
, size
);
6530 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6535 neon_store_reg64(cpu_V0
, rd
+ pass
);
6536 } else if (op
== 4 || op
== 6) {
6537 /* Narrowing operation. */
6538 tmp
= tcg_temp_new_i32();
6542 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6545 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6548 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6549 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6556 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6559 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6562 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6563 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6564 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6572 neon_store_reg(rd
, 0, tmp3
);
6573 neon_store_reg(rd
, 1, tmp
);
6576 /* Write back the result. */
6577 neon_store_reg64(cpu_V0
, rd
+ pass
);
6581 /* Two registers and a scalar. NB that for ops of this form
6582 * the ARM ARM labels bit 24 as Q, but it is in our variable
6589 case 1: /* Float VMLA scalar */
6590 case 5: /* Floating point VMLS scalar */
6591 case 9: /* Floating point VMUL scalar */
6596 case 0: /* Integer VMLA scalar */
6597 case 4: /* Integer VMLS scalar */
6598 case 8: /* Integer VMUL scalar */
6599 case 12: /* VQDMULH scalar */
6600 case 13: /* VQRDMULH scalar */
6601 if (u
&& ((rd
| rn
) & 1)) {
6604 tmp
= neon_get_scalar(size
, rm
);
6605 neon_store_scratch(0, tmp
);
6606 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6607 tmp
= neon_load_scratch(0);
6608 tmp2
= neon_load_reg(rn
, pass
);
6611 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6613 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6615 } else if (op
== 13) {
6617 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6619 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6621 } else if (op
& 1) {
6622 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6623 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6624 tcg_temp_free_ptr(fpstatus
);
6627 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6628 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6629 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6633 tcg_temp_free_i32(tmp2
);
6636 tmp2
= neon_load_reg(rd
, pass
);
6639 gen_neon_add(size
, tmp
, tmp2
);
6643 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6644 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6645 tcg_temp_free_ptr(fpstatus
);
6649 gen_neon_rsb(size
, tmp
, tmp2
);
6653 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6654 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6655 tcg_temp_free_ptr(fpstatus
);
6661 tcg_temp_free_i32(tmp2
);
6663 neon_store_reg(rd
, pass
, tmp
);
6666 case 3: /* VQDMLAL scalar */
6667 case 7: /* VQDMLSL scalar */
6668 case 11: /* VQDMULL scalar */
6673 case 2: /* VMLAL sclar */
6674 case 6: /* VMLSL scalar */
6675 case 10: /* VMULL scalar */
6679 tmp2
= neon_get_scalar(size
, rm
);
6680 /* We need a copy of tmp2 because gen_neon_mull
6681 * deletes it during pass 0. */
6682 tmp4
= tcg_temp_new_i32();
6683 tcg_gen_mov_i32(tmp4
, tmp2
);
6684 tmp3
= neon_load_reg(rn
, 1);
6686 for (pass
= 0; pass
< 2; pass
++) {
6688 tmp
= neon_load_reg(rn
, 0);
6693 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6695 neon_load_reg64(cpu_V1
, rd
+ pass
);
6699 gen_neon_negl(cpu_V0
, size
);
6702 gen_neon_addl(size
);
6705 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6707 gen_neon_negl(cpu_V0
, size
);
6709 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6715 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6720 neon_store_reg64(cpu_V0
, rd
+ pass
);
6725 default: /* 14 and 15 are RESERVED */
6729 } else { /* size == 3 */
6732 imm
= (insn
>> 8) & 0xf;
6737 if (q
&& ((rd
| rn
| rm
) & 1)) {
6742 neon_load_reg64(cpu_V0
, rn
);
6744 neon_load_reg64(cpu_V1
, rn
+ 1);
6746 } else if (imm
== 8) {
6747 neon_load_reg64(cpu_V0
, rn
+ 1);
6749 neon_load_reg64(cpu_V1
, rm
);
6752 tmp64
= tcg_temp_new_i64();
6754 neon_load_reg64(cpu_V0
, rn
);
6755 neon_load_reg64(tmp64
, rn
+ 1);
6757 neon_load_reg64(cpu_V0
, rn
+ 1);
6758 neon_load_reg64(tmp64
, rm
);
6760 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6761 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6762 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6764 neon_load_reg64(cpu_V1
, rm
);
6766 neon_load_reg64(cpu_V1
, rm
+ 1);
6769 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6770 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6771 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6772 tcg_temp_free_i64(tmp64
);
6775 neon_load_reg64(cpu_V0
, rn
);
6776 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6777 neon_load_reg64(cpu_V1
, rm
);
6778 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6779 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6781 neon_store_reg64(cpu_V0
, rd
);
6783 neon_store_reg64(cpu_V1
, rd
+ 1);
6785 } else if ((insn
& (1 << 11)) == 0) {
6786 /* Two register misc. */
6787 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6788 size
= (insn
>> 18) & 3;
6789 /* UNDEF for unknown op values and bad op-size combinations */
6790 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6793 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6794 q
&& ((rm
| rd
) & 1)) {
6798 case NEON_2RM_VREV64
:
6799 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6800 tmp
= neon_load_reg(rm
, pass
* 2);
6801 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6803 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6804 case 1: gen_swap_half(tmp
); break;
6805 case 2: /* no-op */ break;
6808 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6810 neon_store_reg(rd
, pass
* 2, tmp2
);
6813 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6814 case 1: gen_swap_half(tmp2
); break;
6817 neon_store_reg(rd
, pass
* 2, tmp2
);
6821 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6822 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6823 for (pass
= 0; pass
< q
+ 1; pass
++) {
6824 tmp
= neon_load_reg(rm
, pass
* 2);
6825 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6826 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6827 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6829 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6830 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6831 case 2: tcg_gen_add_i64(CPU_V001
); break;
6834 if (op
>= NEON_2RM_VPADAL
) {
6836 neon_load_reg64(cpu_V1
, rd
+ pass
);
6837 gen_neon_addl(size
);
6839 neon_store_reg64(cpu_V0
, rd
+ pass
);
6845 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6846 tmp
= neon_load_reg(rm
, n
);
6847 tmp2
= neon_load_reg(rd
, n
+ 1);
6848 neon_store_reg(rm
, n
, tmp2
);
6849 neon_store_reg(rd
, n
+ 1, tmp
);
6856 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6861 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6865 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6866 /* also VQMOVUN; op field and mnemonics don't line up */
6870 TCGV_UNUSED_I32(tmp2
);
6871 for (pass
= 0; pass
< 2; pass
++) {
6872 neon_load_reg64(cpu_V0
, rm
+ pass
);
6873 tmp
= tcg_temp_new_i32();
6874 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6879 neon_store_reg(rd
, 0, tmp2
);
6880 neon_store_reg(rd
, 1, tmp
);
6884 case NEON_2RM_VSHLL
:
6885 if (q
|| (rd
& 1)) {
6888 tmp
= neon_load_reg(rm
, 0);
6889 tmp2
= neon_load_reg(rm
, 1);
6890 for (pass
= 0; pass
< 2; pass
++) {
6893 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6894 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6895 neon_store_reg64(cpu_V0
, rd
+ pass
);
6898 case NEON_2RM_VCVT_F16_F32
:
6899 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6903 tmp
= tcg_temp_new_i32();
6904 tmp2
= tcg_temp_new_i32();
6905 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6906 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6907 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6908 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6909 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6910 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6911 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6912 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6913 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6914 neon_store_reg(rd
, 0, tmp2
);
6915 tmp2
= tcg_temp_new_i32();
6916 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6917 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6918 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6919 neon_store_reg(rd
, 1, tmp2
);
6920 tcg_temp_free_i32(tmp
);
6922 case NEON_2RM_VCVT_F32_F16
:
6923 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6927 tmp3
= tcg_temp_new_i32();
6928 tmp
= neon_load_reg(rm
, 0);
6929 tmp2
= neon_load_reg(rm
, 1);
6930 tcg_gen_ext16u_i32(tmp3
, tmp
);
6931 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6932 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6933 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6934 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6935 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6936 tcg_temp_free_i32(tmp
);
6937 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6938 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6939 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6940 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6941 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6942 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6943 tcg_temp_free_i32(tmp2
);
6944 tcg_temp_free_i32(tmp3
);
6946 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6947 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6948 || ((rm
| rd
) & 1)) {
6951 tmp
= tcg_const_i32(rd
);
6952 tmp2
= tcg_const_i32(rm
);
6954 /* Bit 6 is the lowest opcode bit; it distinguishes between
6955 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6957 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6959 if (op
== NEON_2RM_AESE
) {
6960 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6962 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6964 tcg_temp_free_i32(tmp
);
6965 tcg_temp_free_i32(tmp2
);
6966 tcg_temp_free_i32(tmp3
);
6968 case NEON_2RM_SHA1H
:
6969 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
6970 || ((rm
| rd
) & 1)) {
6973 tmp
= tcg_const_i32(rd
);
6974 tmp2
= tcg_const_i32(rm
);
6976 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6978 tcg_temp_free_i32(tmp
);
6979 tcg_temp_free_i32(tmp2
);
6981 case NEON_2RM_SHA1SU1
:
6982 if ((rm
| rd
) & 1) {
6985 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6987 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
6990 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
6993 tmp
= tcg_const_i32(rd
);
6994 tmp2
= tcg_const_i32(rm
);
6996 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6998 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7000 tcg_temp_free_i32(tmp
);
7001 tcg_temp_free_i32(tmp2
);
7005 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7006 if (neon_2rm_is_float_op(op
)) {
7007 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7008 neon_reg_offset(rm
, pass
));
7009 TCGV_UNUSED_I32(tmp
);
7011 tmp
= neon_load_reg(rm
, pass
);
7014 case NEON_2RM_VREV32
:
7016 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7017 case 1: gen_swap_half(tmp
); break;
7021 case NEON_2RM_VREV16
:
7026 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7027 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7028 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7034 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7035 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7036 case 2: gen_helper_clz(tmp
, tmp
); break;
7041 gen_helper_neon_cnt_u8(tmp
, tmp
);
7044 tcg_gen_not_i32(tmp
, tmp
);
7046 case NEON_2RM_VQABS
:
7049 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7052 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7055 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7060 case NEON_2RM_VQNEG
:
7063 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7066 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7069 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7074 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7075 tmp2
= tcg_const_i32(0);
7077 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7078 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7079 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7082 tcg_temp_free_i32(tmp2
);
7083 if (op
== NEON_2RM_VCLE0
) {
7084 tcg_gen_not_i32(tmp
, tmp
);
7087 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7088 tmp2
= tcg_const_i32(0);
7090 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7091 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7092 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7095 tcg_temp_free_i32(tmp2
);
7096 if (op
== NEON_2RM_VCLT0
) {
7097 tcg_gen_not_i32(tmp
, tmp
);
7100 case NEON_2RM_VCEQ0
:
7101 tmp2
= tcg_const_i32(0);
7103 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7104 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7105 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7108 tcg_temp_free_i32(tmp2
);
7112 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7113 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7114 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7119 tmp2
= tcg_const_i32(0);
7120 gen_neon_rsb(size
, tmp
, tmp2
);
7121 tcg_temp_free_i32(tmp2
);
7123 case NEON_2RM_VCGT0_F
:
7125 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7126 tmp2
= tcg_const_i32(0);
7127 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7128 tcg_temp_free_i32(tmp2
);
7129 tcg_temp_free_ptr(fpstatus
);
7132 case NEON_2RM_VCGE0_F
:
7134 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7135 tmp2
= tcg_const_i32(0);
7136 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7137 tcg_temp_free_i32(tmp2
);
7138 tcg_temp_free_ptr(fpstatus
);
7141 case NEON_2RM_VCEQ0_F
:
7143 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7144 tmp2
= tcg_const_i32(0);
7145 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7146 tcg_temp_free_i32(tmp2
);
7147 tcg_temp_free_ptr(fpstatus
);
7150 case NEON_2RM_VCLE0_F
:
7152 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7153 tmp2
= tcg_const_i32(0);
7154 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7155 tcg_temp_free_i32(tmp2
);
7156 tcg_temp_free_ptr(fpstatus
);
7159 case NEON_2RM_VCLT0_F
:
7161 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7162 tmp2
= tcg_const_i32(0);
7163 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7164 tcg_temp_free_i32(tmp2
);
7165 tcg_temp_free_ptr(fpstatus
);
7168 case NEON_2RM_VABS_F
:
7171 case NEON_2RM_VNEG_F
:
7175 tmp2
= neon_load_reg(rd
, pass
);
7176 neon_store_reg(rm
, pass
, tmp2
);
7179 tmp2
= neon_load_reg(rd
, pass
);
7181 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7182 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7185 neon_store_reg(rm
, pass
, tmp2
);
7187 case NEON_2RM_VRINTN
:
7188 case NEON_2RM_VRINTA
:
7189 case NEON_2RM_VRINTM
:
7190 case NEON_2RM_VRINTP
:
7191 case NEON_2RM_VRINTZ
:
7194 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7197 if (op
== NEON_2RM_VRINTZ
) {
7198 rmode
= FPROUNDING_ZERO
;
7200 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7203 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7204 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7206 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7207 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7209 tcg_temp_free_ptr(fpstatus
);
7210 tcg_temp_free_i32(tcg_rmode
);
7213 case NEON_2RM_VRINTX
:
7215 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7216 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7217 tcg_temp_free_ptr(fpstatus
);
7220 case NEON_2RM_VCVTAU
:
7221 case NEON_2RM_VCVTAS
:
7222 case NEON_2RM_VCVTNU
:
7223 case NEON_2RM_VCVTNS
:
7224 case NEON_2RM_VCVTPU
:
7225 case NEON_2RM_VCVTPS
:
7226 case NEON_2RM_VCVTMU
:
7227 case NEON_2RM_VCVTMS
:
7229 bool is_signed
= !extract32(insn
, 7, 1);
7230 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7231 TCGv_i32 tcg_rmode
, tcg_shift
;
7232 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7234 tcg_shift
= tcg_const_i32(0);
7235 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7236 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7240 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7243 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7247 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7249 tcg_temp_free_i32(tcg_rmode
);
7250 tcg_temp_free_i32(tcg_shift
);
7251 tcg_temp_free_ptr(fpst
);
7254 case NEON_2RM_VRECPE
:
7256 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7257 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7258 tcg_temp_free_ptr(fpstatus
);
7261 case NEON_2RM_VRSQRTE
:
7263 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7264 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7265 tcg_temp_free_ptr(fpstatus
);
7268 case NEON_2RM_VRECPE_F
:
7270 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7271 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7272 tcg_temp_free_ptr(fpstatus
);
7275 case NEON_2RM_VRSQRTE_F
:
7277 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7278 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7279 tcg_temp_free_ptr(fpstatus
);
7282 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7285 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7288 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7289 gen_vfp_tosiz(0, 1);
7291 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7292 gen_vfp_touiz(0, 1);
7295 /* Reserved op values were caught by the
7296 * neon_2rm_sizes[] check earlier.
7300 if (neon_2rm_is_float_op(op
)) {
7301 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7302 neon_reg_offset(rd
, pass
));
7304 neon_store_reg(rd
, pass
, tmp
);
7309 } else if ((insn
& (1 << 10)) == 0) {
7311 int n
= ((insn
>> 8) & 3) + 1;
7312 if ((rn
+ n
) > 32) {
7313 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7314 * helper function running off the end of the register file.
7319 if (insn
& (1 << 6)) {
7320 tmp
= neon_load_reg(rd
, 0);
7322 tmp
= tcg_temp_new_i32();
7323 tcg_gen_movi_i32(tmp
, 0);
7325 tmp2
= neon_load_reg(rm
, 0);
7326 tmp4
= tcg_const_i32(rn
);
7327 tmp5
= tcg_const_i32(n
);
7328 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7329 tcg_temp_free_i32(tmp
);
7330 if (insn
& (1 << 6)) {
7331 tmp
= neon_load_reg(rd
, 1);
7333 tmp
= tcg_temp_new_i32();
7334 tcg_gen_movi_i32(tmp
, 0);
7336 tmp3
= neon_load_reg(rm
, 1);
7337 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7338 tcg_temp_free_i32(tmp5
);
7339 tcg_temp_free_i32(tmp4
);
7340 neon_store_reg(rd
, 0, tmp2
);
7341 neon_store_reg(rd
, 1, tmp3
);
7342 tcg_temp_free_i32(tmp
);
7343 } else if ((insn
& 0x380) == 0) {
7345 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7348 if (insn
& (1 << 19)) {
7349 tmp
= neon_load_reg(rm
, 1);
7351 tmp
= neon_load_reg(rm
, 0);
7353 if (insn
& (1 << 16)) {
7354 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7355 } else if (insn
& (1 << 17)) {
7356 if ((insn
>> 18) & 1)
7357 gen_neon_dup_high16(tmp
);
7359 gen_neon_dup_low16(tmp
);
7361 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7362 tmp2
= tcg_temp_new_i32();
7363 tcg_gen_mov_i32(tmp2
, tmp
);
7364 neon_store_reg(rd
, pass
, tmp2
);
7366 tcg_temp_free_i32(tmp
);
7375 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7377 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7378 const ARMCPRegInfo
*ri
;
7380 cpnum
= (insn
>> 8) & 0xf;
7382 /* First check for coprocessor space used for XScale/iwMMXt insns */
7383 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7384 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7387 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7388 return disas_iwmmxt_insn(s
, insn
);
7389 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7390 return disas_dsp_insn(s
, insn
);
7395 /* Otherwise treat as a generic register access */
7396 is64
= (insn
& (1 << 25)) == 0;
7397 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7405 opc1
= (insn
>> 4) & 0xf;
7407 rt2
= (insn
>> 16) & 0xf;
7409 crn
= (insn
>> 16) & 0xf;
7410 opc1
= (insn
>> 21) & 7;
7411 opc2
= (insn
>> 5) & 7;
7414 isread
= (insn
>> 20) & 1;
7415 rt
= (insn
>> 12) & 0xf;
7417 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7418 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7420 /* Check access permissions */
7421 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7426 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7427 /* Emit code to perform further access permissions checks at
7428 * runtime; this may result in an exception.
7429 * Note that on XScale all cp0..c13 registers do an access check
7430 * call in order to handle c15_cpar.
7433 TCGv_i32 tcg_syn
, tcg_isread
;
7436 /* Note that since we are an implementation which takes an
7437 * exception on a trapped conditional instruction only if the
7438 * instruction passes its condition code check, we can take
7439 * advantage of the clause in the ARM ARM that allows us to set
7440 * the COND field in the instruction to 0xE in all cases.
7441 * We could fish the actual condition out of the insn (ARM)
7442 * or the condexec bits (Thumb) but it isn't necessary.
7447 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7450 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7456 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7459 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7464 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7465 * so this can only happen if this is an ARMv7 or earlier CPU,
7466 * in which case the syndrome information won't actually be
7469 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7470 syndrome
= syn_uncategorized();
7474 gen_set_condexec(s
);
7475 gen_set_pc_im(s
, s
->pc
- 4);
7476 tmpptr
= tcg_const_ptr(ri
);
7477 tcg_syn
= tcg_const_i32(syndrome
);
7478 tcg_isread
= tcg_const_i32(isread
);
7479 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7481 tcg_temp_free_ptr(tmpptr
);
7482 tcg_temp_free_i32(tcg_syn
);
7483 tcg_temp_free_i32(tcg_isread
);
7486 /* Handle special cases first */
7487 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7494 gen_set_pc_im(s
, s
->pc
);
7495 s
->is_jmp
= DISAS_WFI
;
7501 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7510 if (ri
->type
& ARM_CP_CONST
) {
7511 tmp64
= tcg_const_i64(ri
->resetvalue
);
7512 } else if (ri
->readfn
) {
7514 tmp64
= tcg_temp_new_i64();
7515 tmpptr
= tcg_const_ptr(ri
);
7516 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7517 tcg_temp_free_ptr(tmpptr
);
7519 tmp64
= tcg_temp_new_i64();
7520 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7522 tmp
= tcg_temp_new_i32();
7523 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7524 store_reg(s
, rt
, tmp
);
7525 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7526 tmp
= tcg_temp_new_i32();
7527 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7528 tcg_temp_free_i64(tmp64
);
7529 store_reg(s
, rt2
, tmp
);
7532 if (ri
->type
& ARM_CP_CONST
) {
7533 tmp
= tcg_const_i32(ri
->resetvalue
);
7534 } else if (ri
->readfn
) {
7536 tmp
= tcg_temp_new_i32();
7537 tmpptr
= tcg_const_ptr(ri
);
7538 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7539 tcg_temp_free_ptr(tmpptr
);
7541 tmp
= load_cpu_offset(ri
->fieldoffset
);
7544 /* Destination register of r15 for 32 bit loads sets
7545 * the condition codes from the high 4 bits of the value
7548 tcg_temp_free_i32(tmp
);
7550 store_reg(s
, rt
, tmp
);
7555 if (ri
->type
& ARM_CP_CONST
) {
7556 /* If not forbidden by access permissions, treat as WI */
7561 TCGv_i32 tmplo
, tmphi
;
7562 TCGv_i64 tmp64
= tcg_temp_new_i64();
7563 tmplo
= load_reg(s
, rt
);
7564 tmphi
= load_reg(s
, rt2
);
7565 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7566 tcg_temp_free_i32(tmplo
);
7567 tcg_temp_free_i32(tmphi
);
7569 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7570 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7571 tcg_temp_free_ptr(tmpptr
);
7573 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7575 tcg_temp_free_i64(tmp64
);
7580 tmp
= load_reg(s
, rt
);
7581 tmpptr
= tcg_const_ptr(ri
);
7582 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7583 tcg_temp_free_ptr(tmpptr
);
7584 tcg_temp_free_i32(tmp
);
7586 TCGv_i32 tmp
= load_reg(s
, rt
);
7587 store_cpu_offset(tmp
, ri
->fieldoffset
);
7592 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7593 /* I/O operations must end the TB here (whether read or write) */
7596 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7597 /* We default to ending the TB on a coprocessor register write,
7598 * but allow this to be suppressed by the register definition
7599 * (usually only necessary to work around guest bugs).
7607 /* Unknown register; this might be a guest error or a QEMU
7608 * unimplemented feature.
7611 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7612 "64 bit system register cp:%d opc1: %d crm:%d "
7614 isread
? "read" : "write", cpnum
, opc1
, crm
,
7615 s
->ns
? "non-secure" : "secure");
7617 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7618 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7620 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7621 s
->ns
? "non-secure" : "secure");
7628 /* Store a 64-bit value to a register pair. Clobbers val. */
7629 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7632 tmp
= tcg_temp_new_i32();
7633 tcg_gen_extrl_i64_i32(tmp
, val
);
7634 store_reg(s
, rlow
, tmp
);
7635 tmp
= tcg_temp_new_i32();
7636 tcg_gen_shri_i64(val
, val
, 32);
7637 tcg_gen_extrl_i64_i32(tmp
, val
);
7638 store_reg(s
, rhigh
, tmp
);
7641 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7642 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7647 /* Load value and extend to 64 bits. */
7648 tmp
= tcg_temp_new_i64();
7649 tmp2
= load_reg(s
, rlow
);
7650 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7651 tcg_temp_free_i32(tmp2
);
7652 tcg_gen_add_i64(val
, val
, tmp
);
7653 tcg_temp_free_i64(tmp
);
7656 /* load and add a 64-bit value from a register pair. */
7657 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7663 /* Load 64-bit value rd:rn. */
7664 tmpl
= load_reg(s
, rlow
);
7665 tmph
= load_reg(s
, rhigh
);
7666 tmp
= tcg_temp_new_i64();
7667 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7668 tcg_temp_free_i32(tmpl
);
7669 tcg_temp_free_i32(tmph
);
7670 tcg_gen_add_i64(val
, val
, tmp
);
7671 tcg_temp_free_i64(tmp
);
7674 /* Set N and Z flags from hi|lo. */
7675 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7677 tcg_gen_mov_i32(cpu_NF
, hi
);
7678 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7681 /* Load/Store exclusive instructions are implemented by remembering
7682 the value/address loaded, and seeing if these are the same
7683 when the store is performed. This should be sufficient to implement
7684 the architecturally mandated semantics, and avoids having to monitor
7687 In system emulation mode only one CPU will be running at once, so
7688 this sequence is effectively atomic. In user emulation mode we
7689 throw an exception and handle the atomic operation elsewhere. */
7690 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7691 TCGv_i32 addr
, int size
)
7693 TCGv_i32 tmp
= tcg_temp_new_i32();
7699 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7702 gen_aa32_ld16ua(s
, tmp
, addr
, get_mem_index(s
));
7706 gen_aa32_ld32ua(s
, tmp
, addr
, get_mem_index(s
));
7713 TCGv_i32 tmp2
= tcg_temp_new_i32();
7714 TCGv_i32 tmp3
= tcg_temp_new_i32();
7716 tcg_gen_addi_i32(tmp2
, addr
, 4);
7717 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7718 tcg_temp_free_i32(tmp2
);
7719 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7720 store_reg(s
, rt2
, tmp3
);
7722 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7725 store_reg(s
, rt
, tmp
);
7726 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7729 static void gen_clrex(DisasContext
*s
)
7731 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7734 #ifdef CONFIG_USER_ONLY
7735 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7736 TCGv_i32 addr
, int size
)
7738 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7739 tcg_gen_movi_i32(cpu_exclusive_info
,
7740 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7741 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7744 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7745 TCGv_i32 addr
, int size
)
7748 TCGv_i64 val64
, extaddr
;
7749 TCGLabel
*done_label
;
7750 TCGLabel
*fail_label
;
7752 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7758 fail_label
= gen_new_label();
7759 done_label
= gen_new_label();
7760 extaddr
= tcg_temp_new_i64();
7761 tcg_gen_extu_i32_i64(extaddr
, addr
);
7762 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7763 tcg_temp_free_i64(extaddr
);
7765 tmp
= tcg_temp_new_i32();
7768 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7771 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
7775 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7781 val64
= tcg_temp_new_i64();
7783 TCGv_i32 tmp2
= tcg_temp_new_i32();
7784 TCGv_i32 tmp3
= tcg_temp_new_i32();
7785 tcg_gen_addi_i32(tmp2
, addr
, 4);
7786 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7787 tcg_temp_free_i32(tmp2
);
7788 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7789 tcg_temp_free_i32(tmp3
);
7791 tcg_gen_extu_i32_i64(val64
, tmp
);
7793 tcg_temp_free_i32(tmp
);
7795 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7796 tcg_temp_free_i64(val64
);
7798 tmp
= load_reg(s
, rt
);
7801 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
7804 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
7808 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7813 tcg_temp_free_i32(tmp
);
7815 tcg_gen_addi_i32(addr
, addr
, 4);
7816 tmp
= load_reg(s
, rt2
);
7817 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7818 tcg_temp_free_i32(tmp
);
7820 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7821 tcg_gen_br(done_label
);
7822 gen_set_label(fail_label
);
7823 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7824 gen_set_label(done_label
);
7825 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7832 * @mode: mode field from insn (which stack to store to)
7833 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7834 * @writeback: true if writeback bit set
7836 * Generate code for the SRS (Store Return State) insn.
7838 static void gen_srs(DisasContext
*s
,
7839 uint32_t mode
, uint32_t amode
, bool writeback
)
7846 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7847 * and specified mode is monitor mode
7848 * - UNDEFINED in Hyp mode
7849 * - UNPREDICTABLE in User or System mode
7850 * - UNPREDICTABLE if the specified mode is:
7851 * -- not implemented
7852 * -- not a valid mode number
7853 * -- a mode that's at a higher exception level
7854 * -- Monitor, if we are Non-secure
7855 * For the UNPREDICTABLE cases we choose to UNDEF.
7857 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7858 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7862 if (s
->current_el
== 0 || s
->current_el
== 2) {
7867 case ARM_CPU_MODE_USR
:
7868 case ARM_CPU_MODE_FIQ
:
7869 case ARM_CPU_MODE_IRQ
:
7870 case ARM_CPU_MODE_SVC
:
7871 case ARM_CPU_MODE_ABT
:
7872 case ARM_CPU_MODE_UND
:
7873 case ARM_CPU_MODE_SYS
:
7875 case ARM_CPU_MODE_HYP
:
7876 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7880 case ARM_CPU_MODE_MON
:
7881 /* No need to check specifically for "are we non-secure" because
7882 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7883 * so if this isn't EL3 then we must be non-secure.
7885 if (s
->current_el
!= 3) {
7894 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
7895 default_exception_el(s
));
7899 addr
= tcg_temp_new_i32();
7900 tmp
= tcg_const_i32(mode
);
7901 /* get_r13_banked() will raise an exception if called from System mode */
7902 gen_set_condexec(s
);
7903 gen_set_pc_im(s
, s
->pc
- 4);
7904 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7905 tcg_temp_free_i32(tmp
);
7922 tcg_gen_addi_i32(addr
, addr
, offset
);
7923 tmp
= load_reg(s
, 14);
7924 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7925 tcg_temp_free_i32(tmp
);
7926 tmp
= load_cpu_field(spsr
);
7927 tcg_gen_addi_i32(addr
, addr
, 4);
7928 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7929 tcg_temp_free_i32(tmp
);
7947 tcg_gen_addi_i32(addr
, addr
, offset
);
7948 tmp
= tcg_const_i32(mode
);
7949 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7950 tcg_temp_free_i32(tmp
);
7952 tcg_temp_free_i32(addr
);
7953 s
->is_jmp
= DISAS_UPDATE
;
7956 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7958 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7965 /* M variants do not implement ARM mode. */
7966 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7971 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7972 * choose to UNDEF. In ARMv5 and above the space is used
7973 * for miscellaneous unconditional instructions.
7977 /* Unconditional instructions. */
7978 if (((insn
>> 25) & 7) == 1) {
7979 /* NEON Data processing. */
7980 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7984 if (disas_neon_data_insn(s
, insn
)) {
7989 if ((insn
& 0x0f100000) == 0x04000000) {
7990 /* NEON load/store. */
7991 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7995 if (disas_neon_ls_insn(s
, insn
)) {
8000 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8002 if (disas_vfp_insn(s
, insn
)) {
8007 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8008 ((insn
& 0x0f30f010) == 0x0710f000)) {
8009 if ((insn
& (1 << 22)) == 0) {
8011 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8015 /* Otherwise PLD; v5TE+ */
8019 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8020 ((insn
& 0x0f70f010) == 0x0650f000)) {
8022 return; /* PLI; V7 */
8024 if (((insn
& 0x0f700000) == 0x04100000) ||
8025 ((insn
& 0x0f700010) == 0x06100000)) {
8026 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8029 return; /* v7MP: Unallocated memory hint: must NOP */
8032 if ((insn
& 0x0ffffdff) == 0x01010000) {
8035 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8036 gen_helper_setend(cpu_env
);
8037 s
->is_jmp
= DISAS_UPDATE
;
8040 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8041 switch ((insn
>> 4) & 0xf) {
8049 /* We don't emulate caches so these are a no-op. */
8052 /* We need to break the TB after this insn to execute
8053 * self-modifying code correctly and also to take
8054 * any pending interrupts immediately.
8061 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8064 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8066 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8072 rn
= (insn
>> 16) & 0xf;
8073 addr
= load_reg(s
, rn
);
8074 i
= (insn
>> 23) & 3;
8076 case 0: offset
= -4; break; /* DA */
8077 case 1: offset
= 0; break; /* IA */
8078 case 2: offset
= -8; break; /* DB */
8079 case 3: offset
= 4; break; /* IB */
8083 tcg_gen_addi_i32(addr
, addr
, offset
);
8084 /* Load PC into tmp and CPSR into tmp2. */
8085 tmp
= tcg_temp_new_i32();
8086 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8087 tcg_gen_addi_i32(addr
, addr
, 4);
8088 tmp2
= tcg_temp_new_i32();
8089 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8090 if (insn
& (1 << 21)) {
8091 /* Base writeback. */
8093 case 0: offset
= -8; break;
8094 case 1: offset
= 4; break;
8095 case 2: offset
= -4; break;
8096 case 3: offset
= 0; break;
8100 tcg_gen_addi_i32(addr
, addr
, offset
);
8101 store_reg(s
, rn
, addr
);
8103 tcg_temp_free_i32(addr
);
8105 gen_rfe(s
, tmp
, tmp2
);
8107 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8108 /* branch link and change to thumb (blx <offset>) */
8111 val
= (uint32_t)s
->pc
;
8112 tmp
= tcg_temp_new_i32();
8113 tcg_gen_movi_i32(tmp
, val
);
8114 store_reg(s
, 14, tmp
);
8115 /* Sign-extend the 24-bit offset */
8116 offset
= (((int32_t)insn
) << 8) >> 8;
8117 /* offset * 4 + bit24 * 2 + (thumb bit) */
8118 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8119 /* pipeline offset */
8121 /* protected by ARCH(5); above, near the start of uncond block */
8124 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8125 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8126 /* iWMMXt register transfer. */
8127 if (extract32(s
->c15_cpar
, 1, 1)) {
8128 if (!disas_iwmmxt_insn(s
, insn
)) {
8133 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8134 /* Coprocessor double register transfer. */
8136 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8137 /* Additional coprocessor register transfer. */
8138 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8141 /* cps (privileged) */
8145 if (insn
& (1 << 19)) {
8146 if (insn
& (1 << 8))
8148 if (insn
& (1 << 7))
8150 if (insn
& (1 << 6))
8152 if (insn
& (1 << 18))
8155 if (insn
& (1 << 17)) {
8157 val
|= (insn
& 0x1f);
8160 gen_set_psr_im(s
, mask
, 0, val
);
8167 /* if not always execute, we generate a conditional jump to
8169 s
->condlabel
= gen_new_label();
8170 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8173 if ((insn
& 0x0f900000) == 0x03000000) {
8174 if ((insn
& (1 << 21)) == 0) {
8176 rd
= (insn
>> 12) & 0xf;
8177 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8178 if ((insn
& (1 << 22)) == 0) {
8180 tmp
= tcg_temp_new_i32();
8181 tcg_gen_movi_i32(tmp
, val
);
8184 tmp
= load_reg(s
, rd
);
8185 tcg_gen_ext16u_i32(tmp
, tmp
);
8186 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8188 store_reg(s
, rd
, tmp
);
8190 if (((insn
>> 12) & 0xf) != 0xf)
8192 if (((insn
>> 16) & 0xf) == 0) {
8193 gen_nop_hint(s
, insn
& 0xff);
8195 /* CPSR = immediate */
8197 shift
= ((insn
>> 8) & 0xf) * 2;
8199 val
= (val
>> shift
) | (val
<< (32 - shift
));
8200 i
= ((insn
& (1 << 22)) != 0);
8201 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8207 } else if ((insn
& 0x0f900000) == 0x01000000
8208 && (insn
& 0x00000090) != 0x00000090) {
8209 /* miscellaneous instructions */
8210 op1
= (insn
>> 21) & 3;
8211 sh
= (insn
>> 4) & 0xf;
8214 case 0x0: /* MSR, MRS */
8215 if (insn
& (1 << 9)) {
8216 /* MSR (banked) and MRS (banked) */
8217 int sysm
= extract32(insn
, 16, 4) |
8218 (extract32(insn
, 8, 1) << 4);
8219 int r
= extract32(insn
, 22, 1);
8223 gen_msr_banked(s
, r
, sysm
, rm
);
8226 int rd
= extract32(insn
, 12, 4);
8228 gen_mrs_banked(s
, r
, sysm
, rd
);
8233 /* MSR, MRS (for PSRs) */
8236 tmp
= load_reg(s
, rm
);
8237 i
= ((op1
& 2) != 0);
8238 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8242 rd
= (insn
>> 12) & 0xf;
8246 tmp
= load_cpu_field(spsr
);
8248 tmp
= tcg_temp_new_i32();
8249 gen_helper_cpsr_read(tmp
, cpu_env
);
8251 store_reg(s
, rd
, tmp
);
8256 /* branch/exchange thumb (bx). */
8258 tmp
= load_reg(s
, rm
);
8260 } else if (op1
== 3) {
8263 rd
= (insn
>> 12) & 0xf;
8264 tmp
= load_reg(s
, rm
);
8265 gen_helper_clz(tmp
, tmp
);
8266 store_reg(s
, rd
, tmp
);
8274 /* Trivial implementation equivalent to bx. */
8275 tmp
= load_reg(s
, rm
);
8286 /* branch link/exchange thumb (blx) */
8287 tmp
= load_reg(s
, rm
);
8288 tmp2
= tcg_temp_new_i32();
8289 tcg_gen_movi_i32(tmp2
, s
->pc
);
8290 store_reg(s
, 14, tmp2
);
8296 uint32_t c
= extract32(insn
, 8, 4);
8298 /* Check this CPU supports ARMv8 CRC instructions.
8299 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8300 * Bits 8, 10 and 11 should be zero.
8302 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8307 rn
= extract32(insn
, 16, 4);
8308 rd
= extract32(insn
, 12, 4);
8310 tmp
= load_reg(s
, rn
);
8311 tmp2
= load_reg(s
, rm
);
8313 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8314 } else if (op1
== 1) {
8315 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8317 tmp3
= tcg_const_i32(1 << op1
);
8319 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8321 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8323 tcg_temp_free_i32(tmp2
);
8324 tcg_temp_free_i32(tmp3
);
8325 store_reg(s
, rd
, tmp
);
8328 case 0x5: /* saturating add/subtract */
8330 rd
= (insn
>> 12) & 0xf;
8331 rn
= (insn
>> 16) & 0xf;
8332 tmp
= load_reg(s
, rm
);
8333 tmp2
= load_reg(s
, rn
);
8335 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8337 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8339 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8340 tcg_temp_free_i32(tmp2
);
8341 store_reg(s
, rd
, tmp
);
8345 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8350 gen_exception_insn(s
, 4, EXCP_BKPT
,
8351 syn_aa32_bkpt(imm16
, false),
8352 default_exception_el(s
));
8355 /* Hypervisor call (v7) */
8363 /* Secure monitor call (v6+) */
8375 case 0x8: /* signed multiply */
8380 rs
= (insn
>> 8) & 0xf;
8381 rn
= (insn
>> 12) & 0xf;
8382 rd
= (insn
>> 16) & 0xf;
8384 /* (32 * 16) >> 16 */
8385 tmp
= load_reg(s
, rm
);
8386 tmp2
= load_reg(s
, rs
);
8388 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8391 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8392 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8393 tmp
= tcg_temp_new_i32();
8394 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8395 tcg_temp_free_i64(tmp64
);
8396 if ((sh
& 2) == 0) {
8397 tmp2
= load_reg(s
, rn
);
8398 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8399 tcg_temp_free_i32(tmp2
);
8401 store_reg(s
, rd
, tmp
);
8404 tmp
= load_reg(s
, rm
);
8405 tmp2
= load_reg(s
, rs
);
8406 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8407 tcg_temp_free_i32(tmp2
);
8409 tmp64
= tcg_temp_new_i64();
8410 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8411 tcg_temp_free_i32(tmp
);
8412 gen_addq(s
, tmp64
, rn
, rd
);
8413 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8414 tcg_temp_free_i64(tmp64
);
8417 tmp2
= load_reg(s
, rn
);
8418 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8419 tcg_temp_free_i32(tmp2
);
8421 store_reg(s
, rd
, tmp
);
8428 } else if (((insn
& 0x0e000000) == 0 &&
8429 (insn
& 0x00000090) != 0x90) ||
8430 ((insn
& 0x0e000000) == (1 << 25))) {
8431 int set_cc
, logic_cc
, shiftop
;
8433 op1
= (insn
>> 21) & 0xf;
8434 set_cc
= (insn
>> 20) & 1;
8435 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8437 /* data processing instruction */
8438 if (insn
& (1 << 25)) {
8439 /* immediate operand */
8441 shift
= ((insn
>> 8) & 0xf) * 2;
8443 val
= (val
>> shift
) | (val
<< (32 - shift
));
8445 tmp2
= tcg_temp_new_i32();
8446 tcg_gen_movi_i32(tmp2
, val
);
8447 if (logic_cc
&& shift
) {
8448 gen_set_CF_bit31(tmp2
);
8453 tmp2
= load_reg(s
, rm
);
8454 shiftop
= (insn
>> 5) & 3;
8455 if (!(insn
& (1 << 4))) {
8456 shift
= (insn
>> 7) & 0x1f;
8457 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8459 rs
= (insn
>> 8) & 0xf;
8460 tmp
= load_reg(s
, rs
);
8461 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8464 if (op1
!= 0x0f && op1
!= 0x0d) {
8465 rn
= (insn
>> 16) & 0xf;
8466 tmp
= load_reg(s
, rn
);
8468 TCGV_UNUSED_I32(tmp
);
8470 rd
= (insn
>> 12) & 0xf;
8473 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8477 store_reg_bx(s
, rd
, tmp
);
8480 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8484 store_reg_bx(s
, rd
, tmp
);
8487 if (set_cc
&& rd
== 15) {
8488 /* SUBS r15, ... is used for exception return. */
8492 gen_sub_CC(tmp
, tmp
, tmp2
);
8493 gen_exception_return(s
, tmp
);
8496 gen_sub_CC(tmp
, tmp
, tmp2
);
8498 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8500 store_reg_bx(s
, rd
, tmp
);
8505 gen_sub_CC(tmp
, tmp2
, tmp
);
8507 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8509 store_reg_bx(s
, rd
, tmp
);
8513 gen_add_CC(tmp
, tmp
, tmp2
);
8515 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8517 store_reg_bx(s
, rd
, tmp
);
8521 gen_adc_CC(tmp
, tmp
, tmp2
);
8523 gen_add_carry(tmp
, tmp
, tmp2
);
8525 store_reg_bx(s
, rd
, tmp
);
8529 gen_sbc_CC(tmp
, tmp
, tmp2
);
8531 gen_sub_carry(tmp
, tmp
, tmp2
);
8533 store_reg_bx(s
, rd
, tmp
);
8537 gen_sbc_CC(tmp
, tmp2
, tmp
);
8539 gen_sub_carry(tmp
, tmp2
, tmp
);
8541 store_reg_bx(s
, rd
, tmp
);
8545 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8548 tcg_temp_free_i32(tmp
);
8552 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8555 tcg_temp_free_i32(tmp
);
8559 gen_sub_CC(tmp
, tmp
, tmp2
);
8561 tcg_temp_free_i32(tmp
);
8565 gen_add_CC(tmp
, tmp
, tmp2
);
8567 tcg_temp_free_i32(tmp
);
8570 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8574 store_reg_bx(s
, rd
, tmp
);
8577 if (logic_cc
&& rd
== 15) {
8578 /* MOVS r15, ... is used for exception return. */
8582 gen_exception_return(s
, tmp2
);
8587 store_reg_bx(s
, rd
, tmp2
);
8591 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8595 store_reg_bx(s
, rd
, tmp
);
8599 tcg_gen_not_i32(tmp2
, tmp2
);
8603 store_reg_bx(s
, rd
, tmp2
);
8606 if (op1
!= 0x0f && op1
!= 0x0d) {
8607 tcg_temp_free_i32(tmp2
);
8610 /* other instructions */
8611 op1
= (insn
>> 24) & 0xf;
8615 /* multiplies, extra load/stores */
8616 sh
= (insn
>> 5) & 3;
8619 rd
= (insn
>> 16) & 0xf;
8620 rn
= (insn
>> 12) & 0xf;
8621 rs
= (insn
>> 8) & 0xf;
8623 op1
= (insn
>> 20) & 0xf;
8625 case 0: case 1: case 2: case 3: case 6:
8627 tmp
= load_reg(s
, rs
);
8628 tmp2
= load_reg(s
, rm
);
8629 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8630 tcg_temp_free_i32(tmp2
);
8631 if (insn
& (1 << 22)) {
8632 /* Subtract (mls) */
8634 tmp2
= load_reg(s
, rn
);
8635 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8636 tcg_temp_free_i32(tmp2
);
8637 } else if (insn
& (1 << 21)) {
8639 tmp2
= load_reg(s
, rn
);
8640 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8641 tcg_temp_free_i32(tmp2
);
8643 if (insn
& (1 << 20))
8645 store_reg(s
, rd
, tmp
);
8648 /* 64 bit mul double accumulate (UMAAL) */
8650 tmp
= load_reg(s
, rs
);
8651 tmp2
= load_reg(s
, rm
);
8652 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8653 gen_addq_lo(s
, tmp64
, rn
);
8654 gen_addq_lo(s
, tmp64
, rd
);
8655 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8656 tcg_temp_free_i64(tmp64
);
8658 case 8: case 9: case 10: case 11:
8659 case 12: case 13: case 14: case 15:
8660 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8661 tmp
= load_reg(s
, rs
);
8662 tmp2
= load_reg(s
, rm
);
8663 if (insn
& (1 << 22)) {
8664 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8666 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8668 if (insn
& (1 << 21)) { /* mult accumulate */
8669 TCGv_i32 al
= load_reg(s
, rn
);
8670 TCGv_i32 ah
= load_reg(s
, rd
);
8671 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8672 tcg_temp_free_i32(al
);
8673 tcg_temp_free_i32(ah
);
8675 if (insn
& (1 << 20)) {
8676 gen_logicq_cc(tmp
, tmp2
);
8678 store_reg(s
, rn
, tmp
);
8679 store_reg(s
, rd
, tmp2
);
8685 rn
= (insn
>> 16) & 0xf;
8686 rd
= (insn
>> 12) & 0xf;
8687 if (insn
& (1 << 23)) {
8688 /* load/store exclusive */
8689 int op2
= (insn
>> 8) & 3;
8690 op1
= (insn
>> 21) & 0x3;
8693 case 0: /* lda/stl */
8699 case 1: /* reserved */
8701 case 2: /* ldaex/stlex */
8704 case 3: /* ldrex/strex */
8713 addr
= tcg_temp_local_new_i32();
8714 load_reg_var(s
, addr
, rn
);
8716 /* Since the emulation does not have barriers,
8717 the acquire/release semantics need no special
8720 if (insn
& (1 << 20)) {
8721 tmp
= tcg_temp_new_i32();
8724 gen_aa32_ld32u(s
, tmp
, addr
,
8728 gen_aa32_ld8u(s
, tmp
, addr
,
8732 gen_aa32_ld16u(s
, tmp
, addr
,
8738 store_reg(s
, rd
, tmp
);
8741 tmp
= load_reg(s
, rm
);
8744 gen_aa32_st32(s
, tmp
, addr
,
8748 gen_aa32_st8(s
, tmp
, addr
,
8752 gen_aa32_st16(s
, tmp
, addr
,
8758 tcg_temp_free_i32(tmp
);
8760 } else if (insn
& (1 << 20)) {
8763 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8765 case 1: /* ldrexd */
8766 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8768 case 2: /* ldrexb */
8769 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8771 case 3: /* ldrexh */
8772 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8781 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8783 case 1: /* strexd */
8784 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8786 case 2: /* strexb */
8787 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8789 case 3: /* strexh */
8790 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8796 tcg_temp_free_i32(addr
);
8798 /* SWP instruction */
8801 /* ??? This is not really atomic. However we know
8802 we never have multiple CPUs running in parallel,
8803 so it is good enough. */
8804 addr
= load_reg(s
, rn
);
8805 tmp
= load_reg(s
, rm
);
8806 tmp2
= tcg_temp_new_i32();
8807 if (insn
& (1 << 22)) {
8808 gen_aa32_ld8u(s
, tmp2
, addr
, get_mem_index(s
));
8809 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
8811 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8812 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8814 tcg_temp_free_i32(tmp
);
8815 tcg_temp_free_i32(addr
);
8816 store_reg(s
, rd
, tmp2
);
8821 bool load
= insn
& (1 << 20);
8822 bool doubleword
= false;
8823 /* Misc load/store */
8824 rn
= (insn
>> 16) & 0xf;
8825 rd
= (insn
>> 12) & 0xf;
8827 if (!load
&& (sh
& 2)) {
8831 /* UNPREDICTABLE; we choose to UNDEF */
8834 load
= (sh
& 1) == 0;
8838 addr
= load_reg(s
, rn
);
8839 if (insn
& (1 << 24))
8840 gen_add_datah_offset(s
, insn
, 0, addr
);
8846 tmp
= load_reg(s
, rd
);
8847 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8848 tcg_temp_free_i32(tmp
);
8849 tcg_gen_addi_i32(addr
, addr
, 4);
8850 tmp
= load_reg(s
, rd
+ 1);
8851 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8852 tcg_temp_free_i32(tmp
);
8855 tmp
= tcg_temp_new_i32();
8856 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8857 store_reg(s
, rd
, tmp
);
8858 tcg_gen_addi_i32(addr
, addr
, 4);
8859 tmp
= tcg_temp_new_i32();
8860 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8863 address_offset
= -4;
8866 tmp
= tcg_temp_new_i32();
8869 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
8872 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
8876 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
8881 tmp
= load_reg(s
, rd
);
8882 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
8883 tcg_temp_free_i32(tmp
);
8885 /* Perform base writeback before the loaded value to
8886 ensure correct behavior with overlapping index registers.
8887 ldrd with base writeback is undefined if the
8888 destination and index registers overlap. */
8889 if (!(insn
& (1 << 24))) {
8890 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8891 store_reg(s
, rn
, addr
);
8892 } else if (insn
& (1 << 21)) {
8894 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8895 store_reg(s
, rn
, addr
);
8897 tcg_temp_free_i32(addr
);
8900 /* Complete the load. */
8901 store_reg(s
, rd
, tmp
);
8910 if (insn
& (1 << 4)) {
8912 /* Armv6 Media instructions. */
8914 rn
= (insn
>> 16) & 0xf;
8915 rd
= (insn
>> 12) & 0xf;
8916 rs
= (insn
>> 8) & 0xf;
8917 switch ((insn
>> 23) & 3) {
8918 case 0: /* Parallel add/subtract. */
8919 op1
= (insn
>> 20) & 7;
8920 tmp
= load_reg(s
, rn
);
8921 tmp2
= load_reg(s
, rm
);
8922 sh
= (insn
>> 5) & 7;
8923 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8925 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8926 tcg_temp_free_i32(tmp2
);
8927 store_reg(s
, rd
, tmp
);
8930 if ((insn
& 0x00700020) == 0) {
8931 /* Halfword pack. */
8932 tmp
= load_reg(s
, rn
);
8933 tmp2
= load_reg(s
, rm
);
8934 shift
= (insn
>> 7) & 0x1f;
8935 if (insn
& (1 << 6)) {
8939 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8940 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8941 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8945 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8946 tcg_gen_ext16u_i32(tmp
, tmp
);
8947 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8949 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8950 tcg_temp_free_i32(tmp2
);
8951 store_reg(s
, rd
, tmp
);
8952 } else if ((insn
& 0x00200020) == 0x00200000) {
8954 tmp
= load_reg(s
, rm
);
8955 shift
= (insn
>> 7) & 0x1f;
8956 if (insn
& (1 << 6)) {
8959 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8961 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8963 sh
= (insn
>> 16) & 0x1f;
8964 tmp2
= tcg_const_i32(sh
);
8965 if (insn
& (1 << 22))
8966 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8968 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8969 tcg_temp_free_i32(tmp2
);
8970 store_reg(s
, rd
, tmp
);
8971 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8973 tmp
= load_reg(s
, rm
);
8974 sh
= (insn
>> 16) & 0x1f;
8975 tmp2
= tcg_const_i32(sh
);
8976 if (insn
& (1 << 22))
8977 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8979 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8980 tcg_temp_free_i32(tmp2
);
8981 store_reg(s
, rd
, tmp
);
8982 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8984 tmp
= load_reg(s
, rn
);
8985 tmp2
= load_reg(s
, rm
);
8986 tmp3
= tcg_temp_new_i32();
8987 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8988 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8989 tcg_temp_free_i32(tmp3
);
8990 tcg_temp_free_i32(tmp2
);
8991 store_reg(s
, rd
, tmp
);
8992 } else if ((insn
& 0x000003e0) == 0x00000060) {
8993 tmp
= load_reg(s
, rm
);
8994 shift
= (insn
>> 10) & 3;
8995 /* ??? In many cases it's not necessary to do a
8996 rotate, a shift is sufficient. */
8998 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8999 op1
= (insn
>> 20) & 7;
9001 case 0: gen_sxtb16(tmp
); break;
9002 case 2: gen_sxtb(tmp
); break;
9003 case 3: gen_sxth(tmp
); break;
9004 case 4: gen_uxtb16(tmp
); break;
9005 case 6: gen_uxtb(tmp
); break;
9006 case 7: gen_uxth(tmp
); break;
9007 default: goto illegal_op
;
9010 tmp2
= load_reg(s
, rn
);
9011 if ((op1
& 3) == 0) {
9012 gen_add16(tmp
, tmp2
);
9014 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9015 tcg_temp_free_i32(tmp2
);
9018 store_reg(s
, rd
, tmp
);
9019 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9021 tmp
= load_reg(s
, rm
);
9022 if (insn
& (1 << 22)) {
9023 if (insn
& (1 << 7)) {
9027 gen_helper_rbit(tmp
, tmp
);
9030 if (insn
& (1 << 7))
9033 tcg_gen_bswap32_i32(tmp
, tmp
);
9035 store_reg(s
, rd
, tmp
);
9040 case 2: /* Multiplies (Type 3). */
9041 switch ((insn
>> 20) & 0x7) {
9043 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9044 /* op2 not 00x or 11x : UNDEF */
9047 /* Signed multiply most significant [accumulate].
9048 (SMMUL, SMMLA, SMMLS) */
9049 tmp
= load_reg(s
, rm
);
9050 tmp2
= load_reg(s
, rs
);
9051 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9054 tmp
= load_reg(s
, rd
);
9055 if (insn
& (1 << 6)) {
9056 tmp64
= gen_subq_msw(tmp64
, tmp
);
9058 tmp64
= gen_addq_msw(tmp64
, tmp
);
9061 if (insn
& (1 << 5)) {
9062 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9064 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9065 tmp
= tcg_temp_new_i32();
9066 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9067 tcg_temp_free_i64(tmp64
);
9068 store_reg(s
, rn
, tmp
);
9072 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9073 if (insn
& (1 << 7)) {
9076 tmp
= load_reg(s
, rm
);
9077 tmp2
= load_reg(s
, rs
);
9078 if (insn
& (1 << 5))
9079 gen_swap_half(tmp2
);
9080 gen_smul_dual(tmp
, tmp2
);
9081 if (insn
& (1 << 22)) {
9082 /* smlald, smlsld */
9085 tmp64
= tcg_temp_new_i64();
9086 tmp64_2
= tcg_temp_new_i64();
9087 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9088 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9089 tcg_temp_free_i32(tmp
);
9090 tcg_temp_free_i32(tmp2
);
9091 if (insn
& (1 << 6)) {
9092 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9094 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9096 tcg_temp_free_i64(tmp64_2
);
9097 gen_addq(s
, tmp64
, rd
, rn
);
9098 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9099 tcg_temp_free_i64(tmp64
);
9101 /* smuad, smusd, smlad, smlsd */
9102 if (insn
& (1 << 6)) {
9103 /* This subtraction cannot overflow. */
9104 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9106 /* This addition cannot overflow 32 bits;
9107 * however it may overflow considered as a
9108 * signed operation, in which case we must set
9111 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9113 tcg_temp_free_i32(tmp2
);
9116 tmp2
= load_reg(s
, rd
);
9117 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9118 tcg_temp_free_i32(tmp2
);
9120 store_reg(s
, rn
, tmp
);
9126 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9129 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9132 tmp
= load_reg(s
, rm
);
9133 tmp2
= load_reg(s
, rs
);
9134 if (insn
& (1 << 21)) {
9135 gen_helper_udiv(tmp
, tmp
, tmp2
);
9137 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9139 tcg_temp_free_i32(tmp2
);
9140 store_reg(s
, rn
, tmp
);
9147 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9149 case 0: /* Unsigned sum of absolute differences. */
9151 tmp
= load_reg(s
, rm
);
9152 tmp2
= load_reg(s
, rs
);
9153 gen_helper_usad8(tmp
, tmp
, tmp2
);
9154 tcg_temp_free_i32(tmp2
);
9156 tmp2
= load_reg(s
, rd
);
9157 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9158 tcg_temp_free_i32(tmp2
);
9160 store_reg(s
, rn
, tmp
);
9162 case 0x20: case 0x24: case 0x28: case 0x2c:
9163 /* Bitfield insert/clear. */
9165 shift
= (insn
>> 7) & 0x1f;
9166 i
= (insn
>> 16) & 0x1f;
9168 /* UNPREDICTABLE; we choose to UNDEF */
9173 tmp
= tcg_temp_new_i32();
9174 tcg_gen_movi_i32(tmp
, 0);
9176 tmp
= load_reg(s
, rm
);
9179 tmp2
= load_reg(s
, rd
);
9180 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9181 tcg_temp_free_i32(tmp2
);
9183 store_reg(s
, rd
, tmp
);
9185 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9186 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9188 tmp
= load_reg(s
, rm
);
9189 shift
= (insn
>> 7) & 0x1f;
9190 i
= ((insn
>> 16) & 0x1f) + 1;
9195 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
9197 gen_sbfx(tmp
, shift
, i
);
9200 store_reg(s
, rd
, tmp
);
9210 /* Check for undefined extension instructions
9211 * per the ARM Bible IE:
9212 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9214 sh
= (0xf << 20) | (0xf << 4);
9215 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9219 /* load/store byte/word */
9220 rn
= (insn
>> 16) & 0xf;
9221 rd
= (insn
>> 12) & 0xf;
9222 tmp2
= load_reg(s
, rn
);
9223 if ((insn
& 0x01200000) == 0x00200000) {
9225 i
= get_a32_user_mem_index(s
);
9227 i
= get_mem_index(s
);
9229 if (insn
& (1 << 24))
9230 gen_add_data_offset(s
, insn
, tmp2
);
9231 if (insn
& (1 << 20)) {
9233 tmp
= tcg_temp_new_i32();
9234 if (insn
& (1 << 22)) {
9235 gen_aa32_ld8u(s
, tmp
, tmp2
, i
);
9237 gen_aa32_ld32u(s
, tmp
, tmp2
, i
);
9241 tmp
= load_reg(s
, rd
);
9242 if (insn
& (1 << 22)) {
9243 gen_aa32_st8(s
, tmp
, tmp2
, i
);
9245 gen_aa32_st32(s
, tmp
, tmp2
, i
);
9247 tcg_temp_free_i32(tmp
);
9249 if (!(insn
& (1 << 24))) {
9250 gen_add_data_offset(s
, insn
, tmp2
);
9251 store_reg(s
, rn
, tmp2
);
9252 } else if (insn
& (1 << 21)) {
9253 store_reg(s
, rn
, tmp2
);
9255 tcg_temp_free_i32(tmp2
);
9257 if (insn
& (1 << 20)) {
9258 /* Complete the load. */
9259 store_reg_from_load(s
, rd
, tmp
);
9265 int j
, n
, loaded_base
;
9266 bool exc_return
= false;
9267 bool is_load
= extract32(insn
, 20, 1);
9269 TCGv_i32 loaded_var
;
9270 /* load/store multiple words */
9271 /* XXX: store correct base if write back */
9272 if (insn
& (1 << 22)) {
9273 /* LDM (user), LDM (exception return) and STM (user) */
9275 goto illegal_op
; /* only usable in supervisor mode */
9277 if (is_load
&& extract32(insn
, 15, 1)) {
9283 rn
= (insn
>> 16) & 0xf;
9284 addr
= load_reg(s
, rn
);
9286 /* compute total size */
9288 TCGV_UNUSED_I32(loaded_var
);
9291 if (insn
& (1 << i
))
9294 /* XXX: test invalid n == 0 case ? */
9295 if (insn
& (1 << 23)) {
9296 if (insn
& (1 << 24)) {
9298 tcg_gen_addi_i32(addr
, addr
, 4);
9300 /* post increment */
9303 if (insn
& (1 << 24)) {
9305 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9307 /* post decrement */
9309 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9314 if (insn
& (1 << i
)) {
9317 tmp
= tcg_temp_new_i32();
9318 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9320 tmp2
= tcg_const_i32(i
);
9321 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9322 tcg_temp_free_i32(tmp2
);
9323 tcg_temp_free_i32(tmp
);
9324 } else if (i
== rn
) {
9328 store_reg_from_load(s
, i
, tmp
);
9333 /* special case: r15 = PC + 8 */
9334 val
= (long)s
->pc
+ 4;
9335 tmp
= tcg_temp_new_i32();
9336 tcg_gen_movi_i32(tmp
, val
);
9338 tmp
= tcg_temp_new_i32();
9339 tmp2
= tcg_const_i32(i
);
9340 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9341 tcg_temp_free_i32(tmp2
);
9343 tmp
= load_reg(s
, i
);
9345 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9346 tcg_temp_free_i32(tmp
);
9349 /* no need to add after the last transfer */
9351 tcg_gen_addi_i32(addr
, addr
, 4);
9354 if (insn
& (1 << 21)) {
9356 if (insn
& (1 << 23)) {
9357 if (insn
& (1 << 24)) {
9360 /* post increment */
9361 tcg_gen_addi_i32(addr
, addr
, 4);
9364 if (insn
& (1 << 24)) {
9367 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9369 /* post decrement */
9370 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9373 store_reg(s
, rn
, addr
);
9375 tcg_temp_free_i32(addr
);
9378 store_reg(s
, rn
, loaded_var
);
9381 /* Restore CPSR from SPSR. */
9382 tmp
= load_cpu_field(spsr
);
9383 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9384 tcg_temp_free_i32(tmp
);
9385 s
->is_jmp
= DISAS_JUMP
;
9394 /* branch (and link) */
9395 val
= (int32_t)s
->pc
;
9396 if (insn
& (1 << 24)) {
9397 tmp
= tcg_temp_new_i32();
9398 tcg_gen_movi_i32(tmp
, val
);
9399 store_reg(s
, 14, tmp
);
9401 offset
= sextract32(insn
<< 2, 0, 26);
9409 if (((insn
>> 8) & 0xe) == 10) {
9411 if (disas_vfp_insn(s
, insn
)) {
9414 } else if (disas_coproc_insn(s
, insn
)) {
9421 gen_set_pc_im(s
, s
->pc
);
9422 s
->svc_imm
= extract32(insn
, 0, 24);
9423 s
->is_jmp
= DISAS_SWI
;
9427 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9428 default_exception_el(s
));
9434 /* Return true if this is a Thumb-2 logical op. */
9436 thumb2_logic_op(int op
)
9441 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9442 then set condition code flags based on the result of the operation.
9443 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9444 to the high bit of T1.
9445 Returns zero if the opcode is valid. */
9448 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9449 TCGv_i32 t0
, TCGv_i32 t1
)
9456 tcg_gen_and_i32(t0
, t0
, t1
);
9460 tcg_gen_andc_i32(t0
, t0
, t1
);
9464 tcg_gen_or_i32(t0
, t0
, t1
);
9468 tcg_gen_orc_i32(t0
, t0
, t1
);
9472 tcg_gen_xor_i32(t0
, t0
, t1
);
9477 gen_add_CC(t0
, t0
, t1
);
9479 tcg_gen_add_i32(t0
, t0
, t1
);
9483 gen_adc_CC(t0
, t0
, t1
);
9489 gen_sbc_CC(t0
, t0
, t1
);
9491 gen_sub_carry(t0
, t0
, t1
);
9496 gen_sub_CC(t0
, t0
, t1
);
9498 tcg_gen_sub_i32(t0
, t0
, t1
);
9502 gen_sub_CC(t0
, t1
, t0
);
9504 tcg_gen_sub_i32(t0
, t1
, t0
);
9506 default: /* 5, 6, 7, 9, 12, 15. */
9512 gen_set_CF_bit31(t1
);
9517 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9519 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9521 uint32_t insn
, imm
, shift
, offset
;
9522 uint32_t rd
, rn
, rm
, rs
;
9533 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9534 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9535 /* Thumb-1 cores may need to treat bl and blx as a pair of
9536 16-bit instructions to get correct prefetch abort behavior. */
9538 if ((insn
& (1 << 12)) == 0) {
9540 /* Second half of blx. */
9541 offset
= ((insn
& 0x7ff) << 1);
9542 tmp
= load_reg(s
, 14);
9543 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9544 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9546 tmp2
= tcg_temp_new_i32();
9547 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9548 store_reg(s
, 14, tmp2
);
9552 if (insn
& (1 << 11)) {
9553 /* Second half of bl. */
9554 offset
= ((insn
& 0x7ff) << 1) | 1;
9555 tmp
= load_reg(s
, 14);
9556 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9558 tmp2
= tcg_temp_new_i32();
9559 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9560 store_reg(s
, 14, tmp2
);
9564 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9565 /* Instruction spans a page boundary. Implement it as two
9566 16-bit instructions in case the second half causes an
9568 offset
= ((int32_t)insn
<< 21) >> 9;
9569 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9572 /* Fall through to 32-bit decode. */
9575 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9577 insn
|= (uint32_t)insn_hw1
<< 16;
9579 if ((insn
& 0xf800e800) != 0xf000e800) {
9583 rn
= (insn
>> 16) & 0xf;
9584 rs
= (insn
>> 12) & 0xf;
9585 rd
= (insn
>> 8) & 0xf;
9587 switch ((insn
>> 25) & 0xf) {
9588 case 0: case 1: case 2: case 3:
9589 /* 16-bit instructions. Should never happen. */
9592 if (insn
& (1 << 22)) {
9593 /* Other load/store, table branch. */
9594 if (insn
& 0x01200000) {
9595 /* Load/store doubleword. */
9597 addr
= tcg_temp_new_i32();
9598 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9600 addr
= load_reg(s
, rn
);
9602 offset
= (insn
& 0xff) * 4;
9603 if ((insn
& (1 << 23)) == 0)
9605 if (insn
& (1 << 24)) {
9606 tcg_gen_addi_i32(addr
, addr
, offset
);
9609 if (insn
& (1 << 20)) {
9611 tmp
= tcg_temp_new_i32();
9612 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9613 store_reg(s
, rs
, tmp
);
9614 tcg_gen_addi_i32(addr
, addr
, 4);
9615 tmp
= tcg_temp_new_i32();
9616 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9617 store_reg(s
, rd
, tmp
);
9620 tmp
= load_reg(s
, rs
);
9621 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9622 tcg_temp_free_i32(tmp
);
9623 tcg_gen_addi_i32(addr
, addr
, 4);
9624 tmp
= load_reg(s
, rd
);
9625 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9626 tcg_temp_free_i32(tmp
);
9628 if (insn
& (1 << 21)) {
9629 /* Base writeback. */
9632 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9633 store_reg(s
, rn
, addr
);
9635 tcg_temp_free_i32(addr
);
9637 } else if ((insn
& (1 << 23)) == 0) {
9638 /* Load/store exclusive word. */
9639 addr
= tcg_temp_local_new_i32();
9640 load_reg_var(s
, addr
, rn
);
9641 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9642 if (insn
& (1 << 20)) {
9643 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9645 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9647 tcg_temp_free_i32(addr
);
9648 } else if ((insn
& (7 << 5)) == 0) {
9651 addr
= tcg_temp_new_i32();
9652 tcg_gen_movi_i32(addr
, s
->pc
);
9654 addr
= load_reg(s
, rn
);
9656 tmp
= load_reg(s
, rm
);
9657 tcg_gen_add_i32(addr
, addr
, tmp
);
9658 if (insn
& (1 << 4)) {
9660 tcg_gen_add_i32(addr
, addr
, tmp
);
9661 tcg_temp_free_i32(tmp
);
9662 tmp
= tcg_temp_new_i32();
9663 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9665 tcg_temp_free_i32(tmp
);
9666 tmp
= tcg_temp_new_i32();
9667 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9669 tcg_temp_free_i32(addr
);
9670 tcg_gen_shli_i32(tmp
, tmp
, 1);
9671 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9672 store_reg(s
, 15, tmp
);
9674 int op2
= (insn
>> 6) & 0x3;
9675 op
= (insn
>> 4) & 0x3;
9680 /* Load/store exclusive byte/halfword/doubleword */
9687 /* Load-acquire/store-release */
9693 /* Load-acquire/store-release exclusive */
9697 addr
= tcg_temp_local_new_i32();
9698 load_reg_var(s
, addr
, rn
);
9700 if (insn
& (1 << 20)) {
9701 tmp
= tcg_temp_new_i32();
9704 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9707 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9710 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9715 store_reg(s
, rs
, tmp
);
9717 tmp
= load_reg(s
, rs
);
9720 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
9723 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
9726 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9731 tcg_temp_free_i32(tmp
);
9733 } else if (insn
& (1 << 20)) {
9734 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9736 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9738 tcg_temp_free_i32(addr
);
9741 /* Load/store multiple, RFE, SRS. */
9742 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9743 /* RFE, SRS: not available in user mode or on M profile */
9744 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9747 if (insn
& (1 << 20)) {
9749 addr
= load_reg(s
, rn
);
9750 if ((insn
& (1 << 24)) == 0)
9751 tcg_gen_addi_i32(addr
, addr
, -8);
9752 /* Load PC into tmp and CPSR into tmp2. */
9753 tmp
= tcg_temp_new_i32();
9754 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9755 tcg_gen_addi_i32(addr
, addr
, 4);
9756 tmp2
= tcg_temp_new_i32();
9757 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9758 if (insn
& (1 << 21)) {
9759 /* Base writeback. */
9760 if (insn
& (1 << 24)) {
9761 tcg_gen_addi_i32(addr
, addr
, 4);
9763 tcg_gen_addi_i32(addr
, addr
, -4);
9765 store_reg(s
, rn
, addr
);
9767 tcg_temp_free_i32(addr
);
9769 gen_rfe(s
, tmp
, tmp2
);
9772 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9776 int i
, loaded_base
= 0;
9777 TCGv_i32 loaded_var
;
9778 /* Load/store multiple. */
9779 addr
= load_reg(s
, rn
);
9781 for (i
= 0; i
< 16; i
++) {
9782 if (insn
& (1 << i
))
9785 if (insn
& (1 << 24)) {
9786 tcg_gen_addi_i32(addr
, addr
, -offset
);
9789 TCGV_UNUSED_I32(loaded_var
);
9790 for (i
= 0; i
< 16; i
++) {
9791 if ((insn
& (1 << i
)) == 0)
9793 if (insn
& (1 << 20)) {
9795 tmp
= tcg_temp_new_i32();
9796 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9799 } else if (i
== rn
) {
9803 store_reg(s
, i
, tmp
);
9807 tmp
= load_reg(s
, i
);
9808 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9809 tcg_temp_free_i32(tmp
);
9811 tcg_gen_addi_i32(addr
, addr
, 4);
9814 store_reg(s
, rn
, loaded_var
);
9816 if (insn
& (1 << 21)) {
9817 /* Base register writeback. */
9818 if (insn
& (1 << 24)) {
9819 tcg_gen_addi_i32(addr
, addr
, -offset
);
9821 /* Fault if writeback register is in register list. */
9822 if (insn
& (1 << rn
))
9824 store_reg(s
, rn
, addr
);
9826 tcg_temp_free_i32(addr
);
9833 op
= (insn
>> 21) & 0xf;
9835 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9838 /* Halfword pack. */
9839 tmp
= load_reg(s
, rn
);
9840 tmp2
= load_reg(s
, rm
);
9841 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9842 if (insn
& (1 << 5)) {
9846 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9847 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9848 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9852 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9853 tcg_gen_ext16u_i32(tmp
, tmp
);
9854 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9856 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9857 tcg_temp_free_i32(tmp2
);
9858 store_reg(s
, rd
, tmp
);
9860 /* Data processing register constant shift. */
9862 tmp
= tcg_temp_new_i32();
9863 tcg_gen_movi_i32(tmp
, 0);
9865 tmp
= load_reg(s
, rn
);
9867 tmp2
= load_reg(s
, rm
);
9869 shiftop
= (insn
>> 4) & 3;
9870 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9871 conds
= (insn
& (1 << 20)) != 0;
9872 logic_cc
= (conds
&& thumb2_logic_op(op
));
9873 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9874 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9876 tcg_temp_free_i32(tmp2
);
9878 store_reg(s
, rd
, tmp
);
9880 tcg_temp_free_i32(tmp
);
9884 case 13: /* Misc data processing. */
9885 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9886 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9889 case 0: /* Register controlled shift. */
9890 tmp
= load_reg(s
, rn
);
9891 tmp2
= load_reg(s
, rm
);
9892 if ((insn
& 0x70) != 0)
9894 op
= (insn
>> 21) & 3;
9895 logic_cc
= (insn
& (1 << 20)) != 0;
9896 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9899 store_reg_bx(s
, rd
, tmp
);
9901 case 1: /* Sign/zero extend. */
9902 op
= (insn
>> 20) & 7;
9904 case 0: /* SXTAH, SXTH */
9905 case 1: /* UXTAH, UXTH */
9906 case 4: /* SXTAB, SXTB */
9907 case 5: /* UXTAB, UXTB */
9909 case 2: /* SXTAB16, SXTB16 */
9910 case 3: /* UXTAB16, UXTB16 */
9911 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9919 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9923 tmp
= load_reg(s
, rm
);
9924 shift
= (insn
>> 4) & 3;
9925 /* ??? In many cases it's not necessary to do a
9926 rotate, a shift is sufficient. */
9928 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9929 op
= (insn
>> 20) & 7;
9931 case 0: gen_sxth(tmp
); break;
9932 case 1: gen_uxth(tmp
); break;
9933 case 2: gen_sxtb16(tmp
); break;
9934 case 3: gen_uxtb16(tmp
); break;
9935 case 4: gen_sxtb(tmp
); break;
9936 case 5: gen_uxtb(tmp
); break;
9938 g_assert_not_reached();
9941 tmp2
= load_reg(s
, rn
);
9942 if ((op
>> 1) == 1) {
9943 gen_add16(tmp
, tmp2
);
9945 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9946 tcg_temp_free_i32(tmp2
);
9949 store_reg(s
, rd
, tmp
);
9951 case 2: /* SIMD add/subtract. */
9952 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9955 op
= (insn
>> 20) & 7;
9956 shift
= (insn
>> 4) & 7;
9957 if ((op
& 3) == 3 || (shift
& 3) == 3)
9959 tmp
= load_reg(s
, rn
);
9960 tmp2
= load_reg(s
, rm
);
9961 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9962 tcg_temp_free_i32(tmp2
);
9963 store_reg(s
, rd
, tmp
);
9965 case 3: /* Other data processing. */
9966 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9968 /* Saturating add/subtract. */
9969 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9972 tmp
= load_reg(s
, rn
);
9973 tmp2
= load_reg(s
, rm
);
9975 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9977 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9979 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9980 tcg_temp_free_i32(tmp2
);
9983 case 0x0a: /* rbit */
9984 case 0x08: /* rev */
9985 case 0x09: /* rev16 */
9986 case 0x0b: /* revsh */
9987 case 0x18: /* clz */
9989 case 0x10: /* sel */
9990 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9994 case 0x20: /* crc32/crc32c */
10000 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10007 tmp
= load_reg(s
, rn
);
10009 case 0x0a: /* rbit */
10010 gen_helper_rbit(tmp
, tmp
);
10012 case 0x08: /* rev */
10013 tcg_gen_bswap32_i32(tmp
, tmp
);
10015 case 0x09: /* rev16 */
10018 case 0x0b: /* revsh */
10021 case 0x10: /* sel */
10022 tmp2
= load_reg(s
, rm
);
10023 tmp3
= tcg_temp_new_i32();
10024 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10025 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10026 tcg_temp_free_i32(tmp3
);
10027 tcg_temp_free_i32(tmp2
);
10029 case 0x18: /* clz */
10030 gen_helper_clz(tmp
, tmp
);
10040 uint32_t sz
= op
& 0x3;
10041 uint32_t c
= op
& 0x8;
10043 tmp2
= load_reg(s
, rm
);
10045 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10046 } else if (sz
== 1) {
10047 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10049 tmp3
= tcg_const_i32(1 << sz
);
10051 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10053 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10055 tcg_temp_free_i32(tmp2
);
10056 tcg_temp_free_i32(tmp3
);
10060 g_assert_not_reached();
10063 store_reg(s
, rd
, tmp
);
10065 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10066 switch ((insn
>> 20) & 7) {
10067 case 0: /* 32 x 32 -> 32 */
10068 case 7: /* Unsigned sum of absolute differences. */
10070 case 1: /* 16 x 16 -> 32 */
10071 case 2: /* Dual multiply add. */
10072 case 3: /* 32 * 16 -> 32msb */
10073 case 4: /* Dual multiply subtract. */
10074 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10075 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10080 op
= (insn
>> 4) & 0xf;
10081 tmp
= load_reg(s
, rn
);
10082 tmp2
= load_reg(s
, rm
);
10083 switch ((insn
>> 20) & 7) {
10084 case 0: /* 32 x 32 -> 32 */
10085 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10086 tcg_temp_free_i32(tmp2
);
10088 tmp2
= load_reg(s
, rs
);
10090 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10092 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10093 tcg_temp_free_i32(tmp2
);
10096 case 1: /* 16 x 16 -> 32 */
10097 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10098 tcg_temp_free_i32(tmp2
);
10100 tmp2
= load_reg(s
, rs
);
10101 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10102 tcg_temp_free_i32(tmp2
);
10105 case 2: /* Dual multiply add. */
10106 case 4: /* Dual multiply subtract. */
10108 gen_swap_half(tmp2
);
10109 gen_smul_dual(tmp
, tmp2
);
10110 if (insn
& (1 << 22)) {
10111 /* This subtraction cannot overflow. */
10112 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10114 /* This addition cannot overflow 32 bits;
10115 * however it may overflow considered as a signed
10116 * operation, in which case we must set the Q flag.
10118 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10120 tcg_temp_free_i32(tmp2
);
10123 tmp2
= load_reg(s
, rs
);
10124 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10125 tcg_temp_free_i32(tmp2
);
10128 case 3: /* 32 * 16 -> 32msb */
10130 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10133 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10134 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10135 tmp
= tcg_temp_new_i32();
10136 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10137 tcg_temp_free_i64(tmp64
);
10140 tmp2
= load_reg(s
, rs
);
10141 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10142 tcg_temp_free_i32(tmp2
);
10145 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10146 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10148 tmp
= load_reg(s
, rs
);
10149 if (insn
& (1 << 20)) {
10150 tmp64
= gen_addq_msw(tmp64
, tmp
);
10152 tmp64
= gen_subq_msw(tmp64
, tmp
);
10155 if (insn
& (1 << 4)) {
10156 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10158 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10159 tmp
= tcg_temp_new_i32();
10160 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10161 tcg_temp_free_i64(tmp64
);
10163 case 7: /* Unsigned sum of absolute differences. */
10164 gen_helper_usad8(tmp
, tmp
, tmp2
);
10165 tcg_temp_free_i32(tmp2
);
10167 tmp2
= load_reg(s
, rs
);
10168 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10169 tcg_temp_free_i32(tmp2
);
10173 store_reg(s
, rd
, tmp
);
10175 case 6: case 7: /* 64-bit multiply, Divide. */
10176 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10177 tmp
= load_reg(s
, rn
);
10178 tmp2
= load_reg(s
, rm
);
10179 if ((op
& 0x50) == 0x10) {
10181 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10185 gen_helper_udiv(tmp
, tmp
, tmp2
);
10187 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10188 tcg_temp_free_i32(tmp2
);
10189 store_reg(s
, rd
, tmp
);
10190 } else if ((op
& 0xe) == 0xc) {
10191 /* Dual multiply accumulate long. */
10192 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10193 tcg_temp_free_i32(tmp
);
10194 tcg_temp_free_i32(tmp2
);
10198 gen_swap_half(tmp2
);
10199 gen_smul_dual(tmp
, tmp2
);
10201 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10203 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10205 tcg_temp_free_i32(tmp2
);
10207 tmp64
= tcg_temp_new_i64();
10208 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10209 tcg_temp_free_i32(tmp
);
10210 gen_addq(s
, tmp64
, rs
, rd
);
10211 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10212 tcg_temp_free_i64(tmp64
);
10215 /* Unsigned 64-bit multiply */
10216 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10220 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10221 tcg_temp_free_i32(tmp2
);
10222 tcg_temp_free_i32(tmp
);
10225 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10226 tcg_temp_free_i32(tmp2
);
10227 tmp64
= tcg_temp_new_i64();
10228 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10229 tcg_temp_free_i32(tmp
);
10231 /* Signed 64-bit multiply */
10232 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10237 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10238 tcg_temp_free_i64(tmp64
);
10241 gen_addq_lo(s
, tmp64
, rs
);
10242 gen_addq_lo(s
, tmp64
, rd
);
10243 } else if (op
& 0x40) {
10244 /* 64-bit accumulate. */
10245 gen_addq(s
, tmp64
, rs
, rd
);
10247 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10248 tcg_temp_free_i64(tmp64
);
10253 case 6: case 7: case 14: case 15:
10255 if (((insn
>> 24) & 3) == 3) {
10256 /* Translate into the equivalent ARM encoding. */
10257 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10258 if (disas_neon_data_insn(s
, insn
)) {
10261 } else if (((insn
>> 8) & 0xe) == 10) {
10262 if (disas_vfp_insn(s
, insn
)) {
10266 if (insn
& (1 << 28))
10268 if (disas_coproc_insn(s
, insn
)) {
10273 case 8: case 9: case 10: case 11:
10274 if (insn
& (1 << 15)) {
10275 /* Branches, misc control. */
10276 if (insn
& 0x5000) {
10277 /* Unconditional branch. */
10278 /* signextend(hw1[10:0]) -> offset[:12]. */
10279 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10280 /* hw1[10:0] -> offset[11:1]. */
10281 offset
|= (insn
& 0x7ff) << 1;
10282 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10283 offset[24:22] already have the same value because of the
10284 sign extension above. */
10285 offset
^= ((~insn
) & (1 << 13)) << 10;
10286 offset
^= ((~insn
) & (1 << 11)) << 11;
10288 if (insn
& (1 << 14)) {
10289 /* Branch and link. */
10290 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10294 if (insn
& (1 << 12)) {
10296 gen_jmp(s
, offset
);
10299 offset
&= ~(uint32_t)2;
10300 /* thumb2 bx, no need to check */
10301 gen_bx_im(s
, offset
);
10303 } else if (((insn
>> 23) & 7) == 7) {
10305 if (insn
& (1 << 13))
10308 if (insn
& (1 << 26)) {
10309 if (!(insn
& (1 << 20))) {
10310 /* Hypervisor call (v7) */
10311 int imm16
= extract32(insn
, 16, 4) << 12
10312 | extract32(insn
, 0, 12);
10319 /* Secure monitor call (v6+) */
10327 op
= (insn
>> 20) & 7;
10329 case 0: /* msr cpsr. */
10330 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10331 tmp
= load_reg(s
, rn
);
10332 addr
= tcg_const_i32(insn
& 0xff);
10333 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10334 tcg_temp_free_i32(addr
);
10335 tcg_temp_free_i32(tmp
);
10340 case 1: /* msr spsr. */
10341 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10345 if (extract32(insn
, 5, 1)) {
10347 int sysm
= extract32(insn
, 8, 4) |
10348 (extract32(insn
, 4, 1) << 4);
10351 gen_msr_banked(s
, r
, sysm
, rm
);
10355 /* MSR (for PSRs) */
10356 tmp
= load_reg(s
, rn
);
10358 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10362 case 2: /* cps, nop-hint. */
10363 if (((insn
>> 8) & 7) == 0) {
10364 gen_nop_hint(s
, insn
& 0xff);
10366 /* Implemented as NOP in user mode. */
10371 if (insn
& (1 << 10)) {
10372 if (insn
& (1 << 7))
10374 if (insn
& (1 << 6))
10376 if (insn
& (1 << 5))
10378 if (insn
& (1 << 9))
10379 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10381 if (insn
& (1 << 8)) {
10383 imm
|= (insn
& 0x1f);
10386 gen_set_psr_im(s
, offset
, 0, imm
);
10389 case 3: /* Special control operations. */
10391 op
= (insn
>> 4) & 0xf;
10393 case 2: /* clrex */
10398 /* These execute as NOPs. */
10401 /* We need to break the TB after this insn
10402 * to execute self-modifying code correctly
10403 * and also to take any pending interrupts
10413 /* Trivial implementation equivalent to bx. */
10414 tmp
= load_reg(s
, rn
);
10417 case 5: /* Exception return. */
10421 if (rn
!= 14 || rd
!= 15) {
10424 tmp
= load_reg(s
, rn
);
10425 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10426 gen_exception_return(s
, tmp
);
10429 if (extract32(insn
, 5, 1)) {
10431 int sysm
= extract32(insn
, 16, 4) |
10432 (extract32(insn
, 4, 1) << 4);
10434 gen_mrs_banked(s
, 0, sysm
, rd
);
10439 tmp
= tcg_temp_new_i32();
10440 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10441 addr
= tcg_const_i32(insn
& 0xff);
10442 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10443 tcg_temp_free_i32(addr
);
10445 gen_helper_cpsr_read(tmp
, cpu_env
);
10447 store_reg(s
, rd
, tmp
);
10450 if (extract32(insn
, 5, 1)) {
10452 int sysm
= extract32(insn
, 16, 4) |
10453 (extract32(insn
, 4, 1) << 4);
10455 gen_mrs_banked(s
, 1, sysm
, rd
);
10460 /* Not accessible in user mode. */
10461 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10464 tmp
= load_cpu_field(spsr
);
10465 store_reg(s
, rd
, tmp
);
10470 /* Conditional branch. */
10471 op
= (insn
>> 22) & 0xf;
10472 /* Generate a conditional jump to next instruction. */
10473 s
->condlabel
= gen_new_label();
10474 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10477 /* offset[11:1] = insn[10:0] */
10478 offset
= (insn
& 0x7ff) << 1;
10479 /* offset[17:12] = insn[21:16]. */
10480 offset
|= (insn
& 0x003f0000) >> 4;
10481 /* offset[31:20] = insn[26]. */
10482 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10483 /* offset[18] = insn[13]. */
10484 offset
|= (insn
& (1 << 13)) << 5;
10485 /* offset[19] = insn[11]. */
10486 offset
|= (insn
& (1 << 11)) << 8;
10488 /* jump to the offset */
10489 gen_jmp(s
, s
->pc
+ offset
);
10492 /* Data processing immediate. */
10493 if (insn
& (1 << 25)) {
10494 if (insn
& (1 << 24)) {
10495 if (insn
& (1 << 20))
10497 /* Bitfield/Saturate. */
10498 op
= (insn
>> 21) & 7;
10500 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10502 tmp
= tcg_temp_new_i32();
10503 tcg_gen_movi_i32(tmp
, 0);
10505 tmp
= load_reg(s
, rn
);
10508 case 2: /* Signed bitfield extract. */
10510 if (shift
+ imm
> 32)
10513 gen_sbfx(tmp
, shift
, imm
);
10515 case 6: /* Unsigned bitfield extract. */
10517 if (shift
+ imm
> 32)
10520 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
10522 case 3: /* Bitfield insert/clear. */
10525 imm
= imm
+ 1 - shift
;
10527 tmp2
= load_reg(s
, rd
);
10528 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10529 tcg_temp_free_i32(tmp2
);
10534 default: /* Saturate. */
10537 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10539 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10541 tmp2
= tcg_const_i32(imm
);
10544 if ((op
& 1) && shift
== 0) {
10545 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10546 tcg_temp_free_i32(tmp
);
10547 tcg_temp_free_i32(tmp2
);
10550 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10552 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10556 if ((op
& 1) && shift
== 0) {
10557 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10558 tcg_temp_free_i32(tmp
);
10559 tcg_temp_free_i32(tmp2
);
10562 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10564 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10567 tcg_temp_free_i32(tmp2
);
10570 store_reg(s
, rd
, tmp
);
10572 imm
= ((insn
& 0x04000000) >> 15)
10573 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10574 if (insn
& (1 << 22)) {
10575 /* 16-bit immediate. */
10576 imm
|= (insn
>> 4) & 0xf000;
10577 if (insn
& (1 << 23)) {
10579 tmp
= load_reg(s
, rd
);
10580 tcg_gen_ext16u_i32(tmp
, tmp
);
10581 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10584 tmp
= tcg_temp_new_i32();
10585 tcg_gen_movi_i32(tmp
, imm
);
10588 /* Add/sub 12-bit immediate. */
10590 offset
= s
->pc
& ~(uint32_t)3;
10591 if (insn
& (1 << 23))
10595 tmp
= tcg_temp_new_i32();
10596 tcg_gen_movi_i32(tmp
, offset
);
10598 tmp
= load_reg(s
, rn
);
10599 if (insn
& (1 << 23))
10600 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10602 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10605 store_reg(s
, rd
, tmp
);
10608 int shifter_out
= 0;
10609 /* modified 12-bit immediate. */
10610 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10611 imm
= (insn
& 0xff);
10614 /* Nothing to do. */
10616 case 1: /* 00XY00XY */
10619 case 2: /* XY00XY00 */
10623 case 3: /* XYXYXYXY */
10627 default: /* Rotated constant. */
10628 shift
= (shift
<< 1) | (imm
>> 7);
10630 imm
= imm
<< (32 - shift
);
10634 tmp2
= tcg_temp_new_i32();
10635 tcg_gen_movi_i32(tmp2
, imm
);
10636 rn
= (insn
>> 16) & 0xf;
10638 tmp
= tcg_temp_new_i32();
10639 tcg_gen_movi_i32(tmp
, 0);
10641 tmp
= load_reg(s
, rn
);
10643 op
= (insn
>> 21) & 0xf;
10644 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10645 shifter_out
, tmp
, tmp2
))
10647 tcg_temp_free_i32(tmp2
);
10648 rd
= (insn
>> 8) & 0xf;
10650 store_reg(s
, rd
, tmp
);
10652 tcg_temp_free_i32(tmp
);
10657 case 12: /* Load/store single data item. */
10662 if ((insn
& 0x01100000) == 0x01000000) {
10663 if (disas_neon_ls_insn(s
, insn
)) {
10668 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10670 if (!(insn
& (1 << 20))) {
10674 /* Byte or halfword load space with dest == r15 : memory hints.
10675 * Catch them early so we don't emit pointless addressing code.
10676 * This space is a mix of:
10677 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10678 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10680 * unallocated hints, which must be treated as NOPs
10681 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10682 * which is easiest for the decoding logic
10683 * Some space which must UNDEF
10685 int op1
= (insn
>> 23) & 3;
10686 int op2
= (insn
>> 6) & 0x3f;
10691 /* UNPREDICTABLE, unallocated hint or
10692 * PLD/PLDW/PLI (literal)
10697 return 0; /* PLD/PLDW/PLI or unallocated hint */
10699 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10700 return 0; /* PLD/PLDW/PLI or unallocated hint */
10702 /* UNDEF space, or an UNPREDICTABLE */
10706 memidx
= get_mem_index(s
);
10708 addr
= tcg_temp_new_i32();
10710 /* s->pc has already been incremented by 4. */
10711 imm
= s
->pc
& 0xfffffffc;
10712 if (insn
& (1 << 23))
10713 imm
+= insn
& 0xfff;
10715 imm
-= insn
& 0xfff;
10716 tcg_gen_movi_i32(addr
, imm
);
10718 addr
= load_reg(s
, rn
);
10719 if (insn
& (1 << 23)) {
10720 /* Positive offset. */
10721 imm
= insn
& 0xfff;
10722 tcg_gen_addi_i32(addr
, addr
, imm
);
10725 switch ((insn
>> 8) & 0xf) {
10726 case 0x0: /* Shifted Register. */
10727 shift
= (insn
>> 4) & 0xf;
10729 tcg_temp_free_i32(addr
);
10732 tmp
= load_reg(s
, rm
);
10734 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10735 tcg_gen_add_i32(addr
, addr
, tmp
);
10736 tcg_temp_free_i32(tmp
);
10738 case 0xc: /* Negative offset. */
10739 tcg_gen_addi_i32(addr
, addr
, -imm
);
10741 case 0xe: /* User privilege. */
10742 tcg_gen_addi_i32(addr
, addr
, imm
);
10743 memidx
= get_a32_user_mem_index(s
);
10745 case 0x9: /* Post-decrement. */
10747 /* Fall through. */
10748 case 0xb: /* Post-increment. */
10752 case 0xd: /* Pre-decrement. */
10754 /* Fall through. */
10755 case 0xf: /* Pre-increment. */
10756 tcg_gen_addi_i32(addr
, addr
, imm
);
10760 tcg_temp_free_i32(addr
);
10765 if (insn
& (1 << 20)) {
10767 tmp
= tcg_temp_new_i32();
10770 gen_aa32_ld8u(s
, tmp
, addr
, memidx
);
10773 gen_aa32_ld8s(s
, tmp
, addr
, memidx
);
10776 gen_aa32_ld16u(s
, tmp
, addr
, memidx
);
10779 gen_aa32_ld16s(s
, tmp
, addr
, memidx
);
10782 gen_aa32_ld32u(s
, tmp
, addr
, memidx
);
10785 tcg_temp_free_i32(tmp
);
10786 tcg_temp_free_i32(addr
);
10792 store_reg(s
, rs
, tmp
);
10796 tmp
= load_reg(s
, rs
);
10799 gen_aa32_st8(s
, tmp
, addr
, memidx
);
10802 gen_aa32_st16(s
, tmp
, addr
, memidx
);
10805 gen_aa32_st32(s
, tmp
, addr
, memidx
);
10808 tcg_temp_free_i32(tmp
);
10809 tcg_temp_free_i32(addr
);
10812 tcg_temp_free_i32(tmp
);
10815 tcg_gen_addi_i32(addr
, addr
, imm
);
10817 store_reg(s
, rn
, addr
);
10819 tcg_temp_free_i32(addr
);
10831 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10833 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10840 if (s
->condexec_mask
) {
10841 cond
= s
->condexec_cond
;
10842 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10843 s
->condlabel
= gen_new_label();
10844 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10849 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
10852 switch (insn
>> 12) {
10856 op
= (insn
>> 11) & 3;
10859 rn
= (insn
>> 3) & 7;
10860 tmp
= load_reg(s
, rn
);
10861 if (insn
& (1 << 10)) {
10863 tmp2
= tcg_temp_new_i32();
10864 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10867 rm
= (insn
>> 6) & 7;
10868 tmp2
= load_reg(s
, rm
);
10870 if (insn
& (1 << 9)) {
10871 if (s
->condexec_mask
)
10872 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10874 gen_sub_CC(tmp
, tmp
, tmp2
);
10876 if (s
->condexec_mask
)
10877 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10879 gen_add_CC(tmp
, tmp
, tmp2
);
10881 tcg_temp_free_i32(tmp2
);
10882 store_reg(s
, rd
, tmp
);
10884 /* shift immediate */
10885 rm
= (insn
>> 3) & 7;
10886 shift
= (insn
>> 6) & 0x1f;
10887 tmp
= load_reg(s
, rm
);
10888 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10889 if (!s
->condexec_mask
)
10891 store_reg(s
, rd
, tmp
);
10895 /* arithmetic large immediate */
10896 op
= (insn
>> 11) & 3;
10897 rd
= (insn
>> 8) & 0x7;
10898 if (op
== 0) { /* mov */
10899 tmp
= tcg_temp_new_i32();
10900 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10901 if (!s
->condexec_mask
)
10903 store_reg(s
, rd
, tmp
);
10905 tmp
= load_reg(s
, rd
);
10906 tmp2
= tcg_temp_new_i32();
10907 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10910 gen_sub_CC(tmp
, tmp
, tmp2
);
10911 tcg_temp_free_i32(tmp
);
10912 tcg_temp_free_i32(tmp2
);
10915 if (s
->condexec_mask
)
10916 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10918 gen_add_CC(tmp
, tmp
, tmp2
);
10919 tcg_temp_free_i32(tmp2
);
10920 store_reg(s
, rd
, tmp
);
10923 if (s
->condexec_mask
)
10924 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10926 gen_sub_CC(tmp
, tmp
, tmp2
);
10927 tcg_temp_free_i32(tmp2
);
10928 store_reg(s
, rd
, tmp
);
10934 if (insn
& (1 << 11)) {
10935 rd
= (insn
>> 8) & 7;
10936 /* load pc-relative. Bit 1 of PC is ignored. */
10937 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10938 val
&= ~(uint32_t)2;
10939 addr
= tcg_temp_new_i32();
10940 tcg_gen_movi_i32(addr
, val
);
10941 tmp
= tcg_temp_new_i32();
10942 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10943 tcg_temp_free_i32(addr
);
10944 store_reg(s
, rd
, tmp
);
10947 if (insn
& (1 << 10)) {
10948 /* data processing extended or blx */
10949 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10950 rm
= (insn
>> 3) & 0xf;
10951 op
= (insn
>> 8) & 3;
10954 tmp
= load_reg(s
, rd
);
10955 tmp2
= load_reg(s
, rm
);
10956 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10957 tcg_temp_free_i32(tmp2
);
10958 store_reg(s
, rd
, tmp
);
10961 tmp
= load_reg(s
, rd
);
10962 tmp2
= load_reg(s
, rm
);
10963 gen_sub_CC(tmp
, tmp
, tmp2
);
10964 tcg_temp_free_i32(tmp2
);
10965 tcg_temp_free_i32(tmp
);
10967 case 2: /* mov/cpy */
10968 tmp
= load_reg(s
, rm
);
10969 store_reg(s
, rd
, tmp
);
10971 case 3:/* branch [and link] exchange thumb register */
10972 tmp
= load_reg(s
, rm
);
10973 if (insn
& (1 << 7)) {
10975 val
= (uint32_t)s
->pc
| 1;
10976 tmp2
= tcg_temp_new_i32();
10977 tcg_gen_movi_i32(tmp2
, val
);
10978 store_reg(s
, 14, tmp2
);
10980 /* already thumb, no need to check */
10987 /* data processing register */
10989 rm
= (insn
>> 3) & 7;
10990 op
= (insn
>> 6) & 0xf;
10991 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10992 /* the shift/rotate ops want the operands backwards */
11001 if (op
== 9) { /* neg */
11002 tmp
= tcg_temp_new_i32();
11003 tcg_gen_movi_i32(tmp
, 0);
11004 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11005 tmp
= load_reg(s
, rd
);
11007 TCGV_UNUSED_I32(tmp
);
11010 tmp2
= load_reg(s
, rm
);
11012 case 0x0: /* and */
11013 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11014 if (!s
->condexec_mask
)
11017 case 0x1: /* eor */
11018 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11019 if (!s
->condexec_mask
)
11022 case 0x2: /* lsl */
11023 if (s
->condexec_mask
) {
11024 gen_shl(tmp2
, tmp2
, tmp
);
11026 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11027 gen_logic_CC(tmp2
);
11030 case 0x3: /* lsr */
11031 if (s
->condexec_mask
) {
11032 gen_shr(tmp2
, tmp2
, tmp
);
11034 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11035 gen_logic_CC(tmp2
);
11038 case 0x4: /* asr */
11039 if (s
->condexec_mask
) {
11040 gen_sar(tmp2
, tmp2
, tmp
);
11042 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11043 gen_logic_CC(tmp2
);
11046 case 0x5: /* adc */
11047 if (s
->condexec_mask
) {
11048 gen_adc(tmp
, tmp2
);
11050 gen_adc_CC(tmp
, tmp
, tmp2
);
11053 case 0x6: /* sbc */
11054 if (s
->condexec_mask
) {
11055 gen_sub_carry(tmp
, tmp
, tmp2
);
11057 gen_sbc_CC(tmp
, tmp
, tmp2
);
11060 case 0x7: /* ror */
11061 if (s
->condexec_mask
) {
11062 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11063 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11065 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11066 gen_logic_CC(tmp2
);
11069 case 0x8: /* tst */
11070 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11074 case 0x9: /* neg */
11075 if (s
->condexec_mask
)
11076 tcg_gen_neg_i32(tmp
, tmp2
);
11078 gen_sub_CC(tmp
, tmp
, tmp2
);
11080 case 0xa: /* cmp */
11081 gen_sub_CC(tmp
, tmp
, tmp2
);
11084 case 0xb: /* cmn */
11085 gen_add_CC(tmp
, tmp
, tmp2
);
11088 case 0xc: /* orr */
11089 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11090 if (!s
->condexec_mask
)
11093 case 0xd: /* mul */
11094 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11095 if (!s
->condexec_mask
)
11098 case 0xe: /* bic */
11099 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11100 if (!s
->condexec_mask
)
11103 case 0xf: /* mvn */
11104 tcg_gen_not_i32(tmp2
, tmp2
);
11105 if (!s
->condexec_mask
)
11106 gen_logic_CC(tmp2
);
11113 store_reg(s
, rm
, tmp2
);
11115 tcg_temp_free_i32(tmp
);
11117 store_reg(s
, rd
, tmp
);
11118 tcg_temp_free_i32(tmp2
);
11121 tcg_temp_free_i32(tmp
);
11122 tcg_temp_free_i32(tmp2
);
11127 /* load/store register offset. */
11129 rn
= (insn
>> 3) & 7;
11130 rm
= (insn
>> 6) & 7;
11131 op
= (insn
>> 9) & 7;
11132 addr
= load_reg(s
, rn
);
11133 tmp
= load_reg(s
, rm
);
11134 tcg_gen_add_i32(addr
, addr
, tmp
);
11135 tcg_temp_free_i32(tmp
);
11137 if (op
< 3) { /* store */
11138 tmp
= load_reg(s
, rd
);
11140 tmp
= tcg_temp_new_i32();
11145 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11148 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11151 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11153 case 3: /* ldrsb */
11154 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
11157 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11160 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11163 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11165 case 7: /* ldrsh */
11166 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
11169 if (op
>= 3) { /* load */
11170 store_reg(s
, rd
, tmp
);
11172 tcg_temp_free_i32(tmp
);
11174 tcg_temp_free_i32(addr
);
11178 /* load/store word immediate offset */
11180 rn
= (insn
>> 3) & 7;
11181 addr
= load_reg(s
, rn
);
11182 val
= (insn
>> 4) & 0x7c;
11183 tcg_gen_addi_i32(addr
, addr
, val
);
11185 if (insn
& (1 << 11)) {
11187 tmp
= tcg_temp_new_i32();
11188 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11189 store_reg(s
, rd
, tmp
);
11192 tmp
= load_reg(s
, rd
);
11193 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11194 tcg_temp_free_i32(tmp
);
11196 tcg_temp_free_i32(addr
);
11200 /* load/store byte immediate offset */
11202 rn
= (insn
>> 3) & 7;
11203 addr
= load_reg(s
, rn
);
11204 val
= (insn
>> 6) & 0x1f;
11205 tcg_gen_addi_i32(addr
, addr
, val
);
11207 if (insn
& (1 << 11)) {
11209 tmp
= tcg_temp_new_i32();
11210 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11211 store_reg(s
, rd
, tmp
);
11214 tmp
= load_reg(s
, rd
);
11215 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11216 tcg_temp_free_i32(tmp
);
11218 tcg_temp_free_i32(addr
);
11222 /* load/store halfword immediate offset */
11224 rn
= (insn
>> 3) & 7;
11225 addr
= load_reg(s
, rn
);
11226 val
= (insn
>> 5) & 0x3e;
11227 tcg_gen_addi_i32(addr
, addr
, val
);
11229 if (insn
& (1 << 11)) {
11231 tmp
= tcg_temp_new_i32();
11232 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11233 store_reg(s
, rd
, tmp
);
11236 tmp
= load_reg(s
, rd
);
11237 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11238 tcg_temp_free_i32(tmp
);
11240 tcg_temp_free_i32(addr
);
11244 /* load/store from stack */
11245 rd
= (insn
>> 8) & 7;
11246 addr
= load_reg(s
, 13);
11247 val
= (insn
& 0xff) * 4;
11248 tcg_gen_addi_i32(addr
, addr
, val
);
11250 if (insn
& (1 << 11)) {
11252 tmp
= tcg_temp_new_i32();
11253 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11254 store_reg(s
, rd
, tmp
);
11257 tmp
= load_reg(s
, rd
);
11258 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11259 tcg_temp_free_i32(tmp
);
11261 tcg_temp_free_i32(addr
);
11265 /* add to high reg */
11266 rd
= (insn
>> 8) & 7;
11267 if (insn
& (1 << 11)) {
11269 tmp
= load_reg(s
, 13);
11271 /* PC. bit 1 is ignored. */
11272 tmp
= tcg_temp_new_i32();
11273 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11275 val
= (insn
& 0xff) * 4;
11276 tcg_gen_addi_i32(tmp
, tmp
, val
);
11277 store_reg(s
, rd
, tmp
);
11282 op
= (insn
>> 8) & 0xf;
11285 /* adjust stack pointer */
11286 tmp
= load_reg(s
, 13);
11287 val
= (insn
& 0x7f) * 4;
11288 if (insn
& (1 << 7))
11289 val
= -(int32_t)val
;
11290 tcg_gen_addi_i32(tmp
, tmp
, val
);
11291 store_reg(s
, 13, tmp
);
11294 case 2: /* sign/zero extend. */
11297 rm
= (insn
>> 3) & 7;
11298 tmp
= load_reg(s
, rm
);
11299 switch ((insn
>> 6) & 3) {
11300 case 0: gen_sxth(tmp
); break;
11301 case 1: gen_sxtb(tmp
); break;
11302 case 2: gen_uxth(tmp
); break;
11303 case 3: gen_uxtb(tmp
); break;
11305 store_reg(s
, rd
, tmp
);
11307 case 4: case 5: case 0xc: case 0xd:
11309 addr
= load_reg(s
, 13);
11310 if (insn
& (1 << 8))
11314 for (i
= 0; i
< 8; i
++) {
11315 if (insn
& (1 << i
))
11318 if ((insn
& (1 << 11)) == 0) {
11319 tcg_gen_addi_i32(addr
, addr
, -offset
);
11321 for (i
= 0; i
< 8; i
++) {
11322 if (insn
& (1 << i
)) {
11323 if (insn
& (1 << 11)) {
11325 tmp
= tcg_temp_new_i32();
11326 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11327 store_reg(s
, i
, tmp
);
11330 tmp
= load_reg(s
, i
);
11331 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11332 tcg_temp_free_i32(tmp
);
11334 /* advance to the next address. */
11335 tcg_gen_addi_i32(addr
, addr
, 4);
11338 TCGV_UNUSED_I32(tmp
);
11339 if (insn
& (1 << 8)) {
11340 if (insn
& (1 << 11)) {
11342 tmp
= tcg_temp_new_i32();
11343 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11344 /* don't set the pc until the rest of the instruction
11348 tmp
= load_reg(s
, 14);
11349 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11350 tcg_temp_free_i32(tmp
);
11352 tcg_gen_addi_i32(addr
, addr
, 4);
11354 if ((insn
& (1 << 11)) == 0) {
11355 tcg_gen_addi_i32(addr
, addr
, -offset
);
11357 /* write back the new stack pointer */
11358 store_reg(s
, 13, addr
);
11359 /* set the new PC value */
11360 if ((insn
& 0x0900) == 0x0900) {
11361 store_reg_from_load(s
, 15, tmp
);
11365 case 1: case 3: case 9: case 11: /* czb */
11367 tmp
= load_reg(s
, rm
);
11368 s
->condlabel
= gen_new_label();
11370 if (insn
& (1 << 11))
11371 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11373 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11374 tcg_temp_free_i32(tmp
);
11375 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11376 val
= (uint32_t)s
->pc
+ 2;
11381 case 15: /* IT, nop-hint. */
11382 if ((insn
& 0xf) == 0) {
11383 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11387 s
->condexec_cond
= (insn
>> 4) & 0xe;
11388 s
->condexec_mask
= insn
& 0x1f;
11389 /* No actual code generated for this insn, just setup state. */
11392 case 0xe: /* bkpt */
11394 int imm8
= extract32(insn
, 0, 8);
11396 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11397 default_exception_el(s
));
11401 case 0xa: /* rev */
11403 rn
= (insn
>> 3) & 0x7;
11405 tmp
= load_reg(s
, rn
);
11406 switch ((insn
>> 6) & 3) {
11407 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11408 case 1: gen_rev16(tmp
); break;
11409 case 3: gen_revsh(tmp
); break;
11410 default: goto illegal_op
;
11412 store_reg(s
, rd
, tmp
);
11416 switch ((insn
>> 5) & 7) {
11420 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11421 gen_helper_setend(cpu_env
);
11422 s
->is_jmp
= DISAS_UPDATE
;
11431 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11432 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11435 addr
= tcg_const_i32(19);
11436 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11437 tcg_temp_free_i32(addr
);
11441 addr
= tcg_const_i32(16);
11442 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11443 tcg_temp_free_i32(addr
);
11445 tcg_temp_free_i32(tmp
);
11448 if (insn
& (1 << 4)) {
11449 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11453 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11468 /* load/store multiple */
11469 TCGv_i32 loaded_var
;
11470 TCGV_UNUSED_I32(loaded_var
);
11471 rn
= (insn
>> 8) & 0x7;
11472 addr
= load_reg(s
, rn
);
11473 for (i
= 0; i
< 8; i
++) {
11474 if (insn
& (1 << i
)) {
11475 if (insn
& (1 << 11)) {
11477 tmp
= tcg_temp_new_i32();
11478 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11482 store_reg(s
, i
, tmp
);
11486 tmp
= load_reg(s
, i
);
11487 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11488 tcg_temp_free_i32(tmp
);
11490 /* advance to the next address */
11491 tcg_gen_addi_i32(addr
, addr
, 4);
11494 if ((insn
& (1 << rn
)) == 0) {
11495 /* base reg not in list: base register writeback */
11496 store_reg(s
, rn
, addr
);
11498 /* base reg in list: if load, complete it now */
11499 if (insn
& (1 << 11)) {
11500 store_reg(s
, rn
, loaded_var
);
11502 tcg_temp_free_i32(addr
);
11507 /* conditional branch or swi */
11508 cond
= (insn
>> 8) & 0xf;
11514 gen_set_pc_im(s
, s
->pc
);
11515 s
->svc_imm
= extract32(insn
, 0, 8);
11516 s
->is_jmp
= DISAS_SWI
;
11519 /* generate a conditional jump to next instruction */
11520 s
->condlabel
= gen_new_label();
11521 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11524 /* jump to the offset */
11525 val
= (uint32_t)s
->pc
+ 2;
11526 offset
= ((int32_t)insn
<< 24) >> 24;
11527 val
+= offset
<< 1;
11532 if (insn
& (1 << 11)) {
11533 if (disas_thumb2_insn(env
, s
, insn
))
11537 /* unconditional branch */
11538 val
= (uint32_t)s
->pc
;
11539 offset
= ((int32_t)insn
<< 21) >> 21;
11540 val
+= (offset
<< 1) + 2;
11545 if (disas_thumb2_insn(env
, s
, insn
))
11551 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11552 default_exception_el(s
));
11556 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11557 default_exception_el(s
));
11560 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11562 /* Return true if the insn at dc->pc might cross a page boundary.
11563 * (False positives are OK, false negatives are not.)
11567 if ((s
->pc
& 3) == 0) {
11568 /* At a 4-aligned address we can't be crossing a page */
11572 /* This must be a Thumb insn */
11573 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11575 if ((insn
>> 11) >= 0x1d) {
11576 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11577 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11578 * end up actually treating this as two 16-bit insns (see the
11579 * code at the start of disas_thumb2_insn()) but we don't bother
11580 * to check for that as it is unlikely, and false positives here
11585 /* Definitely a 16-bit insn, can't be crossing a page. */
11589 /* generate intermediate code for basic block 'tb'. */
11590 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11592 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11593 CPUState
*cs
= CPU(cpu
);
11594 DisasContext dc1
, *dc
= &dc1
;
11595 target_ulong pc_start
;
11596 target_ulong next_page_start
;
11601 /* generate intermediate code */
11603 /* The A64 decoder has its own top level loop, because it doesn't need
11604 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11606 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11607 gen_intermediate_code_a64(cpu
, tb
);
11615 dc
->is_jmp
= DISAS_NEXT
;
11617 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11621 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11622 * there is no secure EL1, so we route exceptions to EL3.
11624 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11625 !arm_el_is_aa64(env
, 3);
11626 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11627 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(tb
->flags
);
11628 dc
->be_data
= ARM_TBFLAG_BE_DATA(tb
->flags
) ? MO_BE
: MO_LE
;
11629 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11630 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11631 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11632 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11633 #if !defined(CONFIG_USER_ONLY)
11634 dc
->user
= (dc
->current_el
== 0);
11636 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11637 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11638 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11639 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11640 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11641 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11642 dc
->cp_regs
= cpu
->cp_regs
;
11643 dc
->features
= env
->features
;
11645 /* Single step state. The code-generation logic here is:
11647 * generate code with no special handling for single-stepping (except
11648 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11649 * this happens anyway because those changes are all system register or
11651 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11652 * emit code for one insn
11653 * emit code to clear PSTATE.SS
11654 * emit code to generate software step exception for completed step
11655 * end TB (as usual for having generated an exception)
11656 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11657 * emit code to generate a software step exception
11660 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11661 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11662 dc
->is_ldex
= false;
11663 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11665 cpu_F0s
= tcg_temp_new_i32();
11666 cpu_F1s
= tcg_temp_new_i32();
11667 cpu_F0d
= tcg_temp_new_i64();
11668 cpu_F1d
= tcg_temp_new_i64();
11671 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11672 cpu_M0
= tcg_temp_new_i64();
11673 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11675 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11676 if (max_insns
== 0) {
11677 max_insns
= CF_COUNT_MASK
;
11679 if (max_insns
> TCG_MAX_INSNS
) {
11680 max_insns
= TCG_MAX_INSNS
;
11685 tcg_clear_temp_count();
11687 /* A note on handling of the condexec (IT) bits:
11689 * We want to avoid the overhead of having to write the updated condexec
11690 * bits back to the CPUARMState for every instruction in an IT block. So:
11691 * (1) if the condexec bits are not already zero then we write
11692 * zero back into the CPUARMState now. This avoids complications trying
11693 * to do it at the end of the block. (For example if we don't do this
11694 * it's hard to identify whether we can safely skip writing condexec
11695 * at the end of the TB, which we definitely want to do for the case
11696 * where a TB doesn't do anything with the IT state at all.)
11697 * (2) if we are going to leave the TB then we call gen_set_condexec()
11698 * which will write the correct value into CPUARMState if zero is wrong.
11699 * This is done both for leaving the TB at the end, and for leaving
11700 * it because of an exception we know will happen, which is done in
11701 * gen_exception_insn(). The latter is necessary because we need to
11702 * leave the TB with the PC/IT state just prior to execution of the
11703 * instruction which caused the exception.
11704 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11705 * then the CPUARMState will be wrong and we need to reset it.
11706 * This is handled in the same way as restoration of the
11707 * PC in these situations; we save the value of the condexec bits
11708 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11709 * then uses this to restore them after an exception.
11711 * Note that there are no instructions which can read the condexec
11712 * bits, and none which can write non-static values to them, so
11713 * we don't need to care about whether CPUARMState is correct in the
11717 /* Reset the conditional execution bits immediately. This avoids
11718 complications trying to do it at the end of the block. */
11719 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11721 TCGv_i32 tmp
= tcg_temp_new_i32();
11722 tcg_gen_movi_i32(tmp
, 0);
11723 store_cpu_field(tmp
, condexec_bits
);
11726 tcg_gen_insn_start(dc
->pc
,
11727 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1));
11730 #ifdef CONFIG_USER_ONLY
11731 /* Intercept jump to the magic kernel page. */
11732 if (dc
->pc
>= 0xffff0000) {
11733 /* We always get here via a jump, so know we are not in a
11734 conditional execution block. */
11735 gen_exception_internal(EXCP_KERNEL_TRAP
);
11736 dc
->is_jmp
= DISAS_EXC
;
11740 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11741 /* We always get here via a jump, so know we are not in a
11742 conditional execution block. */
11743 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11744 dc
->is_jmp
= DISAS_EXC
;
11749 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11751 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11752 if (bp
->pc
== dc
->pc
) {
11753 if (bp
->flags
& BP_CPU
) {
11754 gen_set_condexec(dc
);
11755 gen_set_pc_im(dc
, dc
->pc
);
11756 gen_helper_check_breakpoints(cpu_env
);
11757 /* End the TB early; it's likely not going to be executed */
11758 dc
->is_jmp
= DISAS_UPDATE
;
11760 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11761 /* The address covered by the breakpoint must be
11762 included in [tb->pc, tb->pc + tb->size) in order
11763 to for it to be properly cleared -- thus we
11764 increment the PC here so that the logic setting
11765 tb->size below does the right thing. */
11766 /* TODO: Advance PC by correct instruction length to
11767 * avoid disassembler error messages */
11769 goto done_generating
;
11776 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11780 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11781 /* Singlestep state is Active-pending.
11782 * If we're in this state at the start of a TB then either
11783 * a) we just took an exception to an EL which is being debugged
11784 * and this is the first insn in the exception handler
11785 * b) debug exceptions were masked and we just unmasked them
11786 * without changing EL (eg by clearing PSTATE.D)
11787 * In either case we're going to take a swstep exception in the
11788 * "did not step an insn" case, and so the syndrome ISV and EX
11789 * bits should be zero.
11791 assert(num_insns
== 1);
11792 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11793 default_exception_el(dc
));
11794 goto done_generating
;
11798 disas_thumb_insn(env
, dc
);
11799 if (dc
->condexec_mask
) {
11800 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11801 | ((dc
->condexec_mask
>> 4) & 1);
11802 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11803 if (dc
->condexec_mask
== 0) {
11804 dc
->condexec_cond
= 0;
11808 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
11810 disas_arm_insn(dc
, insn
);
11813 if (dc
->condjmp
&& !dc
->is_jmp
) {
11814 gen_set_label(dc
->condlabel
);
11818 if (tcg_check_temp_count()) {
11819 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11823 /* Translation stops when a conditional branch is encountered.
11824 * Otherwise the subsequent code could get translated several times.
11825 * Also stop translation when a page boundary is reached. This
11826 * ensures prefetch aborts occur at the right place. */
11828 /* We want to stop the TB if the next insn starts in a new page,
11829 * or if it spans between this page and the next. This means that
11830 * if we're looking at the last halfword in the page we need to
11831 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11832 * or a 32-bit Thumb insn (which won't).
11833 * This is to avoid generating a silly TB with a single 16-bit insn
11834 * in it at the end of this page (which would execute correctly
11835 * but isn't very efficient).
11837 end_of_page
= (dc
->pc
>= next_page_start
) ||
11838 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
11840 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11841 !cs
->singlestep_enabled
&&
11845 num_insns
< max_insns
);
11847 if (tb
->cflags
& CF_LAST_IO
) {
11849 /* FIXME: This can theoretically happen with self-modifying
11851 cpu_abort(cs
, "IO on conditional branch instruction");
11856 /* At this stage dc->condjmp will only be set when the skipped
11857 instruction was a conditional branch or trap, and the PC has
11858 already been written. */
11859 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11860 /* Unconditional and "condition passed" instruction codepath. */
11861 gen_set_condexec(dc
);
11862 switch (dc
->is_jmp
) {
11864 gen_ss_advance(dc
);
11865 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11866 default_exception_el(dc
));
11869 gen_ss_advance(dc
);
11870 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11873 gen_ss_advance(dc
);
11874 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11878 gen_set_pc_im(dc
, dc
->pc
);
11881 if (dc
->ss_active
) {
11882 gen_step_complete_exception(dc
);
11884 /* FIXME: Single stepping a WFI insn will not halt
11886 gen_exception_internal(EXCP_DEBUG
);
11890 /* "Condition failed" instruction codepath. */
11891 gen_set_label(dc
->condlabel
);
11892 gen_set_condexec(dc
);
11893 gen_set_pc_im(dc
, dc
->pc
);
11894 if (dc
->ss_active
) {
11895 gen_step_complete_exception(dc
);
11897 gen_exception_internal(EXCP_DEBUG
);
11901 /* While branches must always occur at the end of an IT block,
11902 there are a few other things that can cause us to terminate
11903 the TB in the middle of an IT block:
11904 - Exception generating instructions (bkpt, swi, undefined).
11906 - Hardware watchpoints.
11907 Hardware breakpoints have already been handled and skip this code.
11909 gen_set_condexec(dc
);
11910 switch(dc
->is_jmp
) {
11912 gen_goto_tb(dc
, 1, dc
->pc
);
11915 gen_set_pc_im(dc
, dc
->pc
);
11919 /* indicate that the hash table must be used to find the next TB */
11920 tcg_gen_exit_tb(0);
11922 case DISAS_TB_JUMP
:
11923 /* nothing more to generate */
11926 gen_helper_wfi(cpu_env
);
11927 /* The helper doesn't necessarily throw an exception, but we
11928 * must go back to the main loop to check for interrupts anyway.
11930 tcg_gen_exit_tb(0);
11933 gen_helper_wfe(cpu_env
);
11936 gen_helper_yield(cpu_env
);
11939 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11940 default_exception_el(dc
));
11943 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11946 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11950 gen_set_label(dc
->condlabel
);
11951 gen_set_condexec(dc
);
11952 gen_goto_tb(dc
, 1, dc
->pc
);
11958 gen_tb_end(tb
, num_insns
);
11961 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
) &&
11962 qemu_log_in_addr_range(pc_start
)) {
11963 qemu_log("----------------\n");
11964 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11965 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
11966 dc
->thumb
| (dc
->sctlr_b
<< 1));
11970 tb
->size
= dc
->pc
- pc_start
;
11971 tb
->icount
= num_insns
;
11974 static const char *cpu_mode_names
[16] = {
11975 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11976 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11979 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11982 ARMCPU
*cpu
= ARM_CPU(cs
);
11983 CPUARMState
*env
= &cpu
->env
;
11986 const char *ns_status
;
11989 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11993 for(i
=0;i
<16;i
++) {
11994 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11996 cpu_fprintf(f
, "\n");
11998 cpu_fprintf(f
, " ");
12000 psr
= cpsr_read(env
);
12002 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12003 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12004 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12009 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12011 psr
& (1 << 31) ? 'N' : '-',
12012 psr
& (1 << 30) ? 'Z' : '-',
12013 psr
& (1 << 29) ? 'C' : '-',
12014 psr
& (1 << 28) ? 'V' : '-',
12015 psr
& CPSR_T
? 'T' : 'A',
12017 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12019 if (flags
& CPU_DUMP_FPU
) {
12020 int numvfpregs
= 0;
12021 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12024 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12027 for (i
= 0; i
< numvfpregs
; i
++) {
12028 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12029 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12030 i
* 2, (uint32_t)v
,
12031 i
* 2 + 1, (uint32_t)(v
>> 32),
12034 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12038 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12039 target_ulong
*data
)
12043 env
->condexec_bits
= 0;
12045 env
->regs
[15] = data
[0];
12046 env
->condexec_bits
= data
[1];