4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
29 #include "qemu/bitops.h"
32 #include "exec/helper-proto.h"
33 #include "exec/helper-gen.h"
35 #include "trace-tcg.h"
39 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
40 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
41 /* currently all emulated v5 cores are also v5TE, so don't bother */
42 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
43 #define ENABLE_ARCH_5J 0
44 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
45 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
46 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
47 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
48 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
50 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
52 #include "translate.h"
54 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) (s->user)
61 /* We reuse the same 64-bit temporaries for efficiency. */
62 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
63 static TCGv_i32 cpu_R
[16];
64 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
65 TCGv_i64 cpu_exclusive_addr
;
66 TCGv_i64 cpu_exclusive_val
;
67 #ifdef CONFIG_USER_ONLY
68 TCGv_i64 cpu_exclusive_test
;
69 TCGv_i32 cpu_exclusive_info
;
72 /* FIXME: These should be removed. */
73 static TCGv_i32 cpu_F0s
, cpu_F1s
;
74 static TCGv_i64 cpu_F0d
, cpu_F1d
;
76 #include "exec/gen-icount.h"
78 static const char *regnames
[] =
79 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
80 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
82 /* initialize TCG globals. */
83 void arm_translate_init(void)
87 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
89 for (i
= 0; i
< 16; i
++) {
90 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
91 offsetof(CPUARMState
, regs
[i
]),
94 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
95 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
96 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
97 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
99 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
100 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
101 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
102 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
103 #ifdef CONFIG_USER_ONLY
104 cpu_exclusive_test
= tcg_global_mem_new_i64(cpu_env
,
105 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
106 cpu_exclusive_info
= tcg_global_mem_new_i32(cpu_env
,
107 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
110 a64_translate_init();
113 static inline ARMMMUIdx
get_a32_user_mem_index(DisasContext
*s
)
115 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
117 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
118 * otherwise, access as if at PL0.
120 switch (s
->mmu_idx
) {
121 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
122 case ARMMMUIdx_S12NSE0
:
123 case ARMMMUIdx_S12NSE1
:
124 return ARMMMUIdx_S12NSE0
;
126 case ARMMMUIdx_S1SE0
:
127 case ARMMMUIdx_S1SE1
:
128 return ARMMMUIdx_S1SE0
;
131 g_assert_not_reached();
135 static inline TCGv_i32
load_cpu_offset(int offset
)
137 TCGv_i32 tmp
= tcg_temp_new_i32();
138 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
142 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
144 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
146 tcg_gen_st_i32(var
, cpu_env
, offset
);
147 tcg_temp_free_i32(var
);
150 #define store_cpu_field(var, name) \
151 store_cpu_offset(var, offsetof(CPUARMState, name))
153 /* Set a variable to the value of a CPU register. */
154 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
158 /* normally, since we updated PC, we need only to add one insn */
160 addr
= (long)s
->pc
+ 2;
162 addr
= (long)s
->pc
+ 4;
163 tcg_gen_movi_i32(var
, addr
);
165 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
169 /* Create a new temporary and set it to the value of a CPU register. */
170 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
172 TCGv_i32 tmp
= tcg_temp_new_i32();
173 load_reg_var(s
, tmp
, reg
);
177 /* Set a CPU register. The source must be a temporary and will be
179 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
182 tcg_gen_andi_i32(var
, var
, ~1);
183 s
->is_jmp
= DISAS_JUMP
;
185 tcg_gen_mov_i32(cpu_R
[reg
], var
);
186 tcg_temp_free_i32(var
);
189 /* Value extensions. */
190 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
191 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
192 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
193 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
195 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
196 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
199 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
201 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
202 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
203 tcg_temp_free_i32(tmp_mask
);
205 /* Set NZCV flags from the high 4 bits of var. */
206 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
208 static void gen_exception_internal(int excp
)
210 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
212 assert(excp_is_internal(excp
));
213 gen_helper_exception_internal(cpu_env
, tcg_excp
);
214 tcg_temp_free_i32(tcg_excp
);
217 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
219 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
220 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
221 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
223 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
226 tcg_temp_free_i32(tcg_el
);
227 tcg_temp_free_i32(tcg_syn
);
228 tcg_temp_free_i32(tcg_excp
);
231 static void gen_ss_advance(DisasContext
*s
)
233 /* If the singlestep state is Active-not-pending, advance to
238 gen_helper_clear_pstate_ss(cpu_env
);
242 static void gen_step_complete_exception(DisasContext
*s
)
244 /* We just completed step of an insn. Move from Active-not-pending
245 * to Active-pending, and then also take the swstep exception.
246 * This corresponds to making the (IMPDEF) choice to prioritize
247 * swstep exceptions over asynchronous exceptions taken to an exception
248 * level where debug is disabled. This choice has the advantage that
249 * we do not need to maintain internal state corresponding to the
250 * ISV/EX syndrome bits between completion of the step and generation
251 * of the exception, and our syndrome information is always correct.
254 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
255 default_exception_el(s
));
256 s
->is_jmp
= DISAS_EXC
;
259 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
261 TCGv_i32 tmp1
= tcg_temp_new_i32();
262 TCGv_i32 tmp2
= tcg_temp_new_i32();
263 tcg_gen_ext16s_i32(tmp1
, a
);
264 tcg_gen_ext16s_i32(tmp2
, b
);
265 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
266 tcg_temp_free_i32(tmp2
);
267 tcg_gen_sari_i32(a
, a
, 16);
268 tcg_gen_sari_i32(b
, b
, 16);
269 tcg_gen_mul_i32(b
, b
, a
);
270 tcg_gen_mov_i32(a
, tmp1
);
271 tcg_temp_free_i32(tmp1
);
274 /* Byteswap each halfword. */
275 static void gen_rev16(TCGv_i32 var
)
277 TCGv_i32 tmp
= tcg_temp_new_i32();
278 tcg_gen_shri_i32(tmp
, var
, 8);
279 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
280 tcg_gen_shli_i32(var
, var
, 8);
281 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
282 tcg_gen_or_i32(var
, var
, tmp
);
283 tcg_temp_free_i32(tmp
);
286 /* Byteswap low halfword and sign extend. */
287 static void gen_revsh(TCGv_i32 var
)
289 tcg_gen_ext16u_i32(var
, var
);
290 tcg_gen_bswap16_i32(var
, var
);
291 tcg_gen_ext16s_i32(var
, var
);
294 /* Unsigned bitfield extract. */
295 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
298 tcg_gen_shri_i32(var
, var
, shift
);
299 tcg_gen_andi_i32(var
, var
, mask
);
302 /* Signed bitfield extract. */
303 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
308 tcg_gen_sari_i32(var
, var
, shift
);
309 if (shift
+ width
< 32) {
310 signbit
= 1u << (width
- 1);
311 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
312 tcg_gen_xori_i32(var
, var
, signbit
);
313 tcg_gen_subi_i32(var
, var
, signbit
);
317 /* Return (b << 32) + a. Mark inputs as dead */
318 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
320 TCGv_i64 tmp64
= tcg_temp_new_i64();
322 tcg_gen_extu_i32_i64(tmp64
, b
);
323 tcg_temp_free_i32(b
);
324 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
325 tcg_gen_add_i64(a
, tmp64
, a
);
327 tcg_temp_free_i64(tmp64
);
331 /* Return (b << 32) - a. Mark inputs as dead. */
332 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
334 TCGv_i64 tmp64
= tcg_temp_new_i64();
336 tcg_gen_extu_i32_i64(tmp64
, b
);
337 tcg_temp_free_i32(b
);
338 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
339 tcg_gen_sub_i64(a
, tmp64
, a
);
341 tcg_temp_free_i64(tmp64
);
345 /* 32x32->64 multiply. Marks inputs as dead. */
346 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
348 TCGv_i32 lo
= tcg_temp_new_i32();
349 TCGv_i32 hi
= tcg_temp_new_i32();
352 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
353 tcg_temp_free_i32(a
);
354 tcg_temp_free_i32(b
);
356 ret
= tcg_temp_new_i64();
357 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
358 tcg_temp_free_i32(lo
);
359 tcg_temp_free_i32(hi
);
364 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
366 TCGv_i32 lo
= tcg_temp_new_i32();
367 TCGv_i32 hi
= tcg_temp_new_i32();
370 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
371 tcg_temp_free_i32(a
);
372 tcg_temp_free_i32(b
);
374 ret
= tcg_temp_new_i64();
375 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
376 tcg_temp_free_i32(lo
);
377 tcg_temp_free_i32(hi
);
382 /* Swap low and high halfwords. */
383 static void gen_swap_half(TCGv_i32 var
)
385 TCGv_i32 tmp
= tcg_temp_new_i32();
386 tcg_gen_shri_i32(tmp
, var
, 16);
387 tcg_gen_shli_i32(var
, var
, 16);
388 tcg_gen_or_i32(var
, var
, tmp
);
389 tcg_temp_free_i32(tmp
);
392 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
393 tmp = (t0 ^ t1) & 0x8000;
396 t0 = (t0 + t1) ^ tmp;
399 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
401 TCGv_i32 tmp
= tcg_temp_new_i32();
402 tcg_gen_xor_i32(tmp
, t0
, t1
);
403 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
404 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
405 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
406 tcg_gen_add_i32(t0
, t0
, t1
);
407 tcg_gen_xor_i32(t0
, t0
, tmp
);
408 tcg_temp_free_i32(tmp
);
409 tcg_temp_free_i32(t1
);
412 /* Set CF to the top bit of var. */
413 static void gen_set_CF_bit31(TCGv_i32 var
)
415 tcg_gen_shri_i32(cpu_CF
, var
, 31);
418 /* Set N and Z flags from var. */
419 static inline void gen_logic_CC(TCGv_i32 var
)
421 tcg_gen_mov_i32(cpu_NF
, var
);
422 tcg_gen_mov_i32(cpu_ZF
, var
);
426 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
428 tcg_gen_add_i32(t0
, t0
, t1
);
429 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
432 /* dest = T0 + T1 + CF. */
433 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
435 tcg_gen_add_i32(dest
, t0
, t1
);
436 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
439 /* dest = T0 - T1 + CF - 1. */
440 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
442 tcg_gen_sub_i32(dest
, t0
, t1
);
443 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
444 tcg_gen_subi_i32(dest
, dest
, 1);
447 /* dest = T0 + T1. Compute C, N, V and Z flags */
448 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
450 TCGv_i32 tmp
= tcg_temp_new_i32();
451 tcg_gen_movi_i32(tmp
, 0);
452 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
453 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
454 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
455 tcg_gen_xor_i32(tmp
, t0
, t1
);
456 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
457 tcg_temp_free_i32(tmp
);
458 tcg_gen_mov_i32(dest
, cpu_NF
);
461 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
462 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
464 TCGv_i32 tmp
= tcg_temp_new_i32();
465 if (TCG_TARGET_HAS_add2_i32
) {
466 tcg_gen_movi_i32(tmp
, 0);
467 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
468 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
470 TCGv_i64 q0
= tcg_temp_new_i64();
471 TCGv_i64 q1
= tcg_temp_new_i64();
472 tcg_gen_extu_i32_i64(q0
, t0
);
473 tcg_gen_extu_i32_i64(q1
, t1
);
474 tcg_gen_add_i64(q0
, q0
, q1
);
475 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
476 tcg_gen_add_i64(q0
, q0
, q1
);
477 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
478 tcg_temp_free_i64(q0
);
479 tcg_temp_free_i64(q1
);
481 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
482 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
483 tcg_gen_xor_i32(tmp
, t0
, t1
);
484 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
485 tcg_temp_free_i32(tmp
);
486 tcg_gen_mov_i32(dest
, cpu_NF
);
489 /* dest = T0 - T1. Compute C, N, V and Z flags */
490 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
493 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
494 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
495 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
496 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
497 tmp
= tcg_temp_new_i32();
498 tcg_gen_xor_i32(tmp
, t0
, t1
);
499 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
500 tcg_temp_free_i32(tmp
);
501 tcg_gen_mov_i32(dest
, cpu_NF
);
504 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
505 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
507 TCGv_i32 tmp
= tcg_temp_new_i32();
508 tcg_gen_not_i32(tmp
, t1
);
509 gen_adc_CC(dest
, t0
, tmp
);
510 tcg_temp_free_i32(tmp
);
513 #define GEN_SHIFT(name) \
514 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
516 TCGv_i32 tmp1, tmp2, tmp3; \
517 tmp1 = tcg_temp_new_i32(); \
518 tcg_gen_andi_i32(tmp1, t1, 0xff); \
519 tmp2 = tcg_const_i32(0); \
520 tmp3 = tcg_const_i32(0x1f); \
521 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
522 tcg_temp_free_i32(tmp3); \
523 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
524 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
525 tcg_temp_free_i32(tmp2); \
526 tcg_temp_free_i32(tmp1); \
532 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
535 tmp1
= tcg_temp_new_i32();
536 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
537 tmp2
= tcg_const_i32(0x1f);
538 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
539 tcg_temp_free_i32(tmp2
);
540 tcg_gen_sar_i32(dest
, t0
, tmp1
);
541 tcg_temp_free_i32(tmp1
);
544 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
546 TCGv_i32 c0
= tcg_const_i32(0);
547 TCGv_i32 tmp
= tcg_temp_new_i32();
548 tcg_gen_neg_i32(tmp
, src
);
549 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
550 tcg_temp_free_i32(c0
);
551 tcg_temp_free_i32(tmp
);
554 static void shifter_out_im(TCGv_i32 var
, int shift
)
557 tcg_gen_andi_i32(cpu_CF
, var
, 1);
559 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
561 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
566 /* Shift by immediate. Includes special handling for shift == 0. */
567 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
568 int shift
, int flags
)
574 shifter_out_im(var
, 32 - shift
);
575 tcg_gen_shli_i32(var
, var
, shift
);
581 tcg_gen_shri_i32(cpu_CF
, var
, 31);
583 tcg_gen_movi_i32(var
, 0);
586 shifter_out_im(var
, shift
- 1);
587 tcg_gen_shri_i32(var
, var
, shift
);
594 shifter_out_im(var
, shift
- 1);
597 tcg_gen_sari_i32(var
, var
, shift
);
599 case 3: /* ROR/RRX */
602 shifter_out_im(var
, shift
- 1);
603 tcg_gen_rotri_i32(var
, var
, shift
); break;
605 TCGv_i32 tmp
= tcg_temp_new_i32();
606 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
608 shifter_out_im(var
, 0);
609 tcg_gen_shri_i32(var
, var
, 1);
610 tcg_gen_or_i32(var
, var
, tmp
);
611 tcg_temp_free_i32(tmp
);
616 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
617 TCGv_i32 shift
, int flags
)
621 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
622 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
623 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
624 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
629 gen_shl(var
, var
, shift
);
632 gen_shr(var
, var
, shift
);
635 gen_sar(var
, var
, shift
);
637 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
638 tcg_gen_rotr_i32(var
, var
, shift
); break;
641 tcg_temp_free_i32(shift
);
644 #define PAS_OP(pfx) \
646 case 0: gen_pas_helper(glue(pfx,add16)); break; \
647 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
648 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
649 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
650 case 4: gen_pas_helper(glue(pfx,add8)); break; \
651 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
653 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
658 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
660 tmp
= tcg_temp_new_ptr();
661 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
663 tcg_temp_free_ptr(tmp
);
666 tmp
= tcg_temp_new_ptr();
667 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
669 tcg_temp_free_ptr(tmp
);
671 #undef gen_pas_helper
672 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
685 #undef gen_pas_helper
690 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
691 #define PAS_OP(pfx) \
693 case 0: gen_pas_helper(glue(pfx,add8)); break; \
694 case 1: gen_pas_helper(glue(pfx,add16)); break; \
695 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
696 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
697 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
698 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
700 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
705 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
707 tmp
= tcg_temp_new_ptr();
708 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
710 tcg_temp_free_ptr(tmp
);
713 tmp
= tcg_temp_new_ptr();
714 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
716 tcg_temp_free_ptr(tmp
);
718 #undef gen_pas_helper
719 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
732 #undef gen_pas_helper
738 * Generate a conditional based on ARM condition code cc.
739 * This is common between ARM and Aarch64 targets.
741 void arm_test_cc(DisasCompare
*cmp
, int cc
)
772 case 8: /* hi: C && !Z */
773 case 9: /* ls: !C || Z -> !(C && !Z) */
775 value
= tcg_temp_new_i32();
777 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
778 ZF is non-zero for !Z; so AND the two subexpressions. */
779 tcg_gen_neg_i32(value
, cpu_CF
);
780 tcg_gen_and_i32(value
, value
, cpu_ZF
);
783 case 10: /* ge: N == V -> N ^ V == 0 */
784 case 11: /* lt: N != V -> N ^ V != 0 */
785 /* Since we're only interested in the sign bit, == 0 is >= 0. */
787 value
= tcg_temp_new_i32();
789 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
792 case 12: /* gt: !Z && N == V */
793 case 13: /* le: Z || N != V */
795 value
= tcg_temp_new_i32();
797 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
798 * the sign bit then AND with ZF to yield the result. */
799 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
800 tcg_gen_sari_i32(value
, value
, 31);
801 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
804 case 14: /* always */
805 case 15: /* always */
806 /* Use the ALWAYS condition, which will fold early.
807 * It doesn't matter what we use for the value. */
808 cond
= TCG_COND_ALWAYS
;
813 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
818 cond
= tcg_invert_cond(cond
);
824 cmp
->value_global
= global
;
827 void arm_free_cc(DisasCompare
*cmp
)
829 if (!cmp
->value_global
) {
830 tcg_temp_free_i32(cmp
->value
);
834 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
836 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
839 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
842 arm_test_cc(&cmp
, cc
);
843 arm_jump_cc(&cmp
, label
);
847 static const uint8_t table_logic_cc
[16] = {
866 /* Set PC and Thumb state from an immediate address. */
867 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
871 s
->is_jmp
= DISAS_JUMP
;
872 if (s
->thumb
!= (addr
& 1)) {
873 tmp
= tcg_temp_new_i32();
874 tcg_gen_movi_i32(tmp
, addr
& 1);
875 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
876 tcg_temp_free_i32(tmp
);
878 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
881 /* Set PC and Thumb state from var. var is marked as dead. */
882 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
884 s
->is_jmp
= DISAS_JUMP
;
885 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
886 tcg_gen_andi_i32(var
, var
, 1);
887 store_cpu_field(var
, thumb
);
890 /* Variant of store_reg which uses branch&exchange logic when storing
891 to r15 in ARM architecture v7 and above. The source must be a temporary
892 and will be marked as dead. */
893 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
895 if (reg
== 15 && ENABLE_ARCH_7
) {
898 store_reg(s
, reg
, var
);
902 /* Variant of store_reg which uses branch&exchange logic when storing
903 * to r15 in ARM architecture v5T and above. This is used for storing
904 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
905 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
906 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
908 if (reg
== 15 && ENABLE_ARCH_5
) {
911 store_reg(s
, reg
, var
);
915 #ifdef CONFIG_USER_ONLY
916 #define IS_USER_ONLY 1
918 #define IS_USER_ONLY 0
921 /* Abstractions of "generate code to do a guest load/store for
922 * AArch32", where a vaddr is always 32 bits (and is zero
923 * extended if we're a 64 bit core) and data is also
924 * 32 bits unless specifically doing a 64 bit access.
925 * These functions work like tcg_gen_qemu_{ld,st}* except
926 * that the address argument is TCGv_i32 rather than TCGv.
928 #if TARGET_LONG_BITS == 32
930 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
931 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
932 TCGv_i32 addr, int index) \
934 TCGMemOp opc = (OPC) | s->be_data; \
935 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
936 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
937 TCGv addr_be = tcg_temp_new(); \
938 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
939 tcg_gen_qemu_ld_i32(val, addr_be, index, opc); \
940 tcg_temp_free(addr_be); \
943 tcg_gen_qemu_ld_i32(val, addr, index, opc); \
946 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
947 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
948 TCGv_i32 addr, int index) \
950 TCGMemOp opc = (OPC) | s->be_data; \
951 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
952 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
953 TCGv addr_be = tcg_temp_new(); \
954 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
955 tcg_gen_qemu_st_i32(val, addr_be, index, opc); \
956 tcg_temp_free(addr_be); \
959 tcg_gen_qemu_st_i32(val, addr, index, opc); \
962 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
963 TCGv_i32 addr
, int index
)
965 TCGMemOp opc
= MO_Q
| s
->be_data
;
966 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
967 /* Not needed for user-mode BE32, where we use MO_BE instead. */
968 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
969 tcg_gen_rotri_i64(val
, val
, 32);
973 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
974 TCGv_i32 addr
, int index
)
976 TCGMemOp opc
= MO_Q
| s
->be_data
;
977 /* Not needed for user-mode BE32, where we use MO_BE instead. */
978 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
979 TCGv_i64 tmp
= tcg_temp_new_i64();
980 tcg_gen_rotri_i64(tmp
, val
, 32);
981 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
982 tcg_temp_free_i64(tmp
);
985 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
990 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
991 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
992 TCGv_i32 addr, int index) \
994 TCGMemOp opc = (OPC) | s->be_data; \
995 TCGv addr64 = tcg_temp_new(); \
996 tcg_gen_extu_i32_i64(addr64, addr); \
997 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
998 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
999 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1001 tcg_gen_qemu_ld_i32(val, addr64, index, opc); \
1002 tcg_temp_free(addr64); \
1005 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
1006 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1007 TCGv_i32 addr, int index) \
1009 TCGMemOp opc = (OPC) | s->be_data; \
1010 TCGv addr64 = tcg_temp_new(); \
1011 tcg_gen_extu_i32_i64(addr64, addr); \
1012 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
1013 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
1014 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1016 tcg_gen_qemu_st_i32(val, addr64, index, opc); \
1017 tcg_temp_free(addr64); \
1020 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1021 TCGv_i32 addr
, int index
)
1023 TCGMemOp opc
= MO_Q
| s
->be_data
;
1024 TCGv addr64
= tcg_temp_new();
1025 tcg_gen_extu_i32_i64(addr64
, addr
);
1026 tcg_gen_qemu_ld_i64(val
, addr64
, index
, opc
);
1028 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1029 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1030 tcg_gen_rotri_i64(val
, val
, 32);
1032 tcg_temp_free(addr64
);
1035 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1036 TCGv_i32 addr
, int index
)
1038 TCGMemOp opc
= MO_Q
| s
->be_data
;
1039 TCGv addr64
= tcg_temp_new();
1040 tcg_gen_extu_i32_i64(addr64
, addr
);
1042 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1043 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1044 TCGv tmp
= tcg_temp_new();
1045 tcg_gen_rotri_i64(tmp
, val
, 32);
1046 tcg_gen_qemu_st_i64(tmp
, addr64
, index
, opc
);
1049 tcg_gen_qemu_st_i64(val
, addr64
, index
, opc
);
1051 tcg_temp_free(addr64
);
1056 DO_GEN_LD(8s
, MO_SB
, 3)
1057 DO_GEN_LD(8u, MO_UB
, 3)
1058 DO_GEN_LD(16s
, MO_SW
, 2)
1059 DO_GEN_LD(16u, MO_UW
, 2)
1060 DO_GEN_LD(32u, MO_UL
, 0)
1061 /* 'a' variants include an alignment check */
1062 DO_GEN_LD(16ua
, MO_UW
| MO_ALIGN
, 2)
1063 DO_GEN_LD(32ua
, MO_UL
| MO_ALIGN
, 0)
1064 DO_GEN_ST(8, MO_UB
, 3)
1065 DO_GEN_ST(16, MO_UW
, 2)
1066 DO_GEN_ST(32, MO_UL
, 0)
1068 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
1070 tcg_gen_movi_i32(cpu_R
[15], val
);
1073 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1075 /* The pre HVC helper handles cases when HVC gets trapped
1076 * as an undefined insn by runtime configuration (ie before
1077 * the insn really executes).
1079 gen_set_pc_im(s
, s
->pc
- 4);
1080 gen_helper_pre_hvc(cpu_env
);
1081 /* Otherwise we will treat this as a real exception which
1082 * happens after execution of the insn. (The distinction matters
1083 * for the PC value reported to the exception handler and also
1084 * for single stepping.)
1087 gen_set_pc_im(s
, s
->pc
);
1088 s
->is_jmp
= DISAS_HVC
;
1091 static inline void gen_smc(DisasContext
*s
)
1093 /* As with HVC, we may take an exception either before or after
1094 * the insn executes.
1098 gen_set_pc_im(s
, s
->pc
- 4);
1099 tmp
= tcg_const_i32(syn_aa32_smc());
1100 gen_helper_pre_smc(cpu_env
, tmp
);
1101 tcg_temp_free_i32(tmp
);
1102 gen_set_pc_im(s
, s
->pc
);
1103 s
->is_jmp
= DISAS_SMC
;
1107 gen_set_condexec (DisasContext
*s
)
1109 if (s
->condexec_mask
) {
1110 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1111 TCGv_i32 tmp
= tcg_temp_new_i32();
1112 tcg_gen_movi_i32(tmp
, val
);
1113 store_cpu_field(tmp
, condexec_bits
);
1117 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1119 gen_set_condexec(s
);
1120 gen_set_pc_im(s
, s
->pc
- offset
);
1121 gen_exception_internal(excp
);
1122 s
->is_jmp
= DISAS_JUMP
;
1125 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1126 int syn
, uint32_t target_el
)
1128 gen_set_condexec(s
);
1129 gen_set_pc_im(s
, s
->pc
- offset
);
1130 gen_exception(excp
, syn
, target_el
);
1131 s
->is_jmp
= DISAS_JUMP
;
1134 /* Force a TB lookup after an instruction that changes the CPU state. */
1135 static inline void gen_lookup_tb(DisasContext
*s
)
1137 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1138 s
->is_jmp
= DISAS_JUMP
;
1141 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1144 int val
, rm
, shift
, shiftop
;
1147 if (!(insn
& (1 << 25))) {
1150 if (!(insn
& (1 << 23)))
1153 tcg_gen_addi_i32(var
, var
, val
);
1155 /* shift/register */
1157 shift
= (insn
>> 7) & 0x1f;
1158 shiftop
= (insn
>> 5) & 3;
1159 offset
= load_reg(s
, rm
);
1160 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1161 if (!(insn
& (1 << 23)))
1162 tcg_gen_sub_i32(var
, var
, offset
);
1164 tcg_gen_add_i32(var
, var
, offset
);
1165 tcg_temp_free_i32(offset
);
1169 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1170 int extra
, TCGv_i32 var
)
1175 if (insn
& (1 << 22)) {
1177 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1178 if (!(insn
& (1 << 23)))
1182 tcg_gen_addi_i32(var
, var
, val
);
1186 tcg_gen_addi_i32(var
, var
, extra
);
1188 offset
= load_reg(s
, rm
);
1189 if (!(insn
& (1 << 23)))
1190 tcg_gen_sub_i32(var
, var
, offset
);
1192 tcg_gen_add_i32(var
, var
, offset
);
1193 tcg_temp_free_i32(offset
);
1197 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1199 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1202 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1204 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1206 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1210 #define VFP_OP2(name) \
1211 static inline void gen_vfp_##name(int dp) \
1213 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1215 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1217 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1219 tcg_temp_free_ptr(fpst); \
1229 static inline void gen_vfp_F1_mul(int dp
)
1231 /* Like gen_vfp_mul() but put result in F1 */
1232 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1234 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1236 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1238 tcg_temp_free_ptr(fpst
);
1241 static inline void gen_vfp_F1_neg(int dp
)
1243 /* Like gen_vfp_neg() but put result in F1 */
1245 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1247 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1251 static inline void gen_vfp_abs(int dp
)
1254 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1256 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1259 static inline void gen_vfp_neg(int dp
)
1262 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1264 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1267 static inline void gen_vfp_sqrt(int dp
)
1270 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1272 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1275 static inline void gen_vfp_cmp(int dp
)
1278 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1280 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1283 static inline void gen_vfp_cmpe(int dp
)
1286 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1288 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1291 static inline void gen_vfp_F1_ld0(int dp
)
1294 tcg_gen_movi_i64(cpu_F1d
, 0);
1296 tcg_gen_movi_i32(cpu_F1s
, 0);
1299 #define VFP_GEN_ITOF(name) \
1300 static inline void gen_vfp_##name(int dp, int neon) \
1302 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1304 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1306 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1308 tcg_temp_free_ptr(statusptr); \
1315 #define VFP_GEN_FTOI(name) \
1316 static inline void gen_vfp_##name(int dp, int neon) \
1318 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1320 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1322 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1324 tcg_temp_free_ptr(statusptr); \
1333 #define VFP_GEN_FIX(name, round) \
1334 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1336 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1337 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1339 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1342 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1345 tcg_temp_free_i32(tmp_shift); \
1346 tcg_temp_free_ptr(statusptr); \
1348 VFP_GEN_FIX(tosh
, _round_to_zero
)
1349 VFP_GEN_FIX(tosl
, _round_to_zero
)
1350 VFP_GEN_FIX(touh
, _round_to_zero
)
1351 VFP_GEN_FIX(toul
, _round_to_zero
)
1358 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1361 gen_aa32_ld64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1363 gen_aa32_ld32u(s
, cpu_F0s
, addr
, get_mem_index(s
));
1367 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1370 gen_aa32_st64(s
, cpu_F0d
, addr
, get_mem_index(s
));
1372 gen_aa32_st32(s
, cpu_F0s
, addr
, get_mem_index(s
));
1377 vfp_reg_offset (int dp
, int reg
)
1380 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1382 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1383 + offsetof(CPU_DoubleU
, l
.upper
);
1385 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1386 + offsetof(CPU_DoubleU
, l
.lower
);
1390 /* Return the offset of a 32-bit piece of a NEON register.
1391 zero is the least significant end of the register. */
1393 neon_reg_offset (int reg
, int n
)
1397 return vfp_reg_offset(0, sreg
);
1400 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1402 TCGv_i32 tmp
= tcg_temp_new_i32();
1403 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1407 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1409 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1410 tcg_temp_free_i32(var
);
1413 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1415 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1418 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1420 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1423 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1424 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1425 #define tcg_gen_st_f32 tcg_gen_st_i32
1426 #define tcg_gen_st_f64 tcg_gen_st_i64
1428 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1431 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1433 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1436 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1439 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1441 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1444 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1447 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1449 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1452 #define ARM_CP_RW_BIT (1 << 20)
1454 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1456 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1459 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1461 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1464 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1466 TCGv_i32 var
= tcg_temp_new_i32();
1467 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1471 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1473 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1474 tcg_temp_free_i32(var
);
1477 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1479 iwmmxt_store_reg(cpu_M0
, rn
);
1482 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1484 iwmmxt_load_reg(cpu_M0
, rn
);
1487 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1489 iwmmxt_load_reg(cpu_V1
, rn
);
1490 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1493 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1495 iwmmxt_load_reg(cpu_V1
, rn
);
1496 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1499 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1501 iwmmxt_load_reg(cpu_V1
, rn
);
1502 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1505 #define IWMMXT_OP(name) \
1506 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1508 iwmmxt_load_reg(cpu_V1, rn); \
1509 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1512 #define IWMMXT_OP_ENV(name) \
1513 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1515 iwmmxt_load_reg(cpu_V1, rn); \
1516 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1519 #define IWMMXT_OP_ENV_SIZE(name) \
1520 IWMMXT_OP_ENV(name##b) \
1521 IWMMXT_OP_ENV(name##w) \
1522 IWMMXT_OP_ENV(name##l)
1524 #define IWMMXT_OP_ENV1(name) \
1525 static inline void gen_op_iwmmxt_##name##_M0(void) \
1527 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1541 IWMMXT_OP_ENV_SIZE(unpackl
)
1542 IWMMXT_OP_ENV_SIZE(unpackh
)
1544 IWMMXT_OP_ENV1(unpacklub
)
1545 IWMMXT_OP_ENV1(unpackluw
)
1546 IWMMXT_OP_ENV1(unpacklul
)
1547 IWMMXT_OP_ENV1(unpackhub
)
1548 IWMMXT_OP_ENV1(unpackhuw
)
1549 IWMMXT_OP_ENV1(unpackhul
)
1550 IWMMXT_OP_ENV1(unpacklsb
)
1551 IWMMXT_OP_ENV1(unpacklsw
)
1552 IWMMXT_OP_ENV1(unpacklsl
)
1553 IWMMXT_OP_ENV1(unpackhsb
)
1554 IWMMXT_OP_ENV1(unpackhsw
)
1555 IWMMXT_OP_ENV1(unpackhsl
)
1557 IWMMXT_OP_ENV_SIZE(cmpeq
)
1558 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1559 IWMMXT_OP_ENV_SIZE(cmpgts
)
1561 IWMMXT_OP_ENV_SIZE(mins
)
1562 IWMMXT_OP_ENV_SIZE(minu
)
1563 IWMMXT_OP_ENV_SIZE(maxs
)
1564 IWMMXT_OP_ENV_SIZE(maxu
)
1566 IWMMXT_OP_ENV_SIZE(subn
)
1567 IWMMXT_OP_ENV_SIZE(addn
)
1568 IWMMXT_OP_ENV_SIZE(subu
)
1569 IWMMXT_OP_ENV_SIZE(addu
)
1570 IWMMXT_OP_ENV_SIZE(subs
)
1571 IWMMXT_OP_ENV_SIZE(adds
)
1573 IWMMXT_OP_ENV(avgb0
)
1574 IWMMXT_OP_ENV(avgb1
)
1575 IWMMXT_OP_ENV(avgw0
)
1576 IWMMXT_OP_ENV(avgw1
)
1578 IWMMXT_OP_ENV(packuw
)
1579 IWMMXT_OP_ENV(packul
)
1580 IWMMXT_OP_ENV(packuq
)
1581 IWMMXT_OP_ENV(packsw
)
1582 IWMMXT_OP_ENV(packsl
)
1583 IWMMXT_OP_ENV(packsq
)
1585 static void gen_op_iwmmxt_set_mup(void)
1588 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1589 tcg_gen_ori_i32(tmp
, tmp
, 2);
1590 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1593 static void gen_op_iwmmxt_set_cup(void)
1596 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1597 tcg_gen_ori_i32(tmp
, tmp
, 1);
1598 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1601 static void gen_op_iwmmxt_setpsr_nz(void)
1603 TCGv_i32 tmp
= tcg_temp_new_i32();
1604 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1605 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1608 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1610 iwmmxt_load_reg(cpu_V1
, rn
);
1611 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1612 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1615 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1622 rd
= (insn
>> 16) & 0xf;
1623 tmp
= load_reg(s
, rd
);
1625 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1626 if (insn
& (1 << 24)) {
1628 if (insn
& (1 << 23))
1629 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1631 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1632 tcg_gen_mov_i32(dest
, tmp
);
1633 if (insn
& (1 << 21))
1634 store_reg(s
, rd
, tmp
);
1636 tcg_temp_free_i32(tmp
);
1637 } else if (insn
& (1 << 21)) {
1639 tcg_gen_mov_i32(dest
, tmp
);
1640 if (insn
& (1 << 23))
1641 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1643 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1644 store_reg(s
, rd
, tmp
);
1645 } else if (!(insn
& (1 << 23)))
1650 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1652 int rd
= (insn
>> 0) & 0xf;
1655 if (insn
& (1 << 8)) {
1656 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1659 tmp
= iwmmxt_load_creg(rd
);
1662 tmp
= tcg_temp_new_i32();
1663 iwmmxt_load_reg(cpu_V0
, rd
);
1664 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1666 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1667 tcg_gen_mov_i32(dest
, tmp
);
1668 tcg_temp_free_i32(tmp
);
1672 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1673 (ie. an undefined instruction). */
1674 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1677 int rdhi
, rdlo
, rd0
, rd1
, i
;
1679 TCGv_i32 tmp
, tmp2
, tmp3
;
1681 if ((insn
& 0x0e000e00) == 0x0c000000) {
1682 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1684 rdlo
= (insn
>> 12) & 0xf;
1685 rdhi
= (insn
>> 16) & 0xf;
1686 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1687 iwmmxt_load_reg(cpu_V0
, wrd
);
1688 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1689 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1690 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1691 } else { /* TMCRR */
1692 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1693 iwmmxt_store_reg(cpu_V0
, wrd
);
1694 gen_op_iwmmxt_set_mup();
1699 wrd
= (insn
>> 12) & 0xf;
1700 addr
= tcg_temp_new_i32();
1701 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1702 tcg_temp_free_i32(addr
);
1705 if (insn
& ARM_CP_RW_BIT
) {
1706 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1707 tmp
= tcg_temp_new_i32();
1708 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1709 iwmmxt_store_creg(wrd
, tmp
);
1712 if (insn
& (1 << 8)) {
1713 if (insn
& (1 << 22)) { /* WLDRD */
1714 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1716 } else { /* WLDRW wRd */
1717 tmp
= tcg_temp_new_i32();
1718 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1721 tmp
= tcg_temp_new_i32();
1722 if (insn
& (1 << 22)) { /* WLDRH */
1723 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1724 } else { /* WLDRB */
1725 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1729 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1730 tcg_temp_free_i32(tmp
);
1732 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1735 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1736 tmp
= iwmmxt_load_creg(wrd
);
1737 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1739 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1740 tmp
= tcg_temp_new_i32();
1741 if (insn
& (1 << 8)) {
1742 if (insn
& (1 << 22)) { /* WSTRD */
1743 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1744 } else { /* WSTRW wRd */
1745 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1746 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1749 if (insn
& (1 << 22)) { /* WSTRH */
1750 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1751 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1752 } else { /* WSTRB */
1753 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1754 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1758 tcg_temp_free_i32(tmp
);
1760 tcg_temp_free_i32(addr
);
1764 if ((insn
& 0x0f000000) != 0x0e000000)
1767 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1768 case 0x000: /* WOR */
1769 wrd
= (insn
>> 12) & 0xf;
1770 rd0
= (insn
>> 0) & 0xf;
1771 rd1
= (insn
>> 16) & 0xf;
1772 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1773 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1774 gen_op_iwmmxt_setpsr_nz();
1775 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1776 gen_op_iwmmxt_set_mup();
1777 gen_op_iwmmxt_set_cup();
1779 case 0x011: /* TMCR */
1782 rd
= (insn
>> 12) & 0xf;
1783 wrd
= (insn
>> 16) & 0xf;
1785 case ARM_IWMMXT_wCID
:
1786 case ARM_IWMMXT_wCASF
:
1788 case ARM_IWMMXT_wCon
:
1789 gen_op_iwmmxt_set_cup();
1791 case ARM_IWMMXT_wCSSF
:
1792 tmp
= iwmmxt_load_creg(wrd
);
1793 tmp2
= load_reg(s
, rd
);
1794 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1795 tcg_temp_free_i32(tmp2
);
1796 iwmmxt_store_creg(wrd
, tmp
);
1798 case ARM_IWMMXT_wCGR0
:
1799 case ARM_IWMMXT_wCGR1
:
1800 case ARM_IWMMXT_wCGR2
:
1801 case ARM_IWMMXT_wCGR3
:
1802 gen_op_iwmmxt_set_cup();
1803 tmp
= load_reg(s
, rd
);
1804 iwmmxt_store_creg(wrd
, tmp
);
1810 case 0x100: /* WXOR */
1811 wrd
= (insn
>> 12) & 0xf;
1812 rd0
= (insn
>> 0) & 0xf;
1813 rd1
= (insn
>> 16) & 0xf;
1814 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1815 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1816 gen_op_iwmmxt_setpsr_nz();
1817 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1818 gen_op_iwmmxt_set_mup();
1819 gen_op_iwmmxt_set_cup();
1821 case 0x111: /* TMRC */
1824 rd
= (insn
>> 12) & 0xf;
1825 wrd
= (insn
>> 16) & 0xf;
1826 tmp
= iwmmxt_load_creg(wrd
);
1827 store_reg(s
, rd
, tmp
);
1829 case 0x300: /* WANDN */
1830 wrd
= (insn
>> 12) & 0xf;
1831 rd0
= (insn
>> 0) & 0xf;
1832 rd1
= (insn
>> 16) & 0xf;
1833 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1834 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1835 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1836 gen_op_iwmmxt_setpsr_nz();
1837 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1838 gen_op_iwmmxt_set_mup();
1839 gen_op_iwmmxt_set_cup();
1841 case 0x200: /* WAND */
1842 wrd
= (insn
>> 12) & 0xf;
1843 rd0
= (insn
>> 0) & 0xf;
1844 rd1
= (insn
>> 16) & 0xf;
1845 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1846 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1847 gen_op_iwmmxt_setpsr_nz();
1848 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1849 gen_op_iwmmxt_set_mup();
1850 gen_op_iwmmxt_set_cup();
1852 case 0x810: case 0xa10: /* WMADD */
1853 wrd
= (insn
>> 12) & 0xf;
1854 rd0
= (insn
>> 0) & 0xf;
1855 rd1
= (insn
>> 16) & 0xf;
1856 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1857 if (insn
& (1 << 21))
1858 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1860 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1861 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1862 gen_op_iwmmxt_set_mup();
1864 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1865 wrd
= (insn
>> 12) & 0xf;
1866 rd0
= (insn
>> 16) & 0xf;
1867 rd1
= (insn
>> 0) & 0xf;
1868 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1869 switch ((insn
>> 22) & 3) {
1871 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1874 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1877 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1882 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1883 gen_op_iwmmxt_set_mup();
1884 gen_op_iwmmxt_set_cup();
1886 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1887 wrd
= (insn
>> 12) & 0xf;
1888 rd0
= (insn
>> 16) & 0xf;
1889 rd1
= (insn
>> 0) & 0xf;
1890 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1891 switch ((insn
>> 22) & 3) {
1893 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1896 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1899 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1904 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1905 gen_op_iwmmxt_set_mup();
1906 gen_op_iwmmxt_set_cup();
1908 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1909 wrd
= (insn
>> 12) & 0xf;
1910 rd0
= (insn
>> 16) & 0xf;
1911 rd1
= (insn
>> 0) & 0xf;
1912 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1913 if (insn
& (1 << 22))
1914 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1916 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1917 if (!(insn
& (1 << 20)))
1918 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1919 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1920 gen_op_iwmmxt_set_mup();
1922 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1923 wrd
= (insn
>> 12) & 0xf;
1924 rd0
= (insn
>> 16) & 0xf;
1925 rd1
= (insn
>> 0) & 0xf;
1926 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1927 if (insn
& (1 << 21)) {
1928 if (insn
& (1 << 20))
1929 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1931 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1933 if (insn
& (1 << 20))
1934 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1936 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1938 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1939 gen_op_iwmmxt_set_mup();
1941 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1942 wrd
= (insn
>> 12) & 0xf;
1943 rd0
= (insn
>> 16) & 0xf;
1944 rd1
= (insn
>> 0) & 0xf;
1945 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1946 if (insn
& (1 << 21))
1947 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1949 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1950 if (!(insn
& (1 << 20))) {
1951 iwmmxt_load_reg(cpu_V1
, wrd
);
1952 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1954 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1955 gen_op_iwmmxt_set_mup();
1957 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1958 wrd
= (insn
>> 12) & 0xf;
1959 rd0
= (insn
>> 16) & 0xf;
1960 rd1
= (insn
>> 0) & 0xf;
1961 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1962 switch ((insn
>> 22) & 3) {
1964 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1967 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1970 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1975 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1976 gen_op_iwmmxt_set_mup();
1977 gen_op_iwmmxt_set_cup();
1979 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1980 wrd
= (insn
>> 12) & 0xf;
1981 rd0
= (insn
>> 16) & 0xf;
1982 rd1
= (insn
>> 0) & 0xf;
1983 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1984 if (insn
& (1 << 22)) {
1985 if (insn
& (1 << 20))
1986 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1988 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1990 if (insn
& (1 << 20))
1991 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1993 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1995 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1996 gen_op_iwmmxt_set_mup();
1997 gen_op_iwmmxt_set_cup();
1999 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2000 wrd
= (insn
>> 12) & 0xf;
2001 rd0
= (insn
>> 16) & 0xf;
2002 rd1
= (insn
>> 0) & 0xf;
2003 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2004 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2005 tcg_gen_andi_i32(tmp
, tmp
, 7);
2006 iwmmxt_load_reg(cpu_V1
, rd1
);
2007 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2008 tcg_temp_free_i32(tmp
);
2009 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2010 gen_op_iwmmxt_set_mup();
2012 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2013 if (((insn
>> 6) & 3) == 3)
2015 rd
= (insn
>> 12) & 0xf;
2016 wrd
= (insn
>> 16) & 0xf;
2017 tmp
= load_reg(s
, rd
);
2018 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2019 switch ((insn
>> 6) & 3) {
2021 tmp2
= tcg_const_i32(0xff);
2022 tmp3
= tcg_const_i32((insn
& 7) << 3);
2025 tmp2
= tcg_const_i32(0xffff);
2026 tmp3
= tcg_const_i32((insn
& 3) << 4);
2029 tmp2
= tcg_const_i32(0xffffffff);
2030 tmp3
= tcg_const_i32((insn
& 1) << 5);
2033 TCGV_UNUSED_I32(tmp2
);
2034 TCGV_UNUSED_I32(tmp3
);
2036 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2037 tcg_temp_free_i32(tmp3
);
2038 tcg_temp_free_i32(tmp2
);
2039 tcg_temp_free_i32(tmp
);
2040 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2041 gen_op_iwmmxt_set_mup();
2043 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2044 rd
= (insn
>> 12) & 0xf;
2045 wrd
= (insn
>> 16) & 0xf;
2046 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2048 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2049 tmp
= tcg_temp_new_i32();
2050 switch ((insn
>> 22) & 3) {
2052 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2053 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2055 tcg_gen_ext8s_i32(tmp
, tmp
);
2057 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2061 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2062 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2064 tcg_gen_ext16s_i32(tmp
, tmp
);
2066 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2070 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2071 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2074 store_reg(s
, rd
, tmp
);
2076 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2077 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2079 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2080 switch ((insn
>> 22) & 3) {
2082 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2085 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2088 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2091 tcg_gen_shli_i32(tmp
, tmp
, 28);
2093 tcg_temp_free_i32(tmp
);
2095 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2096 if (((insn
>> 6) & 3) == 3)
2098 rd
= (insn
>> 12) & 0xf;
2099 wrd
= (insn
>> 16) & 0xf;
2100 tmp
= load_reg(s
, rd
);
2101 switch ((insn
>> 6) & 3) {
2103 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2106 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2109 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2112 tcg_temp_free_i32(tmp
);
2113 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2114 gen_op_iwmmxt_set_mup();
2116 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2117 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2119 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2120 tmp2
= tcg_temp_new_i32();
2121 tcg_gen_mov_i32(tmp2
, tmp
);
2122 switch ((insn
>> 22) & 3) {
2124 for (i
= 0; i
< 7; i
++) {
2125 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2126 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2130 for (i
= 0; i
< 3; i
++) {
2131 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2132 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2136 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2137 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2141 tcg_temp_free_i32(tmp2
);
2142 tcg_temp_free_i32(tmp
);
2144 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2145 wrd
= (insn
>> 12) & 0xf;
2146 rd0
= (insn
>> 16) & 0xf;
2147 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2148 switch ((insn
>> 22) & 3) {
2150 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2153 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2156 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2161 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2162 gen_op_iwmmxt_set_mup();
2164 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2165 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2167 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2168 tmp2
= tcg_temp_new_i32();
2169 tcg_gen_mov_i32(tmp2
, tmp
);
2170 switch ((insn
>> 22) & 3) {
2172 for (i
= 0; i
< 7; i
++) {
2173 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2174 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2178 for (i
= 0; i
< 3; i
++) {
2179 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2180 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2184 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2185 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2189 tcg_temp_free_i32(tmp2
);
2190 tcg_temp_free_i32(tmp
);
2192 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2193 rd
= (insn
>> 12) & 0xf;
2194 rd0
= (insn
>> 16) & 0xf;
2195 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2197 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2198 tmp
= tcg_temp_new_i32();
2199 switch ((insn
>> 22) & 3) {
2201 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2204 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2207 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2210 store_reg(s
, rd
, tmp
);
2212 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2213 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2214 wrd
= (insn
>> 12) & 0xf;
2215 rd0
= (insn
>> 16) & 0xf;
2216 rd1
= (insn
>> 0) & 0xf;
2217 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2218 switch ((insn
>> 22) & 3) {
2220 if (insn
& (1 << 21))
2221 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2223 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2226 if (insn
& (1 << 21))
2227 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2229 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2232 if (insn
& (1 << 21))
2233 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2235 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2240 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2241 gen_op_iwmmxt_set_mup();
2242 gen_op_iwmmxt_set_cup();
2244 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2245 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2246 wrd
= (insn
>> 12) & 0xf;
2247 rd0
= (insn
>> 16) & 0xf;
2248 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2249 switch ((insn
>> 22) & 3) {
2251 if (insn
& (1 << 21))
2252 gen_op_iwmmxt_unpacklsb_M0();
2254 gen_op_iwmmxt_unpacklub_M0();
2257 if (insn
& (1 << 21))
2258 gen_op_iwmmxt_unpacklsw_M0();
2260 gen_op_iwmmxt_unpackluw_M0();
2263 if (insn
& (1 << 21))
2264 gen_op_iwmmxt_unpacklsl_M0();
2266 gen_op_iwmmxt_unpacklul_M0();
2271 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2272 gen_op_iwmmxt_set_mup();
2273 gen_op_iwmmxt_set_cup();
2275 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2276 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2277 wrd
= (insn
>> 12) & 0xf;
2278 rd0
= (insn
>> 16) & 0xf;
2279 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2280 switch ((insn
>> 22) & 3) {
2282 if (insn
& (1 << 21))
2283 gen_op_iwmmxt_unpackhsb_M0();
2285 gen_op_iwmmxt_unpackhub_M0();
2288 if (insn
& (1 << 21))
2289 gen_op_iwmmxt_unpackhsw_M0();
2291 gen_op_iwmmxt_unpackhuw_M0();
2294 if (insn
& (1 << 21))
2295 gen_op_iwmmxt_unpackhsl_M0();
2297 gen_op_iwmmxt_unpackhul_M0();
2302 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2303 gen_op_iwmmxt_set_mup();
2304 gen_op_iwmmxt_set_cup();
2306 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2307 case 0x214: case 0x614: case 0xa14: case 0xe14:
2308 if (((insn
>> 22) & 3) == 0)
2310 wrd
= (insn
>> 12) & 0xf;
2311 rd0
= (insn
>> 16) & 0xf;
2312 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2313 tmp
= tcg_temp_new_i32();
2314 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2315 tcg_temp_free_i32(tmp
);
2318 switch ((insn
>> 22) & 3) {
2320 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2323 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2326 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2329 tcg_temp_free_i32(tmp
);
2330 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2331 gen_op_iwmmxt_set_mup();
2332 gen_op_iwmmxt_set_cup();
2334 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2335 case 0x014: case 0x414: case 0x814: case 0xc14:
2336 if (((insn
>> 22) & 3) == 0)
2338 wrd
= (insn
>> 12) & 0xf;
2339 rd0
= (insn
>> 16) & 0xf;
2340 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2341 tmp
= tcg_temp_new_i32();
2342 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2343 tcg_temp_free_i32(tmp
);
2346 switch ((insn
>> 22) & 3) {
2348 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2351 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2354 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2357 tcg_temp_free_i32(tmp
);
2358 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2359 gen_op_iwmmxt_set_mup();
2360 gen_op_iwmmxt_set_cup();
2362 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2363 case 0x114: case 0x514: case 0x914: case 0xd14:
2364 if (((insn
>> 22) & 3) == 0)
2366 wrd
= (insn
>> 12) & 0xf;
2367 rd0
= (insn
>> 16) & 0xf;
2368 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2369 tmp
= tcg_temp_new_i32();
2370 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2371 tcg_temp_free_i32(tmp
);
2374 switch ((insn
>> 22) & 3) {
2376 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2379 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2382 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2385 tcg_temp_free_i32(tmp
);
2386 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2387 gen_op_iwmmxt_set_mup();
2388 gen_op_iwmmxt_set_cup();
2390 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2391 case 0x314: case 0x714: case 0xb14: case 0xf14:
2392 if (((insn
>> 22) & 3) == 0)
2394 wrd
= (insn
>> 12) & 0xf;
2395 rd0
= (insn
>> 16) & 0xf;
2396 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2397 tmp
= tcg_temp_new_i32();
2398 switch ((insn
>> 22) & 3) {
2400 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2401 tcg_temp_free_i32(tmp
);
2404 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2407 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2408 tcg_temp_free_i32(tmp
);
2411 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2414 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2415 tcg_temp_free_i32(tmp
);
2418 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2421 tcg_temp_free_i32(tmp
);
2422 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2423 gen_op_iwmmxt_set_mup();
2424 gen_op_iwmmxt_set_cup();
2426 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2427 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2428 wrd
= (insn
>> 12) & 0xf;
2429 rd0
= (insn
>> 16) & 0xf;
2430 rd1
= (insn
>> 0) & 0xf;
2431 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2432 switch ((insn
>> 22) & 3) {
2434 if (insn
& (1 << 21))
2435 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2437 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2440 if (insn
& (1 << 21))
2441 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2443 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2446 if (insn
& (1 << 21))
2447 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2449 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2454 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2455 gen_op_iwmmxt_set_mup();
2457 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2458 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2459 wrd
= (insn
>> 12) & 0xf;
2460 rd0
= (insn
>> 16) & 0xf;
2461 rd1
= (insn
>> 0) & 0xf;
2462 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2463 switch ((insn
>> 22) & 3) {
2465 if (insn
& (1 << 21))
2466 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2468 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2471 if (insn
& (1 << 21))
2472 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2474 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2477 if (insn
& (1 << 21))
2478 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2480 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2485 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2486 gen_op_iwmmxt_set_mup();
2488 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2489 case 0x402: case 0x502: case 0x602: case 0x702:
2490 wrd
= (insn
>> 12) & 0xf;
2491 rd0
= (insn
>> 16) & 0xf;
2492 rd1
= (insn
>> 0) & 0xf;
2493 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2494 tmp
= tcg_const_i32((insn
>> 20) & 3);
2495 iwmmxt_load_reg(cpu_V1
, rd1
);
2496 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2497 tcg_temp_free_i32(tmp
);
2498 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2499 gen_op_iwmmxt_set_mup();
2501 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2502 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2503 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2504 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2505 wrd
= (insn
>> 12) & 0xf;
2506 rd0
= (insn
>> 16) & 0xf;
2507 rd1
= (insn
>> 0) & 0xf;
2508 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2509 switch ((insn
>> 20) & 0xf) {
2511 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2514 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2517 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2520 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2523 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2526 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2529 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2532 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2535 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2540 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2541 gen_op_iwmmxt_set_mup();
2542 gen_op_iwmmxt_set_cup();
2544 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2545 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2546 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2547 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2548 wrd
= (insn
>> 12) & 0xf;
2549 rd0
= (insn
>> 16) & 0xf;
2550 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2551 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2552 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2553 tcg_temp_free_i32(tmp
);
2554 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2555 gen_op_iwmmxt_set_mup();
2556 gen_op_iwmmxt_set_cup();
2558 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2559 case 0x418: case 0x518: case 0x618: case 0x718:
2560 case 0x818: case 0x918: case 0xa18: case 0xb18:
2561 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2562 wrd
= (insn
>> 12) & 0xf;
2563 rd0
= (insn
>> 16) & 0xf;
2564 rd1
= (insn
>> 0) & 0xf;
2565 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2566 switch ((insn
>> 20) & 0xf) {
2568 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2571 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2574 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2577 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2580 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2583 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2586 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2589 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2592 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2597 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2598 gen_op_iwmmxt_set_mup();
2599 gen_op_iwmmxt_set_cup();
2601 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2602 case 0x408: case 0x508: case 0x608: case 0x708:
2603 case 0x808: case 0x908: case 0xa08: case 0xb08:
2604 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2605 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2607 wrd
= (insn
>> 12) & 0xf;
2608 rd0
= (insn
>> 16) & 0xf;
2609 rd1
= (insn
>> 0) & 0xf;
2610 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2611 switch ((insn
>> 22) & 3) {
2613 if (insn
& (1 << 21))
2614 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2616 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2619 if (insn
& (1 << 21))
2620 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2622 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2625 if (insn
& (1 << 21))
2626 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2628 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2631 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2632 gen_op_iwmmxt_set_mup();
2633 gen_op_iwmmxt_set_cup();
2635 case 0x201: case 0x203: case 0x205: case 0x207:
2636 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2637 case 0x211: case 0x213: case 0x215: case 0x217:
2638 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2639 wrd
= (insn
>> 5) & 0xf;
2640 rd0
= (insn
>> 12) & 0xf;
2641 rd1
= (insn
>> 0) & 0xf;
2642 if (rd0
== 0xf || rd1
== 0xf)
2644 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2645 tmp
= load_reg(s
, rd0
);
2646 tmp2
= load_reg(s
, rd1
);
2647 switch ((insn
>> 16) & 0xf) {
2648 case 0x0: /* TMIA */
2649 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2651 case 0x8: /* TMIAPH */
2652 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2654 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2655 if (insn
& (1 << 16))
2656 tcg_gen_shri_i32(tmp
, tmp
, 16);
2657 if (insn
& (1 << 17))
2658 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2659 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2662 tcg_temp_free_i32(tmp2
);
2663 tcg_temp_free_i32(tmp
);
2666 tcg_temp_free_i32(tmp2
);
2667 tcg_temp_free_i32(tmp
);
2668 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2669 gen_op_iwmmxt_set_mup();
2678 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2679 (ie. an undefined instruction). */
2680 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2682 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2685 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2686 /* Multiply with Internal Accumulate Format */
2687 rd0
= (insn
>> 12) & 0xf;
2689 acc
= (insn
>> 5) & 7;
2694 tmp
= load_reg(s
, rd0
);
2695 tmp2
= load_reg(s
, rd1
);
2696 switch ((insn
>> 16) & 0xf) {
2698 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2700 case 0x8: /* MIAPH */
2701 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2703 case 0xc: /* MIABB */
2704 case 0xd: /* MIABT */
2705 case 0xe: /* MIATB */
2706 case 0xf: /* MIATT */
2707 if (insn
& (1 << 16))
2708 tcg_gen_shri_i32(tmp
, tmp
, 16);
2709 if (insn
& (1 << 17))
2710 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2711 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2716 tcg_temp_free_i32(tmp2
);
2717 tcg_temp_free_i32(tmp
);
2719 gen_op_iwmmxt_movq_wRn_M0(acc
);
2723 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2724 /* Internal Accumulator Access Format */
2725 rdhi
= (insn
>> 16) & 0xf;
2726 rdlo
= (insn
>> 12) & 0xf;
2732 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2733 iwmmxt_load_reg(cpu_V0
, acc
);
2734 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2735 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2736 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2737 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2739 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2740 iwmmxt_store_reg(cpu_V0
, acc
);
2748 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2749 #define VFP_SREG(insn, bigbit, smallbit) \
2750 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2751 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2752 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2753 reg = (((insn) >> (bigbit)) & 0x0f) \
2754 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2756 if (insn & (1 << (smallbit))) \
2758 reg = ((insn) >> (bigbit)) & 0x0f; \
2761 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2762 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2763 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2764 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2765 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2766 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2768 /* Move between integer and VFP cores. */
2769 static TCGv_i32
gen_vfp_mrs(void)
2771 TCGv_i32 tmp
= tcg_temp_new_i32();
2772 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2776 static void gen_vfp_msr(TCGv_i32 tmp
)
2778 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2779 tcg_temp_free_i32(tmp
);
2782 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2784 TCGv_i32 tmp
= tcg_temp_new_i32();
2786 tcg_gen_shri_i32(var
, var
, shift
);
2787 tcg_gen_ext8u_i32(var
, var
);
2788 tcg_gen_shli_i32(tmp
, var
, 8);
2789 tcg_gen_or_i32(var
, var
, tmp
);
2790 tcg_gen_shli_i32(tmp
, var
, 16);
2791 tcg_gen_or_i32(var
, var
, tmp
);
2792 tcg_temp_free_i32(tmp
);
2795 static void gen_neon_dup_low16(TCGv_i32 var
)
2797 TCGv_i32 tmp
= tcg_temp_new_i32();
2798 tcg_gen_ext16u_i32(var
, var
);
2799 tcg_gen_shli_i32(tmp
, var
, 16);
2800 tcg_gen_or_i32(var
, var
, tmp
);
2801 tcg_temp_free_i32(tmp
);
2804 static void gen_neon_dup_high16(TCGv_i32 var
)
2806 TCGv_i32 tmp
= tcg_temp_new_i32();
2807 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2808 tcg_gen_shri_i32(tmp
, var
, 16);
2809 tcg_gen_or_i32(var
, var
, tmp
);
2810 tcg_temp_free_i32(tmp
);
2813 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2815 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2816 TCGv_i32 tmp
= tcg_temp_new_i32();
2819 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
2820 gen_neon_dup_u8(tmp
, 0);
2823 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
2824 gen_neon_dup_low16(tmp
);
2827 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
2829 default: /* Avoid compiler warnings. */
2835 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2838 uint32_t cc
= extract32(insn
, 20, 2);
2841 TCGv_i64 frn
, frm
, dest
;
2842 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2844 zero
= tcg_const_i64(0);
2846 frn
= tcg_temp_new_i64();
2847 frm
= tcg_temp_new_i64();
2848 dest
= tcg_temp_new_i64();
2850 zf
= tcg_temp_new_i64();
2851 nf
= tcg_temp_new_i64();
2852 vf
= tcg_temp_new_i64();
2854 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2855 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2856 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2858 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2859 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2862 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2866 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2869 case 2: /* ge: N == V -> N ^ V == 0 */
2870 tmp
= tcg_temp_new_i64();
2871 tcg_gen_xor_i64(tmp
, vf
, nf
);
2872 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2874 tcg_temp_free_i64(tmp
);
2876 case 3: /* gt: !Z && N == V */
2877 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2879 tmp
= tcg_temp_new_i64();
2880 tcg_gen_xor_i64(tmp
, vf
, nf
);
2881 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2883 tcg_temp_free_i64(tmp
);
2886 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2887 tcg_temp_free_i64(frn
);
2888 tcg_temp_free_i64(frm
);
2889 tcg_temp_free_i64(dest
);
2891 tcg_temp_free_i64(zf
);
2892 tcg_temp_free_i64(nf
);
2893 tcg_temp_free_i64(vf
);
2895 tcg_temp_free_i64(zero
);
2897 TCGv_i32 frn
, frm
, dest
;
2900 zero
= tcg_const_i32(0);
2902 frn
= tcg_temp_new_i32();
2903 frm
= tcg_temp_new_i32();
2904 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
));
2909 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2913 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2916 case 2: /* ge: N == V -> N ^ V == 0 */
2917 tmp
= tcg_temp_new_i32();
2918 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2919 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2921 tcg_temp_free_i32(tmp
);
2923 case 3: /* gt: !Z && N == V */
2924 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2926 tmp
= tcg_temp_new_i32();
2927 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2928 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2930 tcg_temp_free_i32(tmp
);
2933 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2934 tcg_temp_free_i32(frn
);
2935 tcg_temp_free_i32(frm
);
2936 tcg_temp_free_i32(dest
);
2938 tcg_temp_free_i32(zero
);
2944 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2945 uint32_t rm
, uint32_t dp
)
2947 uint32_t vmin
= extract32(insn
, 6, 1);
2948 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2951 TCGv_i64 frn
, frm
, dest
;
2953 frn
= tcg_temp_new_i64();
2954 frm
= tcg_temp_new_i64();
2955 dest
= tcg_temp_new_i64();
2957 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2958 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2960 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2962 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2964 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2965 tcg_temp_free_i64(frn
);
2966 tcg_temp_free_i64(frm
);
2967 tcg_temp_free_i64(dest
);
2969 TCGv_i32 frn
, frm
, dest
;
2971 frn
= tcg_temp_new_i32();
2972 frm
= tcg_temp_new_i32();
2973 dest
= tcg_temp_new_i32();
2975 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2976 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2978 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2980 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2982 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2983 tcg_temp_free_i32(frn
);
2984 tcg_temp_free_i32(frm
);
2985 tcg_temp_free_i32(dest
);
2988 tcg_temp_free_ptr(fpst
);
2992 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2995 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2998 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2999 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3004 tcg_op
= tcg_temp_new_i64();
3005 tcg_res
= tcg_temp_new_i64();
3006 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3007 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
3008 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3009 tcg_temp_free_i64(tcg_op
);
3010 tcg_temp_free_i64(tcg_res
);
3014 tcg_op
= tcg_temp_new_i32();
3015 tcg_res
= tcg_temp_new_i32();
3016 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
3017 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
3018 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
3019 tcg_temp_free_i32(tcg_op
);
3020 tcg_temp_free_i32(tcg_res
);
3023 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3024 tcg_temp_free_i32(tcg_rmode
);
3026 tcg_temp_free_ptr(fpst
);
3030 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
3033 bool is_signed
= extract32(insn
, 7, 1);
3034 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3035 TCGv_i32 tcg_rmode
, tcg_shift
;
3037 tcg_shift
= tcg_const_i32(0);
3039 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
3040 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3043 TCGv_i64 tcg_double
, tcg_res
;
3045 /* Rd is encoded as a single precision register even when the source
3046 * is double precision.
3048 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
3049 tcg_double
= tcg_temp_new_i64();
3050 tcg_res
= tcg_temp_new_i64();
3051 tcg_tmp
= tcg_temp_new_i32();
3052 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
3054 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3056 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
3058 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
3059 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
3060 tcg_temp_free_i32(tcg_tmp
);
3061 tcg_temp_free_i64(tcg_res
);
3062 tcg_temp_free_i64(tcg_double
);
3064 TCGv_i32 tcg_single
, tcg_res
;
3065 tcg_single
= tcg_temp_new_i32();
3066 tcg_res
= tcg_temp_new_i32();
3067 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
3069 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3071 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3073 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3074 tcg_temp_free_i32(tcg_res
);
3075 tcg_temp_free_i32(tcg_single
);
3078 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3079 tcg_temp_free_i32(tcg_rmode
);
3081 tcg_temp_free_i32(tcg_shift
);
3083 tcg_temp_free_ptr(fpst
);
3088 /* Table for converting the most common AArch32 encoding of
3089 * rounding mode to arm_fprounding order (which matches the
3090 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3092 static const uint8_t fp_decode_rm
[] = {
3099 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3101 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3103 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3108 VFP_DREG_D(rd
, insn
);
3109 VFP_DREG_N(rn
, insn
);
3110 VFP_DREG_M(rm
, insn
);
3112 rd
= VFP_SREG_D(insn
);
3113 rn
= VFP_SREG_N(insn
);
3114 rm
= VFP_SREG_M(insn
);
3117 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3118 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3119 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3120 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3121 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3122 /* VRINTA, VRINTN, VRINTP, VRINTM */
3123 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3124 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3125 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3126 /* VCVTA, VCVTN, VCVTP, VCVTM */
3127 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3128 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3133 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3134 (ie. an undefined instruction). */
3135 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3137 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3143 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3147 /* FIXME: this access check should not take precedence over UNDEF
3148 * for invalid encodings; we will generate incorrect syndrome information
3149 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3151 if (s
->fp_excp_el
) {
3152 gen_exception_insn(s
, 4, EXCP_UDEF
,
3153 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3157 if (!s
->vfp_enabled
) {
3158 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3159 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3161 rn
= (insn
>> 16) & 0xf;
3162 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3163 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3168 if (extract32(insn
, 28, 4) == 0xf) {
3169 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3170 * only used in v8 and above.
3172 return disas_vfp_v8_insn(s
, insn
);
3175 dp
= ((insn
& 0xf00) == 0xb00);
3176 switch ((insn
>> 24) & 0xf) {
3178 if (insn
& (1 << 4)) {
3179 /* single register transfer */
3180 rd
= (insn
>> 12) & 0xf;
3185 VFP_DREG_N(rn
, insn
);
3188 if (insn
& 0x00c00060
3189 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3193 pass
= (insn
>> 21) & 1;
3194 if (insn
& (1 << 22)) {
3196 offset
= ((insn
>> 5) & 3) * 8;
3197 } else if (insn
& (1 << 5)) {
3199 offset
= (insn
& (1 << 6)) ? 16 : 0;
3204 if (insn
& ARM_CP_RW_BIT
) {
3206 tmp
= neon_load_reg(rn
, pass
);
3210 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3211 if (insn
& (1 << 23))
3217 if (insn
& (1 << 23)) {
3219 tcg_gen_shri_i32(tmp
, tmp
, 16);
3225 tcg_gen_sari_i32(tmp
, tmp
, 16);
3234 store_reg(s
, rd
, tmp
);
3237 tmp
= load_reg(s
, rd
);
3238 if (insn
& (1 << 23)) {
3241 gen_neon_dup_u8(tmp
, 0);
3242 } else if (size
== 1) {
3243 gen_neon_dup_low16(tmp
);
3245 for (n
= 0; n
<= pass
* 2; n
++) {
3246 tmp2
= tcg_temp_new_i32();
3247 tcg_gen_mov_i32(tmp2
, tmp
);
3248 neon_store_reg(rn
, n
, tmp2
);
3250 neon_store_reg(rn
, n
, tmp
);
3255 tmp2
= neon_load_reg(rn
, pass
);
3256 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3257 tcg_temp_free_i32(tmp2
);
3260 tmp2
= neon_load_reg(rn
, pass
);
3261 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3262 tcg_temp_free_i32(tmp2
);
3267 neon_store_reg(rn
, pass
, tmp
);
3271 if ((insn
& 0x6f) != 0x00)
3273 rn
= VFP_SREG_N(insn
);
3274 if (insn
& ARM_CP_RW_BIT
) {
3276 if (insn
& (1 << 21)) {
3277 /* system register */
3282 /* VFP2 allows access to FSID from userspace.
3283 VFP3 restricts all id registers to privileged
3286 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3289 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3294 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3296 case ARM_VFP_FPINST
:
3297 case ARM_VFP_FPINST2
:
3298 /* Not present in VFP3. */
3300 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3303 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3307 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3308 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3310 tmp
= tcg_temp_new_i32();
3311 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3315 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3322 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3325 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3331 gen_mov_F0_vreg(0, rn
);
3332 tmp
= gen_vfp_mrs();
3335 /* Set the 4 flag bits in the CPSR. */
3337 tcg_temp_free_i32(tmp
);
3339 store_reg(s
, rd
, tmp
);
3343 if (insn
& (1 << 21)) {
3345 /* system register */
3350 /* Writes are ignored. */
3353 tmp
= load_reg(s
, rd
);
3354 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3355 tcg_temp_free_i32(tmp
);
3361 /* TODO: VFP subarchitecture support.
3362 * For now, keep the EN bit only */
3363 tmp
= load_reg(s
, rd
);
3364 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3365 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3368 case ARM_VFP_FPINST
:
3369 case ARM_VFP_FPINST2
:
3373 tmp
= load_reg(s
, rd
);
3374 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3380 tmp
= load_reg(s
, rd
);
3382 gen_mov_vreg_F0(0, rn
);
3387 /* data processing */
3388 /* The opcode is in bits 23, 21, 20 and 6. */
3389 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3393 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3395 /* rn is register number */
3396 VFP_DREG_N(rn
, insn
);
3399 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3400 ((rn
& 0x1e) == 0x6))) {
3401 /* Integer or single/half precision destination. */
3402 rd
= VFP_SREG_D(insn
);
3404 VFP_DREG_D(rd
, insn
);
3407 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3408 ((rn
& 0x1e) == 0x4))) {
3409 /* VCVT from int or half precision is always from S reg
3410 * regardless of dp bit. VCVT with immediate frac_bits
3411 * has same format as SREG_M.
3413 rm
= VFP_SREG_M(insn
);
3415 VFP_DREG_M(rm
, insn
);
3418 rn
= VFP_SREG_N(insn
);
3419 if (op
== 15 && rn
== 15) {
3420 /* Double precision destination. */
3421 VFP_DREG_D(rd
, insn
);
3423 rd
= VFP_SREG_D(insn
);
3425 /* NB that we implicitly rely on the encoding for the frac_bits
3426 * in VCVT of fixed to float being the same as that of an SREG_M
3428 rm
= VFP_SREG_M(insn
);
3431 veclen
= s
->vec_len
;
3432 if (op
== 15 && rn
> 3)
3435 /* Shut up compiler warnings. */
3446 /* Figure out what type of vector operation this is. */
3447 if ((rd
& bank_mask
) == 0) {
3452 delta_d
= (s
->vec_stride
>> 1) + 1;
3454 delta_d
= s
->vec_stride
+ 1;
3456 if ((rm
& bank_mask
) == 0) {
3457 /* mixed scalar/vector */
3466 /* Load the initial operands. */
3471 /* Integer source */
3472 gen_mov_F0_vreg(0, rm
);
3477 gen_mov_F0_vreg(dp
, rd
);
3478 gen_mov_F1_vreg(dp
, rm
);
3482 /* Compare with zero */
3483 gen_mov_F0_vreg(dp
, rd
);
3494 /* Source and destination the same. */
3495 gen_mov_F0_vreg(dp
, rd
);
3501 /* VCVTB, VCVTT: only present with the halfprec extension
3502 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3503 * (we choose to UNDEF)
3505 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3506 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3509 if (!extract32(rn
, 1, 1)) {
3510 /* Half precision source. */
3511 gen_mov_F0_vreg(0, rm
);
3514 /* Otherwise fall through */
3516 /* One source operand. */
3517 gen_mov_F0_vreg(dp
, rm
);
3521 /* Two source operands. */
3522 gen_mov_F0_vreg(dp
, rn
);
3523 gen_mov_F1_vreg(dp
, rm
);
3527 /* Perform the calculation. */
3529 case 0: /* VMLA: fd + (fn * fm) */
3530 /* Note that order of inputs to the add matters for NaNs */
3532 gen_mov_F0_vreg(dp
, rd
);
3535 case 1: /* VMLS: fd + -(fn * fm) */
3538 gen_mov_F0_vreg(dp
, rd
);
3541 case 2: /* VNMLS: -fd + (fn * fm) */
3542 /* Note that it isn't valid to replace (-A + B) with (B - A)
3543 * or similar plausible looking simplifications
3544 * because this will give wrong results for NaNs.
3547 gen_mov_F0_vreg(dp
, rd
);
3551 case 3: /* VNMLA: -fd + -(fn * fm) */
3554 gen_mov_F0_vreg(dp
, rd
);
3558 case 4: /* mul: fn * fm */
3561 case 5: /* nmul: -(fn * fm) */
3565 case 6: /* add: fn + fm */
3568 case 7: /* sub: fn - fm */
3571 case 8: /* div: fn / fm */
3574 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3575 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3576 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3577 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3578 /* These are fused multiply-add, and must be done as one
3579 * floating point operation with no rounding between the
3580 * multiplication and addition steps.
3581 * NB that doing the negations here as separate steps is
3582 * correct : an input NaN should come out with its sign bit
3583 * flipped if it is a negated-input.
3585 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3593 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3595 frd
= tcg_temp_new_i64();
3596 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3599 gen_helper_vfp_negd(frd
, frd
);
3601 fpst
= get_fpstatus_ptr(0);
3602 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3603 cpu_F1d
, frd
, fpst
);
3604 tcg_temp_free_ptr(fpst
);
3605 tcg_temp_free_i64(frd
);
3611 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3613 frd
= tcg_temp_new_i32();
3614 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3616 gen_helper_vfp_negs(frd
, frd
);
3618 fpst
= get_fpstatus_ptr(0);
3619 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3620 cpu_F1s
, frd
, fpst
);
3621 tcg_temp_free_ptr(fpst
);
3622 tcg_temp_free_i32(frd
);
3625 case 14: /* fconst */
3626 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3630 n
= (insn
<< 12) & 0x80000000;
3631 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3638 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3645 tcg_gen_movi_i32(cpu_F0s
, n
);
3648 case 15: /* extension space */
3662 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3663 tmp
= gen_vfp_mrs();
3664 tcg_gen_ext16u_i32(tmp
, tmp
);
3666 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3669 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3672 tcg_temp_free_i32(tmp
);
3674 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3675 tmp
= gen_vfp_mrs();
3676 tcg_gen_shri_i32(tmp
, tmp
, 16);
3678 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3681 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3684 tcg_temp_free_i32(tmp
);
3686 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3687 tmp
= tcg_temp_new_i32();
3689 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3692 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3695 gen_mov_F0_vreg(0, rd
);
3696 tmp2
= gen_vfp_mrs();
3697 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3698 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3699 tcg_temp_free_i32(tmp2
);
3702 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3703 tmp
= tcg_temp_new_i32();
3705 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3708 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3711 tcg_gen_shli_i32(tmp
, tmp
, 16);
3712 gen_mov_F0_vreg(0, rd
);
3713 tmp2
= gen_vfp_mrs();
3714 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3715 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3716 tcg_temp_free_i32(tmp2
);
3728 case 11: /* cmpez */
3732 case 12: /* vrintr */
3734 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3736 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3738 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3740 tcg_temp_free_ptr(fpst
);
3743 case 13: /* vrintz */
3745 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3747 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3748 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3750 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3752 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3754 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3755 tcg_temp_free_i32(tcg_rmode
);
3756 tcg_temp_free_ptr(fpst
);
3759 case 14: /* vrintx */
3761 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3763 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3765 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3767 tcg_temp_free_ptr(fpst
);
3770 case 15: /* single<->double conversion */
3772 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3774 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3776 case 16: /* fuito */
3777 gen_vfp_uito(dp
, 0);
3779 case 17: /* fsito */
3780 gen_vfp_sito(dp
, 0);
3782 case 20: /* fshto */
3783 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3786 gen_vfp_shto(dp
, 16 - rm
, 0);
3788 case 21: /* fslto */
3789 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3792 gen_vfp_slto(dp
, 32 - rm
, 0);
3794 case 22: /* fuhto */
3795 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3798 gen_vfp_uhto(dp
, 16 - rm
, 0);
3800 case 23: /* fulto */
3801 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3804 gen_vfp_ulto(dp
, 32 - rm
, 0);
3806 case 24: /* ftoui */
3807 gen_vfp_toui(dp
, 0);
3809 case 25: /* ftouiz */
3810 gen_vfp_touiz(dp
, 0);
3812 case 26: /* ftosi */
3813 gen_vfp_tosi(dp
, 0);
3815 case 27: /* ftosiz */
3816 gen_vfp_tosiz(dp
, 0);
3818 case 28: /* ftosh */
3819 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3822 gen_vfp_tosh(dp
, 16 - rm
, 0);
3824 case 29: /* ftosl */
3825 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3828 gen_vfp_tosl(dp
, 32 - rm
, 0);
3830 case 30: /* ftouh */
3831 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3834 gen_vfp_touh(dp
, 16 - rm
, 0);
3836 case 31: /* ftoul */
3837 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3840 gen_vfp_toul(dp
, 32 - rm
, 0);
3842 default: /* undefined */
3846 default: /* undefined */
3850 /* Write back the result. */
3851 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3852 /* Comparison, do nothing. */
3853 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3854 (rn
& 0x1e) == 0x6)) {
3855 /* VCVT double to int: always integer result.
3856 * VCVT double to half precision is always a single
3859 gen_mov_vreg_F0(0, rd
);
3860 } else if (op
== 15 && rn
== 15) {
3862 gen_mov_vreg_F0(!dp
, rd
);
3864 gen_mov_vreg_F0(dp
, rd
);
3867 /* break out of the loop if we have finished */
3871 if (op
== 15 && delta_m
== 0) {
3872 /* single source one-many */
3874 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3876 gen_mov_vreg_F0(dp
, rd
);
3880 /* Setup the next operands. */
3882 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3886 /* One source operand. */
3887 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3889 gen_mov_F0_vreg(dp
, rm
);
3891 /* Two source operands. */
3892 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3894 gen_mov_F0_vreg(dp
, rn
);
3896 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3898 gen_mov_F1_vreg(dp
, rm
);
3906 if ((insn
& 0x03e00000) == 0x00400000) {
3907 /* two-register transfer */
3908 rn
= (insn
>> 16) & 0xf;
3909 rd
= (insn
>> 12) & 0xf;
3911 VFP_DREG_M(rm
, insn
);
3913 rm
= VFP_SREG_M(insn
);
3916 if (insn
& ARM_CP_RW_BIT
) {
3919 gen_mov_F0_vreg(0, rm
* 2);
3920 tmp
= gen_vfp_mrs();
3921 store_reg(s
, rd
, tmp
);
3922 gen_mov_F0_vreg(0, rm
* 2 + 1);
3923 tmp
= gen_vfp_mrs();
3924 store_reg(s
, rn
, tmp
);
3926 gen_mov_F0_vreg(0, rm
);
3927 tmp
= gen_vfp_mrs();
3928 store_reg(s
, rd
, tmp
);
3929 gen_mov_F0_vreg(0, rm
+ 1);
3930 tmp
= gen_vfp_mrs();
3931 store_reg(s
, rn
, tmp
);
3936 tmp
= load_reg(s
, rd
);
3938 gen_mov_vreg_F0(0, rm
* 2);
3939 tmp
= load_reg(s
, rn
);
3941 gen_mov_vreg_F0(0, rm
* 2 + 1);
3943 tmp
= load_reg(s
, rd
);
3945 gen_mov_vreg_F0(0, rm
);
3946 tmp
= load_reg(s
, rn
);
3948 gen_mov_vreg_F0(0, rm
+ 1);
3953 rn
= (insn
>> 16) & 0xf;
3955 VFP_DREG_D(rd
, insn
);
3957 rd
= VFP_SREG_D(insn
);
3958 if ((insn
& 0x01200000) == 0x01000000) {
3959 /* Single load/store */
3960 offset
= (insn
& 0xff) << 2;
3961 if ((insn
& (1 << 23)) == 0)
3963 if (s
->thumb
&& rn
== 15) {
3964 /* This is actually UNPREDICTABLE */
3965 addr
= tcg_temp_new_i32();
3966 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3968 addr
= load_reg(s
, rn
);
3970 tcg_gen_addi_i32(addr
, addr
, offset
);
3971 if (insn
& (1 << 20)) {
3972 gen_vfp_ld(s
, dp
, addr
);
3973 gen_mov_vreg_F0(dp
, rd
);
3975 gen_mov_F0_vreg(dp
, rd
);
3976 gen_vfp_st(s
, dp
, addr
);
3978 tcg_temp_free_i32(addr
);
3980 /* load/store multiple */
3981 int w
= insn
& (1 << 21);
3983 n
= (insn
>> 1) & 0x7f;
3987 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3988 /* P == U , W == 1 => UNDEF */
3991 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3992 /* UNPREDICTABLE cases for bad immediates: we choose to
3993 * UNDEF to avoid generating huge numbers of TCG ops
3997 if (rn
== 15 && w
) {
3998 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4002 if (s
->thumb
&& rn
== 15) {
4003 /* This is actually UNPREDICTABLE */
4004 addr
= tcg_temp_new_i32();
4005 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
4007 addr
= load_reg(s
, rn
);
4009 if (insn
& (1 << 24)) /* pre-decrement */
4010 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
4016 for (i
= 0; i
< n
; i
++) {
4017 if (insn
& ARM_CP_RW_BIT
) {
4019 gen_vfp_ld(s
, dp
, addr
);
4020 gen_mov_vreg_F0(dp
, rd
+ i
);
4023 gen_mov_F0_vreg(dp
, rd
+ i
);
4024 gen_vfp_st(s
, dp
, addr
);
4026 tcg_gen_addi_i32(addr
, addr
, offset
);
4030 if (insn
& (1 << 24))
4031 offset
= -offset
* n
;
4032 else if (dp
&& (insn
& 1))
4038 tcg_gen_addi_i32(addr
, addr
, offset
);
4039 store_reg(s
, rn
, addr
);
4041 tcg_temp_free_i32(addr
);
4047 /* Should never happen. */
4053 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
4055 #ifndef CONFIG_USER_ONLY
4056 return (s
->tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
4057 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4063 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
4065 if (use_goto_tb(s
, dest
)) {
4067 gen_set_pc_im(s
, dest
);
4068 tcg_gen_exit_tb((uintptr_t)s
->tb
+ n
);
4070 gen_set_pc_im(s
, dest
);
4075 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
4077 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
4078 /* An indirect jump so that we still trigger the debug exception. */
4083 gen_goto_tb(s
, 0, dest
);
4084 s
->is_jmp
= DISAS_TB_JUMP
;
4088 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4091 tcg_gen_sari_i32(t0
, t0
, 16);
4095 tcg_gen_sari_i32(t1
, t1
, 16);
4098 tcg_gen_mul_i32(t0
, t0
, t1
);
4101 /* Return the mask of PSR bits set by a MSR instruction. */
4102 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4107 if (flags
& (1 << 0))
4109 if (flags
& (1 << 1))
4111 if (flags
& (1 << 2))
4113 if (flags
& (1 << 3))
4116 /* Mask out undefined bits. */
4117 mask
&= ~CPSR_RESERVED
;
4118 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4121 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4122 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4124 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4125 mask
&= ~(CPSR_E
| CPSR_GE
);
4127 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4130 /* Mask out execution state and reserved bits. */
4132 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4134 /* Mask out privileged bits. */
4140 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4141 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4145 /* ??? This is also undefined in system mode. */
4149 tmp
= load_cpu_field(spsr
);
4150 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4151 tcg_gen_andi_i32(t0
, t0
, mask
);
4152 tcg_gen_or_i32(tmp
, tmp
, t0
);
4153 store_cpu_field(tmp
, spsr
);
4155 gen_set_cpsr(t0
, mask
);
4157 tcg_temp_free_i32(t0
);
4162 /* Returns nonzero if access to the PSR is not permitted. */
4163 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4166 tmp
= tcg_temp_new_i32();
4167 tcg_gen_movi_i32(tmp
, val
);
4168 return gen_set_psr(s
, mask
, spsr
, tmp
);
4171 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
4172 int *tgtmode
, int *regno
)
4174 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4175 * the target mode and register number, and identify the various
4176 * unpredictable cases.
4177 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4178 * + executed in user mode
4179 * + using R15 as the src/dest register
4180 * + accessing an unimplemented register
4181 * + accessing a register that's inaccessible at current PL/security state*
4182 * + accessing a register that you could access with a different insn
4183 * We choose to UNDEF in all these cases.
4184 * Since we don't know which of the various AArch32 modes we are in
4185 * we have to defer some checks to runtime.
4186 * Accesses to Monitor mode registers from Secure EL1 (which implies
4187 * that EL3 is AArch64) must trap to EL3.
4189 * If the access checks fail this function will emit code to take
4190 * an exception and return false. Otherwise it will return true,
4191 * and set *tgtmode and *regno appropriately.
4193 int exc_target
= default_exception_el(s
);
4195 /* These instructions are present only in ARMv8, or in ARMv7 with the
4196 * Virtualization Extensions.
4198 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
4199 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
4203 if (IS_USER(s
) || rn
== 15) {
4207 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4208 * of registers into (r, sysm).
4211 /* SPSRs for other modes */
4213 case 0xe: /* SPSR_fiq */
4214 *tgtmode
= ARM_CPU_MODE_FIQ
;
4216 case 0x10: /* SPSR_irq */
4217 *tgtmode
= ARM_CPU_MODE_IRQ
;
4219 case 0x12: /* SPSR_svc */
4220 *tgtmode
= ARM_CPU_MODE_SVC
;
4222 case 0x14: /* SPSR_abt */
4223 *tgtmode
= ARM_CPU_MODE_ABT
;
4225 case 0x16: /* SPSR_und */
4226 *tgtmode
= ARM_CPU_MODE_UND
;
4228 case 0x1c: /* SPSR_mon */
4229 *tgtmode
= ARM_CPU_MODE_MON
;
4231 case 0x1e: /* SPSR_hyp */
4232 *tgtmode
= ARM_CPU_MODE_HYP
;
4234 default: /* unallocated */
4237 /* We arbitrarily assign SPSR a register number of 16. */
4240 /* general purpose registers for other modes */
4242 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4243 *tgtmode
= ARM_CPU_MODE_USR
;
4246 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4247 *tgtmode
= ARM_CPU_MODE_FIQ
;
4250 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4251 *tgtmode
= ARM_CPU_MODE_IRQ
;
4252 *regno
= sysm
& 1 ? 13 : 14;
4254 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4255 *tgtmode
= ARM_CPU_MODE_SVC
;
4256 *regno
= sysm
& 1 ? 13 : 14;
4258 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4259 *tgtmode
= ARM_CPU_MODE_ABT
;
4260 *regno
= sysm
& 1 ? 13 : 14;
4262 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4263 *tgtmode
= ARM_CPU_MODE_UND
;
4264 *regno
= sysm
& 1 ? 13 : 14;
4266 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4267 *tgtmode
= ARM_CPU_MODE_MON
;
4268 *regno
= sysm
& 1 ? 13 : 14;
4270 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4271 *tgtmode
= ARM_CPU_MODE_HYP
;
4272 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4273 *regno
= sysm
& 1 ? 13 : 17;
4275 default: /* unallocated */
4280 /* Catch the 'accessing inaccessible register' cases we can detect
4281 * at translate time.
4284 case ARM_CPU_MODE_MON
:
4285 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
4288 if (s
->current_el
== 1) {
4289 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4290 * then accesses to Mon registers trap to EL3
4296 case ARM_CPU_MODE_HYP
:
4297 /* Note that we can forbid accesses from EL2 here because they
4298 * must be from Hyp mode itself
4300 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 3) {
4311 /* If we get here then some access check did not pass */
4312 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
4316 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4318 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4319 int tgtmode
= 0, regno
= 0;
4321 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4325 /* Sync state because msr_banked() can raise exceptions */
4326 gen_set_condexec(s
);
4327 gen_set_pc_im(s
, s
->pc
- 4);
4328 tcg_reg
= load_reg(s
, rn
);
4329 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4330 tcg_regno
= tcg_const_i32(regno
);
4331 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
4332 tcg_temp_free_i32(tcg_tgtmode
);
4333 tcg_temp_free_i32(tcg_regno
);
4334 tcg_temp_free_i32(tcg_reg
);
4335 s
->is_jmp
= DISAS_UPDATE
;
4338 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
4340 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
4341 int tgtmode
= 0, regno
= 0;
4343 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
4347 /* Sync state because mrs_banked() can raise exceptions */
4348 gen_set_condexec(s
);
4349 gen_set_pc_im(s
, s
->pc
- 4);
4350 tcg_reg
= tcg_temp_new_i32();
4351 tcg_tgtmode
= tcg_const_i32(tgtmode
);
4352 tcg_regno
= tcg_const_i32(regno
);
4353 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
4354 tcg_temp_free_i32(tcg_tgtmode
);
4355 tcg_temp_free_i32(tcg_regno
);
4356 store_reg(s
, rn
, tcg_reg
);
4357 s
->is_jmp
= DISAS_UPDATE
;
4360 /* Generate an old-style exception return. Marks pc as dead. */
4361 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4364 store_reg(s
, 15, pc
);
4365 tmp
= load_cpu_field(spsr
);
4366 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
4367 tcg_temp_free_i32(tmp
);
4368 s
->is_jmp
= DISAS_JUMP
;
4371 /* Generate a v6 exception return. Marks both values as dead. */
4372 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4374 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
4375 tcg_temp_free_i32(cpsr
);
4376 store_reg(s
, 15, pc
);
4377 s
->is_jmp
= DISAS_JUMP
;
4380 static void gen_nop_hint(DisasContext
*s
, int val
)
4384 gen_set_pc_im(s
, s
->pc
);
4385 s
->is_jmp
= DISAS_YIELD
;
4388 gen_set_pc_im(s
, s
->pc
);
4389 s
->is_jmp
= DISAS_WFI
;
4392 gen_set_pc_im(s
, s
->pc
);
4393 s
->is_jmp
= DISAS_WFE
;
4397 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4403 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4405 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4408 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4409 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4410 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4415 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4418 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4419 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4420 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4425 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4426 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4427 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4428 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4429 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4431 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4432 switch ((size << 1) | u) { \
4434 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4437 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4440 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4443 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4446 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4449 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4451 default: return 1; \
4454 #define GEN_NEON_INTEGER_OP(name) do { \
4455 switch ((size << 1) | u) { \
4457 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4460 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4463 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4466 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4469 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4472 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4474 default: return 1; \
4477 static TCGv_i32
neon_load_scratch(int scratch
)
4479 TCGv_i32 tmp
= tcg_temp_new_i32();
4480 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4484 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4486 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4487 tcg_temp_free_i32(var
);
4490 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4494 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4496 gen_neon_dup_high16(tmp
);
4498 gen_neon_dup_low16(tmp
);
4501 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4506 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4509 if (!q
&& size
== 2) {
4512 tmp
= tcg_const_i32(rd
);
4513 tmp2
= tcg_const_i32(rm
);
4517 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4520 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4523 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4531 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4534 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4540 tcg_temp_free_i32(tmp
);
4541 tcg_temp_free_i32(tmp2
);
4545 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4548 if (!q
&& size
== 2) {
4551 tmp
= tcg_const_i32(rd
);
4552 tmp2
= tcg_const_i32(rm
);
4556 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4559 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4562 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4570 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4573 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4579 tcg_temp_free_i32(tmp
);
4580 tcg_temp_free_i32(tmp2
);
4584 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4588 rd
= tcg_temp_new_i32();
4589 tmp
= tcg_temp_new_i32();
4591 tcg_gen_shli_i32(rd
, t0
, 8);
4592 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4593 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4594 tcg_gen_or_i32(rd
, rd
, tmp
);
4596 tcg_gen_shri_i32(t1
, t1
, 8);
4597 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4598 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4599 tcg_gen_or_i32(t1
, t1
, tmp
);
4600 tcg_gen_mov_i32(t0
, rd
);
4602 tcg_temp_free_i32(tmp
);
4603 tcg_temp_free_i32(rd
);
4606 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4610 rd
= tcg_temp_new_i32();
4611 tmp
= tcg_temp_new_i32();
4613 tcg_gen_shli_i32(rd
, t0
, 16);
4614 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4615 tcg_gen_or_i32(rd
, rd
, tmp
);
4616 tcg_gen_shri_i32(t1
, t1
, 16);
4617 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4618 tcg_gen_or_i32(t1
, t1
, tmp
);
4619 tcg_gen_mov_i32(t0
, rd
);
4621 tcg_temp_free_i32(tmp
);
4622 tcg_temp_free_i32(rd
);
4630 } neon_ls_element_type
[11] = {
4644 /* Translate a NEON load/store element instruction. Return nonzero if the
4645 instruction is invalid. */
4646 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4665 /* FIXME: this access check should not take precedence over UNDEF
4666 * for invalid encodings; we will generate incorrect syndrome information
4667 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4669 if (s
->fp_excp_el
) {
4670 gen_exception_insn(s
, 4, EXCP_UDEF
,
4671 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4675 if (!s
->vfp_enabled
)
4677 VFP_DREG_D(rd
, insn
);
4678 rn
= (insn
>> 16) & 0xf;
4680 load
= (insn
& (1 << 21)) != 0;
4681 if ((insn
& (1 << 23)) == 0) {
4682 /* Load store all elements. */
4683 op
= (insn
>> 8) & 0xf;
4684 size
= (insn
>> 6) & 3;
4687 /* Catch UNDEF cases for bad values of align field */
4690 if (((insn
>> 5) & 1) == 1) {
4695 if (((insn
>> 4) & 3) == 3) {
4702 nregs
= neon_ls_element_type
[op
].nregs
;
4703 interleave
= neon_ls_element_type
[op
].interleave
;
4704 spacing
= neon_ls_element_type
[op
].spacing
;
4705 if (size
== 3 && (interleave
| spacing
) != 1)
4707 addr
= tcg_temp_new_i32();
4708 load_reg_var(s
, addr
, rn
);
4709 stride
= (1 << size
) * interleave
;
4710 for (reg
= 0; reg
< nregs
; reg
++) {
4711 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4712 load_reg_var(s
, addr
, rn
);
4713 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4714 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4715 load_reg_var(s
, addr
, rn
);
4716 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4719 tmp64
= tcg_temp_new_i64();
4721 gen_aa32_ld64(s
, tmp64
, addr
, get_mem_index(s
));
4722 neon_store_reg64(tmp64
, rd
);
4724 neon_load_reg64(tmp64
, rd
);
4725 gen_aa32_st64(s
, tmp64
, addr
, get_mem_index(s
));
4727 tcg_temp_free_i64(tmp64
);
4728 tcg_gen_addi_i32(addr
, addr
, stride
);
4730 for (pass
= 0; pass
< 2; pass
++) {
4733 tmp
= tcg_temp_new_i32();
4734 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4735 neon_store_reg(rd
, pass
, tmp
);
4737 tmp
= neon_load_reg(rd
, pass
);
4738 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4739 tcg_temp_free_i32(tmp
);
4741 tcg_gen_addi_i32(addr
, addr
, stride
);
4742 } else if (size
== 1) {
4744 tmp
= tcg_temp_new_i32();
4745 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4746 tcg_gen_addi_i32(addr
, addr
, stride
);
4747 tmp2
= tcg_temp_new_i32();
4748 gen_aa32_ld16u(s
, tmp2
, addr
, get_mem_index(s
));
4749 tcg_gen_addi_i32(addr
, addr
, stride
);
4750 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4751 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4752 tcg_temp_free_i32(tmp2
);
4753 neon_store_reg(rd
, pass
, tmp
);
4755 tmp
= neon_load_reg(rd
, pass
);
4756 tmp2
= tcg_temp_new_i32();
4757 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4758 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4759 tcg_temp_free_i32(tmp
);
4760 tcg_gen_addi_i32(addr
, addr
, stride
);
4761 gen_aa32_st16(s
, tmp2
, addr
, get_mem_index(s
));
4762 tcg_temp_free_i32(tmp2
);
4763 tcg_gen_addi_i32(addr
, addr
, stride
);
4765 } else /* size == 0 */ {
4767 TCGV_UNUSED_I32(tmp2
);
4768 for (n
= 0; n
< 4; n
++) {
4769 tmp
= tcg_temp_new_i32();
4770 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4771 tcg_gen_addi_i32(addr
, addr
, stride
);
4775 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4776 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4777 tcg_temp_free_i32(tmp
);
4780 neon_store_reg(rd
, pass
, tmp2
);
4782 tmp2
= neon_load_reg(rd
, pass
);
4783 for (n
= 0; n
< 4; n
++) {
4784 tmp
= tcg_temp_new_i32();
4786 tcg_gen_mov_i32(tmp
, tmp2
);
4788 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4790 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4791 tcg_temp_free_i32(tmp
);
4792 tcg_gen_addi_i32(addr
, addr
, stride
);
4794 tcg_temp_free_i32(tmp2
);
4801 tcg_temp_free_i32(addr
);
4804 size
= (insn
>> 10) & 3;
4806 /* Load single element to all lanes. */
4807 int a
= (insn
>> 4) & 1;
4811 size
= (insn
>> 6) & 3;
4812 nregs
= ((insn
>> 8) & 3) + 1;
4815 if (nregs
!= 4 || a
== 0) {
4818 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4821 if (nregs
== 1 && a
== 1 && size
== 0) {
4824 if (nregs
== 3 && a
== 1) {
4827 addr
= tcg_temp_new_i32();
4828 load_reg_var(s
, addr
, rn
);
4830 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4831 tmp
= gen_load_and_replicate(s
, addr
, size
);
4832 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4833 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4834 if (insn
& (1 << 5)) {
4835 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4836 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4838 tcg_temp_free_i32(tmp
);
4840 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4841 stride
= (insn
& (1 << 5)) ? 2 : 1;
4842 for (reg
= 0; reg
< nregs
; reg
++) {
4843 tmp
= gen_load_and_replicate(s
, addr
, size
);
4844 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4845 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4846 tcg_temp_free_i32(tmp
);
4847 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4851 tcg_temp_free_i32(addr
);
4852 stride
= (1 << size
) * nregs
;
4854 /* Single element. */
4855 int idx
= (insn
>> 4) & 0xf;
4856 pass
= (insn
>> 7) & 1;
4859 shift
= ((insn
>> 5) & 3) * 8;
4863 shift
= ((insn
>> 6) & 1) * 16;
4864 stride
= (insn
& (1 << 5)) ? 2 : 1;
4868 stride
= (insn
& (1 << 6)) ? 2 : 1;
4873 nregs
= ((insn
>> 8) & 3) + 1;
4874 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4877 if (((idx
& (1 << size
)) != 0) ||
4878 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4883 if ((idx
& 1) != 0) {
4888 if (size
== 2 && (idx
& 2) != 0) {
4893 if ((size
== 2) && ((idx
& 3) == 3)) {
4900 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4901 /* Attempts to write off the end of the register file
4902 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4903 * the neon_load_reg() would write off the end of the array.
4907 addr
= tcg_temp_new_i32();
4908 load_reg_var(s
, addr
, rn
);
4909 for (reg
= 0; reg
< nregs
; reg
++) {
4911 tmp
= tcg_temp_new_i32();
4914 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
4917 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
4920 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
4922 default: /* Avoid compiler warnings. */
4926 tmp2
= neon_load_reg(rd
, pass
);
4927 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4928 shift
, size
? 16 : 8);
4929 tcg_temp_free_i32(tmp2
);
4931 neon_store_reg(rd
, pass
, tmp
);
4932 } else { /* Store */
4933 tmp
= neon_load_reg(rd
, pass
);
4935 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4938 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
4941 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
4944 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
4947 tcg_temp_free_i32(tmp
);
4950 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4952 tcg_temp_free_i32(addr
);
4953 stride
= nregs
* (1 << size
);
4959 base
= load_reg(s
, rn
);
4961 tcg_gen_addi_i32(base
, base
, stride
);
4964 index
= load_reg(s
, rm
);
4965 tcg_gen_add_i32(base
, base
, index
);
4966 tcg_temp_free_i32(index
);
4968 store_reg(s
, rn
, base
);
4973 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4974 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4976 tcg_gen_and_i32(t
, t
, c
);
4977 tcg_gen_andc_i32(f
, f
, c
);
4978 tcg_gen_or_i32(dest
, t
, f
);
4981 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4984 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4985 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4986 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4991 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4994 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4995 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4996 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
5001 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5004 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
5005 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
5006 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
5011 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
5014 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
5015 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
5016 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
5021 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
5027 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
5028 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
5033 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
5034 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
5041 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
5042 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
5047 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
5048 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
5055 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
5059 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
5060 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
5061 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
5066 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
5067 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
5068 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
5072 tcg_temp_free_i32(src
);
5075 static inline void gen_neon_addl(int size
)
5078 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
5079 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
5080 case 2: tcg_gen_add_i64(CPU_V001
); break;
5085 static inline void gen_neon_subl(int size
)
5088 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
5089 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
5090 case 2: tcg_gen_sub_i64(CPU_V001
); break;
5095 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
5098 case 0: gen_helper_neon_negl_u16(var
, var
); break;
5099 case 1: gen_helper_neon_negl_u32(var
, var
); break;
5101 tcg_gen_neg_i64(var
, var
);
5107 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
5110 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
5111 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
5116 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
5121 switch ((size
<< 1) | u
) {
5122 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
5123 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
5124 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
5125 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
5127 tmp
= gen_muls_i64_i32(a
, b
);
5128 tcg_gen_mov_i64(dest
, tmp
);
5129 tcg_temp_free_i64(tmp
);
5132 tmp
= gen_mulu_i64_i32(a
, b
);
5133 tcg_gen_mov_i64(dest
, tmp
);
5134 tcg_temp_free_i64(tmp
);
5139 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5140 Don't forget to clean them now. */
5142 tcg_temp_free_i32(a
);
5143 tcg_temp_free_i32(b
);
5147 static void gen_neon_narrow_op(int op
, int u
, int size
,
5148 TCGv_i32 dest
, TCGv_i64 src
)
5152 gen_neon_unarrow_sats(size
, dest
, src
);
5154 gen_neon_narrow(size
, dest
, src
);
5158 gen_neon_narrow_satu(size
, dest
, src
);
5160 gen_neon_narrow_sats(size
, dest
, src
);
5165 /* Symbolic constants for op fields for Neon 3-register same-length.
5166 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5169 #define NEON_3R_VHADD 0
5170 #define NEON_3R_VQADD 1
5171 #define NEON_3R_VRHADD 2
5172 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5173 #define NEON_3R_VHSUB 4
5174 #define NEON_3R_VQSUB 5
5175 #define NEON_3R_VCGT 6
5176 #define NEON_3R_VCGE 7
5177 #define NEON_3R_VSHL 8
5178 #define NEON_3R_VQSHL 9
5179 #define NEON_3R_VRSHL 10
5180 #define NEON_3R_VQRSHL 11
5181 #define NEON_3R_VMAX 12
5182 #define NEON_3R_VMIN 13
5183 #define NEON_3R_VABD 14
5184 #define NEON_3R_VABA 15
5185 #define NEON_3R_VADD_VSUB 16
5186 #define NEON_3R_VTST_VCEQ 17
5187 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5188 #define NEON_3R_VMUL 19
5189 #define NEON_3R_VPMAX 20
5190 #define NEON_3R_VPMIN 21
5191 #define NEON_3R_VQDMULH_VQRDMULH 22
5192 #define NEON_3R_VPADD 23
5193 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5194 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5195 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5196 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5197 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5198 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5199 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5200 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5202 static const uint8_t neon_3r_sizes
[] = {
5203 [NEON_3R_VHADD
] = 0x7,
5204 [NEON_3R_VQADD
] = 0xf,
5205 [NEON_3R_VRHADD
] = 0x7,
5206 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
5207 [NEON_3R_VHSUB
] = 0x7,
5208 [NEON_3R_VQSUB
] = 0xf,
5209 [NEON_3R_VCGT
] = 0x7,
5210 [NEON_3R_VCGE
] = 0x7,
5211 [NEON_3R_VSHL
] = 0xf,
5212 [NEON_3R_VQSHL
] = 0xf,
5213 [NEON_3R_VRSHL
] = 0xf,
5214 [NEON_3R_VQRSHL
] = 0xf,
5215 [NEON_3R_VMAX
] = 0x7,
5216 [NEON_3R_VMIN
] = 0x7,
5217 [NEON_3R_VABD
] = 0x7,
5218 [NEON_3R_VABA
] = 0x7,
5219 [NEON_3R_VADD_VSUB
] = 0xf,
5220 [NEON_3R_VTST_VCEQ
] = 0x7,
5221 [NEON_3R_VML
] = 0x7,
5222 [NEON_3R_VMUL
] = 0x7,
5223 [NEON_3R_VPMAX
] = 0x7,
5224 [NEON_3R_VPMIN
] = 0x7,
5225 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
5226 [NEON_3R_VPADD
] = 0x7,
5227 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
5228 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
5229 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
5230 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
5231 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
5232 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
5233 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
5234 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
5237 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5238 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5241 #define NEON_2RM_VREV64 0
5242 #define NEON_2RM_VREV32 1
5243 #define NEON_2RM_VREV16 2
5244 #define NEON_2RM_VPADDL 4
5245 #define NEON_2RM_VPADDL_U 5
5246 #define NEON_2RM_AESE 6 /* Includes AESD */
5247 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5248 #define NEON_2RM_VCLS 8
5249 #define NEON_2RM_VCLZ 9
5250 #define NEON_2RM_VCNT 10
5251 #define NEON_2RM_VMVN 11
5252 #define NEON_2RM_VPADAL 12
5253 #define NEON_2RM_VPADAL_U 13
5254 #define NEON_2RM_VQABS 14
5255 #define NEON_2RM_VQNEG 15
5256 #define NEON_2RM_VCGT0 16
5257 #define NEON_2RM_VCGE0 17
5258 #define NEON_2RM_VCEQ0 18
5259 #define NEON_2RM_VCLE0 19
5260 #define NEON_2RM_VCLT0 20
5261 #define NEON_2RM_SHA1H 21
5262 #define NEON_2RM_VABS 22
5263 #define NEON_2RM_VNEG 23
5264 #define NEON_2RM_VCGT0_F 24
5265 #define NEON_2RM_VCGE0_F 25
5266 #define NEON_2RM_VCEQ0_F 26
5267 #define NEON_2RM_VCLE0_F 27
5268 #define NEON_2RM_VCLT0_F 28
5269 #define NEON_2RM_VABS_F 30
5270 #define NEON_2RM_VNEG_F 31
5271 #define NEON_2RM_VSWP 32
5272 #define NEON_2RM_VTRN 33
5273 #define NEON_2RM_VUZP 34
5274 #define NEON_2RM_VZIP 35
5275 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5276 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5277 #define NEON_2RM_VSHLL 38
5278 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5279 #define NEON_2RM_VRINTN 40
5280 #define NEON_2RM_VRINTX 41
5281 #define NEON_2RM_VRINTA 42
5282 #define NEON_2RM_VRINTZ 43
5283 #define NEON_2RM_VCVT_F16_F32 44
5284 #define NEON_2RM_VRINTM 45
5285 #define NEON_2RM_VCVT_F32_F16 46
5286 #define NEON_2RM_VRINTP 47
5287 #define NEON_2RM_VCVTAU 48
5288 #define NEON_2RM_VCVTAS 49
5289 #define NEON_2RM_VCVTNU 50
5290 #define NEON_2RM_VCVTNS 51
5291 #define NEON_2RM_VCVTPU 52
5292 #define NEON_2RM_VCVTPS 53
5293 #define NEON_2RM_VCVTMU 54
5294 #define NEON_2RM_VCVTMS 55
5295 #define NEON_2RM_VRECPE 56
5296 #define NEON_2RM_VRSQRTE 57
5297 #define NEON_2RM_VRECPE_F 58
5298 #define NEON_2RM_VRSQRTE_F 59
5299 #define NEON_2RM_VCVT_FS 60
5300 #define NEON_2RM_VCVT_FU 61
5301 #define NEON_2RM_VCVT_SF 62
5302 #define NEON_2RM_VCVT_UF 63
5304 static int neon_2rm_is_float_op(int op
)
5306 /* Return true if this neon 2reg-misc op is float-to-float */
5307 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5308 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5309 op
== NEON_2RM_VRINTM
||
5310 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5311 op
>= NEON_2RM_VRECPE_F
);
5314 /* Each entry in this array has bit n set if the insn allows
5315 * size value n (otherwise it will UNDEF). Since unallocated
5316 * op values will have no bits set they always UNDEF.
5318 static const uint8_t neon_2rm_sizes
[] = {
5319 [NEON_2RM_VREV64
] = 0x7,
5320 [NEON_2RM_VREV32
] = 0x3,
5321 [NEON_2RM_VREV16
] = 0x1,
5322 [NEON_2RM_VPADDL
] = 0x7,
5323 [NEON_2RM_VPADDL_U
] = 0x7,
5324 [NEON_2RM_AESE
] = 0x1,
5325 [NEON_2RM_AESMC
] = 0x1,
5326 [NEON_2RM_VCLS
] = 0x7,
5327 [NEON_2RM_VCLZ
] = 0x7,
5328 [NEON_2RM_VCNT
] = 0x1,
5329 [NEON_2RM_VMVN
] = 0x1,
5330 [NEON_2RM_VPADAL
] = 0x7,
5331 [NEON_2RM_VPADAL_U
] = 0x7,
5332 [NEON_2RM_VQABS
] = 0x7,
5333 [NEON_2RM_VQNEG
] = 0x7,
5334 [NEON_2RM_VCGT0
] = 0x7,
5335 [NEON_2RM_VCGE0
] = 0x7,
5336 [NEON_2RM_VCEQ0
] = 0x7,
5337 [NEON_2RM_VCLE0
] = 0x7,
5338 [NEON_2RM_VCLT0
] = 0x7,
5339 [NEON_2RM_SHA1H
] = 0x4,
5340 [NEON_2RM_VABS
] = 0x7,
5341 [NEON_2RM_VNEG
] = 0x7,
5342 [NEON_2RM_VCGT0_F
] = 0x4,
5343 [NEON_2RM_VCGE0_F
] = 0x4,
5344 [NEON_2RM_VCEQ0_F
] = 0x4,
5345 [NEON_2RM_VCLE0_F
] = 0x4,
5346 [NEON_2RM_VCLT0_F
] = 0x4,
5347 [NEON_2RM_VABS_F
] = 0x4,
5348 [NEON_2RM_VNEG_F
] = 0x4,
5349 [NEON_2RM_VSWP
] = 0x1,
5350 [NEON_2RM_VTRN
] = 0x7,
5351 [NEON_2RM_VUZP
] = 0x7,
5352 [NEON_2RM_VZIP
] = 0x7,
5353 [NEON_2RM_VMOVN
] = 0x7,
5354 [NEON_2RM_VQMOVN
] = 0x7,
5355 [NEON_2RM_VSHLL
] = 0x7,
5356 [NEON_2RM_SHA1SU1
] = 0x4,
5357 [NEON_2RM_VRINTN
] = 0x4,
5358 [NEON_2RM_VRINTX
] = 0x4,
5359 [NEON_2RM_VRINTA
] = 0x4,
5360 [NEON_2RM_VRINTZ
] = 0x4,
5361 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5362 [NEON_2RM_VRINTM
] = 0x4,
5363 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5364 [NEON_2RM_VRINTP
] = 0x4,
5365 [NEON_2RM_VCVTAU
] = 0x4,
5366 [NEON_2RM_VCVTAS
] = 0x4,
5367 [NEON_2RM_VCVTNU
] = 0x4,
5368 [NEON_2RM_VCVTNS
] = 0x4,
5369 [NEON_2RM_VCVTPU
] = 0x4,
5370 [NEON_2RM_VCVTPS
] = 0x4,
5371 [NEON_2RM_VCVTMU
] = 0x4,
5372 [NEON_2RM_VCVTMS
] = 0x4,
5373 [NEON_2RM_VRECPE
] = 0x4,
5374 [NEON_2RM_VRSQRTE
] = 0x4,
5375 [NEON_2RM_VRECPE_F
] = 0x4,
5376 [NEON_2RM_VRSQRTE_F
] = 0x4,
5377 [NEON_2RM_VCVT_FS
] = 0x4,
5378 [NEON_2RM_VCVT_FU
] = 0x4,
5379 [NEON_2RM_VCVT_SF
] = 0x4,
5380 [NEON_2RM_VCVT_UF
] = 0x4,
5383 /* Translate a NEON data processing instruction. Return nonzero if the
5384 instruction is invalid.
5385 We process data in a mixture of 32-bit and 64-bit chunks.
5386 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5388 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5400 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5403 /* FIXME: this access check should not take precedence over UNDEF
5404 * for invalid encodings; we will generate incorrect syndrome information
5405 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5407 if (s
->fp_excp_el
) {
5408 gen_exception_insn(s
, 4, EXCP_UDEF
,
5409 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5413 if (!s
->vfp_enabled
)
5415 q
= (insn
& (1 << 6)) != 0;
5416 u
= (insn
>> 24) & 1;
5417 VFP_DREG_D(rd
, insn
);
5418 VFP_DREG_N(rn
, insn
);
5419 VFP_DREG_M(rm
, insn
);
5420 size
= (insn
>> 20) & 3;
5421 if ((insn
& (1 << 23)) == 0) {
5422 /* Three register same length. */
5423 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5424 /* Catch invalid op and bad size combinations: UNDEF */
5425 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5428 /* All insns of this form UNDEF for either this condition or the
5429 * superset of cases "Q==1"; we catch the latter later.
5431 if (q
&& ((rd
| rn
| rm
) & 1)) {
5435 * The SHA-1/SHA-256 3-register instructions require special treatment
5436 * here, as their size field is overloaded as an op type selector, and
5437 * they all consume their input in a single pass.
5439 if (op
== NEON_3R_SHA
) {
5443 if (!u
) { /* SHA-1 */
5444 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5447 tmp
= tcg_const_i32(rd
);
5448 tmp2
= tcg_const_i32(rn
);
5449 tmp3
= tcg_const_i32(rm
);
5450 tmp4
= tcg_const_i32(size
);
5451 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5452 tcg_temp_free_i32(tmp4
);
5453 } else { /* SHA-256 */
5454 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5457 tmp
= tcg_const_i32(rd
);
5458 tmp2
= tcg_const_i32(rn
);
5459 tmp3
= tcg_const_i32(rm
);
5462 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5465 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5468 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5472 tcg_temp_free_i32(tmp
);
5473 tcg_temp_free_i32(tmp2
);
5474 tcg_temp_free_i32(tmp3
);
5477 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5478 /* 64-bit element instructions. */
5479 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5480 neon_load_reg64(cpu_V0
, rn
+ pass
);
5481 neon_load_reg64(cpu_V1
, rm
+ pass
);
5485 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5488 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5494 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5497 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5503 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5505 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5510 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5513 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5519 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5521 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5524 case NEON_3R_VQRSHL
:
5526 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5529 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5533 case NEON_3R_VADD_VSUB
:
5535 tcg_gen_sub_i64(CPU_V001
);
5537 tcg_gen_add_i64(CPU_V001
);
5543 neon_store_reg64(cpu_V0
, rd
+ pass
);
5552 case NEON_3R_VQRSHL
:
5555 /* Shift instruction operands are reversed. */
5570 case NEON_3R_FLOAT_ARITH
:
5571 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5573 case NEON_3R_FLOAT_MINMAX
:
5574 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5576 case NEON_3R_FLOAT_CMP
:
5578 /* no encoding for U=0 C=1x */
5582 case NEON_3R_FLOAT_ACMP
:
5587 case NEON_3R_FLOAT_MISC
:
5588 /* VMAXNM/VMINNM in ARMv8 */
5589 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5594 if (u
&& (size
!= 0)) {
5595 /* UNDEF on invalid size for polynomial subcase */
5600 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5608 if (pairwise
&& q
) {
5609 /* All the pairwise insns UNDEF if Q is set */
5613 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5618 tmp
= neon_load_reg(rn
, 0);
5619 tmp2
= neon_load_reg(rn
, 1);
5621 tmp
= neon_load_reg(rm
, 0);
5622 tmp2
= neon_load_reg(rm
, 1);
5626 tmp
= neon_load_reg(rn
, pass
);
5627 tmp2
= neon_load_reg(rm
, pass
);
5631 GEN_NEON_INTEGER_OP(hadd
);
5634 GEN_NEON_INTEGER_OP_ENV(qadd
);
5636 case NEON_3R_VRHADD
:
5637 GEN_NEON_INTEGER_OP(rhadd
);
5639 case NEON_3R_LOGIC
: /* Logic ops. */
5640 switch ((u
<< 2) | size
) {
5642 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5645 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5648 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5651 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5654 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5657 tmp3
= neon_load_reg(rd
, pass
);
5658 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5659 tcg_temp_free_i32(tmp3
);
5662 tmp3
= neon_load_reg(rd
, pass
);
5663 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5664 tcg_temp_free_i32(tmp3
);
5667 tmp3
= neon_load_reg(rd
, pass
);
5668 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5669 tcg_temp_free_i32(tmp3
);
5674 GEN_NEON_INTEGER_OP(hsub
);
5677 GEN_NEON_INTEGER_OP_ENV(qsub
);
5680 GEN_NEON_INTEGER_OP(cgt
);
5683 GEN_NEON_INTEGER_OP(cge
);
5686 GEN_NEON_INTEGER_OP(shl
);
5689 GEN_NEON_INTEGER_OP_ENV(qshl
);
5692 GEN_NEON_INTEGER_OP(rshl
);
5694 case NEON_3R_VQRSHL
:
5695 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5698 GEN_NEON_INTEGER_OP(max
);
5701 GEN_NEON_INTEGER_OP(min
);
5704 GEN_NEON_INTEGER_OP(abd
);
5707 GEN_NEON_INTEGER_OP(abd
);
5708 tcg_temp_free_i32(tmp2
);
5709 tmp2
= neon_load_reg(rd
, pass
);
5710 gen_neon_add(size
, tmp
, tmp2
);
5712 case NEON_3R_VADD_VSUB
:
5713 if (!u
) { /* VADD */
5714 gen_neon_add(size
, tmp
, tmp2
);
5717 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5718 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5719 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5724 case NEON_3R_VTST_VCEQ
:
5725 if (!u
) { /* VTST */
5727 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5728 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5729 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5734 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5735 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5736 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5741 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5743 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5744 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5745 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5748 tcg_temp_free_i32(tmp2
);
5749 tmp2
= neon_load_reg(rd
, pass
);
5751 gen_neon_rsb(size
, tmp
, tmp2
);
5753 gen_neon_add(size
, tmp
, tmp2
);
5757 if (u
) { /* polynomial */
5758 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5759 } else { /* Integer */
5761 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5762 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5763 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5769 GEN_NEON_INTEGER_OP(pmax
);
5772 GEN_NEON_INTEGER_OP(pmin
);
5774 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5775 if (!u
) { /* VQDMULH */
5778 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5781 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5785 } else { /* VQRDMULH */
5788 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5791 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5799 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5800 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5801 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5805 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5807 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5808 switch ((u
<< 2) | size
) {
5811 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5814 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5817 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5822 tcg_temp_free_ptr(fpstatus
);
5825 case NEON_3R_FLOAT_MULTIPLY
:
5827 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5828 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5830 tcg_temp_free_i32(tmp2
);
5831 tmp2
= neon_load_reg(rd
, pass
);
5833 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5835 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5838 tcg_temp_free_ptr(fpstatus
);
5841 case NEON_3R_FLOAT_CMP
:
5843 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5845 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5848 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5850 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5853 tcg_temp_free_ptr(fpstatus
);
5856 case NEON_3R_FLOAT_ACMP
:
5858 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5860 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5862 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5864 tcg_temp_free_ptr(fpstatus
);
5867 case NEON_3R_FLOAT_MINMAX
:
5869 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5871 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5873 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5875 tcg_temp_free_ptr(fpstatus
);
5878 case NEON_3R_FLOAT_MISC
:
5881 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5883 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5885 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5887 tcg_temp_free_ptr(fpstatus
);
5890 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5892 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5898 /* VFMA, VFMS: fused multiply-add */
5899 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5900 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5903 gen_helper_vfp_negs(tmp
, tmp
);
5905 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5906 tcg_temp_free_i32(tmp3
);
5907 tcg_temp_free_ptr(fpstatus
);
5913 tcg_temp_free_i32(tmp2
);
5915 /* Save the result. For elementwise operations we can put it
5916 straight into the destination register. For pairwise operations
5917 we have to be careful to avoid clobbering the source operands. */
5918 if (pairwise
&& rd
== rm
) {
5919 neon_store_scratch(pass
, tmp
);
5921 neon_store_reg(rd
, pass
, tmp
);
5925 if (pairwise
&& rd
== rm
) {
5926 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5927 tmp
= neon_load_scratch(pass
);
5928 neon_store_reg(rd
, pass
, tmp
);
5931 /* End of 3 register same size operations. */
5932 } else if (insn
& (1 << 4)) {
5933 if ((insn
& 0x00380080) != 0) {
5934 /* Two registers and shift. */
5935 op
= (insn
>> 8) & 0xf;
5936 if (insn
& (1 << 7)) {
5944 while ((insn
& (1 << (size
+ 19))) == 0)
5947 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5948 /* To avoid excessive duplication of ops we implement shift
5949 by immediate using the variable shift operations. */
5951 /* Shift by immediate:
5952 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5953 if (q
&& ((rd
| rm
) & 1)) {
5956 if (!u
&& (op
== 4 || op
== 6)) {
5959 /* Right shifts are encoded as N - shift, where N is the
5960 element size in bits. */
5962 shift
= shift
- (1 << (size
+ 3));
5970 imm
= (uint8_t) shift
;
5975 imm
= (uint16_t) shift
;
5986 for (pass
= 0; pass
< count
; pass
++) {
5988 neon_load_reg64(cpu_V0
, rm
+ pass
);
5989 tcg_gen_movi_i64(cpu_V1
, imm
);
5994 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5996 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6001 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6003 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6006 case 5: /* VSHL, VSLI */
6007 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6009 case 6: /* VQSHLU */
6010 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6015 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6018 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6023 if (op
== 1 || op
== 3) {
6025 neon_load_reg64(cpu_V1
, rd
+ pass
);
6026 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6027 } else if (op
== 4 || (op
== 5 && u
)) {
6029 neon_load_reg64(cpu_V1
, rd
+ pass
);
6031 if (shift
< -63 || shift
> 63) {
6035 mask
= 0xffffffffffffffffull
>> -shift
;
6037 mask
= 0xffffffffffffffffull
<< shift
;
6040 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6041 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6043 neon_store_reg64(cpu_V0
, rd
+ pass
);
6044 } else { /* size < 3 */
6045 /* Operands in T0 and T1. */
6046 tmp
= neon_load_reg(rm
, pass
);
6047 tmp2
= tcg_temp_new_i32();
6048 tcg_gen_movi_i32(tmp2
, imm
);
6052 GEN_NEON_INTEGER_OP(shl
);
6056 GEN_NEON_INTEGER_OP(rshl
);
6059 case 5: /* VSHL, VSLI */
6061 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6062 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6063 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6067 case 6: /* VQSHLU */
6070 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6074 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6078 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6086 GEN_NEON_INTEGER_OP_ENV(qshl
);
6089 tcg_temp_free_i32(tmp2
);
6091 if (op
== 1 || op
== 3) {
6093 tmp2
= neon_load_reg(rd
, pass
);
6094 gen_neon_add(size
, tmp
, tmp2
);
6095 tcg_temp_free_i32(tmp2
);
6096 } else if (op
== 4 || (op
== 5 && u
)) {
6101 mask
= 0xff >> -shift
;
6103 mask
= (uint8_t)(0xff << shift
);
6109 mask
= 0xffff >> -shift
;
6111 mask
= (uint16_t)(0xffff << shift
);
6115 if (shift
< -31 || shift
> 31) {
6119 mask
= 0xffffffffu
>> -shift
;
6121 mask
= 0xffffffffu
<< shift
;
6127 tmp2
= neon_load_reg(rd
, pass
);
6128 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6129 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6130 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6131 tcg_temp_free_i32(tmp2
);
6133 neon_store_reg(rd
, pass
, tmp
);
6136 } else if (op
< 10) {
6137 /* Shift by immediate and narrow:
6138 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6139 int input_unsigned
= (op
== 8) ? !u
: u
;
6143 shift
= shift
- (1 << (size
+ 3));
6146 tmp64
= tcg_const_i64(shift
);
6147 neon_load_reg64(cpu_V0
, rm
);
6148 neon_load_reg64(cpu_V1
, rm
+ 1);
6149 for (pass
= 0; pass
< 2; pass
++) {
6157 if (input_unsigned
) {
6158 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6160 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6163 if (input_unsigned
) {
6164 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6166 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6169 tmp
= tcg_temp_new_i32();
6170 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6171 neon_store_reg(rd
, pass
, tmp
);
6173 tcg_temp_free_i64(tmp64
);
6176 imm
= (uint16_t)shift
;
6180 imm
= (uint32_t)shift
;
6182 tmp2
= tcg_const_i32(imm
);
6183 tmp4
= neon_load_reg(rm
+ 1, 0);
6184 tmp5
= neon_load_reg(rm
+ 1, 1);
6185 for (pass
= 0; pass
< 2; pass
++) {
6187 tmp
= neon_load_reg(rm
, 0);
6191 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6194 tmp3
= neon_load_reg(rm
, 1);
6198 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6200 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6201 tcg_temp_free_i32(tmp
);
6202 tcg_temp_free_i32(tmp3
);
6203 tmp
= tcg_temp_new_i32();
6204 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6205 neon_store_reg(rd
, pass
, tmp
);
6207 tcg_temp_free_i32(tmp2
);
6209 } else if (op
== 10) {
6211 if (q
|| (rd
& 1)) {
6214 tmp
= neon_load_reg(rm
, 0);
6215 tmp2
= neon_load_reg(rm
, 1);
6216 for (pass
= 0; pass
< 2; pass
++) {
6220 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6223 /* The shift is less than the width of the source
6224 type, so we can just shift the whole register. */
6225 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6226 /* Widen the result of shift: we need to clear
6227 * the potential overflow bits resulting from
6228 * left bits of the narrow input appearing as
6229 * right bits of left the neighbour narrow
6231 if (size
< 2 || !u
) {
6234 imm
= (0xffu
>> (8 - shift
));
6236 } else if (size
== 1) {
6237 imm
= 0xffff >> (16 - shift
);
6240 imm
= 0xffffffff >> (32 - shift
);
6243 imm64
= imm
| (((uint64_t)imm
) << 32);
6247 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6250 neon_store_reg64(cpu_V0
, rd
+ pass
);
6252 } else if (op
>= 14) {
6253 /* VCVT fixed-point. */
6254 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6257 /* We have already masked out the must-be-1 top bit of imm6,
6258 * hence this 32-shift where the ARM ARM has 64-imm6.
6261 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6262 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6265 gen_vfp_ulto(0, shift
, 1);
6267 gen_vfp_slto(0, shift
, 1);
6270 gen_vfp_toul(0, shift
, 1);
6272 gen_vfp_tosl(0, shift
, 1);
6274 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6279 } else { /* (insn & 0x00380080) == 0 */
6281 if (q
&& (rd
& 1)) {
6285 op
= (insn
>> 8) & 0xf;
6286 /* One register and immediate. */
6287 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6288 invert
= (insn
& (1 << 5)) != 0;
6289 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6290 * We choose to not special-case this and will behave as if a
6291 * valid constant encoding of 0 had been given.
6310 imm
= (imm
<< 8) | (imm
<< 24);
6313 imm
= (imm
<< 8) | 0xff;
6316 imm
= (imm
<< 16) | 0xffff;
6319 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6327 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6328 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6334 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6335 if (op
& 1 && op
< 12) {
6336 tmp
= neon_load_reg(rd
, pass
);
6338 /* The immediate value has already been inverted, so
6340 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6342 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6346 tmp
= tcg_temp_new_i32();
6347 if (op
== 14 && invert
) {
6351 for (n
= 0; n
< 4; n
++) {
6352 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6353 val
|= 0xff << (n
* 8);
6355 tcg_gen_movi_i32(tmp
, val
);
6357 tcg_gen_movi_i32(tmp
, imm
);
6360 neon_store_reg(rd
, pass
, tmp
);
6363 } else { /* (insn & 0x00800010 == 0x00800000) */
6365 op
= (insn
>> 8) & 0xf;
6366 if ((insn
& (1 << 6)) == 0) {
6367 /* Three registers of different lengths. */
6371 /* undefreq: bit 0 : UNDEF if size == 0
6372 * bit 1 : UNDEF if size == 1
6373 * bit 2 : UNDEF if size == 2
6374 * bit 3 : UNDEF if U == 1
6375 * Note that [2:0] set implies 'always UNDEF'
6378 /* prewiden, src1_wide, src2_wide, undefreq */
6379 static const int neon_3reg_wide
[16][4] = {
6380 {1, 0, 0, 0}, /* VADDL */
6381 {1, 1, 0, 0}, /* VADDW */
6382 {1, 0, 0, 0}, /* VSUBL */
6383 {1, 1, 0, 0}, /* VSUBW */
6384 {0, 1, 1, 0}, /* VADDHN */
6385 {0, 0, 0, 0}, /* VABAL */
6386 {0, 1, 1, 0}, /* VSUBHN */
6387 {0, 0, 0, 0}, /* VABDL */
6388 {0, 0, 0, 0}, /* VMLAL */
6389 {0, 0, 0, 9}, /* VQDMLAL */
6390 {0, 0, 0, 0}, /* VMLSL */
6391 {0, 0, 0, 9}, /* VQDMLSL */
6392 {0, 0, 0, 0}, /* Integer VMULL */
6393 {0, 0, 0, 1}, /* VQDMULL */
6394 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6395 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6398 prewiden
= neon_3reg_wide
[op
][0];
6399 src1_wide
= neon_3reg_wide
[op
][1];
6400 src2_wide
= neon_3reg_wide
[op
][2];
6401 undefreq
= neon_3reg_wide
[op
][3];
6403 if ((undefreq
& (1 << size
)) ||
6404 ((undefreq
& 8) && u
)) {
6407 if ((src1_wide
&& (rn
& 1)) ||
6408 (src2_wide
&& (rm
& 1)) ||
6409 (!src2_wide
&& (rd
& 1))) {
6413 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6414 * outside the loop below as it only performs a single pass.
6416 if (op
== 14 && size
== 2) {
6417 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6419 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6422 tcg_rn
= tcg_temp_new_i64();
6423 tcg_rm
= tcg_temp_new_i64();
6424 tcg_rd
= tcg_temp_new_i64();
6425 neon_load_reg64(tcg_rn
, rn
);
6426 neon_load_reg64(tcg_rm
, rm
);
6427 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6428 neon_store_reg64(tcg_rd
, rd
);
6429 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6430 neon_store_reg64(tcg_rd
, rd
+ 1);
6431 tcg_temp_free_i64(tcg_rn
);
6432 tcg_temp_free_i64(tcg_rm
);
6433 tcg_temp_free_i64(tcg_rd
);
6437 /* Avoid overlapping operands. Wide source operands are
6438 always aligned so will never overlap with wide
6439 destinations in problematic ways. */
6440 if (rd
== rm
&& !src2_wide
) {
6441 tmp
= neon_load_reg(rm
, 1);
6442 neon_store_scratch(2, tmp
);
6443 } else if (rd
== rn
&& !src1_wide
) {
6444 tmp
= neon_load_reg(rn
, 1);
6445 neon_store_scratch(2, tmp
);
6447 TCGV_UNUSED_I32(tmp3
);
6448 for (pass
= 0; pass
< 2; pass
++) {
6450 neon_load_reg64(cpu_V0
, rn
+ pass
);
6451 TCGV_UNUSED_I32(tmp
);
6453 if (pass
== 1 && rd
== rn
) {
6454 tmp
= neon_load_scratch(2);
6456 tmp
= neon_load_reg(rn
, pass
);
6459 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6463 neon_load_reg64(cpu_V1
, rm
+ pass
);
6464 TCGV_UNUSED_I32(tmp2
);
6466 if (pass
== 1 && rd
== rm
) {
6467 tmp2
= neon_load_scratch(2);
6469 tmp2
= neon_load_reg(rm
, pass
);
6472 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6476 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6477 gen_neon_addl(size
);
6479 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6480 gen_neon_subl(size
);
6482 case 5: case 7: /* VABAL, VABDL */
6483 switch ((size
<< 1) | u
) {
6485 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6488 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6491 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6494 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6497 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6500 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6504 tcg_temp_free_i32(tmp2
);
6505 tcg_temp_free_i32(tmp
);
6507 case 8: case 9: case 10: case 11: case 12: case 13:
6508 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6509 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6511 case 14: /* Polynomial VMULL */
6512 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6513 tcg_temp_free_i32(tmp2
);
6514 tcg_temp_free_i32(tmp
);
6516 default: /* 15 is RESERVED: caught earlier */
6521 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6522 neon_store_reg64(cpu_V0
, rd
+ pass
);
6523 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6525 neon_load_reg64(cpu_V1
, rd
+ pass
);
6527 case 10: /* VMLSL */
6528 gen_neon_negl(cpu_V0
, size
);
6530 case 5: case 8: /* VABAL, VMLAL */
6531 gen_neon_addl(size
);
6533 case 9: case 11: /* VQDMLAL, VQDMLSL */
6534 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6536 gen_neon_negl(cpu_V0
, size
);
6538 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6543 neon_store_reg64(cpu_V0
, rd
+ pass
);
6544 } else if (op
== 4 || op
== 6) {
6545 /* Narrowing operation. */
6546 tmp
= tcg_temp_new_i32();
6550 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6553 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6556 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6557 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6564 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6567 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6570 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6571 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6572 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6580 neon_store_reg(rd
, 0, tmp3
);
6581 neon_store_reg(rd
, 1, tmp
);
6584 /* Write back the result. */
6585 neon_store_reg64(cpu_V0
, rd
+ pass
);
6589 /* Two registers and a scalar. NB that for ops of this form
6590 * the ARM ARM labels bit 24 as Q, but it is in our variable
6597 case 1: /* Float VMLA scalar */
6598 case 5: /* Floating point VMLS scalar */
6599 case 9: /* Floating point VMUL scalar */
6604 case 0: /* Integer VMLA scalar */
6605 case 4: /* Integer VMLS scalar */
6606 case 8: /* Integer VMUL scalar */
6607 case 12: /* VQDMULH scalar */
6608 case 13: /* VQRDMULH scalar */
6609 if (u
&& ((rd
| rn
) & 1)) {
6612 tmp
= neon_get_scalar(size
, rm
);
6613 neon_store_scratch(0, tmp
);
6614 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6615 tmp
= neon_load_scratch(0);
6616 tmp2
= neon_load_reg(rn
, pass
);
6619 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6621 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6623 } else if (op
== 13) {
6625 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6627 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6629 } else if (op
& 1) {
6630 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6631 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6632 tcg_temp_free_ptr(fpstatus
);
6635 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6636 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6637 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6641 tcg_temp_free_i32(tmp2
);
6644 tmp2
= neon_load_reg(rd
, pass
);
6647 gen_neon_add(size
, tmp
, tmp2
);
6651 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6652 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6653 tcg_temp_free_ptr(fpstatus
);
6657 gen_neon_rsb(size
, tmp
, tmp2
);
6661 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6662 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6663 tcg_temp_free_ptr(fpstatus
);
6669 tcg_temp_free_i32(tmp2
);
6671 neon_store_reg(rd
, pass
, tmp
);
6674 case 3: /* VQDMLAL scalar */
6675 case 7: /* VQDMLSL scalar */
6676 case 11: /* VQDMULL scalar */
6681 case 2: /* VMLAL sclar */
6682 case 6: /* VMLSL scalar */
6683 case 10: /* VMULL scalar */
6687 tmp2
= neon_get_scalar(size
, rm
);
6688 /* We need a copy of tmp2 because gen_neon_mull
6689 * deletes it during pass 0. */
6690 tmp4
= tcg_temp_new_i32();
6691 tcg_gen_mov_i32(tmp4
, tmp2
);
6692 tmp3
= neon_load_reg(rn
, 1);
6694 for (pass
= 0; pass
< 2; pass
++) {
6696 tmp
= neon_load_reg(rn
, 0);
6701 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6703 neon_load_reg64(cpu_V1
, rd
+ pass
);
6707 gen_neon_negl(cpu_V0
, size
);
6710 gen_neon_addl(size
);
6713 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6715 gen_neon_negl(cpu_V0
, size
);
6717 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6723 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6728 neon_store_reg64(cpu_V0
, rd
+ pass
);
6733 default: /* 14 and 15 are RESERVED */
6737 } else { /* size == 3 */
6740 imm
= (insn
>> 8) & 0xf;
6745 if (q
&& ((rd
| rn
| rm
) & 1)) {
6750 neon_load_reg64(cpu_V0
, rn
);
6752 neon_load_reg64(cpu_V1
, rn
+ 1);
6754 } else if (imm
== 8) {
6755 neon_load_reg64(cpu_V0
, rn
+ 1);
6757 neon_load_reg64(cpu_V1
, rm
);
6760 tmp64
= tcg_temp_new_i64();
6762 neon_load_reg64(cpu_V0
, rn
);
6763 neon_load_reg64(tmp64
, rn
+ 1);
6765 neon_load_reg64(cpu_V0
, rn
+ 1);
6766 neon_load_reg64(tmp64
, rm
);
6768 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6769 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6770 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6772 neon_load_reg64(cpu_V1
, rm
);
6774 neon_load_reg64(cpu_V1
, rm
+ 1);
6777 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6778 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6779 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6780 tcg_temp_free_i64(tmp64
);
6783 neon_load_reg64(cpu_V0
, rn
);
6784 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6785 neon_load_reg64(cpu_V1
, rm
);
6786 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6787 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6789 neon_store_reg64(cpu_V0
, rd
);
6791 neon_store_reg64(cpu_V1
, rd
+ 1);
6793 } else if ((insn
& (1 << 11)) == 0) {
6794 /* Two register misc. */
6795 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6796 size
= (insn
>> 18) & 3;
6797 /* UNDEF for unknown op values and bad op-size combinations */
6798 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6801 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6802 q
&& ((rm
| rd
) & 1)) {
6806 case NEON_2RM_VREV64
:
6807 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6808 tmp
= neon_load_reg(rm
, pass
* 2);
6809 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6811 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6812 case 1: gen_swap_half(tmp
); break;
6813 case 2: /* no-op */ break;
6816 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6818 neon_store_reg(rd
, pass
* 2, tmp2
);
6821 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6822 case 1: gen_swap_half(tmp2
); break;
6825 neon_store_reg(rd
, pass
* 2, tmp2
);
6829 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6830 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6831 for (pass
= 0; pass
< q
+ 1; pass
++) {
6832 tmp
= neon_load_reg(rm
, pass
* 2);
6833 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6834 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6835 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6837 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6838 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6839 case 2: tcg_gen_add_i64(CPU_V001
); break;
6842 if (op
>= NEON_2RM_VPADAL
) {
6844 neon_load_reg64(cpu_V1
, rd
+ pass
);
6845 gen_neon_addl(size
);
6847 neon_store_reg64(cpu_V0
, rd
+ pass
);
6853 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6854 tmp
= neon_load_reg(rm
, n
);
6855 tmp2
= neon_load_reg(rd
, n
+ 1);
6856 neon_store_reg(rm
, n
, tmp2
);
6857 neon_store_reg(rd
, n
+ 1, tmp
);
6864 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6869 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6873 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6874 /* also VQMOVUN; op field and mnemonics don't line up */
6878 TCGV_UNUSED_I32(tmp2
);
6879 for (pass
= 0; pass
< 2; pass
++) {
6880 neon_load_reg64(cpu_V0
, rm
+ pass
);
6881 tmp
= tcg_temp_new_i32();
6882 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6887 neon_store_reg(rd
, 0, tmp2
);
6888 neon_store_reg(rd
, 1, tmp
);
6892 case NEON_2RM_VSHLL
:
6893 if (q
|| (rd
& 1)) {
6896 tmp
= neon_load_reg(rm
, 0);
6897 tmp2
= neon_load_reg(rm
, 1);
6898 for (pass
= 0; pass
< 2; pass
++) {
6901 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6902 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6903 neon_store_reg64(cpu_V0
, rd
+ pass
);
6906 case NEON_2RM_VCVT_F16_F32
:
6907 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6911 tmp
= tcg_temp_new_i32();
6912 tmp2
= tcg_temp_new_i32();
6913 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6914 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6915 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6916 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6917 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6918 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6919 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6920 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6921 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6922 neon_store_reg(rd
, 0, tmp2
);
6923 tmp2
= tcg_temp_new_i32();
6924 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6925 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6926 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6927 neon_store_reg(rd
, 1, tmp2
);
6928 tcg_temp_free_i32(tmp
);
6930 case NEON_2RM_VCVT_F32_F16
:
6931 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6935 tmp3
= tcg_temp_new_i32();
6936 tmp
= neon_load_reg(rm
, 0);
6937 tmp2
= neon_load_reg(rm
, 1);
6938 tcg_gen_ext16u_i32(tmp3
, tmp
);
6939 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6940 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6941 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6942 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6943 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6944 tcg_temp_free_i32(tmp
);
6945 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6946 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6947 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6948 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6949 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6950 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6951 tcg_temp_free_i32(tmp2
);
6952 tcg_temp_free_i32(tmp3
);
6954 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6955 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6956 || ((rm
| rd
) & 1)) {
6959 tmp
= tcg_const_i32(rd
);
6960 tmp2
= tcg_const_i32(rm
);
6962 /* Bit 6 is the lowest opcode bit; it distinguishes between
6963 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6965 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6967 if (op
== NEON_2RM_AESE
) {
6968 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6970 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6972 tcg_temp_free_i32(tmp
);
6973 tcg_temp_free_i32(tmp2
);
6974 tcg_temp_free_i32(tmp3
);
6976 case NEON_2RM_SHA1H
:
6977 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
6978 || ((rm
| rd
) & 1)) {
6981 tmp
= tcg_const_i32(rd
);
6982 tmp2
= tcg_const_i32(rm
);
6984 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6986 tcg_temp_free_i32(tmp
);
6987 tcg_temp_free_i32(tmp2
);
6989 case NEON_2RM_SHA1SU1
:
6990 if ((rm
| rd
) & 1) {
6993 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6995 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
6998 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7001 tmp
= tcg_const_i32(rd
);
7002 tmp2
= tcg_const_i32(rm
);
7004 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
7006 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7008 tcg_temp_free_i32(tmp
);
7009 tcg_temp_free_i32(tmp2
);
7013 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7014 if (neon_2rm_is_float_op(op
)) {
7015 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7016 neon_reg_offset(rm
, pass
));
7017 TCGV_UNUSED_I32(tmp
);
7019 tmp
= neon_load_reg(rm
, pass
);
7022 case NEON_2RM_VREV32
:
7024 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7025 case 1: gen_swap_half(tmp
); break;
7029 case NEON_2RM_VREV16
:
7034 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7035 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7036 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7042 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7043 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7044 case 2: gen_helper_clz(tmp
, tmp
); break;
7049 gen_helper_neon_cnt_u8(tmp
, tmp
);
7052 tcg_gen_not_i32(tmp
, tmp
);
7054 case NEON_2RM_VQABS
:
7057 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7060 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7063 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7068 case NEON_2RM_VQNEG
:
7071 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7074 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7077 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7082 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7083 tmp2
= tcg_const_i32(0);
7085 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7086 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7087 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7090 tcg_temp_free_i32(tmp2
);
7091 if (op
== NEON_2RM_VCLE0
) {
7092 tcg_gen_not_i32(tmp
, tmp
);
7095 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7096 tmp2
= tcg_const_i32(0);
7098 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7099 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7100 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7103 tcg_temp_free_i32(tmp2
);
7104 if (op
== NEON_2RM_VCLT0
) {
7105 tcg_gen_not_i32(tmp
, tmp
);
7108 case NEON_2RM_VCEQ0
:
7109 tmp2
= tcg_const_i32(0);
7111 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7112 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7113 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7116 tcg_temp_free_i32(tmp2
);
7120 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7121 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7122 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7127 tmp2
= tcg_const_i32(0);
7128 gen_neon_rsb(size
, tmp
, tmp2
);
7129 tcg_temp_free_i32(tmp2
);
7131 case NEON_2RM_VCGT0_F
:
7133 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7134 tmp2
= tcg_const_i32(0);
7135 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7136 tcg_temp_free_i32(tmp2
);
7137 tcg_temp_free_ptr(fpstatus
);
7140 case NEON_2RM_VCGE0_F
:
7142 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7143 tmp2
= tcg_const_i32(0);
7144 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7145 tcg_temp_free_i32(tmp2
);
7146 tcg_temp_free_ptr(fpstatus
);
7149 case NEON_2RM_VCEQ0_F
:
7151 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7152 tmp2
= tcg_const_i32(0);
7153 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7154 tcg_temp_free_i32(tmp2
);
7155 tcg_temp_free_ptr(fpstatus
);
7158 case NEON_2RM_VCLE0_F
:
7160 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7161 tmp2
= tcg_const_i32(0);
7162 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7163 tcg_temp_free_i32(tmp2
);
7164 tcg_temp_free_ptr(fpstatus
);
7167 case NEON_2RM_VCLT0_F
:
7169 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7170 tmp2
= tcg_const_i32(0);
7171 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7172 tcg_temp_free_i32(tmp2
);
7173 tcg_temp_free_ptr(fpstatus
);
7176 case NEON_2RM_VABS_F
:
7179 case NEON_2RM_VNEG_F
:
7183 tmp2
= neon_load_reg(rd
, pass
);
7184 neon_store_reg(rm
, pass
, tmp2
);
7187 tmp2
= neon_load_reg(rd
, pass
);
7189 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7190 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7193 neon_store_reg(rm
, pass
, tmp2
);
7195 case NEON_2RM_VRINTN
:
7196 case NEON_2RM_VRINTA
:
7197 case NEON_2RM_VRINTM
:
7198 case NEON_2RM_VRINTP
:
7199 case NEON_2RM_VRINTZ
:
7202 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7205 if (op
== NEON_2RM_VRINTZ
) {
7206 rmode
= FPROUNDING_ZERO
;
7208 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7211 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7212 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7214 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7215 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7217 tcg_temp_free_ptr(fpstatus
);
7218 tcg_temp_free_i32(tcg_rmode
);
7221 case NEON_2RM_VRINTX
:
7223 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7224 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7225 tcg_temp_free_ptr(fpstatus
);
7228 case NEON_2RM_VCVTAU
:
7229 case NEON_2RM_VCVTAS
:
7230 case NEON_2RM_VCVTNU
:
7231 case NEON_2RM_VCVTNS
:
7232 case NEON_2RM_VCVTPU
:
7233 case NEON_2RM_VCVTPS
:
7234 case NEON_2RM_VCVTMU
:
7235 case NEON_2RM_VCVTMS
:
7237 bool is_signed
= !extract32(insn
, 7, 1);
7238 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7239 TCGv_i32 tcg_rmode
, tcg_shift
;
7240 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7242 tcg_shift
= tcg_const_i32(0);
7243 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7244 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7248 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7251 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7255 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7257 tcg_temp_free_i32(tcg_rmode
);
7258 tcg_temp_free_i32(tcg_shift
);
7259 tcg_temp_free_ptr(fpst
);
7262 case NEON_2RM_VRECPE
:
7264 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7265 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7266 tcg_temp_free_ptr(fpstatus
);
7269 case NEON_2RM_VRSQRTE
:
7271 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7272 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7273 tcg_temp_free_ptr(fpstatus
);
7276 case NEON_2RM_VRECPE_F
:
7278 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7279 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7280 tcg_temp_free_ptr(fpstatus
);
7283 case NEON_2RM_VRSQRTE_F
:
7285 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7286 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7287 tcg_temp_free_ptr(fpstatus
);
7290 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7293 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7296 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7297 gen_vfp_tosiz(0, 1);
7299 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7300 gen_vfp_touiz(0, 1);
7303 /* Reserved op values were caught by the
7304 * neon_2rm_sizes[] check earlier.
7308 if (neon_2rm_is_float_op(op
)) {
7309 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7310 neon_reg_offset(rd
, pass
));
7312 neon_store_reg(rd
, pass
, tmp
);
7317 } else if ((insn
& (1 << 10)) == 0) {
7319 int n
= ((insn
>> 8) & 3) + 1;
7320 if ((rn
+ n
) > 32) {
7321 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7322 * helper function running off the end of the register file.
7327 if (insn
& (1 << 6)) {
7328 tmp
= neon_load_reg(rd
, 0);
7330 tmp
= tcg_temp_new_i32();
7331 tcg_gen_movi_i32(tmp
, 0);
7333 tmp2
= neon_load_reg(rm
, 0);
7334 tmp4
= tcg_const_i32(rn
);
7335 tmp5
= tcg_const_i32(n
);
7336 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7337 tcg_temp_free_i32(tmp
);
7338 if (insn
& (1 << 6)) {
7339 tmp
= neon_load_reg(rd
, 1);
7341 tmp
= tcg_temp_new_i32();
7342 tcg_gen_movi_i32(tmp
, 0);
7344 tmp3
= neon_load_reg(rm
, 1);
7345 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7346 tcg_temp_free_i32(tmp5
);
7347 tcg_temp_free_i32(tmp4
);
7348 neon_store_reg(rd
, 0, tmp2
);
7349 neon_store_reg(rd
, 1, tmp3
);
7350 tcg_temp_free_i32(tmp
);
7351 } else if ((insn
& 0x380) == 0) {
7353 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7356 if (insn
& (1 << 19)) {
7357 tmp
= neon_load_reg(rm
, 1);
7359 tmp
= neon_load_reg(rm
, 0);
7361 if (insn
& (1 << 16)) {
7362 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7363 } else if (insn
& (1 << 17)) {
7364 if ((insn
>> 18) & 1)
7365 gen_neon_dup_high16(tmp
);
7367 gen_neon_dup_low16(tmp
);
7369 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7370 tmp2
= tcg_temp_new_i32();
7371 tcg_gen_mov_i32(tmp2
, tmp
);
7372 neon_store_reg(rd
, pass
, tmp2
);
7374 tcg_temp_free_i32(tmp
);
7383 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7385 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7386 const ARMCPRegInfo
*ri
;
7388 cpnum
= (insn
>> 8) & 0xf;
7390 /* First check for coprocessor space used for XScale/iwMMXt insns */
7391 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7392 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7395 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7396 return disas_iwmmxt_insn(s
, insn
);
7397 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7398 return disas_dsp_insn(s
, insn
);
7403 /* Otherwise treat as a generic register access */
7404 is64
= (insn
& (1 << 25)) == 0;
7405 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7413 opc1
= (insn
>> 4) & 0xf;
7415 rt2
= (insn
>> 16) & 0xf;
7417 crn
= (insn
>> 16) & 0xf;
7418 opc1
= (insn
>> 21) & 7;
7419 opc2
= (insn
>> 5) & 7;
7422 isread
= (insn
>> 20) & 1;
7423 rt
= (insn
>> 12) & 0xf;
7425 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7426 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7428 /* Check access permissions */
7429 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7434 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7435 /* Emit code to perform further access permissions checks at
7436 * runtime; this may result in an exception.
7437 * Note that on XScale all cp0..c13 registers do an access check
7438 * call in order to handle c15_cpar.
7441 TCGv_i32 tcg_syn
, tcg_isread
;
7444 /* Note that since we are an implementation which takes an
7445 * exception on a trapped conditional instruction only if the
7446 * instruction passes its condition code check, we can take
7447 * advantage of the clause in the ARM ARM that allows us to set
7448 * the COND field in the instruction to 0xE in all cases.
7449 * We could fish the actual condition out of the insn (ARM)
7450 * or the condexec bits (Thumb) but it isn't necessary.
7455 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7458 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7464 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7467 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7472 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7473 * so this can only happen if this is an ARMv7 or earlier CPU,
7474 * in which case the syndrome information won't actually be
7477 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7478 syndrome
= syn_uncategorized();
7482 gen_set_condexec(s
);
7483 gen_set_pc_im(s
, s
->pc
- 4);
7484 tmpptr
= tcg_const_ptr(ri
);
7485 tcg_syn
= tcg_const_i32(syndrome
);
7486 tcg_isread
= tcg_const_i32(isread
);
7487 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7489 tcg_temp_free_ptr(tmpptr
);
7490 tcg_temp_free_i32(tcg_syn
);
7491 tcg_temp_free_i32(tcg_isread
);
7494 /* Handle special cases first */
7495 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7502 gen_set_pc_im(s
, s
->pc
);
7503 s
->is_jmp
= DISAS_WFI
;
7509 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7518 if (ri
->type
& ARM_CP_CONST
) {
7519 tmp64
= tcg_const_i64(ri
->resetvalue
);
7520 } else if (ri
->readfn
) {
7522 tmp64
= tcg_temp_new_i64();
7523 tmpptr
= tcg_const_ptr(ri
);
7524 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7525 tcg_temp_free_ptr(tmpptr
);
7527 tmp64
= tcg_temp_new_i64();
7528 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7530 tmp
= tcg_temp_new_i32();
7531 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7532 store_reg(s
, rt
, tmp
);
7533 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7534 tmp
= tcg_temp_new_i32();
7535 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7536 tcg_temp_free_i64(tmp64
);
7537 store_reg(s
, rt2
, tmp
);
7540 if (ri
->type
& ARM_CP_CONST
) {
7541 tmp
= tcg_const_i32(ri
->resetvalue
);
7542 } else if (ri
->readfn
) {
7544 tmp
= tcg_temp_new_i32();
7545 tmpptr
= tcg_const_ptr(ri
);
7546 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7547 tcg_temp_free_ptr(tmpptr
);
7549 tmp
= load_cpu_offset(ri
->fieldoffset
);
7552 /* Destination register of r15 for 32 bit loads sets
7553 * the condition codes from the high 4 bits of the value
7556 tcg_temp_free_i32(tmp
);
7558 store_reg(s
, rt
, tmp
);
7563 if (ri
->type
& ARM_CP_CONST
) {
7564 /* If not forbidden by access permissions, treat as WI */
7569 TCGv_i32 tmplo
, tmphi
;
7570 TCGv_i64 tmp64
= tcg_temp_new_i64();
7571 tmplo
= load_reg(s
, rt
);
7572 tmphi
= load_reg(s
, rt2
);
7573 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7574 tcg_temp_free_i32(tmplo
);
7575 tcg_temp_free_i32(tmphi
);
7577 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7578 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7579 tcg_temp_free_ptr(tmpptr
);
7581 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7583 tcg_temp_free_i64(tmp64
);
7588 tmp
= load_reg(s
, rt
);
7589 tmpptr
= tcg_const_ptr(ri
);
7590 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7591 tcg_temp_free_ptr(tmpptr
);
7592 tcg_temp_free_i32(tmp
);
7594 TCGv_i32 tmp
= load_reg(s
, rt
);
7595 store_cpu_offset(tmp
, ri
->fieldoffset
);
7600 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7601 /* I/O operations must end the TB here (whether read or write) */
7604 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7605 /* We default to ending the TB on a coprocessor register write,
7606 * but allow this to be suppressed by the register definition
7607 * (usually only necessary to work around guest bugs).
7615 /* Unknown register; this might be a guest error or a QEMU
7616 * unimplemented feature.
7619 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7620 "64 bit system register cp:%d opc1: %d crm:%d "
7622 isread
? "read" : "write", cpnum
, opc1
, crm
,
7623 s
->ns
? "non-secure" : "secure");
7625 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7626 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7628 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7629 s
->ns
? "non-secure" : "secure");
7636 /* Store a 64-bit value to a register pair. Clobbers val. */
7637 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7640 tmp
= tcg_temp_new_i32();
7641 tcg_gen_extrl_i64_i32(tmp
, val
);
7642 store_reg(s
, rlow
, tmp
);
7643 tmp
= tcg_temp_new_i32();
7644 tcg_gen_shri_i64(val
, val
, 32);
7645 tcg_gen_extrl_i64_i32(tmp
, val
);
7646 store_reg(s
, rhigh
, tmp
);
7649 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7650 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7655 /* Load value and extend to 64 bits. */
7656 tmp
= tcg_temp_new_i64();
7657 tmp2
= load_reg(s
, rlow
);
7658 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7659 tcg_temp_free_i32(tmp2
);
7660 tcg_gen_add_i64(val
, val
, tmp
);
7661 tcg_temp_free_i64(tmp
);
7664 /* load and add a 64-bit value from a register pair. */
7665 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7671 /* Load 64-bit value rd:rn. */
7672 tmpl
= load_reg(s
, rlow
);
7673 tmph
= load_reg(s
, rhigh
);
7674 tmp
= tcg_temp_new_i64();
7675 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7676 tcg_temp_free_i32(tmpl
);
7677 tcg_temp_free_i32(tmph
);
7678 tcg_gen_add_i64(val
, val
, tmp
);
7679 tcg_temp_free_i64(tmp
);
7682 /* Set N and Z flags from hi|lo. */
7683 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7685 tcg_gen_mov_i32(cpu_NF
, hi
);
7686 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7689 /* Load/Store exclusive instructions are implemented by remembering
7690 the value/address loaded, and seeing if these are the same
7691 when the store is performed. This should be sufficient to implement
7692 the architecturally mandated semantics, and avoids having to monitor
7695 In system emulation mode only one CPU will be running at once, so
7696 this sequence is effectively atomic. In user emulation mode we
7697 throw an exception and handle the atomic operation elsewhere. */
7698 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7699 TCGv_i32 addr
, int size
)
7701 TCGv_i32 tmp
= tcg_temp_new_i32();
7707 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7710 gen_aa32_ld16ua(s
, tmp
, addr
, get_mem_index(s
));
7714 gen_aa32_ld32ua(s
, tmp
, addr
, get_mem_index(s
));
7721 TCGv_i32 tmp2
= tcg_temp_new_i32();
7722 TCGv_i32 tmp3
= tcg_temp_new_i32();
7724 tcg_gen_addi_i32(tmp2
, addr
, 4);
7725 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7726 tcg_temp_free_i32(tmp2
);
7727 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7728 store_reg(s
, rt2
, tmp3
);
7730 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7733 store_reg(s
, rt
, tmp
);
7734 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7737 static void gen_clrex(DisasContext
*s
)
7739 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7742 #ifdef CONFIG_USER_ONLY
7743 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7744 TCGv_i32 addr
, int size
)
7746 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7747 tcg_gen_movi_i32(cpu_exclusive_info
,
7748 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7749 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7752 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7753 TCGv_i32 addr
, int size
)
7756 TCGv_i64 val64
, extaddr
;
7757 TCGLabel
*done_label
;
7758 TCGLabel
*fail_label
;
7760 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7766 fail_label
= gen_new_label();
7767 done_label
= gen_new_label();
7768 extaddr
= tcg_temp_new_i64();
7769 tcg_gen_extu_i32_i64(extaddr
, addr
);
7770 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7771 tcg_temp_free_i64(extaddr
);
7773 tmp
= tcg_temp_new_i32();
7776 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7779 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
7783 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7789 val64
= tcg_temp_new_i64();
7791 TCGv_i32 tmp2
= tcg_temp_new_i32();
7792 TCGv_i32 tmp3
= tcg_temp_new_i32();
7793 tcg_gen_addi_i32(tmp2
, addr
, 4);
7794 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7795 tcg_temp_free_i32(tmp2
);
7796 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7797 tcg_temp_free_i32(tmp3
);
7799 tcg_gen_extu_i32_i64(val64
, tmp
);
7801 tcg_temp_free_i32(tmp
);
7803 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7804 tcg_temp_free_i64(val64
);
7806 tmp
= load_reg(s
, rt
);
7809 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
7812 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
7816 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7821 tcg_temp_free_i32(tmp
);
7823 tcg_gen_addi_i32(addr
, addr
, 4);
7824 tmp
= load_reg(s
, rt2
);
7825 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7826 tcg_temp_free_i32(tmp
);
7828 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7829 tcg_gen_br(done_label
);
7830 gen_set_label(fail_label
);
7831 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7832 gen_set_label(done_label
);
7833 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7840 * @mode: mode field from insn (which stack to store to)
7841 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7842 * @writeback: true if writeback bit set
7844 * Generate code for the SRS (Store Return State) insn.
7846 static void gen_srs(DisasContext
*s
,
7847 uint32_t mode
, uint32_t amode
, bool writeback
)
7854 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7855 * and specified mode is monitor mode
7856 * - UNDEFINED in Hyp mode
7857 * - UNPREDICTABLE in User or System mode
7858 * - UNPREDICTABLE if the specified mode is:
7859 * -- not implemented
7860 * -- not a valid mode number
7861 * -- a mode that's at a higher exception level
7862 * -- Monitor, if we are Non-secure
7863 * For the UNPREDICTABLE cases we choose to UNDEF.
7865 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7866 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7870 if (s
->current_el
== 0 || s
->current_el
== 2) {
7875 case ARM_CPU_MODE_USR
:
7876 case ARM_CPU_MODE_FIQ
:
7877 case ARM_CPU_MODE_IRQ
:
7878 case ARM_CPU_MODE_SVC
:
7879 case ARM_CPU_MODE_ABT
:
7880 case ARM_CPU_MODE_UND
:
7881 case ARM_CPU_MODE_SYS
:
7883 case ARM_CPU_MODE_HYP
:
7884 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7888 case ARM_CPU_MODE_MON
:
7889 /* No need to check specifically for "are we non-secure" because
7890 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7891 * so if this isn't EL3 then we must be non-secure.
7893 if (s
->current_el
!= 3) {
7902 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
7903 default_exception_el(s
));
7907 addr
= tcg_temp_new_i32();
7908 tmp
= tcg_const_i32(mode
);
7909 /* get_r13_banked() will raise an exception if called from System mode */
7910 gen_set_condexec(s
);
7911 gen_set_pc_im(s
, s
->pc
- 4);
7912 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7913 tcg_temp_free_i32(tmp
);
7930 tcg_gen_addi_i32(addr
, addr
, offset
);
7931 tmp
= load_reg(s
, 14);
7932 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7933 tcg_temp_free_i32(tmp
);
7934 tmp
= load_cpu_field(spsr
);
7935 tcg_gen_addi_i32(addr
, addr
, 4);
7936 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7937 tcg_temp_free_i32(tmp
);
7955 tcg_gen_addi_i32(addr
, addr
, offset
);
7956 tmp
= tcg_const_i32(mode
);
7957 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7958 tcg_temp_free_i32(tmp
);
7960 tcg_temp_free_i32(addr
);
7961 s
->is_jmp
= DISAS_UPDATE
;
7964 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7966 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7973 /* M variants do not implement ARM mode. */
7974 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7979 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7980 * choose to UNDEF. In ARMv5 and above the space is used
7981 * for miscellaneous unconditional instructions.
7985 /* Unconditional instructions. */
7986 if (((insn
>> 25) & 7) == 1) {
7987 /* NEON Data processing. */
7988 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7992 if (disas_neon_data_insn(s
, insn
)) {
7997 if ((insn
& 0x0f100000) == 0x04000000) {
7998 /* NEON load/store. */
7999 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8003 if (disas_neon_ls_insn(s
, insn
)) {
8008 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8010 if (disas_vfp_insn(s
, insn
)) {
8015 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8016 ((insn
& 0x0f30f010) == 0x0710f000)) {
8017 if ((insn
& (1 << 22)) == 0) {
8019 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8023 /* Otherwise PLD; v5TE+ */
8027 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8028 ((insn
& 0x0f70f010) == 0x0650f000)) {
8030 return; /* PLI; V7 */
8032 if (((insn
& 0x0f700000) == 0x04100000) ||
8033 ((insn
& 0x0f700010) == 0x06100000)) {
8034 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8037 return; /* v7MP: Unallocated memory hint: must NOP */
8040 if ((insn
& 0x0ffffdff) == 0x01010000) {
8043 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8044 gen_helper_setend(cpu_env
);
8045 s
->is_jmp
= DISAS_UPDATE
;
8048 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8049 switch ((insn
>> 4) & 0xf) {
8057 /* We don't emulate caches so these are a no-op. */
8060 /* We need to break the TB after this insn to execute
8061 * self-modifying code correctly and also to take
8062 * any pending interrupts immediately.
8069 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8072 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8074 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8080 rn
= (insn
>> 16) & 0xf;
8081 addr
= load_reg(s
, rn
);
8082 i
= (insn
>> 23) & 3;
8084 case 0: offset
= -4; break; /* DA */
8085 case 1: offset
= 0; break; /* IA */
8086 case 2: offset
= -8; break; /* DB */
8087 case 3: offset
= 4; break; /* IB */
8091 tcg_gen_addi_i32(addr
, addr
, offset
);
8092 /* Load PC into tmp and CPSR into tmp2. */
8093 tmp
= tcg_temp_new_i32();
8094 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8095 tcg_gen_addi_i32(addr
, addr
, 4);
8096 tmp2
= tcg_temp_new_i32();
8097 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8098 if (insn
& (1 << 21)) {
8099 /* Base writeback. */
8101 case 0: offset
= -8; break;
8102 case 1: offset
= 4; break;
8103 case 2: offset
= -4; break;
8104 case 3: offset
= 0; break;
8108 tcg_gen_addi_i32(addr
, addr
, offset
);
8109 store_reg(s
, rn
, addr
);
8111 tcg_temp_free_i32(addr
);
8113 gen_rfe(s
, tmp
, tmp2
);
8115 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8116 /* branch link and change to thumb (blx <offset>) */
8119 val
= (uint32_t)s
->pc
;
8120 tmp
= tcg_temp_new_i32();
8121 tcg_gen_movi_i32(tmp
, val
);
8122 store_reg(s
, 14, tmp
);
8123 /* Sign-extend the 24-bit offset */
8124 offset
= (((int32_t)insn
) << 8) >> 8;
8125 /* offset * 4 + bit24 * 2 + (thumb bit) */
8126 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8127 /* pipeline offset */
8129 /* protected by ARCH(5); above, near the start of uncond block */
8132 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8133 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8134 /* iWMMXt register transfer. */
8135 if (extract32(s
->c15_cpar
, 1, 1)) {
8136 if (!disas_iwmmxt_insn(s
, insn
)) {
8141 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8142 /* Coprocessor double register transfer. */
8144 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8145 /* Additional coprocessor register transfer. */
8146 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8149 /* cps (privileged) */
8153 if (insn
& (1 << 19)) {
8154 if (insn
& (1 << 8))
8156 if (insn
& (1 << 7))
8158 if (insn
& (1 << 6))
8160 if (insn
& (1 << 18))
8163 if (insn
& (1 << 17)) {
8165 val
|= (insn
& 0x1f);
8168 gen_set_psr_im(s
, mask
, 0, val
);
8175 /* if not always execute, we generate a conditional jump to
8177 s
->condlabel
= gen_new_label();
8178 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8181 if ((insn
& 0x0f900000) == 0x03000000) {
8182 if ((insn
& (1 << 21)) == 0) {
8184 rd
= (insn
>> 12) & 0xf;
8185 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8186 if ((insn
& (1 << 22)) == 0) {
8188 tmp
= tcg_temp_new_i32();
8189 tcg_gen_movi_i32(tmp
, val
);
8192 tmp
= load_reg(s
, rd
);
8193 tcg_gen_ext16u_i32(tmp
, tmp
);
8194 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8196 store_reg(s
, rd
, tmp
);
8198 if (((insn
>> 12) & 0xf) != 0xf)
8200 if (((insn
>> 16) & 0xf) == 0) {
8201 gen_nop_hint(s
, insn
& 0xff);
8203 /* CPSR = immediate */
8205 shift
= ((insn
>> 8) & 0xf) * 2;
8207 val
= (val
>> shift
) | (val
<< (32 - shift
));
8208 i
= ((insn
& (1 << 22)) != 0);
8209 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8215 } else if ((insn
& 0x0f900000) == 0x01000000
8216 && (insn
& 0x00000090) != 0x00000090) {
8217 /* miscellaneous instructions */
8218 op1
= (insn
>> 21) & 3;
8219 sh
= (insn
>> 4) & 0xf;
8222 case 0x0: /* MSR, MRS */
8223 if (insn
& (1 << 9)) {
8224 /* MSR (banked) and MRS (banked) */
8225 int sysm
= extract32(insn
, 16, 4) |
8226 (extract32(insn
, 8, 1) << 4);
8227 int r
= extract32(insn
, 22, 1);
8231 gen_msr_banked(s
, r
, sysm
, rm
);
8234 int rd
= extract32(insn
, 12, 4);
8236 gen_mrs_banked(s
, r
, sysm
, rd
);
8241 /* MSR, MRS (for PSRs) */
8244 tmp
= load_reg(s
, rm
);
8245 i
= ((op1
& 2) != 0);
8246 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8250 rd
= (insn
>> 12) & 0xf;
8254 tmp
= load_cpu_field(spsr
);
8256 tmp
= tcg_temp_new_i32();
8257 gen_helper_cpsr_read(tmp
, cpu_env
);
8259 store_reg(s
, rd
, tmp
);
8264 /* branch/exchange thumb (bx). */
8266 tmp
= load_reg(s
, rm
);
8268 } else if (op1
== 3) {
8271 rd
= (insn
>> 12) & 0xf;
8272 tmp
= load_reg(s
, rm
);
8273 gen_helper_clz(tmp
, tmp
);
8274 store_reg(s
, rd
, tmp
);
8282 /* Trivial implementation equivalent to bx. */
8283 tmp
= load_reg(s
, rm
);
8294 /* branch link/exchange thumb (blx) */
8295 tmp
= load_reg(s
, rm
);
8296 tmp2
= tcg_temp_new_i32();
8297 tcg_gen_movi_i32(tmp2
, s
->pc
);
8298 store_reg(s
, 14, tmp2
);
8304 uint32_t c
= extract32(insn
, 8, 4);
8306 /* Check this CPU supports ARMv8 CRC instructions.
8307 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8308 * Bits 8, 10 and 11 should be zero.
8310 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8315 rn
= extract32(insn
, 16, 4);
8316 rd
= extract32(insn
, 12, 4);
8318 tmp
= load_reg(s
, rn
);
8319 tmp2
= load_reg(s
, rm
);
8321 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8322 } else if (op1
== 1) {
8323 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8325 tmp3
= tcg_const_i32(1 << op1
);
8327 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8329 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8331 tcg_temp_free_i32(tmp2
);
8332 tcg_temp_free_i32(tmp3
);
8333 store_reg(s
, rd
, tmp
);
8336 case 0x5: /* saturating add/subtract */
8338 rd
= (insn
>> 12) & 0xf;
8339 rn
= (insn
>> 16) & 0xf;
8340 tmp
= load_reg(s
, rm
);
8341 tmp2
= load_reg(s
, rn
);
8343 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8345 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8347 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8348 tcg_temp_free_i32(tmp2
);
8349 store_reg(s
, rd
, tmp
);
8353 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8358 gen_exception_insn(s
, 4, EXCP_BKPT
,
8359 syn_aa32_bkpt(imm16
, false),
8360 default_exception_el(s
));
8363 /* Hypervisor call (v7) */
8371 /* Secure monitor call (v6+) */
8383 case 0x8: /* signed multiply */
8388 rs
= (insn
>> 8) & 0xf;
8389 rn
= (insn
>> 12) & 0xf;
8390 rd
= (insn
>> 16) & 0xf;
8392 /* (32 * 16) >> 16 */
8393 tmp
= load_reg(s
, rm
);
8394 tmp2
= load_reg(s
, rs
);
8396 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8399 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8400 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8401 tmp
= tcg_temp_new_i32();
8402 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8403 tcg_temp_free_i64(tmp64
);
8404 if ((sh
& 2) == 0) {
8405 tmp2
= load_reg(s
, rn
);
8406 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8407 tcg_temp_free_i32(tmp2
);
8409 store_reg(s
, rd
, tmp
);
8412 tmp
= load_reg(s
, rm
);
8413 tmp2
= load_reg(s
, rs
);
8414 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8415 tcg_temp_free_i32(tmp2
);
8417 tmp64
= tcg_temp_new_i64();
8418 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8419 tcg_temp_free_i32(tmp
);
8420 gen_addq(s
, tmp64
, rn
, rd
);
8421 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8422 tcg_temp_free_i64(tmp64
);
8425 tmp2
= load_reg(s
, rn
);
8426 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8427 tcg_temp_free_i32(tmp2
);
8429 store_reg(s
, rd
, tmp
);
8436 } else if (((insn
& 0x0e000000) == 0 &&
8437 (insn
& 0x00000090) != 0x90) ||
8438 ((insn
& 0x0e000000) == (1 << 25))) {
8439 int set_cc
, logic_cc
, shiftop
;
8441 op1
= (insn
>> 21) & 0xf;
8442 set_cc
= (insn
>> 20) & 1;
8443 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8445 /* data processing instruction */
8446 if (insn
& (1 << 25)) {
8447 /* immediate operand */
8449 shift
= ((insn
>> 8) & 0xf) * 2;
8451 val
= (val
>> shift
) | (val
<< (32 - shift
));
8453 tmp2
= tcg_temp_new_i32();
8454 tcg_gen_movi_i32(tmp2
, val
);
8455 if (logic_cc
&& shift
) {
8456 gen_set_CF_bit31(tmp2
);
8461 tmp2
= load_reg(s
, rm
);
8462 shiftop
= (insn
>> 5) & 3;
8463 if (!(insn
& (1 << 4))) {
8464 shift
= (insn
>> 7) & 0x1f;
8465 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8467 rs
= (insn
>> 8) & 0xf;
8468 tmp
= load_reg(s
, rs
);
8469 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8472 if (op1
!= 0x0f && op1
!= 0x0d) {
8473 rn
= (insn
>> 16) & 0xf;
8474 tmp
= load_reg(s
, rn
);
8476 TCGV_UNUSED_I32(tmp
);
8478 rd
= (insn
>> 12) & 0xf;
8481 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8485 store_reg_bx(s
, rd
, tmp
);
8488 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8492 store_reg_bx(s
, rd
, tmp
);
8495 if (set_cc
&& rd
== 15) {
8496 /* SUBS r15, ... is used for exception return. */
8500 gen_sub_CC(tmp
, tmp
, tmp2
);
8501 gen_exception_return(s
, tmp
);
8504 gen_sub_CC(tmp
, tmp
, tmp2
);
8506 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8508 store_reg_bx(s
, rd
, tmp
);
8513 gen_sub_CC(tmp
, tmp2
, tmp
);
8515 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8517 store_reg_bx(s
, rd
, tmp
);
8521 gen_add_CC(tmp
, tmp
, tmp2
);
8523 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8525 store_reg_bx(s
, rd
, tmp
);
8529 gen_adc_CC(tmp
, tmp
, tmp2
);
8531 gen_add_carry(tmp
, tmp
, tmp2
);
8533 store_reg_bx(s
, rd
, tmp
);
8537 gen_sbc_CC(tmp
, tmp
, tmp2
);
8539 gen_sub_carry(tmp
, tmp
, tmp2
);
8541 store_reg_bx(s
, rd
, tmp
);
8545 gen_sbc_CC(tmp
, tmp2
, tmp
);
8547 gen_sub_carry(tmp
, tmp2
, tmp
);
8549 store_reg_bx(s
, rd
, tmp
);
8553 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8556 tcg_temp_free_i32(tmp
);
8560 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8563 tcg_temp_free_i32(tmp
);
8567 gen_sub_CC(tmp
, tmp
, tmp2
);
8569 tcg_temp_free_i32(tmp
);
8573 gen_add_CC(tmp
, tmp
, tmp2
);
8575 tcg_temp_free_i32(tmp
);
8578 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8582 store_reg_bx(s
, rd
, tmp
);
8585 if (logic_cc
&& rd
== 15) {
8586 /* MOVS r15, ... is used for exception return. */
8590 gen_exception_return(s
, tmp2
);
8595 store_reg_bx(s
, rd
, tmp2
);
8599 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8603 store_reg_bx(s
, rd
, tmp
);
8607 tcg_gen_not_i32(tmp2
, tmp2
);
8611 store_reg_bx(s
, rd
, tmp2
);
8614 if (op1
!= 0x0f && op1
!= 0x0d) {
8615 tcg_temp_free_i32(tmp2
);
8618 /* other instructions */
8619 op1
= (insn
>> 24) & 0xf;
8623 /* multiplies, extra load/stores */
8624 sh
= (insn
>> 5) & 3;
8627 rd
= (insn
>> 16) & 0xf;
8628 rn
= (insn
>> 12) & 0xf;
8629 rs
= (insn
>> 8) & 0xf;
8631 op1
= (insn
>> 20) & 0xf;
8633 case 0: case 1: case 2: case 3: case 6:
8635 tmp
= load_reg(s
, rs
);
8636 tmp2
= load_reg(s
, rm
);
8637 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8638 tcg_temp_free_i32(tmp2
);
8639 if (insn
& (1 << 22)) {
8640 /* Subtract (mls) */
8642 tmp2
= load_reg(s
, rn
);
8643 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8644 tcg_temp_free_i32(tmp2
);
8645 } else if (insn
& (1 << 21)) {
8647 tmp2
= load_reg(s
, rn
);
8648 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8649 tcg_temp_free_i32(tmp2
);
8651 if (insn
& (1 << 20))
8653 store_reg(s
, rd
, tmp
);
8656 /* 64 bit mul double accumulate (UMAAL) */
8658 tmp
= load_reg(s
, rs
);
8659 tmp2
= load_reg(s
, rm
);
8660 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8661 gen_addq_lo(s
, tmp64
, rn
);
8662 gen_addq_lo(s
, tmp64
, rd
);
8663 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8664 tcg_temp_free_i64(tmp64
);
8666 case 8: case 9: case 10: case 11:
8667 case 12: case 13: case 14: case 15:
8668 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8669 tmp
= load_reg(s
, rs
);
8670 tmp2
= load_reg(s
, rm
);
8671 if (insn
& (1 << 22)) {
8672 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8674 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8676 if (insn
& (1 << 21)) { /* mult accumulate */
8677 TCGv_i32 al
= load_reg(s
, rn
);
8678 TCGv_i32 ah
= load_reg(s
, rd
);
8679 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8680 tcg_temp_free_i32(al
);
8681 tcg_temp_free_i32(ah
);
8683 if (insn
& (1 << 20)) {
8684 gen_logicq_cc(tmp
, tmp2
);
8686 store_reg(s
, rn
, tmp
);
8687 store_reg(s
, rd
, tmp2
);
8693 rn
= (insn
>> 16) & 0xf;
8694 rd
= (insn
>> 12) & 0xf;
8695 if (insn
& (1 << 23)) {
8696 /* load/store exclusive */
8697 int op2
= (insn
>> 8) & 3;
8698 op1
= (insn
>> 21) & 0x3;
8701 case 0: /* lda/stl */
8707 case 1: /* reserved */
8709 case 2: /* ldaex/stlex */
8712 case 3: /* ldrex/strex */
8721 addr
= tcg_temp_local_new_i32();
8722 load_reg_var(s
, addr
, rn
);
8724 /* Since the emulation does not have barriers,
8725 the acquire/release semantics need no special
8728 if (insn
& (1 << 20)) {
8729 tmp
= tcg_temp_new_i32();
8732 gen_aa32_ld32u(s
, tmp
, addr
,
8736 gen_aa32_ld8u(s
, tmp
, addr
,
8740 gen_aa32_ld16u(s
, tmp
, addr
,
8746 store_reg(s
, rd
, tmp
);
8749 tmp
= load_reg(s
, rm
);
8752 gen_aa32_st32(s
, tmp
, addr
,
8756 gen_aa32_st8(s
, tmp
, addr
,
8760 gen_aa32_st16(s
, tmp
, addr
,
8766 tcg_temp_free_i32(tmp
);
8768 } else if (insn
& (1 << 20)) {
8771 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8773 case 1: /* ldrexd */
8774 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8776 case 2: /* ldrexb */
8777 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8779 case 3: /* ldrexh */
8780 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8789 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8791 case 1: /* strexd */
8792 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8794 case 2: /* strexb */
8795 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8797 case 3: /* strexh */
8798 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8804 tcg_temp_free_i32(addr
);
8806 /* SWP instruction */
8809 /* ??? This is not really atomic. However we know
8810 we never have multiple CPUs running in parallel,
8811 so it is good enough. */
8812 addr
= load_reg(s
, rn
);
8813 tmp
= load_reg(s
, rm
);
8814 tmp2
= tcg_temp_new_i32();
8815 if (insn
& (1 << 22)) {
8816 gen_aa32_ld8u(s
, tmp2
, addr
, get_mem_index(s
));
8817 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
8819 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8820 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8822 tcg_temp_free_i32(tmp
);
8823 tcg_temp_free_i32(addr
);
8824 store_reg(s
, rd
, tmp2
);
8829 bool load
= insn
& (1 << 20);
8830 bool doubleword
= false;
8831 /* Misc load/store */
8832 rn
= (insn
>> 16) & 0xf;
8833 rd
= (insn
>> 12) & 0xf;
8835 if (!load
&& (sh
& 2)) {
8839 /* UNPREDICTABLE; we choose to UNDEF */
8842 load
= (sh
& 1) == 0;
8846 addr
= load_reg(s
, rn
);
8847 if (insn
& (1 << 24))
8848 gen_add_datah_offset(s
, insn
, 0, addr
);
8854 tmp
= load_reg(s
, rd
);
8855 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8856 tcg_temp_free_i32(tmp
);
8857 tcg_gen_addi_i32(addr
, addr
, 4);
8858 tmp
= load_reg(s
, rd
+ 1);
8859 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8860 tcg_temp_free_i32(tmp
);
8863 tmp
= tcg_temp_new_i32();
8864 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8865 store_reg(s
, rd
, tmp
);
8866 tcg_gen_addi_i32(addr
, addr
, 4);
8867 tmp
= tcg_temp_new_i32();
8868 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8871 address_offset
= -4;
8874 tmp
= tcg_temp_new_i32();
8877 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
8880 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
8884 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
8889 tmp
= load_reg(s
, rd
);
8890 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
8891 tcg_temp_free_i32(tmp
);
8893 /* Perform base writeback before the loaded value to
8894 ensure correct behavior with overlapping index registers.
8895 ldrd with base writeback is undefined if the
8896 destination and index registers overlap. */
8897 if (!(insn
& (1 << 24))) {
8898 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8899 store_reg(s
, rn
, addr
);
8900 } else if (insn
& (1 << 21)) {
8902 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8903 store_reg(s
, rn
, addr
);
8905 tcg_temp_free_i32(addr
);
8908 /* Complete the load. */
8909 store_reg(s
, rd
, tmp
);
8918 if (insn
& (1 << 4)) {
8920 /* Armv6 Media instructions. */
8922 rn
= (insn
>> 16) & 0xf;
8923 rd
= (insn
>> 12) & 0xf;
8924 rs
= (insn
>> 8) & 0xf;
8925 switch ((insn
>> 23) & 3) {
8926 case 0: /* Parallel add/subtract. */
8927 op1
= (insn
>> 20) & 7;
8928 tmp
= load_reg(s
, rn
);
8929 tmp2
= load_reg(s
, rm
);
8930 sh
= (insn
>> 5) & 7;
8931 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8933 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8934 tcg_temp_free_i32(tmp2
);
8935 store_reg(s
, rd
, tmp
);
8938 if ((insn
& 0x00700020) == 0) {
8939 /* Halfword pack. */
8940 tmp
= load_reg(s
, rn
);
8941 tmp2
= load_reg(s
, rm
);
8942 shift
= (insn
>> 7) & 0x1f;
8943 if (insn
& (1 << 6)) {
8947 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8948 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8949 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8953 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8954 tcg_gen_ext16u_i32(tmp
, tmp
);
8955 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8957 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8958 tcg_temp_free_i32(tmp2
);
8959 store_reg(s
, rd
, tmp
);
8960 } else if ((insn
& 0x00200020) == 0x00200000) {
8962 tmp
= load_reg(s
, rm
);
8963 shift
= (insn
>> 7) & 0x1f;
8964 if (insn
& (1 << 6)) {
8967 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8969 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8971 sh
= (insn
>> 16) & 0x1f;
8972 tmp2
= tcg_const_i32(sh
);
8973 if (insn
& (1 << 22))
8974 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8976 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8977 tcg_temp_free_i32(tmp2
);
8978 store_reg(s
, rd
, tmp
);
8979 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8981 tmp
= load_reg(s
, rm
);
8982 sh
= (insn
>> 16) & 0x1f;
8983 tmp2
= tcg_const_i32(sh
);
8984 if (insn
& (1 << 22))
8985 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8987 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8988 tcg_temp_free_i32(tmp2
);
8989 store_reg(s
, rd
, tmp
);
8990 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8992 tmp
= load_reg(s
, rn
);
8993 tmp2
= load_reg(s
, rm
);
8994 tmp3
= tcg_temp_new_i32();
8995 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8996 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8997 tcg_temp_free_i32(tmp3
);
8998 tcg_temp_free_i32(tmp2
);
8999 store_reg(s
, rd
, tmp
);
9000 } else if ((insn
& 0x000003e0) == 0x00000060) {
9001 tmp
= load_reg(s
, rm
);
9002 shift
= (insn
>> 10) & 3;
9003 /* ??? In many cases it's not necessary to do a
9004 rotate, a shift is sufficient. */
9006 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9007 op1
= (insn
>> 20) & 7;
9009 case 0: gen_sxtb16(tmp
); break;
9010 case 2: gen_sxtb(tmp
); break;
9011 case 3: gen_sxth(tmp
); break;
9012 case 4: gen_uxtb16(tmp
); break;
9013 case 6: gen_uxtb(tmp
); break;
9014 case 7: gen_uxth(tmp
); break;
9015 default: goto illegal_op
;
9018 tmp2
= load_reg(s
, rn
);
9019 if ((op1
& 3) == 0) {
9020 gen_add16(tmp
, tmp2
);
9022 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9023 tcg_temp_free_i32(tmp2
);
9026 store_reg(s
, rd
, tmp
);
9027 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9029 tmp
= load_reg(s
, rm
);
9030 if (insn
& (1 << 22)) {
9031 if (insn
& (1 << 7)) {
9035 gen_helper_rbit(tmp
, tmp
);
9038 if (insn
& (1 << 7))
9041 tcg_gen_bswap32_i32(tmp
, tmp
);
9043 store_reg(s
, rd
, tmp
);
9048 case 2: /* Multiplies (Type 3). */
9049 switch ((insn
>> 20) & 0x7) {
9051 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9052 /* op2 not 00x or 11x : UNDEF */
9055 /* Signed multiply most significant [accumulate].
9056 (SMMUL, SMMLA, SMMLS) */
9057 tmp
= load_reg(s
, rm
);
9058 tmp2
= load_reg(s
, rs
);
9059 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9062 tmp
= load_reg(s
, rd
);
9063 if (insn
& (1 << 6)) {
9064 tmp64
= gen_subq_msw(tmp64
, tmp
);
9066 tmp64
= gen_addq_msw(tmp64
, tmp
);
9069 if (insn
& (1 << 5)) {
9070 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9072 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9073 tmp
= tcg_temp_new_i32();
9074 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9075 tcg_temp_free_i64(tmp64
);
9076 store_reg(s
, rn
, tmp
);
9080 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9081 if (insn
& (1 << 7)) {
9084 tmp
= load_reg(s
, rm
);
9085 tmp2
= load_reg(s
, rs
);
9086 if (insn
& (1 << 5))
9087 gen_swap_half(tmp2
);
9088 gen_smul_dual(tmp
, tmp2
);
9089 if (insn
& (1 << 22)) {
9090 /* smlald, smlsld */
9093 tmp64
= tcg_temp_new_i64();
9094 tmp64_2
= tcg_temp_new_i64();
9095 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9096 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9097 tcg_temp_free_i32(tmp
);
9098 tcg_temp_free_i32(tmp2
);
9099 if (insn
& (1 << 6)) {
9100 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9102 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9104 tcg_temp_free_i64(tmp64_2
);
9105 gen_addq(s
, tmp64
, rd
, rn
);
9106 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9107 tcg_temp_free_i64(tmp64
);
9109 /* smuad, smusd, smlad, smlsd */
9110 if (insn
& (1 << 6)) {
9111 /* This subtraction cannot overflow. */
9112 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9114 /* This addition cannot overflow 32 bits;
9115 * however it may overflow considered as a
9116 * signed operation, in which case we must set
9119 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9121 tcg_temp_free_i32(tmp2
);
9124 tmp2
= load_reg(s
, rd
);
9125 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9126 tcg_temp_free_i32(tmp2
);
9128 store_reg(s
, rn
, tmp
);
9134 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9137 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9140 tmp
= load_reg(s
, rm
);
9141 tmp2
= load_reg(s
, rs
);
9142 if (insn
& (1 << 21)) {
9143 gen_helper_udiv(tmp
, tmp
, tmp2
);
9145 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9147 tcg_temp_free_i32(tmp2
);
9148 store_reg(s
, rn
, tmp
);
9155 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9157 case 0: /* Unsigned sum of absolute differences. */
9159 tmp
= load_reg(s
, rm
);
9160 tmp2
= load_reg(s
, rs
);
9161 gen_helper_usad8(tmp
, tmp
, tmp2
);
9162 tcg_temp_free_i32(tmp2
);
9164 tmp2
= load_reg(s
, rd
);
9165 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9166 tcg_temp_free_i32(tmp2
);
9168 store_reg(s
, rn
, tmp
);
9170 case 0x20: case 0x24: case 0x28: case 0x2c:
9171 /* Bitfield insert/clear. */
9173 shift
= (insn
>> 7) & 0x1f;
9174 i
= (insn
>> 16) & 0x1f;
9176 /* UNPREDICTABLE; we choose to UNDEF */
9181 tmp
= tcg_temp_new_i32();
9182 tcg_gen_movi_i32(tmp
, 0);
9184 tmp
= load_reg(s
, rm
);
9187 tmp2
= load_reg(s
, rd
);
9188 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9189 tcg_temp_free_i32(tmp2
);
9191 store_reg(s
, rd
, tmp
);
9193 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9194 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9196 tmp
= load_reg(s
, rm
);
9197 shift
= (insn
>> 7) & 0x1f;
9198 i
= ((insn
>> 16) & 0x1f) + 1;
9203 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
9205 gen_sbfx(tmp
, shift
, i
);
9208 store_reg(s
, rd
, tmp
);
9218 /* Check for undefined extension instructions
9219 * per the ARM Bible IE:
9220 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9222 sh
= (0xf << 20) | (0xf << 4);
9223 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9227 /* load/store byte/word */
9228 rn
= (insn
>> 16) & 0xf;
9229 rd
= (insn
>> 12) & 0xf;
9230 tmp2
= load_reg(s
, rn
);
9231 if ((insn
& 0x01200000) == 0x00200000) {
9233 i
= get_a32_user_mem_index(s
);
9235 i
= get_mem_index(s
);
9237 if (insn
& (1 << 24))
9238 gen_add_data_offset(s
, insn
, tmp2
);
9239 if (insn
& (1 << 20)) {
9241 tmp
= tcg_temp_new_i32();
9242 if (insn
& (1 << 22)) {
9243 gen_aa32_ld8u(s
, tmp
, tmp2
, i
);
9245 gen_aa32_ld32u(s
, tmp
, tmp2
, i
);
9249 tmp
= load_reg(s
, rd
);
9250 if (insn
& (1 << 22)) {
9251 gen_aa32_st8(s
, tmp
, tmp2
, i
);
9253 gen_aa32_st32(s
, tmp
, tmp2
, i
);
9255 tcg_temp_free_i32(tmp
);
9257 if (!(insn
& (1 << 24))) {
9258 gen_add_data_offset(s
, insn
, tmp2
);
9259 store_reg(s
, rn
, tmp2
);
9260 } else if (insn
& (1 << 21)) {
9261 store_reg(s
, rn
, tmp2
);
9263 tcg_temp_free_i32(tmp2
);
9265 if (insn
& (1 << 20)) {
9266 /* Complete the load. */
9267 store_reg_from_load(s
, rd
, tmp
);
9273 int j
, n
, loaded_base
;
9274 bool exc_return
= false;
9275 bool is_load
= extract32(insn
, 20, 1);
9277 TCGv_i32 loaded_var
;
9278 /* load/store multiple words */
9279 /* XXX: store correct base if write back */
9280 if (insn
& (1 << 22)) {
9281 /* LDM (user), LDM (exception return) and STM (user) */
9283 goto illegal_op
; /* only usable in supervisor mode */
9285 if (is_load
&& extract32(insn
, 15, 1)) {
9291 rn
= (insn
>> 16) & 0xf;
9292 addr
= load_reg(s
, rn
);
9294 /* compute total size */
9296 TCGV_UNUSED_I32(loaded_var
);
9299 if (insn
& (1 << i
))
9302 /* XXX: test invalid n == 0 case ? */
9303 if (insn
& (1 << 23)) {
9304 if (insn
& (1 << 24)) {
9306 tcg_gen_addi_i32(addr
, addr
, 4);
9308 /* post increment */
9311 if (insn
& (1 << 24)) {
9313 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9315 /* post decrement */
9317 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9322 if (insn
& (1 << i
)) {
9325 tmp
= tcg_temp_new_i32();
9326 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9328 tmp2
= tcg_const_i32(i
);
9329 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9330 tcg_temp_free_i32(tmp2
);
9331 tcg_temp_free_i32(tmp
);
9332 } else if (i
== rn
) {
9336 store_reg_from_load(s
, i
, tmp
);
9341 /* special case: r15 = PC + 8 */
9342 val
= (long)s
->pc
+ 4;
9343 tmp
= tcg_temp_new_i32();
9344 tcg_gen_movi_i32(tmp
, val
);
9346 tmp
= tcg_temp_new_i32();
9347 tmp2
= tcg_const_i32(i
);
9348 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9349 tcg_temp_free_i32(tmp2
);
9351 tmp
= load_reg(s
, i
);
9353 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9354 tcg_temp_free_i32(tmp
);
9357 /* no need to add after the last transfer */
9359 tcg_gen_addi_i32(addr
, addr
, 4);
9362 if (insn
& (1 << 21)) {
9364 if (insn
& (1 << 23)) {
9365 if (insn
& (1 << 24)) {
9368 /* post increment */
9369 tcg_gen_addi_i32(addr
, addr
, 4);
9372 if (insn
& (1 << 24)) {
9375 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9377 /* post decrement */
9378 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9381 store_reg(s
, rn
, addr
);
9383 tcg_temp_free_i32(addr
);
9386 store_reg(s
, rn
, loaded_var
);
9389 /* Restore CPSR from SPSR. */
9390 tmp
= load_cpu_field(spsr
);
9391 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9392 tcg_temp_free_i32(tmp
);
9393 s
->is_jmp
= DISAS_JUMP
;
9402 /* branch (and link) */
9403 val
= (int32_t)s
->pc
;
9404 if (insn
& (1 << 24)) {
9405 tmp
= tcg_temp_new_i32();
9406 tcg_gen_movi_i32(tmp
, val
);
9407 store_reg(s
, 14, tmp
);
9409 offset
= sextract32(insn
<< 2, 0, 26);
9417 if (((insn
>> 8) & 0xe) == 10) {
9419 if (disas_vfp_insn(s
, insn
)) {
9422 } else if (disas_coproc_insn(s
, insn
)) {
9429 gen_set_pc_im(s
, s
->pc
);
9430 s
->svc_imm
= extract32(insn
, 0, 24);
9431 s
->is_jmp
= DISAS_SWI
;
9435 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9436 default_exception_el(s
));
9442 /* Return true if this is a Thumb-2 logical op. */
9444 thumb2_logic_op(int op
)
9449 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9450 then set condition code flags based on the result of the operation.
9451 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9452 to the high bit of T1.
9453 Returns zero if the opcode is valid. */
9456 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9457 TCGv_i32 t0
, TCGv_i32 t1
)
9464 tcg_gen_and_i32(t0
, t0
, t1
);
9468 tcg_gen_andc_i32(t0
, t0
, t1
);
9472 tcg_gen_or_i32(t0
, t0
, t1
);
9476 tcg_gen_orc_i32(t0
, t0
, t1
);
9480 tcg_gen_xor_i32(t0
, t0
, t1
);
9485 gen_add_CC(t0
, t0
, t1
);
9487 tcg_gen_add_i32(t0
, t0
, t1
);
9491 gen_adc_CC(t0
, t0
, t1
);
9497 gen_sbc_CC(t0
, t0
, t1
);
9499 gen_sub_carry(t0
, t0
, t1
);
9504 gen_sub_CC(t0
, t0
, t1
);
9506 tcg_gen_sub_i32(t0
, t0
, t1
);
9510 gen_sub_CC(t0
, t1
, t0
);
9512 tcg_gen_sub_i32(t0
, t1
, t0
);
9514 default: /* 5, 6, 7, 9, 12, 15. */
9520 gen_set_CF_bit31(t1
);
9525 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9527 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9529 uint32_t insn
, imm
, shift
, offset
;
9530 uint32_t rd
, rn
, rm
, rs
;
9541 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9542 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9543 /* Thumb-1 cores may need to treat bl and blx as a pair of
9544 16-bit instructions to get correct prefetch abort behavior. */
9546 if ((insn
& (1 << 12)) == 0) {
9548 /* Second half of blx. */
9549 offset
= ((insn
& 0x7ff) << 1);
9550 tmp
= load_reg(s
, 14);
9551 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9552 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9554 tmp2
= tcg_temp_new_i32();
9555 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9556 store_reg(s
, 14, tmp2
);
9560 if (insn
& (1 << 11)) {
9561 /* Second half of bl. */
9562 offset
= ((insn
& 0x7ff) << 1) | 1;
9563 tmp
= load_reg(s
, 14);
9564 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9566 tmp2
= tcg_temp_new_i32();
9567 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9568 store_reg(s
, 14, tmp2
);
9572 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9573 /* Instruction spans a page boundary. Implement it as two
9574 16-bit instructions in case the second half causes an
9576 offset
= ((int32_t)insn
<< 21) >> 9;
9577 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9580 /* Fall through to 32-bit decode. */
9583 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9585 insn
|= (uint32_t)insn_hw1
<< 16;
9587 if ((insn
& 0xf800e800) != 0xf000e800) {
9591 rn
= (insn
>> 16) & 0xf;
9592 rs
= (insn
>> 12) & 0xf;
9593 rd
= (insn
>> 8) & 0xf;
9595 switch ((insn
>> 25) & 0xf) {
9596 case 0: case 1: case 2: case 3:
9597 /* 16-bit instructions. Should never happen. */
9600 if (insn
& (1 << 22)) {
9601 /* Other load/store, table branch. */
9602 if (insn
& 0x01200000) {
9603 /* Load/store doubleword. */
9605 addr
= tcg_temp_new_i32();
9606 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9608 addr
= load_reg(s
, rn
);
9610 offset
= (insn
& 0xff) * 4;
9611 if ((insn
& (1 << 23)) == 0)
9613 if (insn
& (1 << 24)) {
9614 tcg_gen_addi_i32(addr
, addr
, offset
);
9617 if (insn
& (1 << 20)) {
9619 tmp
= tcg_temp_new_i32();
9620 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9621 store_reg(s
, rs
, tmp
);
9622 tcg_gen_addi_i32(addr
, addr
, 4);
9623 tmp
= tcg_temp_new_i32();
9624 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9625 store_reg(s
, rd
, tmp
);
9628 tmp
= load_reg(s
, rs
);
9629 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9630 tcg_temp_free_i32(tmp
);
9631 tcg_gen_addi_i32(addr
, addr
, 4);
9632 tmp
= load_reg(s
, rd
);
9633 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9634 tcg_temp_free_i32(tmp
);
9636 if (insn
& (1 << 21)) {
9637 /* Base writeback. */
9640 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9641 store_reg(s
, rn
, addr
);
9643 tcg_temp_free_i32(addr
);
9645 } else if ((insn
& (1 << 23)) == 0) {
9646 /* Load/store exclusive word. */
9647 addr
= tcg_temp_local_new_i32();
9648 load_reg_var(s
, addr
, rn
);
9649 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9650 if (insn
& (1 << 20)) {
9651 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9653 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9655 tcg_temp_free_i32(addr
);
9656 } else if ((insn
& (7 << 5)) == 0) {
9659 addr
= tcg_temp_new_i32();
9660 tcg_gen_movi_i32(addr
, s
->pc
);
9662 addr
= load_reg(s
, rn
);
9664 tmp
= load_reg(s
, rm
);
9665 tcg_gen_add_i32(addr
, addr
, tmp
);
9666 if (insn
& (1 << 4)) {
9668 tcg_gen_add_i32(addr
, addr
, tmp
);
9669 tcg_temp_free_i32(tmp
);
9670 tmp
= tcg_temp_new_i32();
9671 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9673 tcg_temp_free_i32(tmp
);
9674 tmp
= tcg_temp_new_i32();
9675 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9677 tcg_temp_free_i32(addr
);
9678 tcg_gen_shli_i32(tmp
, tmp
, 1);
9679 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9680 store_reg(s
, 15, tmp
);
9682 int op2
= (insn
>> 6) & 0x3;
9683 op
= (insn
>> 4) & 0x3;
9688 /* Load/store exclusive byte/halfword/doubleword */
9695 /* Load-acquire/store-release */
9701 /* Load-acquire/store-release exclusive */
9705 addr
= tcg_temp_local_new_i32();
9706 load_reg_var(s
, addr
, rn
);
9708 if (insn
& (1 << 20)) {
9709 tmp
= tcg_temp_new_i32();
9712 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9715 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9718 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9723 store_reg(s
, rs
, tmp
);
9725 tmp
= load_reg(s
, rs
);
9728 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
9731 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
9734 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9739 tcg_temp_free_i32(tmp
);
9741 } else if (insn
& (1 << 20)) {
9742 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9744 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9746 tcg_temp_free_i32(addr
);
9749 /* Load/store multiple, RFE, SRS. */
9750 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9751 /* RFE, SRS: not available in user mode or on M profile */
9752 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9755 if (insn
& (1 << 20)) {
9757 addr
= load_reg(s
, rn
);
9758 if ((insn
& (1 << 24)) == 0)
9759 tcg_gen_addi_i32(addr
, addr
, -8);
9760 /* Load PC into tmp and CPSR into tmp2. */
9761 tmp
= tcg_temp_new_i32();
9762 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9763 tcg_gen_addi_i32(addr
, addr
, 4);
9764 tmp2
= tcg_temp_new_i32();
9765 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9766 if (insn
& (1 << 21)) {
9767 /* Base writeback. */
9768 if (insn
& (1 << 24)) {
9769 tcg_gen_addi_i32(addr
, addr
, 4);
9771 tcg_gen_addi_i32(addr
, addr
, -4);
9773 store_reg(s
, rn
, addr
);
9775 tcg_temp_free_i32(addr
);
9777 gen_rfe(s
, tmp
, tmp2
);
9780 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9784 int i
, loaded_base
= 0;
9785 TCGv_i32 loaded_var
;
9786 /* Load/store multiple. */
9787 addr
= load_reg(s
, rn
);
9789 for (i
= 0; i
< 16; i
++) {
9790 if (insn
& (1 << i
))
9793 if (insn
& (1 << 24)) {
9794 tcg_gen_addi_i32(addr
, addr
, -offset
);
9797 TCGV_UNUSED_I32(loaded_var
);
9798 for (i
= 0; i
< 16; i
++) {
9799 if ((insn
& (1 << i
)) == 0)
9801 if (insn
& (1 << 20)) {
9803 tmp
= tcg_temp_new_i32();
9804 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9807 } else if (i
== rn
) {
9811 store_reg(s
, i
, tmp
);
9815 tmp
= load_reg(s
, i
);
9816 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9817 tcg_temp_free_i32(tmp
);
9819 tcg_gen_addi_i32(addr
, addr
, 4);
9822 store_reg(s
, rn
, loaded_var
);
9824 if (insn
& (1 << 21)) {
9825 /* Base register writeback. */
9826 if (insn
& (1 << 24)) {
9827 tcg_gen_addi_i32(addr
, addr
, -offset
);
9829 /* Fault if writeback register is in register list. */
9830 if (insn
& (1 << rn
))
9832 store_reg(s
, rn
, addr
);
9834 tcg_temp_free_i32(addr
);
9841 op
= (insn
>> 21) & 0xf;
9843 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9846 /* Halfword pack. */
9847 tmp
= load_reg(s
, rn
);
9848 tmp2
= load_reg(s
, rm
);
9849 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9850 if (insn
& (1 << 5)) {
9854 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9855 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9856 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9860 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9861 tcg_gen_ext16u_i32(tmp
, tmp
);
9862 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9864 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9865 tcg_temp_free_i32(tmp2
);
9866 store_reg(s
, rd
, tmp
);
9868 /* Data processing register constant shift. */
9870 tmp
= tcg_temp_new_i32();
9871 tcg_gen_movi_i32(tmp
, 0);
9873 tmp
= load_reg(s
, rn
);
9875 tmp2
= load_reg(s
, rm
);
9877 shiftop
= (insn
>> 4) & 3;
9878 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9879 conds
= (insn
& (1 << 20)) != 0;
9880 logic_cc
= (conds
&& thumb2_logic_op(op
));
9881 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9882 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9884 tcg_temp_free_i32(tmp2
);
9886 store_reg(s
, rd
, tmp
);
9888 tcg_temp_free_i32(tmp
);
9892 case 13: /* Misc data processing. */
9893 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9894 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9897 case 0: /* Register controlled shift. */
9898 tmp
= load_reg(s
, rn
);
9899 tmp2
= load_reg(s
, rm
);
9900 if ((insn
& 0x70) != 0)
9902 op
= (insn
>> 21) & 3;
9903 logic_cc
= (insn
& (1 << 20)) != 0;
9904 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9907 store_reg_bx(s
, rd
, tmp
);
9909 case 1: /* Sign/zero extend. */
9910 op
= (insn
>> 20) & 7;
9912 case 0: /* SXTAH, SXTH */
9913 case 1: /* UXTAH, UXTH */
9914 case 4: /* SXTAB, SXTB */
9915 case 5: /* UXTAB, UXTB */
9917 case 2: /* SXTAB16, SXTB16 */
9918 case 3: /* UXTAB16, UXTB16 */
9919 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9927 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9931 tmp
= load_reg(s
, rm
);
9932 shift
= (insn
>> 4) & 3;
9933 /* ??? In many cases it's not necessary to do a
9934 rotate, a shift is sufficient. */
9936 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9937 op
= (insn
>> 20) & 7;
9939 case 0: gen_sxth(tmp
); break;
9940 case 1: gen_uxth(tmp
); break;
9941 case 2: gen_sxtb16(tmp
); break;
9942 case 3: gen_uxtb16(tmp
); break;
9943 case 4: gen_sxtb(tmp
); break;
9944 case 5: gen_uxtb(tmp
); break;
9946 g_assert_not_reached();
9949 tmp2
= load_reg(s
, rn
);
9950 if ((op
>> 1) == 1) {
9951 gen_add16(tmp
, tmp2
);
9953 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9954 tcg_temp_free_i32(tmp2
);
9957 store_reg(s
, rd
, tmp
);
9959 case 2: /* SIMD add/subtract. */
9960 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9963 op
= (insn
>> 20) & 7;
9964 shift
= (insn
>> 4) & 7;
9965 if ((op
& 3) == 3 || (shift
& 3) == 3)
9967 tmp
= load_reg(s
, rn
);
9968 tmp2
= load_reg(s
, rm
);
9969 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9970 tcg_temp_free_i32(tmp2
);
9971 store_reg(s
, rd
, tmp
);
9973 case 3: /* Other data processing. */
9974 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9976 /* Saturating add/subtract. */
9977 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9980 tmp
= load_reg(s
, rn
);
9981 tmp2
= load_reg(s
, rm
);
9983 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9985 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9987 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9988 tcg_temp_free_i32(tmp2
);
9991 case 0x0a: /* rbit */
9992 case 0x08: /* rev */
9993 case 0x09: /* rev16 */
9994 case 0x0b: /* revsh */
9995 case 0x18: /* clz */
9997 case 0x10: /* sel */
9998 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10002 case 0x20: /* crc32/crc32c */
10008 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10015 tmp
= load_reg(s
, rn
);
10017 case 0x0a: /* rbit */
10018 gen_helper_rbit(tmp
, tmp
);
10020 case 0x08: /* rev */
10021 tcg_gen_bswap32_i32(tmp
, tmp
);
10023 case 0x09: /* rev16 */
10026 case 0x0b: /* revsh */
10029 case 0x10: /* sel */
10030 tmp2
= load_reg(s
, rm
);
10031 tmp3
= tcg_temp_new_i32();
10032 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10033 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10034 tcg_temp_free_i32(tmp3
);
10035 tcg_temp_free_i32(tmp2
);
10037 case 0x18: /* clz */
10038 gen_helper_clz(tmp
, tmp
);
10048 uint32_t sz
= op
& 0x3;
10049 uint32_t c
= op
& 0x8;
10051 tmp2
= load_reg(s
, rm
);
10053 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10054 } else if (sz
== 1) {
10055 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10057 tmp3
= tcg_const_i32(1 << sz
);
10059 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10061 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10063 tcg_temp_free_i32(tmp2
);
10064 tcg_temp_free_i32(tmp3
);
10068 g_assert_not_reached();
10071 store_reg(s
, rd
, tmp
);
10073 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10074 switch ((insn
>> 20) & 7) {
10075 case 0: /* 32 x 32 -> 32 */
10076 case 7: /* Unsigned sum of absolute differences. */
10078 case 1: /* 16 x 16 -> 32 */
10079 case 2: /* Dual multiply add. */
10080 case 3: /* 32 * 16 -> 32msb */
10081 case 4: /* Dual multiply subtract. */
10082 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10083 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10088 op
= (insn
>> 4) & 0xf;
10089 tmp
= load_reg(s
, rn
);
10090 tmp2
= load_reg(s
, rm
);
10091 switch ((insn
>> 20) & 7) {
10092 case 0: /* 32 x 32 -> 32 */
10093 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10094 tcg_temp_free_i32(tmp2
);
10096 tmp2
= load_reg(s
, rs
);
10098 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10100 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10101 tcg_temp_free_i32(tmp2
);
10104 case 1: /* 16 x 16 -> 32 */
10105 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10106 tcg_temp_free_i32(tmp2
);
10108 tmp2
= load_reg(s
, rs
);
10109 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10110 tcg_temp_free_i32(tmp2
);
10113 case 2: /* Dual multiply add. */
10114 case 4: /* Dual multiply subtract. */
10116 gen_swap_half(tmp2
);
10117 gen_smul_dual(tmp
, tmp2
);
10118 if (insn
& (1 << 22)) {
10119 /* This subtraction cannot overflow. */
10120 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10122 /* This addition cannot overflow 32 bits;
10123 * however it may overflow considered as a signed
10124 * operation, in which case we must set the Q flag.
10126 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10128 tcg_temp_free_i32(tmp2
);
10131 tmp2
= load_reg(s
, rs
);
10132 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10133 tcg_temp_free_i32(tmp2
);
10136 case 3: /* 32 * 16 -> 32msb */
10138 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10141 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10142 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10143 tmp
= tcg_temp_new_i32();
10144 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10145 tcg_temp_free_i64(tmp64
);
10148 tmp2
= load_reg(s
, rs
);
10149 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10150 tcg_temp_free_i32(tmp2
);
10153 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10154 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10156 tmp
= load_reg(s
, rs
);
10157 if (insn
& (1 << 20)) {
10158 tmp64
= gen_addq_msw(tmp64
, tmp
);
10160 tmp64
= gen_subq_msw(tmp64
, tmp
);
10163 if (insn
& (1 << 4)) {
10164 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10166 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10167 tmp
= tcg_temp_new_i32();
10168 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10169 tcg_temp_free_i64(tmp64
);
10171 case 7: /* Unsigned sum of absolute differences. */
10172 gen_helper_usad8(tmp
, tmp
, tmp2
);
10173 tcg_temp_free_i32(tmp2
);
10175 tmp2
= load_reg(s
, rs
);
10176 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10177 tcg_temp_free_i32(tmp2
);
10181 store_reg(s
, rd
, tmp
);
10183 case 6: case 7: /* 64-bit multiply, Divide. */
10184 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10185 tmp
= load_reg(s
, rn
);
10186 tmp2
= load_reg(s
, rm
);
10187 if ((op
& 0x50) == 0x10) {
10189 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10193 gen_helper_udiv(tmp
, tmp
, tmp2
);
10195 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10196 tcg_temp_free_i32(tmp2
);
10197 store_reg(s
, rd
, tmp
);
10198 } else if ((op
& 0xe) == 0xc) {
10199 /* Dual multiply accumulate long. */
10200 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10201 tcg_temp_free_i32(tmp
);
10202 tcg_temp_free_i32(tmp2
);
10206 gen_swap_half(tmp2
);
10207 gen_smul_dual(tmp
, tmp2
);
10209 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10211 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10213 tcg_temp_free_i32(tmp2
);
10215 tmp64
= tcg_temp_new_i64();
10216 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10217 tcg_temp_free_i32(tmp
);
10218 gen_addq(s
, tmp64
, rs
, rd
);
10219 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10220 tcg_temp_free_i64(tmp64
);
10223 /* Unsigned 64-bit multiply */
10224 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10228 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10229 tcg_temp_free_i32(tmp2
);
10230 tcg_temp_free_i32(tmp
);
10233 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10234 tcg_temp_free_i32(tmp2
);
10235 tmp64
= tcg_temp_new_i64();
10236 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10237 tcg_temp_free_i32(tmp
);
10239 /* Signed 64-bit multiply */
10240 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10245 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10246 tcg_temp_free_i64(tmp64
);
10249 gen_addq_lo(s
, tmp64
, rs
);
10250 gen_addq_lo(s
, tmp64
, rd
);
10251 } else if (op
& 0x40) {
10252 /* 64-bit accumulate. */
10253 gen_addq(s
, tmp64
, rs
, rd
);
10255 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10256 tcg_temp_free_i64(tmp64
);
10261 case 6: case 7: case 14: case 15:
10263 if (((insn
>> 24) & 3) == 3) {
10264 /* Translate into the equivalent ARM encoding. */
10265 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10266 if (disas_neon_data_insn(s
, insn
)) {
10269 } else if (((insn
>> 8) & 0xe) == 10) {
10270 if (disas_vfp_insn(s
, insn
)) {
10274 if (insn
& (1 << 28))
10276 if (disas_coproc_insn(s
, insn
)) {
10281 case 8: case 9: case 10: case 11:
10282 if (insn
& (1 << 15)) {
10283 /* Branches, misc control. */
10284 if (insn
& 0x5000) {
10285 /* Unconditional branch. */
10286 /* signextend(hw1[10:0]) -> offset[:12]. */
10287 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10288 /* hw1[10:0] -> offset[11:1]. */
10289 offset
|= (insn
& 0x7ff) << 1;
10290 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10291 offset[24:22] already have the same value because of the
10292 sign extension above. */
10293 offset
^= ((~insn
) & (1 << 13)) << 10;
10294 offset
^= ((~insn
) & (1 << 11)) << 11;
10296 if (insn
& (1 << 14)) {
10297 /* Branch and link. */
10298 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10302 if (insn
& (1 << 12)) {
10304 gen_jmp(s
, offset
);
10307 offset
&= ~(uint32_t)2;
10308 /* thumb2 bx, no need to check */
10309 gen_bx_im(s
, offset
);
10311 } else if (((insn
>> 23) & 7) == 7) {
10313 if (insn
& (1 << 13))
10316 if (insn
& (1 << 26)) {
10317 if (!(insn
& (1 << 20))) {
10318 /* Hypervisor call (v7) */
10319 int imm16
= extract32(insn
, 16, 4) << 12
10320 | extract32(insn
, 0, 12);
10327 /* Secure monitor call (v6+) */
10335 op
= (insn
>> 20) & 7;
10337 case 0: /* msr cpsr. */
10338 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10339 tmp
= load_reg(s
, rn
);
10340 addr
= tcg_const_i32(insn
& 0xff);
10341 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10342 tcg_temp_free_i32(addr
);
10343 tcg_temp_free_i32(tmp
);
10348 case 1: /* msr spsr. */
10349 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10353 if (extract32(insn
, 5, 1)) {
10355 int sysm
= extract32(insn
, 8, 4) |
10356 (extract32(insn
, 4, 1) << 4);
10359 gen_msr_banked(s
, r
, sysm
, rm
);
10363 /* MSR (for PSRs) */
10364 tmp
= load_reg(s
, rn
);
10366 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10370 case 2: /* cps, nop-hint. */
10371 if (((insn
>> 8) & 7) == 0) {
10372 gen_nop_hint(s
, insn
& 0xff);
10374 /* Implemented as NOP in user mode. */
10379 if (insn
& (1 << 10)) {
10380 if (insn
& (1 << 7))
10382 if (insn
& (1 << 6))
10384 if (insn
& (1 << 5))
10386 if (insn
& (1 << 9))
10387 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10389 if (insn
& (1 << 8)) {
10391 imm
|= (insn
& 0x1f);
10394 gen_set_psr_im(s
, offset
, 0, imm
);
10397 case 3: /* Special control operations. */
10399 op
= (insn
>> 4) & 0xf;
10401 case 2: /* clrex */
10406 /* These execute as NOPs. */
10409 /* We need to break the TB after this insn
10410 * to execute self-modifying code correctly
10411 * and also to take any pending interrupts
10421 /* Trivial implementation equivalent to bx. */
10422 tmp
= load_reg(s
, rn
);
10425 case 5: /* Exception return. */
10429 if (rn
!= 14 || rd
!= 15) {
10432 tmp
= load_reg(s
, rn
);
10433 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10434 gen_exception_return(s
, tmp
);
10437 if (extract32(insn
, 5, 1)) {
10439 int sysm
= extract32(insn
, 16, 4) |
10440 (extract32(insn
, 4, 1) << 4);
10442 gen_mrs_banked(s
, 0, sysm
, rd
);
10447 tmp
= tcg_temp_new_i32();
10448 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10449 addr
= tcg_const_i32(insn
& 0xff);
10450 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10451 tcg_temp_free_i32(addr
);
10453 gen_helper_cpsr_read(tmp
, cpu_env
);
10455 store_reg(s
, rd
, tmp
);
10458 if (extract32(insn
, 5, 1)) {
10460 int sysm
= extract32(insn
, 16, 4) |
10461 (extract32(insn
, 4, 1) << 4);
10463 gen_mrs_banked(s
, 1, sysm
, rd
);
10468 /* Not accessible in user mode. */
10469 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10472 tmp
= load_cpu_field(spsr
);
10473 store_reg(s
, rd
, tmp
);
10478 /* Conditional branch. */
10479 op
= (insn
>> 22) & 0xf;
10480 /* Generate a conditional jump to next instruction. */
10481 s
->condlabel
= gen_new_label();
10482 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10485 /* offset[11:1] = insn[10:0] */
10486 offset
= (insn
& 0x7ff) << 1;
10487 /* offset[17:12] = insn[21:16]. */
10488 offset
|= (insn
& 0x003f0000) >> 4;
10489 /* offset[31:20] = insn[26]. */
10490 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10491 /* offset[18] = insn[13]. */
10492 offset
|= (insn
& (1 << 13)) << 5;
10493 /* offset[19] = insn[11]. */
10494 offset
|= (insn
& (1 << 11)) << 8;
10496 /* jump to the offset */
10497 gen_jmp(s
, s
->pc
+ offset
);
10500 /* Data processing immediate. */
10501 if (insn
& (1 << 25)) {
10502 if (insn
& (1 << 24)) {
10503 if (insn
& (1 << 20))
10505 /* Bitfield/Saturate. */
10506 op
= (insn
>> 21) & 7;
10508 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10510 tmp
= tcg_temp_new_i32();
10511 tcg_gen_movi_i32(tmp
, 0);
10513 tmp
= load_reg(s
, rn
);
10516 case 2: /* Signed bitfield extract. */
10518 if (shift
+ imm
> 32)
10521 gen_sbfx(tmp
, shift
, imm
);
10523 case 6: /* Unsigned bitfield extract. */
10525 if (shift
+ imm
> 32)
10528 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
10530 case 3: /* Bitfield insert/clear. */
10533 imm
= imm
+ 1 - shift
;
10535 tmp2
= load_reg(s
, rd
);
10536 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10537 tcg_temp_free_i32(tmp2
);
10542 default: /* Saturate. */
10545 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10547 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10549 tmp2
= tcg_const_i32(imm
);
10552 if ((op
& 1) && shift
== 0) {
10553 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10554 tcg_temp_free_i32(tmp
);
10555 tcg_temp_free_i32(tmp2
);
10558 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10560 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10564 if ((op
& 1) && shift
== 0) {
10565 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10566 tcg_temp_free_i32(tmp
);
10567 tcg_temp_free_i32(tmp2
);
10570 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10572 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10575 tcg_temp_free_i32(tmp2
);
10578 store_reg(s
, rd
, tmp
);
10580 imm
= ((insn
& 0x04000000) >> 15)
10581 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10582 if (insn
& (1 << 22)) {
10583 /* 16-bit immediate. */
10584 imm
|= (insn
>> 4) & 0xf000;
10585 if (insn
& (1 << 23)) {
10587 tmp
= load_reg(s
, rd
);
10588 tcg_gen_ext16u_i32(tmp
, tmp
);
10589 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10592 tmp
= tcg_temp_new_i32();
10593 tcg_gen_movi_i32(tmp
, imm
);
10596 /* Add/sub 12-bit immediate. */
10598 offset
= s
->pc
& ~(uint32_t)3;
10599 if (insn
& (1 << 23))
10603 tmp
= tcg_temp_new_i32();
10604 tcg_gen_movi_i32(tmp
, offset
);
10606 tmp
= load_reg(s
, rn
);
10607 if (insn
& (1 << 23))
10608 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10610 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10613 store_reg(s
, rd
, tmp
);
10616 int shifter_out
= 0;
10617 /* modified 12-bit immediate. */
10618 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10619 imm
= (insn
& 0xff);
10622 /* Nothing to do. */
10624 case 1: /* 00XY00XY */
10627 case 2: /* XY00XY00 */
10631 case 3: /* XYXYXYXY */
10635 default: /* Rotated constant. */
10636 shift
= (shift
<< 1) | (imm
>> 7);
10638 imm
= imm
<< (32 - shift
);
10642 tmp2
= tcg_temp_new_i32();
10643 tcg_gen_movi_i32(tmp2
, imm
);
10644 rn
= (insn
>> 16) & 0xf;
10646 tmp
= tcg_temp_new_i32();
10647 tcg_gen_movi_i32(tmp
, 0);
10649 tmp
= load_reg(s
, rn
);
10651 op
= (insn
>> 21) & 0xf;
10652 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10653 shifter_out
, tmp
, tmp2
))
10655 tcg_temp_free_i32(tmp2
);
10656 rd
= (insn
>> 8) & 0xf;
10658 store_reg(s
, rd
, tmp
);
10660 tcg_temp_free_i32(tmp
);
10665 case 12: /* Load/store single data item. */
10670 if ((insn
& 0x01100000) == 0x01000000) {
10671 if (disas_neon_ls_insn(s
, insn
)) {
10676 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10678 if (!(insn
& (1 << 20))) {
10682 /* Byte or halfword load space with dest == r15 : memory hints.
10683 * Catch them early so we don't emit pointless addressing code.
10684 * This space is a mix of:
10685 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10686 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10688 * unallocated hints, which must be treated as NOPs
10689 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10690 * which is easiest for the decoding logic
10691 * Some space which must UNDEF
10693 int op1
= (insn
>> 23) & 3;
10694 int op2
= (insn
>> 6) & 0x3f;
10699 /* UNPREDICTABLE, unallocated hint or
10700 * PLD/PLDW/PLI (literal)
10705 return 0; /* PLD/PLDW/PLI or unallocated hint */
10707 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10708 return 0; /* PLD/PLDW/PLI or unallocated hint */
10710 /* UNDEF space, or an UNPREDICTABLE */
10714 memidx
= get_mem_index(s
);
10716 addr
= tcg_temp_new_i32();
10718 /* s->pc has already been incremented by 4. */
10719 imm
= s
->pc
& 0xfffffffc;
10720 if (insn
& (1 << 23))
10721 imm
+= insn
& 0xfff;
10723 imm
-= insn
& 0xfff;
10724 tcg_gen_movi_i32(addr
, imm
);
10726 addr
= load_reg(s
, rn
);
10727 if (insn
& (1 << 23)) {
10728 /* Positive offset. */
10729 imm
= insn
& 0xfff;
10730 tcg_gen_addi_i32(addr
, addr
, imm
);
10733 switch ((insn
>> 8) & 0xf) {
10734 case 0x0: /* Shifted Register. */
10735 shift
= (insn
>> 4) & 0xf;
10737 tcg_temp_free_i32(addr
);
10740 tmp
= load_reg(s
, rm
);
10742 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10743 tcg_gen_add_i32(addr
, addr
, tmp
);
10744 tcg_temp_free_i32(tmp
);
10746 case 0xc: /* Negative offset. */
10747 tcg_gen_addi_i32(addr
, addr
, -imm
);
10749 case 0xe: /* User privilege. */
10750 tcg_gen_addi_i32(addr
, addr
, imm
);
10751 memidx
= get_a32_user_mem_index(s
);
10753 case 0x9: /* Post-decrement. */
10755 /* Fall through. */
10756 case 0xb: /* Post-increment. */
10760 case 0xd: /* Pre-decrement. */
10762 /* Fall through. */
10763 case 0xf: /* Pre-increment. */
10764 tcg_gen_addi_i32(addr
, addr
, imm
);
10768 tcg_temp_free_i32(addr
);
10773 if (insn
& (1 << 20)) {
10775 tmp
= tcg_temp_new_i32();
10778 gen_aa32_ld8u(s
, tmp
, addr
, memidx
);
10781 gen_aa32_ld8s(s
, tmp
, addr
, memidx
);
10784 gen_aa32_ld16u(s
, tmp
, addr
, memidx
);
10787 gen_aa32_ld16s(s
, tmp
, addr
, memidx
);
10790 gen_aa32_ld32u(s
, tmp
, addr
, memidx
);
10793 tcg_temp_free_i32(tmp
);
10794 tcg_temp_free_i32(addr
);
10800 store_reg(s
, rs
, tmp
);
10804 tmp
= load_reg(s
, rs
);
10807 gen_aa32_st8(s
, tmp
, addr
, memidx
);
10810 gen_aa32_st16(s
, tmp
, addr
, memidx
);
10813 gen_aa32_st32(s
, tmp
, addr
, memidx
);
10816 tcg_temp_free_i32(tmp
);
10817 tcg_temp_free_i32(addr
);
10820 tcg_temp_free_i32(tmp
);
10823 tcg_gen_addi_i32(addr
, addr
, imm
);
10825 store_reg(s
, rn
, addr
);
10827 tcg_temp_free_i32(addr
);
10839 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10841 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10848 if (s
->condexec_mask
) {
10849 cond
= s
->condexec_cond
;
10850 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10851 s
->condlabel
= gen_new_label();
10852 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10857 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
10860 switch (insn
>> 12) {
10864 op
= (insn
>> 11) & 3;
10867 rn
= (insn
>> 3) & 7;
10868 tmp
= load_reg(s
, rn
);
10869 if (insn
& (1 << 10)) {
10871 tmp2
= tcg_temp_new_i32();
10872 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10875 rm
= (insn
>> 6) & 7;
10876 tmp2
= load_reg(s
, rm
);
10878 if (insn
& (1 << 9)) {
10879 if (s
->condexec_mask
)
10880 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10882 gen_sub_CC(tmp
, tmp
, tmp2
);
10884 if (s
->condexec_mask
)
10885 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10887 gen_add_CC(tmp
, tmp
, tmp2
);
10889 tcg_temp_free_i32(tmp2
);
10890 store_reg(s
, rd
, tmp
);
10892 /* shift immediate */
10893 rm
= (insn
>> 3) & 7;
10894 shift
= (insn
>> 6) & 0x1f;
10895 tmp
= load_reg(s
, rm
);
10896 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10897 if (!s
->condexec_mask
)
10899 store_reg(s
, rd
, tmp
);
10903 /* arithmetic large immediate */
10904 op
= (insn
>> 11) & 3;
10905 rd
= (insn
>> 8) & 0x7;
10906 if (op
== 0) { /* mov */
10907 tmp
= tcg_temp_new_i32();
10908 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10909 if (!s
->condexec_mask
)
10911 store_reg(s
, rd
, tmp
);
10913 tmp
= load_reg(s
, rd
);
10914 tmp2
= tcg_temp_new_i32();
10915 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10918 gen_sub_CC(tmp
, tmp
, tmp2
);
10919 tcg_temp_free_i32(tmp
);
10920 tcg_temp_free_i32(tmp2
);
10923 if (s
->condexec_mask
)
10924 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10926 gen_add_CC(tmp
, tmp
, tmp2
);
10927 tcg_temp_free_i32(tmp2
);
10928 store_reg(s
, rd
, tmp
);
10931 if (s
->condexec_mask
)
10932 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10934 gen_sub_CC(tmp
, tmp
, tmp2
);
10935 tcg_temp_free_i32(tmp2
);
10936 store_reg(s
, rd
, tmp
);
10942 if (insn
& (1 << 11)) {
10943 rd
= (insn
>> 8) & 7;
10944 /* load pc-relative. Bit 1 of PC is ignored. */
10945 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10946 val
&= ~(uint32_t)2;
10947 addr
= tcg_temp_new_i32();
10948 tcg_gen_movi_i32(addr
, val
);
10949 tmp
= tcg_temp_new_i32();
10950 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10951 tcg_temp_free_i32(addr
);
10952 store_reg(s
, rd
, tmp
);
10955 if (insn
& (1 << 10)) {
10956 /* data processing extended or blx */
10957 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10958 rm
= (insn
>> 3) & 0xf;
10959 op
= (insn
>> 8) & 3;
10962 tmp
= load_reg(s
, rd
);
10963 tmp2
= load_reg(s
, rm
);
10964 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10965 tcg_temp_free_i32(tmp2
);
10966 store_reg(s
, rd
, tmp
);
10969 tmp
= load_reg(s
, rd
);
10970 tmp2
= load_reg(s
, rm
);
10971 gen_sub_CC(tmp
, tmp
, tmp2
);
10972 tcg_temp_free_i32(tmp2
);
10973 tcg_temp_free_i32(tmp
);
10975 case 2: /* mov/cpy */
10976 tmp
= load_reg(s
, rm
);
10977 store_reg(s
, rd
, tmp
);
10979 case 3:/* branch [and link] exchange thumb register */
10980 tmp
= load_reg(s
, rm
);
10981 if (insn
& (1 << 7)) {
10983 val
= (uint32_t)s
->pc
| 1;
10984 tmp2
= tcg_temp_new_i32();
10985 tcg_gen_movi_i32(tmp2
, val
);
10986 store_reg(s
, 14, tmp2
);
10988 /* already thumb, no need to check */
10995 /* data processing register */
10997 rm
= (insn
>> 3) & 7;
10998 op
= (insn
>> 6) & 0xf;
10999 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11000 /* the shift/rotate ops want the operands backwards */
11009 if (op
== 9) { /* neg */
11010 tmp
= tcg_temp_new_i32();
11011 tcg_gen_movi_i32(tmp
, 0);
11012 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11013 tmp
= load_reg(s
, rd
);
11015 TCGV_UNUSED_I32(tmp
);
11018 tmp2
= load_reg(s
, rm
);
11020 case 0x0: /* and */
11021 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11022 if (!s
->condexec_mask
)
11025 case 0x1: /* eor */
11026 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11027 if (!s
->condexec_mask
)
11030 case 0x2: /* lsl */
11031 if (s
->condexec_mask
) {
11032 gen_shl(tmp2
, tmp2
, tmp
);
11034 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11035 gen_logic_CC(tmp2
);
11038 case 0x3: /* lsr */
11039 if (s
->condexec_mask
) {
11040 gen_shr(tmp2
, tmp2
, tmp
);
11042 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11043 gen_logic_CC(tmp2
);
11046 case 0x4: /* asr */
11047 if (s
->condexec_mask
) {
11048 gen_sar(tmp2
, tmp2
, tmp
);
11050 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11051 gen_logic_CC(tmp2
);
11054 case 0x5: /* adc */
11055 if (s
->condexec_mask
) {
11056 gen_adc(tmp
, tmp2
);
11058 gen_adc_CC(tmp
, tmp
, tmp2
);
11061 case 0x6: /* sbc */
11062 if (s
->condexec_mask
) {
11063 gen_sub_carry(tmp
, tmp
, tmp2
);
11065 gen_sbc_CC(tmp
, tmp
, tmp2
);
11068 case 0x7: /* ror */
11069 if (s
->condexec_mask
) {
11070 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11071 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11073 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11074 gen_logic_CC(tmp2
);
11077 case 0x8: /* tst */
11078 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11082 case 0x9: /* neg */
11083 if (s
->condexec_mask
)
11084 tcg_gen_neg_i32(tmp
, tmp2
);
11086 gen_sub_CC(tmp
, tmp
, tmp2
);
11088 case 0xa: /* cmp */
11089 gen_sub_CC(tmp
, tmp
, tmp2
);
11092 case 0xb: /* cmn */
11093 gen_add_CC(tmp
, tmp
, tmp2
);
11096 case 0xc: /* orr */
11097 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11098 if (!s
->condexec_mask
)
11101 case 0xd: /* mul */
11102 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11103 if (!s
->condexec_mask
)
11106 case 0xe: /* bic */
11107 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11108 if (!s
->condexec_mask
)
11111 case 0xf: /* mvn */
11112 tcg_gen_not_i32(tmp2
, tmp2
);
11113 if (!s
->condexec_mask
)
11114 gen_logic_CC(tmp2
);
11121 store_reg(s
, rm
, tmp2
);
11123 tcg_temp_free_i32(tmp
);
11125 store_reg(s
, rd
, tmp
);
11126 tcg_temp_free_i32(tmp2
);
11129 tcg_temp_free_i32(tmp
);
11130 tcg_temp_free_i32(tmp2
);
11135 /* load/store register offset. */
11137 rn
= (insn
>> 3) & 7;
11138 rm
= (insn
>> 6) & 7;
11139 op
= (insn
>> 9) & 7;
11140 addr
= load_reg(s
, rn
);
11141 tmp
= load_reg(s
, rm
);
11142 tcg_gen_add_i32(addr
, addr
, tmp
);
11143 tcg_temp_free_i32(tmp
);
11145 if (op
< 3) { /* store */
11146 tmp
= load_reg(s
, rd
);
11148 tmp
= tcg_temp_new_i32();
11153 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11156 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11159 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11161 case 3: /* ldrsb */
11162 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
11165 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11168 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11171 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11173 case 7: /* ldrsh */
11174 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
11177 if (op
>= 3) { /* load */
11178 store_reg(s
, rd
, tmp
);
11180 tcg_temp_free_i32(tmp
);
11182 tcg_temp_free_i32(addr
);
11186 /* load/store word immediate offset */
11188 rn
= (insn
>> 3) & 7;
11189 addr
= load_reg(s
, rn
);
11190 val
= (insn
>> 4) & 0x7c;
11191 tcg_gen_addi_i32(addr
, addr
, val
);
11193 if (insn
& (1 << 11)) {
11195 tmp
= tcg_temp_new_i32();
11196 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11197 store_reg(s
, rd
, tmp
);
11200 tmp
= load_reg(s
, rd
);
11201 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11202 tcg_temp_free_i32(tmp
);
11204 tcg_temp_free_i32(addr
);
11208 /* load/store byte immediate offset */
11210 rn
= (insn
>> 3) & 7;
11211 addr
= load_reg(s
, rn
);
11212 val
= (insn
>> 6) & 0x1f;
11213 tcg_gen_addi_i32(addr
, addr
, val
);
11215 if (insn
& (1 << 11)) {
11217 tmp
= tcg_temp_new_i32();
11218 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11219 store_reg(s
, rd
, tmp
);
11222 tmp
= load_reg(s
, rd
);
11223 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11224 tcg_temp_free_i32(tmp
);
11226 tcg_temp_free_i32(addr
);
11230 /* load/store halfword immediate offset */
11232 rn
= (insn
>> 3) & 7;
11233 addr
= load_reg(s
, rn
);
11234 val
= (insn
>> 5) & 0x3e;
11235 tcg_gen_addi_i32(addr
, addr
, val
);
11237 if (insn
& (1 << 11)) {
11239 tmp
= tcg_temp_new_i32();
11240 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11241 store_reg(s
, rd
, tmp
);
11244 tmp
= load_reg(s
, rd
);
11245 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11246 tcg_temp_free_i32(tmp
);
11248 tcg_temp_free_i32(addr
);
11252 /* load/store from stack */
11253 rd
= (insn
>> 8) & 7;
11254 addr
= load_reg(s
, 13);
11255 val
= (insn
& 0xff) * 4;
11256 tcg_gen_addi_i32(addr
, addr
, val
);
11258 if (insn
& (1 << 11)) {
11260 tmp
= tcg_temp_new_i32();
11261 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11262 store_reg(s
, rd
, tmp
);
11265 tmp
= load_reg(s
, rd
);
11266 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11267 tcg_temp_free_i32(tmp
);
11269 tcg_temp_free_i32(addr
);
11273 /* add to high reg */
11274 rd
= (insn
>> 8) & 7;
11275 if (insn
& (1 << 11)) {
11277 tmp
= load_reg(s
, 13);
11279 /* PC. bit 1 is ignored. */
11280 tmp
= tcg_temp_new_i32();
11281 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11283 val
= (insn
& 0xff) * 4;
11284 tcg_gen_addi_i32(tmp
, tmp
, val
);
11285 store_reg(s
, rd
, tmp
);
11290 op
= (insn
>> 8) & 0xf;
11293 /* adjust stack pointer */
11294 tmp
= load_reg(s
, 13);
11295 val
= (insn
& 0x7f) * 4;
11296 if (insn
& (1 << 7))
11297 val
= -(int32_t)val
;
11298 tcg_gen_addi_i32(tmp
, tmp
, val
);
11299 store_reg(s
, 13, tmp
);
11302 case 2: /* sign/zero extend. */
11305 rm
= (insn
>> 3) & 7;
11306 tmp
= load_reg(s
, rm
);
11307 switch ((insn
>> 6) & 3) {
11308 case 0: gen_sxth(tmp
); break;
11309 case 1: gen_sxtb(tmp
); break;
11310 case 2: gen_uxth(tmp
); break;
11311 case 3: gen_uxtb(tmp
); break;
11313 store_reg(s
, rd
, tmp
);
11315 case 4: case 5: case 0xc: case 0xd:
11317 addr
= load_reg(s
, 13);
11318 if (insn
& (1 << 8))
11322 for (i
= 0; i
< 8; i
++) {
11323 if (insn
& (1 << i
))
11326 if ((insn
& (1 << 11)) == 0) {
11327 tcg_gen_addi_i32(addr
, addr
, -offset
);
11329 for (i
= 0; i
< 8; i
++) {
11330 if (insn
& (1 << i
)) {
11331 if (insn
& (1 << 11)) {
11333 tmp
= tcg_temp_new_i32();
11334 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11335 store_reg(s
, i
, tmp
);
11338 tmp
= load_reg(s
, i
);
11339 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11340 tcg_temp_free_i32(tmp
);
11342 /* advance to the next address. */
11343 tcg_gen_addi_i32(addr
, addr
, 4);
11346 TCGV_UNUSED_I32(tmp
);
11347 if (insn
& (1 << 8)) {
11348 if (insn
& (1 << 11)) {
11350 tmp
= tcg_temp_new_i32();
11351 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11352 /* don't set the pc until the rest of the instruction
11356 tmp
= load_reg(s
, 14);
11357 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11358 tcg_temp_free_i32(tmp
);
11360 tcg_gen_addi_i32(addr
, addr
, 4);
11362 if ((insn
& (1 << 11)) == 0) {
11363 tcg_gen_addi_i32(addr
, addr
, -offset
);
11365 /* write back the new stack pointer */
11366 store_reg(s
, 13, addr
);
11367 /* set the new PC value */
11368 if ((insn
& 0x0900) == 0x0900) {
11369 store_reg_from_load(s
, 15, tmp
);
11373 case 1: case 3: case 9: case 11: /* czb */
11375 tmp
= load_reg(s
, rm
);
11376 s
->condlabel
= gen_new_label();
11378 if (insn
& (1 << 11))
11379 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11381 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11382 tcg_temp_free_i32(tmp
);
11383 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11384 val
= (uint32_t)s
->pc
+ 2;
11389 case 15: /* IT, nop-hint. */
11390 if ((insn
& 0xf) == 0) {
11391 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11395 s
->condexec_cond
= (insn
>> 4) & 0xe;
11396 s
->condexec_mask
= insn
& 0x1f;
11397 /* No actual code generated for this insn, just setup state. */
11400 case 0xe: /* bkpt */
11402 int imm8
= extract32(insn
, 0, 8);
11404 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11405 default_exception_el(s
));
11409 case 0xa: /* rev */
11411 rn
= (insn
>> 3) & 0x7;
11413 tmp
= load_reg(s
, rn
);
11414 switch ((insn
>> 6) & 3) {
11415 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11416 case 1: gen_rev16(tmp
); break;
11417 case 3: gen_revsh(tmp
); break;
11418 default: goto illegal_op
;
11420 store_reg(s
, rd
, tmp
);
11424 switch ((insn
>> 5) & 7) {
11428 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11429 gen_helper_setend(cpu_env
);
11430 s
->is_jmp
= DISAS_UPDATE
;
11439 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11440 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11443 addr
= tcg_const_i32(19);
11444 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11445 tcg_temp_free_i32(addr
);
11449 addr
= tcg_const_i32(16);
11450 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11451 tcg_temp_free_i32(addr
);
11453 tcg_temp_free_i32(tmp
);
11456 if (insn
& (1 << 4)) {
11457 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11461 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11476 /* load/store multiple */
11477 TCGv_i32 loaded_var
;
11478 TCGV_UNUSED_I32(loaded_var
);
11479 rn
= (insn
>> 8) & 0x7;
11480 addr
= load_reg(s
, rn
);
11481 for (i
= 0; i
< 8; i
++) {
11482 if (insn
& (1 << i
)) {
11483 if (insn
& (1 << 11)) {
11485 tmp
= tcg_temp_new_i32();
11486 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11490 store_reg(s
, i
, tmp
);
11494 tmp
= load_reg(s
, i
);
11495 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11496 tcg_temp_free_i32(tmp
);
11498 /* advance to the next address */
11499 tcg_gen_addi_i32(addr
, addr
, 4);
11502 if ((insn
& (1 << rn
)) == 0) {
11503 /* base reg not in list: base register writeback */
11504 store_reg(s
, rn
, addr
);
11506 /* base reg in list: if load, complete it now */
11507 if (insn
& (1 << 11)) {
11508 store_reg(s
, rn
, loaded_var
);
11510 tcg_temp_free_i32(addr
);
11515 /* conditional branch or swi */
11516 cond
= (insn
>> 8) & 0xf;
11522 gen_set_pc_im(s
, s
->pc
);
11523 s
->svc_imm
= extract32(insn
, 0, 8);
11524 s
->is_jmp
= DISAS_SWI
;
11527 /* generate a conditional jump to next instruction */
11528 s
->condlabel
= gen_new_label();
11529 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11532 /* jump to the offset */
11533 val
= (uint32_t)s
->pc
+ 2;
11534 offset
= ((int32_t)insn
<< 24) >> 24;
11535 val
+= offset
<< 1;
11540 if (insn
& (1 << 11)) {
11541 if (disas_thumb2_insn(env
, s
, insn
))
11545 /* unconditional branch */
11546 val
= (uint32_t)s
->pc
;
11547 offset
= ((int32_t)insn
<< 21) >> 21;
11548 val
+= (offset
<< 1) + 2;
11553 if (disas_thumb2_insn(env
, s
, insn
))
11559 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11560 default_exception_el(s
));
11564 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11565 default_exception_el(s
));
11568 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11570 /* Return true if the insn at dc->pc might cross a page boundary.
11571 * (False positives are OK, false negatives are not.)
11575 if ((s
->pc
& 3) == 0) {
11576 /* At a 4-aligned address we can't be crossing a page */
11580 /* This must be a Thumb insn */
11581 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11583 if ((insn
>> 11) >= 0x1d) {
11584 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11585 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11586 * end up actually treating this as two 16-bit insns (see the
11587 * code at the start of disas_thumb2_insn()) but we don't bother
11588 * to check for that as it is unlikely, and false positives here
11593 /* Definitely a 16-bit insn, can't be crossing a page. */
11597 /* generate intermediate code for basic block 'tb'. */
11598 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11600 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11601 CPUState
*cs
= CPU(cpu
);
11602 DisasContext dc1
, *dc
= &dc1
;
11603 target_ulong pc_start
;
11604 target_ulong next_page_start
;
11609 /* generate intermediate code */
11611 /* The A64 decoder has its own top level loop, because it doesn't need
11612 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11614 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11615 gen_intermediate_code_a64(cpu
, tb
);
11623 dc
->is_jmp
= DISAS_NEXT
;
11625 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11629 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11630 * there is no secure EL1, so we route exceptions to EL3.
11632 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11633 !arm_el_is_aa64(env
, 3);
11634 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11635 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(tb
->flags
);
11636 dc
->be_data
= ARM_TBFLAG_BE_DATA(tb
->flags
) ? MO_BE
: MO_LE
;
11637 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11638 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11639 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11640 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11641 #if !defined(CONFIG_USER_ONLY)
11642 dc
->user
= (dc
->current_el
== 0);
11644 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11645 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11646 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11647 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11648 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11649 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11650 dc
->cp_regs
= cpu
->cp_regs
;
11651 dc
->features
= env
->features
;
11653 /* Single step state. The code-generation logic here is:
11655 * generate code with no special handling for single-stepping (except
11656 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11657 * this happens anyway because those changes are all system register or
11659 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11660 * emit code for one insn
11661 * emit code to clear PSTATE.SS
11662 * emit code to generate software step exception for completed step
11663 * end TB (as usual for having generated an exception)
11664 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11665 * emit code to generate a software step exception
11668 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11669 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11670 dc
->is_ldex
= false;
11671 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11673 cpu_F0s
= tcg_temp_new_i32();
11674 cpu_F1s
= tcg_temp_new_i32();
11675 cpu_F0d
= tcg_temp_new_i64();
11676 cpu_F1d
= tcg_temp_new_i64();
11679 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11680 cpu_M0
= tcg_temp_new_i64();
11681 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11683 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11684 if (max_insns
== 0) {
11685 max_insns
= CF_COUNT_MASK
;
11687 if (max_insns
> TCG_MAX_INSNS
) {
11688 max_insns
= TCG_MAX_INSNS
;
11693 tcg_clear_temp_count();
11695 /* A note on handling of the condexec (IT) bits:
11697 * We want to avoid the overhead of having to write the updated condexec
11698 * bits back to the CPUARMState for every instruction in an IT block. So:
11699 * (1) if the condexec bits are not already zero then we write
11700 * zero back into the CPUARMState now. This avoids complications trying
11701 * to do it at the end of the block. (For example if we don't do this
11702 * it's hard to identify whether we can safely skip writing condexec
11703 * at the end of the TB, which we definitely want to do for the case
11704 * where a TB doesn't do anything with the IT state at all.)
11705 * (2) if we are going to leave the TB then we call gen_set_condexec()
11706 * which will write the correct value into CPUARMState if zero is wrong.
11707 * This is done both for leaving the TB at the end, and for leaving
11708 * it because of an exception we know will happen, which is done in
11709 * gen_exception_insn(). The latter is necessary because we need to
11710 * leave the TB with the PC/IT state just prior to execution of the
11711 * instruction which caused the exception.
11712 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11713 * then the CPUARMState will be wrong and we need to reset it.
11714 * This is handled in the same way as restoration of the
11715 * PC in these situations; we save the value of the condexec bits
11716 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11717 * then uses this to restore them after an exception.
11719 * Note that there are no instructions which can read the condexec
11720 * bits, and none which can write non-static values to them, so
11721 * we don't need to care about whether CPUARMState is correct in the
11725 /* Reset the conditional execution bits immediately. This avoids
11726 complications trying to do it at the end of the block. */
11727 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11729 TCGv_i32 tmp
= tcg_temp_new_i32();
11730 tcg_gen_movi_i32(tmp
, 0);
11731 store_cpu_field(tmp
, condexec_bits
);
11734 tcg_gen_insn_start(dc
->pc
,
11735 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11739 #ifdef CONFIG_USER_ONLY
11740 /* Intercept jump to the magic kernel page. */
11741 if (dc
->pc
>= 0xffff0000) {
11742 /* We always get here via a jump, so know we are not in a
11743 conditional execution block. */
11744 gen_exception_internal(EXCP_KERNEL_TRAP
);
11745 dc
->is_jmp
= DISAS_EXC
;
11749 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11750 /* We always get here via a jump, so know we are not in a
11751 conditional execution block. */
11752 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11753 dc
->is_jmp
= DISAS_EXC
;
11758 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11760 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11761 if (bp
->pc
== dc
->pc
) {
11762 if (bp
->flags
& BP_CPU
) {
11763 gen_set_condexec(dc
);
11764 gen_set_pc_im(dc
, dc
->pc
);
11765 gen_helper_check_breakpoints(cpu_env
);
11766 /* End the TB early; it's likely not going to be executed */
11767 dc
->is_jmp
= DISAS_UPDATE
;
11769 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11770 /* The address covered by the breakpoint must be
11771 included in [tb->pc, tb->pc + tb->size) in order
11772 to for it to be properly cleared -- thus we
11773 increment the PC here so that the logic setting
11774 tb->size below does the right thing. */
11775 /* TODO: Advance PC by correct instruction length to
11776 * avoid disassembler error messages */
11778 goto done_generating
;
11785 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11789 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11790 /* Singlestep state is Active-pending.
11791 * If we're in this state at the start of a TB then either
11792 * a) we just took an exception to an EL which is being debugged
11793 * and this is the first insn in the exception handler
11794 * b) debug exceptions were masked and we just unmasked them
11795 * without changing EL (eg by clearing PSTATE.D)
11796 * In either case we're going to take a swstep exception in the
11797 * "did not step an insn" case, and so the syndrome ISV and EX
11798 * bits should be zero.
11800 assert(num_insns
== 1);
11801 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11802 default_exception_el(dc
));
11803 goto done_generating
;
11807 disas_thumb_insn(env
, dc
);
11808 if (dc
->condexec_mask
) {
11809 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11810 | ((dc
->condexec_mask
>> 4) & 1);
11811 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11812 if (dc
->condexec_mask
== 0) {
11813 dc
->condexec_cond
= 0;
11817 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
11819 disas_arm_insn(dc
, insn
);
11822 if (dc
->condjmp
&& !dc
->is_jmp
) {
11823 gen_set_label(dc
->condlabel
);
11827 if (tcg_check_temp_count()) {
11828 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11832 /* Translation stops when a conditional branch is encountered.
11833 * Otherwise the subsequent code could get translated several times.
11834 * Also stop translation when a page boundary is reached. This
11835 * ensures prefetch aborts occur at the right place. */
11837 /* We want to stop the TB if the next insn starts in a new page,
11838 * or if it spans between this page and the next. This means that
11839 * if we're looking at the last halfword in the page we need to
11840 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11841 * or a 32-bit Thumb insn (which won't).
11842 * This is to avoid generating a silly TB with a single 16-bit insn
11843 * in it at the end of this page (which would execute correctly
11844 * but isn't very efficient).
11846 end_of_page
= (dc
->pc
>= next_page_start
) ||
11847 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
11849 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11850 !cs
->singlestep_enabled
&&
11854 num_insns
< max_insns
);
11856 if (tb
->cflags
& CF_LAST_IO
) {
11858 /* FIXME: This can theoretically happen with self-modifying
11860 cpu_abort(cs
, "IO on conditional branch instruction");
11865 /* At this stage dc->condjmp will only be set when the skipped
11866 instruction was a conditional branch or trap, and the PC has
11867 already been written. */
11868 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11869 /* Unconditional and "condition passed" instruction codepath. */
11870 gen_set_condexec(dc
);
11871 switch (dc
->is_jmp
) {
11873 gen_ss_advance(dc
);
11874 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11875 default_exception_el(dc
));
11878 gen_ss_advance(dc
);
11879 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11882 gen_ss_advance(dc
);
11883 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11887 gen_set_pc_im(dc
, dc
->pc
);
11890 if (dc
->ss_active
) {
11891 gen_step_complete_exception(dc
);
11893 /* FIXME: Single stepping a WFI insn will not halt
11895 gen_exception_internal(EXCP_DEBUG
);
11899 /* "Condition failed" instruction codepath. */
11900 gen_set_label(dc
->condlabel
);
11901 gen_set_condexec(dc
);
11902 gen_set_pc_im(dc
, dc
->pc
);
11903 if (dc
->ss_active
) {
11904 gen_step_complete_exception(dc
);
11906 gen_exception_internal(EXCP_DEBUG
);
11910 /* While branches must always occur at the end of an IT block,
11911 there are a few other things that can cause us to terminate
11912 the TB in the middle of an IT block:
11913 - Exception generating instructions (bkpt, swi, undefined).
11915 - Hardware watchpoints.
11916 Hardware breakpoints have already been handled and skip this code.
11918 gen_set_condexec(dc
);
11919 switch(dc
->is_jmp
) {
11921 gen_goto_tb(dc
, 1, dc
->pc
);
11924 gen_set_pc_im(dc
, dc
->pc
);
11928 /* indicate that the hash table must be used to find the next TB */
11929 tcg_gen_exit_tb(0);
11931 case DISAS_TB_JUMP
:
11932 /* nothing more to generate */
11935 gen_helper_wfi(cpu_env
);
11936 /* The helper doesn't necessarily throw an exception, but we
11937 * must go back to the main loop to check for interrupts anyway.
11939 tcg_gen_exit_tb(0);
11942 gen_helper_wfe(cpu_env
);
11945 gen_helper_yield(cpu_env
);
11948 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11949 default_exception_el(dc
));
11952 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11955 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11959 gen_set_label(dc
->condlabel
);
11960 gen_set_condexec(dc
);
11961 gen_goto_tb(dc
, 1, dc
->pc
);
11967 gen_tb_end(tb
, num_insns
);
11970 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
) &&
11971 qemu_log_in_addr_range(pc_start
)) {
11972 qemu_log("----------------\n");
11973 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11974 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
11975 dc
->thumb
| (dc
->sctlr_b
<< 1));
11979 tb
->size
= dc
->pc
- pc_start
;
11980 tb
->icount
= num_insns
;
11983 static const char *cpu_mode_names
[16] = {
11984 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11985 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11988 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11991 ARMCPU
*cpu
= ARM_CPU(cs
);
11992 CPUARMState
*env
= &cpu
->env
;
11995 const char *ns_status
;
11998 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12002 for(i
=0;i
<16;i
++) {
12003 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12005 cpu_fprintf(f
, "\n");
12007 cpu_fprintf(f
, " ");
12009 psr
= cpsr_read(env
);
12011 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12012 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12013 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12018 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12020 psr
& (1 << 31) ? 'N' : '-',
12021 psr
& (1 << 30) ? 'Z' : '-',
12022 psr
& (1 << 29) ? 'C' : '-',
12023 psr
& (1 << 28) ? 'V' : '-',
12024 psr
& CPSR_T
? 'T' : 'A',
12026 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12028 if (flags
& CPU_DUMP_FPU
) {
12029 int numvfpregs
= 0;
12030 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12033 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12036 for (i
= 0; i
< numvfpregs
; i
++) {
12037 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12038 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12039 i
* 2, (uint32_t)v
,
12040 i
* 2 + 1, (uint32_t)(v
>> 32),
12043 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12047 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12048 target_ulong
*data
)
12052 env
->condexec_bits
= 0;
12053 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12055 env
->regs
[15] = data
[0];
12056 env
->condexec_bits
= data
[1];
12057 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;