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"
56 #if defined(CONFIG_USER_ONLY)
59 #define IS_USER(s) (s->user)
63 /* We reuse the same 64-bit temporaries for efficiency. */
64 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
65 static TCGv_i32 cpu_R
[16];
66 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
67 TCGv_i64 cpu_exclusive_addr
;
68 TCGv_i64 cpu_exclusive_val
;
69 #ifdef CONFIG_USER_ONLY
70 TCGv_i64 cpu_exclusive_test
;
71 TCGv_i32 cpu_exclusive_info
;
74 /* FIXME: These should be removed. */
75 static TCGv_i32 cpu_F0s
, cpu_F1s
;
76 static TCGv_i64 cpu_F0d
, cpu_F1d
;
78 #include "exec/gen-icount.h"
80 static const char *regnames
[] =
81 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
82 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
84 /* initialize TCG globals. */
85 void arm_translate_init(void)
89 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
91 for (i
= 0; i
< 16; i
++) {
92 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
93 offsetof(CPUARMState
, regs
[i
]),
96 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
97 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
98 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
99 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
101 cpu_exclusive_addr
= tcg_global_mem_new_i64(TCG_AREG0
,
102 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
103 cpu_exclusive_val
= tcg_global_mem_new_i64(TCG_AREG0
,
104 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
105 #ifdef CONFIG_USER_ONLY
106 cpu_exclusive_test
= tcg_global_mem_new_i64(TCG_AREG0
,
107 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
108 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
109 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
112 a64_translate_init();
115 static inline ARMMMUIdx
get_a32_user_mem_index(DisasContext
*s
)
117 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
119 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
120 * otherwise, access as if at PL0.
122 switch (s
->mmu_idx
) {
123 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
124 case ARMMMUIdx_S12NSE0
:
125 case ARMMMUIdx_S12NSE1
:
126 return ARMMMUIdx_S12NSE0
;
128 case ARMMMUIdx_S1SE0
:
129 case ARMMMUIdx_S1SE1
:
130 return ARMMMUIdx_S1SE0
;
133 g_assert_not_reached();
137 static inline TCGv_i32
load_cpu_offset(int offset
)
139 TCGv_i32 tmp
= tcg_temp_new_i32();
140 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
144 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
146 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
148 tcg_gen_st_i32(var
, cpu_env
, offset
);
149 tcg_temp_free_i32(var
);
152 #define store_cpu_field(var, name) \
153 store_cpu_offset(var, offsetof(CPUARMState, name))
155 /* Set a variable to the value of a CPU register. */
156 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
160 /* normally, since we updated PC, we need only to add one insn */
162 addr
= (long)s
->pc
+ 2;
164 addr
= (long)s
->pc
+ 4;
165 tcg_gen_movi_i32(var
, addr
);
167 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
171 /* Create a new temporary and set it to the value of a CPU register. */
172 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
174 TCGv_i32 tmp
= tcg_temp_new_i32();
175 load_reg_var(s
, tmp
, reg
);
179 /* Set a CPU register. The source must be a temporary and will be
181 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
184 tcg_gen_andi_i32(var
, var
, ~1);
185 s
->is_jmp
= DISAS_JUMP
;
187 tcg_gen_mov_i32(cpu_R
[reg
], var
);
188 tcg_temp_free_i32(var
);
191 /* Value extensions. */
192 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
193 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
194 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
195 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
197 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
198 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
201 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
203 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
204 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
205 tcg_temp_free_i32(tmp_mask
);
207 /* Set NZCV flags from the high 4 bits of var. */
208 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
210 static void gen_exception_internal(int excp
)
212 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
214 assert(excp_is_internal(excp
));
215 gen_helper_exception_internal(cpu_env
, tcg_excp
);
216 tcg_temp_free_i32(tcg_excp
);
219 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
221 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
222 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
223 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
225 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
228 tcg_temp_free_i32(tcg_el
);
229 tcg_temp_free_i32(tcg_syn
);
230 tcg_temp_free_i32(tcg_excp
);
233 static void gen_ss_advance(DisasContext
*s
)
235 /* If the singlestep state is Active-not-pending, advance to
240 gen_helper_clear_pstate_ss(cpu_env
);
244 static void gen_step_complete_exception(DisasContext
*s
)
246 /* We just completed step of an insn. Move from Active-not-pending
247 * to Active-pending, and then also take the swstep exception.
248 * This corresponds to making the (IMPDEF) choice to prioritize
249 * swstep exceptions over asynchronous exceptions taken to an exception
250 * level where debug is disabled. This choice has the advantage that
251 * we do not need to maintain internal state corresponding to the
252 * ISV/EX syndrome bits between completion of the step and generation
253 * of the exception, and our syndrome information is always correct.
256 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
257 default_exception_el(s
));
258 s
->is_jmp
= DISAS_EXC
;
261 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
263 TCGv_i32 tmp1
= tcg_temp_new_i32();
264 TCGv_i32 tmp2
= tcg_temp_new_i32();
265 tcg_gen_ext16s_i32(tmp1
, a
);
266 tcg_gen_ext16s_i32(tmp2
, b
);
267 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
268 tcg_temp_free_i32(tmp2
);
269 tcg_gen_sari_i32(a
, a
, 16);
270 tcg_gen_sari_i32(b
, b
, 16);
271 tcg_gen_mul_i32(b
, b
, a
);
272 tcg_gen_mov_i32(a
, tmp1
);
273 tcg_temp_free_i32(tmp1
);
276 /* Byteswap each halfword. */
277 static void gen_rev16(TCGv_i32 var
)
279 TCGv_i32 tmp
= tcg_temp_new_i32();
280 tcg_gen_shri_i32(tmp
, var
, 8);
281 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
282 tcg_gen_shli_i32(var
, var
, 8);
283 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
284 tcg_gen_or_i32(var
, var
, tmp
);
285 tcg_temp_free_i32(tmp
);
288 /* Byteswap low halfword and sign extend. */
289 static void gen_revsh(TCGv_i32 var
)
291 tcg_gen_ext16u_i32(var
, var
);
292 tcg_gen_bswap16_i32(var
, var
);
293 tcg_gen_ext16s_i32(var
, var
);
296 /* Unsigned bitfield extract. */
297 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
300 tcg_gen_shri_i32(var
, var
, shift
);
301 tcg_gen_andi_i32(var
, var
, mask
);
304 /* Signed bitfield extract. */
305 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
310 tcg_gen_sari_i32(var
, var
, shift
);
311 if (shift
+ width
< 32) {
312 signbit
= 1u << (width
- 1);
313 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
314 tcg_gen_xori_i32(var
, var
, signbit
);
315 tcg_gen_subi_i32(var
, var
, signbit
);
319 /* Return (b << 32) + a. Mark inputs as dead */
320 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
322 TCGv_i64 tmp64
= tcg_temp_new_i64();
324 tcg_gen_extu_i32_i64(tmp64
, b
);
325 tcg_temp_free_i32(b
);
326 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
327 tcg_gen_add_i64(a
, tmp64
, a
);
329 tcg_temp_free_i64(tmp64
);
333 /* Return (b << 32) - a. Mark inputs as dead. */
334 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
336 TCGv_i64 tmp64
= tcg_temp_new_i64();
338 tcg_gen_extu_i32_i64(tmp64
, b
);
339 tcg_temp_free_i32(b
);
340 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
341 tcg_gen_sub_i64(a
, tmp64
, a
);
343 tcg_temp_free_i64(tmp64
);
347 /* 32x32->64 multiply. Marks inputs as dead. */
348 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
350 TCGv_i32 lo
= tcg_temp_new_i32();
351 TCGv_i32 hi
= tcg_temp_new_i32();
354 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
355 tcg_temp_free_i32(a
);
356 tcg_temp_free_i32(b
);
358 ret
= tcg_temp_new_i64();
359 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
360 tcg_temp_free_i32(lo
);
361 tcg_temp_free_i32(hi
);
366 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
368 TCGv_i32 lo
= tcg_temp_new_i32();
369 TCGv_i32 hi
= tcg_temp_new_i32();
372 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
373 tcg_temp_free_i32(a
);
374 tcg_temp_free_i32(b
);
376 ret
= tcg_temp_new_i64();
377 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
378 tcg_temp_free_i32(lo
);
379 tcg_temp_free_i32(hi
);
384 /* Swap low and high halfwords. */
385 static void gen_swap_half(TCGv_i32 var
)
387 TCGv_i32 tmp
= tcg_temp_new_i32();
388 tcg_gen_shri_i32(tmp
, var
, 16);
389 tcg_gen_shli_i32(var
, var
, 16);
390 tcg_gen_or_i32(var
, var
, tmp
);
391 tcg_temp_free_i32(tmp
);
394 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
395 tmp = (t0 ^ t1) & 0x8000;
398 t0 = (t0 + t1) ^ tmp;
401 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
403 TCGv_i32 tmp
= tcg_temp_new_i32();
404 tcg_gen_xor_i32(tmp
, t0
, t1
);
405 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
406 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
407 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
408 tcg_gen_add_i32(t0
, t0
, t1
);
409 tcg_gen_xor_i32(t0
, t0
, tmp
);
410 tcg_temp_free_i32(tmp
);
411 tcg_temp_free_i32(t1
);
414 /* Set CF to the top bit of var. */
415 static void gen_set_CF_bit31(TCGv_i32 var
)
417 tcg_gen_shri_i32(cpu_CF
, var
, 31);
420 /* Set N and Z flags from var. */
421 static inline void gen_logic_CC(TCGv_i32 var
)
423 tcg_gen_mov_i32(cpu_NF
, var
);
424 tcg_gen_mov_i32(cpu_ZF
, var
);
428 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
430 tcg_gen_add_i32(t0
, t0
, t1
);
431 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
434 /* dest = T0 + T1 + CF. */
435 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
437 tcg_gen_add_i32(dest
, t0
, t1
);
438 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
441 /* dest = T0 - T1 + CF - 1. */
442 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
444 tcg_gen_sub_i32(dest
, t0
, t1
);
445 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
446 tcg_gen_subi_i32(dest
, dest
, 1);
449 /* dest = T0 + T1. Compute C, N, V and Z flags */
450 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
452 TCGv_i32 tmp
= tcg_temp_new_i32();
453 tcg_gen_movi_i32(tmp
, 0);
454 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
455 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
456 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
457 tcg_gen_xor_i32(tmp
, t0
, t1
);
458 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
459 tcg_temp_free_i32(tmp
);
460 tcg_gen_mov_i32(dest
, cpu_NF
);
463 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
464 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
466 TCGv_i32 tmp
= tcg_temp_new_i32();
467 if (TCG_TARGET_HAS_add2_i32
) {
468 tcg_gen_movi_i32(tmp
, 0);
469 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
470 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
472 TCGv_i64 q0
= tcg_temp_new_i64();
473 TCGv_i64 q1
= tcg_temp_new_i64();
474 tcg_gen_extu_i32_i64(q0
, t0
);
475 tcg_gen_extu_i32_i64(q1
, t1
);
476 tcg_gen_add_i64(q0
, q0
, q1
);
477 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
478 tcg_gen_add_i64(q0
, q0
, q1
);
479 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
480 tcg_temp_free_i64(q0
);
481 tcg_temp_free_i64(q1
);
483 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
484 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
485 tcg_gen_xor_i32(tmp
, t0
, t1
);
486 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
487 tcg_temp_free_i32(tmp
);
488 tcg_gen_mov_i32(dest
, cpu_NF
);
491 /* dest = T0 - T1. Compute C, N, V and Z flags */
492 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
495 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
496 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
497 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
498 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
499 tmp
= tcg_temp_new_i32();
500 tcg_gen_xor_i32(tmp
, t0
, t1
);
501 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
502 tcg_temp_free_i32(tmp
);
503 tcg_gen_mov_i32(dest
, cpu_NF
);
506 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
507 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
509 TCGv_i32 tmp
= tcg_temp_new_i32();
510 tcg_gen_not_i32(tmp
, t1
);
511 gen_adc_CC(dest
, t0
, tmp
);
512 tcg_temp_free_i32(tmp
);
515 #define GEN_SHIFT(name) \
516 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
518 TCGv_i32 tmp1, tmp2, tmp3; \
519 tmp1 = tcg_temp_new_i32(); \
520 tcg_gen_andi_i32(tmp1, t1, 0xff); \
521 tmp2 = tcg_const_i32(0); \
522 tmp3 = tcg_const_i32(0x1f); \
523 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
524 tcg_temp_free_i32(tmp3); \
525 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
526 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
527 tcg_temp_free_i32(tmp2); \
528 tcg_temp_free_i32(tmp1); \
534 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
537 tmp1
= tcg_temp_new_i32();
538 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
539 tmp2
= tcg_const_i32(0x1f);
540 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
541 tcg_temp_free_i32(tmp2
);
542 tcg_gen_sar_i32(dest
, t0
, tmp1
);
543 tcg_temp_free_i32(tmp1
);
546 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
548 TCGv_i32 c0
= tcg_const_i32(0);
549 TCGv_i32 tmp
= tcg_temp_new_i32();
550 tcg_gen_neg_i32(tmp
, src
);
551 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
552 tcg_temp_free_i32(c0
);
553 tcg_temp_free_i32(tmp
);
556 static void shifter_out_im(TCGv_i32 var
, int shift
)
559 tcg_gen_andi_i32(cpu_CF
, var
, 1);
561 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
563 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
568 /* Shift by immediate. Includes special handling for shift == 0. */
569 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
570 int shift
, int flags
)
576 shifter_out_im(var
, 32 - shift
);
577 tcg_gen_shli_i32(var
, var
, shift
);
583 tcg_gen_shri_i32(cpu_CF
, var
, 31);
585 tcg_gen_movi_i32(var
, 0);
588 shifter_out_im(var
, shift
- 1);
589 tcg_gen_shri_i32(var
, var
, shift
);
596 shifter_out_im(var
, shift
- 1);
599 tcg_gen_sari_i32(var
, var
, shift
);
601 case 3: /* ROR/RRX */
604 shifter_out_im(var
, shift
- 1);
605 tcg_gen_rotri_i32(var
, var
, shift
); break;
607 TCGv_i32 tmp
= tcg_temp_new_i32();
608 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
610 shifter_out_im(var
, 0);
611 tcg_gen_shri_i32(var
, var
, 1);
612 tcg_gen_or_i32(var
, var
, tmp
);
613 tcg_temp_free_i32(tmp
);
618 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
619 TCGv_i32 shift
, int flags
)
623 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
624 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
625 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
626 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
631 gen_shl(var
, var
, shift
);
634 gen_shr(var
, var
, shift
);
637 gen_sar(var
, var
, shift
);
639 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
640 tcg_gen_rotr_i32(var
, var
, shift
); break;
643 tcg_temp_free_i32(shift
);
646 #define PAS_OP(pfx) \
648 case 0: gen_pas_helper(glue(pfx,add16)); break; \
649 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
650 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
651 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
652 case 4: gen_pas_helper(glue(pfx,add8)); break; \
653 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
655 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
660 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
662 tmp
= tcg_temp_new_ptr();
663 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
665 tcg_temp_free_ptr(tmp
);
668 tmp
= tcg_temp_new_ptr();
669 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
671 tcg_temp_free_ptr(tmp
);
673 #undef gen_pas_helper
674 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
687 #undef gen_pas_helper
692 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
693 #define PAS_OP(pfx) \
695 case 0: gen_pas_helper(glue(pfx,add8)); break; \
696 case 1: gen_pas_helper(glue(pfx,add16)); break; \
697 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
698 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
699 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
700 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
702 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
707 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
709 tmp
= tcg_temp_new_ptr();
710 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
712 tcg_temp_free_ptr(tmp
);
715 tmp
= tcg_temp_new_ptr();
716 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
718 tcg_temp_free_ptr(tmp
);
720 #undef gen_pas_helper
721 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
734 #undef gen_pas_helper
740 * Generate a conditional based on ARM condition code cc.
741 * This is common between ARM and Aarch64 targets.
743 void arm_test_cc(DisasCompare
*cmp
, int cc
)
774 case 8: /* hi: C && !Z */
775 case 9: /* ls: !C || Z -> !(C && !Z) */
777 value
= tcg_temp_new_i32();
779 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
780 ZF is non-zero for !Z; so AND the two subexpressions. */
781 tcg_gen_neg_i32(value
, cpu_CF
);
782 tcg_gen_and_i32(value
, value
, cpu_ZF
);
785 case 10: /* ge: N == V -> N ^ V == 0 */
786 case 11: /* lt: N != V -> N ^ V != 0 */
787 /* Since we're only interested in the sign bit, == 0 is >= 0. */
789 value
= tcg_temp_new_i32();
791 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
794 case 12: /* gt: !Z && N == V */
795 case 13: /* le: Z || N != V */
797 value
= tcg_temp_new_i32();
799 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
800 * the sign bit then AND with ZF to yield the result. */
801 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
802 tcg_gen_sari_i32(value
, value
, 31);
803 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
806 case 14: /* always */
807 case 15: /* always */
808 /* Use the ALWAYS condition, which will fold early.
809 * It doesn't matter what we use for the value. */
810 cond
= TCG_COND_ALWAYS
;
815 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
820 cond
= tcg_invert_cond(cond
);
826 cmp
->value_global
= global
;
829 void arm_free_cc(DisasCompare
*cmp
)
831 if (!cmp
->value_global
) {
832 tcg_temp_free_i32(cmp
->value
);
836 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
838 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
841 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
844 arm_test_cc(&cmp
, cc
);
845 arm_jump_cc(&cmp
, label
);
849 static const uint8_t table_logic_cc
[16] = {
868 /* Set PC and Thumb state from an immediate address. */
869 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
873 s
->is_jmp
= DISAS_JUMP
;
874 if (s
->thumb
!= (addr
& 1)) {
875 tmp
= tcg_temp_new_i32();
876 tcg_gen_movi_i32(tmp
, addr
& 1);
877 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
878 tcg_temp_free_i32(tmp
);
880 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
883 /* Set PC and Thumb state from var. var is marked as dead. */
884 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
886 s
->is_jmp
= DISAS_JUMP
;
887 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
888 tcg_gen_andi_i32(var
, var
, 1);
889 store_cpu_field(var
, thumb
);
892 /* Variant of store_reg which uses branch&exchange logic when storing
893 to r15 in ARM architecture v7 and above. The source must be a temporary
894 and will be marked as dead. */
895 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
897 if (reg
== 15 && ENABLE_ARCH_7
) {
900 store_reg(s
, reg
, var
);
904 /* Variant of store_reg which uses branch&exchange logic when storing
905 * to r15 in ARM architecture v5T and above. This is used for storing
906 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
907 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
908 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
910 if (reg
== 15 && ENABLE_ARCH_5
) {
913 store_reg(s
, reg
, var
);
917 /* Abstractions of "generate code to do a guest load/store for
918 * AArch32", where a vaddr is always 32 bits (and is zero
919 * extended if we're a 64 bit core) and data is also
920 * 32 bits unless specifically doing a 64 bit access.
921 * These functions work like tcg_gen_qemu_{ld,st}* except
922 * that the address argument is TCGv_i32 rather than TCGv.
924 #if TARGET_LONG_BITS == 32
926 #define DO_GEN_LD(SUFF, OPC) \
927 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
929 tcg_gen_qemu_ld_i32(val, addr, index, (OPC)); \
932 #define DO_GEN_ST(SUFF, OPC) \
933 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
935 tcg_gen_qemu_st_i32(val, addr, index, (OPC)); \
938 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
940 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
943 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
945 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
950 #define DO_GEN_LD(SUFF, OPC) \
951 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
953 TCGv addr64 = tcg_temp_new(); \
954 tcg_gen_extu_i32_i64(addr64, addr); \
955 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
956 tcg_temp_free(addr64); \
959 #define DO_GEN_ST(SUFF, OPC) \
960 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
962 TCGv addr64 = tcg_temp_new(); \
963 tcg_gen_extu_i32_i64(addr64, addr); \
964 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
965 tcg_temp_free(addr64); \
968 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
970 TCGv addr64
= tcg_temp_new();
971 tcg_gen_extu_i32_i64(addr64
, addr
);
972 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
973 tcg_temp_free(addr64
);
976 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
978 TCGv addr64
= tcg_temp_new();
979 tcg_gen_extu_i32_i64(addr64
, addr
);
980 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
981 tcg_temp_free(addr64
);
988 DO_GEN_LD(16s
, MO_TESW
)
989 DO_GEN_LD(16u, MO_TEUW
)
990 DO_GEN_LD(32u, MO_TEUL
)
991 /* 'a' variants include an alignment check */
992 DO_GEN_LD(16ua
, MO_TEUW
| MO_ALIGN
)
993 DO_GEN_LD(32ua
, MO_TEUL
| MO_ALIGN
)
995 DO_GEN_ST(16, MO_TEUW
)
996 DO_GEN_ST(32, MO_TEUL
)
998 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
1000 tcg_gen_movi_i32(cpu_R
[15], val
);
1003 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1005 /* The pre HVC helper handles cases when HVC gets trapped
1006 * as an undefined insn by runtime configuration (ie before
1007 * the insn really executes).
1009 gen_set_pc_im(s
, s
->pc
- 4);
1010 gen_helper_pre_hvc(cpu_env
);
1011 /* Otherwise we will treat this as a real exception which
1012 * happens after execution of the insn. (The distinction matters
1013 * for the PC value reported to the exception handler and also
1014 * for single stepping.)
1017 gen_set_pc_im(s
, s
->pc
);
1018 s
->is_jmp
= DISAS_HVC
;
1021 static inline void gen_smc(DisasContext
*s
)
1023 /* As with HVC, we may take an exception either before or after
1024 * the insn executes.
1028 gen_set_pc_im(s
, s
->pc
- 4);
1029 tmp
= tcg_const_i32(syn_aa32_smc());
1030 gen_helper_pre_smc(cpu_env
, tmp
);
1031 tcg_temp_free_i32(tmp
);
1032 gen_set_pc_im(s
, s
->pc
);
1033 s
->is_jmp
= DISAS_SMC
;
1037 gen_set_condexec (DisasContext
*s
)
1039 if (s
->condexec_mask
) {
1040 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1041 TCGv_i32 tmp
= tcg_temp_new_i32();
1042 tcg_gen_movi_i32(tmp
, val
);
1043 store_cpu_field(tmp
, condexec_bits
);
1047 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1049 gen_set_condexec(s
);
1050 gen_set_pc_im(s
, s
->pc
- offset
);
1051 gen_exception_internal(excp
);
1052 s
->is_jmp
= DISAS_JUMP
;
1055 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1056 int syn
, uint32_t target_el
)
1058 gen_set_condexec(s
);
1059 gen_set_pc_im(s
, s
->pc
- offset
);
1060 gen_exception(excp
, syn
, target_el
);
1061 s
->is_jmp
= DISAS_JUMP
;
1064 /* Force a TB lookup after an instruction that changes the CPU state. */
1065 static inline void gen_lookup_tb(DisasContext
*s
)
1067 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1068 s
->is_jmp
= DISAS_JUMP
;
1071 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1074 int val
, rm
, shift
, shiftop
;
1077 if (!(insn
& (1 << 25))) {
1080 if (!(insn
& (1 << 23)))
1083 tcg_gen_addi_i32(var
, var
, val
);
1085 /* shift/register */
1087 shift
= (insn
>> 7) & 0x1f;
1088 shiftop
= (insn
>> 5) & 3;
1089 offset
= load_reg(s
, rm
);
1090 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1091 if (!(insn
& (1 << 23)))
1092 tcg_gen_sub_i32(var
, var
, offset
);
1094 tcg_gen_add_i32(var
, var
, offset
);
1095 tcg_temp_free_i32(offset
);
1099 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1100 int extra
, TCGv_i32 var
)
1105 if (insn
& (1 << 22)) {
1107 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1108 if (!(insn
& (1 << 23)))
1112 tcg_gen_addi_i32(var
, var
, val
);
1116 tcg_gen_addi_i32(var
, var
, extra
);
1118 offset
= load_reg(s
, rm
);
1119 if (!(insn
& (1 << 23)))
1120 tcg_gen_sub_i32(var
, var
, offset
);
1122 tcg_gen_add_i32(var
, var
, offset
);
1123 tcg_temp_free_i32(offset
);
1127 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1129 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1132 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1134 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1136 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1140 #define VFP_OP2(name) \
1141 static inline void gen_vfp_##name(int dp) \
1143 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1145 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1147 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1149 tcg_temp_free_ptr(fpst); \
1159 static inline void gen_vfp_F1_mul(int dp
)
1161 /* Like gen_vfp_mul() but put result in F1 */
1162 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1164 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1166 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1168 tcg_temp_free_ptr(fpst
);
1171 static inline void gen_vfp_F1_neg(int dp
)
1173 /* Like gen_vfp_neg() but put result in F1 */
1175 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1177 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1181 static inline void gen_vfp_abs(int dp
)
1184 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1186 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1189 static inline void gen_vfp_neg(int dp
)
1192 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1194 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1197 static inline void gen_vfp_sqrt(int dp
)
1200 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1202 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1205 static inline void gen_vfp_cmp(int dp
)
1208 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1210 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1213 static inline void gen_vfp_cmpe(int dp
)
1216 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1218 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1221 static inline void gen_vfp_F1_ld0(int dp
)
1224 tcg_gen_movi_i64(cpu_F1d
, 0);
1226 tcg_gen_movi_i32(cpu_F1s
, 0);
1229 #define VFP_GEN_ITOF(name) \
1230 static inline void gen_vfp_##name(int dp, int neon) \
1232 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1234 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1236 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1238 tcg_temp_free_ptr(statusptr); \
1245 #define VFP_GEN_FTOI(name) \
1246 static inline void gen_vfp_##name(int dp, int neon) \
1248 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1250 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1252 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1254 tcg_temp_free_ptr(statusptr); \
1263 #define VFP_GEN_FIX(name, round) \
1264 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1266 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1267 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1269 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1272 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1275 tcg_temp_free_i32(tmp_shift); \
1276 tcg_temp_free_ptr(statusptr); \
1278 VFP_GEN_FIX(tosh
, _round_to_zero
)
1279 VFP_GEN_FIX(tosl
, _round_to_zero
)
1280 VFP_GEN_FIX(touh
, _round_to_zero
)
1281 VFP_GEN_FIX(toul
, _round_to_zero
)
1288 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1291 gen_aa32_ld64(cpu_F0d
, addr
, get_mem_index(s
));
1293 gen_aa32_ld32u(cpu_F0s
, addr
, get_mem_index(s
));
1297 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1300 gen_aa32_st64(cpu_F0d
, addr
, get_mem_index(s
));
1302 gen_aa32_st32(cpu_F0s
, addr
, get_mem_index(s
));
1307 vfp_reg_offset (int dp
, int reg
)
1310 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1312 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1313 + offsetof(CPU_DoubleU
, l
.upper
);
1315 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1316 + offsetof(CPU_DoubleU
, l
.lower
);
1320 /* Return the offset of a 32-bit piece of a NEON register.
1321 zero is the least significant end of the register. */
1323 neon_reg_offset (int reg
, int n
)
1327 return vfp_reg_offset(0, sreg
);
1330 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1332 TCGv_i32 tmp
= tcg_temp_new_i32();
1333 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1337 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1339 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1340 tcg_temp_free_i32(var
);
1343 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1345 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1348 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1350 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1353 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1354 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1355 #define tcg_gen_st_f32 tcg_gen_st_i32
1356 #define tcg_gen_st_f64 tcg_gen_st_i64
1358 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1361 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1363 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1366 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1369 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1371 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1374 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1377 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1379 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1382 #define ARM_CP_RW_BIT (1 << 20)
1384 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1386 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1389 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1391 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1394 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1396 TCGv_i32 var
= tcg_temp_new_i32();
1397 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1401 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1403 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1404 tcg_temp_free_i32(var
);
1407 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1409 iwmmxt_store_reg(cpu_M0
, rn
);
1412 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1414 iwmmxt_load_reg(cpu_M0
, rn
);
1417 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1419 iwmmxt_load_reg(cpu_V1
, rn
);
1420 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1423 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1425 iwmmxt_load_reg(cpu_V1
, rn
);
1426 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1429 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1431 iwmmxt_load_reg(cpu_V1
, rn
);
1432 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1435 #define IWMMXT_OP(name) \
1436 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1438 iwmmxt_load_reg(cpu_V1, rn); \
1439 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1442 #define IWMMXT_OP_ENV(name) \
1443 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1445 iwmmxt_load_reg(cpu_V1, rn); \
1446 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1449 #define IWMMXT_OP_ENV_SIZE(name) \
1450 IWMMXT_OP_ENV(name##b) \
1451 IWMMXT_OP_ENV(name##w) \
1452 IWMMXT_OP_ENV(name##l)
1454 #define IWMMXT_OP_ENV1(name) \
1455 static inline void gen_op_iwmmxt_##name##_M0(void) \
1457 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1471 IWMMXT_OP_ENV_SIZE(unpackl
)
1472 IWMMXT_OP_ENV_SIZE(unpackh
)
1474 IWMMXT_OP_ENV1(unpacklub
)
1475 IWMMXT_OP_ENV1(unpackluw
)
1476 IWMMXT_OP_ENV1(unpacklul
)
1477 IWMMXT_OP_ENV1(unpackhub
)
1478 IWMMXT_OP_ENV1(unpackhuw
)
1479 IWMMXT_OP_ENV1(unpackhul
)
1480 IWMMXT_OP_ENV1(unpacklsb
)
1481 IWMMXT_OP_ENV1(unpacklsw
)
1482 IWMMXT_OP_ENV1(unpacklsl
)
1483 IWMMXT_OP_ENV1(unpackhsb
)
1484 IWMMXT_OP_ENV1(unpackhsw
)
1485 IWMMXT_OP_ENV1(unpackhsl
)
1487 IWMMXT_OP_ENV_SIZE(cmpeq
)
1488 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1489 IWMMXT_OP_ENV_SIZE(cmpgts
)
1491 IWMMXT_OP_ENV_SIZE(mins
)
1492 IWMMXT_OP_ENV_SIZE(minu
)
1493 IWMMXT_OP_ENV_SIZE(maxs
)
1494 IWMMXT_OP_ENV_SIZE(maxu
)
1496 IWMMXT_OP_ENV_SIZE(subn
)
1497 IWMMXT_OP_ENV_SIZE(addn
)
1498 IWMMXT_OP_ENV_SIZE(subu
)
1499 IWMMXT_OP_ENV_SIZE(addu
)
1500 IWMMXT_OP_ENV_SIZE(subs
)
1501 IWMMXT_OP_ENV_SIZE(adds
)
1503 IWMMXT_OP_ENV(avgb0
)
1504 IWMMXT_OP_ENV(avgb1
)
1505 IWMMXT_OP_ENV(avgw0
)
1506 IWMMXT_OP_ENV(avgw1
)
1508 IWMMXT_OP_ENV(packuw
)
1509 IWMMXT_OP_ENV(packul
)
1510 IWMMXT_OP_ENV(packuq
)
1511 IWMMXT_OP_ENV(packsw
)
1512 IWMMXT_OP_ENV(packsl
)
1513 IWMMXT_OP_ENV(packsq
)
1515 static void gen_op_iwmmxt_set_mup(void)
1518 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1519 tcg_gen_ori_i32(tmp
, tmp
, 2);
1520 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1523 static void gen_op_iwmmxt_set_cup(void)
1526 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1527 tcg_gen_ori_i32(tmp
, tmp
, 1);
1528 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1531 static void gen_op_iwmmxt_setpsr_nz(void)
1533 TCGv_i32 tmp
= tcg_temp_new_i32();
1534 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1535 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1538 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1540 iwmmxt_load_reg(cpu_V1
, rn
);
1541 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1542 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1545 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1552 rd
= (insn
>> 16) & 0xf;
1553 tmp
= load_reg(s
, rd
);
1555 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1556 if (insn
& (1 << 24)) {
1558 if (insn
& (1 << 23))
1559 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1561 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1562 tcg_gen_mov_i32(dest
, tmp
);
1563 if (insn
& (1 << 21))
1564 store_reg(s
, rd
, tmp
);
1566 tcg_temp_free_i32(tmp
);
1567 } else if (insn
& (1 << 21)) {
1569 tcg_gen_mov_i32(dest
, tmp
);
1570 if (insn
& (1 << 23))
1571 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1573 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1574 store_reg(s
, rd
, tmp
);
1575 } else if (!(insn
& (1 << 23)))
1580 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1582 int rd
= (insn
>> 0) & 0xf;
1585 if (insn
& (1 << 8)) {
1586 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1589 tmp
= iwmmxt_load_creg(rd
);
1592 tmp
= tcg_temp_new_i32();
1593 iwmmxt_load_reg(cpu_V0
, rd
);
1594 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1596 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1597 tcg_gen_mov_i32(dest
, tmp
);
1598 tcg_temp_free_i32(tmp
);
1602 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1603 (ie. an undefined instruction). */
1604 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1607 int rdhi
, rdlo
, rd0
, rd1
, i
;
1609 TCGv_i32 tmp
, tmp2
, tmp3
;
1611 if ((insn
& 0x0e000e00) == 0x0c000000) {
1612 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1614 rdlo
= (insn
>> 12) & 0xf;
1615 rdhi
= (insn
>> 16) & 0xf;
1616 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1617 iwmmxt_load_reg(cpu_V0
, wrd
);
1618 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1619 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1620 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1621 } else { /* TMCRR */
1622 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1623 iwmmxt_store_reg(cpu_V0
, wrd
);
1624 gen_op_iwmmxt_set_mup();
1629 wrd
= (insn
>> 12) & 0xf;
1630 addr
= tcg_temp_new_i32();
1631 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1632 tcg_temp_free_i32(addr
);
1635 if (insn
& ARM_CP_RW_BIT
) {
1636 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1637 tmp
= tcg_temp_new_i32();
1638 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1639 iwmmxt_store_creg(wrd
, tmp
);
1642 if (insn
& (1 << 8)) {
1643 if (insn
& (1 << 22)) { /* WLDRD */
1644 gen_aa32_ld64(cpu_M0
, addr
, get_mem_index(s
));
1646 } else { /* WLDRW wRd */
1647 tmp
= tcg_temp_new_i32();
1648 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1651 tmp
= tcg_temp_new_i32();
1652 if (insn
& (1 << 22)) { /* WLDRH */
1653 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
1654 } else { /* WLDRB */
1655 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
1659 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1660 tcg_temp_free_i32(tmp
);
1662 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1665 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1666 tmp
= iwmmxt_load_creg(wrd
);
1667 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1669 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1670 tmp
= tcg_temp_new_i32();
1671 if (insn
& (1 << 8)) {
1672 if (insn
& (1 << 22)) { /* WSTRD */
1673 gen_aa32_st64(cpu_M0
, addr
, get_mem_index(s
));
1674 } else { /* WSTRW wRd */
1675 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1676 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1679 if (insn
& (1 << 22)) { /* WSTRH */
1680 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1681 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
1682 } else { /* WSTRB */
1683 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1684 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
1688 tcg_temp_free_i32(tmp
);
1690 tcg_temp_free_i32(addr
);
1694 if ((insn
& 0x0f000000) != 0x0e000000)
1697 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1698 case 0x000: /* WOR */
1699 wrd
= (insn
>> 12) & 0xf;
1700 rd0
= (insn
>> 0) & 0xf;
1701 rd1
= (insn
>> 16) & 0xf;
1702 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1703 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1704 gen_op_iwmmxt_setpsr_nz();
1705 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1706 gen_op_iwmmxt_set_mup();
1707 gen_op_iwmmxt_set_cup();
1709 case 0x011: /* TMCR */
1712 rd
= (insn
>> 12) & 0xf;
1713 wrd
= (insn
>> 16) & 0xf;
1715 case ARM_IWMMXT_wCID
:
1716 case ARM_IWMMXT_wCASF
:
1718 case ARM_IWMMXT_wCon
:
1719 gen_op_iwmmxt_set_cup();
1721 case ARM_IWMMXT_wCSSF
:
1722 tmp
= iwmmxt_load_creg(wrd
);
1723 tmp2
= load_reg(s
, rd
);
1724 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1725 tcg_temp_free_i32(tmp2
);
1726 iwmmxt_store_creg(wrd
, tmp
);
1728 case ARM_IWMMXT_wCGR0
:
1729 case ARM_IWMMXT_wCGR1
:
1730 case ARM_IWMMXT_wCGR2
:
1731 case ARM_IWMMXT_wCGR3
:
1732 gen_op_iwmmxt_set_cup();
1733 tmp
= load_reg(s
, rd
);
1734 iwmmxt_store_creg(wrd
, tmp
);
1740 case 0x100: /* WXOR */
1741 wrd
= (insn
>> 12) & 0xf;
1742 rd0
= (insn
>> 0) & 0xf;
1743 rd1
= (insn
>> 16) & 0xf;
1744 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1745 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1746 gen_op_iwmmxt_setpsr_nz();
1747 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1748 gen_op_iwmmxt_set_mup();
1749 gen_op_iwmmxt_set_cup();
1751 case 0x111: /* TMRC */
1754 rd
= (insn
>> 12) & 0xf;
1755 wrd
= (insn
>> 16) & 0xf;
1756 tmp
= iwmmxt_load_creg(wrd
);
1757 store_reg(s
, rd
, tmp
);
1759 case 0x300: /* WANDN */
1760 wrd
= (insn
>> 12) & 0xf;
1761 rd0
= (insn
>> 0) & 0xf;
1762 rd1
= (insn
>> 16) & 0xf;
1763 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1764 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1765 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1766 gen_op_iwmmxt_setpsr_nz();
1767 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1768 gen_op_iwmmxt_set_mup();
1769 gen_op_iwmmxt_set_cup();
1771 case 0x200: /* WAND */
1772 wrd
= (insn
>> 12) & 0xf;
1773 rd0
= (insn
>> 0) & 0xf;
1774 rd1
= (insn
>> 16) & 0xf;
1775 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1776 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1777 gen_op_iwmmxt_setpsr_nz();
1778 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1779 gen_op_iwmmxt_set_mup();
1780 gen_op_iwmmxt_set_cup();
1782 case 0x810: case 0xa10: /* WMADD */
1783 wrd
= (insn
>> 12) & 0xf;
1784 rd0
= (insn
>> 0) & 0xf;
1785 rd1
= (insn
>> 16) & 0xf;
1786 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1787 if (insn
& (1 << 21))
1788 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1790 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1791 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1792 gen_op_iwmmxt_set_mup();
1794 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1795 wrd
= (insn
>> 12) & 0xf;
1796 rd0
= (insn
>> 16) & 0xf;
1797 rd1
= (insn
>> 0) & 0xf;
1798 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1799 switch ((insn
>> 22) & 3) {
1801 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1804 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1807 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1812 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1813 gen_op_iwmmxt_set_mup();
1814 gen_op_iwmmxt_set_cup();
1816 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1817 wrd
= (insn
>> 12) & 0xf;
1818 rd0
= (insn
>> 16) & 0xf;
1819 rd1
= (insn
>> 0) & 0xf;
1820 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1821 switch ((insn
>> 22) & 3) {
1823 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1826 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1829 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1834 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1835 gen_op_iwmmxt_set_mup();
1836 gen_op_iwmmxt_set_cup();
1838 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1839 wrd
= (insn
>> 12) & 0xf;
1840 rd0
= (insn
>> 16) & 0xf;
1841 rd1
= (insn
>> 0) & 0xf;
1842 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1843 if (insn
& (1 << 22))
1844 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1846 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1847 if (!(insn
& (1 << 20)))
1848 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1849 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1850 gen_op_iwmmxt_set_mup();
1852 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1853 wrd
= (insn
>> 12) & 0xf;
1854 rd0
= (insn
>> 16) & 0xf;
1855 rd1
= (insn
>> 0) & 0xf;
1856 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1857 if (insn
& (1 << 21)) {
1858 if (insn
& (1 << 20))
1859 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1861 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1863 if (insn
& (1 << 20))
1864 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1866 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1868 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1869 gen_op_iwmmxt_set_mup();
1871 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1872 wrd
= (insn
>> 12) & 0xf;
1873 rd0
= (insn
>> 16) & 0xf;
1874 rd1
= (insn
>> 0) & 0xf;
1875 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1876 if (insn
& (1 << 21))
1877 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1879 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1880 if (!(insn
& (1 << 20))) {
1881 iwmmxt_load_reg(cpu_V1
, wrd
);
1882 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1884 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1885 gen_op_iwmmxt_set_mup();
1887 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1888 wrd
= (insn
>> 12) & 0xf;
1889 rd0
= (insn
>> 16) & 0xf;
1890 rd1
= (insn
>> 0) & 0xf;
1891 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1892 switch ((insn
>> 22) & 3) {
1894 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1897 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1900 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1905 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1906 gen_op_iwmmxt_set_mup();
1907 gen_op_iwmmxt_set_cup();
1909 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1910 wrd
= (insn
>> 12) & 0xf;
1911 rd0
= (insn
>> 16) & 0xf;
1912 rd1
= (insn
>> 0) & 0xf;
1913 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1914 if (insn
& (1 << 22)) {
1915 if (insn
& (1 << 20))
1916 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1918 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1920 if (insn
& (1 << 20))
1921 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1923 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1925 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1926 gen_op_iwmmxt_set_mup();
1927 gen_op_iwmmxt_set_cup();
1929 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1930 wrd
= (insn
>> 12) & 0xf;
1931 rd0
= (insn
>> 16) & 0xf;
1932 rd1
= (insn
>> 0) & 0xf;
1933 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1934 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1935 tcg_gen_andi_i32(tmp
, tmp
, 7);
1936 iwmmxt_load_reg(cpu_V1
, rd1
);
1937 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1938 tcg_temp_free_i32(tmp
);
1939 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1940 gen_op_iwmmxt_set_mup();
1942 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1943 if (((insn
>> 6) & 3) == 3)
1945 rd
= (insn
>> 12) & 0xf;
1946 wrd
= (insn
>> 16) & 0xf;
1947 tmp
= load_reg(s
, rd
);
1948 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1949 switch ((insn
>> 6) & 3) {
1951 tmp2
= tcg_const_i32(0xff);
1952 tmp3
= tcg_const_i32((insn
& 7) << 3);
1955 tmp2
= tcg_const_i32(0xffff);
1956 tmp3
= tcg_const_i32((insn
& 3) << 4);
1959 tmp2
= tcg_const_i32(0xffffffff);
1960 tmp3
= tcg_const_i32((insn
& 1) << 5);
1963 TCGV_UNUSED_I32(tmp2
);
1964 TCGV_UNUSED_I32(tmp3
);
1966 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1967 tcg_temp_free_i32(tmp3
);
1968 tcg_temp_free_i32(tmp2
);
1969 tcg_temp_free_i32(tmp
);
1970 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1971 gen_op_iwmmxt_set_mup();
1973 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1974 rd
= (insn
>> 12) & 0xf;
1975 wrd
= (insn
>> 16) & 0xf;
1976 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1978 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1979 tmp
= tcg_temp_new_i32();
1980 switch ((insn
>> 22) & 3) {
1982 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1983 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1985 tcg_gen_ext8s_i32(tmp
, tmp
);
1987 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1991 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1992 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1994 tcg_gen_ext16s_i32(tmp
, tmp
);
1996 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2000 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2001 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2004 store_reg(s
, rd
, tmp
);
2006 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2007 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2009 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2010 switch ((insn
>> 22) & 3) {
2012 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2015 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2018 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2021 tcg_gen_shli_i32(tmp
, tmp
, 28);
2023 tcg_temp_free_i32(tmp
);
2025 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2026 if (((insn
>> 6) & 3) == 3)
2028 rd
= (insn
>> 12) & 0xf;
2029 wrd
= (insn
>> 16) & 0xf;
2030 tmp
= load_reg(s
, rd
);
2031 switch ((insn
>> 6) & 3) {
2033 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2036 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2039 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2042 tcg_temp_free_i32(tmp
);
2043 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2044 gen_op_iwmmxt_set_mup();
2046 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2047 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2049 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2050 tmp2
= tcg_temp_new_i32();
2051 tcg_gen_mov_i32(tmp2
, tmp
);
2052 switch ((insn
>> 22) & 3) {
2054 for (i
= 0; i
< 7; i
++) {
2055 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2056 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2060 for (i
= 0; i
< 3; i
++) {
2061 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2062 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2066 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2067 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2071 tcg_temp_free_i32(tmp2
);
2072 tcg_temp_free_i32(tmp
);
2074 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2075 wrd
= (insn
>> 12) & 0xf;
2076 rd0
= (insn
>> 16) & 0xf;
2077 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2078 switch ((insn
>> 22) & 3) {
2080 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2083 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2086 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2091 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2092 gen_op_iwmmxt_set_mup();
2094 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2095 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2097 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2098 tmp2
= tcg_temp_new_i32();
2099 tcg_gen_mov_i32(tmp2
, tmp
);
2100 switch ((insn
>> 22) & 3) {
2102 for (i
= 0; i
< 7; i
++) {
2103 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2104 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2108 for (i
= 0; i
< 3; i
++) {
2109 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2110 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2114 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2115 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2119 tcg_temp_free_i32(tmp2
);
2120 tcg_temp_free_i32(tmp
);
2122 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2123 rd
= (insn
>> 12) & 0xf;
2124 rd0
= (insn
>> 16) & 0xf;
2125 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2127 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2128 tmp
= tcg_temp_new_i32();
2129 switch ((insn
>> 22) & 3) {
2131 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2134 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2137 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2140 store_reg(s
, rd
, tmp
);
2142 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2143 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2144 wrd
= (insn
>> 12) & 0xf;
2145 rd0
= (insn
>> 16) & 0xf;
2146 rd1
= (insn
>> 0) & 0xf;
2147 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2148 switch ((insn
>> 22) & 3) {
2150 if (insn
& (1 << 21))
2151 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2153 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2156 if (insn
& (1 << 21))
2157 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2159 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2162 if (insn
& (1 << 21))
2163 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2165 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2170 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2171 gen_op_iwmmxt_set_mup();
2172 gen_op_iwmmxt_set_cup();
2174 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2175 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2176 wrd
= (insn
>> 12) & 0xf;
2177 rd0
= (insn
>> 16) & 0xf;
2178 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2179 switch ((insn
>> 22) & 3) {
2181 if (insn
& (1 << 21))
2182 gen_op_iwmmxt_unpacklsb_M0();
2184 gen_op_iwmmxt_unpacklub_M0();
2187 if (insn
& (1 << 21))
2188 gen_op_iwmmxt_unpacklsw_M0();
2190 gen_op_iwmmxt_unpackluw_M0();
2193 if (insn
& (1 << 21))
2194 gen_op_iwmmxt_unpacklsl_M0();
2196 gen_op_iwmmxt_unpacklul_M0();
2201 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2202 gen_op_iwmmxt_set_mup();
2203 gen_op_iwmmxt_set_cup();
2205 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2206 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2207 wrd
= (insn
>> 12) & 0xf;
2208 rd0
= (insn
>> 16) & 0xf;
2209 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2210 switch ((insn
>> 22) & 3) {
2212 if (insn
& (1 << 21))
2213 gen_op_iwmmxt_unpackhsb_M0();
2215 gen_op_iwmmxt_unpackhub_M0();
2218 if (insn
& (1 << 21))
2219 gen_op_iwmmxt_unpackhsw_M0();
2221 gen_op_iwmmxt_unpackhuw_M0();
2224 if (insn
& (1 << 21))
2225 gen_op_iwmmxt_unpackhsl_M0();
2227 gen_op_iwmmxt_unpackhul_M0();
2232 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2233 gen_op_iwmmxt_set_mup();
2234 gen_op_iwmmxt_set_cup();
2236 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2237 case 0x214: case 0x614: case 0xa14: case 0xe14:
2238 if (((insn
>> 22) & 3) == 0)
2240 wrd
= (insn
>> 12) & 0xf;
2241 rd0
= (insn
>> 16) & 0xf;
2242 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2243 tmp
= tcg_temp_new_i32();
2244 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2245 tcg_temp_free_i32(tmp
);
2248 switch ((insn
>> 22) & 3) {
2250 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2253 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2256 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2259 tcg_temp_free_i32(tmp
);
2260 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2261 gen_op_iwmmxt_set_mup();
2262 gen_op_iwmmxt_set_cup();
2264 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2265 case 0x014: case 0x414: case 0x814: case 0xc14:
2266 if (((insn
>> 22) & 3) == 0)
2268 wrd
= (insn
>> 12) & 0xf;
2269 rd0
= (insn
>> 16) & 0xf;
2270 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2271 tmp
= tcg_temp_new_i32();
2272 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2273 tcg_temp_free_i32(tmp
);
2276 switch ((insn
>> 22) & 3) {
2278 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2281 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2284 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2287 tcg_temp_free_i32(tmp
);
2288 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2289 gen_op_iwmmxt_set_mup();
2290 gen_op_iwmmxt_set_cup();
2292 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2293 case 0x114: case 0x514: case 0x914: case 0xd14:
2294 if (((insn
>> 22) & 3) == 0)
2296 wrd
= (insn
>> 12) & 0xf;
2297 rd0
= (insn
>> 16) & 0xf;
2298 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2299 tmp
= tcg_temp_new_i32();
2300 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2301 tcg_temp_free_i32(tmp
);
2304 switch ((insn
>> 22) & 3) {
2306 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2309 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2312 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2315 tcg_temp_free_i32(tmp
);
2316 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2317 gen_op_iwmmxt_set_mup();
2318 gen_op_iwmmxt_set_cup();
2320 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2321 case 0x314: case 0x714: case 0xb14: case 0xf14:
2322 if (((insn
>> 22) & 3) == 0)
2324 wrd
= (insn
>> 12) & 0xf;
2325 rd0
= (insn
>> 16) & 0xf;
2326 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2327 tmp
= tcg_temp_new_i32();
2328 switch ((insn
>> 22) & 3) {
2330 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2331 tcg_temp_free_i32(tmp
);
2334 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2337 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2338 tcg_temp_free_i32(tmp
);
2341 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2344 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2345 tcg_temp_free_i32(tmp
);
2348 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2351 tcg_temp_free_i32(tmp
);
2352 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2353 gen_op_iwmmxt_set_mup();
2354 gen_op_iwmmxt_set_cup();
2356 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2357 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2358 wrd
= (insn
>> 12) & 0xf;
2359 rd0
= (insn
>> 16) & 0xf;
2360 rd1
= (insn
>> 0) & 0xf;
2361 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2362 switch ((insn
>> 22) & 3) {
2364 if (insn
& (1 << 21))
2365 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2367 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2370 if (insn
& (1 << 21))
2371 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2373 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2376 if (insn
& (1 << 21))
2377 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2379 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2384 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2385 gen_op_iwmmxt_set_mup();
2387 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2388 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2389 wrd
= (insn
>> 12) & 0xf;
2390 rd0
= (insn
>> 16) & 0xf;
2391 rd1
= (insn
>> 0) & 0xf;
2392 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2393 switch ((insn
>> 22) & 3) {
2395 if (insn
& (1 << 21))
2396 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2398 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2401 if (insn
& (1 << 21))
2402 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2404 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2407 if (insn
& (1 << 21))
2408 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2410 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2415 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2416 gen_op_iwmmxt_set_mup();
2418 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2419 case 0x402: case 0x502: case 0x602: case 0x702:
2420 wrd
= (insn
>> 12) & 0xf;
2421 rd0
= (insn
>> 16) & 0xf;
2422 rd1
= (insn
>> 0) & 0xf;
2423 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2424 tmp
= tcg_const_i32((insn
>> 20) & 3);
2425 iwmmxt_load_reg(cpu_V1
, rd1
);
2426 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2427 tcg_temp_free_i32(tmp
);
2428 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2429 gen_op_iwmmxt_set_mup();
2431 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2432 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2433 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2434 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2435 wrd
= (insn
>> 12) & 0xf;
2436 rd0
= (insn
>> 16) & 0xf;
2437 rd1
= (insn
>> 0) & 0xf;
2438 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2439 switch ((insn
>> 20) & 0xf) {
2441 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2444 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2447 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2450 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2453 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2456 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2459 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2462 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2465 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2470 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2471 gen_op_iwmmxt_set_mup();
2472 gen_op_iwmmxt_set_cup();
2474 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2475 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2476 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2477 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2478 wrd
= (insn
>> 12) & 0xf;
2479 rd0
= (insn
>> 16) & 0xf;
2480 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2481 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2482 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2483 tcg_temp_free_i32(tmp
);
2484 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2485 gen_op_iwmmxt_set_mup();
2486 gen_op_iwmmxt_set_cup();
2488 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2489 case 0x418: case 0x518: case 0x618: case 0x718:
2490 case 0x818: case 0x918: case 0xa18: case 0xb18:
2491 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2492 wrd
= (insn
>> 12) & 0xf;
2493 rd0
= (insn
>> 16) & 0xf;
2494 rd1
= (insn
>> 0) & 0xf;
2495 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2496 switch ((insn
>> 20) & 0xf) {
2498 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2501 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2504 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2507 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2510 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2513 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2516 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2519 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2522 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2527 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2528 gen_op_iwmmxt_set_mup();
2529 gen_op_iwmmxt_set_cup();
2531 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2532 case 0x408: case 0x508: case 0x608: case 0x708:
2533 case 0x808: case 0x908: case 0xa08: case 0xb08:
2534 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2535 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2537 wrd
= (insn
>> 12) & 0xf;
2538 rd0
= (insn
>> 16) & 0xf;
2539 rd1
= (insn
>> 0) & 0xf;
2540 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2541 switch ((insn
>> 22) & 3) {
2543 if (insn
& (1 << 21))
2544 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2546 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2549 if (insn
& (1 << 21))
2550 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2552 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2555 if (insn
& (1 << 21))
2556 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2558 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2561 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2562 gen_op_iwmmxt_set_mup();
2563 gen_op_iwmmxt_set_cup();
2565 case 0x201: case 0x203: case 0x205: case 0x207:
2566 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2567 case 0x211: case 0x213: case 0x215: case 0x217:
2568 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2569 wrd
= (insn
>> 5) & 0xf;
2570 rd0
= (insn
>> 12) & 0xf;
2571 rd1
= (insn
>> 0) & 0xf;
2572 if (rd0
== 0xf || rd1
== 0xf)
2574 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2575 tmp
= load_reg(s
, rd0
);
2576 tmp2
= load_reg(s
, rd1
);
2577 switch ((insn
>> 16) & 0xf) {
2578 case 0x0: /* TMIA */
2579 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2581 case 0x8: /* TMIAPH */
2582 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2584 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2585 if (insn
& (1 << 16))
2586 tcg_gen_shri_i32(tmp
, tmp
, 16);
2587 if (insn
& (1 << 17))
2588 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2589 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2592 tcg_temp_free_i32(tmp2
);
2593 tcg_temp_free_i32(tmp
);
2596 tcg_temp_free_i32(tmp2
);
2597 tcg_temp_free_i32(tmp
);
2598 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2599 gen_op_iwmmxt_set_mup();
2608 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2609 (ie. an undefined instruction). */
2610 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2612 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2615 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2616 /* Multiply with Internal Accumulate Format */
2617 rd0
= (insn
>> 12) & 0xf;
2619 acc
= (insn
>> 5) & 7;
2624 tmp
= load_reg(s
, rd0
);
2625 tmp2
= load_reg(s
, rd1
);
2626 switch ((insn
>> 16) & 0xf) {
2628 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2630 case 0x8: /* MIAPH */
2631 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2633 case 0xc: /* MIABB */
2634 case 0xd: /* MIABT */
2635 case 0xe: /* MIATB */
2636 case 0xf: /* MIATT */
2637 if (insn
& (1 << 16))
2638 tcg_gen_shri_i32(tmp
, tmp
, 16);
2639 if (insn
& (1 << 17))
2640 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2641 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2646 tcg_temp_free_i32(tmp2
);
2647 tcg_temp_free_i32(tmp
);
2649 gen_op_iwmmxt_movq_wRn_M0(acc
);
2653 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2654 /* Internal Accumulator Access Format */
2655 rdhi
= (insn
>> 16) & 0xf;
2656 rdlo
= (insn
>> 12) & 0xf;
2662 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2663 iwmmxt_load_reg(cpu_V0
, acc
);
2664 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2665 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2666 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2667 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2669 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2670 iwmmxt_store_reg(cpu_V0
, acc
);
2678 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2679 #define VFP_SREG(insn, bigbit, smallbit) \
2680 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2681 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2682 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2683 reg = (((insn) >> (bigbit)) & 0x0f) \
2684 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2686 if (insn & (1 << (smallbit))) \
2688 reg = ((insn) >> (bigbit)) & 0x0f; \
2691 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2692 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2693 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2694 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2695 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2696 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2698 /* Move between integer and VFP cores. */
2699 static TCGv_i32
gen_vfp_mrs(void)
2701 TCGv_i32 tmp
= tcg_temp_new_i32();
2702 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2706 static void gen_vfp_msr(TCGv_i32 tmp
)
2708 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2709 tcg_temp_free_i32(tmp
);
2712 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2714 TCGv_i32 tmp
= tcg_temp_new_i32();
2716 tcg_gen_shri_i32(var
, var
, shift
);
2717 tcg_gen_ext8u_i32(var
, var
);
2718 tcg_gen_shli_i32(tmp
, var
, 8);
2719 tcg_gen_or_i32(var
, var
, tmp
);
2720 tcg_gen_shli_i32(tmp
, var
, 16);
2721 tcg_gen_or_i32(var
, var
, tmp
);
2722 tcg_temp_free_i32(tmp
);
2725 static void gen_neon_dup_low16(TCGv_i32 var
)
2727 TCGv_i32 tmp
= tcg_temp_new_i32();
2728 tcg_gen_ext16u_i32(var
, var
);
2729 tcg_gen_shli_i32(tmp
, var
, 16);
2730 tcg_gen_or_i32(var
, var
, tmp
);
2731 tcg_temp_free_i32(tmp
);
2734 static void gen_neon_dup_high16(TCGv_i32 var
)
2736 TCGv_i32 tmp
= tcg_temp_new_i32();
2737 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2738 tcg_gen_shri_i32(tmp
, var
, 16);
2739 tcg_gen_or_i32(var
, var
, tmp
);
2740 tcg_temp_free_i32(tmp
);
2743 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2745 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2746 TCGv_i32 tmp
= tcg_temp_new_i32();
2749 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
2750 gen_neon_dup_u8(tmp
, 0);
2753 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
2754 gen_neon_dup_low16(tmp
);
2757 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
2759 default: /* Avoid compiler warnings. */
2765 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2768 uint32_t cc
= extract32(insn
, 20, 2);
2771 TCGv_i64 frn
, frm
, dest
;
2772 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2774 zero
= tcg_const_i64(0);
2776 frn
= tcg_temp_new_i64();
2777 frm
= tcg_temp_new_i64();
2778 dest
= tcg_temp_new_i64();
2780 zf
= tcg_temp_new_i64();
2781 nf
= tcg_temp_new_i64();
2782 vf
= tcg_temp_new_i64();
2784 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2785 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2786 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2788 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2789 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2792 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2796 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2799 case 2: /* ge: N == V -> N ^ V == 0 */
2800 tmp
= tcg_temp_new_i64();
2801 tcg_gen_xor_i64(tmp
, vf
, nf
);
2802 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2804 tcg_temp_free_i64(tmp
);
2806 case 3: /* gt: !Z && N == V */
2807 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2809 tmp
= tcg_temp_new_i64();
2810 tcg_gen_xor_i64(tmp
, vf
, nf
);
2811 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2813 tcg_temp_free_i64(tmp
);
2816 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2817 tcg_temp_free_i64(frn
);
2818 tcg_temp_free_i64(frm
);
2819 tcg_temp_free_i64(dest
);
2821 tcg_temp_free_i64(zf
);
2822 tcg_temp_free_i64(nf
);
2823 tcg_temp_free_i64(vf
);
2825 tcg_temp_free_i64(zero
);
2827 TCGv_i32 frn
, frm
, dest
;
2830 zero
= tcg_const_i32(0);
2832 frn
= tcg_temp_new_i32();
2833 frm
= tcg_temp_new_i32();
2834 dest
= tcg_temp_new_i32();
2835 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2836 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2839 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2843 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2846 case 2: /* ge: N == V -> N ^ V == 0 */
2847 tmp
= tcg_temp_new_i32();
2848 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2849 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2851 tcg_temp_free_i32(tmp
);
2853 case 3: /* gt: !Z && N == V */
2854 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2856 tmp
= tcg_temp_new_i32();
2857 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2858 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2860 tcg_temp_free_i32(tmp
);
2863 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2864 tcg_temp_free_i32(frn
);
2865 tcg_temp_free_i32(frm
);
2866 tcg_temp_free_i32(dest
);
2868 tcg_temp_free_i32(zero
);
2874 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2875 uint32_t rm
, uint32_t dp
)
2877 uint32_t vmin
= extract32(insn
, 6, 1);
2878 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2881 TCGv_i64 frn
, frm
, dest
;
2883 frn
= tcg_temp_new_i64();
2884 frm
= tcg_temp_new_i64();
2885 dest
= tcg_temp_new_i64();
2887 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2888 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2890 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2892 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2894 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2895 tcg_temp_free_i64(frn
);
2896 tcg_temp_free_i64(frm
);
2897 tcg_temp_free_i64(dest
);
2899 TCGv_i32 frn
, frm
, dest
;
2901 frn
= tcg_temp_new_i32();
2902 frm
= tcg_temp_new_i32();
2903 dest
= tcg_temp_new_i32();
2905 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2906 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2908 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2910 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2912 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2913 tcg_temp_free_i32(frn
);
2914 tcg_temp_free_i32(frm
);
2915 tcg_temp_free_i32(dest
);
2918 tcg_temp_free_ptr(fpst
);
2922 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2925 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2928 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2929 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2934 tcg_op
= tcg_temp_new_i64();
2935 tcg_res
= tcg_temp_new_i64();
2936 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2937 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2938 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2939 tcg_temp_free_i64(tcg_op
);
2940 tcg_temp_free_i64(tcg_res
);
2944 tcg_op
= tcg_temp_new_i32();
2945 tcg_res
= tcg_temp_new_i32();
2946 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2947 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2948 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2949 tcg_temp_free_i32(tcg_op
);
2950 tcg_temp_free_i32(tcg_res
);
2953 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2954 tcg_temp_free_i32(tcg_rmode
);
2956 tcg_temp_free_ptr(fpst
);
2960 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2963 bool is_signed
= extract32(insn
, 7, 1);
2964 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2965 TCGv_i32 tcg_rmode
, tcg_shift
;
2967 tcg_shift
= tcg_const_i32(0);
2969 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2970 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2973 TCGv_i64 tcg_double
, tcg_res
;
2975 /* Rd is encoded as a single precision register even when the source
2976 * is double precision.
2978 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2979 tcg_double
= tcg_temp_new_i64();
2980 tcg_res
= tcg_temp_new_i64();
2981 tcg_tmp
= tcg_temp_new_i32();
2982 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2984 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2986 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2988 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
2989 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2990 tcg_temp_free_i32(tcg_tmp
);
2991 tcg_temp_free_i64(tcg_res
);
2992 tcg_temp_free_i64(tcg_double
);
2994 TCGv_i32 tcg_single
, tcg_res
;
2995 tcg_single
= tcg_temp_new_i32();
2996 tcg_res
= tcg_temp_new_i32();
2997 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2999 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3001 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3003 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3004 tcg_temp_free_i32(tcg_res
);
3005 tcg_temp_free_i32(tcg_single
);
3008 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3009 tcg_temp_free_i32(tcg_rmode
);
3011 tcg_temp_free_i32(tcg_shift
);
3013 tcg_temp_free_ptr(fpst
);
3018 /* Table for converting the most common AArch32 encoding of
3019 * rounding mode to arm_fprounding order (which matches the
3020 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3022 static const uint8_t fp_decode_rm
[] = {
3029 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3031 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3033 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3038 VFP_DREG_D(rd
, insn
);
3039 VFP_DREG_N(rn
, insn
);
3040 VFP_DREG_M(rm
, insn
);
3042 rd
= VFP_SREG_D(insn
);
3043 rn
= VFP_SREG_N(insn
);
3044 rm
= VFP_SREG_M(insn
);
3047 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3048 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3049 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3050 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3051 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3052 /* VRINTA, VRINTN, VRINTP, VRINTM */
3053 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3054 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3055 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3056 /* VCVTA, VCVTN, VCVTP, VCVTM */
3057 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3058 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3063 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3064 (ie. an undefined instruction). */
3065 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3067 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3073 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3077 /* FIXME: this access check should not take precedence over UNDEF
3078 * for invalid encodings; we will generate incorrect syndrome information
3079 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3081 if (s
->fp_excp_el
) {
3082 gen_exception_insn(s
, 4, EXCP_UDEF
,
3083 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
3087 if (!s
->vfp_enabled
) {
3088 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3089 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3091 rn
= (insn
>> 16) & 0xf;
3092 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3093 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3098 if (extract32(insn
, 28, 4) == 0xf) {
3099 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3100 * only used in v8 and above.
3102 return disas_vfp_v8_insn(s
, insn
);
3105 dp
= ((insn
& 0xf00) == 0xb00);
3106 switch ((insn
>> 24) & 0xf) {
3108 if (insn
& (1 << 4)) {
3109 /* single register transfer */
3110 rd
= (insn
>> 12) & 0xf;
3115 VFP_DREG_N(rn
, insn
);
3118 if (insn
& 0x00c00060
3119 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3123 pass
= (insn
>> 21) & 1;
3124 if (insn
& (1 << 22)) {
3126 offset
= ((insn
>> 5) & 3) * 8;
3127 } else if (insn
& (1 << 5)) {
3129 offset
= (insn
& (1 << 6)) ? 16 : 0;
3134 if (insn
& ARM_CP_RW_BIT
) {
3136 tmp
= neon_load_reg(rn
, pass
);
3140 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3141 if (insn
& (1 << 23))
3147 if (insn
& (1 << 23)) {
3149 tcg_gen_shri_i32(tmp
, tmp
, 16);
3155 tcg_gen_sari_i32(tmp
, tmp
, 16);
3164 store_reg(s
, rd
, tmp
);
3167 tmp
= load_reg(s
, rd
);
3168 if (insn
& (1 << 23)) {
3171 gen_neon_dup_u8(tmp
, 0);
3172 } else if (size
== 1) {
3173 gen_neon_dup_low16(tmp
);
3175 for (n
= 0; n
<= pass
* 2; n
++) {
3176 tmp2
= tcg_temp_new_i32();
3177 tcg_gen_mov_i32(tmp2
, tmp
);
3178 neon_store_reg(rn
, n
, tmp2
);
3180 neon_store_reg(rn
, n
, tmp
);
3185 tmp2
= neon_load_reg(rn
, pass
);
3186 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3187 tcg_temp_free_i32(tmp2
);
3190 tmp2
= neon_load_reg(rn
, pass
);
3191 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3192 tcg_temp_free_i32(tmp2
);
3197 neon_store_reg(rn
, pass
, tmp
);
3201 if ((insn
& 0x6f) != 0x00)
3203 rn
= VFP_SREG_N(insn
);
3204 if (insn
& ARM_CP_RW_BIT
) {
3206 if (insn
& (1 << 21)) {
3207 /* system register */
3212 /* VFP2 allows access to FSID from userspace.
3213 VFP3 restricts all id registers to privileged
3216 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3219 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3224 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3226 case ARM_VFP_FPINST
:
3227 case ARM_VFP_FPINST2
:
3228 /* Not present in VFP3. */
3230 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3233 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3237 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3238 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3240 tmp
= tcg_temp_new_i32();
3241 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3245 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3252 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3255 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3261 gen_mov_F0_vreg(0, rn
);
3262 tmp
= gen_vfp_mrs();
3265 /* Set the 4 flag bits in the CPSR. */
3267 tcg_temp_free_i32(tmp
);
3269 store_reg(s
, rd
, tmp
);
3273 if (insn
& (1 << 21)) {
3275 /* system register */
3280 /* Writes are ignored. */
3283 tmp
= load_reg(s
, rd
);
3284 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3285 tcg_temp_free_i32(tmp
);
3291 /* TODO: VFP subarchitecture support.
3292 * For now, keep the EN bit only */
3293 tmp
= load_reg(s
, rd
);
3294 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3295 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3298 case ARM_VFP_FPINST
:
3299 case ARM_VFP_FPINST2
:
3303 tmp
= load_reg(s
, rd
);
3304 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3310 tmp
= load_reg(s
, rd
);
3312 gen_mov_vreg_F0(0, rn
);
3317 /* data processing */
3318 /* The opcode is in bits 23, 21, 20 and 6. */
3319 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3323 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3325 /* rn is register number */
3326 VFP_DREG_N(rn
, insn
);
3329 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3330 ((rn
& 0x1e) == 0x6))) {
3331 /* Integer or single/half precision destination. */
3332 rd
= VFP_SREG_D(insn
);
3334 VFP_DREG_D(rd
, insn
);
3337 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3338 ((rn
& 0x1e) == 0x4))) {
3339 /* VCVT from int or half precision is always from S reg
3340 * regardless of dp bit. VCVT with immediate frac_bits
3341 * has same format as SREG_M.
3343 rm
= VFP_SREG_M(insn
);
3345 VFP_DREG_M(rm
, insn
);
3348 rn
= VFP_SREG_N(insn
);
3349 if (op
== 15 && rn
== 15) {
3350 /* Double precision destination. */
3351 VFP_DREG_D(rd
, insn
);
3353 rd
= VFP_SREG_D(insn
);
3355 /* NB that we implicitly rely on the encoding for the frac_bits
3356 * in VCVT of fixed to float being the same as that of an SREG_M
3358 rm
= VFP_SREG_M(insn
);
3361 veclen
= s
->vec_len
;
3362 if (op
== 15 && rn
> 3)
3365 /* Shut up compiler warnings. */
3376 /* Figure out what type of vector operation this is. */
3377 if ((rd
& bank_mask
) == 0) {
3382 delta_d
= (s
->vec_stride
>> 1) + 1;
3384 delta_d
= s
->vec_stride
+ 1;
3386 if ((rm
& bank_mask
) == 0) {
3387 /* mixed scalar/vector */
3396 /* Load the initial operands. */
3401 /* Integer source */
3402 gen_mov_F0_vreg(0, rm
);
3407 gen_mov_F0_vreg(dp
, rd
);
3408 gen_mov_F1_vreg(dp
, rm
);
3412 /* Compare with zero */
3413 gen_mov_F0_vreg(dp
, rd
);
3424 /* Source and destination the same. */
3425 gen_mov_F0_vreg(dp
, rd
);
3431 /* VCVTB, VCVTT: only present with the halfprec extension
3432 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3433 * (we choose to UNDEF)
3435 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3436 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3439 if (!extract32(rn
, 1, 1)) {
3440 /* Half precision source. */
3441 gen_mov_F0_vreg(0, rm
);
3444 /* Otherwise fall through */
3446 /* One source operand. */
3447 gen_mov_F0_vreg(dp
, rm
);
3451 /* Two source operands. */
3452 gen_mov_F0_vreg(dp
, rn
);
3453 gen_mov_F1_vreg(dp
, rm
);
3457 /* Perform the calculation. */
3459 case 0: /* VMLA: fd + (fn * fm) */
3460 /* Note that order of inputs to the add matters for NaNs */
3462 gen_mov_F0_vreg(dp
, rd
);
3465 case 1: /* VMLS: fd + -(fn * fm) */
3468 gen_mov_F0_vreg(dp
, rd
);
3471 case 2: /* VNMLS: -fd + (fn * fm) */
3472 /* Note that it isn't valid to replace (-A + B) with (B - A)
3473 * or similar plausible looking simplifications
3474 * because this will give wrong results for NaNs.
3477 gen_mov_F0_vreg(dp
, rd
);
3481 case 3: /* VNMLA: -fd + -(fn * fm) */
3484 gen_mov_F0_vreg(dp
, rd
);
3488 case 4: /* mul: fn * fm */
3491 case 5: /* nmul: -(fn * fm) */
3495 case 6: /* add: fn + fm */
3498 case 7: /* sub: fn - fm */
3501 case 8: /* div: fn / fm */
3504 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3505 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3506 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3507 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3508 /* These are fused multiply-add, and must be done as one
3509 * floating point operation with no rounding between the
3510 * multiplication and addition steps.
3511 * NB that doing the negations here as separate steps is
3512 * correct : an input NaN should come out with its sign bit
3513 * flipped if it is a negated-input.
3515 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3523 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3525 frd
= tcg_temp_new_i64();
3526 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3529 gen_helper_vfp_negd(frd
, frd
);
3531 fpst
= get_fpstatus_ptr(0);
3532 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3533 cpu_F1d
, frd
, fpst
);
3534 tcg_temp_free_ptr(fpst
);
3535 tcg_temp_free_i64(frd
);
3541 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3543 frd
= tcg_temp_new_i32();
3544 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3546 gen_helper_vfp_negs(frd
, frd
);
3548 fpst
= get_fpstatus_ptr(0);
3549 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3550 cpu_F1s
, frd
, fpst
);
3551 tcg_temp_free_ptr(fpst
);
3552 tcg_temp_free_i32(frd
);
3555 case 14: /* fconst */
3556 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3560 n
= (insn
<< 12) & 0x80000000;
3561 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3568 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3575 tcg_gen_movi_i32(cpu_F0s
, n
);
3578 case 15: /* extension space */
3592 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3593 tmp
= gen_vfp_mrs();
3594 tcg_gen_ext16u_i32(tmp
, tmp
);
3596 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3599 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3602 tcg_temp_free_i32(tmp
);
3604 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3605 tmp
= gen_vfp_mrs();
3606 tcg_gen_shri_i32(tmp
, tmp
, 16);
3608 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3611 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3614 tcg_temp_free_i32(tmp
);
3616 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3617 tmp
= tcg_temp_new_i32();
3619 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3622 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3625 gen_mov_F0_vreg(0, rd
);
3626 tmp2
= gen_vfp_mrs();
3627 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3628 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3629 tcg_temp_free_i32(tmp2
);
3632 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3633 tmp
= tcg_temp_new_i32();
3635 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3638 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3641 tcg_gen_shli_i32(tmp
, tmp
, 16);
3642 gen_mov_F0_vreg(0, rd
);
3643 tmp2
= gen_vfp_mrs();
3644 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3645 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3646 tcg_temp_free_i32(tmp2
);
3658 case 11: /* cmpez */
3662 case 12: /* vrintr */
3664 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3666 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3668 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3670 tcg_temp_free_ptr(fpst
);
3673 case 13: /* vrintz */
3675 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3677 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3678 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3680 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3682 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3684 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3685 tcg_temp_free_i32(tcg_rmode
);
3686 tcg_temp_free_ptr(fpst
);
3689 case 14: /* vrintx */
3691 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3693 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3695 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3697 tcg_temp_free_ptr(fpst
);
3700 case 15: /* single<->double conversion */
3702 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3704 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3706 case 16: /* fuito */
3707 gen_vfp_uito(dp
, 0);
3709 case 17: /* fsito */
3710 gen_vfp_sito(dp
, 0);
3712 case 20: /* fshto */
3713 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3716 gen_vfp_shto(dp
, 16 - rm
, 0);
3718 case 21: /* fslto */
3719 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3722 gen_vfp_slto(dp
, 32 - rm
, 0);
3724 case 22: /* fuhto */
3725 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3728 gen_vfp_uhto(dp
, 16 - rm
, 0);
3730 case 23: /* fulto */
3731 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3734 gen_vfp_ulto(dp
, 32 - rm
, 0);
3736 case 24: /* ftoui */
3737 gen_vfp_toui(dp
, 0);
3739 case 25: /* ftouiz */
3740 gen_vfp_touiz(dp
, 0);
3742 case 26: /* ftosi */
3743 gen_vfp_tosi(dp
, 0);
3745 case 27: /* ftosiz */
3746 gen_vfp_tosiz(dp
, 0);
3748 case 28: /* ftosh */
3749 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3752 gen_vfp_tosh(dp
, 16 - rm
, 0);
3754 case 29: /* ftosl */
3755 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3758 gen_vfp_tosl(dp
, 32 - rm
, 0);
3760 case 30: /* ftouh */
3761 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3764 gen_vfp_touh(dp
, 16 - rm
, 0);
3766 case 31: /* ftoul */
3767 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3770 gen_vfp_toul(dp
, 32 - rm
, 0);
3772 default: /* undefined */
3776 default: /* undefined */
3780 /* Write back the result. */
3781 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3782 /* Comparison, do nothing. */
3783 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3784 (rn
& 0x1e) == 0x6)) {
3785 /* VCVT double to int: always integer result.
3786 * VCVT double to half precision is always a single
3789 gen_mov_vreg_F0(0, rd
);
3790 } else if (op
== 15 && rn
== 15) {
3792 gen_mov_vreg_F0(!dp
, rd
);
3794 gen_mov_vreg_F0(dp
, rd
);
3797 /* break out of the loop if we have finished */
3801 if (op
== 15 && delta_m
== 0) {
3802 /* single source one-many */
3804 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3806 gen_mov_vreg_F0(dp
, rd
);
3810 /* Setup the next operands. */
3812 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3816 /* One source operand. */
3817 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3819 gen_mov_F0_vreg(dp
, rm
);
3821 /* Two source operands. */
3822 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3824 gen_mov_F0_vreg(dp
, rn
);
3826 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3828 gen_mov_F1_vreg(dp
, rm
);
3836 if ((insn
& 0x03e00000) == 0x00400000) {
3837 /* two-register transfer */
3838 rn
= (insn
>> 16) & 0xf;
3839 rd
= (insn
>> 12) & 0xf;
3841 VFP_DREG_M(rm
, insn
);
3843 rm
= VFP_SREG_M(insn
);
3846 if (insn
& ARM_CP_RW_BIT
) {
3849 gen_mov_F0_vreg(0, rm
* 2);
3850 tmp
= gen_vfp_mrs();
3851 store_reg(s
, rd
, tmp
);
3852 gen_mov_F0_vreg(0, rm
* 2 + 1);
3853 tmp
= gen_vfp_mrs();
3854 store_reg(s
, rn
, tmp
);
3856 gen_mov_F0_vreg(0, rm
);
3857 tmp
= gen_vfp_mrs();
3858 store_reg(s
, rd
, tmp
);
3859 gen_mov_F0_vreg(0, rm
+ 1);
3860 tmp
= gen_vfp_mrs();
3861 store_reg(s
, rn
, tmp
);
3866 tmp
= load_reg(s
, rd
);
3868 gen_mov_vreg_F0(0, rm
* 2);
3869 tmp
= load_reg(s
, rn
);
3871 gen_mov_vreg_F0(0, rm
* 2 + 1);
3873 tmp
= load_reg(s
, rd
);
3875 gen_mov_vreg_F0(0, rm
);
3876 tmp
= load_reg(s
, rn
);
3878 gen_mov_vreg_F0(0, rm
+ 1);
3883 rn
= (insn
>> 16) & 0xf;
3885 VFP_DREG_D(rd
, insn
);
3887 rd
= VFP_SREG_D(insn
);
3888 if ((insn
& 0x01200000) == 0x01000000) {
3889 /* Single load/store */
3890 offset
= (insn
& 0xff) << 2;
3891 if ((insn
& (1 << 23)) == 0)
3893 if (s
->thumb
&& rn
== 15) {
3894 /* This is actually UNPREDICTABLE */
3895 addr
= tcg_temp_new_i32();
3896 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3898 addr
= load_reg(s
, rn
);
3900 tcg_gen_addi_i32(addr
, addr
, offset
);
3901 if (insn
& (1 << 20)) {
3902 gen_vfp_ld(s
, dp
, addr
);
3903 gen_mov_vreg_F0(dp
, rd
);
3905 gen_mov_F0_vreg(dp
, rd
);
3906 gen_vfp_st(s
, dp
, addr
);
3908 tcg_temp_free_i32(addr
);
3910 /* load/store multiple */
3911 int w
= insn
& (1 << 21);
3913 n
= (insn
>> 1) & 0x7f;
3917 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3918 /* P == U , W == 1 => UNDEF */
3921 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3922 /* UNPREDICTABLE cases for bad immediates: we choose to
3923 * UNDEF to avoid generating huge numbers of TCG ops
3927 if (rn
== 15 && w
) {
3928 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3932 if (s
->thumb
&& rn
== 15) {
3933 /* This is actually UNPREDICTABLE */
3934 addr
= tcg_temp_new_i32();
3935 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3937 addr
= load_reg(s
, rn
);
3939 if (insn
& (1 << 24)) /* pre-decrement */
3940 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3946 for (i
= 0; i
< n
; i
++) {
3947 if (insn
& ARM_CP_RW_BIT
) {
3949 gen_vfp_ld(s
, dp
, addr
);
3950 gen_mov_vreg_F0(dp
, rd
+ i
);
3953 gen_mov_F0_vreg(dp
, rd
+ i
);
3954 gen_vfp_st(s
, dp
, addr
);
3956 tcg_gen_addi_i32(addr
, addr
, offset
);
3960 if (insn
& (1 << 24))
3961 offset
= -offset
* n
;
3962 else if (dp
&& (insn
& 1))
3968 tcg_gen_addi_i32(addr
, addr
, offset
);
3969 store_reg(s
, rn
, addr
);
3971 tcg_temp_free_i32(addr
);
3977 /* Should never happen. */
3983 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3985 TranslationBlock
*tb
;
3988 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3990 gen_set_pc_im(s
, dest
);
3991 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3993 gen_set_pc_im(s
, dest
);
3998 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4000 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
4001 /* An indirect jump so that we still trigger the debug exception. */
4006 gen_goto_tb(s
, 0, dest
);
4007 s
->is_jmp
= DISAS_TB_JUMP
;
4011 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4014 tcg_gen_sari_i32(t0
, t0
, 16);
4018 tcg_gen_sari_i32(t1
, t1
, 16);
4021 tcg_gen_mul_i32(t0
, t0
, t1
);
4024 /* Return the mask of PSR bits set by a MSR instruction. */
4025 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4030 if (flags
& (1 << 0))
4032 if (flags
& (1 << 1))
4034 if (flags
& (1 << 2))
4036 if (flags
& (1 << 3))
4039 /* Mask out undefined bits. */
4040 mask
&= ~CPSR_RESERVED
;
4041 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4044 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4045 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4047 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4048 mask
&= ~(CPSR_E
| CPSR_GE
);
4050 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4053 /* Mask out execution state and reserved bits. */
4055 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4057 /* Mask out privileged bits. */
4063 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4064 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4068 /* ??? This is also undefined in system mode. */
4072 tmp
= load_cpu_field(spsr
);
4073 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4074 tcg_gen_andi_i32(t0
, t0
, mask
);
4075 tcg_gen_or_i32(tmp
, tmp
, t0
);
4076 store_cpu_field(tmp
, spsr
);
4078 gen_set_cpsr(t0
, mask
);
4080 tcg_temp_free_i32(t0
);
4085 /* Returns nonzero if access to the PSR is not permitted. */
4086 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4089 tmp
= tcg_temp_new_i32();
4090 tcg_gen_movi_i32(tmp
, val
);
4091 return gen_set_psr(s
, mask
, spsr
, tmp
);
4094 /* Generate an old-style exception return. Marks pc as dead. */
4095 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4098 store_reg(s
, 15, pc
);
4099 tmp
= load_cpu_field(spsr
);
4100 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
4101 tcg_temp_free_i32(tmp
);
4102 s
->is_jmp
= DISAS_JUMP
;
4105 /* Generate a v6 exception return. Marks both values as dead. */
4106 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4108 gen_set_cpsr(cpsr
, CPSR_ERET_MASK
);
4109 tcg_temp_free_i32(cpsr
);
4110 store_reg(s
, 15, pc
);
4111 s
->is_jmp
= DISAS_JUMP
;
4114 static void gen_nop_hint(DisasContext
*s
, int val
)
4118 gen_set_pc_im(s
, s
->pc
);
4119 s
->is_jmp
= DISAS_YIELD
;
4122 gen_set_pc_im(s
, s
->pc
);
4123 s
->is_jmp
= DISAS_WFI
;
4126 gen_set_pc_im(s
, s
->pc
);
4127 s
->is_jmp
= DISAS_WFE
;
4131 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4137 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4139 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4142 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4143 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4144 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4149 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4152 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4153 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4154 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4159 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4160 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4161 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4162 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4163 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4165 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4166 switch ((size << 1) | u) { \
4168 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4171 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4174 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4177 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4180 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4183 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4185 default: return 1; \
4188 #define GEN_NEON_INTEGER_OP(name) do { \
4189 switch ((size << 1) | u) { \
4191 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4194 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4197 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4200 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4203 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4206 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4208 default: return 1; \
4211 static TCGv_i32
neon_load_scratch(int scratch
)
4213 TCGv_i32 tmp
= tcg_temp_new_i32();
4214 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4218 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4220 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4221 tcg_temp_free_i32(var
);
4224 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4228 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4230 gen_neon_dup_high16(tmp
);
4232 gen_neon_dup_low16(tmp
);
4235 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4240 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4243 if (!q
&& size
== 2) {
4246 tmp
= tcg_const_i32(rd
);
4247 tmp2
= tcg_const_i32(rm
);
4251 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4254 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4257 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4265 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4268 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4274 tcg_temp_free_i32(tmp
);
4275 tcg_temp_free_i32(tmp2
);
4279 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4282 if (!q
&& size
== 2) {
4285 tmp
= tcg_const_i32(rd
);
4286 tmp2
= tcg_const_i32(rm
);
4290 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4293 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4296 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4304 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4307 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4313 tcg_temp_free_i32(tmp
);
4314 tcg_temp_free_i32(tmp2
);
4318 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4322 rd
= tcg_temp_new_i32();
4323 tmp
= tcg_temp_new_i32();
4325 tcg_gen_shli_i32(rd
, t0
, 8);
4326 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4327 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4328 tcg_gen_or_i32(rd
, rd
, tmp
);
4330 tcg_gen_shri_i32(t1
, t1
, 8);
4331 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4332 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4333 tcg_gen_or_i32(t1
, t1
, tmp
);
4334 tcg_gen_mov_i32(t0
, rd
);
4336 tcg_temp_free_i32(tmp
);
4337 tcg_temp_free_i32(rd
);
4340 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4344 rd
= tcg_temp_new_i32();
4345 tmp
= tcg_temp_new_i32();
4347 tcg_gen_shli_i32(rd
, t0
, 16);
4348 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4349 tcg_gen_or_i32(rd
, rd
, tmp
);
4350 tcg_gen_shri_i32(t1
, t1
, 16);
4351 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4352 tcg_gen_or_i32(t1
, t1
, tmp
);
4353 tcg_gen_mov_i32(t0
, rd
);
4355 tcg_temp_free_i32(tmp
);
4356 tcg_temp_free_i32(rd
);
4364 } neon_ls_element_type
[11] = {
4378 /* Translate a NEON load/store element instruction. Return nonzero if the
4379 instruction is invalid. */
4380 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4399 /* FIXME: this access check should not take precedence over UNDEF
4400 * for invalid encodings; we will generate incorrect syndrome information
4401 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4403 if (s
->fp_excp_el
) {
4404 gen_exception_insn(s
, 4, EXCP_UDEF
,
4405 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
4409 if (!s
->vfp_enabled
)
4411 VFP_DREG_D(rd
, insn
);
4412 rn
= (insn
>> 16) & 0xf;
4414 load
= (insn
& (1 << 21)) != 0;
4415 if ((insn
& (1 << 23)) == 0) {
4416 /* Load store all elements. */
4417 op
= (insn
>> 8) & 0xf;
4418 size
= (insn
>> 6) & 3;
4421 /* Catch UNDEF cases for bad values of align field */
4424 if (((insn
>> 5) & 1) == 1) {
4429 if (((insn
>> 4) & 3) == 3) {
4436 nregs
= neon_ls_element_type
[op
].nregs
;
4437 interleave
= neon_ls_element_type
[op
].interleave
;
4438 spacing
= neon_ls_element_type
[op
].spacing
;
4439 if (size
== 3 && (interleave
| spacing
) != 1)
4441 addr
= tcg_temp_new_i32();
4442 load_reg_var(s
, addr
, rn
);
4443 stride
= (1 << size
) * interleave
;
4444 for (reg
= 0; reg
< nregs
; reg
++) {
4445 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4446 load_reg_var(s
, addr
, rn
);
4447 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4448 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4449 load_reg_var(s
, addr
, rn
);
4450 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4453 tmp64
= tcg_temp_new_i64();
4455 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4456 neon_store_reg64(tmp64
, rd
);
4458 neon_load_reg64(tmp64
, rd
);
4459 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4461 tcg_temp_free_i64(tmp64
);
4462 tcg_gen_addi_i32(addr
, addr
, stride
);
4464 for (pass
= 0; pass
< 2; pass
++) {
4467 tmp
= tcg_temp_new_i32();
4468 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4469 neon_store_reg(rd
, pass
, tmp
);
4471 tmp
= neon_load_reg(rd
, pass
);
4472 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4473 tcg_temp_free_i32(tmp
);
4475 tcg_gen_addi_i32(addr
, addr
, stride
);
4476 } else if (size
== 1) {
4478 tmp
= tcg_temp_new_i32();
4479 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4480 tcg_gen_addi_i32(addr
, addr
, stride
);
4481 tmp2
= tcg_temp_new_i32();
4482 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4483 tcg_gen_addi_i32(addr
, addr
, stride
);
4484 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4485 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4486 tcg_temp_free_i32(tmp2
);
4487 neon_store_reg(rd
, pass
, tmp
);
4489 tmp
= neon_load_reg(rd
, pass
);
4490 tmp2
= tcg_temp_new_i32();
4491 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4492 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4493 tcg_temp_free_i32(tmp
);
4494 tcg_gen_addi_i32(addr
, addr
, stride
);
4495 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4496 tcg_temp_free_i32(tmp2
);
4497 tcg_gen_addi_i32(addr
, addr
, stride
);
4499 } else /* size == 0 */ {
4501 TCGV_UNUSED_I32(tmp2
);
4502 for (n
= 0; n
< 4; n
++) {
4503 tmp
= tcg_temp_new_i32();
4504 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4505 tcg_gen_addi_i32(addr
, addr
, stride
);
4509 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4510 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4511 tcg_temp_free_i32(tmp
);
4514 neon_store_reg(rd
, pass
, tmp2
);
4516 tmp2
= neon_load_reg(rd
, pass
);
4517 for (n
= 0; n
< 4; n
++) {
4518 tmp
= tcg_temp_new_i32();
4520 tcg_gen_mov_i32(tmp
, tmp2
);
4522 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4524 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4525 tcg_temp_free_i32(tmp
);
4526 tcg_gen_addi_i32(addr
, addr
, stride
);
4528 tcg_temp_free_i32(tmp2
);
4535 tcg_temp_free_i32(addr
);
4538 size
= (insn
>> 10) & 3;
4540 /* Load single element to all lanes. */
4541 int a
= (insn
>> 4) & 1;
4545 size
= (insn
>> 6) & 3;
4546 nregs
= ((insn
>> 8) & 3) + 1;
4549 if (nregs
!= 4 || a
== 0) {
4552 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4555 if (nregs
== 1 && a
== 1 && size
== 0) {
4558 if (nregs
== 3 && a
== 1) {
4561 addr
= tcg_temp_new_i32();
4562 load_reg_var(s
, addr
, rn
);
4564 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4565 tmp
= gen_load_and_replicate(s
, addr
, size
);
4566 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4567 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4568 if (insn
& (1 << 5)) {
4569 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4570 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4572 tcg_temp_free_i32(tmp
);
4574 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4575 stride
= (insn
& (1 << 5)) ? 2 : 1;
4576 for (reg
= 0; reg
< nregs
; reg
++) {
4577 tmp
= gen_load_and_replicate(s
, addr
, size
);
4578 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4579 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4580 tcg_temp_free_i32(tmp
);
4581 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4585 tcg_temp_free_i32(addr
);
4586 stride
= (1 << size
) * nregs
;
4588 /* Single element. */
4589 int idx
= (insn
>> 4) & 0xf;
4590 pass
= (insn
>> 7) & 1;
4593 shift
= ((insn
>> 5) & 3) * 8;
4597 shift
= ((insn
>> 6) & 1) * 16;
4598 stride
= (insn
& (1 << 5)) ? 2 : 1;
4602 stride
= (insn
& (1 << 6)) ? 2 : 1;
4607 nregs
= ((insn
>> 8) & 3) + 1;
4608 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4611 if (((idx
& (1 << size
)) != 0) ||
4612 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4617 if ((idx
& 1) != 0) {
4622 if (size
== 2 && (idx
& 2) != 0) {
4627 if ((size
== 2) && ((idx
& 3) == 3)) {
4634 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4635 /* Attempts to write off the end of the register file
4636 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4637 * the neon_load_reg() would write off the end of the array.
4641 addr
= tcg_temp_new_i32();
4642 load_reg_var(s
, addr
, rn
);
4643 for (reg
= 0; reg
< nregs
; reg
++) {
4645 tmp
= tcg_temp_new_i32();
4648 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4651 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4654 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4656 default: /* Avoid compiler warnings. */
4660 tmp2
= neon_load_reg(rd
, pass
);
4661 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4662 shift
, size
? 16 : 8);
4663 tcg_temp_free_i32(tmp2
);
4665 neon_store_reg(rd
, pass
, tmp
);
4666 } else { /* Store */
4667 tmp
= neon_load_reg(rd
, pass
);
4669 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4672 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4675 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4678 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4681 tcg_temp_free_i32(tmp
);
4684 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4686 tcg_temp_free_i32(addr
);
4687 stride
= nregs
* (1 << size
);
4693 base
= load_reg(s
, rn
);
4695 tcg_gen_addi_i32(base
, base
, stride
);
4698 index
= load_reg(s
, rm
);
4699 tcg_gen_add_i32(base
, base
, index
);
4700 tcg_temp_free_i32(index
);
4702 store_reg(s
, rn
, base
);
4707 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4708 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4710 tcg_gen_and_i32(t
, t
, c
);
4711 tcg_gen_andc_i32(f
, f
, c
);
4712 tcg_gen_or_i32(dest
, t
, f
);
4715 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4718 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4719 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4720 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4725 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4728 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4729 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4730 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4735 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4738 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4739 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4740 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4745 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4748 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4749 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4750 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4755 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4761 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4762 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4767 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4768 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4775 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4776 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4781 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4782 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4789 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4793 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4794 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4795 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4800 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4801 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4802 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4806 tcg_temp_free_i32(src
);
4809 static inline void gen_neon_addl(int size
)
4812 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4813 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4814 case 2: tcg_gen_add_i64(CPU_V001
); break;
4819 static inline void gen_neon_subl(int size
)
4822 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4823 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4824 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4829 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4832 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4833 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4835 tcg_gen_neg_i64(var
, var
);
4841 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4844 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4845 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4850 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4855 switch ((size
<< 1) | u
) {
4856 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4857 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4858 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4859 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4861 tmp
= gen_muls_i64_i32(a
, b
);
4862 tcg_gen_mov_i64(dest
, tmp
);
4863 tcg_temp_free_i64(tmp
);
4866 tmp
= gen_mulu_i64_i32(a
, b
);
4867 tcg_gen_mov_i64(dest
, tmp
);
4868 tcg_temp_free_i64(tmp
);
4873 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4874 Don't forget to clean them now. */
4876 tcg_temp_free_i32(a
);
4877 tcg_temp_free_i32(b
);
4881 static void gen_neon_narrow_op(int op
, int u
, int size
,
4882 TCGv_i32 dest
, TCGv_i64 src
)
4886 gen_neon_unarrow_sats(size
, dest
, src
);
4888 gen_neon_narrow(size
, dest
, src
);
4892 gen_neon_narrow_satu(size
, dest
, src
);
4894 gen_neon_narrow_sats(size
, dest
, src
);
4899 /* Symbolic constants for op fields for Neon 3-register same-length.
4900 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4903 #define NEON_3R_VHADD 0
4904 #define NEON_3R_VQADD 1
4905 #define NEON_3R_VRHADD 2
4906 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4907 #define NEON_3R_VHSUB 4
4908 #define NEON_3R_VQSUB 5
4909 #define NEON_3R_VCGT 6
4910 #define NEON_3R_VCGE 7
4911 #define NEON_3R_VSHL 8
4912 #define NEON_3R_VQSHL 9
4913 #define NEON_3R_VRSHL 10
4914 #define NEON_3R_VQRSHL 11
4915 #define NEON_3R_VMAX 12
4916 #define NEON_3R_VMIN 13
4917 #define NEON_3R_VABD 14
4918 #define NEON_3R_VABA 15
4919 #define NEON_3R_VADD_VSUB 16
4920 #define NEON_3R_VTST_VCEQ 17
4921 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4922 #define NEON_3R_VMUL 19
4923 #define NEON_3R_VPMAX 20
4924 #define NEON_3R_VPMIN 21
4925 #define NEON_3R_VQDMULH_VQRDMULH 22
4926 #define NEON_3R_VPADD 23
4927 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4928 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4929 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4930 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4931 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4932 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4933 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4934 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4936 static const uint8_t neon_3r_sizes
[] = {
4937 [NEON_3R_VHADD
] = 0x7,
4938 [NEON_3R_VQADD
] = 0xf,
4939 [NEON_3R_VRHADD
] = 0x7,
4940 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4941 [NEON_3R_VHSUB
] = 0x7,
4942 [NEON_3R_VQSUB
] = 0xf,
4943 [NEON_3R_VCGT
] = 0x7,
4944 [NEON_3R_VCGE
] = 0x7,
4945 [NEON_3R_VSHL
] = 0xf,
4946 [NEON_3R_VQSHL
] = 0xf,
4947 [NEON_3R_VRSHL
] = 0xf,
4948 [NEON_3R_VQRSHL
] = 0xf,
4949 [NEON_3R_VMAX
] = 0x7,
4950 [NEON_3R_VMIN
] = 0x7,
4951 [NEON_3R_VABD
] = 0x7,
4952 [NEON_3R_VABA
] = 0x7,
4953 [NEON_3R_VADD_VSUB
] = 0xf,
4954 [NEON_3R_VTST_VCEQ
] = 0x7,
4955 [NEON_3R_VML
] = 0x7,
4956 [NEON_3R_VMUL
] = 0x7,
4957 [NEON_3R_VPMAX
] = 0x7,
4958 [NEON_3R_VPMIN
] = 0x7,
4959 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4960 [NEON_3R_VPADD
] = 0x7,
4961 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4962 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4963 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4964 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4965 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4966 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4967 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4968 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4971 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4972 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4975 #define NEON_2RM_VREV64 0
4976 #define NEON_2RM_VREV32 1
4977 #define NEON_2RM_VREV16 2
4978 #define NEON_2RM_VPADDL 4
4979 #define NEON_2RM_VPADDL_U 5
4980 #define NEON_2RM_AESE 6 /* Includes AESD */
4981 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4982 #define NEON_2RM_VCLS 8
4983 #define NEON_2RM_VCLZ 9
4984 #define NEON_2RM_VCNT 10
4985 #define NEON_2RM_VMVN 11
4986 #define NEON_2RM_VPADAL 12
4987 #define NEON_2RM_VPADAL_U 13
4988 #define NEON_2RM_VQABS 14
4989 #define NEON_2RM_VQNEG 15
4990 #define NEON_2RM_VCGT0 16
4991 #define NEON_2RM_VCGE0 17
4992 #define NEON_2RM_VCEQ0 18
4993 #define NEON_2RM_VCLE0 19
4994 #define NEON_2RM_VCLT0 20
4995 #define NEON_2RM_SHA1H 21
4996 #define NEON_2RM_VABS 22
4997 #define NEON_2RM_VNEG 23
4998 #define NEON_2RM_VCGT0_F 24
4999 #define NEON_2RM_VCGE0_F 25
5000 #define NEON_2RM_VCEQ0_F 26
5001 #define NEON_2RM_VCLE0_F 27
5002 #define NEON_2RM_VCLT0_F 28
5003 #define NEON_2RM_VABS_F 30
5004 #define NEON_2RM_VNEG_F 31
5005 #define NEON_2RM_VSWP 32
5006 #define NEON_2RM_VTRN 33
5007 #define NEON_2RM_VUZP 34
5008 #define NEON_2RM_VZIP 35
5009 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5010 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5011 #define NEON_2RM_VSHLL 38
5012 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5013 #define NEON_2RM_VRINTN 40
5014 #define NEON_2RM_VRINTX 41
5015 #define NEON_2RM_VRINTA 42
5016 #define NEON_2RM_VRINTZ 43
5017 #define NEON_2RM_VCVT_F16_F32 44
5018 #define NEON_2RM_VRINTM 45
5019 #define NEON_2RM_VCVT_F32_F16 46
5020 #define NEON_2RM_VRINTP 47
5021 #define NEON_2RM_VCVTAU 48
5022 #define NEON_2RM_VCVTAS 49
5023 #define NEON_2RM_VCVTNU 50
5024 #define NEON_2RM_VCVTNS 51
5025 #define NEON_2RM_VCVTPU 52
5026 #define NEON_2RM_VCVTPS 53
5027 #define NEON_2RM_VCVTMU 54
5028 #define NEON_2RM_VCVTMS 55
5029 #define NEON_2RM_VRECPE 56
5030 #define NEON_2RM_VRSQRTE 57
5031 #define NEON_2RM_VRECPE_F 58
5032 #define NEON_2RM_VRSQRTE_F 59
5033 #define NEON_2RM_VCVT_FS 60
5034 #define NEON_2RM_VCVT_FU 61
5035 #define NEON_2RM_VCVT_SF 62
5036 #define NEON_2RM_VCVT_UF 63
5038 static int neon_2rm_is_float_op(int op
)
5040 /* Return true if this neon 2reg-misc op is float-to-float */
5041 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5042 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5043 op
== NEON_2RM_VRINTM
||
5044 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5045 op
>= NEON_2RM_VRECPE_F
);
5048 /* Each entry in this array has bit n set if the insn allows
5049 * size value n (otherwise it will UNDEF). Since unallocated
5050 * op values will have no bits set they always UNDEF.
5052 static const uint8_t neon_2rm_sizes
[] = {
5053 [NEON_2RM_VREV64
] = 0x7,
5054 [NEON_2RM_VREV32
] = 0x3,
5055 [NEON_2RM_VREV16
] = 0x1,
5056 [NEON_2RM_VPADDL
] = 0x7,
5057 [NEON_2RM_VPADDL_U
] = 0x7,
5058 [NEON_2RM_AESE
] = 0x1,
5059 [NEON_2RM_AESMC
] = 0x1,
5060 [NEON_2RM_VCLS
] = 0x7,
5061 [NEON_2RM_VCLZ
] = 0x7,
5062 [NEON_2RM_VCNT
] = 0x1,
5063 [NEON_2RM_VMVN
] = 0x1,
5064 [NEON_2RM_VPADAL
] = 0x7,
5065 [NEON_2RM_VPADAL_U
] = 0x7,
5066 [NEON_2RM_VQABS
] = 0x7,
5067 [NEON_2RM_VQNEG
] = 0x7,
5068 [NEON_2RM_VCGT0
] = 0x7,
5069 [NEON_2RM_VCGE0
] = 0x7,
5070 [NEON_2RM_VCEQ0
] = 0x7,
5071 [NEON_2RM_VCLE0
] = 0x7,
5072 [NEON_2RM_VCLT0
] = 0x7,
5073 [NEON_2RM_SHA1H
] = 0x4,
5074 [NEON_2RM_VABS
] = 0x7,
5075 [NEON_2RM_VNEG
] = 0x7,
5076 [NEON_2RM_VCGT0_F
] = 0x4,
5077 [NEON_2RM_VCGE0_F
] = 0x4,
5078 [NEON_2RM_VCEQ0_F
] = 0x4,
5079 [NEON_2RM_VCLE0_F
] = 0x4,
5080 [NEON_2RM_VCLT0_F
] = 0x4,
5081 [NEON_2RM_VABS_F
] = 0x4,
5082 [NEON_2RM_VNEG_F
] = 0x4,
5083 [NEON_2RM_VSWP
] = 0x1,
5084 [NEON_2RM_VTRN
] = 0x7,
5085 [NEON_2RM_VUZP
] = 0x7,
5086 [NEON_2RM_VZIP
] = 0x7,
5087 [NEON_2RM_VMOVN
] = 0x7,
5088 [NEON_2RM_VQMOVN
] = 0x7,
5089 [NEON_2RM_VSHLL
] = 0x7,
5090 [NEON_2RM_SHA1SU1
] = 0x4,
5091 [NEON_2RM_VRINTN
] = 0x4,
5092 [NEON_2RM_VRINTX
] = 0x4,
5093 [NEON_2RM_VRINTA
] = 0x4,
5094 [NEON_2RM_VRINTZ
] = 0x4,
5095 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5096 [NEON_2RM_VRINTM
] = 0x4,
5097 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5098 [NEON_2RM_VRINTP
] = 0x4,
5099 [NEON_2RM_VCVTAU
] = 0x4,
5100 [NEON_2RM_VCVTAS
] = 0x4,
5101 [NEON_2RM_VCVTNU
] = 0x4,
5102 [NEON_2RM_VCVTNS
] = 0x4,
5103 [NEON_2RM_VCVTPU
] = 0x4,
5104 [NEON_2RM_VCVTPS
] = 0x4,
5105 [NEON_2RM_VCVTMU
] = 0x4,
5106 [NEON_2RM_VCVTMS
] = 0x4,
5107 [NEON_2RM_VRECPE
] = 0x4,
5108 [NEON_2RM_VRSQRTE
] = 0x4,
5109 [NEON_2RM_VRECPE_F
] = 0x4,
5110 [NEON_2RM_VRSQRTE_F
] = 0x4,
5111 [NEON_2RM_VCVT_FS
] = 0x4,
5112 [NEON_2RM_VCVT_FU
] = 0x4,
5113 [NEON_2RM_VCVT_SF
] = 0x4,
5114 [NEON_2RM_VCVT_UF
] = 0x4,
5117 /* Translate a NEON data processing instruction. Return nonzero if the
5118 instruction is invalid.
5119 We process data in a mixture of 32-bit and 64-bit chunks.
5120 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5122 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5134 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5137 /* FIXME: this access check should not take precedence over UNDEF
5138 * for invalid encodings; we will generate incorrect syndrome information
5139 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5141 if (s
->fp_excp_el
) {
5142 gen_exception_insn(s
, 4, EXCP_UDEF
,
5143 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
5147 if (!s
->vfp_enabled
)
5149 q
= (insn
& (1 << 6)) != 0;
5150 u
= (insn
>> 24) & 1;
5151 VFP_DREG_D(rd
, insn
);
5152 VFP_DREG_N(rn
, insn
);
5153 VFP_DREG_M(rm
, insn
);
5154 size
= (insn
>> 20) & 3;
5155 if ((insn
& (1 << 23)) == 0) {
5156 /* Three register same length. */
5157 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5158 /* Catch invalid op and bad size combinations: UNDEF */
5159 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5162 /* All insns of this form UNDEF for either this condition or the
5163 * superset of cases "Q==1"; we catch the latter later.
5165 if (q
&& ((rd
| rn
| rm
) & 1)) {
5169 * The SHA-1/SHA-256 3-register instructions require special treatment
5170 * here, as their size field is overloaded as an op type selector, and
5171 * they all consume their input in a single pass.
5173 if (op
== NEON_3R_SHA
) {
5177 if (!u
) { /* SHA-1 */
5178 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5181 tmp
= tcg_const_i32(rd
);
5182 tmp2
= tcg_const_i32(rn
);
5183 tmp3
= tcg_const_i32(rm
);
5184 tmp4
= tcg_const_i32(size
);
5185 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5186 tcg_temp_free_i32(tmp4
);
5187 } else { /* SHA-256 */
5188 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5191 tmp
= tcg_const_i32(rd
);
5192 tmp2
= tcg_const_i32(rn
);
5193 tmp3
= tcg_const_i32(rm
);
5196 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5199 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5202 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5206 tcg_temp_free_i32(tmp
);
5207 tcg_temp_free_i32(tmp2
);
5208 tcg_temp_free_i32(tmp3
);
5211 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5212 /* 64-bit element instructions. */
5213 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5214 neon_load_reg64(cpu_V0
, rn
+ pass
);
5215 neon_load_reg64(cpu_V1
, rm
+ pass
);
5219 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5222 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5228 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5231 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5237 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5239 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5244 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5247 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5253 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5255 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5258 case NEON_3R_VQRSHL
:
5260 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5263 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5267 case NEON_3R_VADD_VSUB
:
5269 tcg_gen_sub_i64(CPU_V001
);
5271 tcg_gen_add_i64(CPU_V001
);
5277 neon_store_reg64(cpu_V0
, rd
+ pass
);
5286 case NEON_3R_VQRSHL
:
5289 /* Shift instruction operands are reversed. */
5304 case NEON_3R_FLOAT_ARITH
:
5305 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5307 case NEON_3R_FLOAT_MINMAX
:
5308 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5310 case NEON_3R_FLOAT_CMP
:
5312 /* no encoding for U=0 C=1x */
5316 case NEON_3R_FLOAT_ACMP
:
5321 case NEON_3R_FLOAT_MISC
:
5322 /* VMAXNM/VMINNM in ARMv8 */
5323 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5328 if (u
&& (size
!= 0)) {
5329 /* UNDEF on invalid size for polynomial subcase */
5334 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5342 if (pairwise
&& q
) {
5343 /* All the pairwise insns UNDEF if Q is set */
5347 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5352 tmp
= neon_load_reg(rn
, 0);
5353 tmp2
= neon_load_reg(rn
, 1);
5355 tmp
= neon_load_reg(rm
, 0);
5356 tmp2
= neon_load_reg(rm
, 1);
5360 tmp
= neon_load_reg(rn
, pass
);
5361 tmp2
= neon_load_reg(rm
, pass
);
5365 GEN_NEON_INTEGER_OP(hadd
);
5368 GEN_NEON_INTEGER_OP_ENV(qadd
);
5370 case NEON_3R_VRHADD
:
5371 GEN_NEON_INTEGER_OP(rhadd
);
5373 case NEON_3R_LOGIC
: /* Logic ops. */
5374 switch ((u
<< 2) | size
) {
5376 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5379 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5382 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5385 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5388 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5391 tmp3
= neon_load_reg(rd
, pass
);
5392 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5393 tcg_temp_free_i32(tmp3
);
5396 tmp3
= neon_load_reg(rd
, pass
);
5397 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5398 tcg_temp_free_i32(tmp3
);
5401 tmp3
= neon_load_reg(rd
, pass
);
5402 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5403 tcg_temp_free_i32(tmp3
);
5408 GEN_NEON_INTEGER_OP(hsub
);
5411 GEN_NEON_INTEGER_OP_ENV(qsub
);
5414 GEN_NEON_INTEGER_OP(cgt
);
5417 GEN_NEON_INTEGER_OP(cge
);
5420 GEN_NEON_INTEGER_OP(shl
);
5423 GEN_NEON_INTEGER_OP_ENV(qshl
);
5426 GEN_NEON_INTEGER_OP(rshl
);
5428 case NEON_3R_VQRSHL
:
5429 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5432 GEN_NEON_INTEGER_OP(max
);
5435 GEN_NEON_INTEGER_OP(min
);
5438 GEN_NEON_INTEGER_OP(abd
);
5441 GEN_NEON_INTEGER_OP(abd
);
5442 tcg_temp_free_i32(tmp2
);
5443 tmp2
= neon_load_reg(rd
, pass
);
5444 gen_neon_add(size
, tmp
, tmp2
);
5446 case NEON_3R_VADD_VSUB
:
5447 if (!u
) { /* VADD */
5448 gen_neon_add(size
, tmp
, tmp2
);
5451 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5452 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5453 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5458 case NEON_3R_VTST_VCEQ
:
5459 if (!u
) { /* VTST */
5461 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5462 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5463 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5468 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5469 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5470 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5475 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5477 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5478 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5479 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5482 tcg_temp_free_i32(tmp2
);
5483 tmp2
= neon_load_reg(rd
, pass
);
5485 gen_neon_rsb(size
, tmp
, tmp2
);
5487 gen_neon_add(size
, tmp
, tmp2
);
5491 if (u
) { /* polynomial */
5492 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5493 } else { /* Integer */
5495 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5496 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5497 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5503 GEN_NEON_INTEGER_OP(pmax
);
5506 GEN_NEON_INTEGER_OP(pmin
);
5508 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5509 if (!u
) { /* VQDMULH */
5512 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5515 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5519 } else { /* VQRDMULH */
5522 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5525 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5533 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5534 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5535 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5539 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5541 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5542 switch ((u
<< 2) | size
) {
5545 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5548 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5551 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5556 tcg_temp_free_ptr(fpstatus
);
5559 case NEON_3R_FLOAT_MULTIPLY
:
5561 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5562 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5564 tcg_temp_free_i32(tmp2
);
5565 tmp2
= neon_load_reg(rd
, pass
);
5567 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5569 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5572 tcg_temp_free_ptr(fpstatus
);
5575 case NEON_3R_FLOAT_CMP
:
5577 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5579 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5582 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5584 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5587 tcg_temp_free_ptr(fpstatus
);
5590 case NEON_3R_FLOAT_ACMP
:
5592 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5594 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5596 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5598 tcg_temp_free_ptr(fpstatus
);
5601 case NEON_3R_FLOAT_MINMAX
:
5603 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5605 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5607 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5609 tcg_temp_free_ptr(fpstatus
);
5612 case NEON_3R_FLOAT_MISC
:
5615 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5617 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5619 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5621 tcg_temp_free_ptr(fpstatus
);
5624 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5626 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5632 /* VFMA, VFMS: fused multiply-add */
5633 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5634 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5637 gen_helper_vfp_negs(tmp
, tmp
);
5639 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5640 tcg_temp_free_i32(tmp3
);
5641 tcg_temp_free_ptr(fpstatus
);
5647 tcg_temp_free_i32(tmp2
);
5649 /* Save the result. For elementwise operations we can put it
5650 straight into the destination register. For pairwise operations
5651 we have to be careful to avoid clobbering the source operands. */
5652 if (pairwise
&& rd
== rm
) {
5653 neon_store_scratch(pass
, tmp
);
5655 neon_store_reg(rd
, pass
, tmp
);
5659 if (pairwise
&& rd
== rm
) {
5660 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5661 tmp
= neon_load_scratch(pass
);
5662 neon_store_reg(rd
, pass
, tmp
);
5665 /* End of 3 register same size operations. */
5666 } else if (insn
& (1 << 4)) {
5667 if ((insn
& 0x00380080) != 0) {
5668 /* Two registers and shift. */
5669 op
= (insn
>> 8) & 0xf;
5670 if (insn
& (1 << 7)) {
5678 while ((insn
& (1 << (size
+ 19))) == 0)
5681 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5682 /* To avoid excessive duplication of ops we implement shift
5683 by immediate using the variable shift operations. */
5685 /* Shift by immediate:
5686 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5687 if (q
&& ((rd
| rm
) & 1)) {
5690 if (!u
&& (op
== 4 || op
== 6)) {
5693 /* Right shifts are encoded as N - shift, where N is the
5694 element size in bits. */
5696 shift
= shift
- (1 << (size
+ 3));
5704 imm
= (uint8_t) shift
;
5709 imm
= (uint16_t) shift
;
5720 for (pass
= 0; pass
< count
; pass
++) {
5722 neon_load_reg64(cpu_V0
, rm
+ pass
);
5723 tcg_gen_movi_i64(cpu_V1
, imm
);
5728 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5730 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5735 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5737 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5740 case 5: /* VSHL, VSLI */
5741 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5743 case 6: /* VQSHLU */
5744 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5749 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5752 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5757 if (op
== 1 || op
== 3) {
5759 neon_load_reg64(cpu_V1
, rd
+ pass
);
5760 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5761 } else if (op
== 4 || (op
== 5 && u
)) {
5763 neon_load_reg64(cpu_V1
, rd
+ pass
);
5765 if (shift
< -63 || shift
> 63) {
5769 mask
= 0xffffffffffffffffull
>> -shift
;
5771 mask
= 0xffffffffffffffffull
<< shift
;
5774 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5775 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5777 neon_store_reg64(cpu_V0
, rd
+ pass
);
5778 } else { /* size < 3 */
5779 /* Operands in T0 and T1. */
5780 tmp
= neon_load_reg(rm
, pass
);
5781 tmp2
= tcg_temp_new_i32();
5782 tcg_gen_movi_i32(tmp2
, imm
);
5786 GEN_NEON_INTEGER_OP(shl
);
5790 GEN_NEON_INTEGER_OP(rshl
);
5793 case 5: /* VSHL, VSLI */
5795 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5796 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5797 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5801 case 6: /* VQSHLU */
5804 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5808 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5812 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5820 GEN_NEON_INTEGER_OP_ENV(qshl
);
5823 tcg_temp_free_i32(tmp2
);
5825 if (op
== 1 || op
== 3) {
5827 tmp2
= neon_load_reg(rd
, pass
);
5828 gen_neon_add(size
, tmp
, tmp2
);
5829 tcg_temp_free_i32(tmp2
);
5830 } else if (op
== 4 || (op
== 5 && u
)) {
5835 mask
= 0xff >> -shift
;
5837 mask
= (uint8_t)(0xff << shift
);
5843 mask
= 0xffff >> -shift
;
5845 mask
= (uint16_t)(0xffff << shift
);
5849 if (shift
< -31 || shift
> 31) {
5853 mask
= 0xffffffffu
>> -shift
;
5855 mask
= 0xffffffffu
<< shift
;
5861 tmp2
= neon_load_reg(rd
, pass
);
5862 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5863 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5864 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5865 tcg_temp_free_i32(tmp2
);
5867 neon_store_reg(rd
, pass
, tmp
);
5870 } else if (op
< 10) {
5871 /* Shift by immediate and narrow:
5872 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5873 int input_unsigned
= (op
== 8) ? !u
: u
;
5877 shift
= shift
- (1 << (size
+ 3));
5880 tmp64
= tcg_const_i64(shift
);
5881 neon_load_reg64(cpu_V0
, rm
);
5882 neon_load_reg64(cpu_V1
, rm
+ 1);
5883 for (pass
= 0; pass
< 2; pass
++) {
5891 if (input_unsigned
) {
5892 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5894 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5897 if (input_unsigned
) {
5898 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5900 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5903 tmp
= tcg_temp_new_i32();
5904 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5905 neon_store_reg(rd
, pass
, tmp
);
5907 tcg_temp_free_i64(tmp64
);
5910 imm
= (uint16_t)shift
;
5914 imm
= (uint32_t)shift
;
5916 tmp2
= tcg_const_i32(imm
);
5917 tmp4
= neon_load_reg(rm
+ 1, 0);
5918 tmp5
= neon_load_reg(rm
+ 1, 1);
5919 for (pass
= 0; pass
< 2; pass
++) {
5921 tmp
= neon_load_reg(rm
, 0);
5925 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5928 tmp3
= neon_load_reg(rm
, 1);
5932 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5934 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5935 tcg_temp_free_i32(tmp
);
5936 tcg_temp_free_i32(tmp3
);
5937 tmp
= tcg_temp_new_i32();
5938 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5939 neon_store_reg(rd
, pass
, tmp
);
5941 tcg_temp_free_i32(tmp2
);
5943 } else if (op
== 10) {
5945 if (q
|| (rd
& 1)) {
5948 tmp
= neon_load_reg(rm
, 0);
5949 tmp2
= neon_load_reg(rm
, 1);
5950 for (pass
= 0; pass
< 2; pass
++) {
5954 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5957 /* The shift is less than the width of the source
5958 type, so we can just shift the whole register. */
5959 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5960 /* Widen the result of shift: we need to clear
5961 * the potential overflow bits resulting from
5962 * left bits of the narrow input appearing as
5963 * right bits of left the neighbour narrow
5965 if (size
< 2 || !u
) {
5968 imm
= (0xffu
>> (8 - shift
));
5970 } else if (size
== 1) {
5971 imm
= 0xffff >> (16 - shift
);
5974 imm
= 0xffffffff >> (32 - shift
);
5977 imm64
= imm
| (((uint64_t)imm
) << 32);
5981 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5984 neon_store_reg64(cpu_V0
, rd
+ pass
);
5986 } else if (op
>= 14) {
5987 /* VCVT fixed-point. */
5988 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5991 /* We have already masked out the must-be-1 top bit of imm6,
5992 * hence this 32-shift where the ARM ARM has 64-imm6.
5995 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5996 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5999 gen_vfp_ulto(0, shift
, 1);
6001 gen_vfp_slto(0, shift
, 1);
6004 gen_vfp_toul(0, shift
, 1);
6006 gen_vfp_tosl(0, shift
, 1);
6008 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6013 } else { /* (insn & 0x00380080) == 0 */
6015 if (q
&& (rd
& 1)) {
6019 op
= (insn
>> 8) & 0xf;
6020 /* One register and immediate. */
6021 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6022 invert
= (insn
& (1 << 5)) != 0;
6023 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6024 * We choose to not special-case this and will behave as if a
6025 * valid constant encoding of 0 had been given.
6044 imm
= (imm
<< 8) | (imm
<< 24);
6047 imm
= (imm
<< 8) | 0xff;
6050 imm
= (imm
<< 16) | 0xffff;
6053 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6061 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6062 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6068 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6069 if (op
& 1 && op
< 12) {
6070 tmp
= neon_load_reg(rd
, pass
);
6072 /* The immediate value has already been inverted, so
6074 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6076 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6080 tmp
= tcg_temp_new_i32();
6081 if (op
== 14 && invert
) {
6085 for (n
= 0; n
< 4; n
++) {
6086 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6087 val
|= 0xff << (n
* 8);
6089 tcg_gen_movi_i32(tmp
, val
);
6091 tcg_gen_movi_i32(tmp
, imm
);
6094 neon_store_reg(rd
, pass
, tmp
);
6097 } else { /* (insn & 0x00800010 == 0x00800000) */
6099 op
= (insn
>> 8) & 0xf;
6100 if ((insn
& (1 << 6)) == 0) {
6101 /* Three registers of different lengths. */
6105 /* undefreq: bit 0 : UNDEF if size == 0
6106 * bit 1 : UNDEF if size == 1
6107 * bit 2 : UNDEF if size == 2
6108 * bit 3 : UNDEF if U == 1
6109 * Note that [2:0] set implies 'always UNDEF'
6112 /* prewiden, src1_wide, src2_wide, undefreq */
6113 static const int neon_3reg_wide
[16][4] = {
6114 {1, 0, 0, 0}, /* VADDL */
6115 {1, 1, 0, 0}, /* VADDW */
6116 {1, 0, 0, 0}, /* VSUBL */
6117 {1, 1, 0, 0}, /* VSUBW */
6118 {0, 1, 1, 0}, /* VADDHN */
6119 {0, 0, 0, 0}, /* VABAL */
6120 {0, 1, 1, 0}, /* VSUBHN */
6121 {0, 0, 0, 0}, /* VABDL */
6122 {0, 0, 0, 0}, /* VMLAL */
6123 {0, 0, 0, 9}, /* VQDMLAL */
6124 {0, 0, 0, 0}, /* VMLSL */
6125 {0, 0, 0, 9}, /* VQDMLSL */
6126 {0, 0, 0, 0}, /* Integer VMULL */
6127 {0, 0, 0, 1}, /* VQDMULL */
6128 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6129 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6132 prewiden
= neon_3reg_wide
[op
][0];
6133 src1_wide
= neon_3reg_wide
[op
][1];
6134 src2_wide
= neon_3reg_wide
[op
][2];
6135 undefreq
= neon_3reg_wide
[op
][3];
6137 if ((undefreq
& (1 << size
)) ||
6138 ((undefreq
& 8) && u
)) {
6141 if ((src1_wide
&& (rn
& 1)) ||
6142 (src2_wide
&& (rm
& 1)) ||
6143 (!src2_wide
&& (rd
& 1))) {
6147 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6148 * outside the loop below as it only performs a single pass.
6150 if (op
== 14 && size
== 2) {
6151 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6153 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6156 tcg_rn
= tcg_temp_new_i64();
6157 tcg_rm
= tcg_temp_new_i64();
6158 tcg_rd
= tcg_temp_new_i64();
6159 neon_load_reg64(tcg_rn
, rn
);
6160 neon_load_reg64(tcg_rm
, rm
);
6161 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6162 neon_store_reg64(tcg_rd
, rd
);
6163 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6164 neon_store_reg64(tcg_rd
, rd
+ 1);
6165 tcg_temp_free_i64(tcg_rn
);
6166 tcg_temp_free_i64(tcg_rm
);
6167 tcg_temp_free_i64(tcg_rd
);
6171 /* Avoid overlapping operands. Wide source operands are
6172 always aligned so will never overlap with wide
6173 destinations in problematic ways. */
6174 if (rd
== rm
&& !src2_wide
) {
6175 tmp
= neon_load_reg(rm
, 1);
6176 neon_store_scratch(2, tmp
);
6177 } else if (rd
== rn
&& !src1_wide
) {
6178 tmp
= neon_load_reg(rn
, 1);
6179 neon_store_scratch(2, tmp
);
6181 TCGV_UNUSED_I32(tmp3
);
6182 for (pass
= 0; pass
< 2; pass
++) {
6184 neon_load_reg64(cpu_V0
, rn
+ pass
);
6185 TCGV_UNUSED_I32(tmp
);
6187 if (pass
== 1 && rd
== rn
) {
6188 tmp
= neon_load_scratch(2);
6190 tmp
= neon_load_reg(rn
, pass
);
6193 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6197 neon_load_reg64(cpu_V1
, rm
+ pass
);
6198 TCGV_UNUSED_I32(tmp2
);
6200 if (pass
== 1 && rd
== rm
) {
6201 tmp2
= neon_load_scratch(2);
6203 tmp2
= neon_load_reg(rm
, pass
);
6206 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6210 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6211 gen_neon_addl(size
);
6213 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6214 gen_neon_subl(size
);
6216 case 5: case 7: /* VABAL, VABDL */
6217 switch ((size
<< 1) | u
) {
6219 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6222 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6225 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6228 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6231 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6234 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6238 tcg_temp_free_i32(tmp2
);
6239 tcg_temp_free_i32(tmp
);
6241 case 8: case 9: case 10: case 11: case 12: case 13:
6242 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6243 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6245 case 14: /* Polynomial VMULL */
6246 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6247 tcg_temp_free_i32(tmp2
);
6248 tcg_temp_free_i32(tmp
);
6250 default: /* 15 is RESERVED: caught earlier */
6255 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6256 neon_store_reg64(cpu_V0
, rd
+ pass
);
6257 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6259 neon_load_reg64(cpu_V1
, rd
+ pass
);
6261 case 10: /* VMLSL */
6262 gen_neon_negl(cpu_V0
, size
);
6264 case 5: case 8: /* VABAL, VMLAL */
6265 gen_neon_addl(size
);
6267 case 9: case 11: /* VQDMLAL, VQDMLSL */
6268 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6270 gen_neon_negl(cpu_V0
, size
);
6272 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6277 neon_store_reg64(cpu_V0
, rd
+ pass
);
6278 } else if (op
== 4 || op
== 6) {
6279 /* Narrowing operation. */
6280 tmp
= tcg_temp_new_i32();
6284 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6287 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6290 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6291 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6298 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6301 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6304 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6305 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6306 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6314 neon_store_reg(rd
, 0, tmp3
);
6315 neon_store_reg(rd
, 1, tmp
);
6318 /* Write back the result. */
6319 neon_store_reg64(cpu_V0
, rd
+ pass
);
6323 /* Two registers and a scalar. NB that for ops of this form
6324 * the ARM ARM labels bit 24 as Q, but it is in our variable
6331 case 1: /* Float VMLA scalar */
6332 case 5: /* Floating point VMLS scalar */
6333 case 9: /* Floating point VMUL scalar */
6338 case 0: /* Integer VMLA scalar */
6339 case 4: /* Integer VMLS scalar */
6340 case 8: /* Integer VMUL scalar */
6341 case 12: /* VQDMULH scalar */
6342 case 13: /* VQRDMULH scalar */
6343 if (u
&& ((rd
| rn
) & 1)) {
6346 tmp
= neon_get_scalar(size
, rm
);
6347 neon_store_scratch(0, tmp
);
6348 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6349 tmp
= neon_load_scratch(0);
6350 tmp2
= neon_load_reg(rn
, pass
);
6353 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6355 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6357 } else if (op
== 13) {
6359 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6361 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6363 } else if (op
& 1) {
6364 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6365 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6366 tcg_temp_free_ptr(fpstatus
);
6369 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6370 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6371 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6375 tcg_temp_free_i32(tmp2
);
6378 tmp2
= neon_load_reg(rd
, pass
);
6381 gen_neon_add(size
, tmp
, tmp2
);
6385 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6386 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6387 tcg_temp_free_ptr(fpstatus
);
6391 gen_neon_rsb(size
, tmp
, tmp2
);
6395 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6396 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6397 tcg_temp_free_ptr(fpstatus
);
6403 tcg_temp_free_i32(tmp2
);
6405 neon_store_reg(rd
, pass
, tmp
);
6408 case 3: /* VQDMLAL scalar */
6409 case 7: /* VQDMLSL scalar */
6410 case 11: /* VQDMULL scalar */
6415 case 2: /* VMLAL sclar */
6416 case 6: /* VMLSL scalar */
6417 case 10: /* VMULL scalar */
6421 tmp2
= neon_get_scalar(size
, rm
);
6422 /* We need a copy of tmp2 because gen_neon_mull
6423 * deletes it during pass 0. */
6424 tmp4
= tcg_temp_new_i32();
6425 tcg_gen_mov_i32(tmp4
, tmp2
);
6426 tmp3
= neon_load_reg(rn
, 1);
6428 for (pass
= 0; pass
< 2; pass
++) {
6430 tmp
= neon_load_reg(rn
, 0);
6435 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6437 neon_load_reg64(cpu_V1
, rd
+ pass
);
6441 gen_neon_negl(cpu_V0
, size
);
6444 gen_neon_addl(size
);
6447 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6449 gen_neon_negl(cpu_V0
, size
);
6451 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6457 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6462 neon_store_reg64(cpu_V0
, rd
+ pass
);
6467 default: /* 14 and 15 are RESERVED */
6471 } else { /* size == 3 */
6474 imm
= (insn
>> 8) & 0xf;
6479 if (q
&& ((rd
| rn
| rm
) & 1)) {
6484 neon_load_reg64(cpu_V0
, rn
);
6486 neon_load_reg64(cpu_V1
, rn
+ 1);
6488 } else if (imm
== 8) {
6489 neon_load_reg64(cpu_V0
, rn
+ 1);
6491 neon_load_reg64(cpu_V1
, rm
);
6494 tmp64
= tcg_temp_new_i64();
6496 neon_load_reg64(cpu_V0
, rn
);
6497 neon_load_reg64(tmp64
, rn
+ 1);
6499 neon_load_reg64(cpu_V0
, rn
+ 1);
6500 neon_load_reg64(tmp64
, rm
);
6502 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6503 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6504 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6506 neon_load_reg64(cpu_V1
, rm
);
6508 neon_load_reg64(cpu_V1
, rm
+ 1);
6511 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6512 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6513 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6514 tcg_temp_free_i64(tmp64
);
6517 neon_load_reg64(cpu_V0
, rn
);
6518 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6519 neon_load_reg64(cpu_V1
, rm
);
6520 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6521 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6523 neon_store_reg64(cpu_V0
, rd
);
6525 neon_store_reg64(cpu_V1
, rd
+ 1);
6527 } else if ((insn
& (1 << 11)) == 0) {
6528 /* Two register misc. */
6529 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6530 size
= (insn
>> 18) & 3;
6531 /* UNDEF for unknown op values and bad op-size combinations */
6532 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6535 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6536 q
&& ((rm
| rd
) & 1)) {
6540 case NEON_2RM_VREV64
:
6541 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6542 tmp
= neon_load_reg(rm
, pass
* 2);
6543 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6545 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6546 case 1: gen_swap_half(tmp
); break;
6547 case 2: /* no-op */ break;
6550 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6552 neon_store_reg(rd
, pass
* 2, tmp2
);
6555 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6556 case 1: gen_swap_half(tmp2
); break;
6559 neon_store_reg(rd
, pass
* 2, tmp2
);
6563 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6564 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6565 for (pass
= 0; pass
< q
+ 1; pass
++) {
6566 tmp
= neon_load_reg(rm
, pass
* 2);
6567 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6568 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6569 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6571 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6572 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6573 case 2: tcg_gen_add_i64(CPU_V001
); break;
6576 if (op
>= NEON_2RM_VPADAL
) {
6578 neon_load_reg64(cpu_V1
, rd
+ pass
);
6579 gen_neon_addl(size
);
6581 neon_store_reg64(cpu_V0
, rd
+ pass
);
6587 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6588 tmp
= neon_load_reg(rm
, n
);
6589 tmp2
= neon_load_reg(rd
, n
+ 1);
6590 neon_store_reg(rm
, n
, tmp2
);
6591 neon_store_reg(rd
, n
+ 1, tmp
);
6598 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6603 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6607 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6608 /* also VQMOVUN; op field and mnemonics don't line up */
6612 TCGV_UNUSED_I32(tmp2
);
6613 for (pass
= 0; pass
< 2; pass
++) {
6614 neon_load_reg64(cpu_V0
, rm
+ pass
);
6615 tmp
= tcg_temp_new_i32();
6616 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6621 neon_store_reg(rd
, 0, tmp2
);
6622 neon_store_reg(rd
, 1, tmp
);
6626 case NEON_2RM_VSHLL
:
6627 if (q
|| (rd
& 1)) {
6630 tmp
= neon_load_reg(rm
, 0);
6631 tmp2
= neon_load_reg(rm
, 1);
6632 for (pass
= 0; pass
< 2; pass
++) {
6635 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6636 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6637 neon_store_reg64(cpu_V0
, rd
+ pass
);
6640 case NEON_2RM_VCVT_F16_F32
:
6641 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6645 tmp
= tcg_temp_new_i32();
6646 tmp2
= tcg_temp_new_i32();
6647 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6648 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6649 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6650 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6651 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6652 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6653 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6654 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6655 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6656 neon_store_reg(rd
, 0, tmp2
);
6657 tmp2
= tcg_temp_new_i32();
6658 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6659 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6660 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6661 neon_store_reg(rd
, 1, tmp2
);
6662 tcg_temp_free_i32(tmp
);
6664 case NEON_2RM_VCVT_F32_F16
:
6665 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6669 tmp3
= tcg_temp_new_i32();
6670 tmp
= neon_load_reg(rm
, 0);
6671 tmp2
= neon_load_reg(rm
, 1);
6672 tcg_gen_ext16u_i32(tmp3
, tmp
);
6673 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6674 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6675 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6676 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6677 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6678 tcg_temp_free_i32(tmp
);
6679 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6680 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6681 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6682 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6683 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6684 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6685 tcg_temp_free_i32(tmp2
);
6686 tcg_temp_free_i32(tmp3
);
6688 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6689 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6690 || ((rm
| rd
) & 1)) {
6693 tmp
= tcg_const_i32(rd
);
6694 tmp2
= tcg_const_i32(rm
);
6696 /* Bit 6 is the lowest opcode bit; it distinguishes between
6697 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6699 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6701 if (op
== NEON_2RM_AESE
) {
6702 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6704 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6706 tcg_temp_free_i32(tmp
);
6707 tcg_temp_free_i32(tmp2
);
6708 tcg_temp_free_i32(tmp3
);
6710 case NEON_2RM_SHA1H
:
6711 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
6712 || ((rm
| rd
) & 1)) {
6715 tmp
= tcg_const_i32(rd
);
6716 tmp2
= tcg_const_i32(rm
);
6718 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6720 tcg_temp_free_i32(tmp
);
6721 tcg_temp_free_i32(tmp2
);
6723 case NEON_2RM_SHA1SU1
:
6724 if ((rm
| rd
) & 1) {
6727 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6729 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
6732 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
6735 tmp
= tcg_const_i32(rd
);
6736 tmp2
= tcg_const_i32(rm
);
6738 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6740 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6742 tcg_temp_free_i32(tmp
);
6743 tcg_temp_free_i32(tmp2
);
6747 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6748 if (neon_2rm_is_float_op(op
)) {
6749 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6750 neon_reg_offset(rm
, pass
));
6751 TCGV_UNUSED_I32(tmp
);
6753 tmp
= neon_load_reg(rm
, pass
);
6756 case NEON_2RM_VREV32
:
6758 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6759 case 1: gen_swap_half(tmp
); break;
6763 case NEON_2RM_VREV16
:
6768 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6769 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6770 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6776 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6777 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6778 case 2: gen_helper_clz(tmp
, tmp
); break;
6783 gen_helper_neon_cnt_u8(tmp
, tmp
);
6786 tcg_gen_not_i32(tmp
, tmp
);
6788 case NEON_2RM_VQABS
:
6791 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6794 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6797 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6802 case NEON_2RM_VQNEG
:
6805 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6808 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6811 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6816 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6817 tmp2
= tcg_const_i32(0);
6819 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6820 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6821 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6824 tcg_temp_free_i32(tmp2
);
6825 if (op
== NEON_2RM_VCLE0
) {
6826 tcg_gen_not_i32(tmp
, tmp
);
6829 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6830 tmp2
= tcg_const_i32(0);
6832 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6833 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6834 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6837 tcg_temp_free_i32(tmp2
);
6838 if (op
== NEON_2RM_VCLT0
) {
6839 tcg_gen_not_i32(tmp
, tmp
);
6842 case NEON_2RM_VCEQ0
:
6843 tmp2
= tcg_const_i32(0);
6845 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6846 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6847 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6850 tcg_temp_free_i32(tmp2
);
6854 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6855 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6856 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6861 tmp2
= tcg_const_i32(0);
6862 gen_neon_rsb(size
, tmp
, tmp2
);
6863 tcg_temp_free_i32(tmp2
);
6865 case NEON_2RM_VCGT0_F
:
6867 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6868 tmp2
= tcg_const_i32(0);
6869 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6870 tcg_temp_free_i32(tmp2
);
6871 tcg_temp_free_ptr(fpstatus
);
6874 case NEON_2RM_VCGE0_F
:
6876 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6877 tmp2
= tcg_const_i32(0);
6878 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6879 tcg_temp_free_i32(tmp2
);
6880 tcg_temp_free_ptr(fpstatus
);
6883 case NEON_2RM_VCEQ0_F
:
6885 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6886 tmp2
= tcg_const_i32(0);
6887 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6888 tcg_temp_free_i32(tmp2
);
6889 tcg_temp_free_ptr(fpstatus
);
6892 case NEON_2RM_VCLE0_F
:
6894 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6895 tmp2
= tcg_const_i32(0);
6896 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6897 tcg_temp_free_i32(tmp2
);
6898 tcg_temp_free_ptr(fpstatus
);
6901 case NEON_2RM_VCLT0_F
:
6903 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6904 tmp2
= tcg_const_i32(0);
6905 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6906 tcg_temp_free_i32(tmp2
);
6907 tcg_temp_free_ptr(fpstatus
);
6910 case NEON_2RM_VABS_F
:
6913 case NEON_2RM_VNEG_F
:
6917 tmp2
= neon_load_reg(rd
, pass
);
6918 neon_store_reg(rm
, pass
, tmp2
);
6921 tmp2
= neon_load_reg(rd
, pass
);
6923 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6924 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6927 neon_store_reg(rm
, pass
, tmp2
);
6929 case NEON_2RM_VRINTN
:
6930 case NEON_2RM_VRINTA
:
6931 case NEON_2RM_VRINTM
:
6932 case NEON_2RM_VRINTP
:
6933 case NEON_2RM_VRINTZ
:
6936 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6939 if (op
== NEON_2RM_VRINTZ
) {
6940 rmode
= FPROUNDING_ZERO
;
6942 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6945 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6946 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6948 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6949 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6951 tcg_temp_free_ptr(fpstatus
);
6952 tcg_temp_free_i32(tcg_rmode
);
6955 case NEON_2RM_VRINTX
:
6957 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6958 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6959 tcg_temp_free_ptr(fpstatus
);
6962 case NEON_2RM_VCVTAU
:
6963 case NEON_2RM_VCVTAS
:
6964 case NEON_2RM_VCVTNU
:
6965 case NEON_2RM_VCVTNS
:
6966 case NEON_2RM_VCVTPU
:
6967 case NEON_2RM_VCVTPS
:
6968 case NEON_2RM_VCVTMU
:
6969 case NEON_2RM_VCVTMS
:
6971 bool is_signed
= !extract32(insn
, 7, 1);
6972 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6973 TCGv_i32 tcg_rmode
, tcg_shift
;
6974 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6976 tcg_shift
= tcg_const_i32(0);
6977 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6978 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6982 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6985 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6989 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6991 tcg_temp_free_i32(tcg_rmode
);
6992 tcg_temp_free_i32(tcg_shift
);
6993 tcg_temp_free_ptr(fpst
);
6996 case NEON_2RM_VRECPE
:
6998 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6999 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7000 tcg_temp_free_ptr(fpstatus
);
7003 case NEON_2RM_VRSQRTE
:
7005 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7006 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7007 tcg_temp_free_ptr(fpstatus
);
7010 case NEON_2RM_VRECPE_F
:
7012 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7013 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7014 tcg_temp_free_ptr(fpstatus
);
7017 case NEON_2RM_VRSQRTE_F
:
7019 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7020 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7021 tcg_temp_free_ptr(fpstatus
);
7024 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7027 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7030 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7031 gen_vfp_tosiz(0, 1);
7033 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7034 gen_vfp_touiz(0, 1);
7037 /* Reserved op values were caught by the
7038 * neon_2rm_sizes[] check earlier.
7042 if (neon_2rm_is_float_op(op
)) {
7043 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7044 neon_reg_offset(rd
, pass
));
7046 neon_store_reg(rd
, pass
, tmp
);
7051 } else if ((insn
& (1 << 10)) == 0) {
7053 int n
= ((insn
>> 8) & 3) + 1;
7054 if ((rn
+ n
) > 32) {
7055 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7056 * helper function running off the end of the register file.
7061 if (insn
& (1 << 6)) {
7062 tmp
= neon_load_reg(rd
, 0);
7064 tmp
= tcg_temp_new_i32();
7065 tcg_gen_movi_i32(tmp
, 0);
7067 tmp2
= neon_load_reg(rm
, 0);
7068 tmp4
= tcg_const_i32(rn
);
7069 tmp5
= tcg_const_i32(n
);
7070 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7071 tcg_temp_free_i32(tmp
);
7072 if (insn
& (1 << 6)) {
7073 tmp
= neon_load_reg(rd
, 1);
7075 tmp
= tcg_temp_new_i32();
7076 tcg_gen_movi_i32(tmp
, 0);
7078 tmp3
= neon_load_reg(rm
, 1);
7079 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7080 tcg_temp_free_i32(tmp5
);
7081 tcg_temp_free_i32(tmp4
);
7082 neon_store_reg(rd
, 0, tmp2
);
7083 neon_store_reg(rd
, 1, tmp3
);
7084 tcg_temp_free_i32(tmp
);
7085 } else if ((insn
& 0x380) == 0) {
7087 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7090 if (insn
& (1 << 19)) {
7091 tmp
= neon_load_reg(rm
, 1);
7093 tmp
= neon_load_reg(rm
, 0);
7095 if (insn
& (1 << 16)) {
7096 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7097 } else if (insn
& (1 << 17)) {
7098 if ((insn
>> 18) & 1)
7099 gen_neon_dup_high16(tmp
);
7101 gen_neon_dup_low16(tmp
);
7103 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7104 tmp2
= tcg_temp_new_i32();
7105 tcg_gen_mov_i32(tmp2
, tmp
);
7106 neon_store_reg(rd
, pass
, tmp2
);
7108 tcg_temp_free_i32(tmp
);
7117 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7119 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7120 const ARMCPRegInfo
*ri
;
7122 cpnum
= (insn
>> 8) & 0xf;
7124 /* First check for coprocessor space used for XScale/iwMMXt insns */
7125 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7126 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7129 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7130 return disas_iwmmxt_insn(s
, insn
);
7131 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7132 return disas_dsp_insn(s
, insn
);
7137 /* Otherwise treat as a generic register access */
7138 is64
= (insn
& (1 << 25)) == 0;
7139 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7147 opc1
= (insn
>> 4) & 0xf;
7149 rt2
= (insn
>> 16) & 0xf;
7151 crn
= (insn
>> 16) & 0xf;
7152 opc1
= (insn
>> 21) & 7;
7153 opc2
= (insn
>> 5) & 7;
7156 isread
= (insn
>> 20) & 1;
7157 rt
= (insn
>> 12) & 0xf;
7159 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7160 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7162 /* Check access permissions */
7163 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7168 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7169 /* Emit code to perform further access permissions checks at
7170 * runtime; this may result in an exception.
7171 * Note that on XScale all cp0..c13 registers do an access check
7172 * call in order to handle c15_cpar.
7178 /* Note that since we are an implementation which takes an
7179 * exception on a trapped conditional instruction only if the
7180 * instruction passes its condition code check, we can take
7181 * advantage of the clause in the ARM ARM that allows us to set
7182 * the COND field in the instruction to 0xE in all cases.
7183 * We could fish the actual condition out of the insn (ARM)
7184 * or the condexec bits (Thumb) but it isn't necessary.
7189 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7192 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7193 rt
, isread
, s
->thumb
);
7198 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7201 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7202 rt
, isread
, s
->thumb
);
7206 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7207 * so this can only happen if this is an ARMv7 or earlier CPU,
7208 * in which case the syndrome information won't actually be
7211 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7212 syndrome
= syn_uncategorized();
7216 gen_set_condexec(s
);
7217 gen_set_pc_im(s
, s
->pc
- 4);
7218 tmpptr
= tcg_const_ptr(ri
);
7219 tcg_syn
= tcg_const_i32(syndrome
);
7220 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7221 tcg_temp_free_ptr(tmpptr
);
7222 tcg_temp_free_i32(tcg_syn
);
7225 /* Handle special cases first */
7226 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7233 gen_set_pc_im(s
, s
->pc
);
7234 s
->is_jmp
= DISAS_WFI
;
7240 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7249 if (ri
->type
& ARM_CP_CONST
) {
7250 tmp64
= tcg_const_i64(ri
->resetvalue
);
7251 } else if (ri
->readfn
) {
7253 tmp64
= tcg_temp_new_i64();
7254 tmpptr
= tcg_const_ptr(ri
);
7255 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7256 tcg_temp_free_ptr(tmpptr
);
7258 tmp64
= tcg_temp_new_i64();
7259 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7261 tmp
= tcg_temp_new_i32();
7262 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7263 store_reg(s
, rt
, tmp
);
7264 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7265 tmp
= tcg_temp_new_i32();
7266 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7267 tcg_temp_free_i64(tmp64
);
7268 store_reg(s
, rt2
, tmp
);
7271 if (ri
->type
& ARM_CP_CONST
) {
7272 tmp
= tcg_const_i32(ri
->resetvalue
);
7273 } else if (ri
->readfn
) {
7275 tmp
= tcg_temp_new_i32();
7276 tmpptr
= tcg_const_ptr(ri
);
7277 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7278 tcg_temp_free_ptr(tmpptr
);
7280 tmp
= load_cpu_offset(ri
->fieldoffset
);
7283 /* Destination register of r15 for 32 bit loads sets
7284 * the condition codes from the high 4 bits of the value
7287 tcg_temp_free_i32(tmp
);
7289 store_reg(s
, rt
, tmp
);
7294 if (ri
->type
& ARM_CP_CONST
) {
7295 /* If not forbidden by access permissions, treat as WI */
7300 TCGv_i32 tmplo
, tmphi
;
7301 TCGv_i64 tmp64
= tcg_temp_new_i64();
7302 tmplo
= load_reg(s
, rt
);
7303 tmphi
= load_reg(s
, rt2
);
7304 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7305 tcg_temp_free_i32(tmplo
);
7306 tcg_temp_free_i32(tmphi
);
7308 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7309 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7310 tcg_temp_free_ptr(tmpptr
);
7312 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7314 tcg_temp_free_i64(tmp64
);
7319 tmp
= load_reg(s
, rt
);
7320 tmpptr
= tcg_const_ptr(ri
);
7321 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7322 tcg_temp_free_ptr(tmpptr
);
7323 tcg_temp_free_i32(tmp
);
7325 TCGv_i32 tmp
= load_reg(s
, rt
);
7326 store_cpu_offset(tmp
, ri
->fieldoffset
);
7331 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7332 /* I/O operations must end the TB here (whether read or write) */
7335 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7336 /* We default to ending the TB on a coprocessor register write,
7337 * but allow this to be suppressed by the register definition
7338 * (usually only necessary to work around guest bugs).
7346 /* Unknown register; this might be a guest error or a QEMU
7347 * unimplemented feature.
7350 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7351 "64 bit system register cp:%d opc1: %d crm:%d "
7353 isread
? "read" : "write", cpnum
, opc1
, crm
,
7354 s
->ns
? "non-secure" : "secure");
7356 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7357 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7359 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7360 s
->ns
? "non-secure" : "secure");
7367 /* Store a 64-bit value to a register pair. Clobbers val. */
7368 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7371 tmp
= tcg_temp_new_i32();
7372 tcg_gen_extrl_i64_i32(tmp
, val
);
7373 store_reg(s
, rlow
, tmp
);
7374 tmp
= tcg_temp_new_i32();
7375 tcg_gen_shri_i64(val
, val
, 32);
7376 tcg_gen_extrl_i64_i32(tmp
, val
);
7377 store_reg(s
, rhigh
, tmp
);
7380 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7381 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7386 /* Load value and extend to 64 bits. */
7387 tmp
= tcg_temp_new_i64();
7388 tmp2
= load_reg(s
, rlow
);
7389 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7390 tcg_temp_free_i32(tmp2
);
7391 tcg_gen_add_i64(val
, val
, tmp
);
7392 tcg_temp_free_i64(tmp
);
7395 /* load and add a 64-bit value from a register pair. */
7396 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7402 /* Load 64-bit value rd:rn. */
7403 tmpl
= load_reg(s
, rlow
);
7404 tmph
= load_reg(s
, rhigh
);
7405 tmp
= tcg_temp_new_i64();
7406 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7407 tcg_temp_free_i32(tmpl
);
7408 tcg_temp_free_i32(tmph
);
7409 tcg_gen_add_i64(val
, val
, tmp
);
7410 tcg_temp_free_i64(tmp
);
7413 /* Set N and Z flags from hi|lo. */
7414 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7416 tcg_gen_mov_i32(cpu_NF
, hi
);
7417 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7420 /* Load/Store exclusive instructions are implemented by remembering
7421 the value/address loaded, and seeing if these are the same
7422 when the store is performed. This should be sufficient to implement
7423 the architecturally mandated semantics, and avoids having to monitor
7426 In system emulation mode only one CPU will be running at once, so
7427 this sequence is effectively atomic. In user emulation mode we
7428 throw an exception and handle the atomic operation elsewhere. */
7429 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7430 TCGv_i32 addr
, int size
)
7432 TCGv_i32 tmp
= tcg_temp_new_i32();
7438 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7441 gen_aa32_ld16ua(tmp
, addr
, get_mem_index(s
));
7445 gen_aa32_ld32ua(tmp
, addr
, get_mem_index(s
));
7452 TCGv_i32 tmp2
= tcg_temp_new_i32();
7453 TCGv_i32 tmp3
= tcg_temp_new_i32();
7455 tcg_gen_addi_i32(tmp2
, addr
, 4);
7456 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7457 tcg_temp_free_i32(tmp2
);
7458 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7459 store_reg(s
, rt2
, tmp3
);
7461 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7464 store_reg(s
, rt
, tmp
);
7465 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7468 static void gen_clrex(DisasContext
*s
)
7470 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7473 #ifdef CONFIG_USER_ONLY
7474 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7475 TCGv_i32 addr
, int size
)
7477 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7478 tcg_gen_movi_i32(cpu_exclusive_info
,
7479 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7480 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7483 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7484 TCGv_i32 addr
, int size
)
7487 TCGv_i64 val64
, extaddr
;
7488 TCGLabel
*done_label
;
7489 TCGLabel
*fail_label
;
7491 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7497 fail_label
= gen_new_label();
7498 done_label
= gen_new_label();
7499 extaddr
= tcg_temp_new_i64();
7500 tcg_gen_extu_i32_i64(extaddr
, addr
);
7501 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7502 tcg_temp_free_i64(extaddr
);
7504 tmp
= tcg_temp_new_i32();
7507 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7510 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7514 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7520 val64
= tcg_temp_new_i64();
7522 TCGv_i32 tmp2
= tcg_temp_new_i32();
7523 TCGv_i32 tmp3
= tcg_temp_new_i32();
7524 tcg_gen_addi_i32(tmp2
, addr
, 4);
7525 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7526 tcg_temp_free_i32(tmp2
);
7527 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7528 tcg_temp_free_i32(tmp3
);
7530 tcg_gen_extu_i32_i64(val64
, tmp
);
7532 tcg_temp_free_i32(tmp
);
7534 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7535 tcg_temp_free_i64(val64
);
7537 tmp
= load_reg(s
, rt
);
7540 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7543 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7547 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7552 tcg_temp_free_i32(tmp
);
7554 tcg_gen_addi_i32(addr
, addr
, 4);
7555 tmp
= load_reg(s
, rt2
);
7556 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7557 tcg_temp_free_i32(tmp
);
7559 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7560 tcg_gen_br(done_label
);
7561 gen_set_label(fail_label
);
7562 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7563 gen_set_label(done_label
);
7564 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7571 * @mode: mode field from insn (which stack to store to)
7572 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7573 * @writeback: true if writeback bit set
7575 * Generate code for the SRS (Store Return State) insn.
7577 static void gen_srs(DisasContext
*s
,
7578 uint32_t mode
, uint32_t amode
, bool writeback
)
7581 TCGv_i32 addr
= tcg_temp_new_i32();
7582 TCGv_i32 tmp
= tcg_const_i32(mode
);
7583 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7584 tcg_temp_free_i32(tmp
);
7601 tcg_gen_addi_i32(addr
, addr
, offset
);
7602 tmp
= load_reg(s
, 14);
7603 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7604 tcg_temp_free_i32(tmp
);
7605 tmp
= load_cpu_field(spsr
);
7606 tcg_gen_addi_i32(addr
, addr
, 4);
7607 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7608 tcg_temp_free_i32(tmp
);
7626 tcg_gen_addi_i32(addr
, addr
, offset
);
7627 tmp
= tcg_const_i32(mode
);
7628 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7629 tcg_temp_free_i32(tmp
);
7631 tcg_temp_free_i32(addr
);
7634 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7636 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7643 /* M variants do not implement ARM mode. */
7644 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7649 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7650 * choose to UNDEF. In ARMv5 and above the space is used
7651 * for miscellaneous unconditional instructions.
7655 /* Unconditional instructions. */
7656 if (((insn
>> 25) & 7) == 1) {
7657 /* NEON Data processing. */
7658 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7662 if (disas_neon_data_insn(s
, insn
)) {
7667 if ((insn
& 0x0f100000) == 0x04000000) {
7668 /* NEON load/store. */
7669 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7673 if (disas_neon_ls_insn(s
, insn
)) {
7678 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7680 if (disas_vfp_insn(s
, insn
)) {
7685 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7686 ((insn
& 0x0f30f010) == 0x0710f000)) {
7687 if ((insn
& (1 << 22)) == 0) {
7689 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7693 /* Otherwise PLD; v5TE+ */
7697 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7698 ((insn
& 0x0f70f010) == 0x0650f000)) {
7700 return; /* PLI; V7 */
7702 if (((insn
& 0x0f700000) == 0x04100000) ||
7703 ((insn
& 0x0f700010) == 0x06100000)) {
7704 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7707 return; /* v7MP: Unallocated memory hint: must NOP */
7710 if ((insn
& 0x0ffffdff) == 0x01010000) {
7713 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7714 /* Dynamic endianness switching not implemented. */
7715 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7719 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7720 switch ((insn
>> 4) & 0xf) {
7728 /* We don't emulate caches so these are a no-op. */
7731 /* We need to break the TB after this insn to execute
7732 * self-modifying code correctly and also to take
7733 * any pending interrupts immediately.
7740 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7746 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7748 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7754 rn
= (insn
>> 16) & 0xf;
7755 addr
= load_reg(s
, rn
);
7756 i
= (insn
>> 23) & 3;
7758 case 0: offset
= -4; break; /* DA */
7759 case 1: offset
= 0; break; /* IA */
7760 case 2: offset
= -8; break; /* DB */
7761 case 3: offset
= 4; break; /* IB */
7765 tcg_gen_addi_i32(addr
, addr
, offset
);
7766 /* Load PC into tmp and CPSR into tmp2. */
7767 tmp
= tcg_temp_new_i32();
7768 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7769 tcg_gen_addi_i32(addr
, addr
, 4);
7770 tmp2
= tcg_temp_new_i32();
7771 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7772 if (insn
& (1 << 21)) {
7773 /* Base writeback. */
7775 case 0: offset
= -8; break;
7776 case 1: offset
= 4; break;
7777 case 2: offset
= -4; break;
7778 case 3: offset
= 0; break;
7782 tcg_gen_addi_i32(addr
, addr
, offset
);
7783 store_reg(s
, rn
, addr
);
7785 tcg_temp_free_i32(addr
);
7787 gen_rfe(s
, tmp
, tmp2
);
7789 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7790 /* branch link and change to thumb (blx <offset>) */
7793 val
= (uint32_t)s
->pc
;
7794 tmp
= tcg_temp_new_i32();
7795 tcg_gen_movi_i32(tmp
, val
);
7796 store_reg(s
, 14, tmp
);
7797 /* Sign-extend the 24-bit offset */
7798 offset
= (((int32_t)insn
) << 8) >> 8;
7799 /* offset * 4 + bit24 * 2 + (thumb bit) */
7800 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7801 /* pipeline offset */
7803 /* protected by ARCH(5); above, near the start of uncond block */
7806 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7807 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7808 /* iWMMXt register transfer. */
7809 if (extract32(s
->c15_cpar
, 1, 1)) {
7810 if (!disas_iwmmxt_insn(s
, insn
)) {
7815 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7816 /* Coprocessor double register transfer. */
7818 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7819 /* Additional coprocessor register transfer. */
7820 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7823 /* cps (privileged) */
7827 if (insn
& (1 << 19)) {
7828 if (insn
& (1 << 8))
7830 if (insn
& (1 << 7))
7832 if (insn
& (1 << 6))
7834 if (insn
& (1 << 18))
7837 if (insn
& (1 << 17)) {
7839 val
|= (insn
& 0x1f);
7842 gen_set_psr_im(s
, mask
, 0, val
);
7849 /* if not always execute, we generate a conditional jump to
7851 s
->condlabel
= gen_new_label();
7852 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7855 if ((insn
& 0x0f900000) == 0x03000000) {
7856 if ((insn
& (1 << 21)) == 0) {
7858 rd
= (insn
>> 12) & 0xf;
7859 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7860 if ((insn
& (1 << 22)) == 0) {
7862 tmp
= tcg_temp_new_i32();
7863 tcg_gen_movi_i32(tmp
, val
);
7866 tmp
= load_reg(s
, rd
);
7867 tcg_gen_ext16u_i32(tmp
, tmp
);
7868 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7870 store_reg(s
, rd
, tmp
);
7872 if (((insn
>> 12) & 0xf) != 0xf)
7874 if (((insn
>> 16) & 0xf) == 0) {
7875 gen_nop_hint(s
, insn
& 0xff);
7877 /* CPSR = immediate */
7879 shift
= ((insn
>> 8) & 0xf) * 2;
7881 val
= (val
>> shift
) | (val
<< (32 - shift
));
7882 i
= ((insn
& (1 << 22)) != 0);
7883 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
7889 } else if ((insn
& 0x0f900000) == 0x01000000
7890 && (insn
& 0x00000090) != 0x00000090) {
7891 /* miscellaneous instructions */
7892 op1
= (insn
>> 21) & 3;
7893 sh
= (insn
>> 4) & 0xf;
7896 case 0x0: /* move program status register */
7899 tmp
= load_reg(s
, rm
);
7900 i
= ((op1
& 2) != 0);
7901 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7905 rd
= (insn
>> 12) & 0xf;
7909 tmp
= load_cpu_field(spsr
);
7911 tmp
= tcg_temp_new_i32();
7912 gen_helper_cpsr_read(tmp
, cpu_env
);
7914 store_reg(s
, rd
, tmp
);
7919 /* branch/exchange thumb (bx). */
7921 tmp
= load_reg(s
, rm
);
7923 } else if (op1
== 3) {
7926 rd
= (insn
>> 12) & 0xf;
7927 tmp
= load_reg(s
, rm
);
7928 gen_helper_clz(tmp
, tmp
);
7929 store_reg(s
, rd
, tmp
);
7937 /* Trivial implementation equivalent to bx. */
7938 tmp
= load_reg(s
, rm
);
7949 /* branch link/exchange thumb (blx) */
7950 tmp
= load_reg(s
, rm
);
7951 tmp2
= tcg_temp_new_i32();
7952 tcg_gen_movi_i32(tmp2
, s
->pc
);
7953 store_reg(s
, 14, tmp2
);
7959 uint32_t c
= extract32(insn
, 8, 4);
7961 /* Check this CPU supports ARMv8 CRC instructions.
7962 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7963 * Bits 8, 10 and 11 should be zero.
7965 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7970 rn
= extract32(insn
, 16, 4);
7971 rd
= extract32(insn
, 12, 4);
7973 tmp
= load_reg(s
, rn
);
7974 tmp2
= load_reg(s
, rm
);
7976 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7977 } else if (op1
== 1) {
7978 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7980 tmp3
= tcg_const_i32(1 << op1
);
7982 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7984 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7986 tcg_temp_free_i32(tmp2
);
7987 tcg_temp_free_i32(tmp3
);
7988 store_reg(s
, rd
, tmp
);
7991 case 0x5: /* saturating add/subtract */
7993 rd
= (insn
>> 12) & 0xf;
7994 rn
= (insn
>> 16) & 0xf;
7995 tmp
= load_reg(s
, rm
);
7996 tmp2
= load_reg(s
, rn
);
7998 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8000 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8002 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8003 tcg_temp_free_i32(tmp2
);
8004 store_reg(s
, rd
, tmp
);
8008 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8013 gen_exception_insn(s
, 4, EXCP_BKPT
,
8014 syn_aa32_bkpt(imm16
, false),
8015 default_exception_el(s
));
8018 /* Hypervisor call (v7) */
8026 /* Secure monitor call (v6+) */
8038 case 0x8: /* signed multiply */
8043 rs
= (insn
>> 8) & 0xf;
8044 rn
= (insn
>> 12) & 0xf;
8045 rd
= (insn
>> 16) & 0xf;
8047 /* (32 * 16) >> 16 */
8048 tmp
= load_reg(s
, rm
);
8049 tmp2
= load_reg(s
, rs
);
8051 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8054 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8055 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8056 tmp
= tcg_temp_new_i32();
8057 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8058 tcg_temp_free_i64(tmp64
);
8059 if ((sh
& 2) == 0) {
8060 tmp2
= load_reg(s
, rn
);
8061 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8062 tcg_temp_free_i32(tmp2
);
8064 store_reg(s
, rd
, tmp
);
8067 tmp
= load_reg(s
, rm
);
8068 tmp2
= load_reg(s
, rs
);
8069 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8070 tcg_temp_free_i32(tmp2
);
8072 tmp64
= tcg_temp_new_i64();
8073 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8074 tcg_temp_free_i32(tmp
);
8075 gen_addq(s
, tmp64
, rn
, rd
);
8076 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8077 tcg_temp_free_i64(tmp64
);
8080 tmp2
= load_reg(s
, rn
);
8081 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8082 tcg_temp_free_i32(tmp2
);
8084 store_reg(s
, rd
, tmp
);
8091 } else if (((insn
& 0x0e000000) == 0 &&
8092 (insn
& 0x00000090) != 0x90) ||
8093 ((insn
& 0x0e000000) == (1 << 25))) {
8094 int set_cc
, logic_cc
, shiftop
;
8096 op1
= (insn
>> 21) & 0xf;
8097 set_cc
= (insn
>> 20) & 1;
8098 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8100 /* data processing instruction */
8101 if (insn
& (1 << 25)) {
8102 /* immediate operand */
8104 shift
= ((insn
>> 8) & 0xf) * 2;
8106 val
= (val
>> shift
) | (val
<< (32 - shift
));
8108 tmp2
= tcg_temp_new_i32();
8109 tcg_gen_movi_i32(tmp2
, val
);
8110 if (logic_cc
&& shift
) {
8111 gen_set_CF_bit31(tmp2
);
8116 tmp2
= load_reg(s
, rm
);
8117 shiftop
= (insn
>> 5) & 3;
8118 if (!(insn
& (1 << 4))) {
8119 shift
= (insn
>> 7) & 0x1f;
8120 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8122 rs
= (insn
>> 8) & 0xf;
8123 tmp
= load_reg(s
, rs
);
8124 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8127 if (op1
!= 0x0f && op1
!= 0x0d) {
8128 rn
= (insn
>> 16) & 0xf;
8129 tmp
= load_reg(s
, rn
);
8131 TCGV_UNUSED_I32(tmp
);
8133 rd
= (insn
>> 12) & 0xf;
8136 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8140 store_reg_bx(s
, rd
, tmp
);
8143 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8147 store_reg_bx(s
, rd
, tmp
);
8150 if (set_cc
&& rd
== 15) {
8151 /* SUBS r15, ... is used for exception return. */
8155 gen_sub_CC(tmp
, tmp
, tmp2
);
8156 gen_exception_return(s
, tmp
);
8159 gen_sub_CC(tmp
, tmp
, tmp2
);
8161 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8163 store_reg_bx(s
, rd
, tmp
);
8168 gen_sub_CC(tmp
, tmp2
, tmp
);
8170 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8172 store_reg_bx(s
, rd
, tmp
);
8176 gen_add_CC(tmp
, tmp
, tmp2
);
8178 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8180 store_reg_bx(s
, rd
, tmp
);
8184 gen_adc_CC(tmp
, tmp
, tmp2
);
8186 gen_add_carry(tmp
, tmp
, tmp2
);
8188 store_reg_bx(s
, rd
, tmp
);
8192 gen_sbc_CC(tmp
, tmp
, tmp2
);
8194 gen_sub_carry(tmp
, tmp
, tmp2
);
8196 store_reg_bx(s
, rd
, tmp
);
8200 gen_sbc_CC(tmp
, tmp2
, tmp
);
8202 gen_sub_carry(tmp
, tmp2
, tmp
);
8204 store_reg_bx(s
, rd
, tmp
);
8208 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8211 tcg_temp_free_i32(tmp
);
8215 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8218 tcg_temp_free_i32(tmp
);
8222 gen_sub_CC(tmp
, tmp
, tmp2
);
8224 tcg_temp_free_i32(tmp
);
8228 gen_add_CC(tmp
, tmp
, tmp2
);
8230 tcg_temp_free_i32(tmp
);
8233 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8237 store_reg_bx(s
, rd
, tmp
);
8240 if (logic_cc
&& rd
== 15) {
8241 /* MOVS r15, ... is used for exception return. */
8245 gen_exception_return(s
, tmp2
);
8250 store_reg_bx(s
, rd
, tmp2
);
8254 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8258 store_reg_bx(s
, rd
, tmp
);
8262 tcg_gen_not_i32(tmp2
, tmp2
);
8266 store_reg_bx(s
, rd
, tmp2
);
8269 if (op1
!= 0x0f && op1
!= 0x0d) {
8270 tcg_temp_free_i32(tmp2
);
8273 /* other instructions */
8274 op1
= (insn
>> 24) & 0xf;
8278 /* multiplies, extra load/stores */
8279 sh
= (insn
>> 5) & 3;
8282 rd
= (insn
>> 16) & 0xf;
8283 rn
= (insn
>> 12) & 0xf;
8284 rs
= (insn
>> 8) & 0xf;
8286 op1
= (insn
>> 20) & 0xf;
8288 case 0: case 1: case 2: case 3: case 6:
8290 tmp
= load_reg(s
, rs
);
8291 tmp2
= load_reg(s
, rm
);
8292 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8293 tcg_temp_free_i32(tmp2
);
8294 if (insn
& (1 << 22)) {
8295 /* Subtract (mls) */
8297 tmp2
= load_reg(s
, rn
);
8298 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8299 tcg_temp_free_i32(tmp2
);
8300 } else if (insn
& (1 << 21)) {
8302 tmp2
= load_reg(s
, rn
);
8303 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8304 tcg_temp_free_i32(tmp2
);
8306 if (insn
& (1 << 20))
8308 store_reg(s
, rd
, tmp
);
8311 /* 64 bit mul double accumulate (UMAAL) */
8313 tmp
= load_reg(s
, rs
);
8314 tmp2
= load_reg(s
, rm
);
8315 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8316 gen_addq_lo(s
, tmp64
, rn
);
8317 gen_addq_lo(s
, tmp64
, rd
);
8318 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8319 tcg_temp_free_i64(tmp64
);
8321 case 8: case 9: case 10: case 11:
8322 case 12: case 13: case 14: case 15:
8323 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8324 tmp
= load_reg(s
, rs
);
8325 tmp2
= load_reg(s
, rm
);
8326 if (insn
& (1 << 22)) {
8327 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8329 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8331 if (insn
& (1 << 21)) { /* mult accumulate */
8332 TCGv_i32 al
= load_reg(s
, rn
);
8333 TCGv_i32 ah
= load_reg(s
, rd
);
8334 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8335 tcg_temp_free_i32(al
);
8336 tcg_temp_free_i32(ah
);
8338 if (insn
& (1 << 20)) {
8339 gen_logicq_cc(tmp
, tmp2
);
8341 store_reg(s
, rn
, tmp
);
8342 store_reg(s
, rd
, tmp2
);
8348 rn
= (insn
>> 16) & 0xf;
8349 rd
= (insn
>> 12) & 0xf;
8350 if (insn
& (1 << 23)) {
8351 /* load/store exclusive */
8352 int op2
= (insn
>> 8) & 3;
8353 op1
= (insn
>> 21) & 0x3;
8356 case 0: /* lda/stl */
8362 case 1: /* reserved */
8364 case 2: /* ldaex/stlex */
8367 case 3: /* ldrex/strex */
8376 addr
= tcg_temp_local_new_i32();
8377 load_reg_var(s
, addr
, rn
);
8379 /* Since the emulation does not have barriers,
8380 the acquire/release semantics need no special
8383 if (insn
& (1 << 20)) {
8384 tmp
= tcg_temp_new_i32();
8387 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8390 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8393 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8398 store_reg(s
, rd
, tmp
);
8401 tmp
= load_reg(s
, rm
);
8404 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8407 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8410 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8415 tcg_temp_free_i32(tmp
);
8417 } else if (insn
& (1 << 20)) {
8420 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8422 case 1: /* ldrexd */
8423 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8425 case 2: /* ldrexb */
8426 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8428 case 3: /* ldrexh */
8429 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8438 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8440 case 1: /* strexd */
8441 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8443 case 2: /* strexb */
8444 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8446 case 3: /* strexh */
8447 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8453 tcg_temp_free_i32(addr
);
8455 /* SWP instruction */
8458 /* ??? This is not really atomic. However we know
8459 we never have multiple CPUs running in parallel,
8460 so it is good enough. */
8461 addr
= load_reg(s
, rn
);
8462 tmp
= load_reg(s
, rm
);
8463 tmp2
= tcg_temp_new_i32();
8464 if (insn
& (1 << 22)) {
8465 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8466 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8468 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8469 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8471 tcg_temp_free_i32(tmp
);
8472 tcg_temp_free_i32(addr
);
8473 store_reg(s
, rd
, tmp2
);
8478 bool load
= insn
& (1 << 20);
8479 bool doubleword
= false;
8480 /* Misc load/store */
8481 rn
= (insn
>> 16) & 0xf;
8482 rd
= (insn
>> 12) & 0xf;
8484 if (!load
&& (sh
& 2)) {
8488 /* UNPREDICTABLE; we choose to UNDEF */
8491 load
= (sh
& 1) == 0;
8495 addr
= load_reg(s
, rn
);
8496 if (insn
& (1 << 24))
8497 gen_add_datah_offset(s
, insn
, 0, addr
);
8503 tmp
= load_reg(s
, rd
);
8504 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8505 tcg_temp_free_i32(tmp
);
8506 tcg_gen_addi_i32(addr
, addr
, 4);
8507 tmp
= load_reg(s
, rd
+ 1);
8508 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8509 tcg_temp_free_i32(tmp
);
8512 tmp
= tcg_temp_new_i32();
8513 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8514 store_reg(s
, rd
, tmp
);
8515 tcg_gen_addi_i32(addr
, addr
, 4);
8516 tmp
= tcg_temp_new_i32();
8517 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8520 address_offset
= -4;
8523 tmp
= tcg_temp_new_i32();
8526 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8529 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8533 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8538 tmp
= load_reg(s
, rd
);
8539 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8540 tcg_temp_free_i32(tmp
);
8542 /* Perform base writeback before the loaded value to
8543 ensure correct behavior with overlapping index registers.
8544 ldrd with base writeback is undefined if the
8545 destination and index registers overlap. */
8546 if (!(insn
& (1 << 24))) {
8547 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8548 store_reg(s
, rn
, addr
);
8549 } else if (insn
& (1 << 21)) {
8551 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8552 store_reg(s
, rn
, addr
);
8554 tcg_temp_free_i32(addr
);
8557 /* Complete the load. */
8558 store_reg(s
, rd
, tmp
);
8567 if (insn
& (1 << 4)) {
8569 /* Armv6 Media instructions. */
8571 rn
= (insn
>> 16) & 0xf;
8572 rd
= (insn
>> 12) & 0xf;
8573 rs
= (insn
>> 8) & 0xf;
8574 switch ((insn
>> 23) & 3) {
8575 case 0: /* Parallel add/subtract. */
8576 op1
= (insn
>> 20) & 7;
8577 tmp
= load_reg(s
, rn
);
8578 tmp2
= load_reg(s
, rm
);
8579 sh
= (insn
>> 5) & 7;
8580 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8582 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8583 tcg_temp_free_i32(tmp2
);
8584 store_reg(s
, rd
, tmp
);
8587 if ((insn
& 0x00700020) == 0) {
8588 /* Halfword pack. */
8589 tmp
= load_reg(s
, rn
);
8590 tmp2
= load_reg(s
, rm
);
8591 shift
= (insn
>> 7) & 0x1f;
8592 if (insn
& (1 << 6)) {
8596 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8597 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8598 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8602 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8603 tcg_gen_ext16u_i32(tmp
, tmp
);
8604 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8606 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8607 tcg_temp_free_i32(tmp2
);
8608 store_reg(s
, rd
, tmp
);
8609 } else if ((insn
& 0x00200020) == 0x00200000) {
8611 tmp
= load_reg(s
, rm
);
8612 shift
= (insn
>> 7) & 0x1f;
8613 if (insn
& (1 << 6)) {
8616 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8618 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8620 sh
= (insn
>> 16) & 0x1f;
8621 tmp2
= tcg_const_i32(sh
);
8622 if (insn
& (1 << 22))
8623 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8625 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8626 tcg_temp_free_i32(tmp2
);
8627 store_reg(s
, rd
, tmp
);
8628 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8630 tmp
= load_reg(s
, rm
);
8631 sh
= (insn
>> 16) & 0x1f;
8632 tmp2
= tcg_const_i32(sh
);
8633 if (insn
& (1 << 22))
8634 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8636 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8637 tcg_temp_free_i32(tmp2
);
8638 store_reg(s
, rd
, tmp
);
8639 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8641 tmp
= load_reg(s
, rn
);
8642 tmp2
= load_reg(s
, rm
);
8643 tmp3
= tcg_temp_new_i32();
8644 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8645 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8646 tcg_temp_free_i32(tmp3
);
8647 tcg_temp_free_i32(tmp2
);
8648 store_reg(s
, rd
, tmp
);
8649 } else if ((insn
& 0x000003e0) == 0x00000060) {
8650 tmp
= load_reg(s
, rm
);
8651 shift
= (insn
>> 10) & 3;
8652 /* ??? In many cases it's not necessary to do a
8653 rotate, a shift is sufficient. */
8655 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8656 op1
= (insn
>> 20) & 7;
8658 case 0: gen_sxtb16(tmp
); break;
8659 case 2: gen_sxtb(tmp
); break;
8660 case 3: gen_sxth(tmp
); break;
8661 case 4: gen_uxtb16(tmp
); break;
8662 case 6: gen_uxtb(tmp
); break;
8663 case 7: gen_uxth(tmp
); break;
8664 default: goto illegal_op
;
8667 tmp2
= load_reg(s
, rn
);
8668 if ((op1
& 3) == 0) {
8669 gen_add16(tmp
, tmp2
);
8671 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8672 tcg_temp_free_i32(tmp2
);
8675 store_reg(s
, rd
, tmp
);
8676 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8678 tmp
= load_reg(s
, rm
);
8679 if (insn
& (1 << 22)) {
8680 if (insn
& (1 << 7)) {
8684 gen_helper_rbit(tmp
, tmp
);
8687 if (insn
& (1 << 7))
8690 tcg_gen_bswap32_i32(tmp
, tmp
);
8692 store_reg(s
, rd
, tmp
);
8697 case 2: /* Multiplies (Type 3). */
8698 switch ((insn
>> 20) & 0x7) {
8700 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8701 /* op2 not 00x or 11x : UNDEF */
8704 /* Signed multiply most significant [accumulate].
8705 (SMMUL, SMMLA, SMMLS) */
8706 tmp
= load_reg(s
, rm
);
8707 tmp2
= load_reg(s
, rs
);
8708 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8711 tmp
= load_reg(s
, rd
);
8712 if (insn
& (1 << 6)) {
8713 tmp64
= gen_subq_msw(tmp64
, tmp
);
8715 tmp64
= gen_addq_msw(tmp64
, tmp
);
8718 if (insn
& (1 << 5)) {
8719 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8721 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8722 tmp
= tcg_temp_new_i32();
8723 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8724 tcg_temp_free_i64(tmp64
);
8725 store_reg(s
, rn
, tmp
);
8729 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8730 if (insn
& (1 << 7)) {
8733 tmp
= load_reg(s
, rm
);
8734 tmp2
= load_reg(s
, rs
);
8735 if (insn
& (1 << 5))
8736 gen_swap_half(tmp2
);
8737 gen_smul_dual(tmp
, tmp2
);
8738 if (insn
& (1 << 22)) {
8739 /* smlald, smlsld */
8742 tmp64
= tcg_temp_new_i64();
8743 tmp64_2
= tcg_temp_new_i64();
8744 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8745 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8746 tcg_temp_free_i32(tmp
);
8747 tcg_temp_free_i32(tmp2
);
8748 if (insn
& (1 << 6)) {
8749 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8751 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8753 tcg_temp_free_i64(tmp64_2
);
8754 gen_addq(s
, tmp64
, rd
, rn
);
8755 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8756 tcg_temp_free_i64(tmp64
);
8758 /* smuad, smusd, smlad, smlsd */
8759 if (insn
& (1 << 6)) {
8760 /* This subtraction cannot overflow. */
8761 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8763 /* This addition cannot overflow 32 bits;
8764 * however it may overflow considered as a
8765 * signed operation, in which case we must set
8768 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8770 tcg_temp_free_i32(tmp2
);
8773 tmp2
= load_reg(s
, rd
);
8774 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8775 tcg_temp_free_i32(tmp2
);
8777 store_reg(s
, rn
, tmp
);
8783 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
8786 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8789 tmp
= load_reg(s
, rm
);
8790 tmp2
= load_reg(s
, rs
);
8791 if (insn
& (1 << 21)) {
8792 gen_helper_udiv(tmp
, tmp
, tmp2
);
8794 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8796 tcg_temp_free_i32(tmp2
);
8797 store_reg(s
, rn
, tmp
);
8804 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8806 case 0: /* Unsigned sum of absolute differences. */
8808 tmp
= load_reg(s
, rm
);
8809 tmp2
= load_reg(s
, rs
);
8810 gen_helper_usad8(tmp
, tmp
, tmp2
);
8811 tcg_temp_free_i32(tmp2
);
8813 tmp2
= load_reg(s
, rd
);
8814 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8815 tcg_temp_free_i32(tmp2
);
8817 store_reg(s
, rn
, tmp
);
8819 case 0x20: case 0x24: case 0x28: case 0x2c:
8820 /* Bitfield insert/clear. */
8822 shift
= (insn
>> 7) & 0x1f;
8823 i
= (insn
>> 16) & 0x1f;
8825 /* UNPREDICTABLE; we choose to UNDEF */
8830 tmp
= tcg_temp_new_i32();
8831 tcg_gen_movi_i32(tmp
, 0);
8833 tmp
= load_reg(s
, rm
);
8836 tmp2
= load_reg(s
, rd
);
8837 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8838 tcg_temp_free_i32(tmp2
);
8840 store_reg(s
, rd
, tmp
);
8842 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8843 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8845 tmp
= load_reg(s
, rm
);
8846 shift
= (insn
>> 7) & 0x1f;
8847 i
= ((insn
>> 16) & 0x1f) + 1;
8852 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8854 gen_sbfx(tmp
, shift
, i
);
8857 store_reg(s
, rd
, tmp
);
8867 /* Check for undefined extension instructions
8868 * per the ARM Bible IE:
8869 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8871 sh
= (0xf << 20) | (0xf << 4);
8872 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8876 /* load/store byte/word */
8877 rn
= (insn
>> 16) & 0xf;
8878 rd
= (insn
>> 12) & 0xf;
8879 tmp2
= load_reg(s
, rn
);
8880 if ((insn
& 0x01200000) == 0x00200000) {
8882 i
= get_a32_user_mem_index(s
);
8884 i
= get_mem_index(s
);
8886 if (insn
& (1 << 24))
8887 gen_add_data_offset(s
, insn
, tmp2
);
8888 if (insn
& (1 << 20)) {
8890 tmp
= tcg_temp_new_i32();
8891 if (insn
& (1 << 22)) {
8892 gen_aa32_ld8u(tmp
, tmp2
, i
);
8894 gen_aa32_ld32u(tmp
, tmp2
, i
);
8898 tmp
= load_reg(s
, rd
);
8899 if (insn
& (1 << 22)) {
8900 gen_aa32_st8(tmp
, tmp2
, i
);
8902 gen_aa32_st32(tmp
, tmp2
, i
);
8904 tcg_temp_free_i32(tmp
);
8906 if (!(insn
& (1 << 24))) {
8907 gen_add_data_offset(s
, insn
, tmp2
);
8908 store_reg(s
, rn
, tmp2
);
8909 } else if (insn
& (1 << 21)) {
8910 store_reg(s
, rn
, tmp2
);
8912 tcg_temp_free_i32(tmp2
);
8914 if (insn
& (1 << 20)) {
8915 /* Complete the load. */
8916 store_reg_from_load(s
, rd
, tmp
);
8922 int j
, n
, loaded_base
;
8923 bool exc_return
= false;
8924 bool is_load
= extract32(insn
, 20, 1);
8926 TCGv_i32 loaded_var
;
8927 /* load/store multiple words */
8928 /* XXX: store correct base if write back */
8929 if (insn
& (1 << 22)) {
8930 /* LDM (user), LDM (exception return) and STM (user) */
8932 goto illegal_op
; /* only usable in supervisor mode */
8934 if (is_load
&& extract32(insn
, 15, 1)) {
8940 rn
= (insn
>> 16) & 0xf;
8941 addr
= load_reg(s
, rn
);
8943 /* compute total size */
8945 TCGV_UNUSED_I32(loaded_var
);
8948 if (insn
& (1 << i
))
8951 /* XXX: test invalid n == 0 case ? */
8952 if (insn
& (1 << 23)) {
8953 if (insn
& (1 << 24)) {
8955 tcg_gen_addi_i32(addr
, addr
, 4);
8957 /* post increment */
8960 if (insn
& (1 << 24)) {
8962 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8964 /* post decrement */
8966 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8971 if (insn
& (1 << i
)) {
8974 tmp
= tcg_temp_new_i32();
8975 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8977 tmp2
= tcg_const_i32(i
);
8978 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8979 tcg_temp_free_i32(tmp2
);
8980 tcg_temp_free_i32(tmp
);
8981 } else if (i
== rn
) {
8985 store_reg_from_load(s
, i
, tmp
);
8990 /* special case: r15 = PC + 8 */
8991 val
= (long)s
->pc
+ 4;
8992 tmp
= tcg_temp_new_i32();
8993 tcg_gen_movi_i32(tmp
, val
);
8995 tmp
= tcg_temp_new_i32();
8996 tmp2
= tcg_const_i32(i
);
8997 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8998 tcg_temp_free_i32(tmp2
);
9000 tmp
= load_reg(s
, i
);
9002 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9003 tcg_temp_free_i32(tmp
);
9006 /* no need to add after the last transfer */
9008 tcg_gen_addi_i32(addr
, addr
, 4);
9011 if (insn
& (1 << 21)) {
9013 if (insn
& (1 << 23)) {
9014 if (insn
& (1 << 24)) {
9017 /* post increment */
9018 tcg_gen_addi_i32(addr
, addr
, 4);
9021 if (insn
& (1 << 24)) {
9024 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9026 /* post decrement */
9027 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9030 store_reg(s
, rn
, addr
);
9032 tcg_temp_free_i32(addr
);
9035 store_reg(s
, rn
, loaded_var
);
9038 /* Restore CPSR from SPSR. */
9039 tmp
= load_cpu_field(spsr
);
9040 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
9041 tcg_temp_free_i32(tmp
);
9042 s
->is_jmp
= DISAS_JUMP
;
9051 /* branch (and link) */
9052 val
= (int32_t)s
->pc
;
9053 if (insn
& (1 << 24)) {
9054 tmp
= tcg_temp_new_i32();
9055 tcg_gen_movi_i32(tmp
, val
);
9056 store_reg(s
, 14, tmp
);
9058 offset
= sextract32(insn
<< 2, 0, 26);
9066 if (((insn
>> 8) & 0xe) == 10) {
9068 if (disas_vfp_insn(s
, insn
)) {
9071 } else if (disas_coproc_insn(s
, insn
)) {
9078 gen_set_pc_im(s
, s
->pc
);
9079 s
->svc_imm
= extract32(insn
, 0, 24);
9080 s
->is_jmp
= DISAS_SWI
;
9084 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9085 default_exception_el(s
));
9091 /* Return true if this is a Thumb-2 logical op. */
9093 thumb2_logic_op(int op
)
9098 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9099 then set condition code flags based on the result of the operation.
9100 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9101 to the high bit of T1.
9102 Returns zero if the opcode is valid. */
9105 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9106 TCGv_i32 t0
, TCGv_i32 t1
)
9113 tcg_gen_and_i32(t0
, t0
, t1
);
9117 tcg_gen_andc_i32(t0
, t0
, t1
);
9121 tcg_gen_or_i32(t0
, t0
, t1
);
9125 tcg_gen_orc_i32(t0
, t0
, t1
);
9129 tcg_gen_xor_i32(t0
, t0
, t1
);
9134 gen_add_CC(t0
, t0
, t1
);
9136 tcg_gen_add_i32(t0
, t0
, t1
);
9140 gen_adc_CC(t0
, t0
, t1
);
9146 gen_sbc_CC(t0
, t0
, t1
);
9148 gen_sub_carry(t0
, t0
, t1
);
9153 gen_sub_CC(t0
, t0
, t1
);
9155 tcg_gen_sub_i32(t0
, t0
, t1
);
9159 gen_sub_CC(t0
, t1
, t0
);
9161 tcg_gen_sub_i32(t0
, t1
, t0
);
9163 default: /* 5, 6, 7, 9, 12, 15. */
9169 gen_set_CF_bit31(t1
);
9174 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9176 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9178 uint32_t insn
, imm
, shift
, offset
;
9179 uint32_t rd
, rn
, rm
, rs
;
9190 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9191 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9192 /* Thumb-1 cores may need to treat bl and blx as a pair of
9193 16-bit instructions to get correct prefetch abort behavior. */
9195 if ((insn
& (1 << 12)) == 0) {
9197 /* Second half of blx. */
9198 offset
= ((insn
& 0x7ff) << 1);
9199 tmp
= load_reg(s
, 14);
9200 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9201 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9203 tmp2
= tcg_temp_new_i32();
9204 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9205 store_reg(s
, 14, tmp2
);
9209 if (insn
& (1 << 11)) {
9210 /* Second half of bl. */
9211 offset
= ((insn
& 0x7ff) << 1) | 1;
9212 tmp
= load_reg(s
, 14);
9213 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9215 tmp2
= tcg_temp_new_i32();
9216 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9217 store_reg(s
, 14, tmp2
);
9221 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9222 /* Instruction spans a page boundary. Implement it as two
9223 16-bit instructions in case the second half causes an
9225 offset
= ((int32_t)insn
<< 21) >> 9;
9226 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9229 /* Fall through to 32-bit decode. */
9232 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9234 insn
|= (uint32_t)insn_hw1
<< 16;
9236 if ((insn
& 0xf800e800) != 0xf000e800) {
9240 rn
= (insn
>> 16) & 0xf;
9241 rs
= (insn
>> 12) & 0xf;
9242 rd
= (insn
>> 8) & 0xf;
9244 switch ((insn
>> 25) & 0xf) {
9245 case 0: case 1: case 2: case 3:
9246 /* 16-bit instructions. Should never happen. */
9249 if (insn
& (1 << 22)) {
9250 /* Other load/store, table branch. */
9251 if (insn
& 0x01200000) {
9252 /* Load/store doubleword. */
9254 addr
= tcg_temp_new_i32();
9255 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9257 addr
= load_reg(s
, rn
);
9259 offset
= (insn
& 0xff) * 4;
9260 if ((insn
& (1 << 23)) == 0)
9262 if (insn
& (1 << 24)) {
9263 tcg_gen_addi_i32(addr
, addr
, offset
);
9266 if (insn
& (1 << 20)) {
9268 tmp
= tcg_temp_new_i32();
9269 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9270 store_reg(s
, rs
, tmp
);
9271 tcg_gen_addi_i32(addr
, addr
, 4);
9272 tmp
= tcg_temp_new_i32();
9273 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9274 store_reg(s
, rd
, tmp
);
9277 tmp
= load_reg(s
, rs
);
9278 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9279 tcg_temp_free_i32(tmp
);
9280 tcg_gen_addi_i32(addr
, addr
, 4);
9281 tmp
= load_reg(s
, rd
);
9282 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9283 tcg_temp_free_i32(tmp
);
9285 if (insn
& (1 << 21)) {
9286 /* Base writeback. */
9289 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9290 store_reg(s
, rn
, addr
);
9292 tcg_temp_free_i32(addr
);
9294 } else if ((insn
& (1 << 23)) == 0) {
9295 /* Load/store exclusive word. */
9296 addr
= tcg_temp_local_new_i32();
9297 load_reg_var(s
, addr
, rn
);
9298 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9299 if (insn
& (1 << 20)) {
9300 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9302 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9304 tcg_temp_free_i32(addr
);
9305 } else if ((insn
& (7 << 5)) == 0) {
9308 addr
= tcg_temp_new_i32();
9309 tcg_gen_movi_i32(addr
, s
->pc
);
9311 addr
= load_reg(s
, rn
);
9313 tmp
= load_reg(s
, rm
);
9314 tcg_gen_add_i32(addr
, addr
, tmp
);
9315 if (insn
& (1 << 4)) {
9317 tcg_gen_add_i32(addr
, addr
, tmp
);
9318 tcg_temp_free_i32(tmp
);
9319 tmp
= tcg_temp_new_i32();
9320 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9322 tcg_temp_free_i32(tmp
);
9323 tmp
= tcg_temp_new_i32();
9324 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9326 tcg_temp_free_i32(addr
);
9327 tcg_gen_shli_i32(tmp
, tmp
, 1);
9328 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9329 store_reg(s
, 15, tmp
);
9331 int op2
= (insn
>> 6) & 0x3;
9332 op
= (insn
>> 4) & 0x3;
9337 /* Load/store exclusive byte/halfword/doubleword */
9344 /* Load-acquire/store-release */
9350 /* Load-acquire/store-release exclusive */
9354 addr
= tcg_temp_local_new_i32();
9355 load_reg_var(s
, addr
, rn
);
9357 if (insn
& (1 << 20)) {
9358 tmp
= tcg_temp_new_i32();
9361 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9364 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9367 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9372 store_reg(s
, rs
, tmp
);
9374 tmp
= load_reg(s
, rs
);
9377 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9380 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9383 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9388 tcg_temp_free_i32(tmp
);
9390 } else if (insn
& (1 << 20)) {
9391 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9393 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9395 tcg_temp_free_i32(addr
);
9398 /* Load/store multiple, RFE, SRS. */
9399 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9400 /* RFE, SRS: not available in user mode or on M profile */
9401 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9404 if (insn
& (1 << 20)) {
9406 addr
= load_reg(s
, rn
);
9407 if ((insn
& (1 << 24)) == 0)
9408 tcg_gen_addi_i32(addr
, addr
, -8);
9409 /* Load PC into tmp and CPSR into tmp2. */
9410 tmp
= tcg_temp_new_i32();
9411 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9412 tcg_gen_addi_i32(addr
, addr
, 4);
9413 tmp2
= tcg_temp_new_i32();
9414 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9415 if (insn
& (1 << 21)) {
9416 /* Base writeback. */
9417 if (insn
& (1 << 24)) {
9418 tcg_gen_addi_i32(addr
, addr
, 4);
9420 tcg_gen_addi_i32(addr
, addr
, -4);
9422 store_reg(s
, rn
, addr
);
9424 tcg_temp_free_i32(addr
);
9426 gen_rfe(s
, tmp
, tmp2
);
9429 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9433 int i
, loaded_base
= 0;
9434 TCGv_i32 loaded_var
;
9435 /* Load/store multiple. */
9436 addr
= load_reg(s
, rn
);
9438 for (i
= 0; i
< 16; i
++) {
9439 if (insn
& (1 << i
))
9442 if (insn
& (1 << 24)) {
9443 tcg_gen_addi_i32(addr
, addr
, -offset
);
9446 TCGV_UNUSED_I32(loaded_var
);
9447 for (i
= 0; i
< 16; i
++) {
9448 if ((insn
& (1 << i
)) == 0)
9450 if (insn
& (1 << 20)) {
9452 tmp
= tcg_temp_new_i32();
9453 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9456 } else if (i
== rn
) {
9460 store_reg(s
, i
, tmp
);
9464 tmp
= load_reg(s
, i
);
9465 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9466 tcg_temp_free_i32(tmp
);
9468 tcg_gen_addi_i32(addr
, addr
, 4);
9471 store_reg(s
, rn
, loaded_var
);
9473 if (insn
& (1 << 21)) {
9474 /* Base register writeback. */
9475 if (insn
& (1 << 24)) {
9476 tcg_gen_addi_i32(addr
, addr
, -offset
);
9478 /* Fault if writeback register is in register list. */
9479 if (insn
& (1 << rn
))
9481 store_reg(s
, rn
, addr
);
9483 tcg_temp_free_i32(addr
);
9490 op
= (insn
>> 21) & 0xf;
9492 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9495 /* Halfword pack. */
9496 tmp
= load_reg(s
, rn
);
9497 tmp2
= load_reg(s
, rm
);
9498 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9499 if (insn
& (1 << 5)) {
9503 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9504 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9505 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9509 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9510 tcg_gen_ext16u_i32(tmp
, tmp
);
9511 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9513 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9514 tcg_temp_free_i32(tmp2
);
9515 store_reg(s
, rd
, tmp
);
9517 /* Data processing register constant shift. */
9519 tmp
= tcg_temp_new_i32();
9520 tcg_gen_movi_i32(tmp
, 0);
9522 tmp
= load_reg(s
, rn
);
9524 tmp2
= load_reg(s
, rm
);
9526 shiftop
= (insn
>> 4) & 3;
9527 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9528 conds
= (insn
& (1 << 20)) != 0;
9529 logic_cc
= (conds
&& thumb2_logic_op(op
));
9530 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9531 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9533 tcg_temp_free_i32(tmp2
);
9535 store_reg(s
, rd
, tmp
);
9537 tcg_temp_free_i32(tmp
);
9541 case 13: /* Misc data processing. */
9542 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9543 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9546 case 0: /* Register controlled shift. */
9547 tmp
= load_reg(s
, rn
);
9548 tmp2
= load_reg(s
, rm
);
9549 if ((insn
& 0x70) != 0)
9551 op
= (insn
>> 21) & 3;
9552 logic_cc
= (insn
& (1 << 20)) != 0;
9553 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9556 store_reg_bx(s
, rd
, tmp
);
9558 case 1: /* Sign/zero extend. */
9559 op
= (insn
>> 20) & 7;
9561 case 0: /* SXTAH, SXTH */
9562 case 1: /* UXTAH, UXTH */
9563 case 4: /* SXTAB, SXTB */
9564 case 5: /* UXTAB, UXTB */
9566 case 2: /* SXTAB16, SXTB16 */
9567 case 3: /* UXTAB16, UXTB16 */
9568 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9576 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9580 tmp
= load_reg(s
, rm
);
9581 shift
= (insn
>> 4) & 3;
9582 /* ??? In many cases it's not necessary to do a
9583 rotate, a shift is sufficient. */
9585 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9586 op
= (insn
>> 20) & 7;
9588 case 0: gen_sxth(tmp
); break;
9589 case 1: gen_uxth(tmp
); break;
9590 case 2: gen_sxtb16(tmp
); break;
9591 case 3: gen_uxtb16(tmp
); break;
9592 case 4: gen_sxtb(tmp
); break;
9593 case 5: gen_uxtb(tmp
); break;
9595 g_assert_not_reached();
9598 tmp2
= load_reg(s
, rn
);
9599 if ((op
>> 1) == 1) {
9600 gen_add16(tmp
, tmp2
);
9602 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9603 tcg_temp_free_i32(tmp2
);
9606 store_reg(s
, rd
, tmp
);
9608 case 2: /* SIMD add/subtract. */
9609 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9612 op
= (insn
>> 20) & 7;
9613 shift
= (insn
>> 4) & 7;
9614 if ((op
& 3) == 3 || (shift
& 3) == 3)
9616 tmp
= load_reg(s
, rn
);
9617 tmp2
= load_reg(s
, rm
);
9618 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9619 tcg_temp_free_i32(tmp2
);
9620 store_reg(s
, rd
, tmp
);
9622 case 3: /* Other data processing. */
9623 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9625 /* Saturating add/subtract. */
9626 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9629 tmp
= load_reg(s
, rn
);
9630 tmp2
= load_reg(s
, rm
);
9632 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9634 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9636 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9637 tcg_temp_free_i32(tmp2
);
9640 case 0x0a: /* rbit */
9641 case 0x08: /* rev */
9642 case 0x09: /* rev16 */
9643 case 0x0b: /* revsh */
9644 case 0x18: /* clz */
9646 case 0x10: /* sel */
9647 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9651 case 0x20: /* crc32/crc32c */
9657 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
9664 tmp
= load_reg(s
, rn
);
9666 case 0x0a: /* rbit */
9667 gen_helper_rbit(tmp
, tmp
);
9669 case 0x08: /* rev */
9670 tcg_gen_bswap32_i32(tmp
, tmp
);
9672 case 0x09: /* rev16 */
9675 case 0x0b: /* revsh */
9678 case 0x10: /* sel */
9679 tmp2
= load_reg(s
, rm
);
9680 tmp3
= tcg_temp_new_i32();
9681 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9682 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9683 tcg_temp_free_i32(tmp3
);
9684 tcg_temp_free_i32(tmp2
);
9686 case 0x18: /* clz */
9687 gen_helper_clz(tmp
, tmp
);
9697 uint32_t sz
= op
& 0x3;
9698 uint32_t c
= op
& 0x8;
9700 tmp2
= load_reg(s
, rm
);
9702 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9703 } else if (sz
== 1) {
9704 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9706 tmp3
= tcg_const_i32(1 << sz
);
9708 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9710 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9712 tcg_temp_free_i32(tmp2
);
9713 tcg_temp_free_i32(tmp3
);
9717 g_assert_not_reached();
9720 store_reg(s
, rd
, tmp
);
9722 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9723 switch ((insn
>> 20) & 7) {
9724 case 0: /* 32 x 32 -> 32 */
9725 case 7: /* Unsigned sum of absolute differences. */
9727 case 1: /* 16 x 16 -> 32 */
9728 case 2: /* Dual multiply add. */
9729 case 3: /* 32 * 16 -> 32msb */
9730 case 4: /* Dual multiply subtract. */
9731 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9732 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9737 op
= (insn
>> 4) & 0xf;
9738 tmp
= load_reg(s
, rn
);
9739 tmp2
= load_reg(s
, rm
);
9740 switch ((insn
>> 20) & 7) {
9741 case 0: /* 32 x 32 -> 32 */
9742 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9743 tcg_temp_free_i32(tmp2
);
9745 tmp2
= load_reg(s
, rs
);
9747 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9749 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9750 tcg_temp_free_i32(tmp2
);
9753 case 1: /* 16 x 16 -> 32 */
9754 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9755 tcg_temp_free_i32(tmp2
);
9757 tmp2
= load_reg(s
, rs
);
9758 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9759 tcg_temp_free_i32(tmp2
);
9762 case 2: /* Dual multiply add. */
9763 case 4: /* Dual multiply subtract. */
9765 gen_swap_half(tmp2
);
9766 gen_smul_dual(tmp
, tmp2
);
9767 if (insn
& (1 << 22)) {
9768 /* This subtraction cannot overflow. */
9769 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9771 /* This addition cannot overflow 32 bits;
9772 * however it may overflow considered as a signed
9773 * operation, in which case we must set the Q flag.
9775 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9777 tcg_temp_free_i32(tmp2
);
9780 tmp2
= load_reg(s
, rs
);
9781 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9782 tcg_temp_free_i32(tmp2
);
9785 case 3: /* 32 * 16 -> 32msb */
9787 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9790 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9791 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9792 tmp
= tcg_temp_new_i32();
9793 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9794 tcg_temp_free_i64(tmp64
);
9797 tmp2
= load_reg(s
, rs
);
9798 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9799 tcg_temp_free_i32(tmp2
);
9802 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9803 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9805 tmp
= load_reg(s
, rs
);
9806 if (insn
& (1 << 20)) {
9807 tmp64
= gen_addq_msw(tmp64
, tmp
);
9809 tmp64
= gen_subq_msw(tmp64
, tmp
);
9812 if (insn
& (1 << 4)) {
9813 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9815 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9816 tmp
= tcg_temp_new_i32();
9817 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9818 tcg_temp_free_i64(tmp64
);
9820 case 7: /* Unsigned sum of absolute differences. */
9821 gen_helper_usad8(tmp
, tmp
, tmp2
);
9822 tcg_temp_free_i32(tmp2
);
9824 tmp2
= load_reg(s
, rs
);
9825 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9826 tcg_temp_free_i32(tmp2
);
9830 store_reg(s
, rd
, tmp
);
9832 case 6: case 7: /* 64-bit multiply, Divide. */
9833 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9834 tmp
= load_reg(s
, rn
);
9835 tmp2
= load_reg(s
, rm
);
9836 if ((op
& 0x50) == 0x10) {
9838 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
9842 gen_helper_udiv(tmp
, tmp
, tmp2
);
9844 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9845 tcg_temp_free_i32(tmp2
);
9846 store_reg(s
, rd
, tmp
);
9847 } else if ((op
& 0xe) == 0xc) {
9848 /* Dual multiply accumulate long. */
9849 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9850 tcg_temp_free_i32(tmp
);
9851 tcg_temp_free_i32(tmp2
);
9855 gen_swap_half(tmp2
);
9856 gen_smul_dual(tmp
, tmp2
);
9858 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9860 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9862 tcg_temp_free_i32(tmp2
);
9864 tmp64
= tcg_temp_new_i64();
9865 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9866 tcg_temp_free_i32(tmp
);
9867 gen_addq(s
, tmp64
, rs
, rd
);
9868 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9869 tcg_temp_free_i64(tmp64
);
9872 /* Unsigned 64-bit multiply */
9873 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9877 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9878 tcg_temp_free_i32(tmp2
);
9879 tcg_temp_free_i32(tmp
);
9882 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9883 tcg_temp_free_i32(tmp2
);
9884 tmp64
= tcg_temp_new_i64();
9885 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9886 tcg_temp_free_i32(tmp
);
9888 /* Signed 64-bit multiply */
9889 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9894 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9895 tcg_temp_free_i64(tmp64
);
9898 gen_addq_lo(s
, tmp64
, rs
);
9899 gen_addq_lo(s
, tmp64
, rd
);
9900 } else if (op
& 0x40) {
9901 /* 64-bit accumulate. */
9902 gen_addq(s
, tmp64
, rs
, rd
);
9904 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9905 tcg_temp_free_i64(tmp64
);
9910 case 6: case 7: case 14: case 15:
9912 if (((insn
>> 24) & 3) == 3) {
9913 /* Translate into the equivalent ARM encoding. */
9914 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9915 if (disas_neon_data_insn(s
, insn
)) {
9918 } else if (((insn
>> 8) & 0xe) == 10) {
9919 if (disas_vfp_insn(s
, insn
)) {
9923 if (insn
& (1 << 28))
9925 if (disas_coproc_insn(s
, insn
)) {
9930 case 8: case 9: case 10: case 11:
9931 if (insn
& (1 << 15)) {
9932 /* Branches, misc control. */
9933 if (insn
& 0x5000) {
9934 /* Unconditional branch. */
9935 /* signextend(hw1[10:0]) -> offset[:12]. */
9936 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9937 /* hw1[10:0] -> offset[11:1]. */
9938 offset
|= (insn
& 0x7ff) << 1;
9939 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9940 offset[24:22] already have the same value because of the
9941 sign extension above. */
9942 offset
^= ((~insn
) & (1 << 13)) << 10;
9943 offset
^= ((~insn
) & (1 << 11)) << 11;
9945 if (insn
& (1 << 14)) {
9946 /* Branch and link. */
9947 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9951 if (insn
& (1 << 12)) {
9956 offset
&= ~(uint32_t)2;
9957 /* thumb2 bx, no need to check */
9958 gen_bx_im(s
, offset
);
9960 } else if (((insn
>> 23) & 7) == 7) {
9962 if (insn
& (1 << 13))
9965 if (insn
& (1 << 26)) {
9966 if (!(insn
& (1 << 20))) {
9967 /* Hypervisor call (v7) */
9968 int imm16
= extract32(insn
, 16, 4) << 12
9969 | extract32(insn
, 0, 12);
9976 /* Secure monitor call (v6+) */
9984 op
= (insn
>> 20) & 7;
9986 case 0: /* msr cpsr. */
9987 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9988 tmp
= load_reg(s
, rn
);
9989 addr
= tcg_const_i32(insn
& 0xff);
9990 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9991 tcg_temp_free_i32(addr
);
9992 tcg_temp_free_i32(tmp
);
9997 case 1: /* msr spsr. */
9998 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10001 tmp
= load_reg(s
, rn
);
10003 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10007 case 2: /* cps, nop-hint. */
10008 if (((insn
>> 8) & 7) == 0) {
10009 gen_nop_hint(s
, insn
& 0xff);
10011 /* Implemented as NOP in user mode. */
10016 if (insn
& (1 << 10)) {
10017 if (insn
& (1 << 7))
10019 if (insn
& (1 << 6))
10021 if (insn
& (1 << 5))
10023 if (insn
& (1 << 9))
10024 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10026 if (insn
& (1 << 8)) {
10028 imm
|= (insn
& 0x1f);
10031 gen_set_psr_im(s
, offset
, 0, imm
);
10034 case 3: /* Special control operations. */
10036 op
= (insn
>> 4) & 0xf;
10038 case 2: /* clrex */
10043 /* These execute as NOPs. */
10046 /* We need to break the TB after this insn
10047 * to execute self-modifying code correctly
10048 * and also to take any pending interrupts
10058 /* Trivial implementation equivalent to bx. */
10059 tmp
= load_reg(s
, rn
);
10062 case 5: /* Exception return. */
10066 if (rn
!= 14 || rd
!= 15) {
10069 tmp
= load_reg(s
, rn
);
10070 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10071 gen_exception_return(s
, tmp
);
10073 case 6: /* mrs cpsr. */
10074 tmp
= tcg_temp_new_i32();
10075 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10076 addr
= tcg_const_i32(insn
& 0xff);
10077 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10078 tcg_temp_free_i32(addr
);
10080 gen_helper_cpsr_read(tmp
, cpu_env
);
10082 store_reg(s
, rd
, tmp
);
10084 case 7: /* mrs spsr. */
10085 /* Not accessible in user mode. */
10086 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10089 tmp
= load_cpu_field(spsr
);
10090 store_reg(s
, rd
, tmp
);
10095 /* Conditional branch. */
10096 op
= (insn
>> 22) & 0xf;
10097 /* Generate a conditional jump to next instruction. */
10098 s
->condlabel
= gen_new_label();
10099 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10102 /* offset[11:1] = insn[10:0] */
10103 offset
= (insn
& 0x7ff) << 1;
10104 /* offset[17:12] = insn[21:16]. */
10105 offset
|= (insn
& 0x003f0000) >> 4;
10106 /* offset[31:20] = insn[26]. */
10107 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10108 /* offset[18] = insn[13]. */
10109 offset
|= (insn
& (1 << 13)) << 5;
10110 /* offset[19] = insn[11]. */
10111 offset
|= (insn
& (1 << 11)) << 8;
10113 /* jump to the offset */
10114 gen_jmp(s
, s
->pc
+ offset
);
10117 /* Data processing immediate. */
10118 if (insn
& (1 << 25)) {
10119 if (insn
& (1 << 24)) {
10120 if (insn
& (1 << 20))
10122 /* Bitfield/Saturate. */
10123 op
= (insn
>> 21) & 7;
10125 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10127 tmp
= tcg_temp_new_i32();
10128 tcg_gen_movi_i32(tmp
, 0);
10130 tmp
= load_reg(s
, rn
);
10133 case 2: /* Signed bitfield extract. */
10135 if (shift
+ imm
> 32)
10138 gen_sbfx(tmp
, shift
, imm
);
10140 case 6: /* Unsigned bitfield extract. */
10142 if (shift
+ imm
> 32)
10145 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
10147 case 3: /* Bitfield insert/clear. */
10150 imm
= imm
+ 1 - shift
;
10152 tmp2
= load_reg(s
, rd
);
10153 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10154 tcg_temp_free_i32(tmp2
);
10159 default: /* Saturate. */
10162 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10164 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10166 tmp2
= tcg_const_i32(imm
);
10169 if ((op
& 1) && shift
== 0) {
10170 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10171 tcg_temp_free_i32(tmp
);
10172 tcg_temp_free_i32(tmp2
);
10175 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10177 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10181 if ((op
& 1) && shift
== 0) {
10182 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10183 tcg_temp_free_i32(tmp
);
10184 tcg_temp_free_i32(tmp2
);
10187 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10189 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10192 tcg_temp_free_i32(tmp2
);
10195 store_reg(s
, rd
, tmp
);
10197 imm
= ((insn
& 0x04000000) >> 15)
10198 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10199 if (insn
& (1 << 22)) {
10200 /* 16-bit immediate. */
10201 imm
|= (insn
>> 4) & 0xf000;
10202 if (insn
& (1 << 23)) {
10204 tmp
= load_reg(s
, rd
);
10205 tcg_gen_ext16u_i32(tmp
, tmp
);
10206 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10209 tmp
= tcg_temp_new_i32();
10210 tcg_gen_movi_i32(tmp
, imm
);
10213 /* Add/sub 12-bit immediate. */
10215 offset
= s
->pc
& ~(uint32_t)3;
10216 if (insn
& (1 << 23))
10220 tmp
= tcg_temp_new_i32();
10221 tcg_gen_movi_i32(tmp
, offset
);
10223 tmp
= load_reg(s
, rn
);
10224 if (insn
& (1 << 23))
10225 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10227 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10230 store_reg(s
, rd
, tmp
);
10233 int shifter_out
= 0;
10234 /* modified 12-bit immediate. */
10235 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10236 imm
= (insn
& 0xff);
10239 /* Nothing to do. */
10241 case 1: /* 00XY00XY */
10244 case 2: /* XY00XY00 */
10248 case 3: /* XYXYXYXY */
10252 default: /* Rotated constant. */
10253 shift
= (shift
<< 1) | (imm
>> 7);
10255 imm
= imm
<< (32 - shift
);
10259 tmp2
= tcg_temp_new_i32();
10260 tcg_gen_movi_i32(tmp2
, imm
);
10261 rn
= (insn
>> 16) & 0xf;
10263 tmp
= tcg_temp_new_i32();
10264 tcg_gen_movi_i32(tmp
, 0);
10266 tmp
= load_reg(s
, rn
);
10268 op
= (insn
>> 21) & 0xf;
10269 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10270 shifter_out
, tmp
, tmp2
))
10272 tcg_temp_free_i32(tmp2
);
10273 rd
= (insn
>> 8) & 0xf;
10275 store_reg(s
, rd
, tmp
);
10277 tcg_temp_free_i32(tmp
);
10282 case 12: /* Load/store single data item. */
10287 if ((insn
& 0x01100000) == 0x01000000) {
10288 if (disas_neon_ls_insn(s
, insn
)) {
10293 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10295 if (!(insn
& (1 << 20))) {
10299 /* Byte or halfword load space with dest == r15 : memory hints.
10300 * Catch them early so we don't emit pointless addressing code.
10301 * This space is a mix of:
10302 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10303 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10305 * unallocated hints, which must be treated as NOPs
10306 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10307 * which is easiest for the decoding logic
10308 * Some space which must UNDEF
10310 int op1
= (insn
>> 23) & 3;
10311 int op2
= (insn
>> 6) & 0x3f;
10316 /* UNPREDICTABLE, unallocated hint or
10317 * PLD/PLDW/PLI (literal)
10322 return 0; /* PLD/PLDW/PLI or unallocated hint */
10324 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10325 return 0; /* PLD/PLDW/PLI or unallocated hint */
10327 /* UNDEF space, or an UNPREDICTABLE */
10331 memidx
= get_mem_index(s
);
10333 addr
= tcg_temp_new_i32();
10335 /* s->pc has already been incremented by 4. */
10336 imm
= s
->pc
& 0xfffffffc;
10337 if (insn
& (1 << 23))
10338 imm
+= insn
& 0xfff;
10340 imm
-= insn
& 0xfff;
10341 tcg_gen_movi_i32(addr
, imm
);
10343 addr
= load_reg(s
, rn
);
10344 if (insn
& (1 << 23)) {
10345 /* Positive offset. */
10346 imm
= insn
& 0xfff;
10347 tcg_gen_addi_i32(addr
, addr
, imm
);
10350 switch ((insn
>> 8) & 0xf) {
10351 case 0x0: /* Shifted Register. */
10352 shift
= (insn
>> 4) & 0xf;
10354 tcg_temp_free_i32(addr
);
10357 tmp
= load_reg(s
, rm
);
10359 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10360 tcg_gen_add_i32(addr
, addr
, tmp
);
10361 tcg_temp_free_i32(tmp
);
10363 case 0xc: /* Negative offset. */
10364 tcg_gen_addi_i32(addr
, addr
, -imm
);
10366 case 0xe: /* User privilege. */
10367 tcg_gen_addi_i32(addr
, addr
, imm
);
10368 memidx
= get_a32_user_mem_index(s
);
10370 case 0x9: /* Post-decrement. */
10372 /* Fall through. */
10373 case 0xb: /* Post-increment. */
10377 case 0xd: /* Pre-decrement. */
10379 /* Fall through. */
10380 case 0xf: /* Pre-increment. */
10381 tcg_gen_addi_i32(addr
, addr
, imm
);
10385 tcg_temp_free_i32(addr
);
10390 if (insn
& (1 << 20)) {
10392 tmp
= tcg_temp_new_i32();
10395 gen_aa32_ld8u(tmp
, addr
, memidx
);
10398 gen_aa32_ld8s(tmp
, addr
, memidx
);
10401 gen_aa32_ld16u(tmp
, addr
, memidx
);
10404 gen_aa32_ld16s(tmp
, addr
, memidx
);
10407 gen_aa32_ld32u(tmp
, addr
, memidx
);
10410 tcg_temp_free_i32(tmp
);
10411 tcg_temp_free_i32(addr
);
10417 store_reg(s
, rs
, tmp
);
10421 tmp
= load_reg(s
, rs
);
10424 gen_aa32_st8(tmp
, addr
, memidx
);
10427 gen_aa32_st16(tmp
, addr
, memidx
);
10430 gen_aa32_st32(tmp
, addr
, memidx
);
10433 tcg_temp_free_i32(tmp
);
10434 tcg_temp_free_i32(addr
);
10437 tcg_temp_free_i32(tmp
);
10440 tcg_gen_addi_i32(addr
, addr
, imm
);
10442 store_reg(s
, rn
, addr
);
10444 tcg_temp_free_i32(addr
);
10456 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10458 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10465 if (s
->condexec_mask
) {
10466 cond
= s
->condexec_cond
;
10467 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10468 s
->condlabel
= gen_new_label();
10469 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10474 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10477 switch (insn
>> 12) {
10481 op
= (insn
>> 11) & 3;
10484 rn
= (insn
>> 3) & 7;
10485 tmp
= load_reg(s
, rn
);
10486 if (insn
& (1 << 10)) {
10488 tmp2
= tcg_temp_new_i32();
10489 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10492 rm
= (insn
>> 6) & 7;
10493 tmp2
= load_reg(s
, rm
);
10495 if (insn
& (1 << 9)) {
10496 if (s
->condexec_mask
)
10497 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10499 gen_sub_CC(tmp
, tmp
, tmp2
);
10501 if (s
->condexec_mask
)
10502 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10504 gen_add_CC(tmp
, tmp
, tmp2
);
10506 tcg_temp_free_i32(tmp2
);
10507 store_reg(s
, rd
, tmp
);
10509 /* shift immediate */
10510 rm
= (insn
>> 3) & 7;
10511 shift
= (insn
>> 6) & 0x1f;
10512 tmp
= load_reg(s
, rm
);
10513 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10514 if (!s
->condexec_mask
)
10516 store_reg(s
, rd
, tmp
);
10520 /* arithmetic large immediate */
10521 op
= (insn
>> 11) & 3;
10522 rd
= (insn
>> 8) & 0x7;
10523 if (op
== 0) { /* mov */
10524 tmp
= tcg_temp_new_i32();
10525 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10526 if (!s
->condexec_mask
)
10528 store_reg(s
, rd
, tmp
);
10530 tmp
= load_reg(s
, rd
);
10531 tmp2
= tcg_temp_new_i32();
10532 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10535 gen_sub_CC(tmp
, tmp
, tmp2
);
10536 tcg_temp_free_i32(tmp
);
10537 tcg_temp_free_i32(tmp2
);
10540 if (s
->condexec_mask
)
10541 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10543 gen_add_CC(tmp
, tmp
, tmp2
);
10544 tcg_temp_free_i32(tmp2
);
10545 store_reg(s
, rd
, tmp
);
10548 if (s
->condexec_mask
)
10549 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10551 gen_sub_CC(tmp
, tmp
, tmp2
);
10552 tcg_temp_free_i32(tmp2
);
10553 store_reg(s
, rd
, tmp
);
10559 if (insn
& (1 << 11)) {
10560 rd
= (insn
>> 8) & 7;
10561 /* load pc-relative. Bit 1 of PC is ignored. */
10562 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10563 val
&= ~(uint32_t)2;
10564 addr
= tcg_temp_new_i32();
10565 tcg_gen_movi_i32(addr
, val
);
10566 tmp
= tcg_temp_new_i32();
10567 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10568 tcg_temp_free_i32(addr
);
10569 store_reg(s
, rd
, tmp
);
10572 if (insn
& (1 << 10)) {
10573 /* data processing extended or blx */
10574 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10575 rm
= (insn
>> 3) & 0xf;
10576 op
= (insn
>> 8) & 3;
10579 tmp
= load_reg(s
, rd
);
10580 tmp2
= load_reg(s
, rm
);
10581 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10582 tcg_temp_free_i32(tmp2
);
10583 store_reg(s
, rd
, tmp
);
10586 tmp
= load_reg(s
, rd
);
10587 tmp2
= load_reg(s
, rm
);
10588 gen_sub_CC(tmp
, tmp
, tmp2
);
10589 tcg_temp_free_i32(tmp2
);
10590 tcg_temp_free_i32(tmp
);
10592 case 2: /* mov/cpy */
10593 tmp
= load_reg(s
, rm
);
10594 store_reg(s
, rd
, tmp
);
10596 case 3:/* branch [and link] exchange thumb register */
10597 tmp
= load_reg(s
, rm
);
10598 if (insn
& (1 << 7)) {
10600 val
= (uint32_t)s
->pc
| 1;
10601 tmp2
= tcg_temp_new_i32();
10602 tcg_gen_movi_i32(tmp2
, val
);
10603 store_reg(s
, 14, tmp2
);
10605 /* already thumb, no need to check */
10612 /* data processing register */
10614 rm
= (insn
>> 3) & 7;
10615 op
= (insn
>> 6) & 0xf;
10616 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10617 /* the shift/rotate ops want the operands backwards */
10626 if (op
== 9) { /* neg */
10627 tmp
= tcg_temp_new_i32();
10628 tcg_gen_movi_i32(tmp
, 0);
10629 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10630 tmp
= load_reg(s
, rd
);
10632 TCGV_UNUSED_I32(tmp
);
10635 tmp2
= load_reg(s
, rm
);
10637 case 0x0: /* and */
10638 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10639 if (!s
->condexec_mask
)
10642 case 0x1: /* eor */
10643 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10644 if (!s
->condexec_mask
)
10647 case 0x2: /* lsl */
10648 if (s
->condexec_mask
) {
10649 gen_shl(tmp2
, tmp2
, tmp
);
10651 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10652 gen_logic_CC(tmp2
);
10655 case 0x3: /* lsr */
10656 if (s
->condexec_mask
) {
10657 gen_shr(tmp2
, tmp2
, tmp
);
10659 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10660 gen_logic_CC(tmp2
);
10663 case 0x4: /* asr */
10664 if (s
->condexec_mask
) {
10665 gen_sar(tmp2
, tmp2
, tmp
);
10667 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10668 gen_logic_CC(tmp2
);
10671 case 0x5: /* adc */
10672 if (s
->condexec_mask
) {
10673 gen_adc(tmp
, tmp2
);
10675 gen_adc_CC(tmp
, tmp
, tmp2
);
10678 case 0x6: /* sbc */
10679 if (s
->condexec_mask
) {
10680 gen_sub_carry(tmp
, tmp
, tmp2
);
10682 gen_sbc_CC(tmp
, tmp
, tmp2
);
10685 case 0x7: /* ror */
10686 if (s
->condexec_mask
) {
10687 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10688 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10690 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10691 gen_logic_CC(tmp2
);
10694 case 0x8: /* tst */
10695 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10699 case 0x9: /* neg */
10700 if (s
->condexec_mask
)
10701 tcg_gen_neg_i32(tmp
, tmp2
);
10703 gen_sub_CC(tmp
, tmp
, tmp2
);
10705 case 0xa: /* cmp */
10706 gen_sub_CC(tmp
, tmp
, tmp2
);
10709 case 0xb: /* cmn */
10710 gen_add_CC(tmp
, tmp
, tmp2
);
10713 case 0xc: /* orr */
10714 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10715 if (!s
->condexec_mask
)
10718 case 0xd: /* mul */
10719 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10720 if (!s
->condexec_mask
)
10723 case 0xe: /* bic */
10724 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10725 if (!s
->condexec_mask
)
10728 case 0xf: /* mvn */
10729 tcg_gen_not_i32(tmp2
, tmp2
);
10730 if (!s
->condexec_mask
)
10731 gen_logic_CC(tmp2
);
10738 store_reg(s
, rm
, tmp2
);
10740 tcg_temp_free_i32(tmp
);
10742 store_reg(s
, rd
, tmp
);
10743 tcg_temp_free_i32(tmp2
);
10746 tcg_temp_free_i32(tmp
);
10747 tcg_temp_free_i32(tmp2
);
10752 /* load/store register offset. */
10754 rn
= (insn
>> 3) & 7;
10755 rm
= (insn
>> 6) & 7;
10756 op
= (insn
>> 9) & 7;
10757 addr
= load_reg(s
, rn
);
10758 tmp
= load_reg(s
, rm
);
10759 tcg_gen_add_i32(addr
, addr
, tmp
);
10760 tcg_temp_free_i32(tmp
);
10762 if (op
< 3) { /* store */
10763 tmp
= load_reg(s
, rd
);
10765 tmp
= tcg_temp_new_i32();
10770 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10773 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10776 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10778 case 3: /* ldrsb */
10779 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10782 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10785 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10788 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10790 case 7: /* ldrsh */
10791 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10794 if (op
>= 3) { /* load */
10795 store_reg(s
, rd
, tmp
);
10797 tcg_temp_free_i32(tmp
);
10799 tcg_temp_free_i32(addr
);
10803 /* load/store word immediate offset */
10805 rn
= (insn
>> 3) & 7;
10806 addr
= load_reg(s
, rn
);
10807 val
= (insn
>> 4) & 0x7c;
10808 tcg_gen_addi_i32(addr
, addr
, val
);
10810 if (insn
& (1 << 11)) {
10812 tmp
= tcg_temp_new_i32();
10813 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10814 store_reg(s
, rd
, tmp
);
10817 tmp
= load_reg(s
, rd
);
10818 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10819 tcg_temp_free_i32(tmp
);
10821 tcg_temp_free_i32(addr
);
10825 /* load/store byte immediate offset */
10827 rn
= (insn
>> 3) & 7;
10828 addr
= load_reg(s
, rn
);
10829 val
= (insn
>> 6) & 0x1f;
10830 tcg_gen_addi_i32(addr
, addr
, val
);
10832 if (insn
& (1 << 11)) {
10834 tmp
= tcg_temp_new_i32();
10835 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10836 store_reg(s
, rd
, tmp
);
10839 tmp
= load_reg(s
, rd
);
10840 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10841 tcg_temp_free_i32(tmp
);
10843 tcg_temp_free_i32(addr
);
10847 /* load/store halfword immediate offset */
10849 rn
= (insn
>> 3) & 7;
10850 addr
= load_reg(s
, rn
);
10851 val
= (insn
>> 5) & 0x3e;
10852 tcg_gen_addi_i32(addr
, addr
, val
);
10854 if (insn
& (1 << 11)) {
10856 tmp
= tcg_temp_new_i32();
10857 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10858 store_reg(s
, rd
, tmp
);
10861 tmp
= load_reg(s
, rd
);
10862 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10863 tcg_temp_free_i32(tmp
);
10865 tcg_temp_free_i32(addr
);
10869 /* load/store from stack */
10870 rd
= (insn
>> 8) & 7;
10871 addr
= load_reg(s
, 13);
10872 val
= (insn
& 0xff) * 4;
10873 tcg_gen_addi_i32(addr
, addr
, val
);
10875 if (insn
& (1 << 11)) {
10877 tmp
= tcg_temp_new_i32();
10878 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10879 store_reg(s
, rd
, tmp
);
10882 tmp
= load_reg(s
, rd
);
10883 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10884 tcg_temp_free_i32(tmp
);
10886 tcg_temp_free_i32(addr
);
10890 /* add to high reg */
10891 rd
= (insn
>> 8) & 7;
10892 if (insn
& (1 << 11)) {
10894 tmp
= load_reg(s
, 13);
10896 /* PC. bit 1 is ignored. */
10897 tmp
= tcg_temp_new_i32();
10898 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10900 val
= (insn
& 0xff) * 4;
10901 tcg_gen_addi_i32(tmp
, tmp
, val
);
10902 store_reg(s
, rd
, tmp
);
10907 op
= (insn
>> 8) & 0xf;
10910 /* adjust stack pointer */
10911 tmp
= load_reg(s
, 13);
10912 val
= (insn
& 0x7f) * 4;
10913 if (insn
& (1 << 7))
10914 val
= -(int32_t)val
;
10915 tcg_gen_addi_i32(tmp
, tmp
, val
);
10916 store_reg(s
, 13, tmp
);
10919 case 2: /* sign/zero extend. */
10922 rm
= (insn
>> 3) & 7;
10923 tmp
= load_reg(s
, rm
);
10924 switch ((insn
>> 6) & 3) {
10925 case 0: gen_sxth(tmp
); break;
10926 case 1: gen_sxtb(tmp
); break;
10927 case 2: gen_uxth(tmp
); break;
10928 case 3: gen_uxtb(tmp
); break;
10930 store_reg(s
, rd
, tmp
);
10932 case 4: case 5: case 0xc: case 0xd:
10934 addr
= load_reg(s
, 13);
10935 if (insn
& (1 << 8))
10939 for (i
= 0; i
< 8; i
++) {
10940 if (insn
& (1 << i
))
10943 if ((insn
& (1 << 11)) == 0) {
10944 tcg_gen_addi_i32(addr
, addr
, -offset
);
10946 for (i
= 0; i
< 8; i
++) {
10947 if (insn
& (1 << i
)) {
10948 if (insn
& (1 << 11)) {
10950 tmp
= tcg_temp_new_i32();
10951 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10952 store_reg(s
, i
, tmp
);
10955 tmp
= load_reg(s
, i
);
10956 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10957 tcg_temp_free_i32(tmp
);
10959 /* advance to the next address. */
10960 tcg_gen_addi_i32(addr
, addr
, 4);
10963 TCGV_UNUSED_I32(tmp
);
10964 if (insn
& (1 << 8)) {
10965 if (insn
& (1 << 11)) {
10967 tmp
= tcg_temp_new_i32();
10968 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10969 /* don't set the pc until the rest of the instruction
10973 tmp
= load_reg(s
, 14);
10974 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10975 tcg_temp_free_i32(tmp
);
10977 tcg_gen_addi_i32(addr
, addr
, 4);
10979 if ((insn
& (1 << 11)) == 0) {
10980 tcg_gen_addi_i32(addr
, addr
, -offset
);
10982 /* write back the new stack pointer */
10983 store_reg(s
, 13, addr
);
10984 /* set the new PC value */
10985 if ((insn
& 0x0900) == 0x0900) {
10986 store_reg_from_load(s
, 15, tmp
);
10990 case 1: case 3: case 9: case 11: /* czb */
10992 tmp
= load_reg(s
, rm
);
10993 s
->condlabel
= gen_new_label();
10995 if (insn
& (1 << 11))
10996 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10998 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10999 tcg_temp_free_i32(tmp
);
11000 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11001 val
= (uint32_t)s
->pc
+ 2;
11006 case 15: /* IT, nop-hint. */
11007 if ((insn
& 0xf) == 0) {
11008 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11012 s
->condexec_cond
= (insn
>> 4) & 0xe;
11013 s
->condexec_mask
= insn
& 0x1f;
11014 /* No actual code generated for this insn, just setup state. */
11017 case 0xe: /* bkpt */
11019 int imm8
= extract32(insn
, 0, 8);
11021 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11022 default_exception_el(s
));
11026 case 0xa: /* rev */
11028 rn
= (insn
>> 3) & 0x7;
11030 tmp
= load_reg(s
, rn
);
11031 switch ((insn
>> 6) & 3) {
11032 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11033 case 1: gen_rev16(tmp
); break;
11034 case 3: gen_revsh(tmp
); break;
11035 default: goto illegal_op
;
11037 store_reg(s
, rd
, tmp
);
11041 switch ((insn
>> 5) & 7) {
11045 if (((insn
>> 3) & 1) != s
->bswap_code
) {
11046 /* Dynamic endianness switching not implemented. */
11047 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
11057 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11058 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11061 addr
= tcg_const_i32(19);
11062 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11063 tcg_temp_free_i32(addr
);
11067 addr
= tcg_const_i32(16);
11068 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11069 tcg_temp_free_i32(addr
);
11071 tcg_temp_free_i32(tmp
);
11074 if (insn
& (1 << 4)) {
11075 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11079 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11094 /* load/store multiple */
11095 TCGv_i32 loaded_var
;
11096 TCGV_UNUSED_I32(loaded_var
);
11097 rn
= (insn
>> 8) & 0x7;
11098 addr
= load_reg(s
, rn
);
11099 for (i
= 0; i
< 8; i
++) {
11100 if (insn
& (1 << i
)) {
11101 if (insn
& (1 << 11)) {
11103 tmp
= tcg_temp_new_i32();
11104 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
11108 store_reg(s
, i
, tmp
);
11112 tmp
= load_reg(s
, i
);
11113 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
11114 tcg_temp_free_i32(tmp
);
11116 /* advance to the next address */
11117 tcg_gen_addi_i32(addr
, addr
, 4);
11120 if ((insn
& (1 << rn
)) == 0) {
11121 /* base reg not in list: base register writeback */
11122 store_reg(s
, rn
, addr
);
11124 /* base reg in list: if load, complete it now */
11125 if (insn
& (1 << 11)) {
11126 store_reg(s
, rn
, loaded_var
);
11128 tcg_temp_free_i32(addr
);
11133 /* conditional branch or swi */
11134 cond
= (insn
>> 8) & 0xf;
11140 gen_set_pc_im(s
, s
->pc
);
11141 s
->svc_imm
= extract32(insn
, 0, 8);
11142 s
->is_jmp
= DISAS_SWI
;
11145 /* generate a conditional jump to next instruction */
11146 s
->condlabel
= gen_new_label();
11147 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11150 /* jump to the offset */
11151 val
= (uint32_t)s
->pc
+ 2;
11152 offset
= ((int32_t)insn
<< 24) >> 24;
11153 val
+= offset
<< 1;
11158 if (insn
& (1 << 11)) {
11159 if (disas_thumb2_insn(env
, s
, insn
))
11163 /* unconditional branch */
11164 val
= (uint32_t)s
->pc
;
11165 offset
= ((int32_t)insn
<< 21) >> 21;
11166 val
+= (offset
<< 1) + 2;
11171 if (disas_thumb2_insn(env
, s
, insn
))
11177 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11178 default_exception_el(s
));
11182 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11183 default_exception_el(s
));
11186 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11188 /* Return true if the insn at dc->pc might cross a page boundary.
11189 * (False positives are OK, false negatives are not.)
11193 if ((s
->pc
& 3) == 0) {
11194 /* At a 4-aligned address we can't be crossing a page */
11198 /* This must be a Thumb insn */
11199 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
11201 if ((insn
>> 11) >= 0x1d) {
11202 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11203 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11204 * end up actually treating this as two 16-bit insns (see the
11205 * code at the start of disas_thumb2_insn()) but we don't bother
11206 * to check for that as it is unlikely, and false positives here
11211 /* Definitely a 16-bit insn, can't be crossing a page. */
11215 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
11216 basic block 'tb'. */
11217 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11219 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11220 CPUState
*cs
= CPU(cpu
);
11221 DisasContext dc1
, *dc
= &dc1
;
11222 target_ulong pc_start
;
11223 target_ulong next_page_start
;
11228 /* generate intermediate code */
11230 /* The A64 decoder has its own top level loop, because it doesn't need
11231 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11233 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11234 gen_intermediate_code_a64(cpu
, tb
);
11242 dc
->is_jmp
= DISAS_NEXT
;
11244 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11248 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11249 * there is no secure EL1, so we route exceptions to EL3.
11251 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11252 !arm_el_is_aa64(env
, 3);
11253 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11254 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
11255 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11256 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11257 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11258 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11259 #if !defined(CONFIG_USER_ONLY)
11260 dc
->user
= (dc
->current_el
== 0);
11262 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11263 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11264 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11265 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11266 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11267 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11268 dc
->cp_regs
= cpu
->cp_regs
;
11269 dc
->features
= env
->features
;
11271 /* Single step state. The code-generation logic here is:
11273 * generate code with no special handling for single-stepping (except
11274 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11275 * this happens anyway because those changes are all system register or
11277 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11278 * emit code for one insn
11279 * emit code to clear PSTATE.SS
11280 * emit code to generate software step exception for completed step
11281 * end TB (as usual for having generated an exception)
11282 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11283 * emit code to generate a software step exception
11286 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11287 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11288 dc
->is_ldex
= false;
11289 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11291 cpu_F0s
= tcg_temp_new_i32();
11292 cpu_F1s
= tcg_temp_new_i32();
11293 cpu_F0d
= tcg_temp_new_i64();
11294 cpu_F1d
= tcg_temp_new_i64();
11297 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11298 cpu_M0
= tcg_temp_new_i64();
11299 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11301 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11302 if (max_insns
== 0) {
11303 max_insns
= CF_COUNT_MASK
;
11305 if (max_insns
> TCG_MAX_INSNS
) {
11306 max_insns
= TCG_MAX_INSNS
;
11311 tcg_clear_temp_count();
11313 /* A note on handling of the condexec (IT) bits:
11315 * We want to avoid the overhead of having to write the updated condexec
11316 * bits back to the CPUARMState for every instruction in an IT block. So:
11317 * (1) if the condexec bits are not already zero then we write
11318 * zero back into the CPUARMState now. This avoids complications trying
11319 * to do it at the end of the block. (For example if we don't do this
11320 * it's hard to identify whether we can safely skip writing condexec
11321 * at the end of the TB, which we definitely want to do for the case
11322 * where a TB doesn't do anything with the IT state at all.)
11323 * (2) if we are going to leave the TB then we call gen_set_condexec()
11324 * which will write the correct value into CPUARMState if zero is wrong.
11325 * This is done both for leaving the TB at the end, and for leaving
11326 * it because of an exception we know will happen, which is done in
11327 * gen_exception_insn(). The latter is necessary because we need to
11328 * leave the TB with the PC/IT state just prior to execution of the
11329 * instruction which caused the exception.
11330 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11331 * then the CPUARMState will be wrong and we need to reset it.
11332 * This is handled in the same way as restoration of the
11333 * PC in these situations; we save the value of the condexec bits
11334 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11335 * then uses this to restore them after an exception.
11337 * Note that there are no instructions which can read the condexec
11338 * bits, and none which can write non-static values to them, so
11339 * we don't need to care about whether CPUARMState is correct in the
11343 /* Reset the conditional execution bits immediately. This avoids
11344 complications trying to do it at the end of the block. */
11345 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11347 TCGv_i32 tmp
= tcg_temp_new_i32();
11348 tcg_gen_movi_i32(tmp
, 0);
11349 store_cpu_field(tmp
, condexec_bits
);
11352 tcg_gen_insn_start(dc
->pc
,
11353 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1));
11356 #ifdef CONFIG_USER_ONLY
11357 /* Intercept jump to the magic kernel page. */
11358 if (dc
->pc
>= 0xffff0000) {
11359 /* We always get here via a jump, so know we are not in a
11360 conditional execution block. */
11361 gen_exception_internal(EXCP_KERNEL_TRAP
);
11362 dc
->is_jmp
= DISAS_EXC
;
11366 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11367 /* We always get here via a jump, so know we are not in a
11368 conditional execution block. */
11369 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11370 dc
->is_jmp
= DISAS_EXC
;
11375 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11377 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11378 if (bp
->pc
== dc
->pc
) {
11379 if (bp
->flags
& BP_CPU
) {
11380 gen_set_condexec(dc
);
11381 gen_set_pc_im(dc
, dc
->pc
);
11382 gen_helper_check_breakpoints(cpu_env
);
11383 /* End the TB early; it's likely not going to be executed */
11384 dc
->is_jmp
= DISAS_UPDATE
;
11386 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11387 /* The address covered by the breakpoint must be
11388 included in [tb->pc, tb->pc + tb->size) in order
11389 to for it to be properly cleared -- thus we
11390 increment the PC here so that the logic setting
11391 tb->size below does the right thing. */
11392 /* TODO: Advance PC by correct instruction length to
11393 * avoid disassembler error messages */
11395 goto done_generating
;
11402 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11406 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11407 /* Singlestep state is Active-pending.
11408 * If we're in this state at the start of a TB then either
11409 * a) we just took an exception to an EL which is being debugged
11410 * and this is the first insn in the exception handler
11411 * b) debug exceptions were masked and we just unmasked them
11412 * without changing EL (eg by clearing PSTATE.D)
11413 * In either case we're going to take a swstep exception in the
11414 * "did not step an insn" case, and so the syndrome ISV and EX
11415 * bits should be zero.
11417 assert(num_insns
== 1);
11418 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11419 default_exception_el(dc
));
11420 goto done_generating
;
11424 disas_thumb_insn(env
, dc
);
11425 if (dc
->condexec_mask
) {
11426 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11427 | ((dc
->condexec_mask
>> 4) & 1);
11428 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11429 if (dc
->condexec_mask
== 0) {
11430 dc
->condexec_cond
= 0;
11434 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->bswap_code
);
11436 disas_arm_insn(dc
, insn
);
11439 if (dc
->condjmp
&& !dc
->is_jmp
) {
11440 gen_set_label(dc
->condlabel
);
11444 if (tcg_check_temp_count()) {
11445 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11449 /* Translation stops when a conditional branch is encountered.
11450 * Otherwise the subsequent code could get translated several times.
11451 * Also stop translation when a page boundary is reached. This
11452 * ensures prefetch aborts occur at the right place. */
11454 /* We want to stop the TB if the next insn starts in a new page,
11455 * or if it spans between this page and the next. This means that
11456 * if we're looking at the last halfword in the page we need to
11457 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11458 * or a 32-bit Thumb insn (which won't).
11459 * This is to avoid generating a silly TB with a single 16-bit insn
11460 * in it at the end of this page (which would execute correctly
11461 * but isn't very efficient).
11463 end_of_page
= (dc
->pc
>= next_page_start
) ||
11464 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
11466 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11467 !cs
->singlestep_enabled
&&
11471 num_insns
< max_insns
);
11473 if (tb
->cflags
& CF_LAST_IO
) {
11475 /* FIXME: This can theoretically happen with self-modifying
11477 cpu_abort(cs
, "IO on conditional branch instruction");
11482 /* At this stage dc->condjmp will only be set when the skipped
11483 instruction was a conditional branch or trap, and the PC has
11484 already been written. */
11485 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11486 /* Unconditional and "condition passed" instruction codepath. */
11487 gen_set_condexec(dc
);
11488 switch (dc
->is_jmp
) {
11490 gen_ss_advance(dc
);
11491 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11492 default_exception_el(dc
));
11495 gen_ss_advance(dc
);
11496 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11499 gen_ss_advance(dc
);
11500 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11504 gen_set_pc_im(dc
, dc
->pc
);
11507 if (dc
->ss_active
) {
11508 gen_step_complete_exception(dc
);
11510 /* FIXME: Single stepping a WFI insn will not halt
11512 gen_exception_internal(EXCP_DEBUG
);
11516 /* "Condition failed" instruction codepath. */
11517 gen_set_label(dc
->condlabel
);
11518 gen_set_condexec(dc
);
11519 gen_set_pc_im(dc
, dc
->pc
);
11520 if (dc
->ss_active
) {
11521 gen_step_complete_exception(dc
);
11523 gen_exception_internal(EXCP_DEBUG
);
11527 /* While branches must always occur at the end of an IT block,
11528 there are a few other things that can cause us to terminate
11529 the TB in the middle of an IT block:
11530 - Exception generating instructions (bkpt, swi, undefined).
11532 - Hardware watchpoints.
11533 Hardware breakpoints have already been handled and skip this code.
11535 gen_set_condexec(dc
);
11536 switch(dc
->is_jmp
) {
11538 gen_goto_tb(dc
, 1, dc
->pc
);
11541 gen_set_pc_im(dc
, dc
->pc
);
11545 /* indicate that the hash table must be used to find the next TB */
11546 tcg_gen_exit_tb(0);
11548 case DISAS_TB_JUMP
:
11549 /* nothing more to generate */
11552 gen_helper_wfi(cpu_env
);
11553 /* The helper doesn't necessarily throw an exception, but we
11554 * must go back to the main loop to check for interrupts anyway.
11556 tcg_gen_exit_tb(0);
11559 gen_helper_wfe(cpu_env
);
11562 gen_helper_yield(cpu_env
);
11565 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11566 default_exception_el(dc
));
11569 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11572 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11576 gen_set_label(dc
->condlabel
);
11577 gen_set_condexec(dc
);
11578 gen_goto_tb(dc
, 1, dc
->pc
);
11584 gen_tb_end(tb
, num_insns
);
11587 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11588 qemu_log("----------------\n");
11589 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11590 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
11591 dc
->thumb
| (dc
->bswap_code
<< 1));
11595 tb
->size
= dc
->pc
- pc_start
;
11596 tb
->icount
= num_insns
;
11599 static const char *cpu_mode_names
[16] = {
11600 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11601 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11604 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11607 ARMCPU
*cpu
= ARM_CPU(cs
);
11608 CPUARMState
*env
= &cpu
->env
;
11611 const char *ns_status
;
11614 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11618 for(i
=0;i
<16;i
++) {
11619 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11621 cpu_fprintf(f
, "\n");
11623 cpu_fprintf(f
, " ");
11625 psr
= cpsr_read(env
);
11627 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
11628 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
11629 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
11634 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
11636 psr
& (1 << 31) ? 'N' : '-',
11637 psr
& (1 << 30) ? 'Z' : '-',
11638 psr
& (1 << 29) ? 'C' : '-',
11639 psr
& (1 << 28) ? 'V' : '-',
11640 psr
& CPSR_T
? 'T' : 'A',
11642 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11644 if (flags
& CPU_DUMP_FPU
) {
11645 int numvfpregs
= 0;
11646 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11649 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11652 for (i
= 0; i
< numvfpregs
; i
++) {
11653 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11654 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11655 i
* 2, (uint32_t)v
,
11656 i
* 2 + 1, (uint32_t)(v
>> 32),
11659 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11663 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
11664 target_ulong
*data
)
11668 env
->condexec_bits
= 0;
11670 env
->regs
[15] = data
[0];
11671 env
->condexec_bits
= data
[1];