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/>.
28 #include "internals.h"
29 #include "disas/disas.h"
32 #include "qemu/bitops.h"
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
38 #include "trace-tcg.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J 0
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
55 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
57 #if defined(CONFIG_USER_ONLY)
60 #define IS_USER(s) (s->user)
64 /* We reuse the same 64-bit temporaries for efficiency. */
65 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
66 static TCGv_i32 cpu_R
[16];
67 static TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
68 static TCGv_i64 cpu_exclusive_addr
;
69 static TCGv_i64 cpu_exclusive_val
;
70 #ifdef CONFIG_USER_ONLY
71 static TCGv_i64 cpu_exclusive_test
;
72 static TCGv_i32 cpu_exclusive_info
;
75 /* FIXME: These should be removed. */
76 static TCGv_i32 cpu_F0s
, cpu_F1s
;
77 static TCGv_i64 cpu_F0d
, cpu_F1d
;
79 #include "exec/gen-icount.h"
81 static const char *regnames
[] =
82 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
83 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
85 /* initialize TCG globals. */
86 void arm_translate_init(void)
90 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
92 for (i
= 0; i
< 16; i
++) {
93 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
94 offsetof(CPUARMState
, regs
[i
]),
97 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
98 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
99 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
100 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
102 cpu_exclusive_addr
= tcg_global_mem_new_i64(TCG_AREG0
,
103 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
104 cpu_exclusive_val
= tcg_global_mem_new_i64(TCG_AREG0
,
105 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
106 #ifdef CONFIG_USER_ONLY
107 cpu_exclusive_test
= tcg_global_mem_new_i64(TCG_AREG0
,
108 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
109 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
110 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
113 a64_translate_init();
116 static inline ARMMMUIdx
get_a32_user_mem_index(DisasContext
*s
)
118 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
120 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
121 * otherwise, access as if at PL0.
123 switch (s
->mmu_idx
) {
124 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
125 case ARMMMUIdx_S12NSE0
:
126 case ARMMMUIdx_S12NSE1
:
127 return ARMMMUIdx_S12NSE0
;
129 case ARMMMUIdx_S1SE0
:
130 case ARMMMUIdx_S1SE1
:
131 return ARMMMUIdx_S1SE0
;
134 g_assert_not_reached();
138 static inline TCGv_i32
load_cpu_offset(int offset
)
140 TCGv_i32 tmp
= tcg_temp_new_i32();
141 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
145 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
147 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
149 tcg_gen_st_i32(var
, cpu_env
, offset
);
150 tcg_temp_free_i32(var
);
153 #define store_cpu_field(var, name) \
154 store_cpu_offset(var, offsetof(CPUARMState, name))
156 /* Set a variable to the value of a CPU register. */
157 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
161 /* normally, since we updated PC, we need only to add one insn */
163 addr
= (long)s
->pc
+ 2;
165 addr
= (long)s
->pc
+ 4;
166 tcg_gen_movi_i32(var
, addr
);
168 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
172 /* Create a new temporary and set it to the value of a CPU register. */
173 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
175 TCGv_i32 tmp
= tcg_temp_new_i32();
176 load_reg_var(s
, tmp
, reg
);
180 /* Set a CPU register. The source must be a temporary and will be
182 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
185 tcg_gen_andi_i32(var
, var
, ~1);
186 s
->is_jmp
= DISAS_JUMP
;
188 tcg_gen_mov_i32(cpu_R
[reg
], var
);
189 tcg_temp_free_i32(var
);
192 /* Value extensions. */
193 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
194 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
195 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
196 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
198 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
199 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
202 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
204 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
205 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
206 tcg_temp_free_i32(tmp_mask
);
208 /* Set NZCV flags from the high 4 bits of var. */
209 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
211 static void gen_exception_internal(int excp
)
213 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
215 assert(excp_is_internal(excp
));
216 gen_helper_exception_internal(cpu_env
, tcg_excp
);
217 tcg_temp_free_i32(tcg_excp
);
220 static void gen_exception(int excp
, uint32_t syndrome
)
222 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
223 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
225 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
, tcg_syn
);
226 tcg_temp_free_i32(tcg_syn
);
227 tcg_temp_free_i32(tcg_excp
);
230 static void gen_ss_advance(DisasContext
*s
)
232 /* If the singlestep state is Active-not-pending, advance to
237 gen_helper_clear_pstate_ss(cpu_env
);
241 static void gen_step_complete_exception(DisasContext
*s
)
243 /* We just completed step of an insn. Move from Active-not-pending
244 * to Active-pending, and then also take the swstep exception.
245 * This corresponds to making the (IMPDEF) choice to prioritize
246 * swstep exceptions over asynchronous exceptions taken to an exception
247 * level where debug is disabled. This choice has the advantage that
248 * we do not need to maintain internal state corresponding to the
249 * ISV/EX syndrome bits between completion of the step and generation
250 * of the exception, and our syndrome information is always correct.
253 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
));
254 s
->is_jmp
= DISAS_EXC
;
257 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
259 TCGv_i32 tmp1
= tcg_temp_new_i32();
260 TCGv_i32 tmp2
= tcg_temp_new_i32();
261 tcg_gen_ext16s_i32(tmp1
, a
);
262 tcg_gen_ext16s_i32(tmp2
, b
);
263 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
264 tcg_temp_free_i32(tmp2
);
265 tcg_gen_sari_i32(a
, a
, 16);
266 tcg_gen_sari_i32(b
, b
, 16);
267 tcg_gen_mul_i32(b
, b
, a
);
268 tcg_gen_mov_i32(a
, tmp1
);
269 tcg_temp_free_i32(tmp1
);
272 /* Byteswap each halfword. */
273 static void gen_rev16(TCGv_i32 var
)
275 TCGv_i32 tmp
= tcg_temp_new_i32();
276 tcg_gen_shri_i32(tmp
, var
, 8);
277 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
278 tcg_gen_shli_i32(var
, var
, 8);
279 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
280 tcg_gen_or_i32(var
, var
, tmp
);
281 tcg_temp_free_i32(tmp
);
284 /* Byteswap low halfword and sign extend. */
285 static void gen_revsh(TCGv_i32 var
)
287 tcg_gen_ext16u_i32(var
, var
);
288 tcg_gen_bswap16_i32(var
, var
);
289 tcg_gen_ext16s_i32(var
, var
);
292 /* Unsigned bitfield extract. */
293 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
296 tcg_gen_shri_i32(var
, var
, shift
);
297 tcg_gen_andi_i32(var
, var
, mask
);
300 /* Signed bitfield extract. */
301 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
306 tcg_gen_sari_i32(var
, var
, shift
);
307 if (shift
+ width
< 32) {
308 signbit
= 1u << (width
- 1);
309 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
310 tcg_gen_xori_i32(var
, var
, signbit
);
311 tcg_gen_subi_i32(var
, var
, signbit
);
315 /* Return (b << 32) + a. Mark inputs as dead */
316 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
318 TCGv_i64 tmp64
= tcg_temp_new_i64();
320 tcg_gen_extu_i32_i64(tmp64
, b
);
321 tcg_temp_free_i32(b
);
322 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
323 tcg_gen_add_i64(a
, tmp64
, a
);
325 tcg_temp_free_i64(tmp64
);
329 /* Return (b << 32) - a. Mark inputs as dead. */
330 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
332 TCGv_i64 tmp64
= tcg_temp_new_i64();
334 tcg_gen_extu_i32_i64(tmp64
, b
);
335 tcg_temp_free_i32(b
);
336 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
337 tcg_gen_sub_i64(a
, tmp64
, a
);
339 tcg_temp_free_i64(tmp64
);
343 /* 32x32->64 multiply. Marks inputs as dead. */
344 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
346 TCGv_i32 lo
= tcg_temp_new_i32();
347 TCGv_i32 hi
= tcg_temp_new_i32();
350 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
351 tcg_temp_free_i32(a
);
352 tcg_temp_free_i32(b
);
354 ret
= tcg_temp_new_i64();
355 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
356 tcg_temp_free_i32(lo
);
357 tcg_temp_free_i32(hi
);
362 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
364 TCGv_i32 lo
= tcg_temp_new_i32();
365 TCGv_i32 hi
= tcg_temp_new_i32();
368 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
369 tcg_temp_free_i32(a
);
370 tcg_temp_free_i32(b
);
372 ret
= tcg_temp_new_i64();
373 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
374 tcg_temp_free_i32(lo
);
375 tcg_temp_free_i32(hi
);
380 /* Swap low and high halfwords. */
381 static void gen_swap_half(TCGv_i32 var
)
383 TCGv_i32 tmp
= tcg_temp_new_i32();
384 tcg_gen_shri_i32(tmp
, var
, 16);
385 tcg_gen_shli_i32(var
, var
, 16);
386 tcg_gen_or_i32(var
, var
, tmp
);
387 tcg_temp_free_i32(tmp
);
390 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
391 tmp = (t0 ^ t1) & 0x8000;
394 t0 = (t0 + t1) ^ tmp;
397 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
399 TCGv_i32 tmp
= tcg_temp_new_i32();
400 tcg_gen_xor_i32(tmp
, t0
, t1
);
401 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
402 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
403 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
404 tcg_gen_add_i32(t0
, t0
, t1
);
405 tcg_gen_xor_i32(t0
, t0
, tmp
);
406 tcg_temp_free_i32(tmp
);
407 tcg_temp_free_i32(t1
);
410 /* Set CF to the top bit of var. */
411 static void gen_set_CF_bit31(TCGv_i32 var
)
413 tcg_gen_shri_i32(cpu_CF
, var
, 31);
416 /* Set N and Z flags from var. */
417 static inline void gen_logic_CC(TCGv_i32 var
)
419 tcg_gen_mov_i32(cpu_NF
, var
);
420 tcg_gen_mov_i32(cpu_ZF
, var
);
424 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
426 tcg_gen_add_i32(t0
, t0
, t1
);
427 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
430 /* dest = T0 + T1 + CF. */
431 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
433 tcg_gen_add_i32(dest
, t0
, t1
);
434 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
437 /* dest = T0 - T1 + CF - 1. */
438 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
440 tcg_gen_sub_i32(dest
, t0
, t1
);
441 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
442 tcg_gen_subi_i32(dest
, dest
, 1);
445 /* dest = T0 + T1. Compute C, N, V and Z flags */
446 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
448 TCGv_i32 tmp
= tcg_temp_new_i32();
449 tcg_gen_movi_i32(tmp
, 0);
450 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
451 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
452 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
453 tcg_gen_xor_i32(tmp
, t0
, t1
);
454 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
455 tcg_temp_free_i32(tmp
);
456 tcg_gen_mov_i32(dest
, cpu_NF
);
459 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
460 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
462 TCGv_i32 tmp
= tcg_temp_new_i32();
463 if (TCG_TARGET_HAS_add2_i32
) {
464 tcg_gen_movi_i32(tmp
, 0);
465 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
466 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
468 TCGv_i64 q0
= tcg_temp_new_i64();
469 TCGv_i64 q1
= tcg_temp_new_i64();
470 tcg_gen_extu_i32_i64(q0
, t0
);
471 tcg_gen_extu_i32_i64(q1
, t1
);
472 tcg_gen_add_i64(q0
, q0
, q1
);
473 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
474 tcg_gen_add_i64(q0
, q0
, q1
);
475 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
476 tcg_temp_free_i64(q0
);
477 tcg_temp_free_i64(q1
);
479 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
480 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
481 tcg_gen_xor_i32(tmp
, t0
, t1
);
482 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
483 tcg_temp_free_i32(tmp
);
484 tcg_gen_mov_i32(dest
, cpu_NF
);
487 /* dest = T0 - T1. Compute C, N, V and Z flags */
488 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
491 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
492 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
493 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
494 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
495 tmp
= tcg_temp_new_i32();
496 tcg_gen_xor_i32(tmp
, t0
, t1
);
497 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
498 tcg_temp_free_i32(tmp
);
499 tcg_gen_mov_i32(dest
, cpu_NF
);
502 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
503 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
505 TCGv_i32 tmp
= tcg_temp_new_i32();
506 tcg_gen_not_i32(tmp
, t1
);
507 gen_adc_CC(dest
, t0
, tmp
);
508 tcg_temp_free_i32(tmp
);
511 #define GEN_SHIFT(name) \
512 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
514 TCGv_i32 tmp1, tmp2, tmp3; \
515 tmp1 = tcg_temp_new_i32(); \
516 tcg_gen_andi_i32(tmp1, t1, 0xff); \
517 tmp2 = tcg_const_i32(0); \
518 tmp3 = tcg_const_i32(0x1f); \
519 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
520 tcg_temp_free_i32(tmp3); \
521 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
522 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
523 tcg_temp_free_i32(tmp2); \
524 tcg_temp_free_i32(tmp1); \
530 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
533 tmp1
= tcg_temp_new_i32();
534 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
535 tmp2
= tcg_const_i32(0x1f);
536 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
537 tcg_temp_free_i32(tmp2
);
538 tcg_gen_sar_i32(dest
, t0
, tmp1
);
539 tcg_temp_free_i32(tmp1
);
542 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
544 TCGv_i32 c0
= tcg_const_i32(0);
545 TCGv_i32 tmp
= tcg_temp_new_i32();
546 tcg_gen_neg_i32(tmp
, src
);
547 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
548 tcg_temp_free_i32(c0
);
549 tcg_temp_free_i32(tmp
);
552 static void shifter_out_im(TCGv_i32 var
, int shift
)
555 tcg_gen_andi_i32(cpu_CF
, var
, 1);
557 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
559 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
564 /* Shift by immediate. Includes special handling for shift == 0. */
565 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
566 int shift
, int flags
)
572 shifter_out_im(var
, 32 - shift
);
573 tcg_gen_shli_i32(var
, var
, shift
);
579 tcg_gen_shri_i32(cpu_CF
, var
, 31);
581 tcg_gen_movi_i32(var
, 0);
584 shifter_out_im(var
, shift
- 1);
585 tcg_gen_shri_i32(var
, var
, shift
);
592 shifter_out_im(var
, shift
- 1);
595 tcg_gen_sari_i32(var
, var
, shift
);
597 case 3: /* ROR/RRX */
600 shifter_out_im(var
, shift
- 1);
601 tcg_gen_rotri_i32(var
, var
, shift
); break;
603 TCGv_i32 tmp
= tcg_temp_new_i32();
604 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
606 shifter_out_im(var
, 0);
607 tcg_gen_shri_i32(var
, var
, 1);
608 tcg_gen_or_i32(var
, var
, tmp
);
609 tcg_temp_free_i32(tmp
);
614 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
615 TCGv_i32 shift
, int flags
)
619 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
620 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
621 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
622 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
627 gen_shl(var
, var
, shift
);
630 gen_shr(var
, var
, shift
);
633 gen_sar(var
, var
, shift
);
635 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
636 tcg_gen_rotr_i32(var
, var
, shift
); break;
639 tcg_temp_free_i32(shift
);
642 #define PAS_OP(pfx) \
644 case 0: gen_pas_helper(glue(pfx,add16)); break; \
645 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
646 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
647 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
648 case 4: gen_pas_helper(glue(pfx,add8)); break; \
649 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
651 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
656 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
658 tmp
= tcg_temp_new_ptr();
659 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
661 tcg_temp_free_ptr(tmp
);
664 tmp
= tcg_temp_new_ptr();
665 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
667 tcg_temp_free_ptr(tmp
);
669 #undef gen_pas_helper
670 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
683 #undef gen_pas_helper
688 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
689 #define PAS_OP(pfx) \
691 case 0: gen_pas_helper(glue(pfx,add8)); break; \
692 case 1: gen_pas_helper(glue(pfx,add16)); break; \
693 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
694 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
695 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
696 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
698 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
703 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
705 tmp
= tcg_temp_new_ptr();
706 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
708 tcg_temp_free_ptr(tmp
);
711 tmp
= tcg_temp_new_ptr();
712 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
714 tcg_temp_free_ptr(tmp
);
716 #undef gen_pas_helper
717 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
730 #undef gen_pas_helper
736 * generate a conditional branch based on ARM condition code cc.
737 * This is common between ARM and Aarch64 targets.
739 void arm_gen_test_cc(int cc
, int label
)
746 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
749 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
752 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
755 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
758 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
761 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
764 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
767 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
769 case 8: /* hi: C && !Z */
770 inv
= gen_new_label();
771 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
772 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
775 case 9: /* ls: !C || Z */
776 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
777 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
779 case 10: /* ge: N == V -> N ^ V == 0 */
780 tmp
= tcg_temp_new_i32();
781 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
782 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
783 tcg_temp_free_i32(tmp
);
785 case 11: /* lt: N != V -> N ^ V != 0 */
786 tmp
= tcg_temp_new_i32();
787 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
788 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
789 tcg_temp_free_i32(tmp
);
791 case 12: /* gt: !Z && N == V */
792 inv
= gen_new_label();
793 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
794 tmp
= tcg_temp_new_i32();
795 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
796 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
797 tcg_temp_free_i32(tmp
);
800 case 13: /* le: Z || N != V */
801 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
802 tmp
= tcg_temp_new_i32();
803 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
804 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
805 tcg_temp_free_i32(tmp
);
808 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
813 static const uint8_t table_logic_cc
[16] = {
832 /* Set PC and Thumb state from an immediate address. */
833 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
837 s
->is_jmp
= DISAS_UPDATE
;
838 if (s
->thumb
!= (addr
& 1)) {
839 tmp
= tcg_temp_new_i32();
840 tcg_gen_movi_i32(tmp
, addr
& 1);
841 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
842 tcg_temp_free_i32(tmp
);
844 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
847 /* Set PC and Thumb state from var. var is marked as dead. */
848 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
850 s
->is_jmp
= DISAS_UPDATE
;
851 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
852 tcg_gen_andi_i32(var
, var
, 1);
853 store_cpu_field(var
, thumb
);
856 /* Variant of store_reg which uses branch&exchange logic when storing
857 to r15 in ARM architecture v7 and above. The source must be a temporary
858 and will be marked as dead. */
859 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
861 if (reg
== 15 && ENABLE_ARCH_7
) {
864 store_reg(s
, reg
, var
);
868 /* Variant of store_reg which uses branch&exchange logic when storing
869 * to r15 in ARM architecture v5T and above. This is used for storing
870 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
871 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
872 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
874 if (reg
== 15 && ENABLE_ARCH_5
) {
877 store_reg(s
, reg
, var
);
881 /* Abstractions of "generate code to do a guest load/store for
882 * AArch32", where a vaddr is always 32 bits (and is zero
883 * extended if we're a 64 bit core) and data is also
884 * 32 bits unless specifically doing a 64 bit access.
885 * These functions work like tcg_gen_qemu_{ld,st}* except
886 * that the address argument is TCGv_i32 rather than TCGv.
888 #if TARGET_LONG_BITS == 32
890 #define DO_GEN_LD(SUFF, OPC) \
891 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
893 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
896 #define DO_GEN_ST(SUFF, OPC) \
897 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
899 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
902 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
904 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
907 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
909 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
914 #define DO_GEN_LD(SUFF, OPC) \
915 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
917 TCGv addr64 = tcg_temp_new(); \
918 tcg_gen_extu_i32_i64(addr64, addr); \
919 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
920 tcg_temp_free(addr64); \
923 #define DO_GEN_ST(SUFF, OPC) \
924 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
926 TCGv addr64 = tcg_temp_new(); \
927 tcg_gen_extu_i32_i64(addr64, addr); \
928 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
929 tcg_temp_free(addr64); \
932 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
934 TCGv addr64
= tcg_temp_new();
935 tcg_gen_extu_i32_i64(addr64
, addr
);
936 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
937 tcg_temp_free(addr64
);
940 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
942 TCGv addr64
= tcg_temp_new();
943 tcg_gen_extu_i32_i64(addr64
, addr
);
944 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
945 tcg_temp_free(addr64
);
952 DO_GEN_LD(16s
, MO_TESW
)
953 DO_GEN_LD(16u, MO_TEUW
)
954 DO_GEN_LD(32u, MO_TEUL
)
956 DO_GEN_ST(16, MO_TEUW
)
957 DO_GEN_ST(32, MO_TEUL
)
959 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
961 tcg_gen_movi_i32(cpu_R
[15], val
);
964 static inline void gen_hvc(DisasContext
*s
, int imm16
)
966 /* The pre HVC helper handles cases when HVC gets trapped
967 * as an undefined insn by runtime configuration (ie before
968 * the insn really executes).
970 gen_set_pc_im(s
, s
->pc
- 4);
971 gen_helper_pre_hvc(cpu_env
);
972 /* Otherwise we will treat this as a real exception which
973 * happens after execution of the insn. (The distinction matters
974 * for the PC value reported to the exception handler and also
975 * for single stepping.)
978 gen_set_pc_im(s
, s
->pc
);
979 s
->is_jmp
= DISAS_HVC
;
982 static inline void gen_smc(DisasContext
*s
)
984 /* As with HVC, we may take an exception either before or after
989 gen_set_pc_im(s
, s
->pc
- 4);
990 tmp
= tcg_const_i32(syn_aa32_smc());
991 gen_helper_pre_smc(cpu_env
, tmp
);
992 tcg_temp_free_i32(tmp
);
993 gen_set_pc_im(s
, s
->pc
);
994 s
->is_jmp
= DISAS_SMC
;
998 gen_set_condexec (DisasContext
*s
)
1000 if (s
->condexec_mask
) {
1001 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1002 TCGv_i32 tmp
= tcg_temp_new_i32();
1003 tcg_gen_movi_i32(tmp
, val
);
1004 store_cpu_field(tmp
, condexec_bits
);
1008 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1010 gen_set_condexec(s
);
1011 gen_set_pc_im(s
, s
->pc
- offset
);
1012 gen_exception_internal(excp
);
1013 s
->is_jmp
= DISAS_JUMP
;
1016 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
, int syn
)
1018 gen_set_condexec(s
);
1019 gen_set_pc_im(s
, s
->pc
- offset
);
1020 gen_exception(excp
, syn
);
1021 s
->is_jmp
= DISAS_JUMP
;
1024 /* Force a TB lookup after an instruction that changes the CPU state. */
1025 static inline void gen_lookup_tb(DisasContext
*s
)
1027 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1028 s
->is_jmp
= DISAS_UPDATE
;
1031 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1034 int val
, rm
, shift
, shiftop
;
1037 if (!(insn
& (1 << 25))) {
1040 if (!(insn
& (1 << 23)))
1043 tcg_gen_addi_i32(var
, var
, val
);
1045 /* shift/register */
1047 shift
= (insn
>> 7) & 0x1f;
1048 shiftop
= (insn
>> 5) & 3;
1049 offset
= load_reg(s
, rm
);
1050 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1051 if (!(insn
& (1 << 23)))
1052 tcg_gen_sub_i32(var
, var
, offset
);
1054 tcg_gen_add_i32(var
, var
, offset
);
1055 tcg_temp_free_i32(offset
);
1059 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1060 int extra
, TCGv_i32 var
)
1065 if (insn
& (1 << 22)) {
1067 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1068 if (!(insn
& (1 << 23)))
1072 tcg_gen_addi_i32(var
, var
, val
);
1076 tcg_gen_addi_i32(var
, var
, extra
);
1078 offset
= load_reg(s
, rm
);
1079 if (!(insn
& (1 << 23)))
1080 tcg_gen_sub_i32(var
, var
, offset
);
1082 tcg_gen_add_i32(var
, var
, offset
);
1083 tcg_temp_free_i32(offset
);
1087 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1089 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1092 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1094 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1096 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1100 #define VFP_OP2(name) \
1101 static inline void gen_vfp_##name(int dp) \
1103 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1105 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1107 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1109 tcg_temp_free_ptr(fpst); \
1119 static inline void gen_vfp_F1_mul(int dp
)
1121 /* Like gen_vfp_mul() but put result in F1 */
1122 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1124 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1126 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1128 tcg_temp_free_ptr(fpst
);
1131 static inline void gen_vfp_F1_neg(int dp
)
1133 /* Like gen_vfp_neg() but put result in F1 */
1135 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1137 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1141 static inline void gen_vfp_abs(int dp
)
1144 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1146 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1149 static inline void gen_vfp_neg(int dp
)
1152 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1154 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1157 static inline void gen_vfp_sqrt(int dp
)
1160 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1162 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1165 static inline void gen_vfp_cmp(int dp
)
1168 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1170 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1173 static inline void gen_vfp_cmpe(int dp
)
1176 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1178 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1181 static inline void gen_vfp_F1_ld0(int dp
)
1184 tcg_gen_movi_i64(cpu_F1d
, 0);
1186 tcg_gen_movi_i32(cpu_F1s
, 0);
1189 #define VFP_GEN_ITOF(name) \
1190 static inline void gen_vfp_##name(int dp, int neon) \
1192 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1194 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1196 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1198 tcg_temp_free_ptr(statusptr); \
1205 #define VFP_GEN_FTOI(name) \
1206 static inline void gen_vfp_##name(int dp, int neon) \
1208 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1210 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1212 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1214 tcg_temp_free_ptr(statusptr); \
1223 #define VFP_GEN_FIX(name, round) \
1224 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1226 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1227 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1229 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1232 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1235 tcg_temp_free_i32(tmp_shift); \
1236 tcg_temp_free_ptr(statusptr); \
1238 VFP_GEN_FIX(tosh
, _round_to_zero
)
1239 VFP_GEN_FIX(tosl
, _round_to_zero
)
1240 VFP_GEN_FIX(touh
, _round_to_zero
)
1241 VFP_GEN_FIX(toul
, _round_to_zero
)
1248 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1251 gen_aa32_ld64(cpu_F0d
, addr
, get_mem_index(s
));
1253 gen_aa32_ld32u(cpu_F0s
, addr
, get_mem_index(s
));
1257 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1260 gen_aa32_st64(cpu_F0d
, addr
, get_mem_index(s
));
1262 gen_aa32_st32(cpu_F0s
, addr
, get_mem_index(s
));
1267 vfp_reg_offset (int dp
, int reg
)
1270 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1272 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1273 + offsetof(CPU_DoubleU
, l
.upper
);
1275 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1276 + offsetof(CPU_DoubleU
, l
.lower
);
1280 /* Return the offset of a 32-bit piece of a NEON register.
1281 zero is the least significant end of the register. */
1283 neon_reg_offset (int reg
, int n
)
1287 return vfp_reg_offset(0, sreg
);
1290 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1292 TCGv_i32 tmp
= tcg_temp_new_i32();
1293 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1297 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1299 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1300 tcg_temp_free_i32(var
);
1303 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1305 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1308 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1310 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1313 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1314 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1315 #define tcg_gen_st_f32 tcg_gen_st_i32
1316 #define tcg_gen_st_f64 tcg_gen_st_i64
1318 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1321 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1323 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1326 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1329 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1331 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1334 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1337 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1339 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1342 #define ARM_CP_RW_BIT (1 << 20)
1344 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1346 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1349 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1351 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1354 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1356 TCGv_i32 var
= tcg_temp_new_i32();
1357 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1361 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1363 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1364 tcg_temp_free_i32(var
);
1367 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1369 iwmmxt_store_reg(cpu_M0
, rn
);
1372 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1374 iwmmxt_load_reg(cpu_M0
, rn
);
1377 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1379 iwmmxt_load_reg(cpu_V1
, rn
);
1380 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1383 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1385 iwmmxt_load_reg(cpu_V1
, rn
);
1386 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1389 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1391 iwmmxt_load_reg(cpu_V1
, rn
);
1392 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1395 #define IWMMXT_OP(name) \
1396 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1398 iwmmxt_load_reg(cpu_V1, rn); \
1399 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1402 #define IWMMXT_OP_ENV(name) \
1403 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1405 iwmmxt_load_reg(cpu_V1, rn); \
1406 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1409 #define IWMMXT_OP_ENV_SIZE(name) \
1410 IWMMXT_OP_ENV(name##b) \
1411 IWMMXT_OP_ENV(name##w) \
1412 IWMMXT_OP_ENV(name##l)
1414 #define IWMMXT_OP_ENV1(name) \
1415 static inline void gen_op_iwmmxt_##name##_M0(void) \
1417 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1431 IWMMXT_OP_ENV_SIZE(unpackl
)
1432 IWMMXT_OP_ENV_SIZE(unpackh
)
1434 IWMMXT_OP_ENV1(unpacklub
)
1435 IWMMXT_OP_ENV1(unpackluw
)
1436 IWMMXT_OP_ENV1(unpacklul
)
1437 IWMMXT_OP_ENV1(unpackhub
)
1438 IWMMXT_OP_ENV1(unpackhuw
)
1439 IWMMXT_OP_ENV1(unpackhul
)
1440 IWMMXT_OP_ENV1(unpacklsb
)
1441 IWMMXT_OP_ENV1(unpacklsw
)
1442 IWMMXT_OP_ENV1(unpacklsl
)
1443 IWMMXT_OP_ENV1(unpackhsb
)
1444 IWMMXT_OP_ENV1(unpackhsw
)
1445 IWMMXT_OP_ENV1(unpackhsl
)
1447 IWMMXT_OP_ENV_SIZE(cmpeq
)
1448 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1449 IWMMXT_OP_ENV_SIZE(cmpgts
)
1451 IWMMXT_OP_ENV_SIZE(mins
)
1452 IWMMXT_OP_ENV_SIZE(minu
)
1453 IWMMXT_OP_ENV_SIZE(maxs
)
1454 IWMMXT_OP_ENV_SIZE(maxu
)
1456 IWMMXT_OP_ENV_SIZE(subn
)
1457 IWMMXT_OP_ENV_SIZE(addn
)
1458 IWMMXT_OP_ENV_SIZE(subu
)
1459 IWMMXT_OP_ENV_SIZE(addu
)
1460 IWMMXT_OP_ENV_SIZE(subs
)
1461 IWMMXT_OP_ENV_SIZE(adds
)
1463 IWMMXT_OP_ENV(avgb0
)
1464 IWMMXT_OP_ENV(avgb1
)
1465 IWMMXT_OP_ENV(avgw0
)
1466 IWMMXT_OP_ENV(avgw1
)
1468 IWMMXT_OP_ENV(packuw
)
1469 IWMMXT_OP_ENV(packul
)
1470 IWMMXT_OP_ENV(packuq
)
1471 IWMMXT_OP_ENV(packsw
)
1472 IWMMXT_OP_ENV(packsl
)
1473 IWMMXT_OP_ENV(packsq
)
1475 static void gen_op_iwmmxt_set_mup(void)
1478 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1479 tcg_gen_ori_i32(tmp
, tmp
, 2);
1480 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1483 static void gen_op_iwmmxt_set_cup(void)
1486 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1487 tcg_gen_ori_i32(tmp
, tmp
, 1);
1488 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1491 static void gen_op_iwmmxt_setpsr_nz(void)
1493 TCGv_i32 tmp
= tcg_temp_new_i32();
1494 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1495 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1498 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1500 iwmmxt_load_reg(cpu_V1
, rn
);
1501 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1502 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1505 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1512 rd
= (insn
>> 16) & 0xf;
1513 tmp
= load_reg(s
, rd
);
1515 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1516 if (insn
& (1 << 24)) {
1518 if (insn
& (1 << 23))
1519 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1521 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1522 tcg_gen_mov_i32(dest
, tmp
);
1523 if (insn
& (1 << 21))
1524 store_reg(s
, rd
, tmp
);
1526 tcg_temp_free_i32(tmp
);
1527 } else if (insn
& (1 << 21)) {
1529 tcg_gen_mov_i32(dest
, tmp
);
1530 if (insn
& (1 << 23))
1531 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1533 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1534 store_reg(s
, rd
, tmp
);
1535 } else if (!(insn
& (1 << 23)))
1540 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1542 int rd
= (insn
>> 0) & 0xf;
1545 if (insn
& (1 << 8)) {
1546 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1549 tmp
= iwmmxt_load_creg(rd
);
1552 tmp
= tcg_temp_new_i32();
1553 iwmmxt_load_reg(cpu_V0
, rd
);
1554 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1556 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1557 tcg_gen_mov_i32(dest
, tmp
);
1558 tcg_temp_free_i32(tmp
);
1562 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1563 (ie. an undefined instruction). */
1564 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1567 int rdhi
, rdlo
, rd0
, rd1
, i
;
1569 TCGv_i32 tmp
, tmp2
, tmp3
;
1571 if ((insn
& 0x0e000e00) == 0x0c000000) {
1572 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1574 rdlo
= (insn
>> 12) & 0xf;
1575 rdhi
= (insn
>> 16) & 0xf;
1576 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1577 iwmmxt_load_reg(cpu_V0
, wrd
);
1578 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1579 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1580 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1581 } else { /* TMCRR */
1582 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1583 iwmmxt_store_reg(cpu_V0
, wrd
);
1584 gen_op_iwmmxt_set_mup();
1589 wrd
= (insn
>> 12) & 0xf;
1590 addr
= tcg_temp_new_i32();
1591 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1592 tcg_temp_free_i32(addr
);
1595 if (insn
& ARM_CP_RW_BIT
) {
1596 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1597 tmp
= tcg_temp_new_i32();
1598 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1599 iwmmxt_store_creg(wrd
, tmp
);
1602 if (insn
& (1 << 8)) {
1603 if (insn
& (1 << 22)) { /* WLDRD */
1604 gen_aa32_ld64(cpu_M0
, addr
, get_mem_index(s
));
1606 } else { /* WLDRW wRd */
1607 tmp
= tcg_temp_new_i32();
1608 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1611 tmp
= tcg_temp_new_i32();
1612 if (insn
& (1 << 22)) { /* WLDRH */
1613 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
1614 } else { /* WLDRB */
1615 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
1619 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1620 tcg_temp_free_i32(tmp
);
1622 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1625 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1626 tmp
= iwmmxt_load_creg(wrd
);
1627 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1629 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1630 tmp
= tcg_temp_new_i32();
1631 if (insn
& (1 << 8)) {
1632 if (insn
& (1 << 22)) { /* WSTRD */
1633 gen_aa32_st64(cpu_M0
, addr
, get_mem_index(s
));
1634 } else { /* WSTRW wRd */
1635 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1636 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1639 if (insn
& (1 << 22)) { /* WSTRH */
1640 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1641 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
1642 } else { /* WSTRB */
1643 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1644 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
1648 tcg_temp_free_i32(tmp
);
1650 tcg_temp_free_i32(addr
);
1654 if ((insn
& 0x0f000000) != 0x0e000000)
1657 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1658 case 0x000: /* WOR */
1659 wrd
= (insn
>> 12) & 0xf;
1660 rd0
= (insn
>> 0) & 0xf;
1661 rd1
= (insn
>> 16) & 0xf;
1662 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1663 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1664 gen_op_iwmmxt_setpsr_nz();
1665 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1666 gen_op_iwmmxt_set_mup();
1667 gen_op_iwmmxt_set_cup();
1669 case 0x011: /* TMCR */
1672 rd
= (insn
>> 12) & 0xf;
1673 wrd
= (insn
>> 16) & 0xf;
1675 case ARM_IWMMXT_wCID
:
1676 case ARM_IWMMXT_wCASF
:
1678 case ARM_IWMMXT_wCon
:
1679 gen_op_iwmmxt_set_cup();
1681 case ARM_IWMMXT_wCSSF
:
1682 tmp
= iwmmxt_load_creg(wrd
);
1683 tmp2
= load_reg(s
, rd
);
1684 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1685 tcg_temp_free_i32(tmp2
);
1686 iwmmxt_store_creg(wrd
, tmp
);
1688 case ARM_IWMMXT_wCGR0
:
1689 case ARM_IWMMXT_wCGR1
:
1690 case ARM_IWMMXT_wCGR2
:
1691 case ARM_IWMMXT_wCGR3
:
1692 gen_op_iwmmxt_set_cup();
1693 tmp
= load_reg(s
, rd
);
1694 iwmmxt_store_creg(wrd
, tmp
);
1700 case 0x100: /* WXOR */
1701 wrd
= (insn
>> 12) & 0xf;
1702 rd0
= (insn
>> 0) & 0xf;
1703 rd1
= (insn
>> 16) & 0xf;
1704 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1705 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1706 gen_op_iwmmxt_setpsr_nz();
1707 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1708 gen_op_iwmmxt_set_mup();
1709 gen_op_iwmmxt_set_cup();
1711 case 0x111: /* TMRC */
1714 rd
= (insn
>> 12) & 0xf;
1715 wrd
= (insn
>> 16) & 0xf;
1716 tmp
= iwmmxt_load_creg(wrd
);
1717 store_reg(s
, rd
, tmp
);
1719 case 0x300: /* WANDN */
1720 wrd
= (insn
>> 12) & 0xf;
1721 rd0
= (insn
>> 0) & 0xf;
1722 rd1
= (insn
>> 16) & 0xf;
1723 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1724 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1725 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1726 gen_op_iwmmxt_setpsr_nz();
1727 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1728 gen_op_iwmmxt_set_mup();
1729 gen_op_iwmmxt_set_cup();
1731 case 0x200: /* WAND */
1732 wrd
= (insn
>> 12) & 0xf;
1733 rd0
= (insn
>> 0) & 0xf;
1734 rd1
= (insn
>> 16) & 0xf;
1735 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1736 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1737 gen_op_iwmmxt_setpsr_nz();
1738 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1739 gen_op_iwmmxt_set_mup();
1740 gen_op_iwmmxt_set_cup();
1742 case 0x810: case 0xa10: /* WMADD */
1743 wrd
= (insn
>> 12) & 0xf;
1744 rd0
= (insn
>> 0) & 0xf;
1745 rd1
= (insn
>> 16) & 0xf;
1746 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1747 if (insn
& (1 << 21))
1748 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1750 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1751 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1752 gen_op_iwmmxt_set_mup();
1754 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1755 wrd
= (insn
>> 12) & 0xf;
1756 rd0
= (insn
>> 16) & 0xf;
1757 rd1
= (insn
>> 0) & 0xf;
1758 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1759 switch ((insn
>> 22) & 3) {
1761 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1764 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1767 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1772 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1773 gen_op_iwmmxt_set_mup();
1774 gen_op_iwmmxt_set_cup();
1776 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1777 wrd
= (insn
>> 12) & 0xf;
1778 rd0
= (insn
>> 16) & 0xf;
1779 rd1
= (insn
>> 0) & 0xf;
1780 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1781 switch ((insn
>> 22) & 3) {
1783 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1786 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1789 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1794 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1795 gen_op_iwmmxt_set_mup();
1796 gen_op_iwmmxt_set_cup();
1798 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1799 wrd
= (insn
>> 12) & 0xf;
1800 rd0
= (insn
>> 16) & 0xf;
1801 rd1
= (insn
>> 0) & 0xf;
1802 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1803 if (insn
& (1 << 22))
1804 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1806 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1807 if (!(insn
& (1 << 20)))
1808 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1809 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1810 gen_op_iwmmxt_set_mup();
1812 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1813 wrd
= (insn
>> 12) & 0xf;
1814 rd0
= (insn
>> 16) & 0xf;
1815 rd1
= (insn
>> 0) & 0xf;
1816 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1817 if (insn
& (1 << 21)) {
1818 if (insn
& (1 << 20))
1819 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1821 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1823 if (insn
& (1 << 20))
1824 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1826 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1828 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1829 gen_op_iwmmxt_set_mup();
1831 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1832 wrd
= (insn
>> 12) & 0xf;
1833 rd0
= (insn
>> 16) & 0xf;
1834 rd1
= (insn
>> 0) & 0xf;
1835 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1836 if (insn
& (1 << 21))
1837 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1839 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1840 if (!(insn
& (1 << 20))) {
1841 iwmmxt_load_reg(cpu_V1
, wrd
);
1842 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1844 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1845 gen_op_iwmmxt_set_mup();
1847 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1848 wrd
= (insn
>> 12) & 0xf;
1849 rd0
= (insn
>> 16) & 0xf;
1850 rd1
= (insn
>> 0) & 0xf;
1851 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1852 switch ((insn
>> 22) & 3) {
1854 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1857 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1860 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1865 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1866 gen_op_iwmmxt_set_mup();
1867 gen_op_iwmmxt_set_cup();
1869 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1870 wrd
= (insn
>> 12) & 0xf;
1871 rd0
= (insn
>> 16) & 0xf;
1872 rd1
= (insn
>> 0) & 0xf;
1873 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1874 if (insn
& (1 << 22)) {
1875 if (insn
& (1 << 20))
1876 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1878 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1880 if (insn
& (1 << 20))
1881 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1883 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1885 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1886 gen_op_iwmmxt_set_mup();
1887 gen_op_iwmmxt_set_cup();
1889 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1890 wrd
= (insn
>> 12) & 0xf;
1891 rd0
= (insn
>> 16) & 0xf;
1892 rd1
= (insn
>> 0) & 0xf;
1893 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1894 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1895 tcg_gen_andi_i32(tmp
, tmp
, 7);
1896 iwmmxt_load_reg(cpu_V1
, rd1
);
1897 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1898 tcg_temp_free_i32(tmp
);
1899 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1900 gen_op_iwmmxt_set_mup();
1902 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1903 if (((insn
>> 6) & 3) == 3)
1905 rd
= (insn
>> 12) & 0xf;
1906 wrd
= (insn
>> 16) & 0xf;
1907 tmp
= load_reg(s
, rd
);
1908 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1909 switch ((insn
>> 6) & 3) {
1911 tmp2
= tcg_const_i32(0xff);
1912 tmp3
= tcg_const_i32((insn
& 7) << 3);
1915 tmp2
= tcg_const_i32(0xffff);
1916 tmp3
= tcg_const_i32((insn
& 3) << 4);
1919 tmp2
= tcg_const_i32(0xffffffff);
1920 tmp3
= tcg_const_i32((insn
& 1) << 5);
1923 TCGV_UNUSED_I32(tmp2
);
1924 TCGV_UNUSED_I32(tmp3
);
1926 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1927 tcg_temp_free_i32(tmp3
);
1928 tcg_temp_free_i32(tmp2
);
1929 tcg_temp_free_i32(tmp
);
1930 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1931 gen_op_iwmmxt_set_mup();
1933 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1934 rd
= (insn
>> 12) & 0xf;
1935 wrd
= (insn
>> 16) & 0xf;
1936 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1938 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1939 tmp
= tcg_temp_new_i32();
1940 switch ((insn
>> 22) & 3) {
1942 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1943 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1945 tcg_gen_ext8s_i32(tmp
, tmp
);
1947 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1951 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1952 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1954 tcg_gen_ext16s_i32(tmp
, tmp
);
1956 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1960 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1961 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1964 store_reg(s
, rd
, tmp
);
1966 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1967 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1969 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1970 switch ((insn
>> 22) & 3) {
1972 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1975 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1978 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1981 tcg_gen_shli_i32(tmp
, tmp
, 28);
1983 tcg_temp_free_i32(tmp
);
1985 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1986 if (((insn
>> 6) & 3) == 3)
1988 rd
= (insn
>> 12) & 0xf;
1989 wrd
= (insn
>> 16) & 0xf;
1990 tmp
= load_reg(s
, rd
);
1991 switch ((insn
>> 6) & 3) {
1993 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1996 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1999 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2002 tcg_temp_free_i32(tmp
);
2003 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2004 gen_op_iwmmxt_set_mup();
2006 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2007 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2009 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2010 tmp2
= tcg_temp_new_i32();
2011 tcg_gen_mov_i32(tmp2
, tmp
);
2012 switch ((insn
>> 22) & 3) {
2014 for (i
= 0; i
< 7; i
++) {
2015 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2016 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2020 for (i
= 0; i
< 3; i
++) {
2021 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2022 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2026 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2027 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2031 tcg_temp_free_i32(tmp2
);
2032 tcg_temp_free_i32(tmp
);
2034 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2035 wrd
= (insn
>> 12) & 0xf;
2036 rd0
= (insn
>> 16) & 0xf;
2037 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2038 switch ((insn
>> 22) & 3) {
2040 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2043 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2046 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2051 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2052 gen_op_iwmmxt_set_mup();
2054 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2055 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2057 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2058 tmp2
= tcg_temp_new_i32();
2059 tcg_gen_mov_i32(tmp2
, tmp
);
2060 switch ((insn
>> 22) & 3) {
2062 for (i
= 0; i
< 7; i
++) {
2063 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2064 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2068 for (i
= 0; i
< 3; i
++) {
2069 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2070 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2074 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2075 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2079 tcg_temp_free_i32(tmp2
);
2080 tcg_temp_free_i32(tmp
);
2082 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2083 rd
= (insn
>> 12) & 0xf;
2084 rd0
= (insn
>> 16) & 0xf;
2085 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2087 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2088 tmp
= tcg_temp_new_i32();
2089 switch ((insn
>> 22) & 3) {
2091 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2094 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2097 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2100 store_reg(s
, rd
, tmp
);
2102 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2103 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2104 wrd
= (insn
>> 12) & 0xf;
2105 rd0
= (insn
>> 16) & 0xf;
2106 rd1
= (insn
>> 0) & 0xf;
2107 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2108 switch ((insn
>> 22) & 3) {
2110 if (insn
& (1 << 21))
2111 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2113 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2116 if (insn
& (1 << 21))
2117 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2119 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2122 if (insn
& (1 << 21))
2123 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2125 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2130 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2131 gen_op_iwmmxt_set_mup();
2132 gen_op_iwmmxt_set_cup();
2134 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2135 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2136 wrd
= (insn
>> 12) & 0xf;
2137 rd0
= (insn
>> 16) & 0xf;
2138 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2139 switch ((insn
>> 22) & 3) {
2141 if (insn
& (1 << 21))
2142 gen_op_iwmmxt_unpacklsb_M0();
2144 gen_op_iwmmxt_unpacklub_M0();
2147 if (insn
& (1 << 21))
2148 gen_op_iwmmxt_unpacklsw_M0();
2150 gen_op_iwmmxt_unpackluw_M0();
2153 if (insn
& (1 << 21))
2154 gen_op_iwmmxt_unpacklsl_M0();
2156 gen_op_iwmmxt_unpacklul_M0();
2161 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2162 gen_op_iwmmxt_set_mup();
2163 gen_op_iwmmxt_set_cup();
2165 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2166 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2167 wrd
= (insn
>> 12) & 0xf;
2168 rd0
= (insn
>> 16) & 0xf;
2169 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2170 switch ((insn
>> 22) & 3) {
2172 if (insn
& (1 << 21))
2173 gen_op_iwmmxt_unpackhsb_M0();
2175 gen_op_iwmmxt_unpackhub_M0();
2178 if (insn
& (1 << 21))
2179 gen_op_iwmmxt_unpackhsw_M0();
2181 gen_op_iwmmxt_unpackhuw_M0();
2184 if (insn
& (1 << 21))
2185 gen_op_iwmmxt_unpackhsl_M0();
2187 gen_op_iwmmxt_unpackhul_M0();
2192 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2193 gen_op_iwmmxt_set_mup();
2194 gen_op_iwmmxt_set_cup();
2196 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2197 case 0x214: case 0x614: case 0xa14: case 0xe14:
2198 if (((insn
>> 22) & 3) == 0)
2200 wrd
= (insn
>> 12) & 0xf;
2201 rd0
= (insn
>> 16) & 0xf;
2202 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2203 tmp
= tcg_temp_new_i32();
2204 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2205 tcg_temp_free_i32(tmp
);
2208 switch ((insn
>> 22) & 3) {
2210 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2213 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2216 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2219 tcg_temp_free_i32(tmp
);
2220 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2221 gen_op_iwmmxt_set_mup();
2222 gen_op_iwmmxt_set_cup();
2224 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2225 case 0x014: case 0x414: case 0x814: case 0xc14:
2226 if (((insn
>> 22) & 3) == 0)
2228 wrd
= (insn
>> 12) & 0xf;
2229 rd0
= (insn
>> 16) & 0xf;
2230 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2231 tmp
= tcg_temp_new_i32();
2232 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2233 tcg_temp_free_i32(tmp
);
2236 switch ((insn
>> 22) & 3) {
2238 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2241 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2244 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2247 tcg_temp_free_i32(tmp
);
2248 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2249 gen_op_iwmmxt_set_mup();
2250 gen_op_iwmmxt_set_cup();
2252 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2253 case 0x114: case 0x514: case 0x914: case 0xd14:
2254 if (((insn
>> 22) & 3) == 0)
2256 wrd
= (insn
>> 12) & 0xf;
2257 rd0
= (insn
>> 16) & 0xf;
2258 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2259 tmp
= tcg_temp_new_i32();
2260 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2261 tcg_temp_free_i32(tmp
);
2264 switch ((insn
>> 22) & 3) {
2266 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2269 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2272 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2275 tcg_temp_free_i32(tmp
);
2276 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2277 gen_op_iwmmxt_set_mup();
2278 gen_op_iwmmxt_set_cup();
2280 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2281 case 0x314: case 0x714: case 0xb14: case 0xf14:
2282 if (((insn
>> 22) & 3) == 0)
2284 wrd
= (insn
>> 12) & 0xf;
2285 rd0
= (insn
>> 16) & 0xf;
2286 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2287 tmp
= tcg_temp_new_i32();
2288 switch ((insn
>> 22) & 3) {
2290 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2291 tcg_temp_free_i32(tmp
);
2294 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2297 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2298 tcg_temp_free_i32(tmp
);
2301 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2304 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2305 tcg_temp_free_i32(tmp
);
2308 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2311 tcg_temp_free_i32(tmp
);
2312 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2313 gen_op_iwmmxt_set_mup();
2314 gen_op_iwmmxt_set_cup();
2316 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2317 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2318 wrd
= (insn
>> 12) & 0xf;
2319 rd0
= (insn
>> 16) & 0xf;
2320 rd1
= (insn
>> 0) & 0xf;
2321 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2322 switch ((insn
>> 22) & 3) {
2324 if (insn
& (1 << 21))
2325 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2327 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2330 if (insn
& (1 << 21))
2331 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2333 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2336 if (insn
& (1 << 21))
2337 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2339 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2344 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2345 gen_op_iwmmxt_set_mup();
2347 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2348 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2349 wrd
= (insn
>> 12) & 0xf;
2350 rd0
= (insn
>> 16) & 0xf;
2351 rd1
= (insn
>> 0) & 0xf;
2352 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2353 switch ((insn
>> 22) & 3) {
2355 if (insn
& (1 << 21))
2356 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2358 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2361 if (insn
& (1 << 21))
2362 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2364 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2367 if (insn
& (1 << 21))
2368 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2370 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2375 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2376 gen_op_iwmmxt_set_mup();
2378 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2379 case 0x402: case 0x502: case 0x602: case 0x702:
2380 wrd
= (insn
>> 12) & 0xf;
2381 rd0
= (insn
>> 16) & 0xf;
2382 rd1
= (insn
>> 0) & 0xf;
2383 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2384 tmp
= tcg_const_i32((insn
>> 20) & 3);
2385 iwmmxt_load_reg(cpu_V1
, rd1
);
2386 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2387 tcg_temp_free_i32(tmp
);
2388 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2389 gen_op_iwmmxt_set_mup();
2391 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2392 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2393 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2394 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2395 wrd
= (insn
>> 12) & 0xf;
2396 rd0
= (insn
>> 16) & 0xf;
2397 rd1
= (insn
>> 0) & 0xf;
2398 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2399 switch ((insn
>> 20) & 0xf) {
2401 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2404 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2407 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2410 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2413 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2416 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2419 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2422 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2425 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2430 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2431 gen_op_iwmmxt_set_mup();
2432 gen_op_iwmmxt_set_cup();
2434 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2435 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2436 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2437 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2438 wrd
= (insn
>> 12) & 0xf;
2439 rd0
= (insn
>> 16) & 0xf;
2440 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2441 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2442 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2443 tcg_temp_free_i32(tmp
);
2444 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2445 gen_op_iwmmxt_set_mup();
2446 gen_op_iwmmxt_set_cup();
2448 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2449 case 0x418: case 0x518: case 0x618: case 0x718:
2450 case 0x818: case 0x918: case 0xa18: case 0xb18:
2451 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2452 wrd
= (insn
>> 12) & 0xf;
2453 rd0
= (insn
>> 16) & 0xf;
2454 rd1
= (insn
>> 0) & 0xf;
2455 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2456 switch ((insn
>> 20) & 0xf) {
2458 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2461 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2464 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2467 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2470 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2473 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2476 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2479 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2482 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2487 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2488 gen_op_iwmmxt_set_mup();
2489 gen_op_iwmmxt_set_cup();
2491 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2492 case 0x408: case 0x508: case 0x608: case 0x708:
2493 case 0x808: case 0x908: case 0xa08: case 0xb08:
2494 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2495 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2497 wrd
= (insn
>> 12) & 0xf;
2498 rd0
= (insn
>> 16) & 0xf;
2499 rd1
= (insn
>> 0) & 0xf;
2500 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2501 switch ((insn
>> 22) & 3) {
2503 if (insn
& (1 << 21))
2504 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2506 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2509 if (insn
& (1 << 21))
2510 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2512 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2515 if (insn
& (1 << 21))
2516 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2518 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2521 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2522 gen_op_iwmmxt_set_mup();
2523 gen_op_iwmmxt_set_cup();
2525 case 0x201: case 0x203: case 0x205: case 0x207:
2526 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2527 case 0x211: case 0x213: case 0x215: case 0x217:
2528 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2529 wrd
= (insn
>> 5) & 0xf;
2530 rd0
= (insn
>> 12) & 0xf;
2531 rd1
= (insn
>> 0) & 0xf;
2532 if (rd0
== 0xf || rd1
== 0xf)
2534 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2535 tmp
= load_reg(s
, rd0
);
2536 tmp2
= load_reg(s
, rd1
);
2537 switch ((insn
>> 16) & 0xf) {
2538 case 0x0: /* TMIA */
2539 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2541 case 0x8: /* TMIAPH */
2542 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2544 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2545 if (insn
& (1 << 16))
2546 tcg_gen_shri_i32(tmp
, tmp
, 16);
2547 if (insn
& (1 << 17))
2548 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2549 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2552 tcg_temp_free_i32(tmp2
);
2553 tcg_temp_free_i32(tmp
);
2556 tcg_temp_free_i32(tmp2
);
2557 tcg_temp_free_i32(tmp
);
2558 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2559 gen_op_iwmmxt_set_mup();
2568 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2569 (ie. an undefined instruction). */
2570 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2572 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2575 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2576 /* Multiply with Internal Accumulate Format */
2577 rd0
= (insn
>> 12) & 0xf;
2579 acc
= (insn
>> 5) & 7;
2584 tmp
= load_reg(s
, rd0
);
2585 tmp2
= load_reg(s
, rd1
);
2586 switch ((insn
>> 16) & 0xf) {
2588 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2590 case 0x8: /* MIAPH */
2591 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2593 case 0xc: /* MIABB */
2594 case 0xd: /* MIABT */
2595 case 0xe: /* MIATB */
2596 case 0xf: /* MIATT */
2597 if (insn
& (1 << 16))
2598 tcg_gen_shri_i32(tmp
, tmp
, 16);
2599 if (insn
& (1 << 17))
2600 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2601 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2606 tcg_temp_free_i32(tmp2
);
2607 tcg_temp_free_i32(tmp
);
2609 gen_op_iwmmxt_movq_wRn_M0(acc
);
2613 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2614 /* Internal Accumulator Access Format */
2615 rdhi
= (insn
>> 16) & 0xf;
2616 rdlo
= (insn
>> 12) & 0xf;
2622 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2623 iwmmxt_load_reg(cpu_V0
, acc
);
2624 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2625 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2626 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2627 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2629 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2630 iwmmxt_store_reg(cpu_V0
, acc
);
2638 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2639 #define VFP_SREG(insn, bigbit, smallbit) \
2640 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2641 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2642 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2643 reg = (((insn) >> (bigbit)) & 0x0f) \
2644 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2646 if (insn & (1 << (smallbit))) \
2648 reg = ((insn) >> (bigbit)) & 0x0f; \
2651 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2652 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2653 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2654 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2655 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2656 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2658 /* Move between integer and VFP cores. */
2659 static TCGv_i32
gen_vfp_mrs(void)
2661 TCGv_i32 tmp
= tcg_temp_new_i32();
2662 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2666 static void gen_vfp_msr(TCGv_i32 tmp
)
2668 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2669 tcg_temp_free_i32(tmp
);
2672 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2674 TCGv_i32 tmp
= tcg_temp_new_i32();
2676 tcg_gen_shri_i32(var
, var
, shift
);
2677 tcg_gen_ext8u_i32(var
, var
);
2678 tcg_gen_shli_i32(tmp
, var
, 8);
2679 tcg_gen_or_i32(var
, var
, tmp
);
2680 tcg_gen_shli_i32(tmp
, var
, 16);
2681 tcg_gen_or_i32(var
, var
, tmp
);
2682 tcg_temp_free_i32(tmp
);
2685 static void gen_neon_dup_low16(TCGv_i32 var
)
2687 TCGv_i32 tmp
= tcg_temp_new_i32();
2688 tcg_gen_ext16u_i32(var
, var
);
2689 tcg_gen_shli_i32(tmp
, var
, 16);
2690 tcg_gen_or_i32(var
, var
, tmp
);
2691 tcg_temp_free_i32(tmp
);
2694 static void gen_neon_dup_high16(TCGv_i32 var
)
2696 TCGv_i32 tmp
= tcg_temp_new_i32();
2697 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2698 tcg_gen_shri_i32(tmp
, var
, 16);
2699 tcg_gen_or_i32(var
, var
, tmp
);
2700 tcg_temp_free_i32(tmp
);
2703 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2705 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2706 TCGv_i32 tmp
= tcg_temp_new_i32();
2709 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
2710 gen_neon_dup_u8(tmp
, 0);
2713 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
2714 gen_neon_dup_low16(tmp
);
2717 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
2719 default: /* Avoid compiler warnings. */
2725 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2728 uint32_t cc
= extract32(insn
, 20, 2);
2731 TCGv_i64 frn
, frm
, dest
;
2732 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2734 zero
= tcg_const_i64(0);
2736 frn
= tcg_temp_new_i64();
2737 frm
= tcg_temp_new_i64();
2738 dest
= tcg_temp_new_i64();
2740 zf
= tcg_temp_new_i64();
2741 nf
= tcg_temp_new_i64();
2742 vf
= tcg_temp_new_i64();
2744 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2745 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2746 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2748 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2749 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2752 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2756 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2759 case 2: /* ge: N == V -> N ^ V == 0 */
2760 tmp
= tcg_temp_new_i64();
2761 tcg_gen_xor_i64(tmp
, vf
, nf
);
2762 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2764 tcg_temp_free_i64(tmp
);
2766 case 3: /* gt: !Z && N == V */
2767 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2769 tmp
= tcg_temp_new_i64();
2770 tcg_gen_xor_i64(tmp
, vf
, nf
);
2771 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2773 tcg_temp_free_i64(tmp
);
2776 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2777 tcg_temp_free_i64(frn
);
2778 tcg_temp_free_i64(frm
);
2779 tcg_temp_free_i64(dest
);
2781 tcg_temp_free_i64(zf
);
2782 tcg_temp_free_i64(nf
);
2783 tcg_temp_free_i64(vf
);
2785 tcg_temp_free_i64(zero
);
2787 TCGv_i32 frn
, frm
, dest
;
2790 zero
= tcg_const_i32(0);
2792 frn
= tcg_temp_new_i32();
2793 frm
= tcg_temp_new_i32();
2794 dest
= tcg_temp_new_i32();
2795 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2796 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2799 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2803 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2806 case 2: /* ge: N == V -> N ^ V == 0 */
2807 tmp
= tcg_temp_new_i32();
2808 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2809 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2811 tcg_temp_free_i32(tmp
);
2813 case 3: /* gt: !Z && N == V */
2814 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2816 tmp
= tcg_temp_new_i32();
2817 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2818 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2820 tcg_temp_free_i32(tmp
);
2823 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2824 tcg_temp_free_i32(frn
);
2825 tcg_temp_free_i32(frm
);
2826 tcg_temp_free_i32(dest
);
2828 tcg_temp_free_i32(zero
);
2834 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2835 uint32_t rm
, uint32_t dp
)
2837 uint32_t vmin
= extract32(insn
, 6, 1);
2838 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2841 TCGv_i64 frn
, frm
, dest
;
2843 frn
= tcg_temp_new_i64();
2844 frm
= tcg_temp_new_i64();
2845 dest
= tcg_temp_new_i64();
2847 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2848 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2850 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2852 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2854 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2855 tcg_temp_free_i64(frn
);
2856 tcg_temp_free_i64(frm
);
2857 tcg_temp_free_i64(dest
);
2859 TCGv_i32 frn
, frm
, dest
;
2861 frn
= tcg_temp_new_i32();
2862 frm
= tcg_temp_new_i32();
2863 dest
= tcg_temp_new_i32();
2865 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2866 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2868 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2870 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2872 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2873 tcg_temp_free_i32(frn
);
2874 tcg_temp_free_i32(frm
);
2875 tcg_temp_free_i32(dest
);
2878 tcg_temp_free_ptr(fpst
);
2882 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2885 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2888 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2889 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2894 tcg_op
= tcg_temp_new_i64();
2895 tcg_res
= tcg_temp_new_i64();
2896 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2897 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2898 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2899 tcg_temp_free_i64(tcg_op
);
2900 tcg_temp_free_i64(tcg_res
);
2904 tcg_op
= tcg_temp_new_i32();
2905 tcg_res
= tcg_temp_new_i32();
2906 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2907 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2908 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2909 tcg_temp_free_i32(tcg_op
);
2910 tcg_temp_free_i32(tcg_res
);
2913 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2914 tcg_temp_free_i32(tcg_rmode
);
2916 tcg_temp_free_ptr(fpst
);
2920 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2923 bool is_signed
= extract32(insn
, 7, 1);
2924 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2925 TCGv_i32 tcg_rmode
, tcg_shift
;
2927 tcg_shift
= tcg_const_i32(0);
2929 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2930 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2933 TCGv_i64 tcg_double
, tcg_res
;
2935 /* Rd is encoded as a single precision register even when the source
2936 * is double precision.
2938 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2939 tcg_double
= tcg_temp_new_i64();
2940 tcg_res
= tcg_temp_new_i64();
2941 tcg_tmp
= tcg_temp_new_i32();
2942 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2944 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2946 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2948 tcg_gen_trunc_i64_i32(tcg_tmp
, tcg_res
);
2949 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2950 tcg_temp_free_i32(tcg_tmp
);
2951 tcg_temp_free_i64(tcg_res
);
2952 tcg_temp_free_i64(tcg_double
);
2954 TCGv_i32 tcg_single
, tcg_res
;
2955 tcg_single
= tcg_temp_new_i32();
2956 tcg_res
= tcg_temp_new_i32();
2957 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2959 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2961 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2963 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
2964 tcg_temp_free_i32(tcg_res
);
2965 tcg_temp_free_i32(tcg_single
);
2968 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2969 tcg_temp_free_i32(tcg_rmode
);
2971 tcg_temp_free_i32(tcg_shift
);
2973 tcg_temp_free_ptr(fpst
);
2978 /* Table for converting the most common AArch32 encoding of
2979 * rounding mode to arm_fprounding order (which matches the
2980 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2982 static const uint8_t fp_decode_rm
[] = {
2989 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
2991 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
2993 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
2998 VFP_DREG_D(rd
, insn
);
2999 VFP_DREG_N(rn
, insn
);
3000 VFP_DREG_M(rm
, insn
);
3002 rd
= VFP_SREG_D(insn
);
3003 rn
= VFP_SREG_N(insn
);
3004 rm
= VFP_SREG_M(insn
);
3007 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3008 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3009 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3010 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3011 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3012 /* VRINTA, VRINTN, VRINTP, VRINTM */
3013 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3014 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3015 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3016 /* VCVTA, VCVTN, VCVTP, VCVTM */
3017 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3018 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3023 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3024 (ie. an undefined instruction). */
3025 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3027 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3033 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3037 /* FIXME: this access check should not take precedence over UNDEF
3038 * for invalid encodings; we will generate incorrect syndrome information
3039 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3041 if (!s
->cpacr_fpen
) {
3042 gen_exception_insn(s
, 4, EXCP_UDEF
,
3043 syn_fp_access_trap(1, 0xe, s
->thumb
));
3047 if (!s
->vfp_enabled
) {
3048 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3049 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3051 rn
= (insn
>> 16) & 0xf;
3052 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3053 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3058 if (extract32(insn
, 28, 4) == 0xf) {
3059 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3060 * only used in v8 and above.
3062 return disas_vfp_v8_insn(s
, insn
);
3065 dp
= ((insn
& 0xf00) == 0xb00);
3066 switch ((insn
>> 24) & 0xf) {
3068 if (insn
& (1 << 4)) {
3069 /* single register transfer */
3070 rd
= (insn
>> 12) & 0xf;
3075 VFP_DREG_N(rn
, insn
);
3078 if (insn
& 0x00c00060
3079 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3083 pass
= (insn
>> 21) & 1;
3084 if (insn
& (1 << 22)) {
3086 offset
= ((insn
>> 5) & 3) * 8;
3087 } else if (insn
& (1 << 5)) {
3089 offset
= (insn
& (1 << 6)) ? 16 : 0;
3094 if (insn
& ARM_CP_RW_BIT
) {
3096 tmp
= neon_load_reg(rn
, pass
);
3100 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3101 if (insn
& (1 << 23))
3107 if (insn
& (1 << 23)) {
3109 tcg_gen_shri_i32(tmp
, tmp
, 16);
3115 tcg_gen_sari_i32(tmp
, tmp
, 16);
3124 store_reg(s
, rd
, tmp
);
3127 tmp
= load_reg(s
, rd
);
3128 if (insn
& (1 << 23)) {
3131 gen_neon_dup_u8(tmp
, 0);
3132 } else if (size
== 1) {
3133 gen_neon_dup_low16(tmp
);
3135 for (n
= 0; n
<= pass
* 2; n
++) {
3136 tmp2
= tcg_temp_new_i32();
3137 tcg_gen_mov_i32(tmp2
, tmp
);
3138 neon_store_reg(rn
, n
, tmp2
);
3140 neon_store_reg(rn
, n
, tmp
);
3145 tmp2
= neon_load_reg(rn
, pass
);
3146 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3147 tcg_temp_free_i32(tmp2
);
3150 tmp2
= neon_load_reg(rn
, pass
);
3151 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3152 tcg_temp_free_i32(tmp2
);
3157 neon_store_reg(rn
, pass
, tmp
);
3161 if ((insn
& 0x6f) != 0x00)
3163 rn
= VFP_SREG_N(insn
);
3164 if (insn
& ARM_CP_RW_BIT
) {
3166 if (insn
& (1 << 21)) {
3167 /* system register */
3172 /* VFP2 allows access to FSID from userspace.
3173 VFP3 restricts all id registers to privileged
3176 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3179 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3184 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3186 case ARM_VFP_FPINST
:
3187 case ARM_VFP_FPINST2
:
3188 /* Not present in VFP3. */
3190 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3193 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3197 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3198 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3200 tmp
= tcg_temp_new_i32();
3201 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3205 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3212 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3215 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3221 gen_mov_F0_vreg(0, rn
);
3222 tmp
= gen_vfp_mrs();
3225 /* Set the 4 flag bits in the CPSR. */
3227 tcg_temp_free_i32(tmp
);
3229 store_reg(s
, rd
, tmp
);
3233 if (insn
& (1 << 21)) {
3235 /* system register */
3240 /* Writes are ignored. */
3243 tmp
= load_reg(s
, rd
);
3244 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3245 tcg_temp_free_i32(tmp
);
3251 /* TODO: VFP subarchitecture support.
3252 * For now, keep the EN bit only */
3253 tmp
= load_reg(s
, rd
);
3254 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3255 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3258 case ARM_VFP_FPINST
:
3259 case ARM_VFP_FPINST2
:
3263 tmp
= load_reg(s
, rd
);
3264 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3270 tmp
= load_reg(s
, rd
);
3272 gen_mov_vreg_F0(0, rn
);
3277 /* data processing */
3278 /* The opcode is in bits 23, 21, 20 and 6. */
3279 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3283 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3285 /* rn is register number */
3286 VFP_DREG_N(rn
, insn
);
3289 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3290 ((rn
& 0x1e) == 0x6))) {
3291 /* Integer or single/half precision destination. */
3292 rd
= VFP_SREG_D(insn
);
3294 VFP_DREG_D(rd
, insn
);
3297 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3298 ((rn
& 0x1e) == 0x4))) {
3299 /* VCVT from int or half precision is always from S reg
3300 * regardless of dp bit. VCVT with immediate frac_bits
3301 * has same format as SREG_M.
3303 rm
= VFP_SREG_M(insn
);
3305 VFP_DREG_M(rm
, insn
);
3308 rn
= VFP_SREG_N(insn
);
3309 if (op
== 15 && rn
== 15) {
3310 /* Double precision destination. */
3311 VFP_DREG_D(rd
, insn
);
3313 rd
= VFP_SREG_D(insn
);
3315 /* NB that we implicitly rely on the encoding for the frac_bits
3316 * in VCVT of fixed to float being the same as that of an SREG_M
3318 rm
= VFP_SREG_M(insn
);
3321 veclen
= s
->vec_len
;
3322 if (op
== 15 && rn
> 3)
3325 /* Shut up compiler warnings. */
3336 /* Figure out what type of vector operation this is. */
3337 if ((rd
& bank_mask
) == 0) {
3342 delta_d
= (s
->vec_stride
>> 1) + 1;
3344 delta_d
= s
->vec_stride
+ 1;
3346 if ((rm
& bank_mask
) == 0) {
3347 /* mixed scalar/vector */
3356 /* Load the initial operands. */
3361 /* Integer source */
3362 gen_mov_F0_vreg(0, rm
);
3367 gen_mov_F0_vreg(dp
, rd
);
3368 gen_mov_F1_vreg(dp
, rm
);
3372 /* Compare with zero */
3373 gen_mov_F0_vreg(dp
, rd
);
3384 /* Source and destination the same. */
3385 gen_mov_F0_vreg(dp
, rd
);
3391 /* VCVTB, VCVTT: only present with the halfprec extension
3392 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3393 * (we choose to UNDEF)
3395 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3396 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3399 if (!extract32(rn
, 1, 1)) {
3400 /* Half precision source. */
3401 gen_mov_F0_vreg(0, rm
);
3404 /* Otherwise fall through */
3406 /* One source operand. */
3407 gen_mov_F0_vreg(dp
, rm
);
3411 /* Two source operands. */
3412 gen_mov_F0_vreg(dp
, rn
);
3413 gen_mov_F1_vreg(dp
, rm
);
3417 /* Perform the calculation. */
3419 case 0: /* VMLA: fd + (fn * fm) */
3420 /* Note that order of inputs to the add matters for NaNs */
3422 gen_mov_F0_vreg(dp
, rd
);
3425 case 1: /* VMLS: fd + -(fn * fm) */
3428 gen_mov_F0_vreg(dp
, rd
);
3431 case 2: /* VNMLS: -fd + (fn * fm) */
3432 /* Note that it isn't valid to replace (-A + B) with (B - A)
3433 * or similar plausible looking simplifications
3434 * because this will give wrong results for NaNs.
3437 gen_mov_F0_vreg(dp
, rd
);
3441 case 3: /* VNMLA: -fd + -(fn * fm) */
3444 gen_mov_F0_vreg(dp
, rd
);
3448 case 4: /* mul: fn * fm */
3451 case 5: /* nmul: -(fn * fm) */
3455 case 6: /* add: fn + fm */
3458 case 7: /* sub: fn - fm */
3461 case 8: /* div: fn / fm */
3464 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3465 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3466 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3467 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3468 /* These are fused multiply-add, and must be done as one
3469 * floating point operation with no rounding between the
3470 * multiplication and addition steps.
3471 * NB that doing the negations here as separate steps is
3472 * correct : an input NaN should come out with its sign bit
3473 * flipped if it is a negated-input.
3475 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3483 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3485 frd
= tcg_temp_new_i64();
3486 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3489 gen_helper_vfp_negd(frd
, frd
);
3491 fpst
= get_fpstatus_ptr(0);
3492 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3493 cpu_F1d
, frd
, fpst
);
3494 tcg_temp_free_ptr(fpst
);
3495 tcg_temp_free_i64(frd
);
3501 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3503 frd
= tcg_temp_new_i32();
3504 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3506 gen_helper_vfp_negs(frd
, frd
);
3508 fpst
= get_fpstatus_ptr(0);
3509 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3510 cpu_F1s
, frd
, fpst
);
3511 tcg_temp_free_ptr(fpst
);
3512 tcg_temp_free_i32(frd
);
3515 case 14: /* fconst */
3516 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3520 n
= (insn
<< 12) & 0x80000000;
3521 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3528 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3535 tcg_gen_movi_i32(cpu_F0s
, n
);
3538 case 15: /* extension space */
3552 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3553 tmp
= gen_vfp_mrs();
3554 tcg_gen_ext16u_i32(tmp
, tmp
);
3556 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3559 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3562 tcg_temp_free_i32(tmp
);
3564 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3565 tmp
= gen_vfp_mrs();
3566 tcg_gen_shri_i32(tmp
, tmp
, 16);
3568 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3571 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3574 tcg_temp_free_i32(tmp
);
3576 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3577 tmp
= tcg_temp_new_i32();
3579 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3582 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3585 gen_mov_F0_vreg(0, rd
);
3586 tmp2
= gen_vfp_mrs();
3587 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3588 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3589 tcg_temp_free_i32(tmp2
);
3592 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3593 tmp
= tcg_temp_new_i32();
3595 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3598 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3601 tcg_gen_shli_i32(tmp
, tmp
, 16);
3602 gen_mov_F0_vreg(0, rd
);
3603 tmp2
= gen_vfp_mrs();
3604 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3605 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3606 tcg_temp_free_i32(tmp2
);
3618 case 11: /* cmpez */
3622 case 12: /* vrintr */
3624 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3626 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3628 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3630 tcg_temp_free_ptr(fpst
);
3633 case 13: /* vrintz */
3635 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3637 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3638 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3640 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3642 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3644 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3645 tcg_temp_free_i32(tcg_rmode
);
3646 tcg_temp_free_ptr(fpst
);
3649 case 14: /* vrintx */
3651 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3653 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3655 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3657 tcg_temp_free_ptr(fpst
);
3660 case 15: /* single<->double conversion */
3662 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3664 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3666 case 16: /* fuito */
3667 gen_vfp_uito(dp
, 0);
3669 case 17: /* fsito */
3670 gen_vfp_sito(dp
, 0);
3672 case 20: /* fshto */
3673 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3676 gen_vfp_shto(dp
, 16 - rm
, 0);
3678 case 21: /* fslto */
3679 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3682 gen_vfp_slto(dp
, 32 - rm
, 0);
3684 case 22: /* fuhto */
3685 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3688 gen_vfp_uhto(dp
, 16 - rm
, 0);
3690 case 23: /* fulto */
3691 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3694 gen_vfp_ulto(dp
, 32 - rm
, 0);
3696 case 24: /* ftoui */
3697 gen_vfp_toui(dp
, 0);
3699 case 25: /* ftouiz */
3700 gen_vfp_touiz(dp
, 0);
3702 case 26: /* ftosi */
3703 gen_vfp_tosi(dp
, 0);
3705 case 27: /* ftosiz */
3706 gen_vfp_tosiz(dp
, 0);
3708 case 28: /* ftosh */
3709 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3712 gen_vfp_tosh(dp
, 16 - rm
, 0);
3714 case 29: /* ftosl */
3715 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3718 gen_vfp_tosl(dp
, 32 - rm
, 0);
3720 case 30: /* ftouh */
3721 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3724 gen_vfp_touh(dp
, 16 - rm
, 0);
3726 case 31: /* ftoul */
3727 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3730 gen_vfp_toul(dp
, 32 - rm
, 0);
3732 default: /* undefined */
3736 default: /* undefined */
3740 /* Write back the result. */
3741 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3742 /* Comparison, do nothing. */
3743 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3744 (rn
& 0x1e) == 0x6)) {
3745 /* VCVT double to int: always integer result.
3746 * VCVT double to half precision is always a single
3749 gen_mov_vreg_F0(0, rd
);
3750 } else if (op
== 15 && rn
== 15) {
3752 gen_mov_vreg_F0(!dp
, rd
);
3754 gen_mov_vreg_F0(dp
, rd
);
3757 /* break out of the loop if we have finished */
3761 if (op
== 15 && delta_m
== 0) {
3762 /* single source one-many */
3764 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3766 gen_mov_vreg_F0(dp
, rd
);
3770 /* Setup the next operands. */
3772 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3776 /* One source operand. */
3777 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3779 gen_mov_F0_vreg(dp
, rm
);
3781 /* Two source operands. */
3782 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3784 gen_mov_F0_vreg(dp
, rn
);
3786 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3788 gen_mov_F1_vreg(dp
, rm
);
3796 if ((insn
& 0x03e00000) == 0x00400000) {
3797 /* two-register transfer */
3798 rn
= (insn
>> 16) & 0xf;
3799 rd
= (insn
>> 12) & 0xf;
3801 VFP_DREG_M(rm
, insn
);
3803 rm
= VFP_SREG_M(insn
);
3806 if (insn
& ARM_CP_RW_BIT
) {
3809 gen_mov_F0_vreg(0, rm
* 2);
3810 tmp
= gen_vfp_mrs();
3811 store_reg(s
, rd
, tmp
);
3812 gen_mov_F0_vreg(0, rm
* 2 + 1);
3813 tmp
= gen_vfp_mrs();
3814 store_reg(s
, rn
, tmp
);
3816 gen_mov_F0_vreg(0, rm
);
3817 tmp
= gen_vfp_mrs();
3818 store_reg(s
, rd
, tmp
);
3819 gen_mov_F0_vreg(0, rm
+ 1);
3820 tmp
= gen_vfp_mrs();
3821 store_reg(s
, rn
, tmp
);
3826 tmp
= load_reg(s
, rd
);
3828 gen_mov_vreg_F0(0, rm
* 2);
3829 tmp
= load_reg(s
, rn
);
3831 gen_mov_vreg_F0(0, rm
* 2 + 1);
3833 tmp
= load_reg(s
, rd
);
3835 gen_mov_vreg_F0(0, rm
);
3836 tmp
= load_reg(s
, rn
);
3838 gen_mov_vreg_F0(0, rm
+ 1);
3843 rn
= (insn
>> 16) & 0xf;
3845 VFP_DREG_D(rd
, insn
);
3847 rd
= VFP_SREG_D(insn
);
3848 if ((insn
& 0x01200000) == 0x01000000) {
3849 /* Single load/store */
3850 offset
= (insn
& 0xff) << 2;
3851 if ((insn
& (1 << 23)) == 0)
3853 if (s
->thumb
&& rn
== 15) {
3854 /* This is actually UNPREDICTABLE */
3855 addr
= tcg_temp_new_i32();
3856 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3858 addr
= load_reg(s
, rn
);
3860 tcg_gen_addi_i32(addr
, addr
, offset
);
3861 if (insn
& (1 << 20)) {
3862 gen_vfp_ld(s
, dp
, addr
);
3863 gen_mov_vreg_F0(dp
, rd
);
3865 gen_mov_F0_vreg(dp
, rd
);
3866 gen_vfp_st(s
, dp
, addr
);
3868 tcg_temp_free_i32(addr
);
3870 /* load/store multiple */
3871 int w
= insn
& (1 << 21);
3873 n
= (insn
>> 1) & 0x7f;
3877 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3878 /* P == U , W == 1 => UNDEF */
3881 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3882 /* UNPREDICTABLE cases for bad immediates: we choose to
3883 * UNDEF to avoid generating huge numbers of TCG ops
3887 if (rn
== 15 && w
) {
3888 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3892 if (s
->thumb
&& rn
== 15) {
3893 /* This is actually UNPREDICTABLE */
3894 addr
= tcg_temp_new_i32();
3895 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3897 addr
= load_reg(s
, rn
);
3899 if (insn
& (1 << 24)) /* pre-decrement */
3900 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3906 for (i
= 0; i
< n
; i
++) {
3907 if (insn
& ARM_CP_RW_BIT
) {
3909 gen_vfp_ld(s
, dp
, addr
);
3910 gen_mov_vreg_F0(dp
, rd
+ i
);
3913 gen_mov_F0_vreg(dp
, rd
+ i
);
3914 gen_vfp_st(s
, dp
, addr
);
3916 tcg_gen_addi_i32(addr
, addr
, offset
);
3920 if (insn
& (1 << 24))
3921 offset
= -offset
* n
;
3922 else if (dp
&& (insn
& 1))
3928 tcg_gen_addi_i32(addr
, addr
, offset
);
3929 store_reg(s
, rn
, addr
);
3931 tcg_temp_free_i32(addr
);
3937 /* Should never happen. */
3943 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3945 TranslationBlock
*tb
;
3948 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3950 gen_set_pc_im(s
, dest
);
3951 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3953 gen_set_pc_im(s
, dest
);
3958 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3960 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
3961 /* An indirect jump so that we still trigger the debug exception. */
3966 gen_goto_tb(s
, 0, dest
);
3967 s
->is_jmp
= DISAS_TB_JUMP
;
3971 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3974 tcg_gen_sari_i32(t0
, t0
, 16);
3978 tcg_gen_sari_i32(t1
, t1
, 16);
3981 tcg_gen_mul_i32(t0
, t0
, t1
);
3984 /* Return the mask of PSR bits set by a MSR instruction. */
3985 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
3990 if (flags
& (1 << 0))
3992 if (flags
& (1 << 1))
3994 if (flags
& (1 << 2))
3996 if (flags
& (1 << 3))
3999 /* Mask out undefined bits. */
4000 mask
&= ~CPSR_RESERVED
;
4001 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4004 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4005 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4007 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4008 mask
&= ~(CPSR_E
| CPSR_GE
);
4010 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4013 /* Mask out execution state and reserved bits. */
4015 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4017 /* Mask out privileged bits. */
4023 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4024 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4028 /* ??? This is also undefined in system mode. */
4032 tmp
= load_cpu_field(spsr
);
4033 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4034 tcg_gen_andi_i32(t0
, t0
, mask
);
4035 tcg_gen_or_i32(tmp
, tmp
, t0
);
4036 store_cpu_field(tmp
, spsr
);
4038 gen_set_cpsr(t0
, mask
);
4040 tcg_temp_free_i32(t0
);
4045 /* Returns nonzero if access to the PSR is not permitted. */
4046 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4049 tmp
= tcg_temp_new_i32();
4050 tcg_gen_movi_i32(tmp
, val
);
4051 return gen_set_psr(s
, mask
, spsr
, tmp
);
4054 /* Generate an old-style exception return. Marks pc as dead. */
4055 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4058 store_reg(s
, 15, pc
);
4059 tmp
= load_cpu_field(spsr
);
4060 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
4061 tcg_temp_free_i32(tmp
);
4062 s
->is_jmp
= DISAS_UPDATE
;
4065 /* Generate a v6 exception return. Marks both values as dead. */
4066 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4068 gen_set_cpsr(cpsr
, CPSR_ERET_MASK
);
4069 tcg_temp_free_i32(cpsr
);
4070 store_reg(s
, 15, pc
);
4071 s
->is_jmp
= DISAS_UPDATE
;
4074 static void gen_nop_hint(DisasContext
*s
, int val
)
4078 gen_set_pc_im(s
, s
->pc
);
4079 s
->is_jmp
= DISAS_WFI
;
4082 gen_set_pc_im(s
, s
->pc
);
4083 s
->is_jmp
= DISAS_WFE
;
4087 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4093 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4095 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4098 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4099 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4100 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4105 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4108 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4109 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4110 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4115 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4116 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4117 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4118 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4119 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4121 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4122 switch ((size << 1) | u) { \
4124 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4127 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4130 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4133 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4136 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4139 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4141 default: return 1; \
4144 #define GEN_NEON_INTEGER_OP(name) do { \
4145 switch ((size << 1) | u) { \
4147 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4150 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4153 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4156 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4159 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4162 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4164 default: return 1; \
4167 static TCGv_i32
neon_load_scratch(int scratch
)
4169 TCGv_i32 tmp
= tcg_temp_new_i32();
4170 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4174 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4176 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4177 tcg_temp_free_i32(var
);
4180 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4184 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4186 gen_neon_dup_high16(tmp
);
4188 gen_neon_dup_low16(tmp
);
4191 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4196 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4199 if (!q
&& size
== 2) {
4202 tmp
= tcg_const_i32(rd
);
4203 tmp2
= tcg_const_i32(rm
);
4207 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4210 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4213 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4221 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4224 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4230 tcg_temp_free_i32(tmp
);
4231 tcg_temp_free_i32(tmp2
);
4235 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4238 if (!q
&& size
== 2) {
4241 tmp
= tcg_const_i32(rd
);
4242 tmp2
= tcg_const_i32(rm
);
4246 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4249 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4252 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4260 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4263 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4269 tcg_temp_free_i32(tmp
);
4270 tcg_temp_free_i32(tmp2
);
4274 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4278 rd
= tcg_temp_new_i32();
4279 tmp
= tcg_temp_new_i32();
4281 tcg_gen_shli_i32(rd
, t0
, 8);
4282 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4283 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4284 tcg_gen_or_i32(rd
, rd
, tmp
);
4286 tcg_gen_shri_i32(t1
, t1
, 8);
4287 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4288 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4289 tcg_gen_or_i32(t1
, t1
, tmp
);
4290 tcg_gen_mov_i32(t0
, rd
);
4292 tcg_temp_free_i32(tmp
);
4293 tcg_temp_free_i32(rd
);
4296 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4300 rd
= tcg_temp_new_i32();
4301 tmp
= tcg_temp_new_i32();
4303 tcg_gen_shli_i32(rd
, t0
, 16);
4304 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4305 tcg_gen_or_i32(rd
, rd
, tmp
);
4306 tcg_gen_shri_i32(t1
, t1
, 16);
4307 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4308 tcg_gen_or_i32(t1
, t1
, tmp
);
4309 tcg_gen_mov_i32(t0
, rd
);
4311 tcg_temp_free_i32(tmp
);
4312 tcg_temp_free_i32(rd
);
4320 } neon_ls_element_type
[11] = {
4334 /* Translate a NEON load/store element instruction. Return nonzero if the
4335 instruction is invalid. */
4336 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4355 /* FIXME: this access check should not take precedence over UNDEF
4356 * for invalid encodings; we will generate incorrect syndrome information
4357 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4359 if (!s
->cpacr_fpen
) {
4360 gen_exception_insn(s
, 4, EXCP_UDEF
,
4361 syn_fp_access_trap(1, 0xe, s
->thumb
));
4365 if (!s
->vfp_enabled
)
4367 VFP_DREG_D(rd
, insn
);
4368 rn
= (insn
>> 16) & 0xf;
4370 load
= (insn
& (1 << 21)) != 0;
4371 if ((insn
& (1 << 23)) == 0) {
4372 /* Load store all elements. */
4373 op
= (insn
>> 8) & 0xf;
4374 size
= (insn
>> 6) & 3;
4377 /* Catch UNDEF cases for bad values of align field */
4380 if (((insn
>> 5) & 1) == 1) {
4385 if (((insn
>> 4) & 3) == 3) {
4392 nregs
= neon_ls_element_type
[op
].nregs
;
4393 interleave
= neon_ls_element_type
[op
].interleave
;
4394 spacing
= neon_ls_element_type
[op
].spacing
;
4395 if (size
== 3 && (interleave
| spacing
) != 1)
4397 addr
= tcg_temp_new_i32();
4398 load_reg_var(s
, addr
, rn
);
4399 stride
= (1 << size
) * interleave
;
4400 for (reg
= 0; reg
< nregs
; reg
++) {
4401 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4402 load_reg_var(s
, addr
, rn
);
4403 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4404 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4405 load_reg_var(s
, addr
, rn
);
4406 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4409 tmp64
= tcg_temp_new_i64();
4411 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4412 neon_store_reg64(tmp64
, rd
);
4414 neon_load_reg64(tmp64
, rd
);
4415 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4417 tcg_temp_free_i64(tmp64
);
4418 tcg_gen_addi_i32(addr
, addr
, stride
);
4420 for (pass
= 0; pass
< 2; pass
++) {
4423 tmp
= tcg_temp_new_i32();
4424 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4425 neon_store_reg(rd
, pass
, tmp
);
4427 tmp
= neon_load_reg(rd
, pass
);
4428 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4429 tcg_temp_free_i32(tmp
);
4431 tcg_gen_addi_i32(addr
, addr
, stride
);
4432 } else if (size
== 1) {
4434 tmp
= tcg_temp_new_i32();
4435 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4436 tcg_gen_addi_i32(addr
, addr
, stride
);
4437 tmp2
= tcg_temp_new_i32();
4438 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4439 tcg_gen_addi_i32(addr
, addr
, stride
);
4440 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4441 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4442 tcg_temp_free_i32(tmp2
);
4443 neon_store_reg(rd
, pass
, tmp
);
4445 tmp
= neon_load_reg(rd
, pass
);
4446 tmp2
= tcg_temp_new_i32();
4447 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4448 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4449 tcg_temp_free_i32(tmp
);
4450 tcg_gen_addi_i32(addr
, addr
, stride
);
4451 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4452 tcg_temp_free_i32(tmp2
);
4453 tcg_gen_addi_i32(addr
, addr
, stride
);
4455 } else /* size == 0 */ {
4457 TCGV_UNUSED_I32(tmp2
);
4458 for (n
= 0; n
< 4; n
++) {
4459 tmp
= tcg_temp_new_i32();
4460 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4461 tcg_gen_addi_i32(addr
, addr
, stride
);
4465 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4466 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4467 tcg_temp_free_i32(tmp
);
4470 neon_store_reg(rd
, pass
, tmp2
);
4472 tmp2
= neon_load_reg(rd
, pass
);
4473 for (n
= 0; n
< 4; n
++) {
4474 tmp
= tcg_temp_new_i32();
4476 tcg_gen_mov_i32(tmp
, tmp2
);
4478 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4480 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4481 tcg_temp_free_i32(tmp
);
4482 tcg_gen_addi_i32(addr
, addr
, stride
);
4484 tcg_temp_free_i32(tmp2
);
4491 tcg_temp_free_i32(addr
);
4494 size
= (insn
>> 10) & 3;
4496 /* Load single element to all lanes. */
4497 int a
= (insn
>> 4) & 1;
4501 size
= (insn
>> 6) & 3;
4502 nregs
= ((insn
>> 8) & 3) + 1;
4505 if (nregs
!= 4 || a
== 0) {
4508 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4511 if (nregs
== 1 && a
== 1 && size
== 0) {
4514 if (nregs
== 3 && a
== 1) {
4517 addr
= tcg_temp_new_i32();
4518 load_reg_var(s
, addr
, rn
);
4520 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4521 tmp
= gen_load_and_replicate(s
, addr
, size
);
4522 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4523 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4524 if (insn
& (1 << 5)) {
4525 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4526 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4528 tcg_temp_free_i32(tmp
);
4530 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4531 stride
= (insn
& (1 << 5)) ? 2 : 1;
4532 for (reg
= 0; reg
< nregs
; reg
++) {
4533 tmp
= gen_load_and_replicate(s
, addr
, size
);
4534 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4535 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4536 tcg_temp_free_i32(tmp
);
4537 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4541 tcg_temp_free_i32(addr
);
4542 stride
= (1 << size
) * nregs
;
4544 /* Single element. */
4545 int idx
= (insn
>> 4) & 0xf;
4546 pass
= (insn
>> 7) & 1;
4549 shift
= ((insn
>> 5) & 3) * 8;
4553 shift
= ((insn
>> 6) & 1) * 16;
4554 stride
= (insn
& (1 << 5)) ? 2 : 1;
4558 stride
= (insn
& (1 << 6)) ? 2 : 1;
4563 nregs
= ((insn
>> 8) & 3) + 1;
4564 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4567 if (((idx
& (1 << size
)) != 0) ||
4568 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4573 if ((idx
& 1) != 0) {
4578 if (size
== 2 && (idx
& 2) != 0) {
4583 if ((size
== 2) && ((idx
& 3) == 3)) {
4590 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4591 /* Attempts to write off the end of the register file
4592 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4593 * the neon_load_reg() would write off the end of the array.
4597 addr
= tcg_temp_new_i32();
4598 load_reg_var(s
, addr
, rn
);
4599 for (reg
= 0; reg
< nregs
; reg
++) {
4601 tmp
= tcg_temp_new_i32();
4604 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4607 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4610 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4612 default: /* Avoid compiler warnings. */
4616 tmp2
= neon_load_reg(rd
, pass
);
4617 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4618 shift
, size
? 16 : 8);
4619 tcg_temp_free_i32(tmp2
);
4621 neon_store_reg(rd
, pass
, tmp
);
4622 } else { /* Store */
4623 tmp
= neon_load_reg(rd
, pass
);
4625 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4628 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4631 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4634 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4637 tcg_temp_free_i32(tmp
);
4640 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4642 tcg_temp_free_i32(addr
);
4643 stride
= nregs
* (1 << size
);
4649 base
= load_reg(s
, rn
);
4651 tcg_gen_addi_i32(base
, base
, stride
);
4654 index
= load_reg(s
, rm
);
4655 tcg_gen_add_i32(base
, base
, index
);
4656 tcg_temp_free_i32(index
);
4658 store_reg(s
, rn
, base
);
4663 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4664 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4666 tcg_gen_and_i32(t
, t
, c
);
4667 tcg_gen_andc_i32(f
, f
, c
);
4668 tcg_gen_or_i32(dest
, t
, f
);
4671 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4674 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4675 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4676 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4681 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4684 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4685 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4686 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4691 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4694 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4695 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4696 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4701 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4704 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4705 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4706 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4711 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4717 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4718 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4723 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4724 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4731 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4732 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4737 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4738 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4745 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4749 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4750 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4751 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4756 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4757 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4758 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4762 tcg_temp_free_i32(src
);
4765 static inline void gen_neon_addl(int size
)
4768 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4769 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4770 case 2: tcg_gen_add_i64(CPU_V001
); break;
4775 static inline void gen_neon_subl(int size
)
4778 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4779 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4780 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4785 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4788 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4789 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4791 tcg_gen_neg_i64(var
, var
);
4797 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4800 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4801 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4806 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4811 switch ((size
<< 1) | u
) {
4812 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4813 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4814 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4815 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4817 tmp
= gen_muls_i64_i32(a
, b
);
4818 tcg_gen_mov_i64(dest
, tmp
);
4819 tcg_temp_free_i64(tmp
);
4822 tmp
= gen_mulu_i64_i32(a
, b
);
4823 tcg_gen_mov_i64(dest
, tmp
);
4824 tcg_temp_free_i64(tmp
);
4829 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4830 Don't forget to clean them now. */
4832 tcg_temp_free_i32(a
);
4833 tcg_temp_free_i32(b
);
4837 static void gen_neon_narrow_op(int op
, int u
, int size
,
4838 TCGv_i32 dest
, TCGv_i64 src
)
4842 gen_neon_unarrow_sats(size
, dest
, src
);
4844 gen_neon_narrow(size
, dest
, src
);
4848 gen_neon_narrow_satu(size
, dest
, src
);
4850 gen_neon_narrow_sats(size
, dest
, src
);
4855 /* Symbolic constants for op fields for Neon 3-register same-length.
4856 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4859 #define NEON_3R_VHADD 0
4860 #define NEON_3R_VQADD 1
4861 #define NEON_3R_VRHADD 2
4862 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4863 #define NEON_3R_VHSUB 4
4864 #define NEON_3R_VQSUB 5
4865 #define NEON_3R_VCGT 6
4866 #define NEON_3R_VCGE 7
4867 #define NEON_3R_VSHL 8
4868 #define NEON_3R_VQSHL 9
4869 #define NEON_3R_VRSHL 10
4870 #define NEON_3R_VQRSHL 11
4871 #define NEON_3R_VMAX 12
4872 #define NEON_3R_VMIN 13
4873 #define NEON_3R_VABD 14
4874 #define NEON_3R_VABA 15
4875 #define NEON_3R_VADD_VSUB 16
4876 #define NEON_3R_VTST_VCEQ 17
4877 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4878 #define NEON_3R_VMUL 19
4879 #define NEON_3R_VPMAX 20
4880 #define NEON_3R_VPMIN 21
4881 #define NEON_3R_VQDMULH_VQRDMULH 22
4882 #define NEON_3R_VPADD 23
4883 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4884 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4885 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4886 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4887 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4888 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4889 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4890 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4892 static const uint8_t neon_3r_sizes
[] = {
4893 [NEON_3R_VHADD
] = 0x7,
4894 [NEON_3R_VQADD
] = 0xf,
4895 [NEON_3R_VRHADD
] = 0x7,
4896 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4897 [NEON_3R_VHSUB
] = 0x7,
4898 [NEON_3R_VQSUB
] = 0xf,
4899 [NEON_3R_VCGT
] = 0x7,
4900 [NEON_3R_VCGE
] = 0x7,
4901 [NEON_3R_VSHL
] = 0xf,
4902 [NEON_3R_VQSHL
] = 0xf,
4903 [NEON_3R_VRSHL
] = 0xf,
4904 [NEON_3R_VQRSHL
] = 0xf,
4905 [NEON_3R_VMAX
] = 0x7,
4906 [NEON_3R_VMIN
] = 0x7,
4907 [NEON_3R_VABD
] = 0x7,
4908 [NEON_3R_VABA
] = 0x7,
4909 [NEON_3R_VADD_VSUB
] = 0xf,
4910 [NEON_3R_VTST_VCEQ
] = 0x7,
4911 [NEON_3R_VML
] = 0x7,
4912 [NEON_3R_VMUL
] = 0x7,
4913 [NEON_3R_VPMAX
] = 0x7,
4914 [NEON_3R_VPMIN
] = 0x7,
4915 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4916 [NEON_3R_VPADD
] = 0x7,
4917 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4918 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4919 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4920 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4921 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4922 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4923 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4924 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4927 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4928 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4931 #define NEON_2RM_VREV64 0
4932 #define NEON_2RM_VREV32 1
4933 #define NEON_2RM_VREV16 2
4934 #define NEON_2RM_VPADDL 4
4935 #define NEON_2RM_VPADDL_U 5
4936 #define NEON_2RM_AESE 6 /* Includes AESD */
4937 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4938 #define NEON_2RM_VCLS 8
4939 #define NEON_2RM_VCLZ 9
4940 #define NEON_2RM_VCNT 10
4941 #define NEON_2RM_VMVN 11
4942 #define NEON_2RM_VPADAL 12
4943 #define NEON_2RM_VPADAL_U 13
4944 #define NEON_2RM_VQABS 14
4945 #define NEON_2RM_VQNEG 15
4946 #define NEON_2RM_VCGT0 16
4947 #define NEON_2RM_VCGE0 17
4948 #define NEON_2RM_VCEQ0 18
4949 #define NEON_2RM_VCLE0 19
4950 #define NEON_2RM_VCLT0 20
4951 #define NEON_2RM_SHA1H 21
4952 #define NEON_2RM_VABS 22
4953 #define NEON_2RM_VNEG 23
4954 #define NEON_2RM_VCGT0_F 24
4955 #define NEON_2RM_VCGE0_F 25
4956 #define NEON_2RM_VCEQ0_F 26
4957 #define NEON_2RM_VCLE0_F 27
4958 #define NEON_2RM_VCLT0_F 28
4959 #define NEON_2RM_VABS_F 30
4960 #define NEON_2RM_VNEG_F 31
4961 #define NEON_2RM_VSWP 32
4962 #define NEON_2RM_VTRN 33
4963 #define NEON_2RM_VUZP 34
4964 #define NEON_2RM_VZIP 35
4965 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4966 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4967 #define NEON_2RM_VSHLL 38
4968 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4969 #define NEON_2RM_VRINTN 40
4970 #define NEON_2RM_VRINTX 41
4971 #define NEON_2RM_VRINTA 42
4972 #define NEON_2RM_VRINTZ 43
4973 #define NEON_2RM_VCVT_F16_F32 44
4974 #define NEON_2RM_VRINTM 45
4975 #define NEON_2RM_VCVT_F32_F16 46
4976 #define NEON_2RM_VRINTP 47
4977 #define NEON_2RM_VCVTAU 48
4978 #define NEON_2RM_VCVTAS 49
4979 #define NEON_2RM_VCVTNU 50
4980 #define NEON_2RM_VCVTNS 51
4981 #define NEON_2RM_VCVTPU 52
4982 #define NEON_2RM_VCVTPS 53
4983 #define NEON_2RM_VCVTMU 54
4984 #define NEON_2RM_VCVTMS 55
4985 #define NEON_2RM_VRECPE 56
4986 #define NEON_2RM_VRSQRTE 57
4987 #define NEON_2RM_VRECPE_F 58
4988 #define NEON_2RM_VRSQRTE_F 59
4989 #define NEON_2RM_VCVT_FS 60
4990 #define NEON_2RM_VCVT_FU 61
4991 #define NEON_2RM_VCVT_SF 62
4992 #define NEON_2RM_VCVT_UF 63
4994 static int neon_2rm_is_float_op(int op
)
4996 /* Return true if this neon 2reg-misc op is float-to-float */
4997 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4998 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4999 op
== NEON_2RM_VRINTM
||
5000 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5001 op
>= NEON_2RM_VRECPE_F
);
5004 /* Each entry in this array has bit n set if the insn allows
5005 * size value n (otherwise it will UNDEF). Since unallocated
5006 * op values will have no bits set they always UNDEF.
5008 static const uint8_t neon_2rm_sizes
[] = {
5009 [NEON_2RM_VREV64
] = 0x7,
5010 [NEON_2RM_VREV32
] = 0x3,
5011 [NEON_2RM_VREV16
] = 0x1,
5012 [NEON_2RM_VPADDL
] = 0x7,
5013 [NEON_2RM_VPADDL_U
] = 0x7,
5014 [NEON_2RM_AESE
] = 0x1,
5015 [NEON_2RM_AESMC
] = 0x1,
5016 [NEON_2RM_VCLS
] = 0x7,
5017 [NEON_2RM_VCLZ
] = 0x7,
5018 [NEON_2RM_VCNT
] = 0x1,
5019 [NEON_2RM_VMVN
] = 0x1,
5020 [NEON_2RM_VPADAL
] = 0x7,
5021 [NEON_2RM_VPADAL_U
] = 0x7,
5022 [NEON_2RM_VQABS
] = 0x7,
5023 [NEON_2RM_VQNEG
] = 0x7,
5024 [NEON_2RM_VCGT0
] = 0x7,
5025 [NEON_2RM_VCGE0
] = 0x7,
5026 [NEON_2RM_VCEQ0
] = 0x7,
5027 [NEON_2RM_VCLE0
] = 0x7,
5028 [NEON_2RM_VCLT0
] = 0x7,
5029 [NEON_2RM_SHA1H
] = 0x4,
5030 [NEON_2RM_VABS
] = 0x7,
5031 [NEON_2RM_VNEG
] = 0x7,
5032 [NEON_2RM_VCGT0_F
] = 0x4,
5033 [NEON_2RM_VCGE0_F
] = 0x4,
5034 [NEON_2RM_VCEQ0_F
] = 0x4,
5035 [NEON_2RM_VCLE0_F
] = 0x4,
5036 [NEON_2RM_VCLT0_F
] = 0x4,
5037 [NEON_2RM_VABS_F
] = 0x4,
5038 [NEON_2RM_VNEG_F
] = 0x4,
5039 [NEON_2RM_VSWP
] = 0x1,
5040 [NEON_2RM_VTRN
] = 0x7,
5041 [NEON_2RM_VUZP
] = 0x7,
5042 [NEON_2RM_VZIP
] = 0x7,
5043 [NEON_2RM_VMOVN
] = 0x7,
5044 [NEON_2RM_VQMOVN
] = 0x7,
5045 [NEON_2RM_VSHLL
] = 0x7,
5046 [NEON_2RM_SHA1SU1
] = 0x4,
5047 [NEON_2RM_VRINTN
] = 0x4,
5048 [NEON_2RM_VRINTX
] = 0x4,
5049 [NEON_2RM_VRINTA
] = 0x4,
5050 [NEON_2RM_VRINTZ
] = 0x4,
5051 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5052 [NEON_2RM_VRINTM
] = 0x4,
5053 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5054 [NEON_2RM_VRINTP
] = 0x4,
5055 [NEON_2RM_VCVTAU
] = 0x4,
5056 [NEON_2RM_VCVTAS
] = 0x4,
5057 [NEON_2RM_VCVTNU
] = 0x4,
5058 [NEON_2RM_VCVTNS
] = 0x4,
5059 [NEON_2RM_VCVTPU
] = 0x4,
5060 [NEON_2RM_VCVTPS
] = 0x4,
5061 [NEON_2RM_VCVTMU
] = 0x4,
5062 [NEON_2RM_VCVTMS
] = 0x4,
5063 [NEON_2RM_VRECPE
] = 0x4,
5064 [NEON_2RM_VRSQRTE
] = 0x4,
5065 [NEON_2RM_VRECPE_F
] = 0x4,
5066 [NEON_2RM_VRSQRTE_F
] = 0x4,
5067 [NEON_2RM_VCVT_FS
] = 0x4,
5068 [NEON_2RM_VCVT_FU
] = 0x4,
5069 [NEON_2RM_VCVT_SF
] = 0x4,
5070 [NEON_2RM_VCVT_UF
] = 0x4,
5073 /* Translate a NEON data processing instruction. Return nonzero if the
5074 instruction is invalid.
5075 We process data in a mixture of 32-bit and 64-bit chunks.
5076 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5078 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5090 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5093 /* FIXME: this access check should not take precedence over UNDEF
5094 * for invalid encodings; we will generate incorrect syndrome information
5095 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5097 if (!s
->cpacr_fpen
) {
5098 gen_exception_insn(s
, 4, EXCP_UDEF
,
5099 syn_fp_access_trap(1, 0xe, s
->thumb
));
5103 if (!s
->vfp_enabled
)
5105 q
= (insn
& (1 << 6)) != 0;
5106 u
= (insn
>> 24) & 1;
5107 VFP_DREG_D(rd
, insn
);
5108 VFP_DREG_N(rn
, insn
);
5109 VFP_DREG_M(rm
, insn
);
5110 size
= (insn
>> 20) & 3;
5111 if ((insn
& (1 << 23)) == 0) {
5112 /* Three register same length. */
5113 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5114 /* Catch invalid op and bad size combinations: UNDEF */
5115 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5118 /* All insns of this form UNDEF for either this condition or the
5119 * superset of cases "Q==1"; we catch the latter later.
5121 if (q
&& ((rd
| rn
| rm
) & 1)) {
5125 * The SHA-1/SHA-256 3-register instructions require special treatment
5126 * here, as their size field is overloaded as an op type selector, and
5127 * they all consume their input in a single pass.
5129 if (op
== NEON_3R_SHA
) {
5133 if (!u
) { /* SHA-1 */
5134 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5137 tmp
= tcg_const_i32(rd
);
5138 tmp2
= tcg_const_i32(rn
);
5139 tmp3
= tcg_const_i32(rm
);
5140 tmp4
= tcg_const_i32(size
);
5141 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5142 tcg_temp_free_i32(tmp4
);
5143 } else { /* SHA-256 */
5144 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5147 tmp
= tcg_const_i32(rd
);
5148 tmp2
= tcg_const_i32(rn
);
5149 tmp3
= tcg_const_i32(rm
);
5152 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5155 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5158 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5162 tcg_temp_free_i32(tmp
);
5163 tcg_temp_free_i32(tmp2
);
5164 tcg_temp_free_i32(tmp3
);
5167 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5168 /* 64-bit element instructions. */
5169 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5170 neon_load_reg64(cpu_V0
, rn
+ pass
);
5171 neon_load_reg64(cpu_V1
, rm
+ pass
);
5175 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5178 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5184 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5187 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5193 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5195 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5200 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5203 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5209 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5211 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5214 case NEON_3R_VQRSHL
:
5216 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5219 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5223 case NEON_3R_VADD_VSUB
:
5225 tcg_gen_sub_i64(CPU_V001
);
5227 tcg_gen_add_i64(CPU_V001
);
5233 neon_store_reg64(cpu_V0
, rd
+ pass
);
5242 case NEON_3R_VQRSHL
:
5245 /* Shift instruction operands are reversed. */
5260 case NEON_3R_FLOAT_ARITH
:
5261 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5263 case NEON_3R_FLOAT_MINMAX
:
5264 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5266 case NEON_3R_FLOAT_CMP
:
5268 /* no encoding for U=0 C=1x */
5272 case NEON_3R_FLOAT_ACMP
:
5277 case NEON_3R_FLOAT_MISC
:
5278 /* VMAXNM/VMINNM in ARMv8 */
5279 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5284 if (u
&& (size
!= 0)) {
5285 /* UNDEF on invalid size for polynomial subcase */
5290 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5298 if (pairwise
&& q
) {
5299 /* All the pairwise insns UNDEF if Q is set */
5303 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5308 tmp
= neon_load_reg(rn
, 0);
5309 tmp2
= neon_load_reg(rn
, 1);
5311 tmp
= neon_load_reg(rm
, 0);
5312 tmp2
= neon_load_reg(rm
, 1);
5316 tmp
= neon_load_reg(rn
, pass
);
5317 tmp2
= neon_load_reg(rm
, pass
);
5321 GEN_NEON_INTEGER_OP(hadd
);
5324 GEN_NEON_INTEGER_OP_ENV(qadd
);
5326 case NEON_3R_VRHADD
:
5327 GEN_NEON_INTEGER_OP(rhadd
);
5329 case NEON_3R_LOGIC
: /* Logic ops. */
5330 switch ((u
<< 2) | size
) {
5332 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5335 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5338 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5341 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5344 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5347 tmp3
= neon_load_reg(rd
, pass
);
5348 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5349 tcg_temp_free_i32(tmp3
);
5352 tmp3
= neon_load_reg(rd
, pass
);
5353 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5354 tcg_temp_free_i32(tmp3
);
5357 tmp3
= neon_load_reg(rd
, pass
);
5358 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5359 tcg_temp_free_i32(tmp3
);
5364 GEN_NEON_INTEGER_OP(hsub
);
5367 GEN_NEON_INTEGER_OP_ENV(qsub
);
5370 GEN_NEON_INTEGER_OP(cgt
);
5373 GEN_NEON_INTEGER_OP(cge
);
5376 GEN_NEON_INTEGER_OP(shl
);
5379 GEN_NEON_INTEGER_OP_ENV(qshl
);
5382 GEN_NEON_INTEGER_OP(rshl
);
5384 case NEON_3R_VQRSHL
:
5385 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5388 GEN_NEON_INTEGER_OP(max
);
5391 GEN_NEON_INTEGER_OP(min
);
5394 GEN_NEON_INTEGER_OP(abd
);
5397 GEN_NEON_INTEGER_OP(abd
);
5398 tcg_temp_free_i32(tmp2
);
5399 tmp2
= neon_load_reg(rd
, pass
);
5400 gen_neon_add(size
, tmp
, tmp2
);
5402 case NEON_3R_VADD_VSUB
:
5403 if (!u
) { /* VADD */
5404 gen_neon_add(size
, tmp
, tmp2
);
5407 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5408 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5409 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5414 case NEON_3R_VTST_VCEQ
:
5415 if (!u
) { /* VTST */
5417 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5418 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5419 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5424 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5425 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5426 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5431 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5433 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5434 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5435 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5438 tcg_temp_free_i32(tmp2
);
5439 tmp2
= neon_load_reg(rd
, pass
);
5441 gen_neon_rsb(size
, tmp
, tmp2
);
5443 gen_neon_add(size
, tmp
, tmp2
);
5447 if (u
) { /* polynomial */
5448 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5449 } else { /* Integer */
5451 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5452 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5453 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5459 GEN_NEON_INTEGER_OP(pmax
);
5462 GEN_NEON_INTEGER_OP(pmin
);
5464 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5465 if (!u
) { /* VQDMULH */
5468 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5471 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5475 } else { /* VQRDMULH */
5478 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5481 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5489 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5490 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5491 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5495 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5497 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5498 switch ((u
<< 2) | size
) {
5501 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5504 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5507 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5512 tcg_temp_free_ptr(fpstatus
);
5515 case NEON_3R_FLOAT_MULTIPLY
:
5517 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5518 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5520 tcg_temp_free_i32(tmp2
);
5521 tmp2
= neon_load_reg(rd
, pass
);
5523 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5525 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5528 tcg_temp_free_ptr(fpstatus
);
5531 case NEON_3R_FLOAT_CMP
:
5533 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5535 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5538 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5540 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5543 tcg_temp_free_ptr(fpstatus
);
5546 case NEON_3R_FLOAT_ACMP
:
5548 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5550 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5552 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5554 tcg_temp_free_ptr(fpstatus
);
5557 case NEON_3R_FLOAT_MINMAX
:
5559 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5561 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5563 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5565 tcg_temp_free_ptr(fpstatus
);
5568 case NEON_3R_FLOAT_MISC
:
5571 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5573 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5575 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5577 tcg_temp_free_ptr(fpstatus
);
5580 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5582 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5588 /* VFMA, VFMS: fused multiply-add */
5589 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5590 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5593 gen_helper_vfp_negs(tmp
, tmp
);
5595 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5596 tcg_temp_free_i32(tmp3
);
5597 tcg_temp_free_ptr(fpstatus
);
5603 tcg_temp_free_i32(tmp2
);
5605 /* Save the result. For elementwise operations we can put it
5606 straight into the destination register. For pairwise operations
5607 we have to be careful to avoid clobbering the source operands. */
5608 if (pairwise
&& rd
== rm
) {
5609 neon_store_scratch(pass
, tmp
);
5611 neon_store_reg(rd
, pass
, tmp
);
5615 if (pairwise
&& rd
== rm
) {
5616 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5617 tmp
= neon_load_scratch(pass
);
5618 neon_store_reg(rd
, pass
, tmp
);
5621 /* End of 3 register same size operations. */
5622 } else if (insn
& (1 << 4)) {
5623 if ((insn
& 0x00380080) != 0) {
5624 /* Two registers and shift. */
5625 op
= (insn
>> 8) & 0xf;
5626 if (insn
& (1 << 7)) {
5634 while ((insn
& (1 << (size
+ 19))) == 0)
5637 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5638 /* To avoid excessive duplication of ops we implement shift
5639 by immediate using the variable shift operations. */
5641 /* Shift by immediate:
5642 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5643 if (q
&& ((rd
| rm
) & 1)) {
5646 if (!u
&& (op
== 4 || op
== 6)) {
5649 /* Right shifts are encoded as N - shift, where N is the
5650 element size in bits. */
5652 shift
= shift
- (1 << (size
+ 3));
5660 imm
= (uint8_t) shift
;
5665 imm
= (uint16_t) shift
;
5676 for (pass
= 0; pass
< count
; pass
++) {
5678 neon_load_reg64(cpu_V0
, rm
+ pass
);
5679 tcg_gen_movi_i64(cpu_V1
, imm
);
5684 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5686 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5691 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5693 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5696 case 5: /* VSHL, VSLI */
5697 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5699 case 6: /* VQSHLU */
5700 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5705 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5708 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5713 if (op
== 1 || op
== 3) {
5715 neon_load_reg64(cpu_V1
, rd
+ pass
);
5716 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5717 } else if (op
== 4 || (op
== 5 && u
)) {
5719 neon_load_reg64(cpu_V1
, rd
+ pass
);
5721 if (shift
< -63 || shift
> 63) {
5725 mask
= 0xffffffffffffffffull
>> -shift
;
5727 mask
= 0xffffffffffffffffull
<< shift
;
5730 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5731 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5733 neon_store_reg64(cpu_V0
, rd
+ pass
);
5734 } else { /* size < 3 */
5735 /* Operands in T0 and T1. */
5736 tmp
= neon_load_reg(rm
, pass
);
5737 tmp2
= tcg_temp_new_i32();
5738 tcg_gen_movi_i32(tmp2
, imm
);
5742 GEN_NEON_INTEGER_OP(shl
);
5746 GEN_NEON_INTEGER_OP(rshl
);
5749 case 5: /* VSHL, VSLI */
5751 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5752 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5753 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5757 case 6: /* VQSHLU */
5760 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5764 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5768 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5776 GEN_NEON_INTEGER_OP_ENV(qshl
);
5779 tcg_temp_free_i32(tmp2
);
5781 if (op
== 1 || op
== 3) {
5783 tmp2
= neon_load_reg(rd
, pass
);
5784 gen_neon_add(size
, tmp
, tmp2
);
5785 tcg_temp_free_i32(tmp2
);
5786 } else if (op
== 4 || (op
== 5 && u
)) {
5791 mask
= 0xff >> -shift
;
5793 mask
= (uint8_t)(0xff << shift
);
5799 mask
= 0xffff >> -shift
;
5801 mask
= (uint16_t)(0xffff << shift
);
5805 if (shift
< -31 || shift
> 31) {
5809 mask
= 0xffffffffu
>> -shift
;
5811 mask
= 0xffffffffu
<< shift
;
5817 tmp2
= neon_load_reg(rd
, pass
);
5818 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5819 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5820 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5821 tcg_temp_free_i32(tmp2
);
5823 neon_store_reg(rd
, pass
, tmp
);
5826 } else if (op
< 10) {
5827 /* Shift by immediate and narrow:
5828 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5829 int input_unsigned
= (op
== 8) ? !u
: u
;
5833 shift
= shift
- (1 << (size
+ 3));
5836 tmp64
= tcg_const_i64(shift
);
5837 neon_load_reg64(cpu_V0
, rm
);
5838 neon_load_reg64(cpu_V1
, rm
+ 1);
5839 for (pass
= 0; pass
< 2; pass
++) {
5847 if (input_unsigned
) {
5848 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5850 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5853 if (input_unsigned
) {
5854 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5856 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5859 tmp
= tcg_temp_new_i32();
5860 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5861 neon_store_reg(rd
, pass
, tmp
);
5863 tcg_temp_free_i64(tmp64
);
5866 imm
= (uint16_t)shift
;
5870 imm
= (uint32_t)shift
;
5872 tmp2
= tcg_const_i32(imm
);
5873 tmp4
= neon_load_reg(rm
+ 1, 0);
5874 tmp5
= neon_load_reg(rm
+ 1, 1);
5875 for (pass
= 0; pass
< 2; pass
++) {
5877 tmp
= neon_load_reg(rm
, 0);
5881 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5884 tmp3
= neon_load_reg(rm
, 1);
5888 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5890 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5891 tcg_temp_free_i32(tmp
);
5892 tcg_temp_free_i32(tmp3
);
5893 tmp
= tcg_temp_new_i32();
5894 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5895 neon_store_reg(rd
, pass
, tmp
);
5897 tcg_temp_free_i32(tmp2
);
5899 } else if (op
== 10) {
5901 if (q
|| (rd
& 1)) {
5904 tmp
= neon_load_reg(rm
, 0);
5905 tmp2
= neon_load_reg(rm
, 1);
5906 for (pass
= 0; pass
< 2; pass
++) {
5910 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5913 /* The shift is less than the width of the source
5914 type, so we can just shift the whole register. */
5915 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5916 /* Widen the result of shift: we need to clear
5917 * the potential overflow bits resulting from
5918 * left bits of the narrow input appearing as
5919 * right bits of left the neighbour narrow
5921 if (size
< 2 || !u
) {
5924 imm
= (0xffu
>> (8 - shift
));
5926 } else if (size
== 1) {
5927 imm
= 0xffff >> (16 - shift
);
5930 imm
= 0xffffffff >> (32 - shift
);
5933 imm64
= imm
| (((uint64_t)imm
) << 32);
5937 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5940 neon_store_reg64(cpu_V0
, rd
+ pass
);
5942 } else if (op
>= 14) {
5943 /* VCVT fixed-point. */
5944 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5947 /* We have already masked out the must-be-1 top bit of imm6,
5948 * hence this 32-shift where the ARM ARM has 64-imm6.
5951 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5952 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5955 gen_vfp_ulto(0, shift
, 1);
5957 gen_vfp_slto(0, shift
, 1);
5960 gen_vfp_toul(0, shift
, 1);
5962 gen_vfp_tosl(0, shift
, 1);
5964 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5969 } else { /* (insn & 0x00380080) == 0 */
5971 if (q
&& (rd
& 1)) {
5975 op
= (insn
>> 8) & 0xf;
5976 /* One register and immediate. */
5977 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5978 invert
= (insn
& (1 << 5)) != 0;
5979 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5980 * We choose to not special-case this and will behave as if a
5981 * valid constant encoding of 0 had been given.
6000 imm
= (imm
<< 8) | (imm
<< 24);
6003 imm
= (imm
<< 8) | 0xff;
6006 imm
= (imm
<< 16) | 0xffff;
6009 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6017 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6018 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6024 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6025 if (op
& 1 && op
< 12) {
6026 tmp
= neon_load_reg(rd
, pass
);
6028 /* The immediate value has already been inverted, so
6030 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6032 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6036 tmp
= tcg_temp_new_i32();
6037 if (op
== 14 && invert
) {
6041 for (n
= 0; n
< 4; n
++) {
6042 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6043 val
|= 0xff << (n
* 8);
6045 tcg_gen_movi_i32(tmp
, val
);
6047 tcg_gen_movi_i32(tmp
, imm
);
6050 neon_store_reg(rd
, pass
, tmp
);
6053 } else { /* (insn & 0x00800010 == 0x00800000) */
6055 op
= (insn
>> 8) & 0xf;
6056 if ((insn
& (1 << 6)) == 0) {
6057 /* Three registers of different lengths. */
6061 /* undefreq: bit 0 : UNDEF if size == 0
6062 * bit 1 : UNDEF if size == 1
6063 * bit 2 : UNDEF if size == 2
6064 * bit 3 : UNDEF if U == 1
6065 * Note that [2:0] set implies 'always UNDEF'
6068 /* prewiden, src1_wide, src2_wide, undefreq */
6069 static const int neon_3reg_wide
[16][4] = {
6070 {1, 0, 0, 0}, /* VADDL */
6071 {1, 1, 0, 0}, /* VADDW */
6072 {1, 0, 0, 0}, /* VSUBL */
6073 {1, 1, 0, 0}, /* VSUBW */
6074 {0, 1, 1, 0}, /* VADDHN */
6075 {0, 0, 0, 0}, /* VABAL */
6076 {0, 1, 1, 0}, /* VSUBHN */
6077 {0, 0, 0, 0}, /* VABDL */
6078 {0, 0, 0, 0}, /* VMLAL */
6079 {0, 0, 0, 9}, /* VQDMLAL */
6080 {0, 0, 0, 0}, /* VMLSL */
6081 {0, 0, 0, 9}, /* VQDMLSL */
6082 {0, 0, 0, 0}, /* Integer VMULL */
6083 {0, 0, 0, 1}, /* VQDMULL */
6084 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6085 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6088 prewiden
= neon_3reg_wide
[op
][0];
6089 src1_wide
= neon_3reg_wide
[op
][1];
6090 src2_wide
= neon_3reg_wide
[op
][2];
6091 undefreq
= neon_3reg_wide
[op
][3];
6093 if ((undefreq
& (1 << size
)) ||
6094 ((undefreq
& 8) && u
)) {
6097 if ((src1_wide
&& (rn
& 1)) ||
6098 (src2_wide
&& (rm
& 1)) ||
6099 (!src2_wide
&& (rd
& 1))) {
6103 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6104 * outside the loop below as it only performs a single pass.
6106 if (op
== 14 && size
== 2) {
6107 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6109 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6112 tcg_rn
= tcg_temp_new_i64();
6113 tcg_rm
= tcg_temp_new_i64();
6114 tcg_rd
= tcg_temp_new_i64();
6115 neon_load_reg64(tcg_rn
, rn
);
6116 neon_load_reg64(tcg_rm
, rm
);
6117 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6118 neon_store_reg64(tcg_rd
, rd
);
6119 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6120 neon_store_reg64(tcg_rd
, rd
+ 1);
6121 tcg_temp_free_i64(tcg_rn
);
6122 tcg_temp_free_i64(tcg_rm
);
6123 tcg_temp_free_i64(tcg_rd
);
6127 /* Avoid overlapping operands. Wide source operands are
6128 always aligned so will never overlap with wide
6129 destinations in problematic ways. */
6130 if (rd
== rm
&& !src2_wide
) {
6131 tmp
= neon_load_reg(rm
, 1);
6132 neon_store_scratch(2, tmp
);
6133 } else if (rd
== rn
&& !src1_wide
) {
6134 tmp
= neon_load_reg(rn
, 1);
6135 neon_store_scratch(2, tmp
);
6137 TCGV_UNUSED_I32(tmp3
);
6138 for (pass
= 0; pass
< 2; pass
++) {
6140 neon_load_reg64(cpu_V0
, rn
+ pass
);
6141 TCGV_UNUSED_I32(tmp
);
6143 if (pass
== 1 && rd
== rn
) {
6144 tmp
= neon_load_scratch(2);
6146 tmp
= neon_load_reg(rn
, pass
);
6149 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6153 neon_load_reg64(cpu_V1
, rm
+ pass
);
6154 TCGV_UNUSED_I32(tmp2
);
6156 if (pass
== 1 && rd
== rm
) {
6157 tmp2
= neon_load_scratch(2);
6159 tmp2
= neon_load_reg(rm
, pass
);
6162 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6166 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6167 gen_neon_addl(size
);
6169 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6170 gen_neon_subl(size
);
6172 case 5: case 7: /* VABAL, VABDL */
6173 switch ((size
<< 1) | u
) {
6175 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6178 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6181 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6184 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6187 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6190 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6194 tcg_temp_free_i32(tmp2
);
6195 tcg_temp_free_i32(tmp
);
6197 case 8: case 9: case 10: case 11: case 12: case 13:
6198 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6199 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6201 case 14: /* Polynomial VMULL */
6202 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6203 tcg_temp_free_i32(tmp2
);
6204 tcg_temp_free_i32(tmp
);
6206 default: /* 15 is RESERVED: caught earlier */
6211 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6212 neon_store_reg64(cpu_V0
, rd
+ pass
);
6213 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6215 neon_load_reg64(cpu_V1
, rd
+ pass
);
6217 case 10: /* VMLSL */
6218 gen_neon_negl(cpu_V0
, size
);
6220 case 5: case 8: /* VABAL, VMLAL */
6221 gen_neon_addl(size
);
6223 case 9: case 11: /* VQDMLAL, VQDMLSL */
6224 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6226 gen_neon_negl(cpu_V0
, size
);
6228 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6233 neon_store_reg64(cpu_V0
, rd
+ pass
);
6234 } else if (op
== 4 || op
== 6) {
6235 /* Narrowing operation. */
6236 tmp
= tcg_temp_new_i32();
6240 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6243 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6246 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6247 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6254 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6257 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6260 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6261 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6262 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6270 neon_store_reg(rd
, 0, tmp3
);
6271 neon_store_reg(rd
, 1, tmp
);
6274 /* Write back the result. */
6275 neon_store_reg64(cpu_V0
, rd
+ pass
);
6279 /* Two registers and a scalar. NB that for ops of this form
6280 * the ARM ARM labels bit 24 as Q, but it is in our variable
6287 case 1: /* Float VMLA scalar */
6288 case 5: /* Floating point VMLS scalar */
6289 case 9: /* Floating point VMUL scalar */
6294 case 0: /* Integer VMLA scalar */
6295 case 4: /* Integer VMLS scalar */
6296 case 8: /* Integer VMUL scalar */
6297 case 12: /* VQDMULH scalar */
6298 case 13: /* VQRDMULH scalar */
6299 if (u
&& ((rd
| rn
) & 1)) {
6302 tmp
= neon_get_scalar(size
, rm
);
6303 neon_store_scratch(0, tmp
);
6304 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6305 tmp
= neon_load_scratch(0);
6306 tmp2
= neon_load_reg(rn
, pass
);
6309 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6311 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6313 } else if (op
== 13) {
6315 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6317 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6319 } else if (op
& 1) {
6320 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6321 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6322 tcg_temp_free_ptr(fpstatus
);
6325 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6326 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6327 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6331 tcg_temp_free_i32(tmp2
);
6334 tmp2
= neon_load_reg(rd
, pass
);
6337 gen_neon_add(size
, tmp
, tmp2
);
6341 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6342 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6343 tcg_temp_free_ptr(fpstatus
);
6347 gen_neon_rsb(size
, tmp
, tmp2
);
6351 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6352 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6353 tcg_temp_free_ptr(fpstatus
);
6359 tcg_temp_free_i32(tmp2
);
6361 neon_store_reg(rd
, pass
, tmp
);
6364 case 3: /* VQDMLAL scalar */
6365 case 7: /* VQDMLSL scalar */
6366 case 11: /* VQDMULL scalar */
6371 case 2: /* VMLAL sclar */
6372 case 6: /* VMLSL scalar */
6373 case 10: /* VMULL scalar */
6377 tmp2
= neon_get_scalar(size
, rm
);
6378 /* We need a copy of tmp2 because gen_neon_mull
6379 * deletes it during pass 0. */
6380 tmp4
= tcg_temp_new_i32();
6381 tcg_gen_mov_i32(tmp4
, tmp2
);
6382 tmp3
= neon_load_reg(rn
, 1);
6384 for (pass
= 0; pass
< 2; pass
++) {
6386 tmp
= neon_load_reg(rn
, 0);
6391 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6393 neon_load_reg64(cpu_V1
, rd
+ pass
);
6397 gen_neon_negl(cpu_V0
, size
);
6400 gen_neon_addl(size
);
6403 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6405 gen_neon_negl(cpu_V0
, size
);
6407 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6413 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6418 neon_store_reg64(cpu_V0
, rd
+ pass
);
6423 default: /* 14 and 15 are RESERVED */
6427 } else { /* size == 3 */
6430 imm
= (insn
>> 8) & 0xf;
6435 if (q
&& ((rd
| rn
| rm
) & 1)) {
6440 neon_load_reg64(cpu_V0
, rn
);
6442 neon_load_reg64(cpu_V1
, rn
+ 1);
6444 } else if (imm
== 8) {
6445 neon_load_reg64(cpu_V0
, rn
+ 1);
6447 neon_load_reg64(cpu_V1
, rm
);
6450 tmp64
= tcg_temp_new_i64();
6452 neon_load_reg64(cpu_V0
, rn
);
6453 neon_load_reg64(tmp64
, rn
+ 1);
6455 neon_load_reg64(cpu_V0
, rn
+ 1);
6456 neon_load_reg64(tmp64
, rm
);
6458 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6459 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6460 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6462 neon_load_reg64(cpu_V1
, rm
);
6464 neon_load_reg64(cpu_V1
, rm
+ 1);
6467 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6468 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6469 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6470 tcg_temp_free_i64(tmp64
);
6473 neon_load_reg64(cpu_V0
, rn
);
6474 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6475 neon_load_reg64(cpu_V1
, rm
);
6476 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6477 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6479 neon_store_reg64(cpu_V0
, rd
);
6481 neon_store_reg64(cpu_V1
, rd
+ 1);
6483 } else if ((insn
& (1 << 11)) == 0) {
6484 /* Two register misc. */
6485 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6486 size
= (insn
>> 18) & 3;
6487 /* UNDEF for unknown op values and bad op-size combinations */
6488 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6491 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6492 q
&& ((rm
| rd
) & 1)) {
6496 case NEON_2RM_VREV64
:
6497 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6498 tmp
= neon_load_reg(rm
, pass
* 2);
6499 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6501 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6502 case 1: gen_swap_half(tmp
); break;
6503 case 2: /* no-op */ break;
6506 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6508 neon_store_reg(rd
, pass
* 2, tmp2
);
6511 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6512 case 1: gen_swap_half(tmp2
); break;
6515 neon_store_reg(rd
, pass
* 2, tmp2
);
6519 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6520 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6521 for (pass
= 0; pass
< q
+ 1; pass
++) {
6522 tmp
= neon_load_reg(rm
, pass
* 2);
6523 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6524 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6525 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6527 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6528 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6529 case 2: tcg_gen_add_i64(CPU_V001
); break;
6532 if (op
>= NEON_2RM_VPADAL
) {
6534 neon_load_reg64(cpu_V1
, rd
+ pass
);
6535 gen_neon_addl(size
);
6537 neon_store_reg64(cpu_V0
, rd
+ pass
);
6543 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6544 tmp
= neon_load_reg(rm
, n
);
6545 tmp2
= neon_load_reg(rd
, n
+ 1);
6546 neon_store_reg(rm
, n
, tmp2
);
6547 neon_store_reg(rd
, n
+ 1, tmp
);
6554 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6559 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6563 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6564 /* also VQMOVUN; op field and mnemonics don't line up */
6568 TCGV_UNUSED_I32(tmp2
);
6569 for (pass
= 0; pass
< 2; pass
++) {
6570 neon_load_reg64(cpu_V0
, rm
+ pass
);
6571 tmp
= tcg_temp_new_i32();
6572 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6577 neon_store_reg(rd
, 0, tmp2
);
6578 neon_store_reg(rd
, 1, tmp
);
6582 case NEON_2RM_VSHLL
:
6583 if (q
|| (rd
& 1)) {
6586 tmp
= neon_load_reg(rm
, 0);
6587 tmp2
= neon_load_reg(rm
, 1);
6588 for (pass
= 0; pass
< 2; pass
++) {
6591 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6592 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6593 neon_store_reg64(cpu_V0
, rd
+ pass
);
6596 case NEON_2RM_VCVT_F16_F32
:
6597 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6601 tmp
= tcg_temp_new_i32();
6602 tmp2
= tcg_temp_new_i32();
6603 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6604 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6605 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6606 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6607 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6608 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6609 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6610 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6611 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6612 neon_store_reg(rd
, 0, tmp2
);
6613 tmp2
= tcg_temp_new_i32();
6614 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6615 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6616 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6617 neon_store_reg(rd
, 1, tmp2
);
6618 tcg_temp_free_i32(tmp
);
6620 case NEON_2RM_VCVT_F32_F16
:
6621 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6625 tmp3
= tcg_temp_new_i32();
6626 tmp
= neon_load_reg(rm
, 0);
6627 tmp2
= neon_load_reg(rm
, 1);
6628 tcg_gen_ext16u_i32(tmp3
, tmp
);
6629 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6630 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6631 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6632 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6633 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6634 tcg_temp_free_i32(tmp
);
6635 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6636 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6637 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6638 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6639 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6640 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6641 tcg_temp_free_i32(tmp2
);
6642 tcg_temp_free_i32(tmp3
);
6644 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6645 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6646 || ((rm
| rd
) & 1)) {
6649 tmp
= tcg_const_i32(rd
);
6650 tmp2
= tcg_const_i32(rm
);
6652 /* Bit 6 is the lowest opcode bit; it distinguishes between
6653 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6655 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6657 if (op
== NEON_2RM_AESE
) {
6658 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6660 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6662 tcg_temp_free_i32(tmp
);
6663 tcg_temp_free_i32(tmp2
);
6664 tcg_temp_free_i32(tmp3
);
6666 case NEON_2RM_SHA1H
:
6667 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
6668 || ((rm
| rd
) & 1)) {
6671 tmp
= tcg_const_i32(rd
);
6672 tmp2
= tcg_const_i32(rm
);
6674 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6676 tcg_temp_free_i32(tmp
);
6677 tcg_temp_free_i32(tmp2
);
6679 case NEON_2RM_SHA1SU1
:
6680 if ((rm
| rd
) & 1) {
6683 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6685 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
6688 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
6691 tmp
= tcg_const_i32(rd
);
6692 tmp2
= tcg_const_i32(rm
);
6694 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6696 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6698 tcg_temp_free_i32(tmp
);
6699 tcg_temp_free_i32(tmp2
);
6703 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6704 if (neon_2rm_is_float_op(op
)) {
6705 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6706 neon_reg_offset(rm
, pass
));
6707 TCGV_UNUSED_I32(tmp
);
6709 tmp
= neon_load_reg(rm
, pass
);
6712 case NEON_2RM_VREV32
:
6714 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6715 case 1: gen_swap_half(tmp
); break;
6719 case NEON_2RM_VREV16
:
6724 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6725 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6726 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6732 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6733 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6734 case 2: gen_helper_clz(tmp
, tmp
); break;
6739 gen_helper_neon_cnt_u8(tmp
, tmp
);
6742 tcg_gen_not_i32(tmp
, tmp
);
6744 case NEON_2RM_VQABS
:
6747 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6750 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6753 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6758 case NEON_2RM_VQNEG
:
6761 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6764 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6767 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6772 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6773 tmp2
= tcg_const_i32(0);
6775 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6776 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6777 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6780 tcg_temp_free_i32(tmp2
);
6781 if (op
== NEON_2RM_VCLE0
) {
6782 tcg_gen_not_i32(tmp
, tmp
);
6785 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6786 tmp2
= tcg_const_i32(0);
6788 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6789 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6790 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6793 tcg_temp_free_i32(tmp2
);
6794 if (op
== NEON_2RM_VCLT0
) {
6795 tcg_gen_not_i32(tmp
, tmp
);
6798 case NEON_2RM_VCEQ0
:
6799 tmp2
= tcg_const_i32(0);
6801 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6802 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6803 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6806 tcg_temp_free_i32(tmp2
);
6810 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6811 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6812 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6817 tmp2
= tcg_const_i32(0);
6818 gen_neon_rsb(size
, tmp
, tmp2
);
6819 tcg_temp_free_i32(tmp2
);
6821 case NEON_2RM_VCGT0_F
:
6823 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6824 tmp2
= tcg_const_i32(0);
6825 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6826 tcg_temp_free_i32(tmp2
);
6827 tcg_temp_free_ptr(fpstatus
);
6830 case NEON_2RM_VCGE0_F
:
6832 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6833 tmp2
= tcg_const_i32(0);
6834 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6835 tcg_temp_free_i32(tmp2
);
6836 tcg_temp_free_ptr(fpstatus
);
6839 case NEON_2RM_VCEQ0_F
:
6841 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6842 tmp2
= tcg_const_i32(0);
6843 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6844 tcg_temp_free_i32(tmp2
);
6845 tcg_temp_free_ptr(fpstatus
);
6848 case NEON_2RM_VCLE0_F
:
6850 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6851 tmp2
= tcg_const_i32(0);
6852 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6853 tcg_temp_free_i32(tmp2
);
6854 tcg_temp_free_ptr(fpstatus
);
6857 case NEON_2RM_VCLT0_F
:
6859 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6860 tmp2
= tcg_const_i32(0);
6861 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6862 tcg_temp_free_i32(tmp2
);
6863 tcg_temp_free_ptr(fpstatus
);
6866 case NEON_2RM_VABS_F
:
6869 case NEON_2RM_VNEG_F
:
6873 tmp2
= neon_load_reg(rd
, pass
);
6874 neon_store_reg(rm
, pass
, tmp2
);
6877 tmp2
= neon_load_reg(rd
, pass
);
6879 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6880 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6883 neon_store_reg(rm
, pass
, tmp2
);
6885 case NEON_2RM_VRINTN
:
6886 case NEON_2RM_VRINTA
:
6887 case NEON_2RM_VRINTM
:
6888 case NEON_2RM_VRINTP
:
6889 case NEON_2RM_VRINTZ
:
6892 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6895 if (op
== NEON_2RM_VRINTZ
) {
6896 rmode
= FPROUNDING_ZERO
;
6898 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6901 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6902 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6904 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6905 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6907 tcg_temp_free_ptr(fpstatus
);
6908 tcg_temp_free_i32(tcg_rmode
);
6911 case NEON_2RM_VRINTX
:
6913 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6914 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6915 tcg_temp_free_ptr(fpstatus
);
6918 case NEON_2RM_VCVTAU
:
6919 case NEON_2RM_VCVTAS
:
6920 case NEON_2RM_VCVTNU
:
6921 case NEON_2RM_VCVTNS
:
6922 case NEON_2RM_VCVTPU
:
6923 case NEON_2RM_VCVTPS
:
6924 case NEON_2RM_VCVTMU
:
6925 case NEON_2RM_VCVTMS
:
6927 bool is_signed
= !extract32(insn
, 7, 1);
6928 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6929 TCGv_i32 tcg_rmode
, tcg_shift
;
6930 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6932 tcg_shift
= tcg_const_i32(0);
6933 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6934 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6938 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6941 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6945 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6947 tcg_temp_free_i32(tcg_rmode
);
6948 tcg_temp_free_i32(tcg_shift
);
6949 tcg_temp_free_ptr(fpst
);
6952 case NEON_2RM_VRECPE
:
6954 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6955 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6956 tcg_temp_free_ptr(fpstatus
);
6959 case NEON_2RM_VRSQRTE
:
6961 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6962 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6963 tcg_temp_free_ptr(fpstatus
);
6966 case NEON_2RM_VRECPE_F
:
6968 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6969 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6970 tcg_temp_free_ptr(fpstatus
);
6973 case NEON_2RM_VRSQRTE_F
:
6975 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6976 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6977 tcg_temp_free_ptr(fpstatus
);
6980 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6983 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6986 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6987 gen_vfp_tosiz(0, 1);
6989 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6990 gen_vfp_touiz(0, 1);
6993 /* Reserved op values were caught by the
6994 * neon_2rm_sizes[] check earlier.
6998 if (neon_2rm_is_float_op(op
)) {
6999 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7000 neon_reg_offset(rd
, pass
));
7002 neon_store_reg(rd
, pass
, tmp
);
7007 } else if ((insn
& (1 << 10)) == 0) {
7009 int n
= ((insn
>> 8) & 3) + 1;
7010 if ((rn
+ n
) > 32) {
7011 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7012 * helper function running off the end of the register file.
7017 if (insn
& (1 << 6)) {
7018 tmp
= neon_load_reg(rd
, 0);
7020 tmp
= tcg_temp_new_i32();
7021 tcg_gen_movi_i32(tmp
, 0);
7023 tmp2
= neon_load_reg(rm
, 0);
7024 tmp4
= tcg_const_i32(rn
);
7025 tmp5
= tcg_const_i32(n
);
7026 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7027 tcg_temp_free_i32(tmp
);
7028 if (insn
& (1 << 6)) {
7029 tmp
= neon_load_reg(rd
, 1);
7031 tmp
= tcg_temp_new_i32();
7032 tcg_gen_movi_i32(tmp
, 0);
7034 tmp3
= neon_load_reg(rm
, 1);
7035 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7036 tcg_temp_free_i32(tmp5
);
7037 tcg_temp_free_i32(tmp4
);
7038 neon_store_reg(rd
, 0, tmp2
);
7039 neon_store_reg(rd
, 1, tmp3
);
7040 tcg_temp_free_i32(tmp
);
7041 } else if ((insn
& 0x380) == 0) {
7043 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7046 if (insn
& (1 << 19)) {
7047 tmp
= neon_load_reg(rm
, 1);
7049 tmp
= neon_load_reg(rm
, 0);
7051 if (insn
& (1 << 16)) {
7052 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7053 } else if (insn
& (1 << 17)) {
7054 if ((insn
>> 18) & 1)
7055 gen_neon_dup_high16(tmp
);
7057 gen_neon_dup_low16(tmp
);
7059 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7060 tmp2
= tcg_temp_new_i32();
7061 tcg_gen_mov_i32(tmp2
, tmp
);
7062 neon_store_reg(rd
, pass
, tmp2
);
7064 tcg_temp_free_i32(tmp
);
7073 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7075 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7076 const ARMCPRegInfo
*ri
;
7078 cpnum
= (insn
>> 8) & 0xf;
7080 /* First check for coprocessor space used for XScale/iwMMXt insns */
7081 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7082 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7085 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7086 return disas_iwmmxt_insn(s
, insn
);
7087 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7088 return disas_dsp_insn(s
, insn
);
7093 /* Otherwise treat as a generic register access */
7094 is64
= (insn
& (1 << 25)) == 0;
7095 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7103 opc1
= (insn
>> 4) & 0xf;
7105 rt2
= (insn
>> 16) & 0xf;
7107 crn
= (insn
>> 16) & 0xf;
7108 opc1
= (insn
>> 21) & 7;
7109 opc2
= (insn
>> 5) & 7;
7112 isread
= (insn
>> 20) & 1;
7113 rt
= (insn
>> 12) & 0xf;
7115 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7116 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7118 /* Check access permissions */
7119 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7124 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7125 /* Emit code to perform further access permissions checks at
7126 * runtime; this may result in an exception.
7127 * Note that on XScale all cp0..c13 registers do an access check
7128 * call in order to handle c15_cpar.
7134 /* Note that since we are an implementation which takes an
7135 * exception on a trapped conditional instruction only if the
7136 * instruction passes its condition code check, we can take
7137 * advantage of the clause in the ARM ARM that allows us to set
7138 * the COND field in the instruction to 0xE in all cases.
7139 * We could fish the actual condition out of the insn (ARM)
7140 * or the condexec bits (Thumb) but it isn't necessary.
7145 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7148 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7149 rt
, isread
, s
->thumb
);
7154 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7157 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7158 rt
, isread
, s
->thumb
);
7162 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7163 * so this can only happen if this is an ARMv7 or earlier CPU,
7164 * in which case the syndrome information won't actually be
7167 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7168 syndrome
= syn_uncategorized();
7172 gen_set_pc_im(s
, s
->pc
);
7173 tmpptr
= tcg_const_ptr(ri
);
7174 tcg_syn
= tcg_const_i32(syndrome
);
7175 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7176 tcg_temp_free_ptr(tmpptr
);
7177 tcg_temp_free_i32(tcg_syn
);
7180 /* Handle special cases first */
7181 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7188 gen_set_pc_im(s
, s
->pc
);
7189 s
->is_jmp
= DISAS_WFI
;
7195 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7204 if (ri
->type
& ARM_CP_CONST
) {
7205 tmp64
= tcg_const_i64(ri
->resetvalue
);
7206 } else if (ri
->readfn
) {
7208 tmp64
= tcg_temp_new_i64();
7209 tmpptr
= tcg_const_ptr(ri
);
7210 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7211 tcg_temp_free_ptr(tmpptr
);
7213 tmp64
= tcg_temp_new_i64();
7214 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7216 tmp
= tcg_temp_new_i32();
7217 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7218 store_reg(s
, rt
, tmp
);
7219 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7220 tmp
= tcg_temp_new_i32();
7221 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7222 tcg_temp_free_i64(tmp64
);
7223 store_reg(s
, rt2
, tmp
);
7226 if (ri
->type
& ARM_CP_CONST
) {
7227 tmp
= tcg_const_i32(ri
->resetvalue
);
7228 } else if (ri
->readfn
) {
7230 tmp
= tcg_temp_new_i32();
7231 tmpptr
= tcg_const_ptr(ri
);
7232 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7233 tcg_temp_free_ptr(tmpptr
);
7235 tmp
= load_cpu_offset(ri
->fieldoffset
);
7238 /* Destination register of r15 for 32 bit loads sets
7239 * the condition codes from the high 4 bits of the value
7242 tcg_temp_free_i32(tmp
);
7244 store_reg(s
, rt
, tmp
);
7249 if (ri
->type
& ARM_CP_CONST
) {
7250 /* If not forbidden by access permissions, treat as WI */
7255 TCGv_i32 tmplo
, tmphi
;
7256 TCGv_i64 tmp64
= tcg_temp_new_i64();
7257 tmplo
= load_reg(s
, rt
);
7258 tmphi
= load_reg(s
, rt2
);
7259 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7260 tcg_temp_free_i32(tmplo
);
7261 tcg_temp_free_i32(tmphi
);
7263 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7264 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7265 tcg_temp_free_ptr(tmpptr
);
7267 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7269 tcg_temp_free_i64(tmp64
);
7274 tmp
= load_reg(s
, rt
);
7275 tmpptr
= tcg_const_ptr(ri
);
7276 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7277 tcg_temp_free_ptr(tmpptr
);
7278 tcg_temp_free_i32(tmp
);
7280 TCGv_i32 tmp
= load_reg(s
, rt
);
7281 store_cpu_offset(tmp
, ri
->fieldoffset
);
7286 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7287 /* I/O operations must end the TB here (whether read or write) */
7290 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7291 /* We default to ending the TB on a coprocessor register write,
7292 * but allow this to be suppressed by the register definition
7293 * (usually only necessary to work around guest bugs).
7301 /* Unknown register; this might be a guest error or a QEMU
7302 * unimplemented feature.
7305 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7306 "64 bit system register cp:%d opc1: %d crm:%d "
7308 isread
? "read" : "write", cpnum
, opc1
, crm
,
7309 s
->ns
? "non-secure" : "secure");
7311 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7312 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7314 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7315 s
->ns
? "non-secure" : "secure");
7322 /* Store a 64-bit value to a register pair. Clobbers val. */
7323 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7326 tmp
= tcg_temp_new_i32();
7327 tcg_gen_trunc_i64_i32(tmp
, val
);
7328 store_reg(s
, rlow
, tmp
);
7329 tmp
= tcg_temp_new_i32();
7330 tcg_gen_shri_i64(val
, val
, 32);
7331 tcg_gen_trunc_i64_i32(tmp
, val
);
7332 store_reg(s
, rhigh
, tmp
);
7335 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7336 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7341 /* Load value and extend to 64 bits. */
7342 tmp
= tcg_temp_new_i64();
7343 tmp2
= load_reg(s
, rlow
);
7344 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7345 tcg_temp_free_i32(tmp2
);
7346 tcg_gen_add_i64(val
, val
, tmp
);
7347 tcg_temp_free_i64(tmp
);
7350 /* load and add a 64-bit value from a register pair. */
7351 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7357 /* Load 64-bit value rd:rn. */
7358 tmpl
= load_reg(s
, rlow
);
7359 tmph
= load_reg(s
, rhigh
);
7360 tmp
= tcg_temp_new_i64();
7361 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7362 tcg_temp_free_i32(tmpl
);
7363 tcg_temp_free_i32(tmph
);
7364 tcg_gen_add_i64(val
, val
, tmp
);
7365 tcg_temp_free_i64(tmp
);
7368 /* Set N and Z flags from hi|lo. */
7369 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7371 tcg_gen_mov_i32(cpu_NF
, hi
);
7372 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7375 /* Load/Store exclusive instructions are implemented by remembering
7376 the value/address loaded, and seeing if these are the same
7377 when the store is performed. This should be sufficient to implement
7378 the architecturally mandated semantics, and avoids having to monitor
7381 In system emulation mode only one CPU will be running at once, so
7382 this sequence is effectively atomic. In user emulation mode we
7383 throw an exception and handle the atomic operation elsewhere. */
7384 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7385 TCGv_i32 addr
, int size
)
7387 TCGv_i32 tmp
= tcg_temp_new_i32();
7393 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7396 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7400 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7407 TCGv_i32 tmp2
= tcg_temp_new_i32();
7408 TCGv_i32 tmp3
= tcg_temp_new_i32();
7410 tcg_gen_addi_i32(tmp2
, addr
, 4);
7411 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7412 tcg_temp_free_i32(tmp2
);
7413 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7414 store_reg(s
, rt2
, tmp3
);
7416 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7419 store_reg(s
, rt
, tmp
);
7420 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7423 static void gen_clrex(DisasContext
*s
)
7425 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7428 #ifdef CONFIG_USER_ONLY
7429 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7430 TCGv_i32 addr
, int size
)
7432 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7433 tcg_gen_movi_i32(cpu_exclusive_info
,
7434 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7435 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7438 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7439 TCGv_i32 addr
, int size
)
7442 TCGv_i64 val64
, extaddr
;
7446 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7452 fail_label
= gen_new_label();
7453 done_label
= gen_new_label();
7454 extaddr
= tcg_temp_new_i64();
7455 tcg_gen_extu_i32_i64(extaddr
, addr
);
7456 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7457 tcg_temp_free_i64(extaddr
);
7459 tmp
= tcg_temp_new_i32();
7462 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7465 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7469 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7475 val64
= tcg_temp_new_i64();
7477 TCGv_i32 tmp2
= tcg_temp_new_i32();
7478 TCGv_i32 tmp3
= tcg_temp_new_i32();
7479 tcg_gen_addi_i32(tmp2
, addr
, 4);
7480 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7481 tcg_temp_free_i32(tmp2
);
7482 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7483 tcg_temp_free_i32(tmp3
);
7485 tcg_gen_extu_i32_i64(val64
, tmp
);
7487 tcg_temp_free_i32(tmp
);
7489 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7490 tcg_temp_free_i64(val64
);
7492 tmp
= load_reg(s
, rt
);
7495 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7498 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7502 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7507 tcg_temp_free_i32(tmp
);
7509 tcg_gen_addi_i32(addr
, addr
, 4);
7510 tmp
= load_reg(s
, rt2
);
7511 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7512 tcg_temp_free_i32(tmp
);
7514 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7515 tcg_gen_br(done_label
);
7516 gen_set_label(fail_label
);
7517 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7518 gen_set_label(done_label
);
7519 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7526 * @mode: mode field from insn (which stack to store to)
7527 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7528 * @writeback: true if writeback bit set
7530 * Generate code for the SRS (Store Return State) insn.
7532 static void gen_srs(DisasContext
*s
,
7533 uint32_t mode
, uint32_t amode
, bool writeback
)
7536 TCGv_i32 addr
= tcg_temp_new_i32();
7537 TCGv_i32 tmp
= tcg_const_i32(mode
);
7538 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7539 tcg_temp_free_i32(tmp
);
7556 tcg_gen_addi_i32(addr
, addr
, offset
);
7557 tmp
= load_reg(s
, 14);
7558 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7559 tcg_temp_free_i32(tmp
);
7560 tmp
= load_cpu_field(spsr
);
7561 tcg_gen_addi_i32(addr
, addr
, 4);
7562 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7563 tcg_temp_free_i32(tmp
);
7581 tcg_gen_addi_i32(addr
, addr
, offset
);
7582 tmp
= tcg_const_i32(mode
);
7583 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7584 tcg_temp_free_i32(tmp
);
7586 tcg_temp_free_i32(addr
);
7589 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7591 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7598 /* M variants do not implement ARM mode. */
7599 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7604 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7605 * choose to UNDEF. In ARMv5 and above the space is used
7606 * for miscellaneous unconditional instructions.
7610 /* Unconditional instructions. */
7611 if (((insn
>> 25) & 7) == 1) {
7612 /* NEON Data processing. */
7613 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7617 if (disas_neon_data_insn(s
, insn
)) {
7622 if ((insn
& 0x0f100000) == 0x04000000) {
7623 /* NEON load/store. */
7624 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7628 if (disas_neon_ls_insn(s
, insn
)) {
7633 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7635 if (disas_vfp_insn(s
, insn
)) {
7640 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7641 ((insn
& 0x0f30f010) == 0x0710f000)) {
7642 if ((insn
& (1 << 22)) == 0) {
7644 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7648 /* Otherwise PLD; v5TE+ */
7652 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7653 ((insn
& 0x0f70f010) == 0x0650f000)) {
7655 return; /* PLI; V7 */
7657 if (((insn
& 0x0f700000) == 0x04100000) ||
7658 ((insn
& 0x0f700010) == 0x06100000)) {
7659 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7662 return; /* v7MP: Unallocated memory hint: must NOP */
7665 if ((insn
& 0x0ffffdff) == 0x01010000) {
7668 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7669 /* Dynamic endianness switching not implemented. */
7670 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7674 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7675 switch ((insn
>> 4) & 0xf) {
7684 /* We don't emulate caches so these are a no-op. */
7689 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7695 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7697 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7703 rn
= (insn
>> 16) & 0xf;
7704 addr
= load_reg(s
, rn
);
7705 i
= (insn
>> 23) & 3;
7707 case 0: offset
= -4; break; /* DA */
7708 case 1: offset
= 0; break; /* IA */
7709 case 2: offset
= -8; break; /* DB */
7710 case 3: offset
= 4; break; /* IB */
7714 tcg_gen_addi_i32(addr
, addr
, offset
);
7715 /* Load PC into tmp and CPSR into tmp2. */
7716 tmp
= tcg_temp_new_i32();
7717 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7718 tcg_gen_addi_i32(addr
, addr
, 4);
7719 tmp2
= tcg_temp_new_i32();
7720 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7721 if (insn
& (1 << 21)) {
7722 /* Base writeback. */
7724 case 0: offset
= -8; break;
7725 case 1: offset
= 4; break;
7726 case 2: offset
= -4; break;
7727 case 3: offset
= 0; break;
7731 tcg_gen_addi_i32(addr
, addr
, offset
);
7732 store_reg(s
, rn
, addr
);
7734 tcg_temp_free_i32(addr
);
7736 gen_rfe(s
, tmp
, tmp2
);
7738 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7739 /* branch link and change to thumb (blx <offset>) */
7742 val
= (uint32_t)s
->pc
;
7743 tmp
= tcg_temp_new_i32();
7744 tcg_gen_movi_i32(tmp
, val
);
7745 store_reg(s
, 14, tmp
);
7746 /* Sign-extend the 24-bit offset */
7747 offset
= (((int32_t)insn
) << 8) >> 8;
7748 /* offset * 4 + bit24 * 2 + (thumb bit) */
7749 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7750 /* pipeline offset */
7752 /* protected by ARCH(5); above, near the start of uncond block */
7755 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7756 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7757 /* iWMMXt register transfer. */
7758 if (extract32(s
->c15_cpar
, 1, 1)) {
7759 if (!disas_iwmmxt_insn(s
, insn
)) {
7764 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7765 /* Coprocessor double register transfer. */
7767 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7768 /* Additional coprocessor register transfer. */
7769 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7772 /* cps (privileged) */
7776 if (insn
& (1 << 19)) {
7777 if (insn
& (1 << 8))
7779 if (insn
& (1 << 7))
7781 if (insn
& (1 << 6))
7783 if (insn
& (1 << 18))
7786 if (insn
& (1 << 17)) {
7788 val
|= (insn
& 0x1f);
7791 gen_set_psr_im(s
, mask
, 0, val
);
7798 /* if not always execute, we generate a conditional jump to
7800 s
->condlabel
= gen_new_label();
7801 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7804 if ((insn
& 0x0f900000) == 0x03000000) {
7805 if ((insn
& (1 << 21)) == 0) {
7807 rd
= (insn
>> 12) & 0xf;
7808 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7809 if ((insn
& (1 << 22)) == 0) {
7811 tmp
= tcg_temp_new_i32();
7812 tcg_gen_movi_i32(tmp
, val
);
7815 tmp
= load_reg(s
, rd
);
7816 tcg_gen_ext16u_i32(tmp
, tmp
);
7817 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7819 store_reg(s
, rd
, tmp
);
7821 if (((insn
>> 12) & 0xf) != 0xf)
7823 if (((insn
>> 16) & 0xf) == 0) {
7824 gen_nop_hint(s
, insn
& 0xff);
7826 /* CPSR = immediate */
7828 shift
= ((insn
>> 8) & 0xf) * 2;
7830 val
= (val
>> shift
) | (val
<< (32 - shift
));
7831 i
= ((insn
& (1 << 22)) != 0);
7832 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
7838 } else if ((insn
& 0x0f900000) == 0x01000000
7839 && (insn
& 0x00000090) != 0x00000090) {
7840 /* miscellaneous instructions */
7841 op1
= (insn
>> 21) & 3;
7842 sh
= (insn
>> 4) & 0xf;
7845 case 0x0: /* move program status register */
7848 tmp
= load_reg(s
, rm
);
7849 i
= ((op1
& 2) != 0);
7850 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7854 rd
= (insn
>> 12) & 0xf;
7858 tmp
= load_cpu_field(spsr
);
7860 tmp
= tcg_temp_new_i32();
7861 gen_helper_cpsr_read(tmp
, cpu_env
);
7863 store_reg(s
, rd
, tmp
);
7868 /* branch/exchange thumb (bx). */
7870 tmp
= load_reg(s
, rm
);
7872 } else if (op1
== 3) {
7875 rd
= (insn
>> 12) & 0xf;
7876 tmp
= load_reg(s
, rm
);
7877 gen_helper_clz(tmp
, tmp
);
7878 store_reg(s
, rd
, tmp
);
7886 /* Trivial implementation equivalent to bx. */
7887 tmp
= load_reg(s
, rm
);
7898 /* branch link/exchange thumb (blx) */
7899 tmp
= load_reg(s
, rm
);
7900 tmp2
= tcg_temp_new_i32();
7901 tcg_gen_movi_i32(tmp2
, s
->pc
);
7902 store_reg(s
, 14, tmp2
);
7908 uint32_t c
= extract32(insn
, 8, 4);
7910 /* Check this CPU supports ARMv8 CRC instructions.
7911 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7912 * Bits 8, 10 and 11 should be zero.
7914 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7919 rn
= extract32(insn
, 16, 4);
7920 rd
= extract32(insn
, 12, 4);
7922 tmp
= load_reg(s
, rn
);
7923 tmp2
= load_reg(s
, rm
);
7925 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7926 } else if (op1
== 1) {
7927 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7929 tmp3
= tcg_const_i32(1 << op1
);
7931 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7933 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7935 tcg_temp_free_i32(tmp2
);
7936 tcg_temp_free_i32(tmp3
);
7937 store_reg(s
, rd
, tmp
);
7940 case 0x5: /* saturating add/subtract */
7942 rd
= (insn
>> 12) & 0xf;
7943 rn
= (insn
>> 16) & 0xf;
7944 tmp
= load_reg(s
, rm
);
7945 tmp2
= load_reg(s
, rn
);
7947 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7949 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7951 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7952 tcg_temp_free_i32(tmp2
);
7953 store_reg(s
, rd
, tmp
);
7957 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
7962 gen_exception_insn(s
, 4, EXCP_BKPT
,
7963 syn_aa32_bkpt(imm16
, false));
7966 /* Hypervisor call (v7) */
7974 /* Secure monitor call (v6+) */
7986 case 0x8: /* signed multiply */
7991 rs
= (insn
>> 8) & 0xf;
7992 rn
= (insn
>> 12) & 0xf;
7993 rd
= (insn
>> 16) & 0xf;
7995 /* (32 * 16) >> 16 */
7996 tmp
= load_reg(s
, rm
);
7997 tmp2
= load_reg(s
, rs
);
7999 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8002 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8003 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8004 tmp
= tcg_temp_new_i32();
8005 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8006 tcg_temp_free_i64(tmp64
);
8007 if ((sh
& 2) == 0) {
8008 tmp2
= load_reg(s
, rn
);
8009 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8010 tcg_temp_free_i32(tmp2
);
8012 store_reg(s
, rd
, tmp
);
8015 tmp
= load_reg(s
, rm
);
8016 tmp2
= load_reg(s
, rs
);
8017 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8018 tcg_temp_free_i32(tmp2
);
8020 tmp64
= tcg_temp_new_i64();
8021 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8022 tcg_temp_free_i32(tmp
);
8023 gen_addq(s
, tmp64
, rn
, rd
);
8024 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8025 tcg_temp_free_i64(tmp64
);
8028 tmp2
= load_reg(s
, rn
);
8029 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8030 tcg_temp_free_i32(tmp2
);
8032 store_reg(s
, rd
, tmp
);
8039 } else if (((insn
& 0x0e000000) == 0 &&
8040 (insn
& 0x00000090) != 0x90) ||
8041 ((insn
& 0x0e000000) == (1 << 25))) {
8042 int set_cc
, logic_cc
, shiftop
;
8044 op1
= (insn
>> 21) & 0xf;
8045 set_cc
= (insn
>> 20) & 1;
8046 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8048 /* data processing instruction */
8049 if (insn
& (1 << 25)) {
8050 /* immediate operand */
8052 shift
= ((insn
>> 8) & 0xf) * 2;
8054 val
= (val
>> shift
) | (val
<< (32 - shift
));
8056 tmp2
= tcg_temp_new_i32();
8057 tcg_gen_movi_i32(tmp2
, val
);
8058 if (logic_cc
&& shift
) {
8059 gen_set_CF_bit31(tmp2
);
8064 tmp2
= load_reg(s
, rm
);
8065 shiftop
= (insn
>> 5) & 3;
8066 if (!(insn
& (1 << 4))) {
8067 shift
= (insn
>> 7) & 0x1f;
8068 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8070 rs
= (insn
>> 8) & 0xf;
8071 tmp
= load_reg(s
, rs
);
8072 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8075 if (op1
!= 0x0f && op1
!= 0x0d) {
8076 rn
= (insn
>> 16) & 0xf;
8077 tmp
= load_reg(s
, rn
);
8079 TCGV_UNUSED_I32(tmp
);
8081 rd
= (insn
>> 12) & 0xf;
8084 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8088 store_reg_bx(s
, rd
, tmp
);
8091 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8095 store_reg_bx(s
, rd
, tmp
);
8098 if (set_cc
&& rd
== 15) {
8099 /* SUBS r15, ... is used for exception return. */
8103 gen_sub_CC(tmp
, tmp
, tmp2
);
8104 gen_exception_return(s
, tmp
);
8107 gen_sub_CC(tmp
, tmp
, tmp2
);
8109 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8111 store_reg_bx(s
, rd
, tmp
);
8116 gen_sub_CC(tmp
, tmp2
, tmp
);
8118 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8120 store_reg_bx(s
, rd
, tmp
);
8124 gen_add_CC(tmp
, tmp
, tmp2
);
8126 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8128 store_reg_bx(s
, rd
, tmp
);
8132 gen_adc_CC(tmp
, tmp
, tmp2
);
8134 gen_add_carry(tmp
, tmp
, tmp2
);
8136 store_reg_bx(s
, rd
, tmp
);
8140 gen_sbc_CC(tmp
, tmp
, tmp2
);
8142 gen_sub_carry(tmp
, tmp
, tmp2
);
8144 store_reg_bx(s
, rd
, tmp
);
8148 gen_sbc_CC(tmp
, tmp2
, tmp
);
8150 gen_sub_carry(tmp
, tmp2
, tmp
);
8152 store_reg_bx(s
, rd
, tmp
);
8156 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8159 tcg_temp_free_i32(tmp
);
8163 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8166 tcg_temp_free_i32(tmp
);
8170 gen_sub_CC(tmp
, tmp
, tmp2
);
8172 tcg_temp_free_i32(tmp
);
8176 gen_add_CC(tmp
, tmp
, tmp2
);
8178 tcg_temp_free_i32(tmp
);
8181 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8185 store_reg_bx(s
, rd
, tmp
);
8188 if (logic_cc
&& rd
== 15) {
8189 /* MOVS r15, ... is used for exception return. */
8193 gen_exception_return(s
, tmp2
);
8198 store_reg_bx(s
, rd
, tmp2
);
8202 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8206 store_reg_bx(s
, rd
, tmp
);
8210 tcg_gen_not_i32(tmp2
, tmp2
);
8214 store_reg_bx(s
, rd
, tmp2
);
8217 if (op1
!= 0x0f && op1
!= 0x0d) {
8218 tcg_temp_free_i32(tmp2
);
8221 /* other instructions */
8222 op1
= (insn
>> 24) & 0xf;
8226 /* multiplies, extra load/stores */
8227 sh
= (insn
>> 5) & 3;
8230 rd
= (insn
>> 16) & 0xf;
8231 rn
= (insn
>> 12) & 0xf;
8232 rs
= (insn
>> 8) & 0xf;
8234 op1
= (insn
>> 20) & 0xf;
8236 case 0: case 1: case 2: case 3: case 6:
8238 tmp
= load_reg(s
, rs
);
8239 tmp2
= load_reg(s
, rm
);
8240 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8241 tcg_temp_free_i32(tmp2
);
8242 if (insn
& (1 << 22)) {
8243 /* Subtract (mls) */
8245 tmp2
= load_reg(s
, rn
);
8246 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8247 tcg_temp_free_i32(tmp2
);
8248 } else if (insn
& (1 << 21)) {
8250 tmp2
= load_reg(s
, rn
);
8251 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8252 tcg_temp_free_i32(tmp2
);
8254 if (insn
& (1 << 20))
8256 store_reg(s
, rd
, tmp
);
8259 /* 64 bit mul double accumulate (UMAAL) */
8261 tmp
= load_reg(s
, rs
);
8262 tmp2
= load_reg(s
, rm
);
8263 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8264 gen_addq_lo(s
, tmp64
, rn
);
8265 gen_addq_lo(s
, tmp64
, rd
);
8266 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8267 tcg_temp_free_i64(tmp64
);
8269 case 8: case 9: case 10: case 11:
8270 case 12: case 13: case 14: case 15:
8271 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8272 tmp
= load_reg(s
, rs
);
8273 tmp2
= load_reg(s
, rm
);
8274 if (insn
& (1 << 22)) {
8275 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8277 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8279 if (insn
& (1 << 21)) { /* mult accumulate */
8280 TCGv_i32 al
= load_reg(s
, rn
);
8281 TCGv_i32 ah
= load_reg(s
, rd
);
8282 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8283 tcg_temp_free_i32(al
);
8284 tcg_temp_free_i32(ah
);
8286 if (insn
& (1 << 20)) {
8287 gen_logicq_cc(tmp
, tmp2
);
8289 store_reg(s
, rn
, tmp
);
8290 store_reg(s
, rd
, tmp2
);
8296 rn
= (insn
>> 16) & 0xf;
8297 rd
= (insn
>> 12) & 0xf;
8298 if (insn
& (1 << 23)) {
8299 /* load/store exclusive */
8300 int op2
= (insn
>> 8) & 3;
8301 op1
= (insn
>> 21) & 0x3;
8304 case 0: /* lda/stl */
8310 case 1: /* reserved */
8312 case 2: /* ldaex/stlex */
8315 case 3: /* ldrex/strex */
8324 addr
= tcg_temp_local_new_i32();
8325 load_reg_var(s
, addr
, rn
);
8327 /* Since the emulation does not have barriers,
8328 the acquire/release semantics need no special
8331 if (insn
& (1 << 20)) {
8332 tmp
= tcg_temp_new_i32();
8335 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8338 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8341 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8346 store_reg(s
, rd
, tmp
);
8349 tmp
= load_reg(s
, rm
);
8352 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8355 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8358 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8363 tcg_temp_free_i32(tmp
);
8365 } else if (insn
& (1 << 20)) {
8368 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8370 case 1: /* ldrexd */
8371 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8373 case 2: /* ldrexb */
8374 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8376 case 3: /* ldrexh */
8377 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8386 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8388 case 1: /* strexd */
8389 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8391 case 2: /* strexb */
8392 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8394 case 3: /* strexh */
8395 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8401 tcg_temp_free_i32(addr
);
8403 /* SWP instruction */
8406 /* ??? This is not really atomic. However we know
8407 we never have multiple CPUs running in parallel,
8408 so it is good enough. */
8409 addr
= load_reg(s
, rn
);
8410 tmp
= load_reg(s
, rm
);
8411 tmp2
= tcg_temp_new_i32();
8412 if (insn
& (1 << 22)) {
8413 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8414 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8416 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8417 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8419 tcg_temp_free_i32(tmp
);
8420 tcg_temp_free_i32(addr
);
8421 store_reg(s
, rd
, tmp2
);
8427 /* Misc load/store */
8428 rn
= (insn
>> 16) & 0xf;
8429 rd
= (insn
>> 12) & 0xf;
8430 addr
= load_reg(s
, rn
);
8431 if (insn
& (1 << 24))
8432 gen_add_datah_offset(s
, insn
, 0, addr
);
8434 if (insn
& (1 << 20)) {
8436 tmp
= tcg_temp_new_i32();
8439 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8442 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8446 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8450 } else if (sh
& 2) {
8455 tmp
= load_reg(s
, rd
);
8456 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8457 tcg_temp_free_i32(tmp
);
8458 tcg_gen_addi_i32(addr
, addr
, 4);
8459 tmp
= load_reg(s
, rd
+ 1);
8460 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8461 tcg_temp_free_i32(tmp
);
8465 tmp
= tcg_temp_new_i32();
8466 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8467 store_reg(s
, rd
, tmp
);
8468 tcg_gen_addi_i32(addr
, addr
, 4);
8469 tmp
= tcg_temp_new_i32();
8470 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8474 address_offset
= -4;
8477 tmp
= load_reg(s
, rd
);
8478 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8479 tcg_temp_free_i32(tmp
);
8482 /* Perform base writeback before the loaded value to
8483 ensure correct behavior with overlapping index registers.
8484 ldrd with base writeback is is undefined if the
8485 destination and index registers overlap. */
8486 if (!(insn
& (1 << 24))) {
8487 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8488 store_reg(s
, rn
, addr
);
8489 } else if (insn
& (1 << 21)) {
8491 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8492 store_reg(s
, rn
, addr
);
8494 tcg_temp_free_i32(addr
);
8497 /* Complete the load. */
8498 store_reg(s
, rd
, tmp
);
8507 if (insn
& (1 << 4)) {
8509 /* Armv6 Media instructions. */
8511 rn
= (insn
>> 16) & 0xf;
8512 rd
= (insn
>> 12) & 0xf;
8513 rs
= (insn
>> 8) & 0xf;
8514 switch ((insn
>> 23) & 3) {
8515 case 0: /* Parallel add/subtract. */
8516 op1
= (insn
>> 20) & 7;
8517 tmp
= load_reg(s
, rn
);
8518 tmp2
= load_reg(s
, rm
);
8519 sh
= (insn
>> 5) & 7;
8520 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8522 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8523 tcg_temp_free_i32(tmp2
);
8524 store_reg(s
, rd
, tmp
);
8527 if ((insn
& 0x00700020) == 0) {
8528 /* Halfword pack. */
8529 tmp
= load_reg(s
, rn
);
8530 tmp2
= load_reg(s
, rm
);
8531 shift
= (insn
>> 7) & 0x1f;
8532 if (insn
& (1 << 6)) {
8536 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8537 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8538 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8542 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8543 tcg_gen_ext16u_i32(tmp
, tmp
);
8544 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8546 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8547 tcg_temp_free_i32(tmp2
);
8548 store_reg(s
, rd
, tmp
);
8549 } else if ((insn
& 0x00200020) == 0x00200000) {
8551 tmp
= load_reg(s
, rm
);
8552 shift
= (insn
>> 7) & 0x1f;
8553 if (insn
& (1 << 6)) {
8556 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8558 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8560 sh
= (insn
>> 16) & 0x1f;
8561 tmp2
= tcg_const_i32(sh
);
8562 if (insn
& (1 << 22))
8563 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8565 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8566 tcg_temp_free_i32(tmp2
);
8567 store_reg(s
, rd
, tmp
);
8568 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8570 tmp
= load_reg(s
, rm
);
8571 sh
= (insn
>> 16) & 0x1f;
8572 tmp2
= tcg_const_i32(sh
);
8573 if (insn
& (1 << 22))
8574 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8576 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8577 tcg_temp_free_i32(tmp2
);
8578 store_reg(s
, rd
, tmp
);
8579 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8581 tmp
= load_reg(s
, rn
);
8582 tmp2
= load_reg(s
, rm
);
8583 tmp3
= tcg_temp_new_i32();
8584 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8585 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8586 tcg_temp_free_i32(tmp3
);
8587 tcg_temp_free_i32(tmp2
);
8588 store_reg(s
, rd
, tmp
);
8589 } else if ((insn
& 0x000003e0) == 0x00000060) {
8590 tmp
= load_reg(s
, rm
);
8591 shift
= (insn
>> 10) & 3;
8592 /* ??? In many cases it's not necessary to do a
8593 rotate, a shift is sufficient. */
8595 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8596 op1
= (insn
>> 20) & 7;
8598 case 0: gen_sxtb16(tmp
); break;
8599 case 2: gen_sxtb(tmp
); break;
8600 case 3: gen_sxth(tmp
); break;
8601 case 4: gen_uxtb16(tmp
); break;
8602 case 6: gen_uxtb(tmp
); break;
8603 case 7: gen_uxth(tmp
); break;
8604 default: goto illegal_op
;
8607 tmp2
= load_reg(s
, rn
);
8608 if ((op1
& 3) == 0) {
8609 gen_add16(tmp
, tmp2
);
8611 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8612 tcg_temp_free_i32(tmp2
);
8615 store_reg(s
, rd
, tmp
);
8616 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8618 tmp
= load_reg(s
, rm
);
8619 if (insn
& (1 << 22)) {
8620 if (insn
& (1 << 7)) {
8624 gen_helper_rbit(tmp
, tmp
);
8627 if (insn
& (1 << 7))
8630 tcg_gen_bswap32_i32(tmp
, tmp
);
8632 store_reg(s
, rd
, tmp
);
8637 case 2: /* Multiplies (Type 3). */
8638 switch ((insn
>> 20) & 0x7) {
8640 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8641 /* op2 not 00x or 11x : UNDEF */
8644 /* Signed multiply most significant [accumulate].
8645 (SMMUL, SMMLA, SMMLS) */
8646 tmp
= load_reg(s
, rm
);
8647 tmp2
= load_reg(s
, rs
);
8648 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8651 tmp
= load_reg(s
, rd
);
8652 if (insn
& (1 << 6)) {
8653 tmp64
= gen_subq_msw(tmp64
, tmp
);
8655 tmp64
= gen_addq_msw(tmp64
, tmp
);
8658 if (insn
& (1 << 5)) {
8659 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8661 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8662 tmp
= tcg_temp_new_i32();
8663 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8664 tcg_temp_free_i64(tmp64
);
8665 store_reg(s
, rn
, tmp
);
8669 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8670 if (insn
& (1 << 7)) {
8673 tmp
= load_reg(s
, rm
);
8674 tmp2
= load_reg(s
, rs
);
8675 if (insn
& (1 << 5))
8676 gen_swap_half(tmp2
);
8677 gen_smul_dual(tmp
, tmp2
);
8678 if (insn
& (1 << 22)) {
8679 /* smlald, smlsld */
8682 tmp64
= tcg_temp_new_i64();
8683 tmp64_2
= tcg_temp_new_i64();
8684 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8685 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8686 tcg_temp_free_i32(tmp
);
8687 tcg_temp_free_i32(tmp2
);
8688 if (insn
& (1 << 6)) {
8689 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8691 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8693 tcg_temp_free_i64(tmp64_2
);
8694 gen_addq(s
, tmp64
, rd
, rn
);
8695 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8696 tcg_temp_free_i64(tmp64
);
8698 /* smuad, smusd, smlad, smlsd */
8699 if (insn
& (1 << 6)) {
8700 /* This subtraction cannot overflow. */
8701 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8703 /* This addition cannot overflow 32 bits;
8704 * however it may overflow considered as a
8705 * signed operation, in which case we must set
8708 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8710 tcg_temp_free_i32(tmp2
);
8713 tmp2
= load_reg(s
, rd
);
8714 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8715 tcg_temp_free_i32(tmp2
);
8717 store_reg(s
, rn
, tmp
);
8723 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
8726 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8729 tmp
= load_reg(s
, rm
);
8730 tmp2
= load_reg(s
, rs
);
8731 if (insn
& (1 << 21)) {
8732 gen_helper_udiv(tmp
, tmp
, tmp2
);
8734 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8736 tcg_temp_free_i32(tmp2
);
8737 store_reg(s
, rn
, tmp
);
8744 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8746 case 0: /* Unsigned sum of absolute differences. */
8748 tmp
= load_reg(s
, rm
);
8749 tmp2
= load_reg(s
, rs
);
8750 gen_helper_usad8(tmp
, tmp
, tmp2
);
8751 tcg_temp_free_i32(tmp2
);
8753 tmp2
= load_reg(s
, rd
);
8754 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8755 tcg_temp_free_i32(tmp2
);
8757 store_reg(s
, rn
, tmp
);
8759 case 0x20: case 0x24: case 0x28: case 0x2c:
8760 /* Bitfield insert/clear. */
8762 shift
= (insn
>> 7) & 0x1f;
8763 i
= (insn
>> 16) & 0x1f;
8765 /* UNPREDICTABLE; we choose to UNDEF */
8770 tmp
= tcg_temp_new_i32();
8771 tcg_gen_movi_i32(tmp
, 0);
8773 tmp
= load_reg(s
, rm
);
8776 tmp2
= load_reg(s
, rd
);
8777 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8778 tcg_temp_free_i32(tmp2
);
8780 store_reg(s
, rd
, tmp
);
8782 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8783 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8785 tmp
= load_reg(s
, rm
);
8786 shift
= (insn
>> 7) & 0x1f;
8787 i
= ((insn
>> 16) & 0x1f) + 1;
8792 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8794 gen_sbfx(tmp
, shift
, i
);
8797 store_reg(s
, rd
, tmp
);
8807 /* Check for undefined extension instructions
8808 * per the ARM Bible IE:
8809 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8811 sh
= (0xf << 20) | (0xf << 4);
8812 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8816 /* load/store byte/word */
8817 rn
= (insn
>> 16) & 0xf;
8818 rd
= (insn
>> 12) & 0xf;
8819 tmp2
= load_reg(s
, rn
);
8820 if ((insn
& 0x01200000) == 0x00200000) {
8822 i
= get_a32_user_mem_index(s
);
8824 i
= get_mem_index(s
);
8826 if (insn
& (1 << 24))
8827 gen_add_data_offset(s
, insn
, tmp2
);
8828 if (insn
& (1 << 20)) {
8830 tmp
= tcg_temp_new_i32();
8831 if (insn
& (1 << 22)) {
8832 gen_aa32_ld8u(tmp
, tmp2
, i
);
8834 gen_aa32_ld32u(tmp
, tmp2
, i
);
8838 tmp
= load_reg(s
, rd
);
8839 if (insn
& (1 << 22)) {
8840 gen_aa32_st8(tmp
, tmp2
, i
);
8842 gen_aa32_st32(tmp
, tmp2
, i
);
8844 tcg_temp_free_i32(tmp
);
8846 if (!(insn
& (1 << 24))) {
8847 gen_add_data_offset(s
, insn
, tmp2
);
8848 store_reg(s
, rn
, tmp2
);
8849 } else if (insn
& (1 << 21)) {
8850 store_reg(s
, rn
, tmp2
);
8852 tcg_temp_free_i32(tmp2
);
8854 if (insn
& (1 << 20)) {
8855 /* Complete the load. */
8856 store_reg_from_load(s
, rd
, tmp
);
8862 int j
, n
, user
, loaded_base
;
8863 TCGv_i32 loaded_var
;
8864 /* load/store multiple words */
8865 /* XXX: store correct base if write back */
8867 if (insn
& (1 << 22)) {
8869 goto illegal_op
; /* only usable in supervisor mode */
8871 if ((insn
& (1 << 15)) == 0)
8874 rn
= (insn
>> 16) & 0xf;
8875 addr
= load_reg(s
, rn
);
8877 /* compute total size */
8879 TCGV_UNUSED_I32(loaded_var
);
8882 if (insn
& (1 << i
))
8885 /* XXX: test invalid n == 0 case ? */
8886 if (insn
& (1 << 23)) {
8887 if (insn
& (1 << 24)) {
8889 tcg_gen_addi_i32(addr
, addr
, 4);
8891 /* post increment */
8894 if (insn
& (1 << 24)) {
8896 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8898 /* post decrement */
8900 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8905 if (insn
& (1 << i
)) {
8906 if (insn
& (1 << 20)) {
8908 tmp
= tcg_temp_new_i32();
8909 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8911 tmp2
= tcg_const_i32(i
);
8912 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8913 tcg_temp_free_i32(tmp2
);
8914 tcg_temp_free_i32(tmp
);
8915 } else if (i
== rn
) {
8919 store_reg_from_load(s
, i
, tmp
);
8924 /* special case: r15 = PC + 8 */
8925 val
= (long)s
->pc
+ 4;
8926 tmp
= tcg_temp_new_i32();
8927 tcg_gen_movi_i32(tmp
, val
);
8929 tmp
= tcg_temp_new_i32();
8930 tmp2
= tcg_const_i32(i
);
8931 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8932 tcg_temp_free_i32(tmp2
);
8934 tmp
= load_reg(s
, i
);
8936 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8937 tcg_temp_free_i32(tmp
);
8940 /* no need to add after the last transfer */
8942 tcg_gen_addi_i32(addr
, addr
, 4);
8945 if (insn
& (1 << 21)) {
8947 if (insn
& (1 << 23)) {
8948 if (insn
& (1 << 24)) {
8951 /* post increment */
8952 tcg_gen_addi_i32(addr
, addr
, 4);
8955 if (insn
& (1 << 24)) {
8958 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8960 /* post decrement */
8961 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8964 store_reg(s
, rn
, addr
);
8966 tcg_temp_free_i32(addr
);
8969 store_reg(s
, rn
, loaded_var
);
8971 if ((insn
& (1 << 22)) && !user
) {
8972 /* Restore CPSR from SPSR. */
8973 tmp
= load_cpu_field(spsr
);
8974 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
8975 tcg_temp_free_i32(tmp
);
8976 s
->is_jmp
= DISAS_UPDATE
;
8985 /* branch (and link) */
8986 val
= (int32_t)s
->pc
;
8987 if (insn
& (1 << 24)) {
8988 tmp
= tcg_temp_new_i32();
8989 tcg_gen_movi_i32(tmp
, val
);
8990 store_reg(s
, 14, tmp
);
8992 offset
= sextract32(insn
<< 2, 0, 26);
9000 if (((insn
>> 8) & 0xe) == 10) {
9002 if (disas_vfp_insn(s
, insn
)) {
9005 } else if (disas_coproc_insn(s
, insn
)) {
9012 gen_set_pc_im(s
, s
->pc
);
9013 s
->svc_imm
= extract32(insn
, 0, 24);
9014 s
->is_jmp
= DISAS_SWI
;
9018 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
9024 /* Return true if this is a Thumb-2 logical op. */
9026 thumb2_logic_op(int op
)
9031 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9032 then set condition code flags based on the result of the operation.
9033 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9034 to the high bit of T1.
9035 Returns zero if the opcode is valid. */
9038 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9039 TCGv_i32 t0
, TCGv_i32 t1
)
9046 tcg_gen_and_i32(t0
, t0
, t1
);
9050 tcg_gen_andc_i32(t0
, t0
, t1
);
9054 tcg_gen_or_i32(t0
, t0
, t1
);
9058 tcg_gen_orc_i32(t0
, t0
, t1
);
9062 tcg_gen_xor_i32(t0
, t0
, t1
);
9067 gen_add_CC(t0
, t0
, t1
);
9069 tcg_gen_add_i32(t0
, t0
, t1
);
9073 gen_adc_CC(t0
, t0
, t1
);
9079 gen_sbc_CC(t0
, t0
, t1
);
9081 gen_sub_carry(t0
, t0
, t1
);
9086 gen_sub_CC(t0
, t0
, t1
);
9088 tcg_gen_sub_i32(t0
, t0
, t1
);
9092 gen_sub_CC(t0
, t1
, t0
);
9094 tcg_gen_sub_i32(t0
, t1
, t0
);
9096 default: /* 5, 6, 7, 9, 12, 15. */
9102 gen_set_CF_bit31(t1
);
9107 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9109 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9111 uint32_t insn
, imm
, shift
, offset
;
9112 uint32_t rd
, rn
, rm
, rs
;
9123 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9124 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9125 /* Thumb-1 cores may need to treat bl and blx as a pair of
9126 16-bit instructions to get correct prefetch abort behavior. */
9128 if ((insn
& (1 << 12)) == 0) {
9130 /* Second half of blx. */
9131 offset
= ((insn
& 0x7ff) << 1);
9132 tmp
= load_reg(s
, 14);
9133 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9134 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9136 tmp2
= tcg_temp_new_i32();
9137 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9138 store_reg(s
, 14, tmp2
);
9142 if (insn
& (1 << 11)) {
9143 /* Second half of bl. */
9144 offset
= ((insn
& 0x7ff) << 1) | 1;
9145 tmp
= load_reg(s
, 14);
9146 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9148 tmp2
= tcg_temp_new_i32();
9149 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9150 store_reg(s
, 14, tmp2
);
9154 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9155 /* Instruction spans a page boundary. Implement it as two
9156 16-bit instructions in case the second half causes an
9158 offset
= ((int32_t)insn
<< 21) >> 9;
9159 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9162 /* Fall through to 32-bit decode. */
9165 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9167 insn
|= (uint32_t)insn_hw1
<< 16;
9169 if ((insn
& 0xf800e800) != 0xf000e800) {
9173 rn
= (insn
>> 16) & 0xf;
9174 rs
= (insn
>> 12) & 0xf;
9175 rd
= (insn
>> 8) & 0xf;
9177 switch ((insn
>> 25) & 0xf) {
9178 case 0: case 1: case 2: case 3:
9179 /* 16-bit instructions. Should never happen. */
9182 if (insn
& (1 << 22)) {
9183 /* Other load/store, table branch. */
9184 if (insn
& 0x01200000) {
9185 /* Load/store doubleword. */
9187 addr
= tcg_temp_new_i32();
9188 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9190 addr
= load_reg(s
, rn
);
9192 offset
= (insn
& 0xff) * 4;
9193 if ((insn
& (1 << 23)) == 0)
9195 if (insn
& (1 << 24)) {
9196 tcg_gen_addi_i32(addr
, addr
, offset
);
9199 if (insn
& (1 << 20)) {
9201 tmp
= tcg_temp_new_i32();
9202 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9203 store_reg(s
, rs
, tmp
);
9204 tcg_gen_addi_i32(addr
, addr
, 4);
9205 tmp
= tcg_temp_new_i32();
9206 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9207 store_reg(s
, rd
, tmp
);
9210 tmp
= load_reg(s
, rs
);
9211 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9212 tcg_temp_free_i32(tmp
);
9213 tcg_gen_addi_i32(addr
, addr
, 4);
9214 tmp
= load_reg(s
, rd
);
9215 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9216 tcg_temp_free_i32(tmp
);
9218 if (insn
& (1 << 21)) {
9219 /* Base writeback. */
9222 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9223 store_reg(s
, rn
, addr
);
9225 tcg_temp_free_i32(addr
);
9227 } else if ((insn
& (1 << 23)) == 0) {
9228 /* Load/store exclusive word. */
9229 addr
= tcg_temp_local_new_i32();
9230 load_reg_var(s
, addr
, rn
);
9231 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9232 if (insn
& (1 << 20)) {
9233 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9235 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9237 tcg_temp_free_i32(addr
);
9238 } else if ((insn
& (7 << 5)) == 0) {
9241 addr
= tcg_temp_new_i32();
9242 tcg_gen_movi_i32(addr
, s
->pc
);
9244 addr
= load_reg(s
, rn
);
9246 tmp
= load_reg(s
, rm
);
9247 tcg_gen_add_i32(addr
, addr
, tmp
);
9248 if (insn
& (1 << 4)) {
9250 tcg_gen_add_i32(addr
, addr
, tmp
);
9251 tcg_temp_free_i32(tmp
);
9252 tmp
= tcg_temp_new_i32();
9253 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9255 tcg_temp_free_i32(tmp
);
9256 tmp
= tcg_temp_new_i32();
9257 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9259 tcg_temp_free_i32(addr
);
9260 tcg_gen_shli_i32(tmp
, tmp
, 1);
9261 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9262 store_reg(s
, 15, tmp
);
9264 int op2
= (insn
>> 6) & 0x3;
9265 op
= (insn
>> 4) & 0x3;
9270 /* Load/store exclusive byte/halfword/doubleword */
9277 /* Load-acquire/store-release */
9283 /* Load-acquire/store-release exclusive */
9287 addr
= tcg_temp_local_new_i32();
9288 load_reg_var(s
, addr
, rn
);
9290 if (insn
& (1 << 20)) {
9291 tmp
= tcg_temp_new_i32();
9294 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9297 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9300 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9305 store_reg(s
, rs
, tmp
);
9307 tmp
= load_reg(s
, rs
);
9310 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9313 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9316 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9321 tcg_temp_free_i32(tmp
);
9323 } else if (insn
& (1 << 20)) {
9324 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9326 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9328 tcg_temp_free_i32(addr
);
9331 /* Load/store multiple, RFE, SRS. */
9332 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9333 /* RFE, SRS: not available in user mode or on M profile */
9334 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9337 if (insn
& (1 << 20)) {
9339 addr
= load_reg(s
, rn
);
9340 if ((insn
& (1 << 24)) == 0)
9341 tcg_gen_addi_i32(addr
, addr
, -8);
9342 /* Load PC into tmp and CPSR into tmp2. */
9343 tmp
= tcg_temp_new_i32();
9344 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9345 tcg_gen_addi_i32(addr
, addr
, 4);
9346 tmp2
= tcg_temp_new_i32();
9347 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9348 if (insn
& (1 << 21)) {
9349 /* Base writeback. */
9350 if (insn
& (1 << 24)) {
9351 tcg_gen_addi_i32(addr
, addr
, 4);
9353 tcg_gen_addi_i32(addr
, addr
, -4);
9355 store_reg(s
, rn
, addr
);
9357 tcg_temp_free_i32(addr
);
9359 gen_rfe(s
, tmp
, tmp2
);
9362 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9366 int i
, loaded_base
= 0;
9367 TCGv_i32 loaded_var
;
9368 /* Load/store multiple. */
9369 addr
= load_reg(s
, rn
);
9371 for (i
= 0; i
< 16; i
++) {
9372 if (insn
& (1 << i
))
9375 if (insn
& (1 << 24)) {
9376 tcg_gen_addi_i32(addr
, addr
, -offset
);
9379 TCGV_UNUSED_I32(loaded_var
);
9380 for (i
= 0; i
< 16; i
++) {
9381 if ((insn
& (1 << i
)) == 0)
9383 if (insn
& (1 << 20)) {
9385 tmp
= tcg_temp_new_i32();
9386 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9389 } else if (i
== rn
) {
9393 store_reg(s
, i
, tmp
);
9397 tmp
= load_reg(s
, i
);
9398 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9399 tcg_temp_free_i32(tmp
);
9401 tcg_gen_addi_i32(addr
, addr
, 4);
9404 store_reg(s
, rn
, loaded_var
);
9406 if (insn
& (1 << 21)) {
9407 /* Base register writeback. */
9408 if (insn
& (1 << 24)) {
9409 tcg_gen_addi_i32(addr
, addr
, -offset
);
9411 /* Fault if writeback register is in register list. */
9412 if (insn
& (1 << rn
))
9414 store_reg(s
, rn
, addr
);
9416 tcg_temp_free_i32(addr
);
9423 op
= (insn
>> 21) & 0xf;
9425 /* Halfword pack. */
9426 tmp
= load_reg(s
, rn
);
9427 tmp2
= load_reg(s
, rm
);
9428 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9429 if (insn
& (1 << 5)) {
9433 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9434 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9435 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9439 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9440 tcg_gen_ext16u_i32(tmp
, tmp
);
9441 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9443 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9444 tcg_temp_free_i32(tmp2
);
9445 store_reg(s
, rd
, tmp
);
9447 /* Data processing register constant shift. */
9449 tmp
= tcg_temp_new_i32();
9450 tcg_gen_movi_i32(tmp
, 0);
9452 tmp
= load_reg(s
, rn
);
9454 tmp2
= load_reg(s
, rm
);
9456 shiftop
= (insn
>> 4) & 3;
9457 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9458 conds
= (insn
& (1 << 20)) != 0;
9459 logic_cc
= (conds
&& thumb2_logic_op(op
));
9460 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9461 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9463 tcg_temp_free_i32(tmp2
);
9465 store_reg(s
, rd
, tmp
);
9467 tcg_temp_free_i32(tmp
);
9471 case 13: /* Misc data processing. */
9472 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9473 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9476 case 0: /* Register controlled shift. */
9477 tmp
= load_reg(s
, rn
);
9478 tmp2
= load_reg(s
, rm
);
9479 if ((insn
& 0x70) != 0)
9481 op
= (insn
>> 21) & 3;
9482 logic_cc
= (insn
& (1 << 20)) != 0;
9483 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9486 store_reg_bx(s
, rd
, tmp
);
9488 case 1: /* Sign/zero extend. */
9489 tmp
= load_reg(s
, rm
);
9490 shift
= (insn
>> 4) & 3;
9491 /* ??? In many cases it's not necessary to do a
9492 rotate, a shift is sufficient. */
9494 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9495 op
= (insn
>> 20) & 7;
9497 case 0: gen_sxth(tmp
); break;
9498 case 1: gen_uxth(tmp
); break;
9499 case 2: gen_sxtb16(tmp
); break;
9500 case 3: gen_uxtb16(tmp
); break;
9501 case 4: gen_sxtb(tmp
); break;
9502 case 5: gen_uxtb(tmp
); break;
9503 default: goto illegal_op
;
9506 tmp2
= load_reg(s
, rn
);
9507 if ((op
>> 1) == 1) {
9508 gen_add16(tmp
, tmp2
);
9510 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9511 tcg_temp_free_i32(tmp2
);
9514 store_reg(s
, rd
, tmp
);
9516 case 2: /* SIMD add/subtract. */
9517 op
= (insn
>> 20) & 7;
9518 shift
= (insn
>> 4) & 7;
9519 if ((op
& 3) == 3 || (shift
& 3) == 3)
9521 tmp
= load_reg(s
, rn
);
9522 tmp2
= load_reg(s
, rm
);
9523 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9524 tcg_temp_free_i32(tmp2
);
9525 store_reg(s
, rd
, tmp
);
9527 case 3: /* Other data processing. */
9528 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9530 /* Saturating add/subtract. */
9531 tmp
= load_reg(s
, rn
);
9532 tmp2
= load_reg(s
, rm
);
9534 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9536 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9538 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9539 tcg_temp_free_i32(tmp2
);
9541 tmp
= load_reg(s
, rn
);
9543 case 0x0a: /* rbit */
9544 gen_helper_rbit(tmp
, tmp
);
9546 case 0x08: /* rev */
9547 tcg_gen_bswap32_i32(tmp
, tmp
);
9549 case 0x09: /* rev16 */
9552 case 0x0b: /* revsh */
9555 case 0x10: /* sel */
9556 tmp2
= load_reg(s
, rm
);
9557 tmp3
= tcg_temp_new_i32();
9558 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9559 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9560 tcg_temp_free_i32(tmp3
);
9561 tcg_temp_free_i32(tmp2
);
9563 case 0x18: /* clz */
9564 gen_helper_clz(tmp
, tmp
);
9574 uint32_t sz
= op
& 0x3;
9575 uint32_t c
= op
& 0x8;
9577 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
9581 tmp2
= load_reg(s
, rm
);
9583 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9584 } else if (sz
== 1) {
9585 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9587 tmp3
= tcg_const_i32(1 << sz
);
9589 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9591 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9593 tcg_temp_free_i32(tmp2
);
9594 tcg_temp_free_i32(tmp3
);
9601 store_reg(s
, rd
, tmp
);
9603 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9604 op
= (insn
>> 4) & 0xf;
9605 tmp
= load_reg(s
, rn
);
9606 tmp2
= load_reg(s
, rm
);
9607 switch ((insn
>> 20) & 7) {
9608 case 0: /* 32 x 32 -> 32 */
9609 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9610 tcg_temp_free_i32(tmp2
);
9612 tmp2
= load_reg(s
, rs
);
9614 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9616 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9617 tcg_temp_free_i32(tmp2
);
9620 case 1: /* 16 x 16 -> 32 */
9621 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9622 tcg_temp_free_i32(tmp2
);
9624 tmp2
= load_reg(s
, rs
);
9625 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9626 tcg_temp_free_i32(tmp2
);
9629 case 2: /* Dual multiply add. */
9630 case 4: /* Dual multiply subtract. */
9632 gen_swap_half(tmp2
);
9633 gen_smul_dual(tmp
, tmp2
);
9634 if (insn
& (1 << 22)) {
9635 /* This subtraction cannot overflow. */
9636 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9638 /* This addition cannot overflow 32 bits;
9639 * however it may overflow considered as a signed
9640 * operation, in which case we must set the Q flag.
9642 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9644 tcg_temp_free_i32(tmp2
);
9647 tmp2
= load_reg(s
, rs
);
9648 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9649 tcg_temp_free_i32(tmp2
);
9652 case 3: /* 32 * 16 -> 32msb */
9654 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9657 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9658 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9659 tmp
= tcg_temp_new_i32();
9660 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9661 tcg_temp_free_i64(tmp64
);
9664 tmp2
= load_reg(s
, rs
);
9665 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9666 tcg_temp_free_i32(tmp2
);
9669 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9670 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9672 tmp
= load_reg(s
, rs
);
9673 if (insn
& (1 << 20)) {
9674 tmp64
= gen_addq_msw(tmp64
, tmp
);
9676 tmp64
= gen_subq_msw(tmp64
, tmp
);
9679 if (insn
& (1 << 4)) {
9680 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9682 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9683 tmp
= tcg_temp_new_i32();
9684 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9685 tcg_temp_free_i64(tmp64
);
9687 case 7: /* Unsigned sum of absolute differences. */
9688 gen_helper_usad8(tmp
, tmp
, tmp2
);
9689 tcg_temp_free_i32(tmp2
);
9691 tmp2
= load_reg(s
, rs
);
9692 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9693 tcg_temp_free_i32(tmp2
);
9697 store_reg(s
, rd
, tmp
);
9699 case 6: case 7: /* 64-bit multiply, Divide. */
9700 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9701 tmp
= load_reg(s
, rn
);
9702 tmp2
= load_reg(s
, rm
);
9703 if ((op
& 0x50) == 0x10) {
9705 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
9709 gen_helper_udiv(tmp
, tmp
, tmp2
);
9711 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9712 tcg_temp_free_i32(tmp2
);
9713 store_reg(s
, rd
, tmp
);
9714 } else if ((op
& 0xe) == 0xc) {
9715 /* Dual multiply accumulate long. */
9717 gen_swap_half(tmp2
);
9718 gen_smul_dual(tmp
, tmp2
);
9720 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9722 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9724 tcg_temp_free_i32(tmp2
);
9726 tmp64
= tcg_temp_new_i64();
9727 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9728 tcg_temp_free_i32(tmp
);
9729 gen_addq(s
, tmp64
, rs
, rd
);
9730 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9731 tcg_temp_free_i64(tmp64
);
9734 /* Unsigned 64-bit multiply */
9735 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9739 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9740 tcg_temp_free_i32(tmp2
);
9741 tmp64
= tcg_temp_new_i64();
9742 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9743 tcg_temp_free_i32(tmp
);
9745 /* Signed 64-bit multiply */
9746 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9751 gen_addq_lo(s
, tmp64
, rs
);
9752 gen_addq_lo(s
, tmp64
, rd
);
9753 } else if (op
& 0x40) {
9754 /* 64-bit accumulate. */
9755 gen_addq(s
, tmp64
, rs
, rd
);
9757 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9758 tcg_temp_free_i64(tmp64
);
9763 case 6: case 7: case 14: case 15:
9765 if (((insn
>> 24) & 3) == 3) {
9766 /* Translate into the equivalent ARM encoding. */
9767 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9768 if (disas_neon_data_insn(s
, insn
)) {
9771 } else if (((insn
>> 8) & 0xe) == 10) {
9772 if (disas_vfp_insn(s
, insn
)) {
9776 if (insn
& (1 << 28))
9778 if (disas_coproc_insn(s
, insn
)) {
9783 case 8: case 9: case 10: case 11:
9784 if (insn
& (1 << 15)) {
9785 /* Branches, misc control. */
9786 if (insn
& 0x5000) {
9787 /* Unconditional branch. */
9788 /* signextend(hw1[10:0]) -> offset[:12]. */
9789 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9790 /* hw1[10:0] -> offset[11:1]. */
9791 offset
|= (insn
& 0x7ff) << 1;
9792 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9793 offset[24:22] already have the same value because of the
9794 sign extension above. */
9795 offset
^= ((~insn
) & (1 << 13)) << 10;
9796 offset
^= ((~insn
) & (1 << 11)) << 11;
9798 if (insn
& (1 << 14)) {
9799 /* Branch and link. */
9800 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9804 if (insn
& (1 << 12)) {
9809 offset
&= ~(uint32_t)2;
9810 /* thumb2 bx, no need to check */
9811 gen_bx_im(s
, offset
);
9813 } else if (((insn
>> 23) & 7) == 7) {
9815 if (insn
& (1 << 13))
9818 if (insn
& (1 << 26)) {
9819 if (!(insn
& (1 << 20))) {
9820 /* Hypervisor call (v7) */
9821 int imm16
= extract32(insn
, 16, 4) << 12
9822 | extract32(insn
, 0, 12);
9829 /* Secure monitor call (v6+) */
9837 op
= (insn
>> 20) & 7;
9839 case 0: /* msr cpsr. */
9840 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9841 tmp
= load_reg(s
, rn
);
9842 addr
= tcg_const_i32(insn
& 0xff);
9843 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9844 tcg_temp_free_i32(addr
);
9845 tcg_temp_free_i32(tmp
);
9850 case 1: /* msr spsr. */
9851 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9854 tmp
= load_reg(s
, rn
);
9856 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
9860 case 2: /* cps, nop-hint. */
9861 if (((insn
>> 8) & 7) == 0) {
9862 gen_nop_hint(s
, insn
& 0xff);
9864 /* Implemented as NOP in user mode. */
9869 if (insn
& (1 << 10)) {
9870 if (insn
& (1 << 7))
9872 if (insn
& (1 << 6))
9874 if (insn
& (1 << 5))
9876 if (insn
& (1 << 9))
9877 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9879 if (insn
& (1 << 8)) {
9881 imm
|= (insn
& 0x1f);
9884 gen_set_psr_im(s
, offset
, 0, imm
);
9887 case 3: /* Special control operations. */
9889 op
= (insn
>> 4) & 0xf;
9897 /* These execute as NOPs. */
9904 /* Trivial implementation equivalent to bx. */
9905 tmp
= load_reg(s
, rn
);
9908 case 5: /* Exception return. */
9912 if (rn
!= 14 || rd
!= 15) {
9915 tmp
= load_reg(s
, rn
);
9916 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9917 gen_exception_return(s
, tmp
);
9919 case 6: /* mrs cpsr. */
9920 tmp
= tcg_temp_new_i32();
9921 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9922 addr
= tcg_const_i32(insn
& 0xff);
9923 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9924 tcg_temp_free_i32(addr
);
9926 gen_helper_cpsr_read(tmp
, cpu_env
);
9928 store_reg(s
, rd
, tmp
);
9930 case 7: /* mrs spsr. */
9931 /* Not accessible in user mode. */
9932 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9935 tmp
= load_cpu_field(spsr
);
9936 store_reg(s
, rd
, tmp
);
9941 /* Conditional branch. */
9942 op
= (insn
>> 22) & 0xf;
9943 /* Generate a conditional jump to next instruction. */
9944 s
->condlabel
= gen_new_label();
9945 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9948 /* offset[11:1] = insn[10:0] */
9949 offset
= (insn
& 0x7ff) << 1;
9950 /* offset[17:12] = insn[21:16]. */
9951 offset
|= (insn
& 0x003f0000) >> 4;
9952 /* offset[31:20] = insn[26]. */
9953 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9954 /* offset[18] = insn[13]. */
9955 offset
|= (insn
& (1 << 13)) << 5;
9956 /* offset[19] = insn[11]. */
9957 offset
|= (insn
& (1 << 11)) << 8;
9959 /* jump to the offset */
9960 gen_jmp(s
, s
->pc
+ offset
);
9963 /* Data processing immediate. */
9964 if (insn
& (1 << 25)) {
9965 if (insn
& (1 << 24)) {
9966 if (insn
& (1 << 20))
9968 /* Bitfield/Saturate. */
9969 op
= (insn
>> 21) & 7;
9971 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9973 tmp
= tcg_temp_new_i32();
9974 tcg_gen_movi_i32(tmp
, 0);
9976 tmp
= load_reg(s
, rn
);
9979 case 2: /* Signed bitfield extract. */
9981 if (shift
+ imm
> 32)
9984 gen_sbfx(tmp
, shift
, imm
);
9986 case 6: /* Unsigned bitfield extract. */
9988 if (shift
+ imm
> 32)
9991 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9993 case 3: /* Bitfield insert/clear. */
9996 imm
= imm
+ 1 - shift
;
9998 tmp2
= load_reg(s
, rd
);
9999 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10000 tcg_temp_free_i32(tmp2
);
10005 default: /* Saturate. */
10008 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10010 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10012 tmp2
= tcg_const_i32(imm
);
10015 if ((op
& 1) && shift
== 0)
10016 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10018 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10021 if ((op
& 1) && shift
== 0)
10022 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10024 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10026 tcg_temp_free_i32(tmp2
);
10029 store_reg(s
, rd
, tmp
);
10031 imm
= ((insn
& 0x04000000) >> 15)
10032 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10033 if (insn
& (1 << 22)) {
10034 /* 16-bit immediate. */
10035 imm
|= (insn
>> 4) & 0xf000;
10036 if (insn
& (1 << 23)) {
10038 tmp
= load_reg(s
, rd
);
10039 tcg_gen_ext16u_i32(tmp
, tmp
);
10040 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10043 tmp
= tcg_temp_new_i32();
10044 tcg_gen_movi_i32(tmp
, imm
);
10047 /* Add/sub 12-bit immediate. */
10049 offset
= s
->pc
& ~(uint32_t)3;
10050 if (insn
& (1 << 23))
10054 tmp
= tcg_temp_new_i32();
10055 tcg_gen_movi_i32(tmp
, offset
);
10057 tmp
= load_reg(s
, rn
);
10058 if (insn
& (1 << 23))
10059 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10061 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10064 store_reg(s
, rd
, tmp
);
10067 int shifter_out
= 0;
10068 /* modified 12-bit immediate. */
10069 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10070 imm
= (insn
& 0xff);
10073 /* Nothing to do. */
10075 case 1: /* 00XY00XY */
10078 case 2: /* XY00XY00 */
10082 case 3: /* XYXYXYXY */
10086 default: /* Rotated constant. */
10087 shift
= (shift
<< 1) | (imm
>> 7);
10089 imm
= imm
<< (32 - shift
);
10093 tmp2
= tcg_temp_new_i32();
10094 tcg_gen_movi_i32(tmp2
, imm
);
10095 rn
= (insn
>> 16) & 0xf;
10097 tmp
= tcg_temp_new_i32();
10098 tcg_gen_movi_i32(tmp
, 0);
10100 tmp
= load_reg(s
, rn
);
10102 op
= (insn
>> 21) & 0xf;
10103 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10104 shifter_out
, tmp
, tmp2
))
10106 tcg_temp_free_i32(tmp2
);
10107 rd
= (insn
>> 8) & 0xf;
10109 store_reg(s
, rd
, tmp
);
10111 tcg_temp_free_i32(tmp
);
10116 case 12: /* Load/store single data item. */
10121 if ((insn
& 0x01100000) == 0x01000000) {
10122 if (disas_neon_ls_insn(s
, insn
)) {
10127 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10129 if (!(insn
& (1 << 20))) {
10133 /* Byte or halfword load space with dest == r15 : memory hints.
10134 * Catch them early so we don't emit pointless addressing code.
10135 * This space is a mix of:
10136 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10137 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10139 * unallocated hints, which must be treated as NOPs
10140 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10141 * which is easiest for the decoding logic
10142 * Some space which must UNDEF
10144 int op1
= (insn
>> 23) & 3;
10145 int op2
= (insn
>> 6) & 0x3f;
10150 /* UNPREDICTABLE, unallocated hint or
10151 * PLD/PLDW/PLI (literal)
10156 return 0; /* PLD/PLDW/PLI or unallocated hint */
10158 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10159 return 0; /* PLD/PLDW/PLI or unallocated hint */
10161 /* UNDEF space, or an UNPREDICTABLE */
10165 memidx
= get_mem_index(s
);
10167 addr
= tcg_temp_new_i32();
10169 /* s->pc has already been incremented by 4. */
10170 imm
= s
->pc
& 0xfffffffc;
10171 if (insn
& (1 << 23))
10172 imm
+= insn
& 0xfff;
10174 imm
-= insn
& 0xfff;
10175 tcg_gen_movi_i32(addr
, imm
);
10177 addr
= load_reg(s
, rn
);
10178 if (insn
& (1 << 23)) {
10179 /* Positive offset. */
10180 imm
= insn
& 0xfff;
10181 tcg_gen_addi_i32(addr
, addr
, imm
);
10184 switch ((insn
>> 8) & 0xf) {
10185 case 0x0: /* Shifted Register. */
10186 shift
= (insn
>> 4) & 0xf;
10188 tcg_temp_free_i32(addr
);
10191 tmp
= load_reg(s
, rm
);
10193 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10194 tcg_gen_add_i32(addr
, addr
, tmp
);
10195 tcg_temp_free_i32(tmp
);
10197 case 0xc: /* Negative offset. */
10198 tcg_gen_addi_i32(addr
, addr
, -imm
);
10200 case 0xe: /* User privilege. */
10201 tcg_gen_addi_i32(addr
, addr
, imm
);
10202 memidx
= get_a32_user_mem_index(s
);
10204 case 0x9: /* Post-decrement. */
10206 /* Fall through. */
10207 case 0xb: /* Post-increment. */
10211 case 0xd: /* Pre-decrement. */
10213 /* Fall through. */
10214 case 0xf: /* Pre-increment. */
10215 tcg_gen_addi_i32(addr
, addr
, imm
);
10219 tcg_temp_free_i32(addr
);
10224 if (insn
& (1 << 20)) {
10226 tmp
= tcg_temp_new_i32();
10229 gen_aa32_ld8u(tmp
, addr
, memidx
);
10232 gen_aa32_ld8s(tmp
, addr
, memidx
);
10235 gen_aa32_ld16u(tmp
, addr
, memidx
);
10238 gen_aa32_ld16s(tmp
, addr
, memidx
);
10241 gen_aa32_ld32u(tmp
, addr
, memidx
);
10244 tcg_temp_free_i32(tmp
);
10245 tcg_temp_free_i32(addr
);
10251 store_reg(s
, rs
, tmp
);
10255 tmp
= load_reg(s
, rs
);
10258 gen_aa32_st8(tmp
, addr
, memidx
);
10261 gen_aa32_st16(tmp
, addr
, memidx
);
10264 gen_aa32_st32(tmp
, addr
, memidx
);
10267 tcg_temp_free_i32(tmp
);
10268 tcg_temp_free_i32(addr
);
10271 tcg_temp_free_i32(tmp
);
10274 tcg_gen_addi_i32(addr
, addr
, imm
);
10276 store_reg(s
, rn
, addr
);
10278 tcg_temp_free_i32(addr
);
10290 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10292 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10299 if (s
->condexec_mask
) {
10300 cond
= s
->condexec_cond
;
10301 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10302 s
->condlabel
= gen_new_label();
10303 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10308 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10311 switch (insn
>> 12) {
10315 op
= (insn
>> 11) & 3;
10318 rn
= (insn
>> 3) & 7;
10319 tmp
= load_reg(s
, rn
);
10320 if (insn
& (1 << 10)) {
10322 tmp2
= tcg_temp_new_i32();
10323 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10326 rm
= (insn
>> 6) & 7;
10327 tmp2
= load_reg(s
, rm
);
10329 if (insn
& (1 << 9)) {
10330 if (s
->condexec_mask
)
10331 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10333 gen_sub_CC(tmp
, tmp
, tmp2
);
10335 if (s
->condexec_mask
)
10336 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10338 gen_add_CC(tmp
, tmp
, tmp2
);
10340 tcg_temp_free_i32(tmp2
);
10341 store_reg(s
, rd
, tmp
);
10343 /* shift immediate */
10344 rm
= (insn
>> 3) & 7;
10345 shift
= (insn
>> 6) & 0x1f;
10346 tmp
= load_reg(s
, rm
);
10347 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10348 if (!s
->condexec_mask
)
10350 store_reg(s
, rd
, tmp
);
10354 /* arithmetic large immediate */
10355 op
= (insn
>> 11) & 3;
10356 rd
= (insn
>> 8) & 0x7;
10357 if (op
== 0) { /* mov */
10358 tmp
= tcg_temp_new_i32();
10359 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10360 if (!s
->condexec_mask
)
10362 store_reg(s
, rd
, tmp
);
10364 tmp
= load_reg(s
, rd
);
10365 tmp2
= tcg_temp_new_i32();
10366 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10369 gen_sub_CC(tmp
, tmp
, tmp2
);
10370 tcg_temp_free_i32(tmp
);
10371 tcg_temp_free_i32(tmp2
);
10374 if (s
->condexec_mask
)
10375 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10377 gen_add_CC(tmp
, tmp
, tmp2
);
10378 tcg_temp_free_i32(tmp2
);
10379 store_reg(s
, rd
, tmp
);
10382 if (s
->condexec_mask
)
10383 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10385 gen_sub_CC(tmp
, tmp
, tmp2
);
10386 tcg_temp_free_i32(tmp2
);
10387 store_reg(s
, rd
, tmp
);
10393 if (insn
& (1 << 11)) {
10394 rd
= (insn
>> 8) & 7;
10395 /* load pc-relative. Bit 1 of PC is ignored. */
10396 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10397 val
&= ~(uint32_t)2;
10398 addr
= tcg_temp_new_i32();
10399 tcg_gen_movi_i32(addr
, val
);
10400 tmp
= tcg_temp_new_i32();
10401 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10402 tcg_temp_free_i32(addr
);
10403 store_reg(s
, rd
, tmp
);
10406 if (insn
& (1 << 10)) {
10407 /* data processing extended or blx */
10408 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10409 rm
= (insn
>> 3) & 0xf;
10410 op
= (insn
>> 8) & 3;
10413 tmp
= load_reg(s
, rd
);
10414 tmp2
= load_reg(s
, rm
);
10415 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10416 tcg_temp_free_i32(tmp2
);
10417 store_reg(s
, rd
, tmp
);
10420 tmp
= load_reg(s
, rd
);
10421 tmp2
= load_reg(s
, rm
);
10422 gen_sub_CC(tmp
, tmp
, tmp2
);
10423 tcg_temp_free_i32(tmp2
);
10424 tcg_temp_free_i32(tmp
);
10426 case 2: /* mov/cpy */
10427 tmp
= load_reg(s
, rm
);
10428 store_reg(s
, rd
, tmp
);
10430 case 3:/* branch [and link] exchange thumb register */
10431 tmp
= load_reg(s
, rm
);
10432 if (insn
& (1 << 7)) {
10434 val
= (uint32_t)s
->pc
| 1;
10435 tmp2
= tcg_temp_new_i32();
10436 tcg_gen_movi_i32(tmp2
, val
);
10437 store_reg(s
, 14, tmp2
);
10439 /* already thumb, no need to check */
10446 /* data processing register */
10448 rm
= (insn
>> 3) & 7;
10449 op
= (insn
>> 6) & 0xf;
10450 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10451 /* the shift/rotate ops want the operands backwards */
10460 if (op
== 9) { /* neg */
10461 tmp
= tcg_temp_new_i32();
10462 tcg_gen_movi_i32(tmp
, 0);
10463 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10464 tmp
= load_reg(s
, rd
);
10466 TCGV_UNUSED_I32(tmp
);
10469 tmp2
= load_reg(s
, rm
);
10471 case 0x0: /* and */
10472 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10473 if (!s
->condexec_mask
)
10476 case 0x1: /* eor */
10477 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10478 if (!s
->condexec_mask
)
10481 case 0x2: /* lsl */
10482 if (s
->condexec_mask
) {
10483 gen_shl(tmp2
, tmp2
, tmp
);
10485 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10486 gen_logic_CC(tmp2
);
10489 case 0x3: /* lsr */
10490 if (s
->condexec_mask
) {
10491 gen_shr(tmp2
, tmp2
, tmp
);
10493 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10494 gen_logic_CC(tmp2
);
10497 case 0x4: /* asr */
10498 if (s
->condexec_mask
) {
10499 gen_sar(tmp2
, tmp2
, tmp
);
10501 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10502 gen_logic_CC(tmp2
);
10505 case 0x5: /* adc */
10506 if (s
->condexec_mask
) {
10507 gen_adc(tmp
, tmp2
);
10509 gen_adc_CC(tmp
, tmp
, tmp2
);
10512 case 0x6: /* sbc */
10513 if (s
->condexec_mask
) {
10514 gen_sub_carry(tmp
, tmp
, tmp2
);
10516 gen_sbc_CC(tmp
, tmp
, tmp2
);
10519 case 0x7: /* ror */
10520 if (s
->condexec_mask
) {
10521 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10522 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10524 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10525 gen_logic_CC(tmp2
);
10528 case 0x8: /* tst */
10529 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10533 case 0x9: /* neg */
10534 if (s
->condexec_mask
)
10535 tcg_gen_neg_i32(tmp
, tmp2
);
10537 gen_sub_CC(tmp
, tmp
, tmp2
);
10539 case 0xa: /* cmp */
10540 gen_sub_CC(tmp
, tmp
, tmp2
);
10543 case 0xb: /* cmn */
10544 gen_add_CC(tmp
, tmp
, tmp2
);
10547 case 0xc: /* orr */
10548 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10549 if (!s
->condexec_mask
)
10552 case 0xd: /* mul */
10553 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10554 if (!s
->condexec_mask
)
10557 case 0xe: /* bic */
10558 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10559 if (!s
->condexec_mask
)
10562 case 0xf: /* mvn */
10563 tcg_gen_not_i32(tmp2
, tmp2
);
10564 if (!s
->condexec_mask
)
10565 gen_logic_CC(tmp2
);
10572 store_reg(s
, rm
, tmp2
);
10574 tcg_temp_free_i32(tmp
);
10576 store_reg(s
, rd
, tmp
);
10577 tcg_temp_free_i32(tmp2
);
10580 tcg_temp_free_i32(tmp
);
10581 tcg_temp_free_i32(tmp2
);
10586 /* load/store register offset. */
10588 rn
= (insn
>> 3) & 7;
10589 rm
= (insn
>> 6) & 7;
10590 op
= (insn
>> 9) & 7;
10591 addr
= load_reg(s
, rn
);
10592 tmp
= load_reg(s
, rm
);
10593 tcg_gen_add_i32(addr
, addr
, tmp
);
10594 tcg_temp_free_i32(tmp
);
10596 if (op
< 3) { /* store */
10597 tmp
= load_reg(s
, rd
);
10599 tmp
= tcg_temp_new_i32();
10604 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10607 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10610 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10612 case 3: /* ldrsb */
10613 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10616 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10619 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10622 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10624 case 7: /* ldrsh */
10625 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10628 if (op
>= 3) { /* load */
10629 store_reg(s
, rd
, tmp
);
10631 tcg_temp_free_i32(tmp
);
10633 tcg_temp_free_i32(addr
);
10637 /* load/store word immediate offset */
10639 rn
= (insn
>> 3) & 7;
10640 addr
= load_reg(s
, rn
);
10641 val
= (insn
>> 4) & 0x7c;
10642 tcg_gen_addi_i32(addr
, addr
, val
);
10644 if (insn
& (1 << 11)) {
10646 tmp
= tcg_temp_new_i32();
10647 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10648 store_reg(s
, rd
, tmp
);
10651 tmp
= load_reg(s
, rd
);
10652 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10653 tcg_temp_free_i32(tmp
);
10655 tcg_temp_free_i32(addr
);
10659 /* load/store byte immediate offset */
10661 rn
= (insn
>> 3) & 7;
10662 addr
= load_reg(s
, rn
);
10663 val
= (insn
>> 6) & 0x1f;
10664 tcg_gen_addi_i32(addr
, addr
, val
);
10666 if (insn
& (1 << 11)) {
10668 tmp
= tcg_temp_new_i32();
10669 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10670 store_reg(s
, rd
, tmp
);
10673 tmp
= load_reg(s
, rd
);
10674 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10675 tcg_temp_free_i32(tmp
);
10677 tcg_temp_free_i32(addr
);
10681 /* load/store halfword immediate offset */
10683 rn
= (insn
>> 3) & 7;
10684 addr
= load_reg(s
, rn
);
10685 val
= (insn
>> 5) & 0x3e;
10686 tcg_gen_addi_i32(addr
, addr
, val
);
10688 if (insn
& (1 << 11)) {
10690 tmp
= tcg_temp_new_i32();
10691 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10692 store_reg(s
, rd
, tmp
);
10695 tmp
= load_reg(s
, rd
);
10696 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10697 tcg_temp_free_i32(tmp
);
10699 tcg_temp_free_i32(addr
);
10703 /* load/store from stack */
10704 rd
= (insn
>> 8) & 7;
10705 addr
= load_reg(s
, 13);
10706 val
= (insn
& 0xff) * 4;
10707 tcg_gen_addi_i32(addr
, addr
, val
);
10709 if (insn
& (1 << 11)) {
10711 tmp
= tcg_temp_new_i32();
10712 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10713 store_reg(s
, rd
, tmp
);
10716 tmp
= load_reg(s
, rd
);
10717 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10718 tcg_temp_free_i32(tmp
);
10720 tcg_temp_free_i32(addr
);
10724 /* add to high reg */
10725 rd
= (insn
>> 8) & 7;
10726 if (insn
& (1 << 11)) {
10728 tmp
= load_reg(s
, 13);
10730 /* PC. bit 1 is ignored. */
10731 tmp
= tcg_temp_new_i32();
10732 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10734 val
= (insn
& 0xff) * 4;
10735 tcg_gen_addi_i32(tmp
, tmp
, val
);
10736 store_reg(s
, rd
, tmp
);
10741 op
= (insn
>> 8) & 0xf;
10744 /* adjust stack pointer */
10745 tmp
= load_reg(s
, 13);
10746 val
= (insn
& 0x7f) * 4;
10747 if (insn
& (1 << 7))
10748 val
= -(int32_t)val
;
10749 tcg_gen_addi_i32(tmp
, tmp
, val
);
10750 store_reg(s
, 13, tmp
);
10753 case 2: /* sign/zero extend. */
10756 rm
= (insn
>> 3) & 7;
10757 tmp
= load_reg(s
, rm
);
10758 switch ((insn
>> 6) & 3) {
10759 case 0: gen_sxth(tmp
); break;
10760 case 1: gen_sxtb(tmp
); break;
10761 case 2: gen_uxth(tmp
); break;
10762 case 3: gen_uxtb(tmp
); break;
10764 store_reg(s
, rd
, tmp
);
10766 case 4: case 5: case 0xc: case 0xd:
10768 addr
= load_reg(s
, 13);
10769 if (insn
& (1 << 8))
10773 for (i
= 0; i
< 8; i
++) {
10774 if (insn
& (1 << i
))
10777 if ((insn
& (1 << 11)) == 0) {
10778 tcg_gen_addi_i32(addr
, addr
, -offset
);
10780 for (i
= 0; i
< 8; i
++) {
10781 if (insn
& (1 << i
)) {
10782 if (insn
& (1 << 11)) {
10784 tmp
= tcg_temp_new_i32();
10785 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10786 store_reg(s
, i
, tmp
);
10789 tmp
= load_reg(s
, i
);
10790 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10791 tcg_temp_free_i32(tmp
);
10793 /* advance to the next address. */
10794 tcg_gen_addi_i32(addr
, addr
, 4);
10797 TCGV_UNUSED_I32(tmp
);
10798 if (insn
& (1 << 8)) {
10799 if (insn
& (1 << 11)) {
10801 tmp
= tcg_temp_new_i32();
10802 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10803 /* don't set the pc until the rest of the instruction
10807 tmp
= load_reg(s
, 14);
10808 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10809 tcg_temp_free_i32(tmp
);
10811 tcg_gen_addi_i32(addr
, addr
, 4);
10813 if ((insn
& (1 << 11)) == 0) {
10814 tcg_gen_addi_i32(addr
, addr
, -offset
);
10816 /* write back the new stack pointer */
10817 store_reg(s
, 13, addr
);
10818 /* set the new PC value */
10819 if ((insn
& 0x0900) == 0x0900) {
10820 store_reg_from_load(s
, 15, tmp
);
10824 case 1: case 3: case 9: case 11: /* czb */
10826 tmp
= load_reg(s
, rm
);
10827 s
->condlabel
= gen_new_label();
10829 if (insn
& (1 << 11))
10830 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10832 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10833 tcg_temp_free_i32(tmp
);
10834 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10835 val
= (uint32_t)s
->pc
+ 2;
10840 case 15: /* IT, nop-hint. */
10841 if ((insn
& 0xf) == 0) {
10842 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10846 s
->condexec_cond
= (insn
>> 4) & 0xe;
10847 s
->condexec_mask
= insn
& 0x1f;
10848 /* No actual code generated for this insn, just setup state. */
10851 case 0xe: /* bkpt */
10853 int imm8
= extract32(insn
, 0, 8);
10855 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true));
10859 case 0xa: /* rev */
10861 rn
= (insn
>> 3) & 0x7;
10863 tmp
= load_reg(s
, rn
);
10864 switch ((insn
>> 6) & 3) {
10865 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10866 case 1: gen_rev16(tmp
); break;
10867 case 3: gen_revsh(tmp
); break;
10868 default: goto illegal_op
;
10870 store_reg(s
, rd
, tmp
);
10874 switch ((insn
>> 5) & 7) {
10878 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10879 /* Dynamic endianness switching not implemented. */
10880 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10890 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10891 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10894 addr
= tcg_const_i32(19);
10895 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10896 tcg_temp_free_i32(addr
);
10900 addr
= tcg_const_i32(16);
10901 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10902 tcg_temp_free_i32(addr
);
10904 tcg_temp_free_i32(tmp
);
10907 if (insn
& (1 << 4)) {
10908 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10912 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10927 /* load/store multiple */
10928 TCGv_i32 loaded_var
;
10929 TCGV_UNUSED_I32(loaded_var
);
10930 rn
= (insn
>> 8) & 0x7;
10931 addr
= load_reg(s
, rn
);
10932 for (i
= 0; i
< 8; i
++) {
10933 if (insn
& (1 << i
)) {
10934 if (insn
& (1 << 11)) {
10936 tmp
= tcg_temp_new_i32();
10937 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10941 store_reg(s
, i
, tmp
);
10945 tmp
= load_reg(s
, i
);
10946 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10947 tcg_temp_free_i32(tmp
);
10949 /* advance to the next address */
10950 tcg_gen_addi_i32(addr
, addr
, 4);
10953 if ((insn
& (1 << rn
)) == 0) {
10954 /* base reg not in list: base register writeback */
10955 store_reg(s
, rn
, addr
);
10957 /* base reg in list: if load, complete it now */
10958 if (insn
& (1 << 11)) {
10959 store_reg(s
, rn
, loaded_var
);
10961 tcg_temp_free_i32(addr
);
10966 /* conditional branch or swi */
10967 cond
= (insn
>> 8) & 0xf;
10973 gen_set_pc_im(s
, s
->pc
);
10974 s
->svc_imm
= extract32(insn
, 0, 8);
10975 s
->is_jmp
= DISAS_SWI
;
10978 /* generate a conditional jump to next instruction */
10979 s
->condlabel
= gen_new_label();
10980 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10983 /* jump to the offset */
10984 val
= (uint32_t)s
->pc
+ 2;
10985 offset
= ((int32_t)insn
<< 24) >> 24;
10986 val
+= offset
<< 1;
10991 if (insn
& (1 << 11)) {
10992 if (disas_thumb2_insn(env
, s
, insn
))
10996 /* unconditional branch */
10997 val
= (uint32_t)s
->pc
;
10998 offset
= ((int32_t)insn
<< 21) >> 21;
10999 val
+= (offset
<< 1) + 2;
11004 if (disas_thumb2_insn(env
, s
, insn
))
11010 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized());
11014 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized());
11017 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
11018 basic block 'tb'. If search_pc is TRUE, also generate PC
11019 information for each intermediate instruction. */
11020 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
11021 TranslationBlock
*tb
,
11024 CPUState
*cs
= CPU(cpu
);
11025 CPUARMState
*env
= &cpu
->env
;
11026 DisasContext dc1
, *dc
= &dc1
;
11029 target_ulong pc_start
;
11030 target_ulong next_page_start
;
11034 /* generate intermediate code */
11036 /* The A64 decoder has its own top level loop, because it doesn't need
11037 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11039 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11040 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
11048 dc
->is_jmp
= DISAS_NEXT
;
11050 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11054 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11055 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
11056 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11057 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11058 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11059 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11060 #if !defined(CONFIG_USER_ONLY)
11061 dc
->user
= (dc
->current_el
== 0);
11063 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11064 dc
->cpacr_fpen
= ARM_TBFLAG_CPACR_FPEN(tb
->flags
);
11065 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11066 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11067 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11068 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11069 dc
->cp_regs
= cpu
->cp_regs
;
11070 dc
->features
= env
->features
;
11072 /* Single step state. The code-generation logic here is:
11074 * generate code with no special handling for single-stepping (except
11075 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11076 * this happens anyway because those changes are all system register or
11078 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11079 * emit code for one insn
11080 * emit code to clear PSTATE.SS
11081 * emit code to generate software step exception for completed step
11082 * end TB (as usual for having generated an exception)
11083 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11084 * emit code to generate a software step exception
11087 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11088 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11089 dc
->is_ldex
= false;
11090 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11092 cpu_F0s
= tcg_temp_new_i32();
11093 cpu_F1s
= tcg_temp_new_i32();
11094 cpu_F0d
= tcg_temp_new_i64();
11095 cpu_F1d
= tcg_temp_new_i64();
11098 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11099 cpu_M0
= tcg_temp_new_i64();
11100 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11103 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11104 if (max_insns
== 0)
11105 max_insns
= CF_COUNT_MASK
;
11109 tcg_clear_temp_count();
11111 /* A note on handling of the condexec (IT) bits:
11113 * We want to avoid the overhead of having to write the updated condexec
11114 * bits back to the CPUARMState for every instruction in an IT block. So:
11115 * (1) if the condexec bits are not already zero then we write
11116 * zero back into the CPUARMState now. This avoids complications trying
11117 * to do it at the end of the block. (For example if we don't do this
11118 * it's hard to identify whether we can safely skip writing condexec
11119 * at the end of the TB, which we definitely want to do for the case
11120 * where a TB doesn't do anything with the IT state at all.)
11121 * (2) if we are going to leave the TB then we call gen_set_condexec()
11122 * which will write the correct value into CPUARMState if zero is wrong.
11123 * This is done both for leaving the TB at the end, and for leaving
11124 * it because of an exception we know will happen, which is done in
11125 * gen_exception_insn(). The latter is necessary because we need to
11126 * leave the TB with the PC/IT state just prior to execution of the
11127 * instruction which caused the exception.
11128 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11129 * then the CPUARMState will be wrong and we need to reset it.
11130 * This is handled in the same way as restoration of the
11131 * PC in these situations: we will be called again with search_pc=1
11132 * and generate a mapping of the condexec bits for each PC in
11133 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11134 * this to restore the condexec bits.
11136 * Note that there are no instructions which can read the condexec
11137 * bits, and none which can write non-static values to them, so
11138 * we don't need to care about whether CPUARMState is correct in the
11142 /* Reset the conditional execution bits immediately. This avoids
11143 complications trying to do it at the end of the block. */
11144 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11146 TCGv_i32 tmp
= tcg_temp_new_i32();
11147 tcg_gen_movi_i32(tmp
, 0);
11148 store_cpu_field(tmp
, condexec_bits
);
11151 #ifdef CONFIG_USER_ONLY
11152 /* Intercept jump to the magic kernel page. */
11153 if (dc
->pc
>= 0xffff0000) {
11154 /* We always get here via a jump, so know we are not in a
11155 conditional execution block. */
11156 gen_exception_internal(EXCP_KERNEL_TRAP
);
11157 dc
->is_jmp
= DISAS_UPDATE
;
11161 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11162 /* We always get here via a jump, so know we are not in a
11163 conditional execution block. */
11164 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11165 dc
->is_jmp
= DISAS_UPDATE
;
11170 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11171 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11172 if (bp
->pc
== dc
->pc
) {
11173 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11174 /* Advance PC so that clearing the breakpoint will
11175 invalidate this TB. */
11177 goto done_generating
;
11182 j
= tcg_op_buf_count();
11186 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11188 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
11189 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
11190 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
11191 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
11194 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
11197 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
11198 tcg_gen_debug_insn_start(dc
->pc
);
11201 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11202 /* Singlestep state is Active-pending.
11203 * If we're in this state at the start of a TB then either
11204 * a) we just took an exception to an EL which is being debugged
11205 * and this is the first insn in the exception handler
11206 * b) debug exceptions were masked and we just unmasked them
11207 * without changing EL (eg by clearing PSTATE.D)
11208 * In either case we're going to take a swstep exception in the
11209 * "did not step an insn" case, and so the syndrome ISV and EX
11210 * bits should be zero.
11212 assert(num_insns
== 0);
11213 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0));
11214 goto done_generating
;
11218 disas_thumb_insn(env
, dc
);
11219 if (dc
->condexec_mask
) {
11220 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11221 | ((dc
->condexec_mask
>> 4) & 1);
11222 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11223 if (dc
->condexec_mask
== 0) {
11224 dc
->condexec_cond
= 0;
11228 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->bswap_code
);
11230 disas_arm_insn(dc
, insn
);
11233 if (dc
->condjmp
&& !dc
->is_jmp
) {
11234 gen_set_label(dc
->condlabel
);
11238 if (tcg_check_temp_count()) {
11239 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11243 /* Translation stops when a conditional branch is encountered.
11244 * Otherwise the subsequent code could get translated several times.
11245 * Also stop translation when a page boundary is reached. This
11246 * ensures prefetch aborts occur at the right place. */
11248 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11249 !cs
->singlestep_enabled
&&
11252 dc
->pc
< next_page_start
&&
11253 num_insns
< max_insns
);
11255 if (tb
->cflags
& CF_LAST_IO
) {
11257 /* FIXME: This can theoretically happen with self-modifying
11259 cpu_abort(cs
, "IO on conditional branch instruction");
11264 /* At this stage dc->condjmp will only be set when the skipped
11265 instruction was a conditional branch or trap, and the PC has
11266 already been written. */
11267 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11268 /* Make sure the pc is updated, and raise a debug exception. */
11270 gen_set_condexec(dc
);
11271 if (dc
->is_jmp
== DISAS_SWI
) {
11272 gen_ss_advance(dc
);
11273 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11274 } else if (dc
->is_jmp
== DISAS_HVC
) {
11275 gen_ss_advance(dc
);
11276 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11277 } else if (dc
->is_jmp
== DISAS_SMC
) {
11278 gen_ss_advance(dc
);
11279 gen_exception(EXCP_SMC
, syn_aa32_smc());
11280 } else if (dc
->ss_active
) {
11281 gen_step_complete_exception(dc
);
11283 gen_exception_internal(EXCP_DEBUG
);
11285 gen_set_label(dc
->condlabel
);
11287 if (dc
->condjmp
|| !dc
->is_jmp
) {
11288 gen_set_pc_im(dc
, dc
->pc
);
11291 gen_set_condexec(dc
);
11292 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11293 gen_ss_advance(dc
);
11294 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11295 } else if (dc
->is_jmp
== DISAS_HVC
&& !dc
->condjmp
) {
11296 gen_ss_advance(dc
);
11297 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11298 } else if (dc
->is_jmp
== DISAS_SMC
&& !dc
->condjmp
) {
11299 gen_ss_advance(dc
);
11300 gen_exception(EXCP_SMC
, syn_aa32_smc());
11301 } else if (dc
->ss_active
) {
11302 gen_step_complete_exception(dc
);
11304 /* FIXME: Single stepping a WFI insn will not halt
11306 gen_exception_internal(EXCP_DEBUG
);
11309 /* While branches must always occur at the end of an IT block,
11310 there are a few other things that can cause us to terminate
11311 the TB in the middle of an IT block:
11312 - Exception generating instructions (bkpt, swi, undefined).
11314 - Hardware watchpoints.
11315 Hardware breakpoints have already been handled and skip this code.
11317 gen_set_condexec(dc
);
11318 switch(dc
->is_jmp
) {
11320 gen_goto_tb(dc
, 1, dc
->pc
);
11325 /* indicate that the hash table must be used to find the next TB */
11326 tcg_gen_exit_tb(0);
11328 case DISAS_TB_JUMP
:
11329 /* nothing more to generate */
11332 gen_helper_wfi(cpu_env
);
11335 gen_helper_wfe(cpu_env
);
11338 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
));
11341 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
));
11344 gen_exception(EXCP_SMC
, syn_aa32_smc());
11348 gen_set_label(dc
->condlabel
);
11349 gen_set_condexec(dc
);
11350 gen_goto_tb(dc
, 1, dc
->pc
);
11356 gen_tb_end(tb
, num_insns
);
11359 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11360 qemu_log("----------------\n");
11361 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11362 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
11363 dc
->thumb
| (dc
->bswap_code
<< 1));
11368 j
= tcg_op_buf_count();
11371 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11373 tb
->size
= dc
->pc
- pc_start
;
11374 tb
->icount
= num_insns
;
11378 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11380 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11383 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11385 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11388 static const char *cpu_mode_names
[16] = {
11389 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11390 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11393 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11396 ARMCPU
*cpu
= ARM_CPU(cs
);
11397 CPUARMState
*env
= &cpu
->env
;
11402 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11406 for(i
=0;i
<16;i
++) {
11407 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11409 cpu_fprintf(f
, "\n");
11411 cpu_fprintf(f
, " ");
11413 psr
= cpsr_read(env
);
11414 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11416 psr
& (1 << 31) ? 'N' : '-',
11417 psr
& (1 << 30) ? 'Z' : '-',
11418 psr
& (1 << 29) ? 'C' : '-',
11419 psr
& (1 << 28) ? 'V' : '-',
11420 psr
& CPSR_T
? 'T' : 'A',
11421 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11423 if (flags
& CPU_DUMP_FPU
) {
11424 int numvfpregs
= 0;
11425 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11428 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11431 for (i
= 0; i
< numvfpregs
; i
++) {
11432 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11433 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11434 i
* 2, (uint32_t)v
,
11435 i
* 2 + 1, (uint32_t)(v
>> 32),
11438 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11442 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11445 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11446 env
->condexec_bits
= 0;
11448 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11449 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];