4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
29 #include "qemu/bitops.h"
31 #include "exec/semihost.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
36 #include "trace-tcg.h"
40 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
41 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
42 /* currently all emulated v5 cores are also v5TE, so don't bother */
43 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
44 #define ENABLE_ARCH_5J 0
45 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
46 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
47 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
48 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
49 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
51 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
53 #include "translate.h"
55 #if defined(CONFIG_USER_ONLY)
58 #define IS_USER(s) (s->user)
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
64 static TCGv_i32 cpu_R
[16];
65 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
66 TCGv_i64 cpu_exclusive_addr
;
67 TCGv_i64 cpu_exclusive_val
;
69 /* FIXME: These should be removed. */
70 static TCGv_i32 cpu_F0s
, cpu_F1s
;
71 static TCGv_i64 cpu_F0d
, cpu_F1d
;
73 #include "exec/gen-icount.h"
75 static const char *regnames
[] =
76 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
79 /* initialize TCG globals. */
80 void arm_translate_init(void)
84 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
85 tcg_ctx
.tcg_env
= cpu_env
;
87 for (i
= 0; i
< 16; i
++) {
88 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
89 offsetof(CPUARMState
, regs
[i
]),
92 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
93 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
94 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
95 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
97 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
98 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
99 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
100 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
102 a64_translate_init();
105 static inline ARMMMUIdx
get_a32_user_mem_index(DisasContext
*s
)
107 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
109 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
110 * otherwise, access as if at PL0.
112 switch (s
->mmu_idx
) {
113 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
114 case ARMMMUIdx_S12NSE0
:
115 case ARMMMUIdx_S12NSE1
:
116 return ARMMMUIdx_S12NSE0
;
118 case ARMMMUIdx_S1SE0
:
119 case ARMMMUIdx_S1SE1
:
120 return ARMMMUIdx_S1SE0
;
123 g_assert_not_reached();
127 static inline TCGv_i32
load_cpu_offset(int offset
)
129 TCGv_i32 tmp
= tcg_temp_new_i32();
130 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
134 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
136 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
138 tcg_gen_st_i32(var
, cpu_env
, offset
);
139 tcg_temp_free_i32(var
);
142 #define store_cpu_field(var, name) \
143 store_cpu_offset(var, offsetof(CPUARMState, name))
145 /* Set a variable to the value of a CPU register. */
146 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
150 /* normally, since we updated PC, we need only to add one insn */
152 addr
= (long)s
->pc
+ 2;
154 addr
= (long)s
->pc
+ 4;
155 tcg_gen_movi_i32(var
, addr
);
157 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
161 /* Create a new temporary and set it to the value of a CPU register. */
162 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
164 TCGv_i32 tmp
= tcg_temp_new_i32();
165 load_reg_var(s
, tmp
, reg
);
169 /* Set a CPU register. The source must be a temporary and will be
171 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
174 /* In Thumb mode, we must ignore bit 0.
175 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
176 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
177 * We choose to ignore [1:0] in ARM mode for all architecture versions.
179 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
180 s
->is_jmp
= DISAS_JUMP
;
182 tcg_gen_mov_i32(cpu_R
[reg
], var
);
183 tcg_temp_free_i32(var
);
186 /* Value extensions. */
187 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
188 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
189 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
190 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
192 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
193 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
196 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
198 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
199 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
200 tcg_temp_free_i32(tmp_mask
);
202 /* Set NZCV flags from the high 4 bits of var. */
203 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
205 static void gen_exception_internal(int excp
)
207 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
209 assert(excp_is_internal(excp
));
210 gen_helper_exception_internal(cpu_env
, tcg_excp
);
211 tcg_temp_free_i32(tcg_excp
);
214 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
216 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
217 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
218 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
220 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
223 tcg_temp_free_i32(tcg_el
);
224 tcg_temp_free_i32(tcg_syn
);
225 tcg_temp_free_i32(tcg_excp
);
228 static void gen_ss_advance(DisasContext
*s
)
230 /* If the singlestep state is Active-not-pending, advance to
235 gen_helper_clear_pstate_ss(cpu_env
);
239 static void gen_step_complete_exception(DisasContext
*s
)
241 /* We just completed step of an insn. Move from Active-not-pending
242 * to Active-pending, and then also take the swstep exception.
243 * This corresponds to making the (IMPDEF) choice to prioritize
244 * swstep exceptions over asynchronous exceptions taken to an exception
245 * level where debug is disabled. This choice has the advantage that
246 * we do not need to maintain internal state corresponding to the
247 * ISV/EX syndrome bits between completion of the step and generation
248 * of the exception, and our syndrome information is always correct.
251 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
252 default_exception_el(s
));
253 s
->is_jmp
= DISAS_EXC
;
256 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
258 TCGv_i32 tmp1
= tcg_temp_new_i32();
259 TCGv_i32 tmp2
= tcg_temp_new_i32();
260 tcg_gen_ext16s_i32(tmp1
, a
);
261 tcg_gen_ext16s_i32(tmp2
, b
);
262 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
263 tcg_temp_free_i32(tmp2
);
264 tcg_gen_sari_i32(a
, a
, 16);
265 tcg_gen_sari_i32(b
, b
, 16);
266 tcg_gen_mul_i32(b
, b
, a
);
267 tcg_gen_mov_i32(a
, tmp1
);
268 tcg_temp_free_i32(tmp1
);
271 /* Byteswap each halfword. */
272 static void gen_rev16(TCGv_i32 var
)
274 TCGv_i32 tmp
= tcg_temp_new_i32();
275 tcg_gen_shri_i32(tmp
, var
, 8);
276 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
277 tcg_gen_shli_i32(var
, var
, 8);
278 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
279 tcg_gen_or_i32(var
, var
, tmp
);
280 tcg_temp_free_i32(tmp
);
283 /* Byteswap low halfword and sign extend. */
284 static void gen_revsh(TCGv_i32 var
)
286 tcg_gen_ext16u_i32(var
, var
);
287 tcg_gen_bswap16_i32(var
, var
);
288 tcg_gen_ext16s_i32(var
, var
);
291 /* Return (b << 32) + a. Mark inputs as dead */
292 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
294 TCGv_i64 tmp64
= tcg_temp_new_i64();
296 tcg_gen_extu_i32_i64(tmp64
, b
);
297 tcg_temp_free_i32(b
);
298 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
299 tcg_gen_add_i64(a
, tmp64
, a
);
301 tcg_temp_free_i64(tmp64
);
305 /* Return (b << 32) - a. Mark inputs as dead. */
306 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
308 TCGv_i64 tmp64
= tcg_temp_new_i64();
310 tcg_gen_extu_i32_i64(tmp64
, b
);
311 tcg_temp_free_i32(b
);
312 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
313 tcg_gen_sub_i64(a
, tmp64
, a
);
315 tcg_temp_free_i64(tmp64
);
319 /* 32x32->64 multiply. Marks inputs as dead. */
320 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
322 TCGv_i32 lo
= tcg_temp_new_i32();
323 TCGv_i32 hi
= tcg_temp_new_i32();
326 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
327 tcg_temp_free_i32(a
);
328 tcg_temp_free_i32(b
);
330 ret
= tcg_temp_new_i64();
331 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
332 tcg_temp_free_i32(lo
);
333 tcg_temp_free_i32(hi
);
338 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
340 TCGv_i32 lo
= tcg_temp_new_i32();
341 TCGv_i32 hi
= tcg_temp_new_i32();
344 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
345 tcg_temp_free_i32(a
);
346 tcg_temp_free_i32(b
);
348 ret
= tcg_temp_new_i64();
349 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
350 tcg_temp_free_i32(lo
);
351 tcg_temp_free_i32(hi
);
356 /* Swap low and high halfwords. */
357 static void gen_swap_half(TCGv_i32 var
)
359 TCGv_i32 tmp
= tcg_temp_new_i32();
360 tcg_gen_shri_i32(tmp
, var
, 16);
361 tcg_gen_shli_i32(var
, var
, 16);
362 tcg_gen_or_i32(var
, var
, tmp
);
363 tcg_temp_free_i32(tmp
);
366 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
367 tmp = (t0 ^ t1) & 0x8000;
370 t0 = (t0 + t1) ^ tmp;
373 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
375 TCGv_i32 tmp
= tcg_temp_new_i32();
376 tcg_gen_xor_i32(tmp
, t0
, t1
);
377 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
378 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
379 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
380 tcg_gen_add_i32(t0
, t0
, t1
);
381 tcg_gen_xor_i32(t0
, t0
, tmp
);
382 tcg_temp_free_i32(tmp
);
383 tcg_temp_free_i32(t1
);
386 /* Set CF to the top bit of var. */
387 static void gen_set_CF_bit31(TCGv_i32 var
)
389 tcg_gen_shri_i32(cpu_CF
, var
, 31);
392 /* Set N and Z flags from var. */
393 static inline void gen_logic_CC(TCGv_i32 var
)
395 tcg_gen_mov_i32(cpu_NF
, var
);
396 tcg_gen_mov_i32(cpu_ZF
, var
);
400 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
402 tcg_gen_add_i32(t0
, t0
, t1
);
403 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
406 /* dest = T0 + T1 + CF. */
407 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
409 tcg_gen_add_i32(dest
, t0
, t1
);
410 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
413 /* dest = T0 - T1 + CF - 1. */
414 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
416 tcg_gen_sub_i32(dest
, t0
, t1
);
417 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
418 tcg_gen_subi_i32(dest
, dest
, 1);
421 /* dest = T0 + T1. Compute C, N, V and Z flags */
422 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
424 TCGv_i32 tmp
= tcg_temp_new_i32();
425 tcg_gen_movi_i32(tmp
, 0);
426 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
427 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
428 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
429 tcg_gen_xor_i32(tmp
, t0
, t1
);
430 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
431 tcg_temp_free_i32(tmp
);
432 tcg_gen_mov_i32(dest
, cpu_NF
);
435 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
436 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
438 TCGv_i32 tmp
= tcg_temp_new_i32();
439 if (TCG_TARGET_HAS_add2_i32
) {
440 tcg_gen_movi_i32(tmp
, 0);
441 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
442 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
444 TCGv_i64 q0
= tcg_temp_new_i64();
445 TCGv_i64 q1
= tcg_temp_new_i64();
446 tcg_gen_extu_i32_i64(q0
, t0
);
447 tcg_gen_extu_i32_i64(q1
, t1
);
448 tcg_gen_add_i64(q0
, q0
, q1
);
449 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
450 tcg_gen_add_i64(q0
, q0
, q1
);
451 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
452 tcg_temp_free_i64(q0
);
453 tcg_temp_free_i64(q1
);
455 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
456 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
457 tcg_gen_xor_i32(tmp
, t0
, t1
);
458 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
459 tcg_temp_free_i32(tmp
);
460 tcg_gen_mov_i32(dest
, cpu_NF
);
463 /* dest = T0 - T1. Compute C, N, V and Z flags */
464 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
467 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
468 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
469 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
470 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
471 tmp
= tcg_temp_new_i32();
472 tcg_gen_xor_i32(tmp
, t0
, t1
);
473 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
474 tcg_temp_free_i32(tmp
);
475 tcg_gen_mov_i32(dest
, cpu_NF
);
478 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
479 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
481 TCGv_i32 tmp
= tcg_temp_new_i32();
482 tcg_gen_not_i32(tmp
, t1
);
483 gen_adc_CC(dest
, t0
, tmp
);
484 tcg_temp_free_i32(tmp
);
487 #define GEN_SHIFT(name) \
488 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
490 TCGv_i32 tmp1, tmp2, tmp3; \
491 tmp1 = tcg_temp_new_i32(); \
492 tcg_gen_andi_i32(tmp1, t1, 0xff); \
493 tmp2 = tcg_const_i32(0); \
494 tmp3 = tcg_const_i32(0x1f); \
495 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
496 tcg_temp_free_i32(tmp3); \
497 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
498 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
499 tcg_temp_free_i32(tmp2); \
500 tcg_temp_free_i32(tmp1); \
506 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
509 tmp1
= tcg_temp_new_i32();
510 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
511 tmp2
= tcg_const_i32(0x1f);
512 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
513 tcg_temp_free_i32(tmp2
);
514 tcg_gen_sar_i32(dest
, t0
, tmp1
);
515 tcg_temp_free_i32(tmp1
);
518 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
520 TCGv_i32 c0
= tcg_const_i32(0);
521 TCGv_i32 tmp
= tcg_temp_new_i32();
522 tcg_gen_neg_i32(tmp
, src
);
523 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
524 tcg_temp_free_i32(c0
);
525 tcg_temp_free_i32(tmp
);
528 static void shifter_out_im(TCGv_i32 var
, int shift
)
531 tcg_gen_andi_i32(cpu_CF
, var
, 1);
533 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
535 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
540 /* Shift by immediate. Includes special handling for shift == 0. */
541 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
542 int shift
, int flags
)
548 shifter_out_im(var
, 32 - shift
);
549 tcg_gen_shli_i32(var
, var
, shift
);
555 tcg_gen_shri_i32(cpu_CF
, var
, 31);
557 tcg_gen_movi_i32(var
, 0);
560 shifter_out_im(var
, shift
- 1);
561 tcg_gen_shri_i32(var
, var
, shift
);
568 shifter_out_im(var
, shift
- 1);
571 tcg_gen_sari_i32(var
, var
, shift
);
573 case 3: /* ROR/RRX */
576 shifter_out_im(var
, shift
- 1);
577 tcg_gen_rotri_i32(var
, var
, shift
); break;
579 TCGv_i32 tmp
= tcg_temp_new_i32();
580 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
582 shifter_out_im(var
, 0);
583 tcg_gen_shri_i32(var
, var
, 1);
584 tcg_gen_or_i32(var
, var
, tmp
);
585 tcg_temp_free_i32(tmp
);
590 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
591 TCGv_i32 shift
, int flags
)
595 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
596 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
597 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
598 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
603 gen_shl(var
, var
, shift
);
606 gen_shr(var
, var
, shift
);
609 gen_sar(var
, var
, shift
);
611 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
612 tcg_gen_rotr_i32(var
, var
, shift
); break;
615 tcg_temp_free_i32(shift
);
618 #define PAS_OP(pfx) \
620 case 0: gen_pas_helper(glue(pfx,add16)); break; \
621 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
622 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
623 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
624 case 4: gen_pas_helper(glue(pfx,add8)); break; \
625 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
627 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
632 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
634 tmp
= tcg_temp_new_ptr();
635 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
637 tcg_temp_free_ptr(tmp
);
640 tmp
= tcg_temp_new_ptr();
641 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
643 tcg_temp_free_ptr(tmp
);
645 #undef gen_pas_helper
646 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
659 #undef gen_pas_helper
664 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
665 #define PAS_OP(pfx) \
667 case 0: gen_pas_helper(glue(pfx,add8)); break; \
668 case 1: gen_pas_helper(glue(pfx,add16)); break; \
669 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
670 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
671 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
672 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
674 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
679 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
681 tmp
= tcg_temp_new_ptr();
682 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
684 tcg_temp_free_ptr(tmp
);
687 tmp
= tcg_temp_new_ptr();
688 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
690 tcg_temp_free_ptr(tmp
);
692 #undef gen_pas_helper
693 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
706 #undef gen_pas_helper
712 * Generate a conditional based on ARM condition code cc.
713 * This is common between ARM and Aarch64 targets.
715 void arm_test_cc(DisasCompare
*cmp
, int cc
)
746 case 8: /* hi: C && !Z */
747 case 9: /* ls: !C || Z -> !(C && !Z) */
749 value
= tcg_temp_new_i32();
751 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
752 ZF is non-zero for !Z; so AND the two subexpressions. */
753 tcg_gen_neg_i32(value
, cpu_CF
);
754 tcg_gen_and_i32(value
, value
, cpu_ZF
);
757 case 10: /* ge: N == V -> N ^ V == 0 */
758 case 11: /* lt: N != V -> N ^ V != 0 */
759 /* Since we're only interested in the sign bit, == 0 is >= 0. */
761 value
= tcg_temp_new_i32();
763 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
766 case 12: /* gt: !Z && N == V */
767 case 13: /* le: Z || N != V */
769 value
= tcg_temp_new_i32();
771 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
772 * the sign bit then AND with ZF to yield the result. */
773 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
774 tcg_gen_sari_i32(value
, value
, 31);
775 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
778 case 14: /* always */
779 case 15: /* always */
780 /* Use the ALWAYS condition, which will fold early.
781 * It doesn't matter what we use for the value. */
782 cond
= TCG_COND_ALWAYS
;
787 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
792 cond
= tcg_invert_cond(cond
);
798 cmp
->value_global
= global
;
801 void arm_free_cc(DisasCompare
*cmp
)
803 if (!cmp
->value_global
) {
804 tcg_temp_free_i32(cmp
->value
);
808 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
810 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
813 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
816 arm_test_cc(&cmp
, cc
);
817 arm_jump_cc(&cmp
, label
);
821 static const uint8_t table_logic_cc
[16] = {
840 /* Set PC and Thumb state from an immediate address. */
841 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
845 s
->is_jmp
= DISAS_JUMP
;
846 if (s
->thumb
!= (addr
& 1)) {
847 tmp
= tcg_temp_new_i32();
848 tcg_gen_movi_i32(tmp
, addr
& 1);
849 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
850 tcg_temp_free_i32(tmp
);
852 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
855 /* Set PC and Thumb state from var. var is marked as dead. */
856 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
858 s
->is_jmp
= DISAS_JUMP
;
859 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
860 tcg_gen_andi_i32(var
, var
, 1);
861 store_cpu_field(var
, thumb
);
864 /* Variant of store_reg which uses branch&exchange logic when storing
865 to r15 in ARM architecture v7 and above. The source must be a temporary
866 and will be marked as dead. */
867 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
869 if (reg
== 15 && ENABLE_ARCH_7
) {
872 store_reg(s
, reg
, var
);
876 /* Variant of store_reg which uses branch&exchange logic when storing
877 * to r15 in ARM architecture v5T and above. This is used for storing
878 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
879 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
880 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
882 if (reg
== 15 && ENABLE_ARCH_5
) {
885 store_reg(s
, reg
, var
);
889 #ifdef CONFIG_USER_ONLY
890 #define IS_USER_ONLY 1
892 #define IS_USER_ONLY 0
895 /* Abstractions of "generate code to do a guest load/store for
896 * AArch32", where a vaddr is always 32 bits (and is zero
897 * extended if we're a 64 bit core) and data is also
898 * 32 bits unless specifically doing a 64 bit access.
899 * These functions work like tcg_gen_qemu_{ld,st}* except
900 * that the address argument is TCGv_i32 rather than TCGv.
903 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, TCGMemOp op
)
905 TCGv addr
= tcg_temp_new();
906 tcg_gen_extu_i32_tl(addr
, a32
);
908 /* Not needed for user-mode BE32, where we use MO_BE instead. */
909 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
910 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
915 static void gen_aa32_ld_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
916 int index
, TCGMemOp opc
)
918 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
919 tcg_gen_qemu_ld_i32(val
, addr
, index
, opc
);
923 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
924 int index
, TCGMemOp opc
)
926 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
927 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
931 #define DO_GEN_LD(SUFF, OPC) \
932 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
933 TCGv_i32 a32, int index) \
935 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
938 #define DO_GEN_ST(SUFF, OPC) \
939 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
940 TCGv_i32 a32, int index) \
942 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
945 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
947 /* Not needed for user-mode BE32, where we use MO_BE instead. */
948 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
949 tcg_gen_rotri_i64(val
, val
, 32);
953 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
954 int index
, TCGMemOp opc
)
956 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
957 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
958 gen_aa32_frob64(s
, val
);
962 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
963 TCGv_i32 a32
, int index
)
965 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
968 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
969 int index
, TCGMemOp opc
)
971 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
973 /* Not needed for user-mode BE32, where we use MO_BE instead. */
974 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
975 TCGv_i64 tmp
= tcg_temp_new_i64();
976 tcg_gen_rotri_i64(tmp
, val
, 32);
977 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
978 tcg_temp_free_i64(tmp
);
980 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
985 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
986 TCGv_i32 a32
, int index
)
988 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
993 DO_GEN_LD(16s
, MO_SW
)
994 DO_GEN_LD(16u, MO_UW
)
995 DO_GEN_LD(32u, MO_UL
)
1000 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
1002 tcg_gen_movi_i32(cpu_R
[15], val
);
1005 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1007 /* The pre HVC helper handles cases when HVC gets trapped
1008 * as an undefined insn by runtime configuration (ie before
1009 * the insn really executes).
1011 gen_set_pc_im(s
, s
->pc
- 4);
1012 gen_helper_pre_hvc(cpu_env
);
1013 /* Otherwise we will treat this as a real exception which
1014 * happens after execution of the insn. (The distinction matters
1015 * for the PC value reported to the exception handler and also
1016 * for single stepping.)
1019 gen_set_pc_im(s
, s
->pc
);
1020 s
->is_jmp
= DISAS_HVC
;
1023 static inline void gen_smc(DisasContext
*s
)
1025 /* As with HVC, we may take an exception either before or after
1026 * the insn executes.
1030 gen_set_pc_im(s
, s
->pc
- 4);
1031 tmp
= tcg_const_i32(syn_aa32_smc());
1032 gen_helper_pre_smc(cpu_env
, tmp
);
1033 tcg_temp_free_i32(tmp
);
1034 gen_set_pc_im(s
, s
->pc
);
1035 s
->is_jmp
= DISAS_SMC
;
1039 gen_set_condexec (DisasContext
*s
)
1041 if (s
->condexec_mask
) {
1042 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1043 TCGv_i32 tmp
= tcg_temp_new_i32();
1044 tcg_gen_movi_i32(tmp
, val
);
1045 store_cpu_field(tmp
, condexec_bits
);
1049 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1051 gen_set_condexec(s
);
1052 gen_set_pc_im(s
, s
->pc
- offset
);
1053 gen_exception_internal(excp
);
1054 s
->is_jmp
= DISAS_JUMP
;
1057 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1058 int syn
, uint32_t target_el
)
1060 gen_set_condexec(s
);
1061 gen_set_pc_im(s
, s
->pc
- offset
);
1062 gen_exception(excp
, syn
, target_el
);
1063 s
->is_jmp
= DISAS_JUMP
;
1066 /* Force a TB lookup after an instruction that changes the CPU state. */
1067 static inline void gen_lookup_tb(DisasContext
*s
)
1069 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1070 s
->is_jmp
= DISAS_JUMP
;
1073 static inline void gen_hlt(DisasContext
*s
, int imm
)
1075 /* HLT. This has two purposes.
1076 * Architecturally, it is an external halting debug instruction.
1077 * Since QEMU doesn't implement external debug, we treat this as
1078 * it is required for halting debug disabled: it will UNDEF.
1079 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1080 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1081 * must trigger semihosting even for ARMv7 and earlier, where
1082 * HLT was an undefined encoding.
1083 * In system mode, we don't allow userspace access to
1084 * semihosting, to provide some semblance of security
1085 * (and for consistency with our 32-bit semihosting).
1087 if (semihosting_enabled() &&
1088 #ifndef CONFIG_USER_ONLY
1089 s
->current_el
!= 0 &&
1091 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1092 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1096 gen_exception_insn(s
, s
->thumb
? 2 : 4, EXCP_UDEF
, syn_uncategorized(),
1097 default_exception_el(s
));
1100 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1103 int val
, rm
, shift
, shiftop
;
1106 if (!(insn
& (1 << 25))) {
1109 if (!(insn
& (1 << 23)))
1112 tcg_gen_addi_i32(var
, var
, val
);
1114 /* shift/register */
1116 shift
= (insn
>> 7) & 0x1f;
1117 shiftop
= (insn
>> 5) & 3;
1118 offset
= load_reg(s
, rm
);
1119 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1120 if (!(insn
& (1 << 23)))
1121 tcg_gen_sub_i32(var
, var
, offset
);
1123 tcg_gen_add_i32(var
, var
, offset
);
1124 tcg_temp_free_i32(offset
);
1128 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1129 int extra
, TCGv_i32 var
)
1134 if (insn
& (1 << 22)) {
1136 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1137 if (!(insn
& (1 << 23)))
1141 tcg_gen_addi_i32(var
, var
, val
);
1145 tcg_gen_addi_i32(var
, var
, extra
);
1147 offset
= load_reg(s
, rm
);
1148 if (!(insn
& (1 << 23)))
1149 tcg_gen_sub_i32(var
, var
, offset
);
1151 tcg_gen_add_i32(var
, var
, offset
);
1152 tcg_temp_free_i32(offset
);
1156 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1158 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1161 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1163 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1165 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1169 #define VFP_OP2(name) \
1170 static inline void gen_vfp_##name(int dp) \
1172 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1174 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1176 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1178 tcg_temp_free_ptr(fpst); \
1188 static inline void gen_vfp_F1_mul(int dp
)
1190 /* Like gen_vfp_mul() but put result in F1 */
1191 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1193 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1195 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1197 tcg_temp_free_ptr(fpst
);
1200 static inline void gen_vfp_F1_neg(int dp
)
1202 /* Like gen_vfp_neg() but put result in F1 */
1204 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1206 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1210 static inline void gen_vfp_abs(int dp
)
1213 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1215 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1218 static inline void gen_vfp_neg(int dp
)
1221 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1223 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1226 static inline void gen_vfp_sqrt(int dp
)
1229 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1231 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1234 static inline void gen_vfp_cmp(int dp
)
1237 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1239 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1242 static inline void gen_vfp_cmpe(int dp
)
1245 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1247 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1250 static inline void gen_vfp_F1_ld0(int dp
)
1253 tcg_gen_movi_i64(cpu_F1d
, 0);
1255 tcg_gen_movi_i32(cpu_F1s
, 0);
1258 #define VFP_GEN_ITOF(name) \
1259 static inline void gen_vfp_##name(int dp, int neon) \
1261 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1263 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1265 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1267 tcg_temp_free_ptr(statusptr); \
1274 #define VFP_GEN_FTOI(name) \
1275 static inline void gen_vfp_##name(int dp, int neon) \
1277 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1279 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1281 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1283 tcg_temp_free_ptr(statusptr); \
1292 #define VFP_GEN_FIX(name, round) \
1293 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1295 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1296 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1298 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1301 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1304 tcg_temp_free_i32(tmp_shift); \
1305 tcg_temp_free_ptr(statusptr); \
1307 VFP_GEN_FIX(tosh
, _round_to_zero
)
1308 VFP_GEN_FIX(tosl
, _round_to_zero
)
1309 VFP_GEN_FIX(touh
, _round_to_zero
)
1310 VFP_GEN_FIX(toul
, _round_to_zero
)
1317 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1320 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1322 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1326 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1329 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1331 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1336 vfp_reg_offset (int dp
, int reg
)
1339 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1341 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1342 + offsetof(CPU_DoubleU
, l
.upper
);
1344 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1345 + offsetof(CPU_DoubleU
, l
.lower
);
1349 /* Return the offset of a 32-bit piece of a NEON register.
1350 zero is the least significant end of the register. */
1352 neon_reg_offset (int reg
, int n
)
1356 return vfp_reg_offset(0, sreg
);
1359 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1361 TCGv_i32 tmp
= tcg_temp_new_i32();
1362 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1366 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1368 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1369 tcg_temp_free_i32(var
);
1372 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1374 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1377 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1379 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1382 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1383 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1384 #define tcg_gen_st_f32 tcg_gen_st_i32
1385 #define tcg_gen_st_f64 tcg_gen_st_i64
1387 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1390 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1392 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1395 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1398 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1400 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1403 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1406 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1408 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1411 #define ARM_CP_RW_BIT (1 << 20)
1413 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1415 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1418 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1420 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1423 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1425 TCGv_i32 var
= tcg_temp_new_i32();
1426 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1430 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1432 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1433 tcg_temp_free_i32(var
);
1436 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1438 iwmmxt_store_reg(cpu_M0
, rn
);
1441 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1443 iwmmxt_load_reg(cpu_M0
, rn
);
1446 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1448 iwmmxt_load_reg(cpu_V1
, rn
);
1449 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1452 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1454 iwmmxt_load_reg(cpu_V1
, rn
);
1455 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1458 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1460 iwmmxt_load_reg(cpu_V1
, rn
);
1461 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1464 #define IWMMXT_OP(name) \
1465 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1467 iwmmxt_load_reg(cpu_V1, rn); \
1468 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1471 #define IWMMXT_OP_ENV(name) \
1472 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1474 iwmmxt_load_reg(cpu_V1, rn); \
1475 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1478 #define IWMMXT_OP_ENV_SIZE(name) \
1479 IWMMXT_OP_ENV(name##b) \
1480 IWMMXT_OP_ENV(name##w) \
1481 IWMMXT_OP_ENV(name##l)
1483 #define IWMMXT_OP_ENV1(name) \
1484 static inline void gen_op_iwmmxt_##name##_M0(void) \
1486 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1500 IWMMXT_OP_ENV_SIZE(unpackl
)
1501 IWMMXT_OP_ENV_SIZE(unpackh
)
1503 IWMMXT_OP_ENV1(unpacklub
)
1504 IWMMXT_OP_ENV1(unpackluw
)
1505 IWMMXT_OP_ENV1(unpacklul
)
1506 IWMMXT_OP_ENV1(unpackhub
)
1507 IWMMXT_OP_ENV1(unpackhuw
)
1508 IWMMXT_OP_ENV1(unpackhul
)
1509 IWMMXT_OP_ENV1(unpacklsb
)
1510 IWMMXT_OP_ENV1(unpacklsw
)
1511 IWMMXT_OP_ENV1(unpacklsl
)
1512 IWMMXT_OP_ENV1(unpackhsb
)
1513 IWMMXT_OP_ENV1(unpackhsw
)
1514 IWMMXT_OP_ENV1(unpackhsl
)
1516 IWMMXT_OP_ENV_SIZE(cmpeq
)
1517 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1518 IWMMXT_OP_ENV_SIZE(cmpgts
)
1520 IWMMXT_OP_ENV_SIZE(mins
)
1521 IWMMXT_OP_ENV_SIZE(minu
)
1522 IWMMXT_OP_ENV_SIZE(maxs
)
1523 IWMMXT_OP_ENV_SIZE(maxu
)
1525 IWMMXT_OP_ENV_SIZE(subn
)
1526 IWMMXT_OP_ENV_SIZE(addn
)
1527 IWMMXT_OP_ENV_SIZE(subu
)
1528 IWMMXT_OP_ENV_SIZE(addu
)
1529 IWMMXT_OP_ENV_SIZE(subs
)
1530 IWMMXT_OP_ENV_SIZE(adds
)
1532 IWMMXT_OP_ENV(avgb0
)
1533 IWMMXT_OP_ENV(avgb1
)
1534 IWMMXT_OP_ENV(avgw0
)
1535 IWMMXT_OP_ENV(avgw1
)
1537 IWMMXT_OP_ENV(packuw
)
1538 IWMMXT_OP_ENV(packul
)
1539 IWMMXT_OP_ENV(packuq
)
1540 IWMMXT_OP_ENV(packsw
)
1541 IWMMXT_OP_ENV(packsl
)
1542 IWMMXT_OP_ENV(packsq
)
1544 static void gen_op_iwmmxt_set_mup(void)
1547 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1548 tcg_gen_ori_i32(tmp
, tmp
, 2);
1549 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1552 static void gen_op_iwmmxt_set_cup(void)
1555 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1556 tcg_gen_ori_i32(tmp
, tmp
, 1);
1557 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1560 static void gen_op_iwmmxt_setpsr_nz(void)
1562 TCGv_i32 tmp
= tcg_temp_new_i32();
1563 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1564 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1567 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1569 iwmmxt_load_reg(cpu_V1
, rn
);
1570 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1571 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1574 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1581 rd
= (insn
>> 16) & 0xf;
1582 tmp
= load_reg(s
, rd
);
1584 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1585 if (insn
& (1 << 24)) {
1587 if (insn
& (1 << 23))
1588 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1590 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1591 tcg_gen_mov_i32(dest
, tmp
);
1592 if (insn
& (1 << 21))
1593 store_reg(s
, rd
, tmp
);
1595 tcg_temp_free_i32(tmp
);
1596 } else if (insn
& (1 << 21)) {
1598 tcg_gen_mov_i32(dest
, tmp
);
1599 if (insn
& (1 << 23))
1600 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1602 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1603 store_reg(s
, rd
, tmp
);
1604 } else if (!(insn
& (1 << 23)))
1609 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1611 int rd
= (insn
>> 0) & 0xf;
1614 if (insn
& (1 << 8)) {
1615 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1618 tmp
= iwmmxt_load_creg(rd
);
1621 tmp
= tcg_temp_new_i32();
1622 iwmmxt_load_reg(cpu_V0
, rd
);
1623 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1625 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1626 tcg_gen_mov_i32(dest
, tmp
);
1627 tcg_temp_free_i32(tmp
);
1631 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1632 (ie. an undefined instruction). */
1633 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1636 int rdhi
, rdlo
, rd0
, rd1
, i
;
1638 TCGv_i32 tmp
, tmp2
, tmp3
;
1640 if ((insn
& 0x0e000e00) == 0x0c000000) {
1641 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1643 rdlo
= (insn
>> 12) & 0xf;
1644 rdhi
= (insn
>> 16) & 0xf;
1645 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1646 iwmmxt_load_reg(cpu_V0
, wrd
);
1647 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1648 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1649 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1650 } else { /* TMCRR */
1651 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1652 iwmmxt_store_reg(cpu_V0
, wrd
);
1653 gen_op_iwmmxt_set_mup();
1658 wrd
= (insn
>> 12) & 0xf;
1659 addr
= tcg_temp_new_i32();
1660 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1661 tcg_temp_free_i32(addr
);
1664 if (insn
& ARM_CP_RW_BIT
) {
1665 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1666 tmp
= tcg_temp_new_i32();
1667 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1668 iwmmxt_store_creg(wrd
, tmp
);
1671 if (insn
& (1 << 8)) {
1672 if (insn
& (1 << 22)) { /* WLDRD */
1673 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1675 } else { /* WLDRW wRd */
1676 tmp
= tcg_temp_new_i32();
1677 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1680 tmp
= tcg_temp_new_i32();
1681 if (insn
& (1 << 22)) { /* WLDRH */
1682 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1683 } else { /* WLDRB */
1684 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1688 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1689 tcg_temp_free_i32(tmp
);
1691 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1694 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1695 tmp
= iwmmxt_load_creg(wrd
);
1696 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1698 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1699 tmp
= tcg_temp_new_i32();
1700 if (insn
& (1 << 8)) {
1701 if (insn
& (1 << 22)) { /* WSTRD */
1702 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1703 } else { /* WSTRW wRd */
1704 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1705 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1708 if (insn
& (1 << 22)) { /* WSTRH */
1709 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1710 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1711 } else { /* WSTRB */
1712 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1713 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1717 tcg_temp_free_i32(tmp
);
1719 tcg_temp_free_i32(addr
);
1723 if ((insn
& 0x0f000000) != 0x0e000000)
1726 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1727 case 0x000: /* WOR */
1728 wrd
= (insn
>> 12) & 0xf;
1729 rd0
= (insn
>> 0) & 0xf;
1730 rd1
= (insn
>> 16) & 0xf;
1731 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1732 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1733 gen_op_iwmmxt_setpsr_nz();
1734 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1735 gen_op_iwmmxt_set_mup();
1736 gen_op_iwmmxt_set_cup();
1738 case 0x011: /* TMCR */
1741 rd
= (insn
>> 12) & 0xf;
1742 wrd
= (insn
>> 16) & 0xf;
1744 case ARM_IWMMXT_wCID
:
1745 case ARM_IWMMXT_wCASF
:
1747 case ARM_IWMMXT_wCon
:
1748 gen_op_iwmmxt_set_cup();
1750 case ARM_IWMMXT_wCSSF
:
1751 tmp
= iwmmxt_load_creg(wrd
);
1752 tmp2
= load_reg(s
, rd
);
1753 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1754 tcg_temp_free_i32(tmp2
);
1755 iwmmxt_store_creg(wrd
, tmp
);
1757 case ARM_IWMMXT_wCGR0
:
1758 case ARM_IWMMXT_wCGR1
:
1759 case ARM_IWMMXT_wCGR2
:
1760 case ARM_IWMMXT_wCGR3
:
1761 gen_op_iwmmxt_set_cup();
1762 tmp
= load_reg(s
, rd
);
1763 iwmmxt_store_creg(wrd
, tmp
);
1769 case 0x100: /* WXOR */
1770 wrd
= (insn
>> 12) & 0xf;
1771 rd0
= (insn
>> 0) & 0xf;
1772 rd1
= (insn
>> 16) & 0xf;
1773 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1774 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1775 gen_op_iwmmxt_setpsr_nz();
1776 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1777 gen_op_iwmmxt_set_mup();
1778 gen_op_iwmmxt_set_cup();
1780 case 0x111: /* TMRC */
1783 rd
= (insn
>> 12) & 0xf;
1784 wrd
= (insn
>> 16) & 0xf;
1785 tmp
= iwmmxt_load_creg(wrd
);
1786 store_reg(s
, rd
, tmp
);
1788 case 0x300: /* WANDN */
1789 wrd
= (insn
>> 12) & 0xf;
1790 rd0
= (insn
>> 0) & 0xf;
1791 rd1
= (insn
>> 16) & 0xf;
1792 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1793 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1794 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1795 gen_op_iwmmxt_setpsr_nz();
1796 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1797 gen_op_iwmmxt_set_mup();
1798 gen_op_iwmmxt_set_cup();
1800 case 0x200: /* WAND */
1801 wrd
= (insn
>> 12) & 0xf;
1802 rd0
= (insn
>> 0) & 0xf;
1803 rd1
= (insn
>> 16) & 0xf;
1804 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1805 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1806 gen_op_iwmmxt_setpsr_nz();
1807 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1808 gen_op_iwmmxt_set_mup();
1809 gen_op_iwmmxt_set_cup();
1811 case 0x810: case 0xa10: /* WMADD */
1812 wrd
= (insn
>> 12) & 0xf;
1813 rd0
= (insn
>> 0) & 0xf;
1814 rd1
= (insn
>> 16) & 0xf;
1815 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1816 if (insn
& (1 << 21))
1817 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1819 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1820 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1821 gen_op_iwmmxt_set_mup();
1823 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1824 wrd
= (insn
>> 12) & 0xf;
1825 rd0
= (insn
>> 16) & 0xf;
1826 rd1
= (insn
>> 0) & 0xf;
1827 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1828 switch ((insn
>> 22) & 3) {
1830 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1833 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1836 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1841 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1842 gen_op_iwmmxt_set_mup();
1843 gen_op_iwmmxt_set_cup();
1845 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1846 wrd
= (insn
>> 12) & 0xf;
1847 rd0
= (insn
>> 16) & 0xf;
1848 rd1
= (insn
>> 0) & 0xf;
1849 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1850 switch ((insn
>> 22) & 3) {
1852 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1855 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1858 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1863 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1864 gen_op_iwmmxt_set_mup();
1865 gen_op_iwmmxt_set_cup();
1867 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1868 wrd
= (insn
>> 12) & 0xf;
1869 rd0
= (insn
>> 16) & 0xf;
1870 rd1
= (insn
>> 0) & 0xf;
1871 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1872 if (insn
& (1 << 22))
1873 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1875 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1876 if (!(insn
& (1 << 20)))
1877 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1878 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1879 gen_op_iwmmxt_set_mup();
1881 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1882 wrd
= (insn
>> 12) & 0xf;
1883 rd0
= (insn
>> 16) & 0xf;
1884 rd1
= (insn
>> 0) & 0xf;
1885 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1886 if (insn
& (1 << 21)) {
1887 if (insn
& (1 << 20))
1888 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1890 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1892 if (insn
& (1 << 20))
1893 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1895 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1897 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1898 gen_op_iwmmxt_set_mup();
1900 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1901 wrd
= (insn
>> 12) & 0xf;
1902 rd0
= (insn
>> 16) & 0xf;
1903 rd1
= (insn
>> 0) & 0xf;
1904 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1905 if (insn
& (1 << 21))
1906 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1908 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1909 if (!(insn
& (1 << 20))) {
1910 iwmmxt_load_reg(cpu_V1
, wrd
);
1911 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1913 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1914 gen_op_iwmmxt_set_mup();
1916 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1917 wrd
= (insn
>> 12) & 0xf;
1918 rd0
= (insn
>> 16) & 0xf;
1919 rd1
= (insn
>> 0) & 0xf;
1920 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1921 switch ((insn
>> 22) & 3) {
1923 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1926 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1929 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1934 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1935 gen_op_iwmmxt_set_mup();
1936 gen_op_iwmmxt_set_cup();
1938 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1939 wrd
= (insn
>> 12) & 0xf;
1940 rd0
= (insn
>> 16) & 0xf;
1941 rd1
= (insn
>> 0) & 0xf;
1942 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1943 if (insn
& (1 << 22)) {
1944 if (insn
& (1 << 20))
1945 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1947 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1949 if (insn
& (1 << 20))
1950 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1952 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1954 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1955 gen_op_iwmmxt_set_mup();
1956 gen_op_iwmmxt_set_cup();
1958 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1959 wrd
= (insn
>> 12) & 0xf;
1960 rd0
= (insn
>> 16) & 0xf;
1961 rd1
= (insn
>> 0) & 0xf;
1962 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1963 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1964 tcg_gen_andi_i32(tmp
, tmp
, 7);
1965 iwmmxt_load_reg(cpu_V1
, rd1
);
1966 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1967 tcg_temp_free_i32(tmp
);
1968 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1969 gen_op_iwmmxt_set_mup();
1971 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1972 if (((insn
>> 6) & 3) == 3)
1974 rd
= (insn
>> 12) & 0xf;
1975 wrd
= (insn
>> 16) & 0xf;
1976 tmp
= load_reg(s
, rd
);
1977 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1978 switch ((insn
>> 6) & 3) {
1980 tmp2
= tcg_const_i32(0xff);
1981 tmp3
= tcg_const_i32((insn
& 7) << 3);
1984 tmp2
= tcg_const_i32(0xffff);
1985 tmp3
= tcg_const_i32((insn
& 3) << 4);
1988 tmp2
= tcg_const_i32(0xffffffff);
1989 tmp3
= tcg_const_i32((insn
& 1) << 5);
1992 TCGV_UNUSED_I32(tmp2
);
1993 TCGV_UNUSED_I32(tmp3
);
1995 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1996 tcg_temp_free_i32(tmp3
);
1997 tcg_temp_free_i32(tmp2
);
1998 tcg_temp_free_i32(tmp
);
1999 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2000 gen_op_iwmmxt_set_mup();
2002 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2003 rd
= (insn
>> 12) & 0xf;
2004 wrd
= (insn
>> 16) & 0xf;
2005 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2007 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2008 tmp
= tcg_temp_new_i32();
2009 switch ((insn
>> 22) & 3) {
2011 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2012 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2014 tcg_gen_ext8s_i32(tmp
, tmp
);
2016 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2020 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2021 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2023 tcg_gen_ext16s_i32(tmp
, tmp
);
2025 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2029 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2030 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2033 store_reg(s
, rd
, tmp
);
2035 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2036 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2038 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2039 switch ((insn
>> 22) & 3) {
2041 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2044 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2047 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2050 tcg_gen_shli_i32(tmp
, tmp
, 28);
2052 tcg_temp_free_i32(tmp
);
2054 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2055 if (((insn
>> 6) & 3) == 3)
2057 rd
= (insn
>> 12) & 0xf;
2058 wrd
= (insn
>> 16) & 0xf;
2059 tmp
= load_reg(s
, rd
);
2060 switch ((insn
>> 6) & 3) {
2062 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2065 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2068 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2071 tcg_temp_free_i32(tmp
);
2072 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2073 gen_op_iwmmxt_set_mup();
2075 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2076 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2078 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2079 tmp2
= tcg_temp_new_i32();
2080 tcg_gen_mov_i32(tmp2
, tmp
);
2081 switch ((insn
>> 22) & 3) {
2083 for (i
= 0; i
< 7; i
++) {
2084 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2085 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2089 for (i
= 0; i
< 3; i
++) {
2090 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2091 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2095 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2096 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2100 tcg_temp_free_i32(tmp2
);
2101 tcg_temp_free_i32(tmp
);
2103 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2104 wrd
= (insn
>> 12) & 0xf;
2105 rd0
= (insn
>> 16) & 0xf;
2106 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2107 switch ((insn
>> 22) & 3) {
2109 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2112 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2115 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2120 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2121 gen_op_iwmmxt_set_mup();
2123 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2124 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2126 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2127 tmp2
= tcg_temp_new_i32();
2128 tcg_gen_mov_i32(tmp2
, tmp
);
2129 switch ((insn
>> 22) & 3) {
2131 for (i
= 0; i
< 7; i
++) {
2132 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2133 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2137 for (i
= 0; i
< 3; i
++) {
2138 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2139 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2143 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2144 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2148 tcg_temp_free_i32(tmp2
);
2149 tcg_temp_free_i32(tmp
);
2151 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2152 rd
= (insn
>> 12) & 0xf;
2153 rd0
= (insn
>> 16) & 0xf;
2154 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2156 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2157 tmp
= tcg_temp_new_i32();
2158 switch ((insn
>> 22) & 3) {
2160 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2163 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2166 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2169 store_reg(s
, rd
, tmp
);
2171 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2172 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2173 wrd
= (insn
>> 12) & 0xf;
2174 rd0
= (insn
>> 16) & 0xf;
2175 rd1
= (insn
>> 0) & 0xf;
2176 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2177 switch ((insn
>> 22) & 3) {
2179 if (insn
& (1 << 21))
2180 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2182 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2185 if (insn
& (1 << 21))
2186 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2188 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2191 if (insn
& (1 << 21))
2192 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2194 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2199 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2200 gen_op_iwmmxt_set_mup();
2201 gen_op_iwmmxt_set_cup();
2203 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2204 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2205 wrd
= (insn
>> 12) & 0xf;
2206 rd0
= (insn
>> 16) & 0xf;
2207 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2208 switch ((insn
>> 22) & 3) {
2210 if (insn
& (1 << 21))
2211 gen_op_iwmmxt_unpacklsb_M0();
2213 gen_op_iwmmxt_unpacklub_M0();
2216 if (insn
& (1 << 21))
2217 gen_op_iwmmxt_unpacklsw_M0();
2219 gen_op_iwmmxt_unpackluw_M0();
2222 if (insn
& (1 << 21))
2223 gen_op_iwmmxt_unpacklsl_M0();
2225 gen_op_iwmmxt_unpacklul_M0();
2230 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2231 gen_op_iwmmxt_set_mup();
2232 gen_op_iwmmxt_set_cup();
2234 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2235 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2236 wrd
= (insn
>> 12) & 0xf;
2237 rd0
= (insn
>> 16) & 0xf;
2238 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2239 switch ((insn
>> 22) & 3) {
2241 if (insn
& (1 << 21))
2242 gen_op_iwmmxt_unpackhsb_M0();
2244 gen_op_iwmmxt_unpackhub_M0();
2247 if (insn
& (1 << 21))
2248 gen_op_iwmmxt_unpackhsw_M0();
2250 gen_op_iwmmxt_unpackhuw_M0();
2253 if (insn
& (1 << 21))
2254 gen_op_iwmmxt_unpackhsl_M0();
2256 gen_op_iwmmxt_unpackhul_M0();
2261 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2262 gen_op_iwmmxt_set_mup();
2263 gen_op_iwmmxt_set_cup();
2265 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2266 case 0x214: case 0x614: case 0xa14: case 0xe14:
2267 if (((insn
>> 22) & 3) == 0)
2269 wrd
= (insn
>> 12) & 0xf;
2270 rd0
= (insn
>> 16) & 0xf;
2271 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2272 tmp
= tcg_temp_new_i32();
2273 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2274 tcg_temp_free_i32(tmp
);
2277 switch ((insn
>> 22) & 3) {
2279 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2282 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2285 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2288 tcg_temp_free_i32(tmp
);
2289 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2290 gen_op_iwmmxt_set_mup();
2291 gen_op_iwmmxt_set_cup();
2293 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2294 case 0x014: case 0x414: case 0x814: case 0xc14:
2295 if (((insn
>> 22) & 3) == 0)
2297 wrd
= (insn
>> 12) & 0xf;
2298 rd0
= (insn
>> 16) & 0xf;
2299 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2300 tmp
= tcg_temp_new_i32();
2301 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2302 tcg_temp_free_i32(tmp
);
2305 switch ((insn
>> 22) & 3) {
2307 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2310 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2313 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2316 tcg_temp_free_i32(tmp
);
2317 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2318 gen_op_iwmmxt_set_mup();
2319 gen_op_iwmmxt_set_cup();
2321 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2322 case 0x114: case 0x514: case 0x914: case 0xd14:
2323 if (((insn
>> 22) & 3) == 0)
2325 wrd
= (insn
>> 12) & 0xf;
2326 rd0
= (insn
>> 16) & 0xf;
2327 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2328 tmp
= tcg_temp_new_i32();
2329 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2330 tcg_temp_free_i32(tmp
);
2333 switch ((insn
>> 22) & 3) {
2335 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2338 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2341 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2344 tcg_temp_free_i32(tmp
);
2345 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2346 gen_op_iwmmxt_set_mup();
2347 gen_op_iwmmxt_set_cup();
2349 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2350 case 0x314: case 0x714: case 0xb14: case 0xf14:
2351 if (((insn
>> 22) & 3) == 0)
2353 wrd
= (insn
>> 12) & 0xf;
2354 rd0
= (insn
>> 16) & 0xf;
2355 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2356 tmp
= tcg_temp_new_i32();
2357 switch ((insn
>> 22) & 3) {
2359 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2360 tcg_temp_free_i32(tmp
);
2363 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2366 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2367 tcg_temp_free_i32(tmp
);
2370 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2373 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2374 tcg_temp_free_i32(tmp
);
2377 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2380 tcg_temp_free_i32(tmp
);
2381 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2382 gen_op_iwmmxt_set_mup();
2383 gen_op_iwmmxt_set_cup();
2385 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2386 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2387 wrd
= (insn
>> 12) & 0xf;
2388 rd0
= (insn
>> 16) & 0xf;
2389 rd1
= (insn
>> 0) & 0xf;
2390 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2391 switch ((insn
>> 22) & 3) {
2393 if (insn
& (1 << 21))
2394 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2396 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2399 if (insn
& (1 << 21))
2400 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2402 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2405 if (insn
& (1 << 21))
2406 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2408 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2413 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2414 gen_op_iwmmxt_set_mup();
2416 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2417 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2418 wrd
= (insn
>> 12) & 0xf;
2419 rd0
= (insn
>> 16) & 0xf;
2420 rd1
= (insn
>> 0) & 0xf;
2421 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2422 switch ((insn
>> 22) & 3) {
2424 if (insn
& (1 << 21))
2425 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2427 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2430 if (insn
& (1 << 21))
2431 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2433 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2436 if (insn
& (1 << 21))
2437 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2439 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2444 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2445 gen_op_iwmmxt_set_mup();
2447 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2448 case 0x402: case 0x502: case 0x602: case 0x702:
2449 wrd
= (insn
>> 12) & 0xf;
2450 rd0
= (insn
>> 16) & 0xf;
2451 rd1
= (insn
>> 0) & 0xf;
2452 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2453 tmp
= tcg_const_i32((insn
>> 20) & 3);
2454 iwmmxt_load_reg(cpu_V1
, rd1
);
2455 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2456 tcg_temp_free_i32(tmp
);
2457 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2458 gen_op_iwmmxt_set_mup();
2460 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2461 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2462 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2463 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2464 wrd
= (insn
>> 12) & 0xf;
2465 rd0
= (insn
>> 16) & 0xf;
2466 rd1
= (insn
>> 0) & 0xf;
2467 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2468 switch ((insn
>> 20) & 0xf) {
2470 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2473 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2476 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2479 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2482 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2485 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2488 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2491 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2494 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2499 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2500 gen_op_iwmmxt_set_mup();
2501 gen_op_iwmmxt_set_cup();
2503 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2504 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2505 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2506 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2507 wrd
= (insn
>> 12) & 0xf;
2508 rd0
= (insn
>> 16) & 0xf;
2509 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2510 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2511 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2512 tcg_temp_free_i32(tmp
);
2513 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2514 gen_op_iwmmxt_set_mup();
2515 gen_op_iwmmxt_set_cup();
2517 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2518 case 0x418: case 0x518: case 0x618: case 0x718:
2519 case 0x818: case 0x918: case 0xa18: case 0xb18:
2520 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2521 wrd
= (insn
>> 12) & 0xf;
2522 rd0
= (insn
>> 16) & 0xf;
2523 rd1
= (insn
>> 0) & 0xf;
2524 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2525 switch ((insn
>> 20) & 0xf) {
2527 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2530 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2533 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2536 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2539 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2542 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2545 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2548 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2551 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2556 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2557 gen_op_iwmmxt_set_mup();
2558 gen_op_iwmmxt_set_cup();
2560 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2561 case 0x408: case 0x508: case 0x608: case 0x708:
2562 case 0x808: case 0x908: case 0xa08: case 0xb08:
2563 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2564 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2566 wrd
= (insn
>> 12) & 0xf;
2567 rd0
= (insn
>> 16) & 0xf;
2568 rd1
= (insn
>> 0) & 0xf;
2569 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2570 switch ((insn
>> 22) & 3) {
2572 if (insn
& (1 << 21))
2573 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2575 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2578 if (insn
& (1 << 21))
2579 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2581 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2584 if (insn
& (1 << 21))
2585 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2587 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2590 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2591 gen_op_iwmmxt_set_mup();
2592 gen_op_iwmmxt_set_cup();
2594 case 0x201: case 0x203: case 0x205: case 0x207:
2595 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2596 case 0x211: case 0x213: case 0x215: case 0x217:
2597 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2598 wrd
= (insn
>> 5) & 0xf;
2599 rd0
= (insn
>> 12) & 0xf;
2600 rd1
= (insn
>> 0) & 0xf;
2601 if (rd0
== 0xf || rd1
== 0xf)
2603 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2604 tmp
= load_reg(s
, rd0
);
2605 tmp2
= load_reg(s
, rd1
);
2606 switch ((insn
>> 16) & 0xf) {
2607 case 0x0: /* TMIA */
2608 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2610 case 0x8: /* TMIAPH */
2611 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2613 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2614 if (insn
& (1 << 16))
2615 tcg_gen_shri_i32(tmp
, tmp
, 16);
2616 if (insn
& (1 << 17))
2617 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2618 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2621 tcg_temp_free_i32(tmp2
);
2622 tcg_temp_free_i32(tmp
);
2625 tcg_temp_free_i32(tmp2
);
2626 tcg_temp_free_i32(tmp
);
2627 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2628 gen_op_iwmmxt_set_mup();
2637 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2638 (ie. an undefined instruction). */
2639 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2641 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2644 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2645 /* Multiply with Internal Accumulate Format */
2646 rd0
= (insn
>> 12) & 0xf;
2648 acc
= (insn
>> 5) & 7;
2653 tmp
= load_reg(s
, rd0
);
2654 tmp2
= load_reg(s
, rd1
);
2655 switch ((insn
>> 16) & 0xf) {
2657 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2659 case 0x8: /* MIAPH */
2660 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2662 case 0xc: /* MIABB */
2663 case 0xd: /* MIABT */
2664 case 0xe: /* MIATB */
2665 case 0xf: /* MIATT */
2666 if (insn
& (1 << 16))
2667 tcg_gen_shri_i32(tmp
, tmp
, 16);
2668 if (insn
& (1 << 17))
2669 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2670 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2675 tcg_temp_free_i32(tmp2
);
2676 tcg_temp_free_i32(tmp
);
2678 gen_op_iwmmxt_movq_wRn_M0(acc
);
2682 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2683 /* Internal Accumulator Access Format */
2684 rdhi
= (insn
>> 16) & 0xf;
2685 rdlo
= (insn
>> 12) & 0xf;
2691 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2692 iwmmxt_load_reg(cpu_V0
, acc
);
2693 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2694 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2695 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2696 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2698 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2699 iwmmxt_store_reg(cpu_V0
, acc
);
2707 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2708 #define VFP_SREG(insn, bigbit, smallbit) \
2709 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2710 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2711 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2712 reg = (((insn) >> (bigbit)) & 0x0f) \
2713 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2715 if (insn & (1 << (smallbit))) \
2717 reg = ((insn) >> (bigbit)) & 0x0f; \
2720 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2721 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2722 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2723 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2724 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2725 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2727 /* Move between integer and VFP cores. */
2728 static TCGv_i32
gen_vfp_mrs(void)
2730 TCGv_i32 tmp
= tcg_temp_new_i32();
2731 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2735 static void gen_vfp_msr(TCGv_i32 tmp
)
2737 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2738 tcg_temp_free_i32(tmp
);
2741 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2743 TCGv_i32 tmp
= tcg_temp_new_i32();
2745 tcg_gen_shri_i32(var
, var
, shift
);
2746 tcg_gen_ext8u_i32(var
, var
);
2747 tcg_gen_shli_i32(tmp
, var
, 8);
2748 tcg_gen_or_i32(var
, var
, tmp
);
2749 tcg_gen_shli_i32(tmp
, var
, 16);
2750 tcg_gen_or_i32(var
, var
, tmp
);
2751 tcg_temp_free_i32(tmp
);
2754 static void gen_neon_dup_low16(TCGv_i32 var
)
2756 TCGv_i32 tmp
= tcg_temp_new_i32();
2757 tcg_gen_ext16u_i32(var
, var
);
2758 tcg_gen_shli_i32(tmp
, var
, 16);
2759 tcg_gen_or_i32(var
, var
, tmp
);
2760 tcg_temp_free_i32(tmp
);
2763 static void gen_neon_dup_high16(TCGv_i32 var
)
2765 TCGv_i32 tmp
= tcg_temp_new_i32();
2766 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2767 tcg_gen_shri_i32(tmp
, var
, 16);
2768 tcg_gen_or_i32(var
, var
, tmp
);
2769 tcg_temp_free_i32(tmp
);
2772 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2774 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2775 TCGv_i32 tmp
= tcg_temp_new_i32();
2778 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2779 gen_neon_dup_u8(tmp
, 0);
2782 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2783 gen_neon_dup_low16(tmp
);
2786 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2788 default: /* Avoid compiler warnings. */
2794 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2797 uint32_t cc
= extract32(insn
, 20, 2);
2800 TCGv_i64 frn
, frm
, dest
;
2801 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2803 zero
= tcg_const_i64(0);
2805 frn
= tcg_temp_new_i64();
2806 frm
= tcg_temp_new_i64();
2807 dest
= tcg_temp_new_i64();
2809 zf
= tcg_temp_new_i64();
2810 nf
= tcg_temp_new_i64();
2811 vf
= tcg_temp_new_i64();
2813 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2814 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2815 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2817 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2818 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2821 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2825 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2828 case 2: /* ge: N == V -> N ^ V == 0 */
2829 tmp
= tcg_temp_new_i64();
2830 tcg_gen_xor_i64(tmp
, vf
, nf
);
2831 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2833 tcg_temp_free_i64(tmp
);
2835 case 3: /* gt: !Z && N == V */
2836 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2838 tmp
= tcg_temp_new_i64();
2839 tcg_gen_xor_i64(tmp
, vf
, nf
);
2840 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2842 tcg_temp_free_i64(tmp
);
2845 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2846 tcg_temp_free_i64(frn
);
2847 tcg_temp_free_i64(frm
);
2848 tcg_temp_free_i64(dest
);
2850 tcg_temp_free_i64(zf
);
2851 tcg_temp_free_i64(nf
);
2852 tcg_temp_free_i64(vf
);
2854 tcg_temp_free_i64(zero
);
2856 TCGv_i32 frn
, frm
, dest
;
2859 zero
= tcg_const_i32(0);
2861 frn
= tcg_temp_new_i32();
2862 frm
= tcg_temp_new_i32();
2863 dest
= tcg_temp_new_i32();
2864 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2865 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2868 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2872 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2875 case 2: /* ge: N == V -> N ^ V == 0 */
2876 tmp
= tcg_temp_new_i32();
2877 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2878 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2880 tcg_temp_free_i32(tmp
);
2882 case 3: /* gt: !Z && N == V */
2883 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2885 tmp
= tcg_temp_new_i32();
2886 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2887 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2889 tcg_temp_free_i32(tmp
);
2892 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2893 tcg_temp_free_i32(frn
);
2894 tcg_temp_free_i32(frm
);
2895 tcg_temp_free_i32(dest
);
2897 tcg_temp_free_i32(zero
);
2903 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2904 uint32_t rm
, uint32_t dp
)
2906 uint32_t vmin
= extract32(insn
, 6, 1);
2907 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2910 TCGv_i64 frn
, frm
, dest
;
2912 frn
= tcg_temp_new_i64();
2913 frm
= tcg_temp_new_i64();
2914 dest
= tcg_temp_new_i64();
2916 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2917 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2919 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2921 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2923 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2924 tcg_temp_free_i64(frn
);
2925 tcg_temp_free_i64(frm
);
2926 tcg_temp_free_i64(dest
);
2928 TCGv_i32 frn
, frm
, dest
;
2930 frn
= tcg_temp_new_i32();
2931 frm
= tcg_temp_new_i32();
2932 dest
= tcg_temp_new_i32();
2934 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2935 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2937 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2939 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2941 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2942 tcg_temp_free_i32(frn
);
2943 tcg_temp_free_i32(frm
);
2944 tcg_temp_free_i32(dest
);
2947 tcg_temp_free_ptr(fpst
);
2951 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2954 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2957 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2958 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2963 tcg_op
= tcg_temp_new_i64();
2964 tcg_res
= tcg_temp_new_i64();
2965 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2966 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2967 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2968 tcg_temp_free_i64(tcg_op
);
2969 tcg_temp_free_i64(tcg_res
);
2973 tcg_op
= tcg_temp_new_i32();
2974 tcg_res
= tcg_temp_new_i32();
2975 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2976 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2977 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2978 tcg_temp_free_i32(tcg_op
);
2979 tcg_temp_free_i32(tcg_res
);
2982 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2983 tcg_temp_free_i32(tcg_rmode
);
2985 tcg_temp_free_ptr(fpst
);
2989 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2992 bool is_signed
= extract32(insn
, 7, 1);
2993 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2994 TCGv_i32 tcg_rmode
, tcg_shift
;
2996 tcg_shift
= tcg_const_i32(0);
2998 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2999 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3002 TCGv_i64 tcg_double
, tcg_res
;
3004 /* Rd is encoded as a single precision register even when the source
3005 * is double precision.
3007 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3008 tcg_double
= tcg_temp_new_i64();
3009 tcg_res
= tcg_temp_new_i64();
3010 tcg_tmp
= tcg_temp_new_i32();
3011 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3013 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3015 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3017 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3018 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3019 tcg_temp_free_i32(tcg_tmp
);
3020 tcg_temp_free_i64(tcg_res
);
3021 tcg_temp_free_i64(tcg_double
);
3023 TCGv_i32 tcg_single
, tcg_res
;
3024 tcg_single
= tcg_temp_new_i32();
3025 tcg_res
= tcg_temp_new_i32();
3026 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3028 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3030 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3032 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3033 tcg_temp_free_i32(tcg_res
);
3034 tcg_temp_free_i32(tcg_single
);
3037 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3038 tcg_temp_free_i32(tcg_rmode
);
3040 tcg_temp_free_i32(tcg_shift
);
3042 tcg_temp_free_ptr(fpst
);
3047 /* Table for converting the most common AArch32 encoding of
3048 * rounding mode to arm_fprounding order (which matches the
3049 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3051 static const uint8_t fp_decode_rm
[] = {
3058 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3060 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3062 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3067 VFP_DREG_D(rd
, insn
);
3068 VFP_DREG_N(rn
, insn
);
3069 VFP_DREG_M(rm
, insn
);
3071 rd
= VFP_SREG_D(insn
);
3072 rn
= VFP_SREG_N(insn
);
3073 rm
= VFP_SREG_M(insn
);
3076 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3077 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3078 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3079 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3080 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3081 /* VRINTA, VRINTN, VRINTP, VRINTM */
3082 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3083 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3084 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3085 /* VCVTA, VCVTN, VCVTP, VCVTM */
3086 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3087 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3092 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3093 (ie. an undefined instruction). */
3094 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3096 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3102 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3106 /* FIXME: this access check should not take precedence over UNDEF
3107 * for invalid encodings; we will generate incorrect syndrome information
3108 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3110 if (s
->fp_excp_el
) {
3111 gen_exception_insn(s
, 4, EXCP_UDEF
,
3112 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3116 if (!s
->vfp_enabled
) {
3117 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3118 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3120 rn
= (insn
>> 16) & 0xf;
3121 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3122 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3127 if (extract32(insn
, 28, 4) == 0xf) {
3128 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3129 * only used in v8 and above.
3131 return disas_vfp_v8_insn(s
, insn
);
3134 dp
= ((insn
& 0xf00) == 0xb00);
3135 switch ((insn
>> 24) & 0xf) {
3137 if (insn
& (1 << 4)) {
3138 /* single register transfer */
3139 rd
= (insn
>> 12) & 0xf;
3144 VFP_DREG_N(rn
, insn
);
3147 if (insn
& 0x00c00060
3148 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3152 pass
= (insn
>> 21) & 1;
3153 if (insn
& (1 << 22)) {
3155 offset
= ((insn
>> 5) & 3) * 8;
3156 } else if (insn
& (1 << 5)) {
3158 offset
= (insn
& (1 << 6)) ? 16 : 0;
3163 if (insn
& ARM_CP_RW_BIT
) {
3165 tmp
= neon_load_reg(rn
, pass
);
3169 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3170 if (insn
& (1 << 23))
3176 if (insn
& (1 << 23)) {
3178 tcg_gen_shri_i32(tmp
, tmp
, 16);
3184 tcg_gen_sari_i32(tmp
, tmp
, 16);
3193 store_reg(s
, rd
, tmp
);
3196 tmp
= load_reg(s
, rd
);
3197 if (insn
& (1 << 23)) {
3200 gen_neon_dup_u8(tmp
, 0);
3201 } else if (size
== 1) {
3202 gen_neon_dup_low16(tmp
);
3204 for (n
= 0; n
<= pass
* 2; n
++) {
3205 tmp2
= tcg_temp_new_i32();
3206 tcg_gen_mov_i32(tmp2
, tmp
);
3207 neon_store_reg(rn
, n
, tmp2
);
3209 neon_store_reg(rn
, n
, tmp
);
3214 tmp2
= neon_load_reg(rn
, pass
);
3215 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3216 tcg_temp_free_i32(tmp2
);
3219 tmp2
= neon_load_reg(rn
, pass
);
3220 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3221 tcg_temp_free_i32(tmp2
);
3226 neon_store_reg(rn
, pass
, tmp
);
3230 if ((insn
& 0x6f) != 0x00)
3232 rn
= VFP_SREG_N(insn
);
3233 if (insn
& ARM_CP_RW_BIT
) {
3235 if (insn
& (1 << 21)) {
3236 /* system register */
3241 /* VFP2 allows access to FSID from userspace.
3242 VFP3 restricts all id registers to privileged
3245 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3248 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3253 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3255 case ARM_VFP_FPINST
:
3256 case ARM_VFP_FPINST2
:
3257 /* Not present in VFP3. */
3259 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3262 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3266 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3267 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3269 tmp
= tcg_temp_new_i32();
3270 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3274 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3281 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3284 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3290 gen_mov_F0_vreg(0, rn
);
3291 tmp
= gen_vfp_mrs();
3294 /* Set the 4 flag bits in the CPSR. */
3296 tcg_temp_free_i32(tmp
);
3298 store_reg(s
, rd
, tmp
);
3302 if (insn
& (1 << 21)) {
3304 /* system register */
3309 /* Writes are ignored. */
3312 tmp
= load_reg(s
, rd
);
3313 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3314 tcg_temp_free_i32(tmp
);
3320 /* TODO: VFP subarchitecture support.
3321 * For now, keep the EN bit only */
3322 tmp
= load_reg(s
, rd
);
3323 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3324 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3327 case ARM_VFP_FPINST
:
3328 case ARM_VFP_FPINST2
:
3332 tmp
= load_reg(s
, rd
);
3333 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3339 tmp
= load_reg(s
, rd
);
3341 gen_mov_vreg_F0(0, rn
);
3346 /* data processing */
3347 /* The opcode is in bits 23, 21, 20 and 6. */
3348 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3352 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3354 /* rn is register number */
3355 VFP_DREG_N(rn
, insn
);
3358 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3359 ((rn
& 0x1e) == 0x6))) {
3360 /* Integer or single/half precision destination. */
3361 rd
= VFP_SREG_D(insn
);
3363 VFP_DREG_D(rd
, insn
);
3366 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3367 ((rn
& 0x1e) == 0x4))) {
3368 /* VCVT from int or half precision is always from S reg
3369 * regardless of dp bit. VCVT with immediate frac_bits
3370 * has same format as SREG_M.
3372 rm
= VFP_SREG_M(insn
);
3374 VFP_DREG_M(rm
, insn
);
3377 rn
= VFP_SREG_N(insn
);
3378 if (op
== 15 && rn
== 15) {
3379 /* Double precision destination. */
3380 VFP_DREG_D(rd
, insn
);
3382 rd
= VFP_SREG_D(insn
);
3384 /* NB that we implicitly rely on the encoding for the frac_bits
3385 * in VCVT of fixed to float being the same as that of an SREG_M
3387 rm
= VFP_SREG_M(insn
);
3390 veclen
= s
->vec_len
;
3391 if (op
== 15 && rn
> 3)
3394 /* Shut up compiler warnings. */
3405 /* Figure out what type of vector operation this is. */
3406 if ((rd
& bank_mask
) == 0) {
3411 delta_d
= (s
->vec_stride
>> 1) + 1;
3413 delta_d
= s
->vec_stride
+ 1;
3415 if ((rm
& bank_mask
) == 0) {
3416 /* mixed scalar/vector */
3425 /* Load the initial operands. */
3430 /* Integer source */
3431 gen_mov_F0_vreg(0, rm
);
3436 gen_mov_F0_vreg(dp
, rd
);
3437 gen_mov_F1_vreg(dp
, rm
);
3441 /* Compare with zero */
3442 gen_mov_F0_vreg(dp
, rd
);
3453 /* Source and destination the same. */
3454 gen_mov_F0_vreg(dp
, rd
);
3460 /* VCVTB, VCVTT: only present with the halfprec extension
3461 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3462 * (we choose to UNDEF)
3464 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3465 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3468 if (!extract32(rn
, 1, 1)) {
3469 /* Half precision source. */
3470 gen_mov_F0_vreg(0, rm
);
3473 /* Otherwise fall through */
3475 /* One source operand. */
3476 gen_mov_F0_vreg(dp
, rm
);
3480 /* Two source operands. */
3481 gen_mov_F0_vreg(dp
, rn
);
3482 gen_mov_F1_vreg(dp
, rm
);
3486 /* Perform the calculation. */
3488 case 0: /* VMLA: fd + (fn * fm) */
3489 /* Note that order of inputs to the add matters for NaNs */
3491 gen_mov_F0_vreg(dp
, rd
);
3494 case 1: /* VMLS: fd + -(fn * fm) */
3497 gen_mov_F0_vreg(dp
, rd
);
3500 case 2: /* VNMLS: -fd + (fn * fm) */
3501 /* Note that it isn't valid to replace (-A + B) with (B - A)
3502 * or similar plausible looking simplifications
3503 * because this will give wrong results for NaNs.
3506 gen_mov_F0_vreg(dp
, rd
);
3510 case 3: /* VNMLA: -fd + -(fn * fm) */
3513 gen_mov_F0_vreg(dp
, rd
);
3517 case 4: /* mul: fn * fm */
3520 case 5: /* nmul: -(fn * fm) */
3524 case 6: /* add: fn + fm */
3527 case 7: /* sub: fn - fm */
3530 case 8: /* div: fn / fm */
3533 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3534 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3535 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3536 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3537 /* These are fused multiply-add, and must be done as one
3538 * floating point operation with no rounding between the
3539 * multiplication and addition steps.
3540 * NB that doing the negations here as separate steps is
3541 * correct : an input NaN should come out with its sign bit
3542 * flipped if it is a negated-input.
3544 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3552 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3554 frd
= tcg_temp_new_i64();
3555 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3558 gen_helper_vfp_negd(frd
, frd
);
3560 fpst
= get_fpstatus_ptr(0);
3561 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3562 cpu_F1d
, frd
, fpst
);
3563 tcg_temp_free_ptr(fpst
);
3564 tcg_temp_free_i64(frd
);
3570 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3572 frd
= tcg_temp_new_i32();
3573 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3575 gen_helper_vfp_negs(frd
, frd
);
3577 fpst
= get_fpstatus_ptr(0);
3578 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3579 cpu_F1s
, frd
, fpst
);
3580 tcg_temp_free_ptr(fpst
);
3581 tcg_temp_free_i32(frd
);
3584 case 14: /* fconst */
3585 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3589 n
= (insn
<< 12) & 0x80000000;
3590 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3597 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3604 tcg_gen_movi_i32(cpu_F0s
, n
);
3607 case 15: /* extension space */
3621 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3622 tmp
= gen_vfp_mrs();
3623 tcg_gen_ext16u_i32(tmp
, tmp
);
3625 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3628 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3631 tcg_temp_free_i32(tmp
);
3633 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3634 tmp
= gen_vfp_mrs();
3635 tcg_gen_shri_i32(tmp
, tmp
, 16);
3637 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3640 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3643 tcg_temp_free_i32(tmp
);
3645 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3646 tmp
= tcg_temp_new_i32();
3648 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3651 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3654 gen_mov_F0_vreg(0, rd
);
3655 tmp2
= gen_vfp_mrs();
3656 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3657 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3658 tcg_temp_free_i32(tmp2
);
3661 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3662 tmp
= tcg_temp_new_i32();
3664 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3667 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3670 tcg_gen_shli_i32(tmp
, tmp
, 16);
3671 gen_mov_F0_vreg(0, rd
);
3672 tmp2
= gen_vfp_mrs();
3673 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3674 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3675 tcg_temp_free_i32(tmp2
);
3687 case 11: /* cmpez */
3691 case 12: /* vrintr */
3693 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3695 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3697 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3699 tcg_temp_free_ptr(fpst
);
3702 case 13: /* vrintz */
3704 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3706 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3707 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3709 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3711 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3713 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3714 tcg_temp_free_i32(tcg_rmode
);
3715 tcg_temp_free_ptr(fpst
);
3718 case 14: /* vrintx */
3720 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3722 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3724 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3726 tcg_temp_free_ptr(fpst
);
3729 case 15: /* single<->double conversion */
3731 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3733 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3735 case 16: /* fuito */
3736 gen_vfp_uito(dp
, 0);
3738 case 17: /* fsito */
3739 gen_vfp_sito(dp
, 0);
3741 case 20: /* fshto */
3742 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3745 gen_vfp_shto(dp
, 16 - rm
, 0);
3747 case 21: /* fslto */
3748 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3751 gen_vfp_slto(dp
, 32 - rm
, 0);
3753 case 22: /* fuhto */
3754 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3757 gen_vfp_uhto(dp
, 16 - rm
, 0);
3759 case 23: /* fulto */
3760 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3763 gen_vfp_ulto(dp
, 32 - rm
, 0);
3765 case 24: /* ftoui */
3766 gen_vfp_toui(dp
, 0);
3768 case 25: /* ftouiz */
3769 gen_vfp_touiz(dp
, 0);
3771 case 26: /* ftosi */
3772 gen_vfp_tosi(dp
, 0);
3774 case 27: /* ftosiz */
3775 gen_vfp_tosiz(dp
, 0);
3777 case 28: /* ftosh */
3778 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3781 gen_vfp_tosh(dp
, 16 - rm
, 0);
3783 case 29: /* ftosl */
3784 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3787 gen_vfp_tosl(dp
, 32 - rm
, 0);
3789 case 30: /* ftouh */
3790 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3793 gen_vfp_touh(dp
, 16 - rm
, 0);
3795 case 31: /* ftoul */
3796 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3799 gen_vfp_toul(dp
, 32 - rm
, 0);
3801 default: /* undefined */
3805 default: /* undefined */
3809 /* Write back the result. */
3810 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3811 /* Comparison, do nothing. */
3812 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3813 (rn
& 0x1e) == 0x6)) {
3814 /* VCVT double to int: always integer result.
3815 * VCVT double to half precision is always a single
3818 gen_mov_vreg_F0(0, rd
);
3819 } else if (op
== 15 && rn
== 15) {
3821 gen_mov_vreg_F0(!dp
, rd
);
3823 gen_mov_vreg_F0(dp
, rd
);
3826 /* break out of the loop if we have finished */
3830 if (op
== 15 && delta_m
== 0) {
3831 /* single source one-many */
3833 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3835 gen_mov_vreg_F0(dp
, rd
);
3839 /* Setup the next operands. */
3841 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3845 /* One source operand. */
3846 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3848 gen_mov_F0_vreg(dp
, rm
);
3850 /* Two source operands. */
3851 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3853 gen_mov_F0_vreg(dp
, rn
);
3855 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3857 gen_mov_F1_vreg(dp
, rm
);
3865 if ((insn
& 0x03e00000) == 0x00400000) {
3866 /* two-register transfer */
3867 rn
= (insn
>> 16) & 0xf;
3868 rd
= (insn
>> 12) & 0xf;
3870 VFP_DREG_M(rm
, insn
);
3872 rm
= VFP_SREG_M(insn
);
3875 if (insn
& ARM_CP_RW_BIT
) {
3878 gen_mov_F0_vreg(0, rm
* 2);
3879 tmp
= gen_vfp_mrs();
3880 store_reg(s
, rd
, tmp
);
3881 gen_mov_F0_vreg(0, rm
* 2 + 1);
3882 tmp
= gen_vfp_mrs();
3883 store_reg(s
, rn
, tmp
);
3885 gen_mov_F0_vreg(0, rm
);
3886 tmp
= gen_vfp_mrs();
3887 store_reg(s
, rd
, tmp
);
3888 gen_mov_F0_vreg(0, rm
+ 1);
3889 tmp
= gen_vfp_mrs();
3890 store_reg(s
, rn
, tmp
);
3895 tmp
= load_reg(s
, rd
);
3897 gen_mov_vreg_F0(0, rm
* 2);
3898 tmp
= load_reg(s
, rn
);
3900 gen_mov_vreg_F0(0, rm
* 2 + 1);
3902 tmp
= load_reg(s
, rd
);
3904 gen_mov_vreg_F0(0, rm
);
3905 tmp
= load_reg(s
, rn
);
3907 gen_mov_vreg_F0(0, rm
+ 1);
3912 rn
= (insn
>> 16) & 0xf;
3914 VFP_DREG_D(rd
, insn
);
3916 rd
= VFP_SREG_D(insn
);
3917 if ((insn
& 0x01200000) == 0x01000000) {
3918 /* Single load/store */
3919 offset
= (insn
& 0xff) << 2;
3920 if ((insn
& (1 << 23)) == 0)
3922 if (s
->thumb
&& rn
== 15) {
3923 /* This is actually UNPREDICTABLE */
3924 addr
= tcg_temp_new_i32();
3925 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3927 addr
= load_reg(s
, rn
);
3929 tcg_gen_addi_i32(addr
, addr
, offset
);
3930 if (insn
& (1 << 20)) {
3931 gen_vfp_ld(s
, dp
, addr
);
3932 gen_mov_vreg_F0(dp
, rd
);
3934 gen_mov_F0_vreg(dp
, rd
);
3935 gen_vfp_st(s
, dp
, addr
);
3937 tcg_temp_free_i32(addr
);
3939 /* load/store multiple */
3940 int w
= insn
& (1 << 21);
3942 n
= (insn
>> 1) & 0x7f;
3946 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3947 /* P == U , W == 1 => UNDEF */
3950 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3951 /* UNPREDICTABLE cases for bad immediates: we choose to
3952 * UNDEF to avoid generating huge numbers of TCG ops
3956 if (rn
== 15 && w
) {
3957 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3961 if (s
->thumb
&& rn
== 15) {
3962 /* This is actually UNPREDICTABLE */
3963 addr
= tcg_temp_new_i32();
3964 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3966 addr
= load_reg(s
, rn
);
3968 if (insn
& (1 << 24)) /* pre-decrement */
3969 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3975 for (i
= 0; i
< n
; i
++) {
3976 if (insn
& ARM_CP_RW_BIT
) {
3978 gen_vfp_ld(s
, dp
, addr
);
3979 gen_mov_vreg_F0(dp
, rd
+ i
);
3982 gen_mov_F0_vreg(dp
, rd
+ i
);
3983 gen_vfp_st(s
, dp
, addr
);
3985 tcg_gen_addi_i32(addr
, addr
, offset
);
3989 if (insn
& (1 << 24))
3990 offset
= -offset
* n
;
3991 else if (dp
&& (insn
& 1))
3997 tcg_gen_addi_i32(addr
, addr
, offset
);
3998 store_reg(s
, rn
, addr
);
4000 tcg_temp_free_i32(addr
);
4006 /* Should never happen. */
4012 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4014 #ifndef CONFIG_USER_ONLY
4015 return (s
->tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4016 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4022 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4024 if (use_goto_tb(s
, dest
)) {
4026 gen_set_pc_im(s
, dest
);
4027 tcg_gen_exit_tb((uintptr_t)s
->tb
+ n
);
4029 gen_set_pc_im(s
, dest
);
4034 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4036 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
4037 /* An indirect jump so that we still trigger the debug exception. */
4042 gen_goto_tb(s
, 0, dest
);
4043 s
->is_jmp
= DISAS_TB_JUMP
;
4047 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4050 tcg_gen_sari_i32(t0
, t0
, 16);
4054 tcg_gen_sari_i32(t1
, t1
, 16);
4057 tcg_gen_mul_i32(t0
, t0
, t1
);
4060 /* Return the mask of PSR bits set by a MSR instruction. */
4061 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4066 if (flags
& (1 << 0))
4068 if (flags
& (1 << 1))
4070 if (flags
& (1 << 2))
4072 if (flags
& (1 << 3))
4075 /* Mask out undefined bits. */
4076 mask
&= ~CPSR_RESERVED
;
4077 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4080 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4081 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4083 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4084 mask
&= ~(CPSR_E
| CPSR_GE
);
4086 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4089 /* Mask out execution state and reserved bits. */
4091 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4093 /* Mask out privileged bits. */
4099 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4100 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4104 /* ??? This is also undefined in system mode. */
4108 tmp
= load_cpu_field(spsr
);
4109 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4110 tcg_gen_andi_i32(t0
, t0
, mask
);
4111 tcg_gen_or_i32(tmp
, tmp
, t0
);
4112 store_cpu_field(tmp
, spsr
);
4114 gen_set_cpsr(t0
, mask
);
4116 tcg_temp_free_i32(t0
);
4121 /* Returns nonzero if access to the PSR is not permitted. */
4122 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4125 tmp
= tcg_temp_new_i32();
4126 tcg_gen_movi_i32(tmp
, val
);
4127 return gen_set_psr(s
, mask
, spsr
, tmp
);
4130 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4131 int *tgtmode
, int *regno
)
4133 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4134 * the target mode and register number, and identify the various
4135 * unpredictable cases.
4136 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4137 * + executed in user mode
4138 * + using R15 as the src/dest register
4139 * + accessing an unimplemented register
4140 * + accessing a register that's inaccessible at current PL/security state*
4141 * + accessing a register that you could access with a different insn
4142 * We choose to UNDEF in all these cases.
4143 * Since we don't know which of the various AArch32 modes we are in
4144 * we have to defer some checks to runtime.
4145 * Accesses to Monitor mode registers from Secure EL1 (which implies
4146 * that EL3 is AArch64) must trap to EL3.
4148 * If the access checks fail this function will emit code to take
4149 * an exception and return false. Otherwise it will return true,
4150 * and set *tgtmode and *regno appropriately.
4152 int exc_target
= default_exception_el(s
);
4154 /* These instructions are present only in ARMv8, or in ARMv7 with the
4155 * Virtualization Extensions.
4157 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4158 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4162 if (IS_USER(s
) || rn
== 15) {
4166 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4167 * of registers into (r, sysm).
4170 /* SPSRs for other modes */
4172 case 0xe: /* SPSR_fiq */
4173 *tgtmode
= ARM_CPU_MODE_FIQ
;
4175 case 0x10: /* SPSR_irq */
4176 *tgtmode
= ARM_CPU_MODE_IRQ
;
4178 case 0x12: /* SPSR_svc */
4179 *tgtmode
= ARM_CPU_MODE_SVC
;
4181 case 0x14: /* SPSR_abt */
4182 *tgtmode
= ARM_CPU_MODE_ABT
;
4184 case 0x16: /* SPSR_und */
4185 *tgtmode
= ARM_CPU_MODE_UND
;
4187 case 0x1c: /* SPSR_mon */
4188 *tgtmode
= ARM_CPU_MODE_MON
;
4190 case 0x1e: /* SPSR_hyp */
4191 *tgtmode
= ARM_CPU_MODE_HYP
;
4193 default: /* unallocated */
4196 /* We arbitrarily assign SPSR a register number of 16. */
4199 /* general purpose registers for other modes */
4201 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4202 *tgtmode
= ARM_CPU_MODE_USR
;
4205 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4206 *tgtmode
= ARM_CPU_MODE_FIQ
;
4209 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4210 *tgtmode
= ARM_CPU_MODE_IRQ
;
4211 *regno
= sysm
& 1 ? 13 : 14;
4213 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4214 *tgtmode
= ARM_CPU_MODE_SVC
;
4215 *regno
= sysm
& 1 ? 13 : 14;
4217 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4218 *tgtmode
= ARM_CPU_MODE_ABT
;
4219 *regno
= sysm
& 1 ? 13 : 14;
4221 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4222 *tgtmode
= ARM_CPU_MODE_UND
;
4223 *regno
= sysm
& 1 ? 13 : 14;
4225 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4226 *tgtmode
= ARM_CPU_MODE_MON
;
4227 *regno
= sysm
& 1 ? 13 : 14;
4229 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4230 *tgtmode
= ARM_CPU_MODE_HYP
;
4231 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4232 *regno
= sysm
& 1 ? 13 : 17;
4234 default: /* unallocated */
4239 /* Catch the 'accessing inaccessible register' cases we can detect
4240 * at translate time.
4243 case ARM_CPU_MODE_MON
:
4244 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4247 if (s
->current_el
== 1) {
4248 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4249 * then accesses to Mon registers trap to EL3
4255 case ARM_CPU_MODE_HYP
:
4256 /* Note that we can forbid accesses from EL2 here because they
4257 * must be from Hyp mode itself
4259 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4270 /* If we get here then some access check did not pass */
4271 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4275 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4277 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4278 int tgtmode
= 0, regno
= 0;
4280 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4284 /* Sync state because msr_banked() can raise exceptions */
4285 gen_set_condexec(s
);
4286 gen_set_pc_im(s
, s
->pc
- 4);
4287 tcg_reg
= load_reg(s
, rn
);
4288 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4289 tcg_regno
= tcg_const_i32(regno
);
4290 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4291 tcg_temp_free_i32(tcg_tgtmode
);
4292 tcg_temp_free_i32(tcg_regno
);
4293 tcg_temp_free_i32(tcg_reg
);
4294 s
->is_jmp
= DISAS_UPDATE
;
4297 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4299 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4300 int tgtmode
= 0, regno
= 0;
4302 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4306 /* Sync state because mrs_banked() can raise exceptions */
4307 gen_set_condexec(s
);
4308 gen_set_pc_im(s
, s
->pc
- 4);
4309 tcg_reg
= tcg_temp_new_i32();
4310 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4311 tcg_regno
= tcg_const_i32(regno
);
4312 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4313 tcg_temp_free_i32(tcg_tgtmode
);
4314 tcg_temp_free_i32(tcg_regno
);
4315 store_reg(s
, rn
, tcg_reg
);
4316 s
->is_jmp
= DISAS_UPDATE
;
4319 /* Store value to PC as for an exception return (ie don't
4320 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4321 * will do the masking based on the new value of the Thumb bit.
4323 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
4325 tcg_gen_mov_i32(cpu_R
[15], pc
);
4326 tcg_temp_free_i32(pc
);
4329 /* Generate a v6 exception return. Marks both values as dead. */
4330 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4332 store_pc_exc_ret(s
, pc
);
4333 /* The cpsr_write_eret helper will mask the low bits of PC
4334 * appropriately depending on the new Thumb bit, so it must
4335 * be called after storing the new PC.
4337 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4338 tcg_temp_free_i32(cpsr
);
4339 s
->is_jmp
= DISAS_JUMP
;
4342 /* Generate an old-style exception return. Marks pc as dead. */
4343 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4345 gen_rfe(s
, pc
, load_cpu_field(spsr
));
4348 static void gen_nop_hint(DisasContext
*s
, int val
)
4352 gen_set_pc_im(s
, s
->pc
);
4353 s
->is_jmp
= DISAS_YIELD
;
4356 gen_set_pc_im(s
, s
->pc
);
4357 s
->is_jmp
= DISAS_WFI
;
4360 gen_set_pc_im(s
, s
->pc
);
4361 s
->is_jmp
= DISAS_WFE
;
4365 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4371 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4373 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4376 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4377 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4378 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4383 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4386 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4387 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4388 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4393 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4394 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4395 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4396 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4397 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4399 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4400 switch ((size << 1) | u) { \
4402 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4405 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4408 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4411 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4414 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4417 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4419 default: return 1; \
4422 #define GEN_NEON_INTEGER_OP(name) do { \
4423 switch ((size << 1) | u) { \
4425 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4428 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4431 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4434 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4437 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4440 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4442 default: return 1; \
4445 static TCGv_i32
neon_load_scratch(int scratch
)
4447 TCGv_i32 tmp
= tcg_temp_new_i32();
4448 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4452 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4454 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4455 tcg_temp_free_i32(var
);
4458 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4462 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4464 gen_neon_dup_high16(tmp
);
4466 gen_neon_dup_low16(tmp
);
4469 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4474 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4477 if (!q
&& size
== 2) {
4480 tmp
= tcg_const_i32(rd
);
4481 tmp2
= tcg_const_i32(rm
);
4485 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4488 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4491 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4499 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4502 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4508 tcg_temp_free_i32(tmp
);
4509 tcg_temp_free_i32(tmp2
);
4513 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4516 if (!q
&& size
== 2) {
4519 tmp
= tcg_const_i32(rd
);
4520 tmp2
= tcg_const_i32(rm
);
4524 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4527 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4530 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4538 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4541 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4547 tcg_temp_free_i32(tmp
);
4548 tcg_temp_free_i32(tmp2
);
4552 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4556 rd
= tcg_temp_new_i32();
4557 tmp
= tcg_temp_new_i32();
4559 tcg_gen_shli_i32(rd
, t0
, 8);
4560 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4561 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4562 tcg_gen_or_i32(rd
, rd
, tmp
);
4564 tcg_gen_shri_i32(t1
, t1
, 8);
4565 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4566 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4567 tcg_gen_or_i32(t1
, t1
, tmp
);
4568 tcg_gen_mov_i32(t0
, rd
);
4570 tcg_temp_free_i32(tmp
);
4571 tcg_temp_free_i32(rd
);
4574 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4578 rd
= tcg_temp_new_i32();
4579 tmp
= tcg_temp_new_i32();
4581 tcg_gen_shli_i32(rd
, t0
, 16);
4582 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4583 tcg_gen_or_i32(rd
, rd
, tmp
);
4584 tcg_gen_shri_i32(t1
, t1
, 16);
4585 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4586 tcg_gen_or_i32(t1
, t1
, tmp
);
4587 tcg_gen_mov_i32(t0
, rd
);
4589 tcg_temp_free_i32(tmp
);
4590 tcg_temp_free_i32(rd
);
4598 } neon_ls_element_type
[11] = {
4612 /* Translate a NEON load/store element instruction. Return nonzero if the
4613 instruction is invalid. */
4614 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4633 /* FIXME: this access check should not take precedence over UNDEF
4634 * for invalid encodings; we will generate incorrect syndrome information
4635 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4637 if (s
->fp_excp_el
) {
4638 gen_exception_insn(s
, 4, EXCP_UDEF
,
4639 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4643 if (!s
->vfp_enabled
)
4645 VFP_DREG_D(rd
, insn
);
4646 rn
= (insn
>> 16) & 0xf;
4648 load
= (insn
& (1 << 21)) != 0;
4649 if ((insn
& (1 << 23)) == 0) {
4650 /* Load store all elements. */
4651 op
= (insn
>> 8) & 0xf;
4652 size
= (insn
>> 6) & 3;
4655 /* Catch UNDEF cases for bad values of align field */
4658 if (((insn
>> 5) & 1) == 1) {
4663 if (((insn
>> 4) & 3) == 3) {
4670 nregs
= neon_ls_element_type
[op
].nregs
;
4671 interleave
= neon_ls_element_type
[op
].interleave
;
4672 spacing
= neon_ls_element_type
[op
].spacing
;
4673 if (size
== 3 && (interleave
| spacing
) != 1)
4675 addr
= tcg_temp_new_i32();
4676 load_reg_var(s
, addr
, rn
);
4677 stride
= (1 << size
) * interleave
;
4678 for (reg
= 0; reg
< nregs
; reg
++) {
4679 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4680 load_reg_var(s
, addr
, rn
);
4681 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4682 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4683 load_reg_var(s
, addr
, rn
);
4684 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4687 tmp64
= tcg_temp_new_i64();
4689 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4690 neon_store_reg64(tmp64
, rd
);
4692 neon_load_reg64(tmp64
, rd
);
4693 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4695 tcg_temp_free_i64(tmp64
);
4696 tcg_gen_addi_i32(addr
, addr
, stride
);
4698 for (pass
= 0; pass
< 2; pass
++) {
4701 tmp
= tcg_temp_new_i32();
4702 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4703 neon_store_reg(rd
, pass
, tmp
);
4705 tmp
= neon_load_reg(rd
, pass
);
4706 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4707 tcg_temp_free_i32(tmp
);
4709 tcg_gen_addi_i32(addr
, addr
, stride
);
4710 } else if (size
== 1) {
4712 tmp
= tcg_temp_new_i32();
4713 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4714 tcg_gen_addi_i32(addr
, addr
, stride
);
4715 tmp2
= tcg_temp_new_i32();
4716 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4717 tcg_gen_addi_i32(addr
, addr
, stride
);
4718 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4719 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4720 tcg_temp_free_i32(tmp2
);
4721 neon_store_reg(rd
, pass
, tmp
);
4723 tmp
= neon_load_reg(rd
, pass
);
4724 tmp2
= tcg_temp_new_i32();
4725 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4726 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4727 tcg_temp_free_i32(tmp
);
4728 tcg_gen_addi_i32(addr
, addr
, stride
);
4729 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4730 tcg_temp_free_i32(tmp2
);
4731 tcg_gen_addi_i32(addr
, addr
, stride
);
4733 } else /* size == 0 */ {
4735 TCGV_UNUSED_I32(tmp2
);
4736 for (n
= 0; n
< 4; n
++) {
4737 tmp
= tcg_temp_new_i32();
4738 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4739 tcg_gen_addi_i32(addr
, addr
, stride
);
4743 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4744 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4745 tcg_temp_free_i32(tmp
);
4748 neon_store_reg(rd
, pass
, tmp2
);
4750 tmp2
= neon_load_reg(rd
, pass
);
4751 for (n
= 0; n
< 4; n
++) {
4752 tmp
= tcg_temp_new_i32();
4754 tcg_gen_mov_i32(tmp
, tmp2
);
4756 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4758 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4759 tcg_temp_free_i32(tmp
);
4760 tcg_gen_addi_i32(addr
, addr
, stride
);
4762 tcg_temp_free_i32(tmp2
);
4769 tcg_temp_free_i32(addr
);
4772 size
= (insn
>> 10) & 3;
4774 /* Load single element to all lanes. */
4775 int a
= (insn
>> 4) & 1;
4779 size
= (insn
>> 6) & 3;
4780 nregs
= ((insn
>> 8) & 3) + 1;
4783 if (nregs
!= 4 || a
== 0) {
4786 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4789 if (nregs
== 1 && a
== 1 && size
== 0) {
4792 if (nregs
== 3 && a
== 1) {
4795 addr
= tcg_temp_new_i32();
4796 load_reg_var(s
, addr
, rn
);
4798 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4799 tmp
= gen_load_and_replicate(s
, addr
, size
);
4800 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4801 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4802 if (insn
& (1 << 5)) {
4803 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4804 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4806 tcg_temp_free_i32(tmp
);
4808 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4809 stride
= (insn
& (1 << 5)) ? 2 : 1;
4810 for (reg
= 0; reg
< nregs
; reg
++) {
4811 tmp
= gen_load_and_replicate(s
, addr
, size
);
4812 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4813 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4814 tcg_temp_free_i32(tmp
);
4815 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4819 tcg_temp_free_i32(addr
);
4820 stride
= (1 << size
) * nregs
;
4822 /* Single element. */
4823 int idx
= (insn
>> 4) & 0xf;
4824 pass
= (insn
>> 7) & 1;
4827 shift
= ((insn
>> 5) & 3) * 8;
4831 shift
= ((insn
>> 6) & 1) * 16;
4832 stride
= (insn
& (1 << 5)) ? 2 : 1;
4836 stride
= (insn
& (1 << 6)) ? 2 : 1;
4841 nregs
= ((insn
>> 8) & 3) + 1;
4842 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4845 if (((idx
& (1 << size
)) != 0) ||
4846 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4851 if ((idx
& 1) != 0) {
4856 if (size
== 2 && (idx
& 2) != 0) {
4861 if ((size
== 2) && ((idx
& 3) == 3)) {
4868 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4869 /* Attempts to write off the end of the register file
4870 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4871 * the neon_load_reg() would write off the end of the array.
4875 addr
= tcg_temp_new_i32();
4876 load_reg_var(s
, addr
, rn
);
4877 for (reg
= 0; reg
< nregs
; reg
++) {
4879 tmp
= tcg_temp_new_i32();
4882 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4885 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4888 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4890 default: /* Avoid compiler warnings. */
4894 tmp2
= neon_load_reg(rd
, pass
);
4895 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4896 shift
, size
? 16 : 8);
4897 tcg_temp_free_i32(tmp2
);
4899 neon_store_reg(rd
, pass
, tmp
);
4900 } else { /* Store */
4901 tmp
= neon_load_reg(rd
, pass
);
4903 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4906 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4909 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4912 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4915 tcg_temp_free_i32(tmp
);
4918 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4920 tcg_temp_free_i32(addr
);
4921 stride
= nregs
* (1 << size
);
4927 base
= load_reg(s
, rn
);
4929 tcg_gen_addi_i32(base
, base
, stride
);
4932 index
= load_reg(s
, rm
);
4933 tcg_gen_add_i32(base
, base
, index
);
4934 tcg_temp_free_i32(index
);
4936 store_reg(s
, rn
, base
);
4941 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4942 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4944 tcg_gen_and_i32(t
, t
, c
);
4945 tcg_gen_andc_i32(f
, f
, c
);
4946 tcg_gen_or_i32(dest
, t
, f
);
4949 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4952 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4953 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4954 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4959 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4962 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4963 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4964 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4969 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4972 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4973 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4974 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4979 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4982 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4983 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4984 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4989 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4995 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4996 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5001 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5002 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5009 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5010 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5015 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5016 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5023 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5027 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5028 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5029 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5034 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5035 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5036 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5040 tcg_temp_free_i32(src
);
5043 static inline void gen_neon_addl(int size
)
5046 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5047 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5048 case 2: tcg_gen_add_i64(CPU_V001
); break;
5053 static inline void gen_neon_subl(int size
)
5056 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5057 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5058 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5063 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5066 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5067 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5069 tcg_gen_neg_i64(var
, var
);
5075 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5078 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5079 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5084 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5089 switch ((size
<< 1) | u
) {
5090 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5091 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5092 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5093 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5095 tmp
= gen_muls_i64_i32(a
, b
);
5096 tcg_gen_mov_i64(dest
, tmp
);
5097 tcg_temp_free_i64(tmp
);
5100 tmp
= gen_mulu_i64_i32(a
, b
);
5101 tcg_gen_mov_i64(dest
, tmp
);
5102 tcg_temp_free_i64(tmp
);
5107 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5108 Don't forget to clean them now. */
5110 tcg_temp_free_i32(a
);
5111 tcg_temp_free_i32(b
);
5115 static void gen_neon_narrow_op(int op
, int u
, int size
,
5116 TCGv_i32 dest
, TCGv_i64 src
)
5120 gen_neon_unarrow_sats(size
, dest
, src
);
5122 gen_neon_narrow(size
, dest
, src
);
5126 gen_neon_narrow_satu(size
, dest
, src
);
5128 gen_neon_narrow_sats(size
, dest
, src
);
5133 /* Symbolic constants for op fields for Neon 3-register same-length.
5134 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5137 #define NEON_3R_VHADD 0
5138 #define NEON_3R_VQADD 1
5139 #define NEON_3R_VRHADD 2
5140 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5141 #define NEON_3R_VHSUB 4
5142 #define NEON_3R_VQSUB 5
5143 #define NEON_3R_VCGT 6
5144 #define NEON_3R_VCGE 7
5145 #define NEON_3R_VSHL 8
5146 #define NEON_3R_VQSHL 9
5147 #define NEON_3R_VRSHL 10
5148 #define NEON_3R_VQRSHL 11
5149 #define NEON_3R_VMAX 12
5150 #define NEON_3R_VMIN 13
5151 #define NEON_3R_VABD 14
5152 #define NEON_3R_VABA 15
5153 #define NEON_3R_VADD_VSUB 16
5154 #define NEON_3R_VTST_VCEQ 17
5155 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5156 #define NEON_3R_VMUL 19
5157 #define NEON_3R_VPMAX 20
5158 #define NEON_3R_VPMIN 21
5159 #define NEON_3R_VQDMULH_VQRDMULH 22
5160 #define NEON_3R_VPADD 23
5161 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5162 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5163 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5164 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5165 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5166 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5167 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5168 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5170 static const uint8_t neon_3r_sizes
[] = {
5171 [NEON_3R_VHADD
] = 0x7,
5172 [NEON_3R_VQADD
] = 0xf,
5173 [NEON_3R_VRHADD
] = 0x7,
5174 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5175 [NEON_3R_VHSUB
] = 0x7,
5176 [NEON_3R_VQSUB
] = 0xf,
5177 [NEON_3R_VCGT
] = 0x7,
5178 [NEON_3R_VCGE
] = 0x7,
5179 [NEON_3R_VSHL
] = 0xf,
5180 [NEON_3R_VQSHL
] = 0xf,
5181 [NEON_3R_VRSHL
] = 0xf,
5182 [NEON_3R_VQRSHL
] = 0xf,
5183 [NEON_3R_VMAX
] = 0x7,
5184 [NEON_3R_VMIN
] = 0x7,
5185 [NEON_3R_VABD
] = 0x7,
5186 [NEON_3R_VABA
] = 0x7,
5187 [NEON_3R_VADD_VSUB
] = 0xf,
5188 [NEON_3R_VTST_VCEQ
] = 0x7,
5189 [NEON_3R_VML
] = 0x7,
5190 [NEON_3R_VMUL
] = 0x7,
5191 [NEON_3R_VPMAX
] = 0x7,
5192 [NEON_3R_VPMIN
] = 0x7,
5193 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5194 [NEON_3R_VPADD
] = 0x7,
5195 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5196 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5197 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5198 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5199 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5200 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5201 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5202 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5205 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5206 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5209 #define NEON_2RM_VREV64 0
5210 #define NEON_2RM_VREV32 1
5211 #define NEON_2RM_VREV16 2
5212 #define NEON_2RM_VPADDL 4
5213 #define NEON_2RM_VPADDL_U 5
5214 #define NEON_2RM_AESE 6 /* Includes AESD */
5215 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5216 #define NEON_2RM_VCLS 8
5217 #define NEON_2RM_VCLZ 9
5218 #define NEON_2RM_VCNT 10
5219 #define NEON_2RM_VMVN 11
5220 #define NEON_2RM_VPADAL 12
5221 #define NEON_2RM_VPADAL_U 13
5222 #define NEON_2RM_VQABS 14
5223 #define NEON_2RM_VQNEG 15
5224 #define NEON_2RM_VCGT0 16
5225 #define NEON_2RM_VCGE0 17
5226 #define NEON_2RM_VCEQ0 18
5227 #define NEON_2RM_VCLE0 19
5228 #define NEON_2RM_VCLT0 20
5229 #define NEON_2RM_SHA1H 21
5230 #define NEON_2RM_VABS 22
5231 #define NEON_2RM_VNEG 23
5232 #define NEON_2RM_VCGT0_F 24
5233 #define NEON_2RM_VCGE0_F 25
5234 #define NEON_2RM_VCEQ0_F 26
5235 #define NEON_2RM_VCLE0_F 27
5236 #define NEON_2RM_VCLT0_F 28
5237 #define NEON_2RM_VABS_F 30
5238 #define NEON_2RM_VNEG_F 31
5239 #define NEON_2RM_VSWP 32
5240 #define NEON_2RM_VTRN 33
5241 #define NEON_2RM_VUZP 34
5242 #define NEON_2RM_VZIP 35
5243 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5244 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5245 #define NEON_2RM_VSHLL 38
5246 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5247 #define NEON_2RM_VRINTN 40
5248 #define NEON_2RM_VRINTX 41
5249 #define NEON_2RM_VRINTA 42
5250 #define NEON_2RM_VRINTZ 43
5251 #define NEON_2RM_VCVT_F16_F32 44
5252 #define NEON_2RM_VRINTM 45
5253 #define NEON_2RM_VCVT_F32_F16 46
5254 #define NEON_2RM_VRINTP 47
5255 #define NEON_2RM_VCVTAU 48
5256 #define NEON_2RM_VCVTAS 49
5257 #define NEON_2RM_VCVTNU 50
5258 #define NEON_2RM_VCVTNS 51
5259 #define NEON_2RM_VCVTPU 52
5260 #define NEON_2RM_VCVTPS 53
5261 #define NEON_2RM_VCVTMU 54
5262 #define NEON_2RM_VCVTMS 55
5263 #define NEON_2RM_VRECPE 56
5264 #define NEON_2RM_VRSQRTE 57
5265 #define NEON_2RM_VRECPE_F 58
5266 #define NEON_2RM_VRSQRTE_F 59
5267 #define NEON_2RM_VCVT_FS 60
5268 #define NEON_2RM_VCVT_FU 61
5269 #define NEON_2RM_VCVT_SF 62
5270 #define NEON_2RM_VCVT_UF 63
5272 static int neon_2rm_is_float_op(int op
)
5274 /* Return true if this neon 2reg-misc op is float-to-float */
5275 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5276 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5277 op
== NEON_2RM_VRINTM
||
5278 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5279 op
>= NEON_2RM_VRECPE_F
);
5282 static bool neon_2rm_is_v8_op(int op
)
5284 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5286 case NEON_2RM_VRINTN
:
5287 case NEON_2RM_VRINTA
:
5288 case NEON_2RM_VRINTM
:
5289 case NEON_2RM_VRINTP
:
5290 case NEON_2RM_VRINTZ
:
5291 case NEON_2RM_VRINTX
:
5292 case NEON_2RM_VCVTAU
:
5293 case NEON_2RM_VCVTAS
:
5294 case NEON_2RM_VCVTNU
:
5295 case NEON_2RM_VCVTNS
:
5296 case NEON_2RM_VCVTPU
:
5297 case NEON_2RM_VCVTPS
:
5298 case NEON_2RM_VCVTMU
:
5299 case NEON_2RM_VCVTMS
:
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 (neon_2rm_is_v8_op(op
) &&
6794 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6797 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6798 q
&& ((rm
| rd
) & 1)) {
6802 case NEON_2RM_VREV64
:
6803 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6804 tmp
= neon_load_reg(rm
, pass
* 2);
6805 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6807 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6808 case 1: gen_swap_half(tmp
); break;
6809 case 2: /* no-op */ break;
6812 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6814 neon_store_reg(rd
, pass
* 2, tmp2
);
6817 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6818 case 1: gen_swap_half(tmp2
); break;
6821 neon_store_reg(rd
, pass
* 2, tmp2
);
6825 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6826 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6827 for (pass
= 0; pass
< q
+ 1; pass
++) {
6828 tmp
= neon_load_reg(rm
, pass
* 2);
6829 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6830 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6831 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6833 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6834 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6835 case 2: tcg_gen_add_i64(CPU_V001
); break;
6838 if (op
>= NEON_2RM_VPADAL
) {
6840 neon_load_reg64(cpu_V1
, rd
+ pass
);
6841 gen_neon_addl(size
);
6843 neon_store_reg64(cpu_V0
, rd
+ pass
);
6849 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6850 tmp
= neon_load_reg(rm
, n
);
6851 tmp2
= neon_load_reg(rd
, n
+ 1);
6852 neon_store_reg(rm
, n
, tmp2
);
6853 neon_store_reg(rd
, n
+ 1, tmp
);
6860 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6865 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6869 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6870 /* also VQMOVUN; op field and mnemonics don't line up */
6874 TCGV_UNUSED_I32(tmp2
);
6875 for (pass
= 0; pass
< 2; pass
++) {
6876 neon_load_reg64(cpu_V0
, rm
+ pass
);
6877 tmp
= tcg_temp_new_i32();
6878 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6883 neon_store_reg(rd
, 0, tmp2
);
6884 neon_store_reg(rd
, 1, tmp
);
6888 case NEON_2RM_VSHLL
:
6889 if (q
|| (rd
& 1)) {
6892 tmp
= neon_load_reg(rm
, 0);
6893 tmp2
= neon_load_reg(rm
, 1);
6894 for (pass
= 0; pass
< 2; pass
++) {
6897 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6898 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6899 neon_store_reg64(cpu_V0
, rd
+ pass
);
6902 case NEON_2RM_VCVT_F16_F32
:
6903 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6907 tmp
= tcg_temp_new_i32();
6908 tmp2
= tcg_temp_new_i32();
6909 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6910 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6911 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6912 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6913 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6914 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6915 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6916 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6917 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6918 neon_store_reg(rd
, 0, tmp2
);
6919 tmp2
= tcg_temp_new_i32();
6920 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6921 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6922 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6923 neon_store_reg(rd
, 1, tmp2
);
6924 tcg_temp_free_i32(tmp
);
6926 case NEON_2RM_VCVT_F32_F16
:
6927 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6931 tmp3
= tcg_temp_new_i32();
6932 tmp
= neon_load_reg(rm
, 0);
6933 tmp2
= neon_load_reg(rm
, 1);
6934 tcg_gen_ext16u_i32(tmp3
, tmp
);
6935 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6936 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6937 tcg_gen_shri_i32(tmp3
, tmp
, 16);
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
, 1));
6940 tcg_temp_free_i32(tmp
);
6941 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6942 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6943 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6944 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6945 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6946 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6947 tcg_temp_free_i32(tmp2
);
6948 tcg_temp_free_i32(tmp3
);
6950 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6951 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6952 || ((rm
| rd
) & 1)) {
6955 tmp
= tcg_const_i32(rd
);
6956 tmp2
= tcg_const_i32(rm
);
6958 /* Bit 6 is the lowest opcode bit; it distinguishes between
6959 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6961 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6963 if (op
== NEON_2RM_AESE
) {
6964 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6966 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6968 tcg_temp_free_i32(tmp
);
6969 tcg_temp_free_i32(tmp2
);
6970 tcg_temp_free_i32(tmp3
);
6972 case NEON_2RM_SHA1H
:
6973 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
6974 || ((rm
| rd
) & 1)) {
6977 tmp
= tcg_const_i32(rd
);
6978 tmp2
= tcg_const_i32(rm
);
6980 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6982 tcg_temp_free_i32(tmp
);
6983 tcg_temp_free_i32(tmp2
);
6985 case NEON_2RM_SHA1SU1
:
6986 if ((rm
| rd
) & 1) {
6989 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6991 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
6994 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
6997 tmp
= tcg_const_i32(rd
);
6998 tmp2
= tcg_const_i32(rm
);
7000 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
7002 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7004 tcg_temp_free_i32(tmp
);
7005 tcg_temp_free_i32(tmp2
);
7009 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7010 if (neon_2rm_is_float_op(op
)) {
7011 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7012 neon_reg_offset(rm
, pass
));
7013 TCGV_UNUSED_I32(tmp
);
7015 tmp
= neon_load_reg(rm
, pass
);
7018 case NEON_2RM_VREV32
:
7020 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7021 case 1: gen_swap_half(tmp
); break;
7025 case NEON_2RM_VREV16
:
7030 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7031 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7032 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7038 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7039 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7040 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
7045 gen_helper_neon_cnt_u8(tmp
, tmp
);
7048 tcg_gen_not_i32(tmp
, tmp
);
7050 case NEON_2RM_VQABS
:
7053 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7056 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7059 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7064 case NEON_2RM_VQNEG
:
7067 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7070 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7073 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7078 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7079 tmp2
= tcg_const_i32(0);
7081 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7082 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7083 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7086 tcg_temp_free_i32(tmp2
);
7087 if (op
== NEON_2RM_VCLE0
) {
7088 tcg_gen_not_i32(tmp
, tmp
);
7091 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7092 tmp2
= tcg_const_i32(0);
7094 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7095 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7096 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7099 tcg_temp_free_i32(tmp2
);
7100 if (op
== NEON_2RM_VCLT0
) {
7101 tcg_gen_not_i32(tmp
, tmp
);
7104 case NEON_2RM_VCEQ0
:
7105 tmp2
= tcg_const_i32(0);
7107 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7108 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7109 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7112 tcg_temp_free_i32(tmp2
);
7116 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7117 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7118 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7123 tmp2
= tcg_const_i32(0);
7124 gen_neon_rsb(size
, tmp
, tmp2
);
7125 tcg_temp_free_i32(tmp2
);
7127 case NEON_2RM_VCGT0_F
:
7129 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7130 tmp2
= tcg_const_i32(0);
7131 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7132 tcg_temp_free_i32(tmp2
);
7133 tcg_temp_free_ptr(fpstatus
);
7136 case NEON_2RM_VCGE0_F
:
7138 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7139 tmp2
= tcg_const_i32(0);
7140 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7141 tcg_temp_free_i32(tmp2
);
7142 tcg_temp_free_ptr(fpstatus
);
7145 case NEON_2RM_VCEQ0_F
:
7147 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7148 tmp2
= tcg_const_i32(0);
7149 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7150 tcg_temp_free_i32(tmp2
);
7151 tcg_temp_free_ptr(fpstatus
);
7154 case NEON_2RM_VCLE0_F
:
7156 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7157 tmp2
= tcg_const_i32(0);
7158 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7159 tcg_temp_free_i32(tmp2
);
7160 tcg_temp_free_ptr(fpstatus
);
7163 case NEON_2RM_VCLT0_F
:
7165 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7166 tmp2
= tcg_const_i32(0);
7167 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7168 tcg_temp_free_i32(tmp2
);
7169 tcg_temp_free_ptr(fpstatus
);
7172 case NEON_2RM_VABS_F
:
7175 case NEON_2RM_VNEG_F
:
7179 tmp2
= neon_load_reg(rd
, pass
);
7180 neon_store_reg(rm
, pass
, tmp2
);
7183 tmp2
= neon_load_reg(rd
, pass
);
7185 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7186 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7189 neon_store_reg(rm
, pass
, tmp2
);
7191 case NEON_2RM_VRINTN
:
7192 case NEON_2RM_VRINTA
:
7193 case NEON_2RM_VRINTM
:
7194 case NEON_2RM_VRINTP
:
7195 case NEON_2RM_VRINTZ
:
7198 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7201 if (op
== NEON_2RM_VRINTZ
) {
7202 rmode
= FPROUNDING_ZERO
;
7204 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7207 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7208 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7210 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7211 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7213 tcg_temp_free_ptr(fpstatus
);
7214 tcg_temp_free_i32(tcg_rmode
);
7217 case NEON_2RM_VRINTX
:
7219 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7220 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7221 tcg_temp_free_ptr(fpstatus
);
7224 case NEON_2RM_VCVTAU
:
7225 case NEON_2RM_VCVTAS
:
7226 case NEON_2RM_VCVTNU
:
7227 case NEON_2RM_VCVTNS
:
7228 case NEON_2RM_VCVTPU
:
7229 case NEON_2RM_VCVTPS
:
7230 case NEON_2RM_VCVTMU
:
7231 case NEON_2RM_VCVTMS
:
7233 bool is_signed
= !extract32(insn
, 7, 1);
7234 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7235 TCGv_i32 tcg_rmode
, tcg_shift
;
7236 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7238 tcg_shift
= tcg_const_i32(0);
7239 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7240 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7244 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7247 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7251 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7253 tcg_temp_free_i32(tcg_rmode
);
7254 tcg_temp_free_i32(tcg_shift
);
7255 tcg_temp_free_ptr(fpst
);
7258 case NEON_2RM_VRECPE
:
7260 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7261 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7262 tcg_temp_free_ptr(fpstatus
);
7265 case NEON_2RM_VRSQRTE
:
7267 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7268 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7269 tcg_temp_free_ptr(fpstatus
);
7272 case NEON_2RM_VRECPE_F
:
7274 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7275 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7276 tcg_temp_free_ptr(fpstatus
);
7279 case NEON_2RM_VRSQRTE_F
:
7281 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7282 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7283 tcg_temp_free_ptr(fpstatus
);
7286 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7289 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7292 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7293 gen_vfp_tosiz(0, 1);
7295 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7296 gen_vfp_touiz(0, 1);
7299 /* Reserved op values were caught by the
7300 * neon_2rm_sizes[] check earlier.
7304 if (neon_2rm_is_float_op(op
)) {
7305 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7306 neon_reg_offset(rd
, pass
));
7308 neon_store_reg(rd
, pass
, tmp
);
7313 } else if ((insn
& (1 << 10)) == 0) {
7315 int n
= ((insn
>> 8) & 3) + 1;
7316 if ((rn
+ n
) > 32) {
7317 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7318 * helper function running off the end of the register file.
7323 if (insn
& (1 << 6)) {
7324 tmp
= neon_load_reg(rd
, 0);
7326 tmp
= tcg_temp_new_i32();
7327 tcg_gen_movi_i32(tmp
, 0);
7329 tmp2
= neon_load_reg(rm
, 0);
7330 tmp4
= tcg_const_i32(rn
);
7331 tmp5
= tcg_const_i32(n
);
7332 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7333 tcg_temp_free_i32(tmp
);
7334 if (insn
& (1 << 6)) {
7335 tmp
= neon_load_reg(rd
, 1);
7337 tmp
= tcg_temp_new_i32();
7338 tcg_gen_movi_i32(tmp
, 0);
7340 tmp3
= neon_load_reg(rm
, 1);
7341 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7342 tcg_temp_free_i32(tmp5
);
7343 tcg_temp_free_i32(tmp4
);
7344 neon_store_reg(rd
, 0, tmp2
);
7345 neon_store_reg(rd
, 1, tmp3
);
7346 tcg_temp_free_i32(tmp
);
7347 } else if ((insn
& 0x380) == 0) {
7349 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7352 if (insn
& (1 << 19)) {
7353 tmp
= neon_load_reg(rm
, 1);
7355 tmp
= neon_load_reg(rm
, 0);
7357 if (insn
& (1 << 16)) {
7358 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7359 } else if (insn
& (1 << 17)) {
7360 if ((insn
>> 18) & 1)
7361 gen_neon_dup_high16(tmp
);
7363 gen_neon_dup_low16(tmp
);
7365 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7366 tmp2
= tcg_temp_new_i32();
7367 tcg_gen_mov_i32(tmp2
, tmp
);
7368 neon_store_reg(rd
, pass
, tmp2
);
7370 tcg_temp_free_i32(tmp
);
7379 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7381 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7382 const ARMCPRegInfo
*ri
;
7384 cpnum
= (insn
>> 8) & 0xf;
7386 /* First check for coprocessor space used for XScale/iwMMXt insns */
7387 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7388 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7391 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7392 return disas_iwmmxt_insn(s
, insn
);
7393 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7394 return disas_dsp_insn(s
, insn
);
7399 /* Otherwise treat as a generic register access */
7400 is64
= (insn
& (1 << 25)) == 0;
7401 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7409 opc1
= (insn
>> 4) & 0xf;
7411 rt2
= (insn
>> 16) & 0xf;
7413 crn
= (insn
>> 16) & 0xf;
7414 opc1
= (insn
>> 21) & 7;
7415 opc2
= (insn
>> 5) & 7;
7418 isread
= (insn
>> 20) & 1;
7419 rt
= (insn
>> 12) & 0xf;
7421 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7422 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7424 /* Check access permissions */
7425 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7430 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7431 /* Emit code to perform further access permissions checks at
7432 * runtime; this may result in an exception.
7433 * Note that on XScale all cp0..c13 registers do an access check
7434 * call in order to handle c15_cpar.
7437 TCGv_i32 tcg_syn
, tcg_isread
;
7440 /* Note that since we are an implementation which takes an
7441 * exception on a trapped conditional instruction only if the
7442 * instruction passes its condition code check, we can take
7443 * advantage of the clause in the ARM ARM that allows us to set
7444 * the COND field in the instruction to 0xE in all cases.
7445 * We could fish the actual condition out of the insn (ARM)
7446 * or the condexec bits (Thumb) but it isn't necessary.
7451 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7454 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7460 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7463 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7468 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7469 * so this can only happen if this is an ARMv7 or earlier CPU,
7470 * in which case the syndrome information won't actually be
7473 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7474 syndrome
= syn_uncategorized();
7478 gen_set_condexec(s
);
7479 gen_set_pc_im(s
, s
->pc
- 4);
7480 tmpptr
= tcg_const_ptr(ri
);
7481 tcg_syn
= tcg_const_i32(syndrome
);
7482 tcg_isread
= tcg_const_i32(isread
);
7483 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7485 tcg_temp_free_ptr(tmpptr
);
7486 tcg_temp_free_i32(tcg_syn
);
7487 tcg_temp_free_i32(tcg_isread
);
7490 /* Handle special cases first */
7491 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7498 gen_set_pc_im(s
, s
->pc
);
7499 s
->is_jmp
= DISAS_WFI
;
7505 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7514 if (ri
->type
& ARM_CP_CONST
) {
7515 tmp64
= tcg_const_i64(ri
->resetvalue
);
7516 } else if (ri
->readfn
) {
7518 tmp64
= tcg_temp_new_i64();
7519 tmpptr
= tcg_const_ptr(ri
);
7520 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7521 tcg_temp_free_ptr(tmpptr
);
7523 tmp64
= tcg_temp_new_i64();
7524 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7526 tmp
= tcg_temp_new_i32();
7527 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7528 store_reg(s
, rt
, tmp
);
7529 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7530 tmp
= tcg_temp_new_i32();
7531 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7532 tcg_temp_free_i64(tmp64
);
7533 store_reg(s
, rt2
, tmp
);
7536 if (ri
->type
& ARM_CP_CONST
) {
7537 tmp
= tcg_const_i32(ri
->resetvalue
);
7538 } else if (ri
->readfn
) {
7540 tmp
= tcg_temp_new_i32();
7541 tmpptr
= tcg_const_ptr(ri
);
7542 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7543 tcg_temp_free_ptr(tmpptr
);
7545 tmp
= load_cpu_offset(ri
->fieldoffset
);
7548 /* Destination register of r15 for 32 bit loads sets
7549 * the condition codes from the high 4 bits of the value
7552 tcg_temp_free_i32(tmp
);
7554 store_reg(s
, rt
, tmp
);
7559 if (ri
->type
& ARM_CP_CONST
) {
7560 /* If not forbidden by access permissions, treat as WI */
7565 TCGv_i32 tmplo
, tmphi
;
7566 TCGv_i64 tmp64
= tcg_temp_new_i64();
7567 tmplo
= load_reg(s
, rt
);
7568 tmphi
= load_reg(s
, rt2
);
7569 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7570 tcg_temp_free_i32(tmplo
);
7571 tcg_temp_free_i32(tmphi
);
7573 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7574 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7575 tcg_temp_free_ptr(tmpptr
);
7577 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7579 tcg_temp_free_i64(tmp64
);
7584 tmp
= load_reg(s
, rt
);
7585 tmpptr
= tcg_const_ptr(ri
);
7586 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7587 tcg_temp_free_ptr(tmpptr
);
7588 tcg_temp_free_i32(tmp
);
7590 TCGv_i32 tmp
= load_reg(s
, rt
);
7591 store_cpu_offset(tmp
, ri
->fieldoffset
);
7596 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7597 /* I/O operations must end the TB here (whether read or write) */
7600 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7601 /* We default to ending the TB on a coprocessor register write,
7602 * but allow this to be suppressed by the register definition
7603 * (usually only necessary to work around guest bugs).
7611 /* Unknown register; this might be a guest error or a QEMU
7612 * unimplemented feature.
7615 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7616 "64 bit system register cp:%d opc1: %d crm:%d "
7618 isread
? "read" : "write", cpnum
, opc1
, crm
,
7619 s
->ns
? "non-secure" : "secure");
7621 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7622 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7624 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7625 s
->ns
? "non-secure" : "secure");
7632 /* Store a 64-bit value to a register pair. Clobbers val. */
7633 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7636 tmp
= tcg_temp_new_i32();
7637 tcg_gen_extrl_i64_i32(tmp
, val
);
7638 store_reg(s
, rlow
, tmp
);
7639 tmp
= tcg_temp_new_i32();
7640 tcg_gen_shri_i64(val
, val
, 32);
7641 tcg_gen_extrl_i64_i32(tmp
, val
);
7642 store_reg(s
, rhigh
, tmp
);
7645 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7646 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7651 /* Load value and extend to 64 bits. */
7652 tmp
= tcg_temp_new_i64();
7653 tmp2
= load_reg(s
, rlow
);
7654 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7655 tcg_temp_free_i32(tmp2
);
7656 tcg_gen_add_i64(val
, val
, tmp
);
7657 tcg_temp_free_i64(tmp
);
7660 /* load and add a 64-bit value from a register pair. */
7661 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7667 /* Load 64-bit value rd:rn. */
7668 tmpl
= load_reg(s
, rlow
);
7669 tmph
= load_reg(s
, rhigh
);
7670 tmp
= tcg_temp_new_i64();
7671 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7672 tcg_temp_free_i32(tmpl
);
7673 tcg_temp_free_i32(tmph
);
7674 tcg_gen_add_i64(val
, val
, tmp
);
7675 tcg_temp_free_i64(tmp
);
7678 /* Set N and Z flags from hi|lo. */
7679 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7681 tcg_gen_mov_i32(cpu_NF
, hi
);
7682 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7685 /* Load/Store exclusive instructions are implemented by remembering
7686 the value/address loaded, and seeing if these are the same
7687 when the store is performed. This should be sufficient to implement
7688 the architecturally mandated semantics, and avoids having to monitor
7689 regular stores. The compare vs the remembered value is done during
7690 the cmpxchg operation, but we must compare the addresses manually. */
7691 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7692 TCGv_i32 addr
, int size
)
7694 TCGv_i32 tmp
= tcg_temp_new_i32();
7695 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7700 TCGv_i32 tmp2
= tcg_temp_new_i32();
7701 TCGv_i64 t64
= tcg_temp_new_i64();
7703 gen_aa32_ld_i64(s
, t64
, addr
, get_mem_index(s
), opc
);
7704 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
7705 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
7706 tcg_temp_free_i64(t64
);
7708 store_reg(s
, rt2
, tmp2
);
7710 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
7711 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7714 store_reg(s
, rt
, tmp
);
7715 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7718 static void gen_clrex(DisasContext
*s
)
7720 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7723 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7724 TCGv_i32 addr
, int size
)
7726 TCGv_i32 t0
, t1
, t2
;
7729 TCGLabel
*done_label
;
7730 TCGLabel
*fail_label
;
7731 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7733 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7739 fail_label
= gen_new_label();
7740 done_label
= gen_new_label();
7741 extaddr
= tcg_temp_new_i64();
7742 tcg_gen_extu_i32_i64(extaddr
, addr
);
7743 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7744 tcg_temp_free_i64(extaddr
);
7746 taddr
= gen_aa32_addr(s
, addr
, opc
);
7747 t0
= tcg_temp_new_i32();
7748 t1
= load_reg(s
, rt
);
7750 TCGv_i64 o64
= tcg_temp_new_i64();
7751 TCGv_i64 n64
= tcg_temp_new_i64();
7753 t2
= load_reg(s
, rt2
);
7754 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
7755 tcg_temp_free_i32(t2
);
7756 gen_aa32_frob64(s
, n64
);
7758 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
7759 get_mem_index(s
), opc
);
7760 tcg_temp_free_i64(n64
);
7762 gen_aa32_frob64(s
, o64
);
7763 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
7764 tcg_gen_extrl_i64_i32(t0
, o64
);
7766 tcg_temp_free_i64(o64
);
7768 t2
= tcg_temp_new_i32();
7769 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
7770 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
7771 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
7772 tcg_temp_free_i32(t2
);
7774 tcg_temp_free_i32(t1
);
7775 tcg_temp_free(taddr
);
7776 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
7777 tcg_temp_free_i32(t0
);
7778 tcg_gen_br(done_label
);
7780 gen_set_label(fail_label
);
7781 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7782 gen_set_label(done_label
);
7783 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7789 * @mode: mode field from insn (which stack to store to)
7790 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7791 * @writeback: true if writeback bit set
7793 * Generate code for the SRS (Store Return State) insn.
7795 static void gen_srs(DisasContext
*s
,
7796 uint32_t mode
, uint32_t amode
, bool writeback
)
7803 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7804 * and specified mode is monitor mode
7805 * - UNDEFINED in Hyp mode
7806 * - UNPREDICTABLE in User or System mode
7807 * - UNPREDICTABLE if the specified mode is:
7808 * -- not implemented
7809 * -- not a valid mode number
7810 * -- a mode that's at a higher exception level
7811 * -- Monitor, if we are Non-secure
7812 * For the UNPREDICTABLE cases we choose to UNDEF.
7814 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7815 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7819 if (s
->current_el
== 0 || s
->current_el
== 2) {
7824 case ARM_CPU_MODE_USR
:
7825 case ARM_CPU_MODE_FIQ
:
7826 case ARM_CPU_MODE_IRQ
:
7827 case ARM_CPU_MODE_SVC
:
7828 case ARM_CPU_MODE_ABT
:
7829 case ARM_CPU_MODE_UND
:
7830 case ARM_CPU_MODE_SYS
:
7832 case ARM_CPU_MODE_HYP
:
7833 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7837 case ARM_CPU_MODE_MON
:
7838 /* No need to check specifically for "are we non-secure" because
7839 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7840 * so if this isn't EL3 then we must be non-secure.
7842 if (s
->current_el
!= 3) {
7851 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
7852 default_exception_el(s
));
7856 addr
= tcg_temp_new_i32();
7857 tmp
= tcg_const_i32(mode
);
7858 /* get_r13_banked() will raise an exception if called from System mode */
7859 gen_set_condexec(s
);
7860 gen_set_pc_im(s
, s
->pc
- 4);
7861 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7862 tcg_temp_free_i32(tmp
);
7879 tcg_gen_addi_i32(addr
, addr
, offset
);
7880 tmp
= load_reg(s
, 14);
7881 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7882 tcg_temp_free_i32(tmp
);
7883 tmp
= load_cpu_field(spsr
);
7884 tcg_gen_addi_i32(addr
, addr
, 4);
7885 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7886 tcg_temp_free_i32(tmp
);
7904 tcg_gen_addi_i32(addr
, addr
, offset
);
7905 tmp
= tcg_const_i32(mode
);
7906 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7907 tcg_temp_free_i32(tmp
);
7909 tcg_temp_free_i32(addr
);
7910 s
->is_jmp
= DISAS_UPDATE
;
7913 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7915 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7922 /* M variants do not implement ARM mode. */
7923 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7928 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7929 * choose to UNDEF. In ARMv5 and above the space is used
7930 * for miscellaneous unconditional instructions.
7934 /* Unconditional instructions. */
7935 if (((insn
>> 25) & 7) == 1) {
7936 /* NEON Data processing. */
7937 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7941 if (disas_neon_data_insn(s
, insn
)) {
7946 if ((insn
& 0x0f100000) == 0x04000000) {
7947 /* NEON load/store. */
7948 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7952 if (disas_neon_ls_insn(s
, insn
)) {
7957 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7959 if (disas_vfp_insn(s
, insn
)) {
7964 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7965 ((insn
& 0x0f30f010) == 0x0710f000)) {
7966 if ((insn
& (1 << 22)) == 0) {
7968 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7972 /* Otherwise PLD; v5TE+ */
7976 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7977 ((insn
& 0x0f70f010) == 0x0650f000)) {
7979 return; /* PLI; V7 */
7981 if (((insn
& 0x0f700000) == 0x04100000) ||
7982 ((insn
& 0x0f700010) == 0x06100000)) {
7983 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7986 return; /* v7MP: Unallocated memory hint: must NOP */
7989 if ((insn
& 0x0ffffdff) == 0x01010000) {
7992 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
7993 gen_helper_setend(cpu_env
);
7994 s
->is_jmp
= DISAS_UPDATE
;
7997 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7998 switch ((insn
>> 4) & 0xf) {
8006 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
8009 /* We need to break the TB after this insn to execute
8010 * self-modifying code correctly and also to take
8011 * any pending interrupts immediately.
8018 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8021 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8023 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8029 rn
= (insn
>> 16) & 0xf;
8030 addr
= load_reg(s
, rn
);
8031 i
= (insn
>> 23) & 3;
8033 case 0: offset
= -4; break; /* DA */
8034 case 1: offset
= 0; break; /* IA */
8035 case 2: offset
= -8; break; /* DB */
8036 case 3: offset
= 4; break; /* IB */
8040 tcg_gen_addi_i32(addr
, addr
, offset
);
8041 /* Load PC into tmp and CPSR into tmp2. */
8042 tmp
= tcg_temp_new_i32();
8043 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8044 tcg_gen_addi_i32(addr
, addr
, 4);
8045 tmp2
= tcg_temp_new_i32();
8046 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8047 if (insn
& (1 << 21)) {
8048 /* Base writeback. */
8050 case 0: offset
= -8; break;
8051 case 1: offset
= 4; break;
8052 case 2: offset
= -4; break;
8053 case 3: offset
= 0; break;
8057 tcg_gen_addi_i32(addr
, addr
, offset
);
8058 store_reg(s
, rn
, addr
);
8060 tcg_temp_free_i32(addr
);
8062 gen_rfe(s
, tmp
, tmp2
);
8064 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8065 /* branch link and change to thumb (blx <offset>) */
8068 val
= (uint32_t)s
->pc
;
8069 tmp
= tcg_temp_new_i32();
8070 tcg_gen_movi_i32(tmp
, val
);
8071 store_reg(s
, 14, tmp
);
8072 /* Sign-extend the 24-bit offset */
8073 offset
= (((int32_t)insn
) << 8) >> 8;
8074 /* offset * 4 + bit24 * 2 + (thumb bit) */
8075 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8076 /* pipeline offset */
8078 /* protected by ARCH(5); above, near the start of uncond block */
8081 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8082 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8083 /* iWMMXt register transfer. */
8084 if (extract32(s
->c15_cpar
, 1, 1)) {
8085 if (!disas_iwmmxt_insn(s
, insn
)) {
8090 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8091 /* Coprocessor double register transfer. */
8093 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8094 /* Additional coprocessor register transfer. */
8095 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8098 /* cps (privileged) */
8102 if (insn
& (1 << 19)) {
8103 if (insn
& (1 << 8))
8105 if (insn
& (1 << 7))
8107 if (insn
& (1 << 6))
8109 if (insn
& (1 << 18))
8112 if (insn
& (1 << 17)) {
8114 val
|= (insn
& 0x1f);
8117 gen_set_psr_im(s
, mask
, 0, val
);
8124 /* if not always execute, we generate a conditional jump to
8126 s
->condlabel
= gen_new_label();
8127 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8130 if ((insn
& 0x0f900000) == 0x03000000) {
8131 if ((insn
& (1 << 21)) == 0) {
8133 rd
= (insn
>> 12) & 0xf;
8134 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8135 if ((insn
& (1 << 22)) == 0) {
8137 tmp
= tcg_temp_new_i32();
8138 tcg_gen_movi_i32(tmp
, val
);
8141 tmp
= load_reg(s
, rd
);
8142 tcg_gen_ext16u_i32(tmp
, tmp
);
8143 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8145 store_reg(s
, rd
, tmp
);
8147 if (((insn
>> 12) & 0xf) != 0xf)
8149 if (((insn
>> 16) & 0xf) == 0) {
8150 gen_nop_hint(s
, insn
& 0xff);
8152 /* CPSR = immediate */
8154 shift
= ((insn
>> 8) & 0xf) * 2;
8156 val
= (val
>> shift
) | (val
<< (32 - shift
));
8157 i
= ((insn
& (1 << 22)) != 0);
8158 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8164 } else if ((insn
& 0x0f900000) == 0x01000000
8165 && (insn
& 0x00000090) != 0x00000090) {
8166 /* miscellaneous instructions */
8167 op1
= (insn
>> 21) & 3;
8168 sh
= (insn
>> 4) & 0xf;
8171 case 0x0: /* MSR, MRS */
8172 if (insn
& (1 << 9)) {
8173 /* MSR (banked) and MRS (banked) */
8174 int sysm
= extract32(insn
, 16, 4) |
8175 (extract32(insn
, 8, 1) << 4);
8176 int r
= extract32(insn
, 22, 1);
8180 gen_msr_banked(s
, r
, sysm
, rm
);
8183 int rd
= extract32(insn
, 12, 4);
8185 gen_mrs_banked(s
, r
, sysm
, rd
);
8190 /* MSR, MRS (for PSRs) */
8193 tmp
= load_reg(s
, rm
);
8194 i
= ((op1
& 2) != 0);
8195 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8199 rd
= (insn
>> 12) & 0xf;
8203 tmp
= load_cpu_field(spsr
);
8205 tmp
= tcg_temp_new_i32();
8206 gen_helper_cpsr_read(tmp
, cpu_env
);
8208 store_reg(s
, rd
, tmp
);
8213 /* branch/exchange thumb (bx). */
8215 tmp
= load_reg(s
, rm
);
8217 } else if (op1
== 3) {
8220 rd
= (insn
>> 12) & 0xf;
8221 tmp
= load_reg(s
, rm
);
8222 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8223 store_reg(s
, rd
, tmp
);
8231 /* Trivial implementation equivalent to bx. */
8232 tmp
= load_reg(s
, rm
);
8243 /* branch link/exchange thumb (blx) */
8244 tmp
= load_reg(s
, rm
);
8245 tmp2
= tcg_temp_new_i32();
8246 tcg_gen_movi_i32(tmp2
, s
->pc
);
8247 store_reg(s
, 14, tmp2
);
8253 uint32_t c
= extract32(insn
, 8, 4);
8255 /* Check this CPU supports ARMv8 CRC instructions.
8256 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8257 * Bits 8, 10 and 11 should be zero.
8259 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8264 rn
= extract32(insn
, 16, 4);
8265 rd
= extract32(insn
, 12, 4);
8267 tmp
= load_reg(s
, rn
);
8268 tmp2
= load_reg(s
, rm
);
8270 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8271 } else if (op1
== 1) {
8272 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8274 tmp3
= tcg_const_i32(1 << op1
);
8276 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8278 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8280 tcg_temp_free_i32(tmp2
);
8281 tcg_temp_free_i32(tmp3
);
8282 store_reg(s
, rd
, tmp
);
8285 case 0x5: /* saturating add/subtract */
8287 rd
= (insn
>> 12) & 0xf;
8288 rn
= (insn
>> 16) & 0xf;
8289 tmp
= load_reg(s
, rm
);
8290 tmp2
= load_reg(s
, rn
);
8292 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8294 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8296 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8297 tcg_temp_free_i32(tmp2
);
8298 store_reg(s
, rd
, tmp
);
8302 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8311 gen_exception_insn(s
, 4, EXCP_BKPT
,
8312 syn_aa32_bkpt(imm16
, false),
8313 default_exception_el(s
));
8316 /* Hypervisor call (v7) */
8324 /* Secure monitor call (v6+) */
8332 g_assert_not_reached();
8336 case 0x8: /* signed multiply */
8341 rs
= (insn
>> 8) & 0xf;
8342 rn
= (insn
>> 12) & 0xf;
8343 rd
= (insn
>> 16) & 0xf;
8345 /* (32 * 16) >> 16 */
8346 tmp
= load_reg(s
, rm
);
8347 tmp2
= load_reg(s
, rs
);
8349 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8352 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8353 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8354 tmp
= tcg_temp_new_i32();
8355 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8356 tcg_temp_free_i64(tmp64
);
8357 if ((sh
& 2) == 0) {
8358 tmp2
= load_reg(s
, rn
);
8359 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8360 tcg_temp_free_i32(tmp2
);
8362 store_reg(s
, rd
, tmp
);
8365 tmp
= load_reg(s
, rm
);
8366 tmp2
= load_reg(s
, rs
);
8367 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8368 tcg_temp_free_i32(tmp2
);
8370 tmp64
= tcg_temp_new_i64();
8371 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8372 tcg_temp_free_i32(tmp
);
8373 gen_addq(s
, tmp64
, rn
, rd
);
8374 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8375 tcg_temp_free_i64(tmp64
);
8378 tmp2
= load_reg(s
, rn
);
8379 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8380 tcg_temp_free_i32(tmp2
);
8382 store_reg(s
, rd
, tmp
);
8389 } else if (((insn
& 0x0e000000) == 0 &&
8390 (insn
& 0x00000090) != 0x90) ||
8391 ((insn
& 0x0e000000) == (1 << 25))) {
8392 int set_cc
, logic_cc
, shiftop
;
8394 op1
= (insn
>> 21) & 0xf;
8395 set_cc
= (insn
>> 20) & 1;
8396 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8398 /* data processing instruction */
8399 if (insn
& (1 << 25)) {
8400 /* immediate operand */
8402 shift
= ((insn
>> 8) & 0xf) * 2;
8404 val
= (val
>> shift
) | (val
<< (32 - shift
));
8406 tmp2
= tcg_temp_new_i32();
8407 tcg_gen_movi_i32(tmp2
, val
);
8408 if (logic_cc
&& shift
) {
8409 gen_set_CF_bit31(tmp2
);
8414 tmp2
= load_reg(s
, rm
);
8415 shiftop
= (insn
>> 5) & 3;
8416 if (!(insn
& (1 << 4))) {
8417 shift
= (insn
>> 7) & 0x1f;
8418 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8420 rs
= (insn
>> 8) & 0xf;
8421 tmp
= load_reg(s
, rs
);
8422 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8425 if (op1
!= 0x0f && op1
!= 0x0d) {
8426 rn
= (insn
>> 16) & 0xf;
8427 tmp
= load_reg(s
, rn
);
8429 TCGV_UNUSED_I32(tmp
);
8431 rd
= (insn
>> 12) & 0xf;
8434 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8438 store_reg_bx(s
, rd
, tmp
);
8441 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8445 store_reg_bx(s
, rd
, tmp
);
8448 if (set_cc
&& rd
== 15) {
8449 /* SUBS r15, ... is used for exception return. */
8453 gen_sub_CC(tmp
, tmp
, tmp2
);
8454 gen_exception_return(s
, tmp
);
8457 gen_sub_CC(tmp
, tmp
, tmp2
);
8459 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8461 store_reg_bx(s
, rd
, tmp
);
8466 gen_sub_CC(tmp
, tmp2
, tmp
);
8468 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8470 store_reg_bx(s
, rd
, tmp
);
8474 gen_add_CC(tmp
, tmp
, tmp2
);
8476 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8478 store_reg_bx(s
, rd
, tmp
);
8482 gen_adc_CC(tmp
, tmp
, tmp2
);
8484 gen_add_carry(tmp
, tmp
, tmp2
);
8486 store_reg_bx(s
, rd
, tmp
);
8490 gen_sbc_CC(tmp
, tmp
, tmp2
);
8492 gen_sub_carry(tmp
, tmp
, tmp2
);
8494 store_reg_bx(s
, rd
, tmp
);
8498 gen_sbc_CC(tmp
, tmp2
, tmp
);
8500 gen_sub_carry(tmp
, tmp2
, tmp
);
8502 store_reg_bx(s
, rd
, tmp
);
8506 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8509 tcg_temp_free_i32(tmp
);
8513 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8516 tcg_temp_free_i32(tmp
);
8520 gen_sub_CC(tmp
, tmp
, tmp2
);
8522 tcg_temp_free_i32(tmp
);
8526 gen_add_CC(tmp
, tmp
, tmp2
);
8528 tcg_temp_free_i32(tmp
);
8531 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8535 store_reg_bx(s
, rd
, tmp
);
8538 if (logic_cc
&& rd
== 15) {
8539 /* MOVS r15, ... is used for exception return. */
8543 gen_exception_return(s
, tmp2
);
8548 store_reg_bx(s
, rd
, tmp2
);
8552 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8556 store_reg_bx(s
, rd
, tmp
);
8560 tcg_gen_not_i32(tmp2
, tmp2
);
8564 store_reg_bx(s
, rd
, tmp2
);
8567 if (op1
!= 0x0f && op1
!= 0x0d) {
8568 tcg_temp_free_i32(tmp2
);
8571 /* other instructions */
8572 op1
= (insn
>> 24) & 0xf;
8576 /* multiplies, extra load/stores */
8577 sh
= (insn
>> 5) & 3;
8580 rd
= (insn
>> 16) & 0xf;
8581 rn
= (insn
>> 12) & 0xf;
8582 rs
= (insn
>> 8) & 0xf;
8584 op1
= (insn
>> 20) & 0xf;
8586 case 0: case 1: case 2: case 3: case 6:
8588 tmp
= load_reg(s
, rs
);
8589 tmp2
= load_reg(s
, rm
);
8590 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8591 tcg_temp_free_i32(tmp2
);
8592 if (insn
& (1 << 22)) {
8593 /* Subtract (mls) */
8595 tmp2
= load_reg(s
, rn
);
8596 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8597 tcg_temp_free_i32(tmp2
);
8598 } else if (insn
& (1 << 21)) {
8600 tmp2
= load_reg(s
, rn
);
8601 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8602 tcg_temp_free_i32(tmp2
);
8604 if (insn
& (1 << 20))
8606 store_reg(s
, rd
, tmp
);
8609 /* 64 bit mul double accumulate (UMAAL) */
8611 tmp
= load_reg(s
, rs
);
8612 tmp2
= load_reg(s
, rm
);
8613 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8614 gen_addq_lo(s
, tmp64
, rn
);
8615 gen_addq_lo(s
, tmp64
, rd
);
8616 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8617 tcg_temp_free_i64(tmp64
);
8619 case 8: case 9: case 10: case 11:
8620 case 12: case 13: case 14: case 15:
8621 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8622 tmp
= load_reg(s
, rs
);
8623 tmp2
= load_reg(s
, rm
);
8624 if (insn
& (1 << 22)) {
8625 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8627 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8629 if (insn
& (1 << 21)) { /* mult accumulate */
8630 TCGv_i32 al
= load_reg(s
, rn
);
8631 TCGv_i32 ah
= load_reg(s
, rd
);
8632 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8633 tcg_temp_free_i32(al
);
8634 tcg_temp_free_i32(ah
);
8636 if (insn
& (1 << 20)) {
8637 gen_logicq_cc(tmp
, tmp2
);
8639 store_reg(s
, rn
, tmp
);
8640 store_reg(s
, rd
, tmp2
);
8646 rn
= (insn
>> 16) & 0xf;
8647 rd
= (insn
>> 12) & 0xf;
8648 if (insn
& (1 << 23)) {
8649 /* load/store exclusive */
8650 int op2
= (insn
>> 8) & 3;
8651 op1
= (insn
>> 21) & 0x3;
8654 case 0: /* lda/stl */
8660 case 1: /* reserved */
8662 case 2: /* ldaex/stlex */
8665 case 3: /* ldrex/strex */
8674 addr
= tcg_temp_local_new_i32();
8675 load_reg_var(s
, addr
, rn
);
8677 /* Since the emulation does not have barriers,
8678 the acquire/release semantics need no special
8681 if (insn
& (1 << 20)) {
8682 tmp
= tcg_temp_new_i32();
8685 gen_aa32_ld32u(s
, tmp
, addr
,
8689 gen_aa32_ld8u(s
, tmp
, addr
,
8693 gen_aa32_ld16u(s
, tmp
, addr
,
8699 store_reg(s
, rd
, tmp
);
8702 tmp
= load_reg(s
, rm
);
8705 gen_aa32_st32(s
, tmp
, addr
,
8709 gen_aa32_st8(s
, tmp
, addr
,
8713 gen_aa32_st16(s
, tmp
, addr
,
8719 tcg_temp_free_i32(tmp
);
8721 } else if (insn
& (1 << 20)) {
8724 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8726 case 1: /* ldrexd */
8727 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8729 case 2: /* ldrexb */
8730 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8732 case 3: /* ldrexh */
8733 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8742 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8744 case 1: /* strexd */
8745 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8747 case 2: /* strexb */
8748 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8750 case 3: /* strexh */
8751 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8757 tcg_temp_free_i32(addr
);
8760 TCGMemOp opc
= s
->be_data
;
8762 /* SWP instruction */
8765 if (insn
& (1 << 22)) {
8768 opc
|= MO_UL
| MO_ALIGN
;
8771 addr
= load_reg(s
, rn
);
8772 taddr
= gen_aa32_addr(s
, addr
, opc
);
8773 tcg_temp_free_i32(addr
);
8775 tmp
= load_reg(s
, rm
);
8776 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
8777 get_mem_index(s
), opc
);
8778 tcg_temp_free(taddr
);
8779 store_reg(s
, rd
, tmp
);
8784 bool load
= insn
& (1 << 20);
8785 bool doubleword
= false;
8786 /* Misc load/store */
8787 rn
= (insn
>> 16) & 0xf;
8788 rd
= (insn
>> 12) & 0xf;
8790 if (!load
&& (sh
& 2)) {
8794 /* UNPREDICTABLE; we choose to UNDEF */
8797 load
= (sh
& 1) == 0;
8801 addr
= load_reg(s
, rn
);
8802 if (insn
& (1 << 24))
8803 gen_add_datah_offset(s
, insn
, 0, addr
);
8809 tmp
= load_reg(s
, rd
);
8810 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8811 tcg_temp_free_i32(tmp
);
8812 tcg_gen_addi_i32(addr
, addr
, 4);
8813 tmp
= load_reg(s
, rd
+ 1);
8814 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8815 tcg_temp_free_i32(tmp
);
8818 tmp
= tcg_temp_new_i32();
8819 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8820 store_reg(s
, rd
, tmp
);
8821 tcg_gen_addi_i32(addr
, addr
, 4);
8822 tmp
= tcg_temp_new_i32();
8823 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8826 address_offset
= -4;
8829 tmp
= tcg_temp_new_i32();
8832 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
8835 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
8839 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
8844 tmp
= load_reg(s
, rd
);
8845 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
8846 tcg_temp_free_i32(tmp
);
8848 /* Perform base writeback before the loaded value to
8849 ensure correct behavior with overlapping index registers.
8850 ldrd with base writeback is undefined if the
8851 destination and index registers overlap. */
8852 if (!(insn
& (1 << 24))) {
8853 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8854 store_reg(s
, rn
, addr
);
8855 } else if (insn
& (1 << 21)) {
8857 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8858 store_reg(s
, rn
, addr
);
8860 tcg_temp_free_i32(addr
);
8863 /* Complete the load. */
8864 store_reg(s
, rd
, tmp
);
8873 if (insn
& (1 << 4)) {
8875 /* Armv6 Media instructions. */
8877 rn
= (insn
>> 16) & 0xf;
8878 rd
= (insn
>> 12) & 0xf;
8879 rs
= (insn
>> 8) & 0xf;
8880 switch ((insn
>> 23) & 3) {
8881 case 0: /* Parallel add/subtract. */
8882 op1
= (insn
>> 20) & 7;
8883 tmp
= load_reg(s
, rn
);
8884 tmp2
= load_reg(s
, rm
);
8885 sh
= (insn
>> 5) & 7;
8886 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8888 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8889 tcg_temp_free_i32(tmp2
);
8890 store_reg(s
, rd
, tmp
);
8893 if ((insn
& 0x00700020) == 0) {
8894 /* Halfword pack. */
8895 tmp
= load_reg(s
, rn
);
8896 tmp2
= load_reg(s
, rm
);
8897 shift
= (insn
>> 7) & 0x1f;
8898 if (insn
& (1 << 6)) {
8902 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8903 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8904 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8908 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8909 tcg_gen_ext16u_i32(tmp
, tmp
);
8910 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8912 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8913 tcg_temp_free_i32(tmp2
);
8914 store_reg(s
, rd
, tmp
);
8915 } else if ((insn
& 0x00200020) == 0x00200000) {
8917 tmp
= load_reg(s
, rm
);
8918 shift
= (insn
>> 7) & 0x1f;
8919 if (insn
& (1 << 6)) {
8922 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8924 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8926 sh
= (insn
>> 16) & 0x1f;
8927 tmp2
= tcg_const_i32(sh
);
8928 if (insn
& (1 << 22))
8929 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8931 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8932 tcg_temp_free_i32(tmp2
);
8933 store_reg(s
, rd
, tmp
);
8934 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8936 tmp
= load_reg(s
, rm
);
8937 sh
= (insn
>> 16) & 0x1f;
8938 tmp2
= tcg_const_i32(sh
);
8939 if (insn
& (1 << 22))
8940 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8942 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8943 tcg_temp_free_i32(tmp2
);
8944 store_reg(s
, rd
, tmp
);
8945 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8947 tmp
= load_reg(s
, rn
);
8948 tmp2
= load_reg(s
, rm
);
8949 tmp3
= tcg_temp_new_i32();
8950 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8951 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8952 tcg_temp_free_i32(tmp3
);
8953 tcg_temp_free_i32(tmp2
);
8954 store_reg(s
, rd
, tmp
);
8955 } else if ((insn
& 0x000003e0) == 0x00000060) {
8956 tmp
= load_reg(s
, rm
);
8957 shift
= (insn
>> 10) & 3;
8958 /* ??? In many cases it's not necessary to do a
8959 rotate, a shift is sufficient. */
8961 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8962 op1
= (insn
>> 20) & 7;
8964 case 0: gen_sxtb16(tmp
); break;
8965 case 2: gen_sxtb(tmp
); break;
8966 case 3: gen_sxth(tmp
); break;
8967 case 4: gen_uxtb16(tmp
); break;
8968 case 6: gen_uxtb(tmp
); break;
8969 case 7: gen_uxth(tmp
); break;
8970 default: goto illegal_op
;
8973 tmp2
= load_reg(s
, rn
);
8974 if ((op1
& 3) == 0) {
8975 gen_add16(tmp
, tmp2
);
8977 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8978 tcg_temp_free_i32(tmp2
);
8981 store_reg(s
, rd
, tmp
);
8982 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8984 tmp
= load_reg(s
, rm
);
8985 if (insn
& (1 << 22)) {
8986 if (insn
& (1 << 7)) {
8990 gen_helper_rbit(tmp
, tmp
);
8993 if (insn
& (1 << 7))
8996 tcg_gen_bswap32_i32(tmp
, tmp
);
8998 store_reg(s
, rd
, tmp
);
9003 case 2: /* Multiplies (Type 3). */
9004 switch ((insn
>> 20) & 0x7) {
9006 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9007 /* op2 not 00x or 11x : UNDEF */
9010 /* Signed multiply most significant [accumulate].
9011 (SMMUL, SMMLA, SMMLS) */
9012 tmp
= load_reg(s
, rm
);
9013 tmp2
= load_reg(s
, rs
);
9014 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9017 tmp
= load_reg(s
, rd
);
9018 if (insn
& (1 << 6)) {
9019 tmp64
= gen_subq_msw(tmp64
, tmp
);
9021 tmp64
= gen_addq_msw(tmp64
, tmp
);
9024 if (insn
& (1 << 5)) {
9025 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9027 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9028 tmp
= tcg_temp_new_i32();
9029 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9030 tcg_temp_free_i64(tmp64
);
9031 store_reg(s
, rn
, tmp
);
9035 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9036 if (insn
& (1 << 7)) {
9039 tmp
= load_reg(s
, rm
);
9040 tmp2
= load_reg(s
, rs
);
9041 if (insn
& (1 << 5))
9042 gen_swap_half(tmp2
);
9043 gen_smul_dual(tmp
, tmp2
);
9044 if (insn
& (1 << 22)) {
9045 /* smlald, smlsld */
9048 tmp64
= tcg_temp_new_i64();
9049 tmp64_2
= tcg_temp_new_i64();
9050 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9051 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9052 tcg_temp_free_i32(tmp
);
9053 tcg_temp_free_i32(tmp2
);
9054 if (insn
& (1 << 6)) {
9055 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9057 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9059 tcg_temp_free_i64(tmp64_2
);
9060 gen_addq(s
, tmp64
, rd
, rn
);
9061 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9062 tcg_temp_free_i64(tmp64
);
9064 /* smuad, smusd, smlad, smlsd */
9065 if (insn
& (1 << 6)) {
9066 /* This subtraction cannot overflow. */
9067 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9069 /* This addition cannot overflow 32 bits;
9070 * however it may overflow considered as a
9071 * signed operation, in which case we must set
9074 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9076 tcg_temp_free_i32(tmp2
);
9079 tmp2
= load_reg(s
, rd
);
9080 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9081 tcg_temp_free_i32(tmp2
);
9083 store_reg(s
, rn
, tmp
);
9089 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9092 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9095 tmp
= load_reg(s
, rm
);
9096 tmp2
= load_reg(s
, rs
);
9097 if (insn
& (1 << 21)) {
9098 gen_helper_udiv(tmp
, tmp
, tmp2
);
9100 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9102 tcg_temp_free_i32(tmp2
);
9103 store_reg(s
, rn
, tmp
);
9110 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9112 case 0: /* Unsigned sum of absolute differences. */
9114 tmp
= load_reg(s
, rm
);
9115 tmp2
= load_reg(s
, rs
);
9116 gen_helper_usad8(tmp
, tmp
, tmp2
);
9117 tcg_temp_free_i32(tmp2
);
9119 tmp2
= load_reg(s
, rd
);
9120 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9121 tcg_temp_free_i32(tmp2
);
9123 store_reg(s
, rn
, tmp
);
9125 case 0x20: case 0x24: case 0x28: case 0x2c:
9126 /* Bitfield insert/clear. */
9128 shift
= (insn
>> 7) & 0x1f;
9129 i
= (insn
>> 16) & 0x1f;
9131 /* UNPREDICTABLE; we choose to UNDEF */
9136 tmp
= tcg_temp_new_i32();
9137 tcg_gen_movi_i32(tmp
, 0);
9139 tmp
= load_reg(s
, rm
);
9142 tmp2
= load_reg(s
, rd
);
9143 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9144 tcg_temp_free_i32(tmp2
);
9146 store_reg(s
, rd
, tmp
);
9148 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9149 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9151 tmp
= load_reg(s
, rm
);
9152 shift
= (insn
>> 7) & 0x1f;
9153 i
= ((insn
>> 16) & 0x1f) + 1;
9158 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9160 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9163 store_reg(s
, rd
, tmp
);
9173 /* Check for undefined extension instructions
9174 * per the ARM Bible IE:
9175 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9177 sh
= (0xf << 20) | (0xf << 4);
9178 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9182 /* load/store byte/word */
9183 rn
= (insn
>> 16) & 0xf;
9184 rd
= (insn
>> 12) & 0xf;
9185 tmp2
= load_reg(s
, rn
);
9186 if ((insn
& 0x01200000) == 0x00200000) {
9188 i
= get_a32_user_mem_index(s
);
9190 i
= get_mem_index(s
);
9192 if (insn
& (1 << 24))
9193 gen_add_data_offset(s
, insn
, tmp2
);
9194 if (insn
& (1 << 20)) {
9196 tmp
= tcg_temp_new_i32();
9197 if (insn
& (1 << 22)) {
9198 gen_aa32_ld8u(s
, tmp
, tmp2
, i
);
9200 gen_aa32_ld32u(s
, tmp
, tmp2
, i
);
9204 tmp
= load_reg(s
, rd
);
9205 if (insn
& (1 << 22)) {
9206 gen_aa32_st8(s
, tmp
, tmp2
, i
);
9208 gen_aa32_st32(s
, tmp
, tmp2
, i
);
9210 tcg_temp_free_i32(tmp
);
9212 if (!(insn
& (1 << 24))) {
9213 gen_add_data_offset(s
, insn
, tmp2
);
9214 store_reg(s
, rn
, tmp2
);
9215 } else if (insn
& (1 << 21)) {
9216 store_reg(s
, rn
, tmp2
);
9218 tcg_temp_free_i32(tmp2
);
9220 if (insn
& (1 << 20)) {
9221 /* Complete the load. */
9222 store_reg_from_load(s
, rd
, tmp
);
9228 int j
, n
, loaded_base
;
9229 bool exc_return
= false;
9230 bool is_load
= extract32(insn
, 20, 1);
9232 TCGv_i32 loaded_var
;
9233 /* load/store multiple words */
9234 /* XXX: store correct base if write back */
9235 if (insn
& (1 << 22)) {
9236 /* LDM (user), LDM (exception return) and STM (user) */
9238 goto illegal_op
; /* only usable in supervisor mode */
9240 if (is_load
&& extract32(insn
, 15, 1)) {
9246 rn
= (insn
>> 16) & 0xf;
9247 addr
= load_reg(s
, rn
);
9249 /* compute total size */
9251 TCGV_UNUSED_I32(loaded_var
);
9254 if (insn
& (1 << i
))
9257 /* XXX: test invalid n == 0 case ? */
9258 if (insn
& (1 << 23)) {
9259 if (insn
& (1 << 24)) {
9261 tcg_gen_addi_i32(addr
, addr
, 4);
9263 /* post increment */
9266 if (insn
& (1 << 24)) {
9268 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9270 /* post decrement */
9272 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9277 if (insn
& (1 << i
)) {
9280 tmp
= tcg_temp_new_i32();
9281 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9283 tmp2
= tcg_const_i32(i
);
9284 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9285 tcg_temp_free_i32(tmp2
);
9286 tcg_temp_free_i32(tmp
);
9287 } else if (i
== rn
) {
9290 } else if (rn
== 15 && exc_return
) {
9291 store_pc_exc_ret(s
, tmp
);
9293 store_reg_from_load(s
, i
, tmp
);
9298 /* special case: r15 = PC + 8 */
9299 val
= (long)s
->pc
+ 4;
9300 tmp
= tcg_temp_new_i32();
9301 tcg_gen_movi_i32(tmp
, val
);
9303 tmp
= tcg_temp_new_i32();
9304 tmp2
= tcg_const_i32(i
);
9305 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9306 tcg_temp_free_i32(tmp2
);
9308 tmp
= load_reg(s
, i
);
9310 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9311 tcg_temp_free_i32(tmp
);
9314 /* no need to add after the last transfer */
9316 tcg_gen_addi_i32(addr
, addr
, 4);
9319 if (insn
& (1 << 21)) {
9321 if (insn
& (1 << 23)) {
9322 if (insn
& (1 << 24)) {
9325 /* post increment */
9326 tcg_gen_addi_i32(addr
, addr
, 4);
9329 if (insn
& (1 << 24)) {
9332 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9334 /* post decrement */
9335 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9338 store_reg(s
, rn
, addr
);
9340 tcg_temp_free_i32(addr
);
9343 store_reg(s
, rn
, loaded_var
);
9346 /* Restore CPSR from SPSR. */
9347 tmp
= load_cpu_field(spsr
);
9348 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9349 tcg_temp_free_i32(tmp
);
9350 s
->is_jmp
= DISAS_JUMP
;
9359 /* branch (and link) */
9360 val
= (int32_t)s
->pc
;
9361 if (insn
& (1 << 24)) {
9362 tmp
= tcg_temp_new_i32();
9363 tcg_gen_movi_i32(tmp
, val
);
9364 store_reg(s
, 14, tmp
);
9366 offset
= sextract32(insn
<< 2, 0, 26);
9374 if (((insn
>> 8) & 0xe) == 10) {
9376 if (disas_vfp_insn(s
, insn
)) {
9379 } else if (disas_coproc_insn(s
, insn
)) {
9386 gen_set_pc_im(s
, s
->pc
);
9387 s
->svc_imm
= extract32(insn
, 0, 24);
9388 s
->is_jmp
= DISAS_SWI
;
9392 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9393 default_exception_el(s
));
9399 /* Return true if this is a Thumb-2 logical op. */
9401 thumb2_logic_op(int op
)
9406 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9407 then set condition code flags based on the result of the operation.
9408 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9409 to the high bit of T1.
9410 Returns zero if the opcode is valid. */
9413 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9414 TCGv_i32 t0
, TCGv_i32 t1
)
9421 tcg_gen_and_i32(t0
, t0
, t1
);
9425 tcg_gen_andc_i32(t0
, t0
, t1
);
9429 tcg_gen_or_i32(t0
, t0
, t1
);
9433 tcg_gen_orc_i32(t0
, t0
, t1
);
9437 tcg_gen_xor_i32(t0
, t0
, t1
);
9442 gen_add_CC(t0
, t0
, t1
);
9444 tcg_gen_add_i32(t0
, t0
, t1
);
9448 gen_adc_CC(t0
, t0
, t1
);
9454 gen_sbc_CC(t0
, t0
, t1
);
9456 gen_sub_carry(t0
, t0
, t1
);
9461 gen_sub_CC(t0
, t0
, t1
);
9463 tcg_gen_sub_i32(t0
, t0
, t1
);
9467 gen_sub_CC(t0
, t1
, t0
);
9469 tcg_gen_sub_i32(t0
, t1
, t0
);
9471 default: /* 5, 6, 7, 9, 12, 15. */
9477 gen_set_CF_bit31(t1
);
9482 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9484 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9486 uint32_t insn
, imm
, shift
, offset
;
9487 uint32_t rd
, rn
, rm
, rs
;
9498 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9499 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9500 /* Thumb-1 cores may need to treat bl and blx as a pair of
9501 16-bit instructions to get correct prefetch abort behavior. */
9503 if ((insn
& (1 << 12)) == 0) {
9505 /* Second half of blx. */
9506 offset
= ((insn
& 0x7ff) << 1);
9507 tmp
= load_reg(s
, 14);
9508 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9509 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9511 tmp2
= tcg_temp_new_i32();
9512 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9513 store_reg(s
, 14, tmp2
);
9517 if (insn
& (1 << 11)) {
9518 /* Second half of bl. */
9519 offset
= ((insn
& 0x7ff) << 1) | 1;
9520 tmp
= load_reg(s
, 14);
9521 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9523 tmp2
= tcg_temp_new_i32();
9524 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9525 store_reg(s
, 14, tmp2
);
9529 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9530 /* Instruction spans a page boundary. Implement it as two
9531 16-bit instructions in case the second half causes an
9533 offset
= ((int32_t)insn
<< 21) >> 9;
9534 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9537 /* Fall through to 32-bit decode. */
9540 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9542 insn
|= (uint32_t)insn_hw1
<< 16;
9544 if ((insn
& 0xf800e800) != 0xf000e800) {
9548 rn
= (insn
>> 16) & 0xf;
9549 rs
= (insn
>> 12) & 0xf;
9550 rd
= (insn
>> 8) & 0xf;
9552 switch ((insn
>> 25) & 0xf) {
9553 case 0: case 1: case 2: case 3:
9554 /* 16-bit instructions. Should never happen. */
9557 if (insn
& (1 << 22)) {
9558 /* Other load/store, table branch. */
9559 if (insn
& 0x01200000) {
9560 /* Load/store doubleword. */
9562 addr
= tcg_temp_new_i32();
9563 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9565 addr
= load_reg(s
, rn
);
9567 offset
= (insn
& 0xff) * 4;
9568 if ((insn
& (1 << 23)) == 0)
9570 if (insn
& (1 << 24)) {
9571 tcg_gen_addi_i32(addr
, addr
, offset
);
9574 if (insn
& (1 << 20)) {
9576 tmp
= tcg_temp_new_i32();
9577 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9578 store_reg(s
, rs
, tmp
);
9579 tcg_gen_addi_i32(addr
, addr
, 4);
9580 tmp
= tcg_temp_new_i32();
9581 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9582 store_reg(s
, rd
, tmp
);
9585 tmp
= load_reg(s
, rs
);
9586 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9587 tcg_temp_free_i32(tmp
);
9588 tcg_gen_addi_i32(addr
, addr
, 4);
9589 tmp
= load_reg(s
, rd
);
9590 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9591 tcg_temp_free_i32(tmp
);
9593 if (insn
& (1 << 21)) {
9594 /* Base writeback. */
9597 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9598 store_reg(s
, rn
, addr
);
9600 tcg_temp_free_i32(addr
);
9602 } else if ((insn
& (1 << 23)) == 0) {
9603 /* Load/store exclusive word. */
9604 addr
= tcg_temp_local_new_i32();
9605 load_reg_var(s
, addr
, rn
);
9606 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9607 if (insn
& (1 << 20)) {
9608 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9610 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9612 tcg_temp_free_i32(addr
);
9613 } else if ((insn
& (7 << 5)) == 0) {
9616 addr
= tcg_temp_new_i32();
9617 tcg_gen_movi_i32(addr
, s
->pc
);
9619 addr
= load_reg(s
, rn
);
9621 tmp
= load_reg(s
, rm
);
9622 tcg_gen_add_i32(addr
, addr
, tmp
);
9623 if (insn
& (1 << 4)) {
9625 tcg_gen_add_i32(addr
, addr
, tmp
);
9626 tcg_temp_free_i32(tmp
);
9627 tmp
= tcg_temp_new_i32();
9628 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9630 tcg_temp_free_i32(tmp
);
9631 tmp
= tcg_temp_new_i32();
9632 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9634 tcg_temp_free_i32(addr
);
9635 tcg_gen_shli_i32(tmp
, tmp
, 1);
9636 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9637 store_reg(s
, 15, tmp
);
9639 int op2
= (insn
>> 6) & 0x3;
9640 op
= (insn
>> 4) & 0x3;
9645 /* Load/store exclusive byte/halfword/doubleword */
9652 /* Load-acquire/store-release */
9658 /* Load-acquire/store-release exclusive */
9662 addr
= tcg_temp_local_new_i32();
9663 load_reg_var(s
, addr
, rn
);
9665 if (insn
& (1 << 20)) {
9666 tmp
= tcg_temp_new_i32();
9669 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9672 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9675 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9680 store_reg(s
, rs
, tmp
);
9682 tmp
= load_reg(s
, rs
);
9685 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
9688 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
9691 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9696 tcg_temp_free_i32(tmp
);
9698 } else if (insn
& (1 << 20)) {
9699 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9701 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9703 tcg_temp_free_i32(addr
);
9706 /* Load/store multiple, RFE, SRS. */
9707 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9708 /* RFE, SRS: not available in user mode or on M profile */
9709 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9712 if (insn
& (1 << 20)) {
9714 addr
= load_reg(s
, rn
);
9715 if ((insn
& (1 << 24)) == 0)
9716 tcg_gen_addi_i32(addr
, addr
, -8);
9717 /* Load PC into tmp and CPSR into tmp2. */
9718 tmp
= tcg_temp_new_i32();
9719 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9720 tcg_gen_addi_i32(addr
, addr
, 4);
9721 tmp2
= tcg_temp_new_i32();
9722 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9723 if (insn
& (1 << 21)) {
9724 /* Base writeback. */
9725 if (insn
& (1 << 24)) {
9726 tcg_gen_addi_i32(addr
, addr
, 4);
9728 tcg_gen_addi_i32(addr
, addr
, -4);
9730 store_reg(s
, rn
, addr
);
9732 tcg_temp_free_i32(addr
);
9734 gen_rfe(s
, tmp
, tmp2
);
9737 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9741 int i
, loaded_base
= 0;
9742 TCGv_i32 loaded_var
;
9743 /* Load/store multiple. */
9744 addr
= load_reg(s
, rn
);
9746 for (i
= 0; i
< 16; i
++) {
9747 if (insn
& (1 << i
))
9750 if (insn
& (1 << 24)) {
9751 tcg_gen_addi_i32(addr
, addr
, -offset
);
9754 TCGV_UNUSED_I32(loaded_var
);
9755 for (i
= 0; i
< 16; i
++) {
9756 if ((insn
& (1 << i
)) == 0)
9758 if (insn
& (1 << 20)) {
9760 tmp
= tcg_temp_new_i32();
9761 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9764 } else if (i
== rn
) {
9768 store_reg(s
, i
, tmp
);
9772 tmp
= load_reg(s
, i
);
9773 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9774 tcg_temp_free_i32(tmp
);
9776 tcg_gen_addi_i32(addr
, addr
, 4);
9779 store_reg(s
, rn
, loaded_var
);
9781 if (insn
& (1 << 21)) {
9782 /* Base register writeback. */
9783 if (insn
& (1 << 24)) {
9784 tcg_gen_addi_i32(addr
, addr
, -offset
);
9786 /* Fault if writeback register is in register list. */
9787 if (insn
& (1 << rn
))
9789 store_reg(s
, rn
, addr
);
9791 tcg_temp_free_i32(addr
);
9798 op
= (insn
>> 21) & 0xf;
9800 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9803 /* Halfword pack. */
9804 tmp
= load_reg(s
, rn
);
9805 tmp2
= load_reg(s
, rm
);
9806 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9807 if (insn
& (1 << 5)) {
9811 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9812 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9813 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9817 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9818 tcg_gen_ext16u_i32(tmp
, tmp
);
9819 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9821 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9822 tcg_temp_free_i32(tmp2
);
9823 store_reg(s
, rd
, tmp
);
9825 /* Data processing register constant shift. */
9827 tmp
= tcg_temp_new_i32();
9828 tcg_gen_movi_i32(tmp
, 0);
9830 tmp
= load_reg(s
, rn
);
9832 tmp2
= load_reg(s
, rm
);
9834 shiftop
= (insn
>> 4) & 3;
9835 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9836 conds
= (insn
& (1 << 20)) != 0;
9837 logic_cc
= (conds
&& thumb2_logic_op(op
));
9838 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9839 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9841 tcg_temp_free_i32(tmp2
);
9843 store_reg(s
, rd
, tmp
);
9845 tcg_temp_free_i32(tmp
);
9849 case 13: /* Misc data processing. */
9850 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9851 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9854 case 0: /* Register controlled shift. */
9855 tmp
= load_reg(s
, rn
);
9856 tmp2
= load_reg(s
, rm
);
9857 if ((insn
& 0x70) != 0)
9859 op
= (insn
>> 21) & 3;
9860 logic_cc
= (insn
& (1 << 20)) != 0;
9861 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9864 store_reg_bx(s
, rd
, tmp
);
9866 case 1: /* Sign/zero extend. */
9867 op
= (insn
>> 20) & 7;
9869 case 0: /* SXTAH, SXTH */
9870 case 1: /* UXTAH, UXTH */
9871 case 4: /* SXTAB, SXTB */
9872 case 5: /* UXTAB, UXTB */
9874 case 2: /* SXTAB16, SXTB16 */
9875 case 3: /* UXTAB16, UXTB16 */
9876 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9884 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9888 tmp
= load_reg(s
, rm
);
9889 shift
= (insn
>> 4) & 3;
9890 /* ??? In many cases it's not necessary to do a
9891 rotate, a shift is sufficient. */
9893 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9894 op
= (insn
>> 20) & 7;
9896 case 0: gen_sxth(tmp
); break;
9897 case 1: gen_uxth(tmp
); break;
9898 case 2: gen_sxtb16(tmp
); break;
9899 case 3: gen_uxtb16(tmp
); break;
9900 case 4: gen_sxtb(tmp
); break;
9901 case 5: gen_uxtb(tmp
); break;
9903 g_assert_not_reached();
9906 tmp2
= load_reg(s
, rn
);
9907 if ((op
>> 1) == 1) {
9908 gen_add16(tmp
, tmp2
);
9910 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9911 tcg_temp_free_i32(tmp2
);
9914 store_reg(s
, rd
, tmp
);
9916 case 2: /* SIMD add/subtract. */
9917 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9920 op
= (insn
>> 20) & 7;
9921 shift
= (insn
>> 4) & 7;
9922 if ((op
& 3) == 3 || (shift
& 3) == 3)
9924 tmp
= load_reg(s
, rn
);
9925 tmp2
= load_reg(s
, rm
);
9926 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9927 tcg_temp_free_i32(tmp2
);
9928 store_reg(s
, rd
, tmp
);
9930 case 3: /* Other data processing. */
9931 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9933 /* Saturating add/subtract. */
9934 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9937 tmp
= load_reg(s
, rn
);
9938 tmp2
= load_reg(s
, rm
);
9940 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9942 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9944 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9945 tcg_temp_free_i32(tmp2
);
9948 case 0x0a: /* rbit */
9949 case 0x08: /* rev */
9950 case 0x09: /* rev16 */
9951 case 0x0b: /* revsh */
9952 case 0x18: /* clz */
9954 case 0x10: /* sel */
9955 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9959 case 0x20: /* crc32/crc32c */
9965 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
9972 tmp
= load_reg(s
, rn
);
9974 case 0x0a: /* rbit */
9975 gen_helper_rbit(tmp
, tmp
);
9977 case 0x08: /* rev */
9978 tcg_gen_bswap32_i32(tmp
, tmp
);
9980 case 0x09: /* rev16 */
9983 case 0x0b: /* revsh */
9986 case 0x10: /* sel */
9987 tmp2
= load_reg(s
, rm
);
9988 tmp3
= tcg_temp_new_i32();
9989 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9990 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9991 tcg_temp_free_i32(tmp3
);
9992 tcg_temp_free_i32(tmp2
);
9994 case 0x18: /* clz */
9995 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10005 uint32_t sz
= op
& 0x3;
10006 uint32_t c
= op
& 0x8;
10008 tmp2
= load_reg(s
, rm
);
10010 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10011 } else if (sz
== 1) {
10012 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10014 tmp3
= tcg_const_i32(1 << sz
);
10016 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10018 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10020 tcg_temp_free_i32(tmp2
);
10021 tcg_temp_free_i32(tmp3
);
10025 g_assert_not_reached();
10028 store_reg(s
, rd
, tmp
);
10030 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10031 switch ((insn
>> 20) & 7) {
10032 case 0: /* 32 x 32 -> 32 */
10033 case 7: /* Unsigned sum of absolute differences. */
10035 case 1: /* 16 x 16 -> 32 */
10036 case 2: /* Dual multiply add. */
10037 case 3: /* 32 * 16 -> 32msb */
10038 case 4: /* Dual multiply subtract. */
10039 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10040 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10045 op
= (insn
>> 4) & 0xf;
10046 tmp
= load_reg(s
, rn
);
10047 tmp2
= load_reg(s
, rm
);
10048 switch ((insn
>> 20) & 7) {
10049 case 0: /* 32 x 32 -> 32 */
10050 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10051 tcg_temp_free_i32(tmp2
);
10053 tmp2
= load_reg(s
, rs
);
10055 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10057 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10058 tcg_temp_free_i32(tmp2
);
10061 case 1: /* 16 x 16 -> 32 */
10062 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10063 tcg_temp_free_i32(tmp2
);
10065 tmp2
= load_reg(s
, rs
);
10066 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10067 tcg_temp_free_i32(tmp2
);
10070 case 2: /* Dual multiply add. */
10071 case 4: /* Dual multiply subtract. */
10073 gen_swap_half(tmp2
);
10074 gen_smul_dual(tmp
, tmp2
);
10075 if (insn
& (1 << 22)) {
10076 /* This subtraction cannot overflow. */
10077 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10079 /* This addition cannot overflow 32 bits;
10080 * however it may overflow considered as a signed
10081 * operation, in which case we must set the Q flag.
10083 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10085 tcg_temp_free_i32(tmp2
);
10088 tmp2
= load_reg(s
, rs
);
10089 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10090 tcg_temp_free_i32(tmp2
);
10093 case 3: /* 32 * 16 -> 32msb */
10095 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10098 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10099 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10100 tmp
= tcg_temp_new_i32();
10101 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10102 tcg_temp_free_i64(tmp64
);
10105 tmp2
= load_reg(s
, rs
);
10106 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10107 tcg_temp_free_i32(tmp2
);
10110 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10111 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10113 tmp
= load_reg(s
, rs
);
10114 if (insn
& (1 << 20)) {
10115 tmp64
= gen_addq_msw(tmp64
, tmp
);
10117 tmp64
= gen_subq_msw(tmp64
, tmp
);
10120 if (insn
& (1 << 4)) {
10121 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10123 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10124 tmp
= tcg_temp_new_i32();
10125 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10126 tcg_temp_free_i64(tmp64
);
10128 case 7: /* Unsigned sum of absolute differences. */
10129 gen_helper_usad8(tmp
, tmp
, tmp2
);
10130 tcg_temp_free_i32(tmp2
);
10132 tmp2
= load_reg(s
, rs
);
10133 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10134 tcg_temp_free_i32(tmp2
);
10138 store_reg(s
, rd
, tmp
);
10140 case 6: case 7: /* 64-bit multiply, Divide. */
10141 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10142 tmp
= load_reg(s
, rn
);
10143 tmp2
= load_reg(s
, rm
);
10144 if ((op
& 0x50) == 0x10) {
10146 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10150 gen_helper_udiv(tmp
, tmp
, tmp2
);
10152 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10153 tcg_temp_free_i32(tmp2
);
10154 store_reg(s
, rd
, tmp
);
10155 } else if ((op
& 0xe) == 0xc) {
10156 /* Dual multiply accumulate long. */
10157 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10158 tcg_temp_free_i32(tmp
);
10159 tcg_temp_free_i32(tmp2
);
10163 gen_swap_half(tmp2
);
10164 gen_smul_dual(tmp
, tmp2
);
10166 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10168 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10170 tcg_temp_free_i32(tmp2
);
10172 tmp64
= tcg_temp_new_i64();
10173 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10174 tcg_temp_free_i32(tmp
);
10175 gen_addq(s
, tmp64
, rs
, rd
);
10176 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10177 tcg_temp_free_i64(tmp64
);
10180 /* Unsigned 64-bit multiply */
10181 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10185 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10186 tcg_temp_free_i32(tmp2
);
10187 tcg_temp_free_i32(tmp
);
10190 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10191 tcg_temp_free_i32(tmp2
);
10192 tmp64
= tcg_temp_new_i64();
10193 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10194 tcg_temp_free_i32(tmp
);
10196 /* Signed 64-bit multiply */
10197 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10202 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10203 tcg_temp_free_i64(tmp64
);
10206 gen_addq_lo(s
, tmp64
, rs
);
10207 gen_addq_lo(s
, tmp64
, rd
);
10208 } else if (op
& 0x40) {
10209 /* 64-bit accumulate. */
10210 gen_addq(s
, tmp64
, rs
, rd
);
10212 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10213 tcg_temp_free_i64(tmp64
);
10218 case 6: case 7: case 14: case 15:
10220 if (((insn
>> 24) & 3) == 3) {
10221 /* Translate into the equivalent ARM encoding. */
10222 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10223 if (disas_neon_data_insn(s
, insn
)) {
10226 } else if (((insn
>> 8) & 0xe) == 10) {
10227 if (disas_vfp_insn(s
, insn
)) {
10231 if (insn
& (1 << 28))
10233 if (disas_coproc_insn(s
, insn
)) {
10238 case 8: case 9: case 10: case 11:
10239 if (insn
& (1 << 15)) {
10240 /* Branches, misc control. */
10241 if (insn
& 0x5000) {
10242 /* Unconditional branch. */
10243 /* signextend(hw1[10:0]) -> offset[:12]. */
10244 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10245 /* hw1[10:0] -> offset[11:1]. */
10246 offset
|= (insn
& 0x7ff) << 1;
10247 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10248 offset[24:22] already have the same value because of the
10249 sign extension above. */
10250 offset
^= ((~insn
) & (1 << 13)) << 10;
10251 offset
^= ((~insn
) & (1 << 11)) << 11;
10253 if (insn
& (1 << 14)) {
10254 /* Branch and link. */
10255 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10259 if (insn
& (1 << 12)) {
10261 gen_jmp(s
, offset
);
10264 offset
&= ~(uint32_t)2;
10265 /* thumb2 bx, no need to check */
10266 gen_bx_im(s
, offset
);
10268 } else if (((insn
>> 23) & 7) == 7) {
10270 if (insn
& (1 << 13))
10273 if (insn
& (1 << 26)) {
10274 if (!(insn
& (1 << 20))) {
10275 /* Hypervisor call (v7) */
10276 int imm16
= extract32(insn
, 16, 4) << 12
10277 | extract32(insn
, 0, 12);
10284 /* Secure monitor call (v6+) */
10292 op
= (insn
>> 20) & 7;
10294 case 0: /* msr cpsr. */
10295 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10296 tmp
= load_reg(s
, rn
);
10297 addr
= tcg_const_i32(insn
& 0xff);
10298 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10299 tcg_temp_free_i32(addr
);
10300 tcg_temp_free_i32(tmp
);
10305 case 1: /* msr spsr. */
10306 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10310 if (extract32(insn
, 5, 1)) {
10312 int sysm
= extract32(insn
, 8, 4) |
10313 (extract32(insn
, 4, 1) << 4);
10316 gen_msr_banked(s
, r
, sysm
, rm
);
10320 /* MSR (for PSRs) */
10321 tmp
= load_reg(s
, rn
);
10323 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10327 case 2: /* cps, nop-hint. */
10328 if (((insn
>> 8) & 7) == 0) {
10329 gen_nop_hint(s
, insn
& 0xff);
10331 /* Implemented as NOP in user mode. */
10336 if (insn
& (1 << 10)) {
10337 if (insn
& (1 << 7))
10339 if (insn
& (1 << 6))
10341 if (insn
& (1 << 5))
10343 if (insn
& (1 << 9))
10344 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10346 if (insn
& (1 << 8)) {
10348 imm
|= (insn
& 0x1f);
10351 gen_set_psr_im(s
, offset
, 0, imm
);
10354 case 3: /* Special control operations. */
10356 op
= (insn
>> 4) & 0xf;
10358 case 2: /* clrex */
10363 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10366 /* We need to break the TB after this insn
10367 * to execute self-modifying code correctly
10368 * and also to take any pending interrupts
10378 /* Trivial implementation equivalent to bx. */
10379 tmp
= load_reg(s
, rn
);
10382 case 5: /* Exception return. */
10386 if (rn
!= 14 || rd
!= 15) {
10389 tmp
= load_reg(s
, rn
);
10390 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10391 gen_exception_return(s
, tmp
);
10394 if (extract32(insn
, 5, 1)) {
10396 int sysm
= extract32(insn
, 16, 4) |
10397 (extract32(insn
, 4, 1) << 4);
10399 gen_mrs_banked(s
, 0, sysm
, rd
);
10404 tmp
= tcg_temp_new_i32();
10405 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10406 addr
= tcg_const_i32(insn
& 0xff);
10407 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10408 tcg_temp_free_i32(addr
);
10410 gen_helper_cpsr_read(tmp
, cpu_env
);
10412 store_reg(s
, rd
, tmp
);
10415 if (extract32(insn
, 5, 1)) {
10417 int sysm
= extract32(insn
, 16, 4) |
10418 (extract32(insn
, 4, 1) << 4);
10420 gen_mrs_banked(s
, 1, sysm
, rd
);
10425 /* Not accessible in user mode. */
10426 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10429 tmp
= load_cpu_field(spsr
);
10430 store_reg(s
, rd
, tmp
);
10435 /* Conditional branch. */
10436 op
= (insn
>> 22) & 0xf;
10437 /* Generate a conditional jump to next instruction. */
10438 s
->condlabel
= gen_new_label();
10439 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10442 /* offset[11:1] = insn[10:0] */
10443 offset
= (insn
& 0x7ff) << 1;
10444 /* offset[17:12] = insn[21:16]. */
10445 offset
|= (insn
& 0x003f0000) >> 4;
10446 /* offset[31:20] = insn[26]. */
10447 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10448 /* offset[18] = insn[13]. */
10449 offset
|= (insn
& (1 << 13)) << 5;
10450 /* offset[19] = insn[11]. */
10451 offset
|= (insn
& (1 << 11)) << 8;
10453 /* jump to the offset */
10454 gen_jmp(s
, s
->pc
+ offset
);
10457 /* Data processing immediate. */
10458 if (insn
& (1 << 25)) {
10459 if (insn
& (1 << 24)) {
10460 if (insn
& (1 << 20))
10462 /* Bitfield/Saturate. */
10463 op
= (insn
>> 21) & 7;
10465 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10467 tmp
= tcg_temp_new_i32();
10468 tcg_gen_movi_i32(tmp
, 0);
10470 tmp
= load_reg(s
, rn
);
10473 case 2: /* Signed bitfield extract. */
10475 if (shift
+ imm
> 32)
10478 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
10481 case 6: /* Unsigned bitfield extract. */
10483 if (shift
+ imm
> 32)
10486 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
10489 case 3: /* Bitfield insert/clear. */
10492 imm
= imm
+ 1 - shift
;
10494 tmp2
= load_reg(s
, rd
);
10495 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10496 tcg_temp_free_i32(tmp2
);
10501 default: /* Saturate. */
10504 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10506 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10508 tmp2
= tcg_const_i32(imm
);
10511 if ((op
& 1) && shift
== 0) {
10512 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10513 tcg_temp_free_i32(tmp
);
10514 tcg_temp_free_i32(tmp2
);
10517 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10519 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10523 if ((op
& 1) && shift
== 0) {
10524 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10525 tcg_temp_free_i32(tmp
);
10526 tcg_temp_free_i32(tmp2
);
10529 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10531 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10534 tcg_temp_free_i32(tmp2
);
10537 store_reg(s
, rd
, tmp
);
10539 imm
= ((insn
& 0x04000000) >> 15)
10540 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10541 if (insn
& (1 << 22)) {
10542 /* 16-bit immediate. */
10543 imm
|= (insn
>> 4) & 0xf000;
10544 if (insn
& (1 << 23)) {
10546 tmp
= load_reg(s
, rd
);
10547 tcg_gen_ext16u_i32(tmp
, tmp
);
10548 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10551 tmp
= tcg_temp_new_i32();
10552 tcg_gen_movi_i32(tmp
, imm
);
10555 /* Add/sub 12-bit immediate. */
10557 offset
= s
->pc
& ~(uint32_t)3;
10558 if (insn
& (1 << 23))
10562 tmp
= tcg_temp_new_i32();
10563 tcg_gen_movi_i32(tmp
, offset
);
10565 tmp
= load_reg(s
, rn
);
10566 if (insn
& (1 << 23))
10567 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10569 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10572 store_reg(s
, rd
, tmp
);
10575 int shifter_out
= 0;
10576 /* modified 12-bit immediate. */
10577 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10578 imm
= (insn
& 0xff);
10581 /* Nothing to do. */
10583 case 1: /* 00XY00XY */
10586 case 2: /* XY00XY00 */
10590 case 3: /* XYXYXYXY */
10594 default: /* Rotated constant. */
10595 shift
= (shift
<< 1) | (imm
>> 7);
10597 imm
= imm
<< (32 - shift
);
10601 tmp2
= tcg_temp_new_i32();
10602 tcg_gen_movi_i32(tmp2
, imm
);
10603 rn
= (insn
>> 16) & 0xf;
10605 tmp
= tcg_temp_new_i32();
10606 tcg_gen_movi_i32(tmp
, 0);
10608 tmp
= load_reg(s
, rn
);
10610 op
= (insn
>> 21) & 0xf;
10611 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10612 shifter_out
, tmp
, tmp2
))
10614 tcg_temp_free_i32(tmp2
);
10615 rd
= (insn
>> 8) & 0xf;
10617 store_reg(s
, rd
, tmp
);
10619 tcg_temp_free_i32(tmp
);
10624 case 12: /* Load/store single data item. */
10629 if ((insn
& 0x01100000) == 0x01000000) {
10630 if (disas_neon_ls_insn(s
, insn
)) {
10635 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10637 if (!(insn
& (1 << 20))) {
10641 /* Byte or halfword load space with dest == r15 : memory hints.
10642 * Catch them early so we don't emit pointless addressing code.
10643 * This space is a mix of:
10644 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10645 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10647 * unallocated hints, which must be treated as NOPs
10648 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10649 * which is easiest for the decoding logic
10650 * Some space which must UNDEF
10652 int op1
= (insn
>> 23) & 3;
10653 int op2
= (insn
>> 6) & 0x3f;
10658 /* UNPREDICTABLE, unallocated hint or
10659 * PLD/PLDW/PLI (literal)
10664 return 0; /* PLD/PLDW/PLI or unallocated hint */
10666 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10667 return 0; /* PLD/PLDW/PLI or unallocated hint */
10669 /* UNDEF space, or an UNPREDICTABLE */
10673 memidx
= get_mem_index(s
);
10675 addr
= tcg_temp_new_i32();
10677 /* s->pc has already been incremented by 4. */
10678 imm
= s
->pc
& 0xfffffffc;
10679 if (insn
& (1 << 23))
10680 imm
+= insn
& 0xfff;
10682 imm
-= insn
& 0xfff;
10683 tcg_gen_movi_i32(addr
, imm
);
10685 addr
= load_reg(s
, rn
);
10686 if (insn
& (1 << 23)) {
10687 /* Positive offset. */
10688 imm
= insn
& 0xfff;
10689 tcg_gen_addi_i32(addr
, addr
, imm
);
10692 switch ((insn
>> 8) & 0xf) {
10693 case 0x0: /* Shifted Register. */
10694 shift
= (insn
>> 4) & 0xf;
10696 tcg_temp_free_i32(addr
);
10699 tmp
= load_reg(s
, rm
);
10701 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10702 tcg_gen_add_i32(addr
, addr
, tmp
);
10703 tcg_temp_free_i32(tmp
);
10705 case 0xc: /* Negative offset. */
10706 tcg_gen_addi_i32(addr
, addr
, -imm
);
10708 case 0xe: /* User privilege. */
10709 tcg_gen_addi_i32(addr
, addr
, imm
);
10710 memidx
= get_a32_user_mem_index(s
);
10712 case 0x9: /* Post-decrement. */
10714 /* Fall through. */
10715 case 0xb: /* Post-increment. */
10719 case 0xd: /* Pre-decrement. */
10721 /* Fall through. */
10722 case 0xf: /* Pre-increment. */
10723 tcg_gen_addi_i32(addr
, addr
, imm
);
10727 tcg_temp_free_i32(addr
);
10732 if (insn
& (1 << 20)) {
10734 tmp
= tcg_temp_new_i32();
10737 gen_aa32_ld8u(s
, tmp
, addr
, memidx
);
10740 gen_aa32_ld8s(s
, tmp
, addr
, memidx
);
10743 gen_aa32_ld16u(s
, tmp
, addr
, memidx
);
10746 gen_aa32_ld16s(s
, tmp
, addr
, memidx
);
10749 gen_aa32_ld32u(s
, tmp
, addr
, memidx
);
10752 tcg_temp_free_i32(tmp
);
10753 tcg_temp_free_i32(addr
);
10759 store_reg(s
, rs
, tmp
);
10763 tmp
= load_reg(s
, rs
);
10766 gen_aa32_st8(s
, tmp
, addr
, memidx
);
10769 gen_aa32_st16(s
, tmp
, addr
, memidx
);
10772 gen_aa32_st32(s
, tmp
, addr
, memidx
);
10775 tcg_temp_free_i32(tmp
);
10776 tcg_temp_free_i32(addr
);
10779 tcg_temp_free_i32(tmp
);
10782 tcg_gen_addi_i32(addr
, addr
, imm
);
10784 store_reg(s
, rn
, addr
);
10786 tcg_temp_free_i32(addr
);
10798 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10800 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10807 if (s
->condexec_mask
) {
10808 cond
= s
->condexec_cond
;
10809 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10810 s
->condlabel
= gen_new_label();
10811 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10816 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
10819 switch (insn
>> 12) {
10823 op
= (insn
>> 11) & 3;
10826 rn
= (insn
>> 3) & 7;
10827 tmp
= load_reg(s
, rn
);
10828 if (insn
& (1 << 10)) {
10830 tmp2
= tcg_temp_new_i32();
10831 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10834 rm
= (insn
>> 6) & 7;
10835 tmp2
= load_reg(s
, rm
);
10837 if (insn
& (1 << 9)) {
10838 if (s
->condexec_mask
)
10839 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10841 gen_sub_CC(tmp
, tmp
, tmp2
);
10843 if (s
->condexec_mask
)
10844 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10846 gen_add_CC(tmp
, tmp
, tmp2
);
10848 tcg_temp_free_i32(tmp2
);
10849 store_reg(s
, rd
, tmp
);
10851 /* shift immediate */
10852 rm
= (insn
>> 3) & 7;
10853 shift
= (insn
>> 6) & 0x1f;
10854 tmp
= load_reg(s
, rm
);
10855 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10856 if (!s
->condexec_mask
)
10858 store_reg(s
, rd
, tmp
);
10862 /* arithmetic large immediate */
10863 op
= (insn
>> 11) & 3;
10864 rd
= (insn
>> 8) & 0x7;
10865 if (op
== 0) { /* mov */
10866 tmp
= tcg_temp_new_i32();
10867 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10868 if (!s
->condexec_mask
)
10870 store_reg(s
, rd
, tmp
);
10872 tmp
= load_reg(s
, rd
);
10873 tmp2
= tcg_temp_new_i32();
10874 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10877 gen_sub_CC(tmp
, tmp
, tmp2
);
10878 tcg_temp_free_i32(tmp
);
10879 tcg_temp_free_i32(tmp2
);
10882 if (s
->condexec_mask
)
10883 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10885 gen_add_CC(tmp
, tmp
, tmp2
);
10886 tcg_temp_free_i32(tmp2
);
10887 store_reg(s
, rd
, tmp
);
10890 if (s
->condexec_mask
)
10891 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10893 gen_sub_CC(tmp
, tmp
, tmp2
);
10894 tcg_temp_free_i32(tmp2
);
10895 store_reg(s
, rd
, tmp
);
10901 if (insn
& (1 << 11)) {
10902 rd
= (insn
>> 8) & 7;
10903 /* load pc-relative. Bit 1 of PC is ignored. */
10904 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10905 val
&= ~(uint32_t)2;
10906 addr
= tcg_temp_new_i32();
10907 tcg_gen_movi_i32(addr
, val
);
10908 tmp
= tcg_temp_new_i32();
10909 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10910 tcg_temp_free_i32(addr
);
10911 store_reg(s
, rd
, tmp
);
10914 if (insn
& (1 << 10)) {
10915 /* data processing extended or blx */
10916 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10917 rm
= (insn
>> 3) & 0xf;
10918 op
= (insn
>> 8) & 3;
10921 tmp
= load_reg(s
, rd
);
10922 tmp2
= load_reg(s
, rm
);
10923 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10924 tcg_temp_free_i32(tmp2
);
10925 store_reg(s
, rd
, tmp
);
10928 tmp
= load_reg(s
, rd
);
10929 tmp2
= load_reg(s
, rm
);
10930 gen_sub_CC(tmp
, tmp
, tmp2
);
10931 tcg_temp_free_i32(tmp2
);
10932 tcg_temp_free_i32(tmp
);
10934 case 2: /* mov/cpy */
10935 tmp
= load_reg(s
, rm
);
10936 store_reg(s
, rd
, tmp
);
10938 case 3:/* branch [and link] exchange thumb register */
10939 tmp
= load_reg(s
, rm
);
10940 if (insn
& (1 << 7)) {
10942 val
= (uint32_t)s
->pc
| 1;
10943 tmp2
= tcg_temp_new_i32();
10944 tcg_gen_movi_i32(tmp2
, val
);
10945 store_reg(s
, 14, tmp2
);
10947 /* already thumb, no need to check */
10954 /* data processing register */
10956 rm
= (insn
>> 3) & 7;
10957 op
= (insn
>> 6) & 0xf;
10958 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10959 /* the shift/rotate ops want the operands backwards */
10968 if (op
== 9) { /* neg */
10969 tmp
= tcg_temp_new_i32();
10970 tcg_gen_movi_i32(tmp
, 0);
10971 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10972 tmp
= load_reg(s
, rd
);
10974 TCGV_UNUSED_I32(tmp
);
10977 tmp2
= load_reg(s
, rm
);
10979 case 0x0: /* and */
10980 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10981 if (!s
->condexec_mask
)
10984 case 0x1: /* eor */
10985 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10986 if (!s
->condexec_mask
)
10989 case 0x2: /* lsl */
10990 if (s
->condexec_mask
) {
10991 gen_shl(tmp2
, tmp2
, tmp
);
10993 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10994 gen_logic_CC(tmp2
);
10997 case 0x3: /* lsr */
10998 if (s
->condexec_mask
) {
10999 gen_shr(tmp2
, tmp2
, tmp
);
11001 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11002 gen_logic_CC(tmp2
);
11005 case 0x4: /* asr */
11006 if (s
->condexec_mask
) {
11007 gen_sar(tmp2
, tmp2
, tmp
);
11009 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11010 gen_logic_CC(tmp2
);
11013 case 0x5: /* adc */
11014 if (s
->condexec_mask
) {
11015 gen_adc(tmp
, tmp2
);
11017 gen_adc_CC(tmp
, tmp
, tmp2
);
11020 case 0x6: /* sbc */
11021 if (s
->condexec_mask
) {
11022 gen_sub_carry(tmp
, tmp
, tmp2
);
11024 gen_sbc_CC(tmp
, tmp
, tmp2
);
11027 case 0x7: /* ror */
11028 if (s
->condexec_mask
) {
11029 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11030 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11032 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11033 gen_logic_CC(tmp2
);
11036 case 0x8: /* tst */
11037 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11041 case 0x9: /* neg */
11042 if (s
->condexec_mask
)
11043 tcg_gen_neg_i32(tmp
, tmp2
);
11045 gen_sub_CC(tmp
, tmp
, tmp2
);
11047 case 0xa: /* cmp */
11048 gen_sub_CC(tmp
, tmp
, tmp2
);
11051 case 0xb: /* cmn */
11052 gen_add_CC(tmp
, tmp
, tmp2
);
11055 case 0xc: /* orr */
11056 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11057 if (!s
->condexec_mask
)
11060 case 0xd: /* mul */
11061 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11062 if (!s
->condexec_mask
)
11065 case 0xe: /* bic */
11066 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11067 if (!s
->condexec_mask
)
11070 case 0xf: /* mvn */
11071 tcg_gen_not_i32(tmp2
, tmp2
);
11072 if (!s
->condexec_mask
)
11073 gen_logic_CC(tmp2
);
11080 store_reg(s
, rm
, tmp2
);
11082 tcg_temp_free_i32(tmp
);
11084 store_reg(s
, rd
, tmp
);
11085 tcg_temp_free_i32(tmp2
);
11088 tcg_temp_free_i32(tmp
);
11089 tcg_temp_free_i32(tmp2
);
11094 /* load/store register offset. */
11096 rn
= (insn
>> 3) & 7;
11097 rm
= (insn
>> 6) & 7;
11098 op
= (insn
>> 9) & 7;
11099 addr
= load_reg(s
, rn
);
11100 tmp
= load_reg(s
, rm
);
11101 tcg_gen_add_i32(addr
, addr
, tmp
);
11102 tcg_temp_free_i32(tmp
);
11104 if (op
< 3) { /* store */
11105 tmp
= load_reg(s
, rd
);
11107 tmp
= tcg_temp_new_i32();
11112 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11115 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11118 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11120 case 3: /* ldrsb */
11121 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
11124 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11127 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11130 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11132 case 7: /* ldrsh */
11133 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
11136 if (op
>= 3) { /* load */
11137 store_reg(s
, rd
, tmp
);
11139 tcg_temp_free_i32(tmp
);
11141 tcg_temp_free_i32(addr
);
11145 /* load/store word immediate offset */
11147 rn
= (insn
>> 3) & 7;
11148 addr
= load_reg(s
, rn
);
11149 val
= (insn
>> 4) & 0x7c;
11150 tcg_gen_addi_i32(addr
, addr
, val
);
11152 if (insn
& (1 << 11)) {
11154 tmp
= tcg_temp_new_i32();
11155 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11156 store_reg(s
, rd
, tmp
);
11159 tmp
= load_reg(s
, rd
);
11160 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11161 tcg_temp_free_i32(tmp
);
11163 tcg_temp_free_i32(addr
);
11167 /* load/store byte immediate offset */
11169 rn
= (insn
>> 3) & 7;
11170 addr
= load_reg(s
, rn
);
11171 val
= (insn
>> 6) & 0x1f;
11172 tcg_gen_addi_i32(addr
, addr
, val
);
11174 if (insn
& (1 << 11)) {
11176 tmp
= tcg_temp_new_i32();
11177 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11178 store_reg(s
, rd
, tmp
);
11181 tmp
= load_reg(s
, rd
);
11182 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11183 tcg_temp_free_i32(tmp
);
11185 tcg_temp_free_i32(addr
);
11189 /* load/store halfword immediate offset */
11191 rn
= (insn
>> 3) & 7;
11192 addr
= load_reg(s
, rn
);
11193 val
= (insn
>> 5) & 0x3e;
11194 tcg_gen_addi_i32(addr
, addr
, val
);
11196 if (insn
& (1 << 11)) {
11198 tmp
= tcg_temp_new_i32();
11199 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11200 store_reg(s
, rd
, tmp
);
11203 tmp
= load_reg(s
, rd
);
11204 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11205 tcg_temp_free_i32(tmp
);
11207 tcg_temp_free_i32(addr
);
11211 /* load/store from stack */
11212 rd
= (insn
>> 8) & 7;
11213 addr
= load_reg(s
, 13);
11214 val
= (insn
& 0xff) * 4;
11215 tcg_gen_addi_i32(addr
, addr
, val
);
11217 if (insn
& (1 << 11)) {
11219 tmp
= tcg_temp_new_i32();
11220 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11221 store_reg(s
, rd
, tmp
);
11224 tmp
= load_reg(s
, rd
);
11225 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11226 tcg_temp_free_i32(tmp
);
11228 tcg_temp_free_i32(addr
);
11232 /* add to high reg */
11233 rd
= (insn
>> 8) & 7;
11234 if (insn
& (1 << 11)) {
11236 tmp
= load_reg(s
, 13);
11238 /* PC. bit 1 is ignored. */
11239 tmp
= tcg_temp_new_i32();
11240 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11242 val
= (insn
& 0xff) * 4;
11243 tcg_gen_addi_i32(tmp
, tmp
, val
);
11244 store_reg(s
, rd
, tmp
);
11249 op
= (insn
>> 8) & 0xf;
11252 /* adjust stack pointer */
11253 tmp
= load_reg(s
, 13);
11254 val
= (insn
& 0x7f) * 4;
11255 if (insn
& (1 << 7))
11256 val
= -(int32_t)val
;
11257 tcg_gen_addi_i32(tmp
, tmp
, val
);
11258 store_reg(s
, 13, tmp
);
11261 case 2: /* sign/zero extend. */
11264 rm
= (insn
>> 3) & 7;
11265 tmp
= load_reg(s
, rm
);
11266 switch ((insn
>> 6) & 3) {
11267 case 0: gen_sxth(tmp
); break;
11268 case 1: gen_sxtb(tmp
); break;
11269 case 2: gen_uxth(tmp
); break;
11270 case 3: gen_uxtb(tmp
); break;
11272 store_reg(s
, rd
, tmp
);
11274 case 4: case 5: case 0xc: case 0xd:
11276 addr
= load_reg(s
, 13);
11277 if (insn
& (1 << 8))
11281 for (i
= 0; i
< 8; i
++) {
11282 if (insn
& (1 << i
))
11285 if ((insn
& (1 << 11)) == 0) {
11286 tcg_gen_addi_i32(addr
, addr
, -offset
);
11288 for (i
= 0; i
< 8; i
++) {
11289 if (insn
& (1 << i
)) {
11290 if (insn
& (1 << 11)) {
11292 tmp
= tcg_temp_new_i32();
11293 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11294 store_reg(s
, i
, tmp
);
11297 tmp
= load_reg(s
, i
);
11298 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11299 tcg_temp_free_i32(tmp
);
11301 /* advance to the next address. */
11302 tcg_gen_addi_i32(addr
, addr
, 4);
11305 TCGV_UNUSED_I32(tmp
);
11306 if (insn
& (1 << 8)) {
11307 if (insn
& (1 << 11)) {
11309 tmp
= tcg_temp_new_i32();
11310 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11311 /* don't set the pc until the rest of the instruction
11315 tmp
= load_reg(s
, 14);
11316 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11317 tcg_temp_free_i32(tmp
);
11319 tcg_gen_addi_i32(addr
, addr
, 4);
11321 if ((insn
& (1 << 11)) == 0) {
11322 tcg_gen_addi_i32(addr
, addr
, -offset
);
11324 /* write back the new stack pointer */
11325 store_reg(s
, 13, addr
);
11326 /* set the new PC value */
11327 if ((insn
& 0x0900) == 0x0900) {
11328 store_reg_from_load(s
, 15, tmp
);
11332 case 1: case 3: case 9: case 11: /* czb */
11334 tmp
= load_reg(s
, rm
);
11335 s
->condlabel
= gen_new_label();
11337 if (insn
& (1 << 11))
11338 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11340 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11341 tcg_temp_free_i32(tmp
);
11342 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11343 val
= (uint32_t)s
->pc
+ 2;
11348 case 15: /* IT, nop-hint. */
11349 if ((insn
& 0xf) == 0) {
11350 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11354 s
->condexec_cond
= (insn
>> 4) & 0xe;
11355 s
->condexec_mask
= insn
& 0x1f;
11356 /* No actual code generated for this insn, just setup state. */
11359 case 0xe: /* bkpt */
11361 int imm8
= extract32(insn
, 0, 8);
11363 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11364 default_exception_el(s
));
11368 case 0xa: /* rev, and hlt */
11370 int op1
= extract32(insn
, 6, 2);
11374 int imm6
= extract32(insn
, 0, 6);
11380 /* Otherwise this is rev */
11382 rn
= (insn
>> 3) & 0x7;
11384 tmp
= load_reg(s
, rn
);
11386 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11387 case 1: gen_rev16(tmp
); break;
11388 case 3: gen_revsh(tmp
); break;
11390 g_assert_not_reached();
11392 store_reg(s
, rd
, tmp
);
11397 switch ((insn
>> 5) & 7) {
11401 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11402 gen_helper_setend(cpu_env
);
11403 s
->is_jmp
= DISAS_UPDATE
;
11412 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11413 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11416 addr
= tcg_const_i32(19);
11417 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11418 tcg_temp_free_i32(addr
);
11422 addr
= tcg_const_i32(16);
11423 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11424 tcg_temp_free_i32(addr
);
11426 tcg_temp_free_i32(tmp
);
11429 if (insn
& (1 << 4)) {
11430 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11434 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11449 /* load/store multiple */
11450 TCGv_i32 loaded_var
;
11451 TCGV_UNUSED_I32(loaded_var
);
11452 rn
= (insn
>> 8) & 0x7;
11453 addr
= load_reg(s
, rn
);
11454 for (i
= 0; i
< 8; i
++) {
11455 if (insn
& (1 << i
)) {
11456 if (insn
& (1 << 11)) {
11458 tmp
= tcg_temp_new_i32();
11459 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11463 store_reg(s
, i
, tmp
);
11467 tmp
= load_reg(s
, i
);
11468 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11469 tcg_temp_free_i32(tmp
);
11471 /* advance to the next address */
11472 tcg_gen_addi_i32(addr
, addr
, 4);
11475 if ((insn
& (1 << rn
)) == 0) {
11476 /* base reg not in list: base register writeback */
11477 store_reg(s
, rn
, addr
);
11479 /* base reg in list: if load, complete it now */
11480 if (insn
& (1 << 11)) {
11481 store_reg(s
, rn
, loaded_var
);
11483 tcg_temp_free_i32(addr
);
11488 /* conditional branch or swi */
11489 cond
= (insn
>> 8) & 0xf;
11495 gen_set_pc_im(s
, s
->pc
);
11496 s
->svc_imm
= extract32(insn
, 0, 8);
11497 s
->is_jmp
= DISAS_SWI
;
11500 /* generate a conditional jump to next instruction */
11501 s
->condlabel
= gen_new_label();
11502 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11505 /* jump to the offset */
11506 val
= (uint32_t)s
->pc
+ 2;
11507 offset
= ((int32_t)insn
<< 24) >> 24;
11508 val
+= offset
<< 1;
11513 if (insn
& (1 << 11)) {
11514 if (disas_thumb2_insn(env
, s
, insn
))
11518 /* unconditional branch */
11519 val
= (uint32_t)s
->pc
;
11520 offset
= ((int32_t)insn
<< 21) >> 21;
11521 val
+= (offset
<< 1) + 2;
11526 if (disas_thumb2_insn(env
, s
, insn
))
11532 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11533 default_exception_el(s
));
11537 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11538 default_exception_el(s
));
11541 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11543 /* Return true if the insn at dc->pc might cross a page boundary.
11544 * (False positives are OK, false negatives are not.)
11548 if ((s
->pc
& 3) == 0) {
11549 /* At a 4-aligned address we can't be crossing a page */
11553 /* This must be a Thumb insn */
11554 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11556 if ((insn
>> 11) >= 0x1d) {
11557 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11558 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11559 * end up actually treating this as two 16-bit insns (see the
11560 * code at the start of disas_thumb2_insn()) but we don't bother
11561 * to check for that as it is unlikely, and false positives here
11566 /* Definitely a 16-bit insn, can't be crossing a page. */
11570 /* generate intermediate code for basic block 'tb'. */
11571 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11573 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11574 CPUState
*cs
= CPU(cpu
);
11575 DisasContext dc1
, *dc
= &dc1
;
11576 target_ulong pc_start
;
11577 target_ulong next_page_start
;
11582 /* generate intermediate code */
11584 /* The A64 decoder has its own top level loop, because it doesn't need
11585 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11587 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11588 gen_intermediate_code_a64(cpu
, tb
);
11596 dc
->is_jmp
= DISAS_NEXT
;
11598 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11602 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11603 * there is no secure EL1, so we route exceptions to EL3.
11605 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11606 !arm_el_is_aa64(env
, 3);
11607 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11608 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(tb
->flags
);
11609 dc
->be_data
= ARM_TBFLAG_BE_DATA(tb
->flags
) ? MO_BE
: MO_LE
;
11610 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11611 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11612 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11613 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11614 #if !defined(CONFIG_USER_ONLY)
11615 dc
->user
= (dc
->current_el
== 0);
11617 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11618 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11619 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11620 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11621 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11622 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11623 dc
->cp_regs
= cpu
->cp_regs
;
11624 dc
->features
= env
->features
;
11626 /* Single step state. The code-generation logic here is:
11628 * generate code with no special handling for single-stepping (except
11629 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11630 * this happens anyway because those changes are all system register or
11632 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11633 * emit code for one insn
11634 * emit code to clear PSTATE.SS
11635 * emit code to generate software step exception for completed step
11636 * end TB (as usual for having generated an exception)
11637 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11638 * emit code to generate a software step exception
11641 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11642 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11643 dc
->is_ldex
= false;
11644 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11646 cpu_F0s
= tcg_temp_new_i32();
11647 cpu_F1s
= tcg_temp_new_i32();
11648 cpu_F0d
= tcg_temp_new_i64();
11649 cpu_F1d
= tcg_temp_new_i64();
11652 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11653 cpu_M0
= tcg_temp_new_i64();
11654 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11656 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11657 if (max_insns
== 0) {
11658 max_insns
= CF_COUNT_MASK
;
11660 if (max_insns
> TCG_MAX_INSNS
) {
11661 max_insns
= TCG_MAX_INSNS
;
11666 tcg_clear_temp_count();
11668 /* A note on handling of the condexec (IT) bits:
11670 * We want to avoid the overhead of having to write the updated condexec
11671 * bits back to the CPUARMState for every instruction in an IT block. So:
11672 * (1) if the condexec bits are not already zero then we write
11673 * zero back into the CPUARMState now. This avoids complications trying
11674 * to do it at the end of the block. (For example if we don't do this
11675 * it's hard to identify whether we can safely skip writing condexec
11676 * at the end of the TB, which we definitely want to do for the case
11677 * where a TB doesn't do anything with the IT state at all.)
11678 * (2) if we are going to leave the TB then we call gen_set_condexec()
11679 * which will write the correct value into CPUARMState if zero is wrong.
11680 * This is done both for leaving the TB at the end, and for leaving
11681 * it because of an exception we know will happen, which is done in
11682 * gen_exception_insn(). The latter is necessary because we need to
11683 * leave the TB with the PC/IT state just prior to execution of the
11684 * instruction which caused the exception.
11685 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11686 * then the CPUARMState will be wrong and we need to reset it.
11687 * This is handled in the same way as restoration of the
11688 * PC in these situations; we save the value of the condexec bits
11689 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11690 * then uses this to restore them after an exception.
11692 * Note that there are no instructions which can read the condexec
11693 * bits, and none which can write non-static values to them, so
11694 * we don't need to care about whether CPUARMState is correct in the
11698 /* Reset the conditional execution bits immediately. This avoids
11699 complications trying to do it at the end of the block. */
11700 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11702 TCGv_i32 tmp
= tcg_temp_new_i32();
11703 tcg_gen_movi_i32(tmp
, 0);
11704 store_cpu_field(tmp
, condexec_bits
);
11707 tcg_gen_insn_start(dc
->pc
,
11708 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11712 #ifdef CONFIG_USER_ONLY
11713 /* Intercept jump to the magic kernel page. */
11714 if (dc
->pc
>= 0xffff0000) {
11715 /* We always get here via a jump, so know we are not in a
11716 conditional execution block. */
11717 gen_exception_internal(EXCP_KERNEL_TRAP
);
11718 dc
->is_jmp
= DISAS_EXC
;
11722 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11723 /* We always get here via a jump, so know we are not in a
11724 conditional execution block. */
11725 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11726 dc
->is_jmp
= DISAS_EXC
;
11731 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11733 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11734 if (bp
->pc
== dc
->pc
) {
11735 if (bp
->flags
& BP_CPU
) {
11736 gen_set_condexec(dc
);
11737 gen_set_pc_im(dc
, dc
->pc
);
11738 gen_helper_check_breakpoints(cpu_env
);
11739 /* End the TB early; it's likely not going to be executed */
11740 dc
->is_jmp
= DISAS_UPDATE
;
11742 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11743 /* The address covered by the breakpoint must be
11744 included in [tb->pc, tb->pc + tb->size) in order
11745 to for it to be properly cleared -- thus we
11746 increment the PC here so that the logic setting
11747 tb->size below does the right thing. */
11748 /* TODO: Advance PC by correct instruction length to
11749 * avoid disassembler error messages */
11751 goto done_generating
;
11758 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11762 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11763 /* Singlestep state is Active-pending.
11764 * If we're in this state at the start of a TB then either
11765 * a) we just took an exception to an EL which is being debugged
11766 * and this is the first insn in the exception handler
11767 * b) debug exceptions were masked and we just unmasked them
11768 * without changing EL (eg by clearing PSTATE.D)
11769 * In either case we're going to take a swstep exception in the
11770 * "did not step an insn" case, and so the syndrome ISV and EX
11771 * bits should be zero.
11773 assert(num_insns
== 1);
11774 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11775 default_exception_el(dc
));
11776 goto done_generating
;
11780 disas_thumb_insn(env
, dc
);
11781 if (dc
->condexec_mask
) {
11782 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11783 | ((dc
->condexec_mask
>> 4) & 1);
11784 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11785 if (dc
->condexec_mask
== 0) {
11786 dc
->condexec_cond
= 0;
11790 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
11792 disas_arm_insn(dc
, insn
);
11795 if (dc
->condjmp
&& !dc
->is_jmp
) {
11796 gen_set_label(dc
->condlabel
);
11800 if (tcg_check_temp_count()) {
11801 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11805 /* Translation stops when a conditional branch is encountered.
11806 * Otherwise the subsequent code could get translated several times.
11807 * Also stop translation when a page boundary is reached. This
11808 * ensures prefetch aborts occur at the right place. */
11810 /* We want to stop the TB if the next insn starts in a new page,
11811 * or if it spans between this page and the next. This means that
11812 * if we're looking at the last halfword in the page we need to
11813 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11814 * or a 32-bit Thumb insn (which won't).
11815 * This is to avoid generating a silly TB with a single 16-bit insn
11816 * in it at the end of this page (which would execute correctly
11817 * but isn't very efficient).
11819 end_of_page
= (dc
->pc
>= next_page_start
) ||
11820 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
11822 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11823 !cs
->singlestep_enabled
&&
11827 num_insns
< max_insns
);
11829 if (tb
->cflags
& CF_LAST_IO
) {
11831 /* FIXME: This can theoretically happen with self-modifying
11833 cpu_abort(cs
, "IO on conditional branch instruction");
11838 /* At this stage dc->condjmp will only be set when the skipped
11839 instruction was a conditional branch or trap, and the PC has
11840 already been written. */
11841 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11842 /* Unconditional and "condition passed" instruction codepath. */
11843 gen_set_condexec(dc
);
11844 switch (dc
->is_jmp
) {
11846 gen_ss_advance(dc
);
11847 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11848 default_exception_el(dc
));
11851 gen_ss_advance(dc
);
11852 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11855 gen_ss_advance(dc
);
11856 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11860 gen_set_pc_im(dc
, dc
->pc
);
11863 if (dc
->ss_active
) {
11864 gen_step_complete_exception(dc
);
11866 /* FIXME: Single stepping a WFI insn will not halt
11868 gen_exception_internal(EXCP_DEBUG
);
11872 /* "Condition failed" instruction codepath. */
11873 gen_set_label(dc
->condlabel
);
11874 gen_set_condexec(dc
);
11875 gen_set_pc_im(dc
, dc
->pc
);
11876 if (dc
->ss_active
) {
11877 gen_step_complete_exception(dc
);
11879 gen_exception_internal(EXCP_DEBUG
);
11883 /* While branches must always occur at the end of an IT block,
11884 there are a few other things that can cause us to terminate
11885 the TB in the middle of an IT block:
11886 - Exception generating instructions (bkpt, swi, undefined).
11888 - Hardware watchpoints.
11889 Hardware breakpoints have already been handled and skip this code.
11891 gen_set_condexec(dc
);
11892 switch(dc
->is_jmp
) {
11894 gen_goto_tb(dc
, 1, dc
->pc
);
11897 gen_set_pc_im(dc
, dc
->pc
);
11901 /* indicate that the hash table must be used to find the next TB */
11902 tcg_gen_exit_tb(0);
11904 case DISAS_TB_JUMP
:
11905 /* nothing more to generate */
11908 gen_helper_wfi(cpu_env
);
11909 /* The helper doesn't necessarily throw an exception, but we
11910 * must go back to the main loop to check for interrupts anyway.
11912 tcg_gen_exit_tb(0);
11915 gen_helper_wfe(cpu_env
);
11918 gen_helper_yield(cpu_env
);
11921 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11922 default_exception_el(dc
));
11925 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11928 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11932 gen_set_label(dc
->condlabel
);
11933 gen_set_condexec(dc
);
11934 gen_goto_tb(dc
, 1, dc
->pc
);
11940 gen_tb_end(tb
, num_insns
);
11943 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
) &&
11944 qemu_log_in_addr_range(pc_start
)) {
11946 qemu_log("----------------\n");
11947 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11948 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
11949 dc
->thumb
| (dc
->sctlr_b
<< 1));
11954 tb
->size
= dc
->pc
- pc_start
;
11955 tb
->icount
= num_insns
;
11958 static const char *cpu_mode_names
[16] = {
11959 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11960 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11963 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11966 ARMCPU
*cpu
= ARM_CPU(cs
);
11967 CPUARMState
*env
= &cpu
->env
;
11970 const char *ns_status
;
11973 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11977 for(i
=0;i
<16;i
++) {
11978 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11980 cpu_fprintf(f
, "\n");
11982 cpu_fprintf(f
, " ");
11984 psr
= cpsr_read(env
);
11986 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
11987 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
11988 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
11993 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
11995 psr
& (1 << 31) ? 'N' : '-',
11996 psr
& (1 << 30) ? 'Z' : '-',
11997 psr
& (1 << 29) ? 'C' : '-',
11998 psr
& (1 << 28) ? 'V' : '-',
11999 psr
& CPSR_T
? 'T' : 'A',
12001 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12003 if (flags
& CPU_DUMP_FPU
) {
12004 int numvfpregs
= 0;
12005 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12008 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12011 for (i
= 0; i
< numvfpregs
; i
++) {
12012 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12013 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12014 i
* 2, (uint32_t)v
,
12015 i
* 2 + 1, (uint32_t)(v
>> 32),
12018 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12022 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12023 target_ulong
*data
)
12027 env
->condexec_bits
= 0;
12028 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12030 env
->regs
[15] = data
[0];
12031 env
->condexec_bits
= data
[1];
12032 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;