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 static bool neon_2rm_is_v8_op(int op
)
5316 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5318 case NEON_2RM_VRINTN
:
5319 case NEON_2RM_VRINTA
:
5320 case NEON_2RM_VRINTM
:
5321 case NEON_2RM_VRINTP
:
5322 case NEON_2RM_VRINTZ
:
5323 case NEON_2RM_VRINTX
:
5324 case NEON_2RM_VCVTAU
:
5325 case NEON_2RM_VCVTAS
:
5326 case NEON_2RM_VCVTNU
:
5327 case NEON_2RM_VCVTNS
:
5328 case NEON_2RM_VCVTPU
:
5329 case NEON_2RM_VCVTPS
:
5330 case NEON_2RM_VCVTMU
:
5331 case NEON_2RM_VCVTMS
:
5338 /* Each entry in this array has bit n set if the insn allows
5339 * size value n (otherwise it will UNDEF). Since unallocated
5340 * op values will have no bits set they always UNDEF.
5342 static const uint8_t neon_2rm_sizes
[] = {
5343 [NEON_2RM_VREV64
] = 0x7,
5344 [NEON_2RM_VREV32
] = 0x3,
5345 [NEON_2RM_VREV16
] = 0x1,
5346 [NEON_2RM_VPADDL
] = 0x7,
5347 [NEON_2RM_VPADDL_U
] = 0x7,
5348 [NEON_2RM_AESE
] = 0x1,
5349 [NEON_2RM_AESMC
] = 0x1,
5350 [NEON_2RM_VCLS
] = 0x7,
5351 [NEON_2RM_VCLZ
] = 0x7,
5352 [NEON_2RM_VCNT
] = 0x1,
5353 [NEON_2RM_VMVN
] = 0x1,
5354 [NEON_2RM_VPADAL
] = 0x7,
5355 [NEON_2RM_VPADAL_U
] = 0x7,
5356 [NEON_2RM_VQABS
] = 0x7,
5357 [NEON_2RM_VQNEG
] = 0x7,
5358 [NEON_2RM_VCGT0
] = 0x7,
5359 [NEON_2RM_VCGE0
] = 0x7,
5360 [NEON_2RM_VCEQ0
] = 0x7,
5361 [NEON_2RM_VCLE0
] = 0x7,
5362 [NEON_2RM_VCLT0
] = 0x7,
5363 [NEON_2RM_SHA1H
] = 0x4,
5364 [NEON_2RM_VABS
] = 0x7,
5365 [NEON_2RM_VNEG
] = 0x7,
5366 [NEON_2RM_VCGT0_F
] = 0x4,
5367 [NEON_2RM_VCGE0_F
] = 0x4,
5368 [NEON_2RM_VCEQ0_F
] = 0x4,
5369 [NEON_2RM_VCLE0_F
] = 0x4,
5370 [NEON_2RM_VCLT0_F
] = 0x4,
5371 [NEON_2RM_VABS_F
] = 0x4,
5372 [NEON_2RM_VNEG_F
] = 0x4,
5373 [NEON_2RM_VSWP
] = 0x1,
5374 [NEON_2RM_VTRN
] = 0x7,
5375 [NEON_2RM_VUZP
] = 0x7,
5376 [NEON_2RM_VZIP
] = 0x7,
5377 [NEON_2RM_VMOVN
] = 0x7,
5378 [NEON_2RM_VQMOVN
] = 0x7,
5379 [NEON_2RM_VSHLL
] = 0x7,
5380 [NEON_2RM_SHA1SU1
] = 0x4,
5381 [NEON_2RM_VRINTN
] = 0x4,
5382 [NEON_2RM_VRINTX
] = 0x4,
5383 [NEON_2RM_VRINTA
] = 0x4,
5384 [NEON_2RM_VRINTZ
] = 0x4,
5385 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5386 [NEON_2RM_VRINTM
] = 0x4,
5387 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5388 [NEON_2RM_VRINTP
] = 0x4,
5389 [NEON_2RM_VCVTAU
] = 0x4,
5390 [NEON_2RM_VCVTAS
] = 0x4,
5391 [NEON_2RM_VCVTNU
] = 0x4,
5392 [NEON_2RM_VCVTNS
] = 0x4,
5393 [NEON_2RM_VCVTPU
] = 0x4,
5394 [NEON_2RM_VCVTPS
] = 0x4,
5395 [NEON_2RM_VCVTMU
] = 0x4,
5396 [NEON_2RM_VCVTMS
] = 0x4,
5397 [NEON_2RM_VRECPE
] = 0x4,
5398 [NEON_2RM_VRSQRTE
] = 0x4,
5399 [NEON_2RM_VRECPE_F
] = 0x4,
5400 [NEON_2RM_VRSQRTE_F
] = 0x4,
5401 [NEON_2RM_VCVT_FS
] = 0x4,
5402 [NEON_2RM_VCVT_FU
] = 0x4,
5403 [NEON_2RM_VCVT_SF
] = 0x4,
5404 [NEON_2RM_VCVT_UF
] = 0x4,
5407 /* Translate a NEON data processing instruction. Return nonzero if the
5408 instruction is invalid.
5409 We process data in a mixture of 32-bit and 64-bit chunks.
5410 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5412 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5424 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5427 /* FIXME: this access check should not take precedence over UNDEF
5428 * for invalid encodings; we will generate incorrect syndrome information
5429 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5431 if (s
->fp_excp_el
) {
5432 gen_exception_insn(s
, 4, EXCP_UDEF
,
5433 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5437 if (!s
->vfp_enabled
)
5439 q
= (insn
& (1 << 6)) != 0;
5440 u
= (insn
>> 24) & 1;
5441 VFP_DREG_D(rd
, insn
);
5442 VFP_DREG_N(rn
, insn
);
5443 VFP_DREG_M(rm
, insn
);
5444 size
= (insn
>> 20) & 3;
5445 if ((insn
& (1 << 23)) == 0) {
5446 /* Three register same length. */
5447 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5448 /* Catch invalid op and bad size combinations: UNDEF */
5449 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5452 /* All insns of this form UNDEF for either this condition or the
5453 * superset of cases "Q==1"; we catch the latter later.
5455 if (q
&& ((rd
| rn
| rm
) & 1)) {
5459 * The SHA-1/SHA-256 3-register instructions require special treatment
5460 * here, as their size field is overloaded as an op type selector, and
5461 * they all consume their input in a single pass.
5463 if (op
== NEON_3R_SHA
) {
5467 if (!u
) { /* SHA-1 */
5468 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5471 tmp
= tcg_const_i32(rd
);
5472 tmp2
= tcg_const_i32(rn
);
5473 tmp3
= tcg_const_i32(rm
);
5474 tmp4
= tcg_const_i32(size
);
5475 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5476 tcg_temp_free_i32(tmp4
);
5477 } else { /* SHA-256 */
5478 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5481 tmp
= tcg_const_i32(rd
);
5482 tmp2
= tcg_const_i32(rn
);
5483 tmp3
= tcg_const_i32(rm
);
5486 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5489 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5492 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5496 tcg_temp_free_i32(tmp
);
5497 tcg_temp_free_i32(tmp2
);
5498 tcg_temp_free_i32(tmp3
);
5501 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5502 /* 64-bit element instructions. */
5503 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5504 neon_load_reg64(cpu_V0
, rn
+ pass
);
5505 neon_load_reg64(cpu_V1
, rm
+ pass
);
5509 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5512 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5518 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5521 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5527 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5529 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5534 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5537 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5543 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5545 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5548 case NEON_3R_VQRSHL
:
5550 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5553 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5557 case NEON_3R_VADD_VSUB
:
5559 tcg_gen_sub_i64(CPU_V001
);
5561 tcg_gen_add_i64(CPU_V001
);
5567 neon_store_reg64(cpu_V0
, rd
+ pass
);
5576 case NEON_3R_VQRSHL
:
5579 /* Shift instruction operands are reversed. */
5594 case NEON_3R_FLOAT_ARITH
:
5595 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5597 case NEON_3R_FLOAT_MINMAX
:
5598 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5600 case NEON_3R_FLOAT_CMP
:
5602 /* no encoding for U=0 C=1x */
5606 case NEON_3R_FLOAT_ACMP
:
5611 case NEON_3R_FLOAT_MISC
:
5612 /* VMAXNM/VMINNM in ARMv8 */
5613 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5618 if (u
&& (size
!= 0)) {
5619 /* UNDEF on invalid size for polynomial subcase */
5624 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5632 if (pairwise
&& q
) {
5633 /* All the pairwise insns UNDEF if Q is set */
5637 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5642 tmp
= neon_load_reg(rn
, 0);
5643 tmp2
= neon_load_reg(rn
, 1);
5645 tmp
= neon_load_reg(rm
, 0);
5646 tmp2
= neon_load_reg(rm
, 1);
5650 tmp
= neon_load_reg(rn
, pass
);
5651 tmp2
= neon_load_reg(rm
, pass
);
5655 GEN_NEON_INTEGER_OP(hadd
);
5658 GEN_NEON_INTEGER_OP_ENV(qadd
);
5660 case NEON_3R_VRHADD
:
5661 GEN_NEON_INTEGER_OP(rhadd
);
5663 case NEON_3R_LOGIC
: /* Logic ops. */
5664 switch ((u
<< 2) | size
) {
5666 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5669 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5672 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5675 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5678 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5681 tmp3
= neon_load_reg(rd
, pass
);
5682 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5683 tcg_temp_free_i32(tmp3
);
5686 tmp3
= neon_load_reg(rd
, pass
);
5687 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5688 tcg_temp_free_i32(tmp3
);
5691 tmp3
= neon_load_reg(rd
, pass
);
5692 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5693 tcg_temp_free_i32(tmp3
);
5698 GEN_NEON_INTEGER_OP(hsub
);
5701 GEN_NEON_INTEGER_OP_ENV(qsub
);
5704 GEN_NEON_INTEGER_OP(cgt
);
5707 GEN_NEON_INTEGER_OP(cge
);
5710 GEN_NEON_INTEGER_OP(shl
);
5713 GEN_NEON_INTEGER_OP_ENV(qshl
);
5716 GEN_NEON_INTEGER_OP(rshl
);
5718 case NEON_3R_VQRSHL
:
5719 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5722 GEN_NEON_INTEGER_OP(max
);
5725 GEN_NEON_INTEGER_OP(min
);
5728 GEN_NEON_INTEGER_OP(abd
);
5731 GEN_NEON_INTEGER_OP(abd
);
5732 tcg_temp_free_i32(tmp2
);
5733 tmp2
= neon_load_reg(rd
, pass
);
5734 gen_neon_add(size
, tmp
, tmp2
);
5736 case NEON_3R_VADD_VSUB
:
5737 if (!u
) { /* VADD */
5738 gen_neon_add(size
, tmp
, tmp2
);
5741 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5742 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5743 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5748 case NEON_3R_VTST_VCEQ
:
5749 if (!u
) { /* VTST */
5751 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5752 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5753 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5758 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5759 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5760 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5765 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5767 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5768 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5769 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5772 tcg_temp_free_i32(tmp2
);
5773 tmp2
= neon_load_reg(rd
, pass
);
5775 gen_neon_rsb(size
, tmp
, tmp2
);
5777 gen_neon_add(size
, tmp
, tmp2
);
5781 if (u
) { /* polynomial */
5782 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5783 } else { /* Integer */
5785 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5786 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5787 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5793 GEN_NEON_INTEGER_OP(pmax
);
5796 GEN_NEON_INTEGER_OP(pmin
);
5798 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5799 if (!u
) { /* VQDMULH */
5802 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5805 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5809 } else { /* VQRDMULH */
5812 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5815 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5823 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5824 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5825 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5829 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5831 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5832 switch ((u
<< 2) | size
) {
5835 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5838 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5841 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5846 tcg_temp_free_ptr(fpstatus
);
5849 case NEON_3R_FLOAT_MULTIPLY
:
5851 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5852 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5854 tcg_temp_free_i32(tmp2
);
5855 tmp2
= neon_load_reg(rd
, pass
);
5857 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5859 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5862 tcg_temp_free_ptr(fpstatus
);
5865 case NEON_3R_FLOAT_CMP
:
5867 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5869 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5872 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5874 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5877 tcg_temp_free_ptr(fpstatus
);
5880 case NEON_3R_FLOAT_ACMP
:
5882 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5884 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5886 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5888 tcg_temp_free_ptr(fpstatus
);
5891 case NEON_3R_FLOAT_MINMAX
:
5893 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5895 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5897 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5899 tcg_temp_free_ptr(fpstatus
);
5902 case NEON_3R_FLOAT_MISC
:
5905 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5907 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5909 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5911 tcg_temp_free_ptr(fpstatus
);
5914 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5916 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5922 /* VFMA, VFMS: fused multiply-add */
5923 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5924 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5927 gen_helper_vfp_negs(tmp
, tmp
);
5929 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5930 tcg_temp_free_i32(tmp3
);
5931 tcg_temp_free_ptr(fpstatus
);
5937 tcg_temp_free_i32(tmp2
);
5939 /* Save the result. For elementwise operations we can put it
5940 straight into the destination register. For pairwise operations
5941 we have to be careful to avoid clobbering the source operands. */
5942 if (pairwise
&& rd
== rm
) {
5943 neon_store_scratch(pass
, tmp
);
5945 neon_store_reg(rd
, pass
, tmp
);
5949 if (pairwise
&& rd
== rm
) {
5950 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5951 tmp
= neon_load_scratch(pass
);
5952 neon_store_reg(rd
, pass
, tmp
);
5955 /* End of 3 register same size operations. */
5956 } else if (insn
& (1 << 4)) {
5957 if ((insn
& 0x00380080) != 0) {
5958 /* Two registers and shift. */
5959 op
= (insn
>> 8) & 0xf;
5960 if (insn
& (1 << 7)) {
5968 while ((insn
& (1 << (size
+ 19))) == 0)
5971 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5972 /* To avoid excessive duplication of ops we implement shift
5973 by immediate using the variable shift operations. */
5975 /* Shift by immediate:
5976 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5977 if (q
&& ((rd
| rm
) & 1)) {
5980 if (!u
&& (op
== 4 || op
== 6)) {
5983 /* Right shifts are encoded as N - shift, where N is the
5984 element size in bits. */
5986 shift
= shift
- (1 << (size
+ 3));
5994 imm
= (uint8_t) shift
;
5999 imm
= (uint16_t) shift
;
6010 for (pass
= 0; pass
< count
; pass
++) {
6012 neon_load_reg64(cpu_V0
, rm
+ pass
);
6013 tcg_gen_movi_i64(cpu_V1
, imm
);
6018 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6020 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6025 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6027 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
6030 case 5: /* VSHL, VSLI */
6031 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
6033 case 6: /* VQSHLU */
6034 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
6039 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
6042 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
6047 if (op
== 1 || op
== 3) {
6049 neon_load_reg64(cpu_V1
, rd
+ pass
);
6050 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6051 } else if (op
== 4 || (op
== 5 && u
)) {
6053 neon_load_reg64(cpu_V1
, rd
+ pass
);
6055 if (shift
< -63 || shift
> 63) {
6059 mask
= 0xffffffffffffffffull
>> -shift
;
6061 mask
= 0xffffffffffffffffull
<< shift
;
6064 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
6065 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6067 neon_store_reg64(cpu_V0
, rd
+ pass
);
6068 } else { /* size < 3 */
6069 /* Operands in T0 and T1. */
6070 tmp
= neon_load_reg(rm
, pass
);
6071 tmp2
= tcg_temp_new_i32();
6072 tcg_gen_movi_i32(tmp2
, imm
);
6076 GEN_NEON_INTEGER_OP(shl
);
6080 GEN_NEON_INTEGER_OP(rshl
);
6083 case 5: /* VSHL, VSLI */
6085 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
6086 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
6087 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
6091 case 6: /* VQSHLU */
6094 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
6098 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
6102 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
6110 GEN_NEON_INTEGER_OP_ENV(qshl
);
6113 tcg_temp_free_i32(tmp2
);
6115 if (op
== 1 || op
== 3) {
6117 tmp2
= neon_load_reg(rd
, pass
);
6118 gen_neon_add(size
, tmp
, tmp2
);
6119 tcg_temp_free_i32(tmp2
);
6120 } else if (op
== 4 || (op
== 5 && u
)) {
6125 mask
= 0xff >> -shift
;
6127 mask
= (uint8_t)(0xff << shift
);
6133 mask
= 0xffff >> -shift
;
6135 mask
= (uint16_t)(0xffff << shift
);
6139 if (shift
< -31 || shift
> 31) {
6143 mask
= 0xffffffffu
>> -shift
;
6145 mask
= 0xffffffffu
<< shift
;
6151 tmp2
= neon_load_reg(rd
, pass
);
6152 tcg_gen_andi_i32(tmp
, tmp
, mask
);
6153 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
6154 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
6155 tcg_temp_free_i32(tmp2
);
6157 neon_store_reg(rd
, pass
, tmp
);
6160 } else if (op
< 10) {
6161 /* Shift by immediate and narrow:
6162 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6163 int input_unsigned
= (op
== 8) ? !u
: u
;
6167 shift
= shift
- (1 << (size
+ 3));
6170 tmp64
= tcg_const_i64(shift
);
6171 neon_load_reg64(cpu_V0
, rm
);
6172 neon_load_reg64(cpu_V1
, rm
+ 1);
6173 for (pass
= 0; pass
< 2; pass
++) {
6181 if (input_unsigned
) {
6182 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
6184 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
6187 if (input_unsigned
) {
6188 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
6190 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
6193 tmp
= tcg_temp_new_i32();
6194 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6195 neon_store_reg(rd
, pass
, tmp
);
6197 tcg_temp_free_i64(tmp64
);
6200 imm
= (uint16_t)shift
;
6204 imm
= (uint32_t)shift
;
6206 tmp2
= tcg_const_i32(imm
);
6207 tmp4
= neon_load_reg(rm
+ 1, 0);
6208 tmp5
= neon_load_reg(rm
+ 1, 1);
6209 for (pass
= 0; pass
< 2; pass
++) {
6211 tmp
= neon_load_reg(rm
, 0);
6215 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
6218 tmp3
= neon_load_reg(rm
, 1);
6222 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
6224 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
6225 tcg_temp_free_i32(tmp
);
6226 tcg_temp_free_i32(tmp3
);
6227 tmp
= tcg_temp_new_i32();
6228 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
6229 neon_store_reg(rd
, pass
, tmp
);
6231 tcg_temp_free_i32(tmp2
);
6233 } else if (op
== 10) {
6235 if (q
|| (rd
& 1)) {
6238 tmp
= neon_load_reg(rm
, 0);
6239 tmp2
= neon_load_reg(rm
, 1);
6240 for (pass
= 0; pass
< 2; pass
++) {
6244 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6247 /* The shift is less than the width of the source
6248 type, so we can just shift the whole register. */
6249 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
6250 /* Widen the result of shift: we need to clear
6251 * the potential overflow bits resulting from
6252 * left bits of the narrow input appearing as
6253 * right bits of left the neighbour narrow
6255 if (size
< 2 || !u
) {
6258 imm
= (0xffu
>> (8 - shift
));
6260 } else if (size
== 1) {
6261 imm
= 0xffff >> (16 - shift
);
6264 imm
= 0xffffffff >> (32 - shift
);
6267 imm64
= imm
| (((uint64_t)imm
) << 32);
6271 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
6274 neon_store_reg64(cpu_V0
, rd
+ pass
);
6276 } else if (op
>= 14) {
6277 /* VCVT fixed-point. */
6278 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
6281 /* We have already masked out the must-be-1 top bit of imm6,
6282 * hence this 32-shift where the ARM ARM has 64-imm6.
6285 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6286 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
6289 gen_vfp_ulto(0, shift
, 1);
6291 gen_vfp_slto(0, shift
, 1);
6294 gen_vfp_toul(0, shift
, 1);
6296 gen_vfp_tosl(0, shift
, 1);
6298 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6303 } else { /* (insn & 0x00380080) == 0 */
6305 if (q
&& (rd
& 1)) {
6309 op
= (insn
>> 8) & 0xf;
6310 /* One register and immediate. */
6311 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6312 invert
= (insn
& (1 << 5)) != 0;
6313 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6314 * We choose to not special-case this and will behave as if a
6315 * valid constant encoding of 0 had been given.
6334 imm
= (imm
<< 8) | (imm
<< 24);
6337 imm
= (imm
<< 8) | 0xff;
6340 imm
= (imm
<< 16) | 0xffff;
6343 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6351 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6352 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6358 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6359 if (op
& 1 && op
< 12) {
6360 tmp
= neon_load_reg(rd
, pass
);
6362 /* The immediate value has already been inverted, so
6364 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6366 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6370 tmp
= tcg_temp_new_i32();
6371 if (op
== 14 && invert
) {
6375 for (n
= 0; n
< 4; n
++) {
6376 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6377 val
|= 0xff << (n
* 8);
6379 tcg_gen_movi_i32(tmp
, val
);
6381 tcg_gen_movi_i32(tmp
, imm
);
6384 neon_store_reg(rd
, pass
, tmp
);
6387 } else { /* (insn & 0x00800010 == 0x00800000) */
6389 op
= (insn
>> 8) & 0xf;
6390 if ((insn
& (1 << 6)) == 0) {
6391 /* Three registers of different lengths. */
6395 /* undefreq: bit 0 : UNDEF if size == 0
6396 * bit 1 : UNDEF if size == 1
6397 * bit 2 : UNDEF if size == 2
6398 * bit 3 : UNDEF if U == 1
6399 * Note that [2:0] set implies 'always UNDEF'
6402 /* prewiden, src1_wide, src2_wide, undefreq */
6403 static const int neon_3reg_wide
[16][4] = {
6404 {1, 0, 0, 0}, /* VADDL */
6405 {1, 1, 0, 0}, /* VADDW */
6406 {1, 0, 0, 0}, /* VSUBL */
6407 {1, 1, 0, 0}, /* VSUBW */
6408 {0, 1, 1, 0}, /* VADDHN */
6409 {0, 0, 0, 0}, /* VABAL */
6410 {0, 1, 1, 0}, /* VSUBHN */
6411 {0, 0, 0, 0}, /* VABDL */
6412 {0, 0, 0, 0}, /* VMLAL */
6413 {0, 0, 0, 9}, /* VQDMLAL */
6414 {0, 0, 0, 0}, /* VMLSL */
6415 {0, 0, 0, 9}, /* VQDMLSL */
6416 {0, 0, 0, 0}, /* Integer VMULL */
6417 {0, 0, 0, 1}, /* VQDMULL */
6418 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6419 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6422 prewiden
= neon_3reg_wide
[op
][0];
6423 src1_wide
= neon_3reg_wide
[op
][1];
6424 src2_wide
= neon_3reg_wide
[op
][2];
6425 undefreq
= neon_3reg_wide
[op
][3];
6427 if ((undefreq
& (1 << size
)) ||
6428 ((undefreq
& 8) && u
)) {
6431 if ((src1_wide
&& (rn
& 1)) ||
6432 (src2_wide
&& (rm
& 1)) ||
6433 (!src2_wide
&& (rd
& 1))) {
6437 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6438 * outside the loop below as it only performs a single pass.
6440 if (op
== 14 && size
== 2) {
6441 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6443 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6446 tcg_rn
= tcg_temp_new_i64();
6447 tcg_rm
= tcg_temp_new_i64();
6448 tcg_rd
= tcg_temp_new_i64();
6449 neon_load_reg64(tcg_rn
, rn
);
6450 neon_load_reg64(tcg_rm
, rm
);
6451 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6452 neon_store_reg64(tcg_rd
, rd
);
6453 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6454 neon_store_reg64(tcg_rd
, rd
+ 1);
6455 tcg_temp_free_i64(tcg_rn
);
6456 tcg_temp_free_i64(tcg_rm
);
6457 tcg_temp_free_i64(tcg_rd
);
6461 /* Avoid overlapping operands. Wide source operands are
6462 always aligned so will never overlap with wide
6463 destinations in problematic ways. */
6464 if (rd
== rm
&& !src2_wide
) {
6465 tmp
= neon_load_reg(rm
, 1);
6466 neon_store_scratch(2, tmp
);
6467 } else if (rd
== rn
&& !src1_wide
) {
6468 tmp
= neon_load_reg(rn
, 1);
6469 neon_store_scratch(2, tmp
);
6471 TCGV_UNUSED_I32(tmp3
);
6472 for (pass
= 0; pass
< 2; pass
++) {
6474 neon_load_reg64(cpu_V0
, rn
+ pass
);
6475 TCGV_UNUSED_I32(tmp
);
6477 if (pass
== 1 && rd
== rn
) {
6478 tmp
= neon_load_scratch(2);
6480 tmp
= neon_load_reg(rn
, pass
);
6483 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6487 neon_load_reg64(cpu_V1
, rm
+ pass
);
6488 TCGV_UNUSED_I32(tmp2
);
6490 if (pass
== 1 && rd
== rm
) {
6491 tmp2
= neon_load_scratch(2);
6493 tmp2
= neon_load_reg(rm
, pass
);
6496 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6500 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6501 gen_neon_addl(size
);
6503 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6504 gen_neon_subl(size
);
6506 case 5: case 7: /* VABAL, VABDL */
6507 switch ((size
<< 1) | u
) {
6509 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6512 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6515 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6518 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6521 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6524 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6528 tcg_temp_free_i32(tmp2
);
6529 tcg_temp_free_i32(tmp
);
6531 case 8: case 9: case 10: case 11: case 12: case 13:
6532 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6533 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6535 case 14: /* Polynomial VMULL */
6536 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6537 tcg_temp_free_i32(tmp2
);
6538 tcg_temp_free_i32(tmp
);
6540 default: /* 15 is RESERVED: caught earlier */
6545 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6546 neon_store_reg64(cpu_V0
, rd
+ pass
);
6547 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6549 neon_load_reg64(cpu_V1
, rd
+ pass
);
6551 case 10: /* VMLSL */
6552 gen_neon_negl(cpu_V0
, size
);
6554 case 5: case 8: /* VABAL, VMLAL */
6555 gen_neon_addl(size
);
6557 case 9: case 11: /* VQDMLAL, VQDMLSL */
6558 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6560 gen_neon_negl(cpu_V0
, size
);
6562 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6567 neon_store_reg64(cpu_V0
, rd
+ pass
);
6568 } else if (op
== 4 || op
== 6) {
6569 /* Narrowing operation. */
6570 tmp
= tcg_temp_new_i32();
6574 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6577 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6580 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6581 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6588 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6591 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6594 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6595 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6596 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6604 neon_store_reg(rd
, 0, tmp3
);
6605 neon_store_reg(rd
, 1, tmp
);
6608 /* Write back the result. */
6609 neon_store_reg64(cpu_V0
, rd
+ pass
);
6613 /* Two registers and a scalar. NB that for ops of this form
6614 * the ARM ARM labels bit 24 as Q, but it is in our variable
6621 case 1: /* Float VMLA scalar */
6622 case 5: /* Floating point VMLS scalar */
6623 case 9: /* Floating point VMUL scalar */
6628 case 0: /* Integer VMLA scalar */
6629 case 4: /* Integer VMLS scalar */
6630 case 8: /* Integer VMUL scalar */
6631 case 12: /* VQDMULH scalar */
6632 case 13: /* VQRDMULH scalar */
6633 if (u
&& ((rd
| rn
) & 1)) {
6636 tmp
= neon_get_scalar(size
, rm
);
6637 neon_store_scratch(0, tmp
);
6638 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6639 tmp
= neon_load_scratch(0);
6640 tmp2
= neon_load_reg(rn
, pass
);
6643 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6645 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6647 } else if (op
== 13) {
6649 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6651 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6653 } else if (op
& 1) {
6654 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6655 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6656 tcg_temp_free_ptr(fpstatus
);
6659 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6660 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6661 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6665 tcg_temp_free_i32(tmp2
);
6668 tmp2
= neon_load_reg(rd
, pass
);
6671 gen_neon_add(size
, tmp
, tmp2
);
6675 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6676 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6677 tcg_temp_free_ptr(fpstatus
);
6681 gen_neon_rsb(size
, tmp
, tmp2
);
6685 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6686 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6687 tcg_temp_free_ptr(fpstatus
);
6693 tcg_temp_free_i32(tmp2
);
6695 neon_store_reg(rd
, pass
, tmp
);
6698 case 3: /* VQDMLAL scalar */
6699 case 7: /* VQDMLSL scalar */
6700 case 11: /* VQDMULL scalar */
6705 case 2: /* VMLAL sclar */
6706 case 6: /* VMLSL scalar */
6707 case 10: /* VMULL scalar */
6711 tmp2
= neon_get_scalar(size
, rm
);
6712 /* We need a copy of tmp2 because gen_neon_mull
6713 * deletes it during pass 0. */
6714 tmp4
= tcg_temp_new_i32();
6715 tcg_gen_mov_i32(tmp4
, tmp2
);
6716 tmp3
= neon_load_reg(rn
, 1);
6718 for (pass
= 0; pass
< 2; pass
++) {
6720 tmp
= neon_load_reg(rn
, 0);
6725 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6727 neon_load_reg64(cpu_V1
, rd
+ pass
);
6731 gen_neon_negl(cpu_V0
, size
);
6734 gen_neon_addl(size
);
6737 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6739 gen_neon_negl(cpu_V0
, size
);
6741 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6747 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6752 neon_store_reg64(cpu_V0
, rd
+ pass
);
6757 default: /* 14 and 15 are RESERVED */
6761 } else { /* size == 3 */
6764 imm
= (insn
>> 8) & 0xf;
6769 if (q
&& ((rd
| rn
| rm
) & 1)) {
6774 neon_load_reg64(cpu_V0
, rn
);
6776 neon_load_reg64(cpu_V1
, rn
+ 1);
6778 } else if (imm
== 8) {
6779 neon_load_reg64(cpu_V0
, rn
+ 1);
6781 neon_load_reg64(cpu_V1
, rm
);
6784 tmp64
= tcg_temp_new_i64();
6786 neon_load_reg64(cpu_V0
, rn
);
6787 neon_load_reg64(tmp64
, rn
+ 1);
6789 neon_load_reg64(cpu_V0
, rn
+ 1);
6790 neon_load_reg64(tmp64
, rm
);
6792 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6793 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6794 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6796 neon_load_reg64(cpu_V1
, rm
);
6798 neon_load_reg64(cpu_V1
, rm
+ 1);
6801 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6802 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6803 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6804 tcg_temp_free_i64(tmp64
);
6807 neon_load_reg64(cpu_V0
, rn
);
6808 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6809 neon_load_reg64(cpu_V1
, rm
);
6810 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6811 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6813 neon_store_reg64(cpu_V0
, rd
);
6815 neon_store_reg64(cpu_V1
, rd
+ 1);
6817 } else if ((insn
& (1 << 11)) == 0) {
6818 /* Two register misc. */
6819 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6820 size
= (insn
>> 18) & 3;
6821 /* UNDEF for unknown op values and bad op-size combinations */
6822 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6825 if (neon_2rm_is_v8_op(op
) &&
6826 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6829 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6830 q
&& ((rm
| rd
) & 1)) {
6834 case NEON_2RM_VREV64
:
6835 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6836 tmp
= neon_load_reg(rm
, pass
* 2);
6837 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6839 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6840 case 1: gen_swap_half(tmp
); break;
6841 case 2: /* no-op */ break;
6844 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6846 neon_store_reg(rd
, pass
* 2, tmp2
);
6849 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6850 case 1: gen_swap_half(tmp2
); break;
6853 neon_store_reg(rd
, pass
* 2, tmp2
);
6857 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6858 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6859 for (pass
= 0; pass
< q
+ 1; pass
++) {
6860 tmp
= neon_load_reg(rm
, pass
* 2);
6861 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6862 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6863 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6865 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6866 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6867 case 2: tcg_gen_add_i64(CPU_V001
); break;
6870 if (op
>= NEON_2RM_VPADAL
) {
6872 neon_load_reg64(cpu_V1
, rd
+ pass
);
6873 gen_neon_addl(size
);
6875 neon_store_reg64(cpu_V0
, rd
+ pass
);
6881 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6882 tmp
= neon_load_reg(rm
, n
);
6883 tmp2
= neon_load_reg(rd
, n
+ 1);
6884 neon_store_reg(rm
, n
, tmp2
);
6885 neon_store_reg(rd
, n
+ 1, tmp
);
6892 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6897 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6901 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6902 /* also VQMOVUN; op field and mnemonics don't line up */
6906 TCGV_UNUSED_I32(tmp2
);
6907 for (pass
= 0; pass
< 2; pass
++) {
6908 neon_load_reg64(cpu_V0
, rm
+ pass
);
6909 tmp
= tcg_temp_new_i32();
6910 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6915 neon_store_reg(rd
, 0, tmp2
);
6916 neon_store_reg(rd
, 1, tmp
);
6920 case NEON_2RM_VSHLL
:
6921 if (q
|| (rd
& 1)) {
6924 tmp
= neon_load_reg(rm
, 0);
6925 tmp2
= neon_load_reg(rm
, 1);
6926 for (pass
= 0; pass
< 2; pass
++) {
6929 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6930 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6931 neon_store_reg64(cpu_V0
, rd
+ pass
);
6934 case NEON_2RM_VCVT_F16_F32
:
6935 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6939 tmp
= tcg_temp_new_i32();
6940 tmp2
= tcg_temp_new_i32();
6941 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6942 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6943 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6944 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6945 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6946 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6947 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6948 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6949 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6950 neon_store_reg(rd
, 0, tmp2
);
6951 tmp2
= tcg_temp_new_i32();
6952 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6953 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6954 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6955 neon_store_reg(rd
, 1, tmp2
);
6956 tcg_temp_free_i32(tmp
);
6958 case NEON_2RM_VCVT_F32_F16
:
6959 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6963 tmp3
= tcg_temp_new_i32();
6964 tmp
= neon_load_reg(rm
, 0);
6965 tmp2
= neon_load_reg(rm
, 1);
6966 tcg_gen_ext16u_i32(tmp3
, tmp
);
6967 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6968 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6969 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6970 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6971 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6972 tcg_temp_free_i32(tmp
);
6973 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6974 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6975 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6976 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6977 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6978 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6979 tcg_temp_free_i32(tmp2
);
6980 tcg_temp_free_i32(tmp3
);
6982 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6983 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6984 || ((rm
| rd
) & 1)) {
6987 tmp
= tcg_const_i32(rd
);
6988 tmp2
= tcg_const_i32(rm
);
6990 /* Bit 6 is the lowest opcode bit; it distinguishes between
6991 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6993 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6995 if (op
== NEON_2RM_AESE
) {
6996 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6998 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
7000 tcg_temp_free_i32(tmp
);
7001 tcg_temp_free_i32(tmp2
);
7002 tcg_temp_free_i32(tmp3
);
7004 case NEON_2RM_SHA1H
:
7005 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
7006 || ((rm
| rd
) & 1)) {
7009 tmp
= tcg_const_i32(rd
);
7010 tmp2
= tcg_const_i32(rm
);
7012 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
7014 tcg_temp_free_i32(tmp
);
7015 tcg_temp_free_i32(tmp2
);
7017 case NEON_2RM_SHA1SU1
:
7018 if ((rm
| rd
) & 1) {
7021 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7023 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
7026 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
7029 tmp
= tcg_const_i32(rd
);
7030 tmp2
= tcg_const_i32(rm
);
7032 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
7034 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
7036 tcg_temp_free_i32(tmp
);
7037 tcg_temp_free_i32(tmp2
);
7041 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7042 if (neon_2rm_is_float_op(op
)) {
7043 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
7044 neon_reg_offset(rm
, pass
));
7045 TCGV_UNUSED_I32(tmp
);
7047 tmp
= neon_load_reg(rm
, pass
);
7050 case NEON_2RM_VREV32
:
7052 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
7053 case 1: gen_swap_half(tmp
); break;
7057 case NEON_2RM_VREV16
:
7062 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
7063 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
7064 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
7070 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
7071 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
7072 case 2: gen_helper_clz(tmp
, tmp
); break;
7077 gen_helper_neon_cnt_u8(tmp
, tmp
);
7080 tcg_gen_not_i32(tmp
, tmp
);
7082 case NEON_2RM_VQABS
:
7085 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
7088 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
7091 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
7096 case NEON_2RM_VQNEG
:
7099 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
7102 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
7105 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
7110 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
7111 tmp2
= tcg_const_i32(0);
7113 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
7114 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
7115 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
7118 tcg_temp_free_i32(tmp2
);
7119 if (op
== NEON_2RM_VCLE0
) {
7120 tcg_gen_not_i32(tmp
, tmp
);
7123 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
7124 tmp2
= tcg_const_i32(0);
7126 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
7127 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
7128 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
7131 tcg_temp_free_i32(tmp2
);
7132 if (op
== NEON_2RM_VCLT0
) {
7133 tcg_gen_not_i32(tmp
, tmp
);
7136 case NEON_2RM_VCEQ0
:
7137 tmp2
= tcg_const_i32(0);
7139 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
7140 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
7141 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
7144 tcg_temp_free_i32(tmp2
);
7148 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
7149 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
7150 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
7155 tmp2
= tcg_const_i32(0);
7156 gen_neon_rsb(size
, tmp
, tmp2
);
7157 tcg_temp_free_i32(tmp2
);
7159 case NEON_2RM_VCGT0_F
:
7161 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7162 tmp2
= tcg_const_i32(0);
7163 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
7164 tcg_temp_free_i32(tmp2
);
7165 tcg_temp_free_ptr(fpstatus
);
7168 case NEON_2RM_VCGE0_F
:
7170 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7171 tmp2
= tcg_const_i32(0);
7172 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
7173 tcg_temp_free_i32(tmp2
);
7174 tcg_temp_free_ptr(fpstatus
);
7177 case NEON_2RM_VCEQ0_F
:
7179 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7180 tmp2
= tcg_const_i32(0);
7181 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
7182 tcg_temp_free_i32(tmp2
);
7183 tcg_temp_free_ptr(fpstatus
);
7186 case NEON_2RM_VCLE0_F
:
7188 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7189 tmp2
= tcg_const_i32(0);
7190 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
7191 tcg_temp_free_i32(tmp2
);
7192 tcg_temp_free_ptr(fpstatus
);
7195 case NEON_2RM_VCLT0_F
:
7197 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7198 tmp2
= tcg_const_i32(0);
7199 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
7200 tcg_temp_free_i32(tmp2
);
7201 tcg_temp_free_ptr(fpstatus
);
7204 case NEON_2RM_VABS_F
:
7207 case NEON_2RM_VNEG_F
:
7211 tmp2
= neon_load_reg(rd
, pass
);
7212 neon_store_reg(rm
, pass
, tmp2
);
7215 tmp2
= neon_load_reg(rd
, pass
);
7217 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
7218 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
7221 neon_store_reg(rm
, pass
, tmp2
);
7223 case NEON_2RM_VRINTN
:
7224 case NEON_2RM_VRINTA
:
7225 case NEON_2RM_VRINTM
:
7226 case NEON_2RM_VRINTP
:
7227 case NEON_2RM_VRINTZ
:
7230 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7233 if (op
== NEON_2RM_VRINTZ
) {
7234 rmode
= FPROUNDING_ZERO
;
7236 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
7239 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7240 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7242 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
7243 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7245 tcg_temp_free_ptr(fpstatus
);
7246 tcg_temp_free_i32(tcg_rmode
);
7249 case NEON_2RM_VRINTX
:
7251 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7252 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
7253 tcg_temp_free_ptr(fpstatus
);
7256 case NEON_2RM_VCVTAU
:
7257 case NEON_2RM_VCVTAS
:
7258 case NEON_2RM_VCVTNU
:
7259 case NEON_2RM_VCVTNS
:
7260 case NEON_2RM_VCVTPU
:
7261 case NEON_2RM_VCVTPS
:
7262 case NEON_2RM_VCVTMU
:
7263 case NEON_2RM_VCVTMS
:
7265 bool is_signed
= !extract32(insn
, 7, 1);
7266 TCGv_ptr fpst
= get_fpstatus_ptr(1);
7267 TCGv_i32 tcg_rmode
, tcg_shift
;
7268 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
7270 tcg_shift
= tcg_const_i32(0);
7271 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
7272 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7276 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
7279 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
7283 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
7285 tcg_temp_free_i32(tcg_rmode
);
7286 tcg_temp_free_i32(tcg_shift
);
7287 tcg_temp_free_ptr(fpst
);
7290 case NEON_2RM_VRECPE
:
7292 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7293 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
7294 tcg_temp_free_ptr(fpstatus
);
7297 case NEON_2RM_VRSQRTE
:
7299 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7300 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7301 tcg_temp_free_ptr(fpstatus
);
7304 case NEON_2RM_VRECPE_F
:
7306 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7307 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7308 tcg_temp_free_ptr(fpstatus
);
7311 case NEON_2RM_VRSQRTE_F
:
7313 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7314 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7315 tcg_temp_free_ptr(fpstatus
);
7318 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7321 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7324 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7325 gen_vfp_tosiz(0, 1);
7327 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7328 gen_vfp_touiz(0, 1);
7331 /* Reserved op values were caught by the
7332 * neon_2rm_sizes[] check earlier.
7336 if (neon_2rm_is_float_op(op
)) {
7337 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7338 neon_reg_offset(rd
, pass
));
7340 neon_store_reg(rd
, pass
, tmp
);
7345 } else if ((insn
& (1 << 10)) == 0) {
7347 int n
= ((insn
>> 8) & 3) + 1;
7348 if ((rn
+ n
) > 32) {
7349 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7350 * helper function running off the end of the register file.
7355 if (insn
& (1 << 6)) {
7356 tmp
= neon_load_reg(rd
, 0);
7358 tmp
= tcg_temp_new_i32();
7359 tcg_gen_movi_i32(tmp
, 0);
7361 tmp2
= neon_load_reg(rm
, 0);
7362 tmp4
= tcg_const_i32(rn
);
7363 tmp5
= tcg_const_i32(n
);
7364 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7365 tcg_temp_free_i32(tmp
);
7366 if (insn
& (1 << 6)) {
7367 tmp
= neon_load_reg(rd
, 1);
7369 tmp
= tcg_temp_new_i32();
7370 tcg_gen_movi_i32(tmp
, 0);
7372 tmp3
= neon_load_reg(rm
, 1);
7373 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7374 tcg_temp_free_i32(tmp5
);
7375 tcg_temp_free_i32(tmp4
);
7376 neon_store_reg(rd
, 0, tmp2
);
7377 neon_store_reg(rd
, 1, tmp3
);
7378 tcg_temp_free_i32(tmp
);
7379 } else if ((insn
& 0x380) == 0) {
7381 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7384 if (insn
& (1 << 19)) {
7385 tmp
= neon_load_reg(rm
, 1);
7387 tmp
= neon_load_reg(rm
, 0);
7389 if (insn
& (1 << 16)) {
7390 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7391 } else if (insn
& (1 << 17)) {
7392 if ((insn
>> 18) & 1)
7393 gen_neon_dup_high16(tmp
);
7395 gen_neon_dup_low16(tmp
);
7397 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7398 tmp2
= tcg_temp_new_i32();
7399 tcg_gen_mov_i32(tmp2
, tmp
);
7400 neon_store_reg(rd
, pass
, tmp2
);
7402 tcg_temp_free_i32(tmp
);
7411 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7413 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7414 const ARMCPRegInfo
*ri
;
7416 cpnum
= (insn
>> 8) & 0xf;
7418 /* First check for coprocessor space used for XScale/iwMMXt insns */
7419 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7420 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7423 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7424 return disas_iwmmxt_insn(s
, insn
);
7425 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7426 return disas_dsp_insn(s
, insn
);
7431 /* Otherwise treat as a generic register access */
7432 is64
= (insn
& (1 << 25)) == 0;
7433 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7441 opc1
= (insn
>> 4) & 0xf;
7443 rt2
= (insn
>> 16) & 0xf;
7445 crn
= (insn
>> 16) & 0xf;
7446 opc1
= (insn
>> 21) & 7;
7447 opc2
= (insn
>> 5) & 7;
7450 isread
= (insn
>> 20) & 1;
7451 rt
= (insn
>> 12) & 0xf;
7453 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7454 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7456 /* Check access permissions */
7457 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7462 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7463 /* Emit code to perform further access permissions checks at
7464 * runtime; this may result in an exception.
7465 * Note that on XScale all cp0..c13 registers do an access check
7466 * call in order to handle c15_cpar.
7469 TCGv_i32 tcg_syn
, tcg_isread
;
7472 /* Note that since we are an implementation which takes an
7473 * exception on a trapped conditional instruction only if the
7474 * instruction passes its condition code check, we can take
7475 * advantage of the clause in the ARM ARM that allows us to set
7476 * the COND field in the instruction to 0xE in all cases.
7477 * We could fish the actual condition out of the insn (ARM)
7478 * or the condexec bits (Thumb) but it isn't necessary.
7483 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7486 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7492 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7495 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7500 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7501 * so this can only happen if this is an ARMv7 or earlier CPU,
7502 * in which case the syndrome information won't actually be
7505 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7506 syndrome
= syn_uncategorized();
7510 gen_set_condexec(s
);
7511 gen_set_pc_im(s
, s
->pc
- 4);
7512 tmpptr
= tcg_const_ptr(ri
);
7513 tcg_syn
= tcg_const_i32(syndrome
);
7514 tcg_isread
= tcg_const_i32(isread
);
7515 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7517 tcg_temp_free_ptr(tmpptr
);
7518 tcg_temp_free_i32(tcg_syn
);
7519 tcg_temp_free_i32(tcg_isread
);
7522 /* Handle special cases first */
7523 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7530 gen_set_pc_im(s
, s
->pc
);
7531 s
->is_jmp
= DISAS_WFI
;
7537 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7546 if (ri
->type
& ARM_CP_CONST
) {
7547 tmp64
= tcg_const_i64(ri
->resetvalue
);
7548 } else if (ri
->readfn
) {
7550 tmp64
= tcg_temp_new_i64();
7551 tmpptr
= tcg_const_ptr(ri
);
7552 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7553 tcg_temp_free_ptr(tmpptr
);
7555 tmp64
= tcg_temp_new_i64();
7556 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7558 tmp
= tcg_temp_new_i32();
7559 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7560 store_reg(s
, rt
, tmp
);
7561 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7562 tmp
= tcg_temp_new_i32();
7563 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7564 tcg_temp_free_i64(tmp64
);
7565 store_reg(s
, rt2
, tmp
);
7568 if (ri
->type
& ARM_CP_CONST
) {
7569 tmp
= tcg_const_i32(ri
->resetvalue
);
7570 } else if (ri
->readfn
) {
7572 tmp
= tcg_temp_new_i32();
7573 tmpptr
= tcg_const_ptr(ri
);
7574 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7575 tcg_temp_free_ptr(tmpptr
);
7577 tmp
= load_cpu_offset(ri
->fieldoffset
);
7580 /* Destination register of r15 for 32 bit loads sets
7581 * the condition codes from the high 4 bits of the value
7584 tcg_temp_free_i32(tmp
);
7586 store_reg(s
, rt
, tmp
);
7591 if (ri
->type
& ARM_CP_CONST
) {
7592 /* If not forbidden by access permissions, treat as WI */
7597 TCGv_i32 tmplo
, tmphi
;
7598 TCGv_i64 tmp64
= tcg_temp_new_i64();
7599 tmplo
= load_reg(s
, rt
);
7600 tmphi
= load_reg(s
, rt2
);
7601 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7602 tcg_temp_free_i32(tmplo
);
7603 tcg_temp_free_i32(tmphi
);
7605 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7606 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7607 tcg_temp_free_ptr(tmpptr
);
7609 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7611 tcg_temp_free_i64(tmp64
);
7616 tmp
= load_reg(s
, rt
);
7617 tmpptr
= tcg_const_ptr(ri
);
7618 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7619 tcg_temp_free_ptr(tmpptr
);
7620 tcg_temp_free_i32(tmp
);
7622 TCGv_i32 tmp
= load_reg(s
, rt
);
7623 store_cpu_offset(tmp
, ri
->fieldoffset
);
7628 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7629 /* I/O operations must end the TB here (whether read or write) */
7632 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7633 /* We default to ending the TB on a coprocessor register write,
7634 * but allow this to be suppressed by the register definition
7635 * (usually only necessary to work around guest bugs).
7643 /* Unknown register; this might be a guest error or a QEMU
7644 * unimplemented feature.
7647 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7648 "64 bit system register cp:%d opc1: %d crm:%d "
7650 isread
? "read" : "write", cpnum
, opc1
, crm
,
7651 s
->ns
? "non-secure" : "secure");
7653 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7654 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7656 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7657 s
->ns
? "non-secure" : "secure");
7664 /* Store a 64-bit value to a register pair. Clobbers val. */
7665 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7668 tmp
= tcg_temp_new_i32();
7669 tcg_gen_extrl_i64_i32(tmp
, val
);
7670 store_reg(s
, rlow
, tmp
);
7671 tmp
= tcg_temp_new_i32();
7672 tcg_gen_shri_i64(val
, val
, 32);
7673 tcg_gen_extrl_i64_i32(tmp
, val
);
7674 store_reg(s
, rhigh
, tmp
);
7677 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7678 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7683 /* Load value and extend to 64 bits. */
7684 tmp
= tcg_temp_new_i64();
7685 tmp2
= load_reg(s
, rlow
);
7686 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7687 tcg_temp_free_i32(tmp2
);
7688 tcg_gen_add_i64(val
, val
, tmp
);
7689 tcg_temp_free_i64(tmp
);
7692 /* load and add a 64-bit value from a register pair. */
7693 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7699 /* Load 64-bit value rd:rn. */
7700 tmpl
= load_reg(s
, rlow
);
7701 tmph
= load_reg(s
, rhigh
);
7702 tmp
= tcg_temp_new_i64();
7703 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7704 tcg_temp_free_i32(tmpl
);
7705 tcg_temp_free_i32(tmph
);
7706 tcg_gen_add_i64(val
, val
, tmp
);
7707 tcg_temp_free_i64(tmp
);
7710 /* Set N and Z flags from hi|lo. */
7711 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7713 tcg_gen_mov_i32(cpu_NF
, hi
);
7714 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7717 /* Load/Store exclusive instructions are implemented by remembering
7718 the value/address loaded, and seeing if these are the same
7719 when the store is performed. This should be sufficient to implement
7720 the architecturally mandated semantics, and avoids having to monitor
7723 In system emulation mode only one CPU will be running at once, so
7724 this sequence is effectively atomic. In user emulation mode we
7725 throw an exception and handle the atomic operation elsewhere. */
7726 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7727 TCGv_i32 addr
, int size
)
7729 TCGv_i32 tmp
= tcg_temp_new_i32();
7735 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7738 gen_aa32_ld16ua(s
, tmp
, addr
, get_mem_index(s
));
7742 gen_aa32_ld32ua(s
, tmp
, addr
, get_mem_index(s
));
7749 TCGv_i32 tmp2
= tcg_temp_new_i32();
7750 TCGv_i32 tmp3
= tcg_temp_new_i32();
7752 tcg_gen_addi_i32(tmp2
, addr
, 4);
7753 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7754 tcg_temp_free_i32(tmp2
);
7755 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7756 store_reg(s
, rt2
, tmp3
);
7758 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7761 store_reg(s
, rt
, tmp
);
7762 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7765 static void gen_clrex(DisasContext
*s
)
7767 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7770 #ifdef CONFIG_USER_ONLY
7771 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7772 TCGv_i32 addr
, int size
)
7774 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7775 tcg_gen_movi_i32(cpu_exclusive_info
,
7776 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7777 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7780 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7781 TCGv_i32 addr
, int size
)
7784 TCGv_i64 val64
, extaddr
;
7785 TCGLabel
*done_label
;
7786 TCGLabel
*fail_label
;
7788 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7794 fail_label
= gen_new_label();
7795 done_label
= gen_new_label();
7796 extaddr
= tcg_temp_new_i64();
7797 tcg_gen_extu_i32_i64(extaddr
, addr
);
7798 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7799 tcg_temp_free_i64(extaddr
);
7801 tmp
= tcg_temp_new_i32();
7804 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
7807 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
7811 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7817 val64
= tcg_temp_new_i64();
7819 TCGv_i32 tmp2
= tcg_temp_new_i32();
7820 TCGv_i32 tmp3
= tcg_temp_new_i32();
7821 tcg_gen_addi_i32(tmp2
, addr
, 4);
7822 gen_aa32_ld32u(s
, tmp3
, tmp2
, get_mem_index(s
));
7823 tcg_temp_free_i32(tmp2
);
7824 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7825 tcg_temp_free_i32(tmp3
);
7827 tcg_gen_extu_i32_i64(val64
, tmp
);
7829 tcg_temp_free_i32(tmp
);
7831 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7832 tcg_temp_free_i64(val64
);
7834 tmp
= load_reg(s
, rt
);
7837 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
7840 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
7844 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7849 tcg_temp_free_i32(tmp
);
7851 tcg_gen_addi_i32(addr
, addr
, 4);
7852 tmp
= load_reg(s
, rt2
);
7853 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7854 tcg_temp_free_i32(tmp
);
7856 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7857 tcg_gen_br(done_label
);
7858 gen_set_label(fail_label
);
7859 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7860 gen_set_label(done_label
);
7861 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7868 * @mode: mode field from insn (which stack to store to)
7869 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7870 * @writeback: true if writeback bit set
7872 * Generate code for the SRS (Store Return State) insn.
7874 static void gen_srs(DisasContext
*s
,
7875 uint32_t mode
, uint32_t amode
, bool writeback
)
7882 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7883 * and specified mode is monitor mode
7884 * - UNDEFINED in Hyp mode
7885 * - UNPREDICTABLE in User or System mode
7886 * - UNPREDICTABLE if the specified mode is:
7887 * -- not implemented
7888 * -- not a valid mode number
7889 * -- a mode that's at a higher exception level
7890 * -- Monitor, if we are Non-secure
7891 * For the UNPREDICTABLE cases we choose to UNDEF.
7893 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7894 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7898 if (s
->current_el
== 0 || s
->current_el
== 2) {
7903 case ARM_CPU_MODE_USR
:
7904 case ARM_CPU_MODE_FIQ
:
7905 case ARM_CPU_MODE_IRQ
:
7906 case ARM_CPU_MODE_SVC
:
7907 case ARM_CPU_MODE_ABT
:
7908 case ARM_CPU_MODE_UND
:
7909 case ARM_CPU_MODE_SYS
:
7911 case ARM_CPU_MODE_HYP
:
7912 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7916 case ARM_CPU_MODE_MON
:
7917 /* No need to check specifically for "are we non-secure" because
7918 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7919 * so if this isn't EL3 then we must be non-secure.
7921 if (s
->current_el
!= 3) {
7930 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
7931 default_exception_el(s
));
7935 addr
= tcg_temp_new_i32();
7936 tmp
= tcg_const_i32(mode
);
7937 /* get_r13_banked() will raise an exception if called from System mode */
7938 gen_set_condexec(s
);
7939 gen_set_pc_im(s
, s
->pc
- 4);
7940 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7941 tcg_temp_free_i32(tmp
);
7958 tcg_gen_addi_i32(addr
, addr
, offset
);
7959 tmp
= load_reg(s
, 14);
7960 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7961 tcg_temp_free_i32(tmp
);
7962 tmp
= load_cpu_field(spsr
);
7963 tcg_gen_addi_i32(addr
, addr
, 4);
7964 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7965 tcg_temp_free_i32(tmp
);
7983 tcg_gen_addi_i32(addr
, addr
, offset
);
7984 tmp
= tcg_const_i32(mode
);
7985 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7986 tcg_temp_free_i32(tmp
);
7988 tcg_temp_free_i32(addr
);
7989 s
->is_jmp
= DISAS_UPDATE
;
7992 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7994 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
8001 /* M variants do not implement ARM mode. */
8002 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8007 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8008 * choose to UNDEF. In ARMv5 and above the space is used
8009 * for miscellaneous unconditional instructions.
8013 /* Unconditional instructions. */
8014 if (((insn
>> 25) & 7) == 1) {
8015 /* NEON Data processing. */
8016 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8020 if (disas_neon_data_insn(s
, insn
)) {
8025 if ((insn
& 0x0f100000) == 0x04000000) {
8026 /* NEON load/store. */
8027 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
8031 if (disas_neon_ls_insn(s
, insn
)) {
8036 if ((insn
& 0x0f000e10) == 0x0e000a00) {
8038 if (disas_vfp_insn(s
, insn
)) {
8043 if (((insn
& 0x0f30f000) == 0x0510f000) ||
8044 ((insn
& 0x0f30f010) == 0x0710f000)) {
8045 if ((insn
& (1 << 22)) == 0) {
8047 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8051 /* Otherwise PLD; v5TE+ */
8055 if (((insn
& 0x0f70f000) == 0x0450f000) ||
8056 ((insn
& 0x0f70f010) == 0x0650f000)) {
8058 return; /* PLI; V7 */
8060 if (((insn
& 0x0f700000) == 0x04100000) ||
8061 ((insn
& 0x0f700010) == 0x06100000)) {
8062 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
8065 return; /* v7MP: Unallocated memory hint: must NOP */
8068 if ((insn
& 0x0ffffdff) == 0x01010000) {
8071 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
8072 gen_helper_setend(cpu_env
);
8073 s
->is_jmp
= DISAS_UPDATE
;
8076 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
8077 switch ((insn
>> 4) & 0xf) {
8085 /* We don't emulate caches so these are a no-op. */
8088 /* We need to break the TB after this insn to execute
8089 * self-modifying code correctly and also to take
8090 * any pending interrupts immediately.
8097 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
8100 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
8102 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
8108 rn
= (insn
>> 16) & 0xf;
8109 addr
= load_reg(s
, rn
);
8110 i
= (insn
>> 23) & 3;
8112 case 0: offset
= -4; break; /* DA */
8113 case 1: offset
= 0; break; /* IA */
8114 case 2: offset
= -8; break; /* DB */
8115 case 3: offset
= 4; break; /* IB */
8119 tcg_gen_addi_i32(addr
, addr
, offset
);
8120 /* Load PC into tmp and CPSR into tmp2. */
8121 tmp
= tcg_temp_new_i32();
8122 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8123 tcg_gen_addi_i32(addr
, addr
, 4);
8124 tmp2
= tcg_temp_new_i32();
8125 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8126 if (insn
& (1 << 21)) {
8127 /* Base writeback. */
8129 case 0: offset
= -8; break;
8130 case 1: offset
= 4; break;
8131 case 2: offset
= -4; break;
8132 case 3: offset
= 0; break;
8136 tcg_gen_addi_i32(addr
, addr
, offset
);
8137 store_reg(s
, rn
, addr
);
8139 tcg_temp_free_i32(addr
);
8141 gen_rfe(s
, tmp
, tmp2
);
8143 } else if ((insn
& 0x0e000000) == 0x0a000000) {
8144 /* branch link and change to thumb (blx <offset>) */
8147 val
= (uint32_t)s
->pc
;
8148 tmp
= tcg_temp_new_i32();
8149 tcg_gen_movi_i32(tmp
, val
);
8150 store_reg(s
, 14, tmp
);
8151 /* Sign-extend the 24-bit offset */
8152 offset
= (((int32_t)insn
) << 8) >> 8;
8153 /* offset * 4 + bit24 * 2 + (thumb bit) */
8154 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
8155 /* pipeline offset */
8157 /* protected by ARCH(5); above, near the start of uncond block */
8160 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
8161 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
8162 /* iWMMXt register transfer. */
8163 if (extract32(s
->c15_cpar
, 1, 1)) {
8164 if (!disas_iwmmxt_insn(s
, insn
)) {
8169 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
8170 /* Coprocessor double register transfer. */
8172 } else if ((insn
& 0x0f000010) == 0x0e000010) {
8173 /* Additional coprocessor register transfer. */
8174 } else if ((insn
& 0x0ff10020) == 0x01000000) {
8177 /* cps (privileged) */
8181 if (insn
& (1 << 19)) {
8182 if (insn
& (1 << 8))
8184 if (insn
& (1 << 7))
8186 if (insn
& (1 << 6))
8188 if (insn
& (1 << 18))
8191 if (insn
& (1 << 17)) {
8193 val
|= (insn
& 0x1f);
8196 gen_set_psr_im(s
, mask
, 0, val
);
8203 /* if not always execute, we generate a conditional jump to
8205 s
->condlabel
= gen_new_label();
8206 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
8209 if ((insn
& 0x0f900000) == 0x03000000) {
8210 if ((insn
& (1 << 21)) == 0) {
8212 rd
= (insn
>> 12) & 0xf;
8213 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
8214 if ((insn
& (1 << 22)) == 0) {
8216 tmp
= tcg_temp_new_i32();
8217 tcg_gen_movi_i32(tmp
, val
);
8220 tmp
= load_reg(s
, rd
);
8221 tcg_gen_ext16u_i32(tmp
, tmp
);
8222 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
8224 store_reg(s
, rd
, tmp
);
8226 if (((insn
>> 12) & 0xf) != 0xf)
8228 if (((insn
>> 16) & 0xf) == 0) {
8229 gen_nop_hint(s
, insn
& 0xff);
8231 /* CPSR = immediate */
8233 shift
= ((insn
>> 8) & 0xf) * 2;
8235 val
= (val
>> shift
) | (val
<< (32 - shift
));
8236 i
= ((insn
& (1 << 22)) != 0);
8237 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
8243 } else if ((insn
& 0x0f900000) == 0x01000000
8244 && (insn
& 0x00000090) != 0x00000090) {
8245 /* miscellaneous instructions */
8246 op1
= (insn
>> 21) & 3;
8247 sh
= (insn
>> 4) & 0xf;
8250 case 0x0: /* MSR, MRS */
8251 if (insn
& (1 << 9)) {
8252 /* MSR (banked) and MRS (banked) */
8253 int sysm
= extract32(insn
, 16, 4) |
8254 (extract32(insn
, 8, 1) << 4);
8255 int r
= extract32(insn
, 22, 1);
8259 gen_msr_banked(s
, r
, sysm
, rm
);
8262 int rd
= extract32(insn
, 12, 4);
8264 gen_mrs_banked(s
, r
, sysm
, rd
);
8269 /* MSR, MRS (for PSRs) */
8272 tmp
= load_reg(s
, rm
);
8273 i
= ((op1
& 2) != 0);
8274 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8278 rd
= (insn
>> 12) & 0xf;
8282 tmp
= load_cpu_field(spsr
);
8284 tmp
= tcg_temp_new_i32();
8285 gen_helper_cpsr_read(tmp
, cpu_env
);
8287 store_reg(s
, rd
, tmp
);
8292 /* branch/exchange thumb (bx). */
8294 tmp
= load_reg(s
, rm
);
8296 } else if (op1
== 3) {
8299 rd
= (insn
>> 12) & 0xf;
8300 tmp
= load_reg(s
, rm
);
8301 gen_helper_clz(tmp
, tmp
);
8302 store_reg(s
, rd
, tmp
);
8310 /* Trivial implementation equivalent to bx. */
8311 tmp
= load_reg(s
, rm
);
8322 /* branch link/exchange thumb (blx) */
8323 tmp
= load_reg(s
, rm
);
8324 tmp2
= tcg_temp_new_i32();
8325 tcg_gen_movi_i32(tmp2
, s
->pc
);
8326 store_reg(s
, 14, tmp2
);
8332 uint32_t c
= extract32(insn
, 8, 4);
8334 /* Check this CPU supports ARMv8 CRC instructions.
8335 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8336 * Bits 8, 10 and 11 should be zero.
8338 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8343 rn
= extract32(insn
, 16, 4);
8344 rd
= extract32(insn
, 12, 4);
8346 tmp
= load_reg(s
, rn
);
8347 tmp2
= load_reg(s
, rm
);
8349 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8350 } else if (op1
== 1) {
8351 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8353 tmp3
= tcg_const_i32(1 << op1
);
8355 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8357 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8359 tcg_temp_free_i32(tmp2
);
8360 tcg_temp_free_i32(tmp3
);
8361 store_reg(s
, rd
, tmp
);
8364 case 0x5: /* saturating add/subtract */
8366 rd
= (insn
>> 12) & 0xf;
8367 rn
= (insn
>> 16) & 0xf;
8368 tmp
= load_reg(s
, rm
);
8369 tmp2
= load_reg(s
, rn
);
8371 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8373 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8375 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8376 tcg_temp_free_i32(tmp2
);
8377 store_reg(s
, rd
, tmp
);
8381 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8386 gen_exception_insn(s
, 4, EXCP_BKPT
,
8387 syn_aa32_bkpt(imm16
, false),
8388 default_exception_el(s
));
8391 /* Hypervisor call (v7) */
8399 /* Secure monitor call (v6+) */
8411 case 0x8: /* signed multiply */
8416 rs
= (insn
>> 8) & 0xf;
8417 rn
= (insn
>> 12) & 0xf;
8418 rd
= (insn
>> 16) & 0xf;
8420 /* (32 * 16) >> 16 */
8421 tmp
= load_reg(s
, rm
);
8422 tmp2
= load_reg(s
, rs
);
8424 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8427 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8428 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8429 tmp
= tcg_temp_new_i32();
8430 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8431 tcg_temp_free_i64(tmp64
);
8432 if ((sh
& 2) == 0) {
8433 tmp2
= load_reg(s
, rn
);
8434 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8435 tcg_temp_free_i32(tmp2
);
8437 store_reg(s
, rd
, tmp
);
8440 tmp
= load_reg(s
, rm
);
8441 tmp2
= load_reg(s
, rs
);
8442 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8443 tcg_temp_free_i32(tmp2
);
8445 tmp64
= tcg_temp_new_i64();
8446 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8447 tcg_temp_free_i32(tmp
);
8448 gen_addq(s
, tmp64
, rn
, rd
);
8449 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8450 tcg_temp_free_i64(tmp64
);
8453 tmp2
= load_reg(s
, rn
);
8454 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8455 tcg_temp_free_i32(tmp2
);
8457 store_reg(s
, rd
, tmp
);
8464 } else if (((insn
& 0x0e000000) == 0 &&
8465 (insn
& 0x00000090) != 0x90) ||
8466 ((insn
& 0x0e000000) == (1 << 25))) {
8467 int set_cc
, logic_cc
, shiftop
;
8469 op1
= (insn
>> 21) & 0xf;
8470 set_cc
= (insn
>> 20) & 1;
8471 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8473 /* data processing instruction */
8474 if (insn
& (1 << 25)) {
8475 /* immediate operand */
8477 shift
= ((insn
>> 8) & 0xf) * 2;
8479 val
= (val
>> shift
) | (val
<< (32 - shift
));
8481 tmp2
= tcg_temp_new_i32();
8482 tcg_gen_movi_i32(tmp2
, val
);
8483 if (logic_cc
&& shift
) {
8484 gen_set_CF_bit31(tmp2
);
8489 tmp2
= load_reg(s
, rm
);
8490 shiftop
= (insn
>> 5) & 3;
8491 if (!(insn
& (1 << 4))) {
8492 shift
= (insn
>> 7) & 0x1f;
8493 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8495 rs
= (insn
>> 8) & 0xf;
8496 tmp
= load_reg(s
, rs
);
8497 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8500 if (op1
!= 0x0f && op1
!= 0x0d) {
8501 rn
= (insn
>> 16) & 0xf;
8502 tmp
= load_reg(s
, rn
);
8504 TCGV_UNUSED_I32(tmp
);
8506 rd
= (insn
>> 12) & 0xf;
8509 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8513 store_reg_bx(s
, rd
, tmp
);
8516 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8520 store_reg_bx(s
, rd
, tmp
);
8523 if (set_cc
&& rd
== 15) {
8524 /* SUBS r15, ... is used for exception return. */
8528 gen_sub_CC(tmp
, tmp
, tmp2
);
8529 gen_exception_return(s
, tmp
);
8532 gen_sub_CC(tmp
, tmp
, tmp2
);
8534 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8536 store_reg_bx(s
, rd
, tmp
);
8541 gen_sub_CC(tmp
, tmp2
, tmp
);
8543 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8545 store_reg_bx(s
, rd
, tmp
);
8549 gen_add_CC(tmp
, tmp
, tmp2
);
8551 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8553 store_reg_bx(s
, rd
, tmp
);
8557 gen_adc_CC(tmp
, tmp
, tmp2
);
8559 gen_add_carry(tmp
, tmp
, tmp2
);
8561 store_reg_bx(s
, rd
, tmp
);
8565 gen_sbc_CC(tmp
, tmp
, tmp2
);
8567 gen_sub_carry(tmp
, tmp
, tmp2
);
8569 store_reg_bx(s
, rd
, tmp
);
8573 gen_sbc_CC(tmp
, tmp2
, tmp
);
8575 gen_sub_carry(tmp
, tmp2
, tmp
);
8577 store_reg_bx(s
, rd
, tmp
);
8581 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8584 tcg_temp_free_i32(tmp
);
8588 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8591 tcg_temp_free_i32(tmp
);
8595 gen_sub_CC(tmp
, tmp
, tmp2
);
8597 tcg_temp_free_i32(tmp
);
8601 gen_add_CC(tmp
, tmp
, tmp2
);
8603 tcg_temp_free_i32(tmp
);
8606 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8610 store_reg_bx(s
, rd
, tmp
);
8613 if (logic_cc
&& rd
== 15) {
8614 /* MOVS r15, ... is used for exception return. */
8618 gen_exception_return(s
, tmp2
);
8623 store_reg_bx(s
, rd
, tmp2
);
8627 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8631 store_reg_bx(s
, rd
, tmp
);
8635 tcg_gen_not_i32(tmp2
, tmp2
);
8639 store_reg_bx(s
, rd
, tmp2
);
8642 if (op1
!= 0x0f && op1
!= 0x0d) {
8643 tcg_temp_free_i32(tmp2
);
8646 /* other instructions */
8647 op1
= (insn
>> 24) & 0xf;
8651 /* multiplies, extra load/stores */
8652 sh
= (insn
>> 5) & 3;
8655 rd
= (insn
>> 16) & 0xf;
8656 rn
= (insn
>> 12) & 0xf;
8657 rs
= (insn
>> 8) & 0xf;
8659 op1
= (insn
>> 20) & 0xf;
8661 case 0: case 1: case 2: case 3: case 6:
8663 tmp
= load_reg(s
, rs
);
8664 tmp2
= load_reg(s
, rm
);
8665 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8666 tcg_temp_free_i32(tmp2
);
8667 if (insn
& (1 << 22)) {
8668 /* Subtract (mls) */
8670 tmp2
= load_reg(s
, rn
);
8671 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8672 tcg_temp_free_i32(tmp2
);
8673 } else if (insn
& (1 << 21)) {
8675 tmp2
= load_reg(s
, rn
);
8676 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8677 tcg_temp_free_i32(tmp2
);
8679 if (insn
& (1 << 20))
8681 store_reg(s
, rd
, tmp
);
8684 /* 64 bit mul double accumulate (UMAAL) */
8686 tmp
= load_reg(s
, rs
);
8687 tmp2
= load_reg(s
, rm
);
8688 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8689 gen_addq_lo(s
, tmp64
, rn
);
8690 gen_addq_lo(s
, tmp64
, rd
);
8691 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8692 tcg_temp_free_i64(tmp64
);
8694 case 8: case 9: case 10: case 11:
8695 case 12: case 13: case 14: case 15:
8696 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8697 tmp
= load_reg(s
, rs
);
8698 tmp2
= load_reg(s
, rm
);
8699 if (insn
& (1 << 22)) {
8700 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8702 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8704 if (insn
& (1 << 21)) { /* mult accumulate */
8705 TCGv_i32 al
= load_reg(s
, rn
);
8706 TCGv_i32 ah
= load_reg(s
, rd
);
8707 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8708 tcg_temp_free_i32(al
);
8709 tcg_temp_free_i32(ah
);
8711 if (insn
& (1 << 20)) {
8712 gen_logicq_cc(tmp
, tmp2
);
8714 store_reg(s
, rn
, tmp
);
8715 store_reg(s
, rd
, tmp2
);
8721 rn
= (insn
>> 16) & 0xf;
8722 rd
= (insn
>> 12) & 0xf;
8723 if (insn
& (1 << 23)) {
8724 /* load/store exclusive */
8725 int op2
= (insn
>> 8) & 3;
8726 op1
= (insn
>> 21) & 0x3;
8729 case 0: /* lda/stl */
8735 case 1: /* reserved */
8737 case 2: /* ldaex/stlex */
8740 case 3: /* ldrex/strex */
8749 addr
= tcg_temp_local_new_i32();
8750 load_reg_var(s
, addr
, rn
);
8752 /* Since the emulation does not have barriers,
8753 the acquire/release semantics need no special
8756 if (insn
& (1 << 20)) {
8757 tmp
= tcg_temp_new_i32();
8760 gen_aa32_ld32u(s
, tmp
, addr
,
8764 gen_aa32_ld8u(s
, tmp
, addr
,
8768 gen_aa32_ld16u(s
, tmp
, addr
,
8774 store_reg(s
, rd
, tmp
);
8777 tmp
= load_reg(s
, rm
);
8780 gen_aa32_st32(s
, tmp
, addr
,
8784 gen_aa32_st8(s
, tmp
, addr
,
8788 gen_aa32_st16(s
, tmp
, addr
,
8794 tcg_temp_free_i32(tmp
);
8796 } else if (insn
& (1 << 20)) {
8799 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8801 case 1: /* ldrexd */
8802 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8804 case 2: /* ldrexb */
8805 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8807 case 3: /* ldrexh */
8808 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8817 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8819 case 1: /* strexd */
8820 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8822 case 2: /* strexb */
8823 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8825 case 3: /* strexh */
8826 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8832 tcg_temp_free_i32(addr
);
8834 /* SWP instruction */
8837 /* ??? This is not really atomic. However we know
8838 we never have multiple CPUs running in parallel,
8839 so it is good enough. */
8840 addr
= load_reg(s
, rn
);
8841 tmp
= load_reg(s
, rm
);
8842 tmp2
= tcg_temp_new_i32();
8843 if (insn
& (1 << 22)) {
8844 gen_aa32_ld8u(s
, tmp2
, addr
, get_mem_index(s
));
8845 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
8847 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
8848 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8850 tcg_temp_free_i32(tmp
);
8851 tcg_temp_free_i32(addr
);
8852 store_reg(s
, rd
, tmp2
);
8857 bool load
= insn
& (1 << 20);
8858 bool doubleword
= false;
8859 /* Misc load/store */
8860 rn
= (insn
>> 16) & 0xf;
8861 rd
= (insn
>> 12) & 0xf;
8863 if (!load
&& (sh
& 2)) {
8867 /* UNPREDICTABLE; we choose to UNDEF */
8870 load
= (sh
& 1) == 0;
8874 addr
= load_reg(s
, rn
);
8875 if (insn
& (1 << 24))
8876 gen_add_datah_offset(s
, insn
, 0, addr
);
8882 tmp
= load_reg(s
, rd
);
8883 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8884 tcg_temp_free_i32(tmp
);
8885 tcg_gen_addi_i32(addr
, addr
, 4);
8886 tmp
= load_reg(s
, rd
+ 1);
8887 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8888 tcg_temp_free_i32(tmp
);
8891 tmp
= tcg_temp_new_i32();
8892 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8893 store_reg(s
, rd
, tmp
);
8894 tcg_gen_addi_i32(addr
, addr
, 4);
8895 tmp
= tcg_temp_new_i32();
8896 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8899 address_offset
= -4;
8902 tmp
= tcg_temp_new_i32();
8905 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
8908 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
8912 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
8917 tmp
= load_reg(s
, rd
);
8918 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
8919 tcg_temp_free_i32(tmp
);
8921 /* Perform base writeback before the loaded value to
8922 ensure correct behavior with overlapping index registers.
8923 ldrd with base writeback is undefined if the
8924 destination and index registers overlap. */
8925 if (!(insn
& (1 << 24))) {
8926 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8927 store_reg(s
, rn
, addr
);
8928 } else if (insn
& (1 << 21)) {
8930 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8931 store_reg(s
, rn
, addr
);
8933 tcg_temp_free_i32(addr
);
8936 /* Complete the load. */
8937 store_reg(s
, rd
, tmp
);
8946 if (insn
& (1 << 4)) {
8948 /* Armv6 Media instructions. */
8950 rn
= (insn
>> 16) & 0xf;
8951 rd
= (insn
>> 12) & 0xf;
8952 rs
= (insn
>> 8) & 0xf;
8953 switch ((insn
>> 23) & 3) {
8954 case 0: /* Parallel add/subtract. */
8955 op1
= (insn
>> 20) & 7;
8956 tmp
= load_reg(s
, rn
);
8957 tmp2
= load_reg(s
, rm
);
8958 sh
= (insn
>> 5) & 7;
8959 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8961 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8962 tcg_temp_free_i32(tmp2
);
8963 store_reg(s
, rd
, tmp
);
8966 if ((insn
& 0x00700020) == 0) {
8967 /* Halfword pack. */
8968 tmp
= load_reg(s
, rn
);
8969 tmp2
= load_reg(s
, rm
);
8970 shift
= (insn
>> 7) & 0x1f;
8971 if (insn
& (1 << 6)) {
8975 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8976 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8977 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8981 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8982 tcg_gen_ext16u_i32(tmp
, tmp
);
8983 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8985 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8986 tcg_temp_free_i32(tmp2
);
8987 store_reg(s
, rd
, tmp
);
8988 } else if ((insn
& 0x00200020) == 0x00200000) {
8990 tmp
= load_reg(s
, rm
);
8991 shift
= (insn
>> 7) & 0x1f;
8992 if (insn
& (1 << 6)) {
8995 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8997 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8999 sh
= (insn
>> 16) & 0x1f;
9000 tmp2
= tcg_const_i32(sh
);
9001 if (insn
& (1 << 22))
9002 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9004 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9005 tcg_temp_free_i32(tmp2
);
9006 store_reg(s
, rd
, tmp
);
9007 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
9009 tmp
= load_reg(s
, rm
);
9010 sh
= (insn
>> 16) & 0x1f;
9011 tmp2
= tcg_const_i32(sh
);
9012 if (insn
& (1 << 22))
9013 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9015 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9016 tcg_temp_free_i32(tmp2
);
9017 store_reg(s
, rd
, tmp
);
9018 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
9020 tmp
= load_reg(s
, rn
);
9021 tmp2
= load_reg(s
, rm
);
9022 tmp3
= tcg_temp_new_i32();
9023 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9024 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9025 tcg_temp_free_i32(tmp3
);
9026 tcg_temp_free_i32(tmp2
);
9027 store_reg(s
, rd
, tmp
);
9028 } else if ((insn
& 0x000003e0) == 0x00000060) {
9029 tmp
= load_reg(s
, rm
);
9030 shift
= (insn
>> 10) & 3;
9031 /* ??? In many cases it's not necessary to do a
9032 rotate, a shift is sufficient. */
9034 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9035 op1
= (insn
>> 20) & 7;
9037 case 0: gen_sxtb16(tmp
); break;
9038 case 2: gen_sxtb(tmp
); break;
9039 case 3: gen_sxth(tmp
); break;
9040 case 4: gen_uxtb16(tmp
); break;
9041 case 6: gen_uxtb(tmp
); break;
9042 case 7: gen_uxth(tmp
); break;
9043 default: goto illegal_op
;
9046 tmp2
= load_reg(s
, rn
);
9047 if ((op1
& 3) == 0) {
9048 gen_add16(tmp
, tmp2
);
9050 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9051 tcg_temp_free_i32(tmp2
);
9054 store_reg(s
, rd
, tmp
);
9055 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
9057 tmp
= load_reg(s
, rm
);
9058 if (insn
& (1 << 22)) {
9059 if (insn
& (1 << 7)) {
9063 gen_helper_rbit(tmp
, tmp
);
9066 if (insn
& (1 << 7))
9069 tcg_gen_bswap32_i32(tmp
, tmp
);
9071 store_reg(s
, rd
, tmp
);
9076 case 2: /* Multiplies (Type 3). */
9077 switch ((insn
>> 20) & 0x7) {
9079 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
9080 /* op2 not 00x or 11x : UNDEF */
9083 /* Signed multiply most significant [accumulate].
9084 (SMMUL, SMMLA, SMMLS) */
9085 tmp
= load_reg(s
, rm
);
9086 tmp2
= load_reg(s
, rs
);
9087 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9090 tmp
= load_reg(s
, rd
);
9091 if (insn
& (1 << 6)) {
9092 tmp64
= gen_subq_msw(tmp64
, tmp
);
9094 tmp64
= gen_addq_msw(tmp64
, tmp
);
9097 if (insn
& (1 << 5)) {
9098 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9100 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9101 tmp
= tcg_temp_new_i32();
9102 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9103 tcg_temp_free_i64(tmp64
);
9104 store_reg(s
, rn
, tmp
);
9108 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9109 if (insn
& (1 << 7)) {
9112 tmp
= load_reg(s
, rm
);
9113 tmp2
= load_reg(s
, rs
);
9114 if (insn
& (1 << 5))
9115 gen_swap_half(tmp2
);
9116 gen_smul_dual(tmp
, tmp2
);
9117 if (insn
& (1 << 22)) {
9118 /* smlald, smlsld */
9121 tmp64
= tcg_temp_new_i64();
9122 tmp64_2
= tcg_temp_new_i64();
9123 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9124 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
9125 tcg_temp_free_i32(tmp
);
9126 tcg_temp_free_i32(tmp2
);
9127 if (insn
& (1 << 6)) {
9128 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
9130 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
9132 tcg_temp_free_i64(tmp64_2
);
9133 gen_addq(s
, tmp64
, rd
, rn
);
9134 gen_storeq_reg(s
, rd
, rn
, tmp64
);
9135 tcg_temp_free_i64(tmp64
);
9137 /* smuad, smusd, smlad, smlsd */
9138 if (insn
& (1 << 6)) {
9139 /* This subtraction cannot overflow. */
9140 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9142 /* This addition cannot overflow 32 bits;
9143 * however it may overflow considered as a
9144 * signed operation, in which case we must set
9147 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9149 tcg_temp_free_i32(tmp2
);
9152 tmp2
= load_reg(s
, rd
);
9153 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9154 tcg_temp_free_i32(tmp2
);
9156 store_reg(s
, rn
, tmp
);
9162 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
9165 if (((insn
>> 5) & 7) || (rd
!= 15)) {
9168 tmp
= load_reg(s
, rm
);
9169 tmp2
= load_reg(s
, rs
);
9170 if (insn
& (1 << 21)) {
9171 gen_helper_udiv(tmp
, tmp
, tmp2
);
9173 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9175 tcg_temp_free_i32(tmp2
);
9176 store_reg(s
, rn
, tmp
);
9183 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
9185 case 0: /* Unsigned sum of absolute differences. */
9187 tmp
= load_reg(s
, rm
);
9188 tmp2
= load_reg(s
, rs
);
9189 gen_helper_usad8(tmp
, tmp
, tmp2
);
9190 tcg_temp_free_i32(tmp2
);
9192 tmp2
= load_reg(s
, rd
);
9193 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9194 tcg_temp_free_i32(tmp2
);
9196 store_reg(s
, rn
, tmp
);
9198 case 0x20: case 0x24: case 0x28: case 0x2c:
9199 /* Bitfield insert/clear. */
9201 shift
= (insn
>> 7) & 0x1f;
9202 i
= (insn
>> 16) & 0x1f;
9204 /* UNPREDICTABLE; we choose to UNDEF */
9209 tmp
= tcg_temp_new_i32();
9210 tcg_gen_movi_i32(tmp
, 0);
9212 tmp
= load_reg(s
, rm
);
9215 tmp2
= load_reg(s
, rd
);
9216 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9217 tcg_temp_free_i32(tmp2
);
9219 store_reg(s
, rd
, tmp
);
9221 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9222 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9224 tmp
= load_reg(s
, rm
);
9225 shift
= (insn
>> 7) & 0x1f;
9226 i
= ((insn
>> 16) & 0x1f) + 1;
9231 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
9233 gen_sbfx(tmp
, shift
, i
);
9236 store_reg(s
, rd
, tmp
);
9246 /* Check for undefined extension instructions
9247 * per the ARM Bible IE:
9248 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9250 sh
= (0xf << 20) | (0xf << 4);
9251 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9255 /* load/store byte/word */
9256 rn
= (insn
>> 16) & 0xf;
9257 rd
= (insn
>> 12) & 0xf;
9258 tmp2
= load_reg(s
, rn
);
9259 if ((insn
& 0x01200000) == 0x00200000) {
9261 i
= get_a32_user_mem_index(s
);
9263 i
= get_mem_index(s
);
9265 if (insn
& (1 << 24))
9266 gen_add_data_offset(s
, insn
, tmp2
);
9267 if (insn
& (1 << 20)) {
9269 tmp
= tcg_temp_new_i32();
9270 if (insn
& (1 << 22)) {
9271 gen_aa32_ld8u(s
, tmp
, tmp2
, i
);
9273 gen_aa32_ld32u(s
, tmp
, tmp2
, i
);
9277 tmp
= load_reg(s
, rd
);
9278 if (insn
& (1 << 22)) {
9279 gen_aa32_st8(s
, tmp
, tmp2
, i
);
9281 gen_aa32_st32(s
, tmp
, tmp2
, i
);
9283 tcg_temp_free_i32(tmp
);
9285 if (!(insn
& (1 << 24))) {
9286 gen_add_data_offset(s
, insn
, tmp2
);
9287 store_reg(s
, rn
, tmp2
);
9288 } else if (insn
& (1 << 21)) {
9289 store_reg(s
, rn
, tmp2
);
9291 tcg_temp_free_i32(tmp2
);
9293 if (insn
& (1 << 20)) {
9294 /* Complete the load. */
9295 store_reg_from_load(s
, rd
, tmp
);
9301 int j
, n
, loaded_base
;
9302 bool exc_return
= false;
9303 bool is_load
= extract32(insn
, 20, 1);
9305 TCGv_i32 loaded_var
;
9306 /* load/store multiple words */
9307 /* XXX: store correct base if write back */
9308 if (insn
& (1 << 22)) {
9309 /* LDM (user), LDM (exception return) and STM (user) */
9311 goto illegal_op
; /* only usable in supervisor mode */
9313 if (is_load
&& extract32(insn
, 15, 1)) {
9319 rn
= (insn
>> 16) & 0xf;
9320 addr
= load_reg(s
, rn
);
9322 /* compute total size */
9324 TCGV_UNUSED_I32(loaded_var
);
9327 if (insn
& (1 << i
))
9330 /* XXX: test invalid n == 0 case ? */
9331 if (insn
& (1 << 23)) {
9332 if (insn
& (1 << 24)) {
9334 tcg_gen_addi_i32(addr
, addr
, 4);
9336 /* post increment */
9339 if (insn
& (1 << 24)) {
9341 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9343 /* post decrement */
9345 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9350 if (insn
& (1 << i
)) {
9353 tmp
= tcg_temp_new_i32();
9354 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9356 tmp2
= tcg_const_i32(i
);
9357 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9358 tcg_temp_free_i32(tmp2
);
9359 tcg_temp_free_i32(tmp
);
9360 } else if (i
== rn
) {
9364 store_reg_from_load(s
, i
, tmp
);
9369 /* special case: r15 = PC + 8 */
9370 val
= (long)s
->pc
+ 4;
9371 tmp
= tcg_temp_new_i32();
9372 tcg_gen_movi_i32(tmp
, val
);
9374 tmp
= tcg_temp_new_i32();
9375 tmp2
= tcg_const_i32(i
);
9376 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9377 tcg_temp_free_i32(tmp2
);
9379 tmp
= load_reg(s
, i
);
9381 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9382 tcg_temp_free_i32(tmp
);
9385 /* no need to add after the last transfer */
9387 tcg_gen_addi_i32(addr
, addr
, 4);
9390 if (insn
& (1 << 21)) {
9392 if (insn
& (1 << 23)) {
9393 if (insn
& (1 << 24)) {
9396 /* post increment */
9397 tcg_gen_addi_i32(addr
, addr
, 4);
9400 if (insn
& (1 << 24)) {
9403 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9405 /* post decrement */
9406 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9409 store_reg(s
, rn
, addr
);
9411 tcg_temp_free_i32(addr
);
9414 store_reg(s
, rn
, loaded_var
);
9417 /* Restore CPSR from SPSR. */
9418 tmp
= load_cpu_field(spsr
);
9419 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9420 tcg_temp_free_i32(tmp
);
9421 s
->is_jmp
= DISAS_JUMP
;
9430 /* branch (and link) */
9431 val
= (int32_t)s
->pc
;
9432 if (insn
& (1 << 24)) {
9433 tmp
= tcg_temp_new_i32();
9434 tcg_gen_movi_i32(tmp
, val
);
9435 store_reg(s
, 14, tmp
);
9437 offset
= sextract32(insn
<< 2, 0, 26);
9445 if (((insn
>> 8) & 0xe) == 10) {
9447 if (disas_vfp_insn(s
, insn
)) {
9450 } else if (disas_coproc_insn(s
, insn
)) {
9457 gen_set_pc_im(s
, s
->pc
);
9458 s
->svc_imm
= extract32(insn
, 0, 24);
9459 s
->is_jmp
= DISAS_SWI
;
9463 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9464 default_exception_el(s
));
9470 /* Return true if this is a Thumb-2 logical op. */
9472 thumb2_logic_op(int op
)
9477 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9478 then set condition code flags based on the result of the operation.
9479 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9480 to the high bit of T1.
9481 Returns zero if the opcode is valid. */
9484 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9485 TCGv_i32 t0
, TCGv_i32 t1
)
9492 tcg_gen_and_i32(t0
, t0
, t1
);
9496 tcg_gen_andc_i32(t0
, t0
, t1
);
9500 tcg_gen_or_i32(t0
, t0
, t1
);
9504 tcg_gen_orc_i32(t0
, t0
, t1
);
9508 tcg_gen_xor_i32(t0
, t0
, t1
);
9513 gen_add_CC(t0
, t0
, t1
);
9515 tcg_gen_add_i32(t0
, t0
, t1
);
9519 gen_adc_CC(t0
, t0
, t1
);
9525 gen_sbc_CC(t0
, t0
, t1
);
9527 gen_sub_carry(t0
, t0
, t1
);
9532 gen_sub_CC(t0
, t0
, t1
);
9534 tcg_gen_sub_i32(t0
, t0
, t1
);
9538 gen_sub_CC(t0
, t1
, t0
);
9540 tcg_gen_sub_i32(t0
, t1
, t0
);
9542 default: /* 5, 6, 7, 9, 12, 15. */
9548 gen_set_CF_bit31(t1
);
9553 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9555 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9557 uint32_t insn
, imm
, shift
, offset
;
9558 uint32_t rd
, rn
, rm
, rs
;
9569 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9570 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9571 /* Thumb-1 cores may need to treat bl and blx as a pair of
9572 16-bit instructions to get correct prefetch abort behavior. */
9574 if ((insn
& (1 << 12)) == 0) {
9576 /* Second half of blx. */
9577 offset
= ((insn
& 0x7ff) << 1);
9578 tmp
= load_reg(s
, 14);
9579 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9580 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9582 tmp2
= tcg_temp_new_i32();
9583 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9584 store_reg(s
, 14, tmp2
);
9588 if (insn
& (1 << 11)) {
9589 /* Second half of bl. */
9590 offset
= ((insn
& 0x7ff) << 1) | 1;
9591 tmp
= load_reg(s
, 14);
9592 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9594 tmp2
= tcg_temp_new_i32();
9595 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9596 store_reg(s
, 14, tmp2
);
9600 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9601 /* Instruction spans a page boundary. Implement it as two
9602 16-bit instructions in case the second half causes an
9604 offset
= ((int32_t)insn
<< 21) >> 9;
9605 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9608 /* Fall through to 32-bit decode. */
9611 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
9613 insn
|= (uint32_t)insn_hw1
<< 16;
9615 if ((insn
& 0xf800e800) != 0xf000e800) {
9619 rn
= (insn
>> 16) & 0xf;
9620 rs
= (insn
>> 12) & 0xf;
9621 rd
= (insn
>> 8) & 0xf;
9623 switch ((insn
>> 25) & 0xf) {
9624 case 0: case 1: case 2: case 3:
9625 /* 16-bit instructions. Should never happen. */
9628 if (insn
& (1 << 22)) {
9629 /* Other load/store, table branch. */
9630 if (insn
& 0x01200000) {
9631 /* Load/store doubleword. */
9633 addr
= tcg_temp_new_i32();
9634 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9636 addr
= load_reg(s
, rn
);
9638 offset
= (insn
& 0xff) * 4;
9639 if ((insn
& (1 << 23)) == 0)
9641 if (insn
& (1 << 24)) {
9642 tcg_gen_addi_i32(addr
, addr
, offset
);
9645 if (insn
& (1 << 20)) {
9647 tmp
= tcg_temp_new_i32();
9648 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9649 store_reg(s
, rs
, tmp
);
9650 tcg_gen_addi_i32(addr
, addr
, 4);
9651 tmp
= tcg_temp_new_i32();
9652 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9653 store_reg(s
, rd
, tmp
);
9656 tmp
= load_reg(s
, rs
);
9657 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9658 tcg_temp_free_i32(tmp
);
9659 tcg_gen_addi_i32(addr
, addr
, 4);
9660 tmp
= load_reg(s
, rd
);
9661 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9662 tcg_temp_free_i32(tmp
);
9664 if (insn
& (1 << 21)) {
9665 /* Base writeback. */
9668 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9669 store_reg(s
, rn
, addr
);
9671 tcg_temp_free_i32(addr
);
9673 } else if ((insn
& (1 << 23)) == 0) {
9674 /* Load/store exclusive word. */
9675 addr
= tcg_temp_local_new_i32();
9676 load_reg_var(s
, addr
, rn
);
9677 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9678 if (insn
& (1 << 20)) {
9679 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9681 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9683 tcg_temp_free_i32(addr
);
9684 } else if ((insn
& (7 << 5)) == 0) {
9687 addr
= tcg_temp_new_i32();
9688 tcg_gen_movi_i32(addr
, s
->pc
);
9690 addr
= load_reg(s
, rn
);
9692 tmp
= load_reg(s
, rm
);
9693 tcg_gen_add_i32(addr
, addr
, tmp
);
9694 if (insn
& (1 << 4)) {
9696 tcg_gen_add_i32(addr
, addr
, tmp
);
9697 tcg_temp_free_i32(tmp
);
9698 tmp
= tcg_temp_new_i32();
9699 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9701 tcg_temp_free_i32(tmp
);
9702 tmp
= tcg_temp_new_i32();
9703 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9705 tcg_temp_free_i32(addr
);
9706 tcg_gen_shli_i32(tmp
, tmp
, 1);
9707 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9708 store_reg(s
, 15, tmp
);
9710 int op2
= (insn
>> 6) & 0x3;
9711 op
= (insn
>> 4) & 0x3;
9716 /* Load/store exclusive byte/halfword/doubleword */
9723 /* Load-acquire/store-release */
9729 /* Load-acquire/store-release exclusive */
9733 addr
= tcg_temp_local_new_i32();
9734 load_reg_var(s
, addr
, rn
);
9736 if (insn
& (1 << 20)) {
9737 tmp
= tcg_temp_new_i32();
9740 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9743 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9746 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9751 store_reg(s
, rs
, tmp
);
9753 tmp
= load_reg(s
, rs
);
9756 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
9759 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
9762 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9767 tcg_temp_free_i32(tmp
);
9769 } else if (insn
& (1 << 20)) {
9770 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9772 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9774 tcg_temp_free_i32(addr
);
9777 /* Load/store multiple, RFE, SRS. */
9778 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9779 /* RFE, SRS: not available in user mode or on M profile */
9780 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9783 if (insn
& (1 << 20)) {
9785 addr
= load_reg(s
, rn
);
9786 if ((insn
& (1 << 24)) == 0)
9787 tcg_gen_addi_i32(addr
, addr
, -8);
9788 /* Load PC into tmp and CPSR into tmp2. */
9789 tmp
= tcg_temp_new_i32();
9790 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9791 tcg_gen_addi_i32(addr
, addr
, 4);
9792 tmp2
= tcg_temp_new_i32();
9793 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9794 if (insn
& (1 << 21)) {
9795 /* Base writeback. */
9796 if (insn
& (1 << 24)) {
9797 tcg_gen_addi_i32(addr
, addr
, 4);
9799 tcg_gen_addi_i32(addr
, addr
, -4);
9801 store_reg(s
, rn
, addr
);
9803 tcg_temp_free_i32(addr
);
9805 gen_rfe(s
, tmp
, tmp2
);
9808 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9812 int i
, loaded_base
= 0;
9813 TCGv_i32 loaded_var
;
9814 /* Load/store multiple. */
9815 addr
= load_reg(s
, rn
);
9817 for (i
= 0; i
< 16; i
++) {
9818 if (insn
& (1 << i
))
9821 if (insn
& (1 << 24)) {
9822 tcg_gen_addi_i32(addr
, addr
, -offset
);
9825 TCGV_UNUSED_I32(loaded_var
);
9826 for (i
= 0; i
< 16; i
++) {
9827 if ((insn
& (1 << i
)) == 0)
9829 if (insn
& (1 << 20)) {
9831 tmp
= tcg_temp_new_i32();
9832 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9835 } else if (i
== rn
) {
9839 store_reg(s
, i
, tmp
);
9843 tmp
= load_reg(s
, i
);
9844 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9845 tcg_temp_free_i32(tmp
);
9847 tcg_gen_addi_i32(addr
, addr
, 4);
9850 store_reg(s
, rn
, loaded_var
);
9852 if (insn
& (1 << 21)) {
9853 /* Base register writeback. */
9854 if (insn
& (1 << 24)) {
9855 tcg_gen_addi_i32(addr
, addr
, -offset
);
9857 /* Fault if writeback register is in register list. */
9858 if (insn
& (1 << rn
))
9860 store_reg(s
, rn
, addr
);
9862 tcg_temp_free_i32(addr
);
9869 op
= (insn
>> 21) & 0xf;
9871 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9874 /* Halfword pack. */
9875 tmp
= load_reg(s
, rn
);
9876 tmp2
= load_reg(s
, rm
);
9877 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9878 if (insn
& (1 << 5)) {
9882 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9883 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9884 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9888 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9889 tcg_gen_ext16u_i32(tmp
, tmp
);
9890 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9892 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9893 tcg_temp_free_i32(tmp2
);
9894 store_reg(s
, rd
, tmp
);
9896 /* Data processing register constant shift. */
9898 tmp
= tcg_temp_new_i32();
9899 tcg_gen_movi_i32(tmp
, 0);
9901 tmp
= load_reg(s
, rn
);
9903 tmp2
= load_reg(s
, rm
);
9905 shiftop
= (insn
>> 4) & 3;
9906 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9907 conds
= (insn
& (1 << 20)) != 0;
9908 logic_cc
= (conds
&& thumb2_logic_op(op
));
9909 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9910 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9912 tcg_temp_free_i32(tmp2
);
9914 store_reg(s
, rd
, tmp
);
9916 tcg_temp_free_i32(tmp
);
9920 case 13: /* Misc data processing. */
9921 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9922 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9925 case 0: /* Register controlled shift. */
9926 tmp
= load_reg(s
, rn
);
9927 tmp2
= load_reg(s
, rm
);
9928 if ((insn
& 0x70) != 0)
9930 op
= (insn
>> 21) & 3;
9931 logic_cc
= (insn
& (1 << 20)) != 0;
9932 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9935 store_reg_bx(s
, rd
, tmp
);
9937 case 1: /* Sign/zero extend. */
9938 op
= (insn
>> 20) & 7;
9940 case 0: /* SXTAH, SXTH */
9941 case 1: /* UXTAH, UXTH */
9942 case 4: /* SXTAB, SXTB */
9943 case 5: /* UXTAB, UXTB */
9945 case 2: /* SXTAB16, SXTB16 */
9946 case 3: /* UXTAB16, UXTB16 */
9947 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9955 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9959 tmp
= load_reg(s
, rm
);
9960 shift
= (insn
>> 4) & 3;
9961 /* ??? In many cases it's not necessary to do a
9962 rotate, a shift is sufficient. */
9964 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9965 op
= (insn
>> 20) & 7;
9967 case 0: gen_sxth(tmp
); break;
9968 case 1: gen_uxth(tmp
); break;
9969 case 2: gen_sxtb16(tmp
); break;
9970 case 3: gen_uxtb16(tmp
); break;
9971 case 4: gen_sxtb(tmp
); break;
9972 case 5: gen_uxtb(tmp
); break;
9974 g_assert_not_reached();
9977 tmp2
= load_reg(s
, rn
);
9978 if ((op
>> 1) == 1) {
9979 gen_add16(tmp
, tmp2
);
9981 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9982 tcg_temp_free_i32(tmp2
);
9985 store_reg(s
, rd
, tmp
);
9987 case 2: /* SIMD add/subtract. */
9988 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9991 op
= (insn
>> 20) & 7;
9992 shift
= (insn
>> 4) & 7;
9993 if ((op
& 3) == 3 || (shift
& 3) == 3)
9995 tmp
= load_reg(s
, rn
);
9996 tmp2
= load_reg(s
, rm
);
9997 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9998 tcg_temp_free_i32(tmp2
);
9999 store_reg(s
, rd
, tmp
);
10001 case 3: /* Other data processing. */
10002 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
10004 /* Saturating add/subtract. */
10005 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10008 tmp
= load_reg(s
, rn
);
10009 tmp2
= load_reg(s
, rm
);
10011 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
10013 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
10015 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
10016 tcg_temp_free_i32(tmp2
);
10019 case 0x0a: /* rbit */
10020 case 0x08: /* rev */
10021 case 0x09: /* rev16 */
10022 case 0x0b: /* revsh */
10023 case 0x18: /* clz */
10025 case 0x10: /* sel */
10026 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10030 case 0x20: /* crc32/crc32c */
10036 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
10043 tmp
= load_reg(s
, rn
);
10045 case 0x0a: /* rbit */
10046 gen_helper_rbit(tmp
, tmp
);
10048 case 0x08: /* rev */
10049 tcg_gen_bswap32_i32(tmp
, tmp
);
10051 case 0x09: /* rev16 */
10054 case 0x0b: /* revsh */
10057 case 0x10: /* sel */
10058 tmp2
= load_reg(s
, rm
);
10059 tmp3
= tcg_temp_new_i32();
10060 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10061 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10062 tcg_temp_free_i32(tmp3
);
10063 tcg_temp_free_i32(tmp2
);
10065 case 0x18: /* clz */
10066 gen_helper_clz(tmp
, tmp
);
10076 uint32_t sz
= op
& 0x3;
10077 uint32_t c
= op
& 0x8;
10079 tmp2
= load_reg(s
, rm
);
10081 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10082 } else if (sz
== 1) {
10083 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10085 tmp3
= tcg_const_i32(1 << sz
);
10087 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10089 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10091 tcg_temp_free_i32(tmp2
);
10092 tcg_temp_free_i32(tmp3
);
10096 g_assert_not_reached();
10099 store_reg(s
, rd
, tmp
);
10101 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10102 switch ((insn
>> 20) & 7) {
10103 case 0: /* 32 x 32 -> 32 */
10104 case 7: /* Unsigned sum of absolute differences. */
10106 case 1: /* 16 x 16 -> 32 */
10107 case 2: /* Dual multiply add. */
10108 case 3: /* 32 * 16 -> 32msb */
10109 case 4: /* Dual multiply subtract. */
10110 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10111 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10116 op
= (insn
>> 4) & 0xf;
10117 tmp
= load_reg(s
, rn
);
10118 tmp2
= load_reg(s
, rm
);
10119 switch ((insn
>> 20) & 7) {
10120 case 0: /* 32 x 32 -> 32 */
10121 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10122 tcg_temp_free_i32(tmp2
);
10124 tmp2
= load_reg(s
, rs
);
10126 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10128 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10129 tcg_temp_free_i32(tmp2
);
10132 case 1: /* 16 x 16 -> 32 */
10133 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10134 tcg_temp_free_i32(tmp2
);
10136 tmp2
= load_reg(s
, rs
);
10137 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10138 tcg_temp_free_i32(tmp2
);
10141 case 2: /* Dual multiply add. */
10142 case 4: /* Dual multiply subtract. */
10144 gen_swap_half(tmp2
);
10145 gen_smul_dual(tmp
, tmp2
);
10146 if (insn
& (1 << 22)) {
10147 /* This subtraction cannot overflow. */
10148 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10150 /* This addition cannot overflow 32 bits;
10151 * however it may overflow considered as a signed
10152 * operation, in which case we must set the Q flag.
10154 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10156 tcg_temp_free_i32(tmp2
);
10159 tmp2
= load_reg(s
, rs
);
10160 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10161 tcg_temp_free_i32(tmp2
);
10164 case 3: /* 32 * 16 -> 32msb */
10166 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10169 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10170 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10171 tmp
= tcg_temp_new_i32();
10172 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10173 tcg_temp_free_i64(tmp64
);
10176 tmp2
= load_reg(s
, rs
);
10177 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10178 tcg_temp_free_i32(tmp2
);
10181 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10182 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10184 tmp
= load_reg(s
, rs
);
10185 if (insn
& (1 << 20)) {
10186 tmp64
= gen_addq_msw(tmp64
, tmp
);
10188 tmp64
= gen_subq_msw(tmp64
, tmp
);
10191 if (insn
& (1 << 4)) {
10192 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10194 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10195 tmp
= tcg_temp_new_i32();
10196 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10197 tcg_temp_free_i64(tmp64
);
10199 case 7: /* Unsigned sum of absolute differences. */
10200 gen_helper_usad8(tmp
, tmp
, tmp2
);
10201 tcg_temp_free_i32(tmp2
);
10203 tmp2
= load_reg(s
, rs
);
10204 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10205 tcg_temp_free_i32(tmp2
);
10209 store_reg(s
, rd
, tmp
);
10211 case 6: case 7: /* 64-bit multiply, Divide. */
10212 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10213 tmp
= load_reg(s
, rn
);
10214 tmp2
= load_reg(s
, rm
);
10215 if ((op
& 0x50) == 0x10) {
10217 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
10221 gen_helper_udiv(tmp
, tmp
, tmp2
);
10223 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10224 tcg_temp_free_i32(tmp2
);
10225 store_reg(s
, rd
, tmp
);
10226 } else if ((op
& 0xe) == 0xc) {
10227 /* Dual multiply accumulate long. */
10228 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10229 tcg_temp_free_i32(tmp
);
10230 tcg_temp_free_i32(tmp2
);
10234 gen_swap_half(tmp2
);
10235 gen_smul_dual(tmp
, tmp2
);
10237 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10239 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10241 tcg_temp_free_i32(tmp2
);
10243 tmp64
= tcg_temp_new_i64();
10244 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10245 tcg_temp_free_i32(tmp
);
10246 gen_addq(s
, tmp64
, rs
, rd
);
10247 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10248 tcg_temp_free_i64(tmp64
);
10251 /* Unsigned 64-bit multiply */
10252 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10256 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10257 tcg_temp_free_i32(tmp2
);
10258 tcg_temp_free_i32(tmp
);
10261 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10262 tcg_temp_free_i32(tmp2
);
10263 tmp64
= tcg_temp_new_i64();
10264 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10265 tcg_temp_free_i32(tmp
);
10267 /* Signed 64-bit multiply */
10268 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10273 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10274 tcg_temp_free_i64(tmp64
);
10277 gen_addq_lo(s
, tmp64
, rs
);
10278 gen_addq_lo(s
, tmp64
, rd
);
10279 } else if (op
& 0x40) {
10280 /* 64-bit accumulate. */
10281 gen_addq(s
, tmp64
, rs
, rd
);
10283 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10284 tcg_temp_free_i64(tmp64
);
10289 case 6: case 7: case 14: case 15:
10291 if (((insn
>> 24) & 3) == 3) {
10292 /* Translate into the equivalent ARM encoding. */
10293 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10294 if (disas_neon_data_insn(s
, insn
)) {
10297 } else if (((insn
>> 8) & 0xe) == 10) {
10298 if (disas_vfp_insn(s
, insn
)) {
10302 if (insn
& (1 << 28))
10304 if (disas_coproc_insn(s
, insn
)) {
10309 case 8: case 9: case 10: case 11:
10310 if (insn
& (1 << 15)) {
10311 /* Branches, misc control. */
10312 if (insn
& 0x5000) {
10313 /* Unconditional branch. */
10314 /* signextend(hw1[10:0]) -> offset[:12]. */
10315 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10316 /* hw1[10:0] -> offset[11:1]. */
10317 offset
|= (insn
& 0x7ff) << 1;
10318 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10319 offset[24:22] already have the same value because of the
10320 sign extension above. */
10321 offset
^= ((~insn
) & (1 << 13)) << 10;
10322 offset
^= ((~insn
) & (1 << 11)) << 11;
10324 if (insn
& (1 << 14)) {
10325 /* Branch and link. */
10326 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10330 if (insn
& (1 << 12)) {
10332 gen_jmp(s
, offset
);
10335 offset
&= ~(uint32_t)2;
10336 /* thumb2 bx, no need to check */
10337 gen_bx_im(s
, offset
);
10339 } else if (((insn
>> 23) & 7) == 7) {
10341 if (insn
& (1 << 13))
10344 if (insn
& (1 << 26)) {
10345 if (!(insn
& (1 << 20))) {
10346 /* Hypervisor call (v7) */
10347 int imm16
= extract32(insn
, 16, 4) << 12
10348 | extract32(insn
, 0, 12);
10355 /* Secure monitor call (v6+) */
10363 op
= (insn
>> 20) & 7;
10365 case 0: /* msr cpsr. */
10366 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10367 tmp
= load_reg(s
, rn
);
10368 addr
= tcg_const_i32(insn
& 0xff);
10369 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10370 tcg_temp_free_i32(addr
);
10371 tcg_temp_free_i32(tmp
);
10376 case 1: /* msr spsr. */
10377 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10381 if (extract32(insn
, 5, 1)) {
10383 int sysm
= extract32(insn
, 8, 4) |
10384 (extract32(insn
, 4, 1) << 4);
10387 gen_msr_banked(s
, r
, sysm
, rm
);
10391 /* MSR (for PSRs) */
10392 tmp
= load_reg(s
, rn
);
10394 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10398 case 2: /* cps, nop-hint. */
10399 if (((insn
>> 8) & 7) == 0) {
10400 gen_nop_hint(s
, insn
& 0xff);
10402 /* Implemented as NOP in user mode. */
10407 if (insn
& (1 << 10)) {
10408 if (insn
& (1 << 7))
10410 if (insn
& (1 << 6))
10412 if (insn
& (1 << 5))
10414 if (insn
& (1 << 9))
10415 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10417 if (insn
& (1 << 8)) {
10419 imm
|= (insn
& 0x1f);
10422 gen_set_psr_im(s
, offset
, 0, imm
);
10425 case 3: /* Special control operations. */
10427 op
= (insn
>> 4) & 0xf;
10429 case 2: /* clrex */
10434 /* These execute as NOPs. */
10437 /* We need to break the TB after this insn
10438 * to execute self-modifying code correctly
10439 * and also to take any pending interrupts
10449 /* Trivial implementation equivalent to bx. */
10450 tmp
= load_reg(s
, rn
);
10453 case 5: /* Exception return. */
10457 if (rn
!= 14 || rd
!= 15) {
10460 tmp
= load_reg(s
, rn
);
10461 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10462 gen_exception_return(s
, tmp
);
10465 if (extract32(insn
, 5, 1)) {
10467 int sysm
= extract32(insn
, 16, 4) |
10468 (extract32(insn
, 4, 1) << 4);
10470 gen_mrs_banked(s
, 0, sysm
, rd
);
10475 tmp
= tcg_temp_new_i32();
10476 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10477 addr
= tcg_const_i32(insn
& 0xff);
10478 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10479 tcg_temp_free_i32(addr
);
10481 gen_helper_cpsr_read(tmp
, cpu_env
);
10483 store_reg(s
, rd
, tmp
);
10486 if (extract32(insn
, 5, 1)) {
10488 int sysm
= extract32(insn
, 16, 4) |
10489 (extract32(insn
, 4, 1) << 4);
10491 gen_mrs_banked(s
, 1, sysm
, rd
);
10496 /* Not accessible in user mode. */
10497 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10500 tmp
= load_cpu_field(spsr
);
10501 store_reg(s
, rd
, tmp
);
10506 /* Conditional branch. */
10507 op
= (insn
>> 22) & 0xf;
10508 /* Generate a conditional jump to next instruction. */
10509 s
->condlabel
= gen_new_label();
10510 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10513 /* offset[11:1] = insn[10:0] */
10514 offset
= (insn
& 0x7ff) << 1;
10515 /* offset[17:12] = insn[21:16]. */
10516 offset
|= (insn
& 0x003f0000) >> 4;
10517 /* offset[31:20] = insn[26]. */
10518 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10519 /* offset[18] = insn[13]. */
10520 offset
|= (insn
& (1 << 13)) << 5;
10521 /* offset[19] = insn[11]. */
10522 offset
|= (insn
& (1 << 11)) << 8;
10524 /* jump to the offset */
10525 gen_jmp(s
, s
->pc
+ offset
);
10528 /* Data processing immediate. */
10529 if (insn
& (1 << 25)) {
10530 if (insn
& (1 << 24)) {
10531 if (insn
& (1 << 20))
10533 /* Bitfield/Saturate. */
10534 op
= (insn
>> 21) & 7;
10536 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10538 tmp
= tcg_temp_new_i32();
10539 tcg_gen_movi_i32(tmp
, 0);
10541 tmp
= load_reg(s
, rn
);
10544 case 2: /* Signed bitfield extract. */
10546 if (shift
+ imm
> 32)
10549 gen_sbfx(tmp
, shift
, imm
);
10551 case 6: /* Unsigned bitfield extract. */
10553 if (shift
+ imm
> 32)
10556 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
10558 case 3: /* Bitfield insert/clear. */
10561 imm
= imm
+ 1 - shift
;
10563 tmp2
= load_reg(s
, rd
);
10564 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10565 tcg_temp_free_i32(tmp2
);
10570 default: /* Saturate. */
10573 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10575 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10577 tmp2
= tcg_const_i32(imm
);
10580 if ((op
& 1) && shift
== 0) {
10581 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10582 tcg_temp_free_i32(tmp
);
10583 tcg_temp_free_i32(tmp2
);
10586 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10588 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10592 if ((op
& 1) && shift
== 0) {
10593 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10594 tcg_temp_free_i32(tmp
);
10595 tcg_temp_free_i32(tmp2
);
10598 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10600 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10603 tcg_temp_free_i32(tmp2
);
10606 store_reg(s
, rd
, tmp
);
10608 imm
= ((insn
& 0x04000000) >> 15)
10609 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10610 if (insn
& (1 << 22)) {
10611 /* 16-bit immediate. */
10612 imm
|= (insn
>> 4) & 0xf000;
10613 if (insn
& (1 << 23)) {
10615 tmp
= load_reg(s
, rd
);
10616 tcg_gen_ext16u_i32(tmp
, tmp
);
10617 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10620 tmp
= tcg_temp_new_i32();
10621 tcg_gen_movi_i32(tmp
, imm
);
10624 /* Add/sub 12-bit immediate. */
10626 offset
= s
->pc
& ~(uint32_t)3;
10627 if (insn
& (1 << 23))
10631 tmp
= tcg_temp_new_i32();
10632 tcg_gen_movi_i32(tmp
, offset
);
10634 tmp
= load_reg(s
, rn
);
10635 if (insn
& (1 << 23))
10636 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10638 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10641 store_reg(s
, rd
, tmp
);
10644 int shifter_out
= 0;
10645 /* modified 12-bit immediate. */
10646 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10647 imm
= (insn
& 0xff);
10650 /* Nothing to do. */
10652 case 1: /* 00XY00XY */
10655 case 2: /* XY00XY00 */
10659 case 3: /* XYXYXYXY */
10663 default: /* Rotated constant. */
10664 shift
= (shift
<< 1) | (imm
>> 7);
10666 imm
= imm
<< (32 - shift
);
10670 tmp2
= tcg_temp_new_i32();
10671 tcg_gen_movi_i32(tmp2
, imm
);
10672 rn
= (insn
>> 16) & 0xf;
10674 tmp
= tcg_temp_new_i32();
10675 tcg_gen_movi_i32(tmp
, 0);
10677 tmp
= load_reg(s
, rn
);
10679 op
= (insn
>> 21) & 0xf;
10680 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10681 shifter_out
, tmp
, tmp2
))
10683 tcg_temp_free_i32(tmp2
);
10684 rd
= (insn
>> 8) & 0xf;
10686 store_reg(s
, rd
, tmp
);
10688 tcg_temp_free_i32(tmp
);
10693 case 12: /* Load/store single data item. */
10698 if ((insn
& 0x01100000) == 0x01000000) {
10699 if (disas_neon_ls_insn(s
, insn
)) {
10704 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10706 if (!(insn
& (1 << 20))) {
10710 /* Byte or halfword load space with dest == r15 : memory hints.
10711 * Catch them early so we don't emit pointless addressing code.
10712 * This space is a mix of:
10713 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10714 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10716 * unallocated hints, which must be treated as NOPs
10717 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10718 * which is easiest for the decoding logic
10719 * Some space which must UNDEF
10721 int op1
= (insn
>> 23) & 3;
10722 int op2
= (insn
>> 6) & 0x3f;
10727 /* UNPREDICTABLE, unallocated hint or
10728 * PLD/PLDW/PLI (literal)
10733 return 0; /* PLD/PLDW/PLI or unallocated hint */
10735 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10736 return 0; /* PLD/PLDW/PLI or unallocated hint */
10738 /* UNDEF space, or an UNPREDICTABLE */
10742 memidx
= get_mem_index(s
);
10744 addr
= tcg_temp_new_i32();
10746 /* s->pc has already been incremented by 4. */
10747 imm
= s
->pc
& 0xfffffffc;
10748 if (insn
& (1 << 23))
10749 imm
+= insn
& 0xfff;
10751 imm
-= insn
& 0xfff;
10752 tcg_gen_movi_i32(addr
, imm
);
10754 addr
= load_reg(s
, rn
);
10755 if (insn
& (1 << 23)) {
10756 /* Positive offset. */
10757 imm
= insn
& 0xfff;
10758 tcg_gen_addi_i32(addr
, addr
, imm
);
10761 switch ((insn
>> 8) & 0xf) {
10762 case 0x0: /* Shifted Register. */
10763 shift
= (insn
>> 4) & 0xf;
10765 tcg_temp_free_i32(addr
);
10768 tmp
= load_reg(s
, rm
);
10770 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10771 tcg_gen_add_i32(addr
, addr
, tmp
);
10772 tcg_temp_free_i32(tmp
);
10774 case 0xc: /* Negative offset. */
10775 tcg_gen_addi_i32(addr
, addr
, -imm
);
10777 case 0xe: /* User privilege. */
10778 tcg_gen_addi_i32(addr
, addr
, imm
);
10779 memidx
= get_a32_user_mem_index(s
);
10781 case 0x9: /* Post-decrement. */
10783 /* Fall through. */
10784 case 0xb: /* Post-increment. */
10788 case 0xd: /* Pre-decrement. */
10790 /* Fall through. */
10791 case 0xf: /* Pre-increment. */
10792 tcg_gen_addi_i32(addr
, addr
, imm
);
10796 tcg_temp_free_i32(addr
);
10801 if (insn
& (1 << 20)) {
10803 tmp
= tcg_temp_new_i32();
10806 gen_aa32_ld8u(s
, tmp
, addr
, memidx
);
10809 gen_aa32_ld8s(s
, tmp
, addr
, memidx
);
10812 gen_aa32_ld16u(s
, tmp
, addr
, memidx
);
10815 gen_aa32_ld16s(s
, tmp
, addr
, memidx
);
10818 gen_aa32_ld32u(s
, tmp
, addr
, memidx
);
10821 tcg_temp_free_i32(tmp
);
10822 tcg_temp_free_i32(addr
);
10828 store_reg(s
, rs
, tmp
);
10832 tmp
= load_reg(s
, rs
);
10835 gen_aa32_st8(s
, tmp
, addr
, memidx
);
10838 gen_aa32_st16(s
, tmp
, addr
, memidx
);
10841 gen_aa32_st32(s
, tmp
, addr
, memidx
);
10844 tcg_temp_free_i32(tmp
);
10845 tcg_temp_free_i32(addr
);
10848 tcg_temp_free_i32(tmp
);
10851 tcg_gen_addi_i32(addr
, addr
, imm
);
10853 store_reg(s
, rn
, addr
);
10855 tcg_temp_free_i32(addr
);
10867 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10869 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10876 if (s
->condexec_mask
) {
10877 cond
= s
->condexec_cond
;
10878 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10879 s
->condlabel
= gen_new_label();
10880 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10885 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
10888 switch (insn
>> 12) {
10892 op
= (insn
>> 11) & 3;
10895 rn
= (insn
>> 3) & 7;
10896 tmp
= load_reg(s
, rn
);
10897 if (insn
& (1 << 10)) {
10899 tmp2
= tcg_temp_new_i32();
10900 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10903 rm
= (insn
>> 6) & 7;
10904 tmp2
= load_reg(s
, rm
);
10906 if (insn
& (1 << 9)) {
10907 if (s
->condexec_mask
)
10908 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10910 gen_sub_CC(tmp
, tmp
, tmp2
);
10912 if (s
->condexec_mask
)
10913 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10915 gen_add_CC(tmp
, tmp
, tmp2
);
10917 tcg_temp_free_i32(tmp2
);
10918 store_reg(s
, rd
, tmp
);
10920 /* shift immediate */
10921 rm
= (insn
>> 3) & 7;
10922 shift
= (insn
>> 6) & 0x1f;
10923 tmp
= load_reg(s
, rm
);
10924 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10925 if (!s
->condexec_mask
)
10927 store_reg(s
, rd
, tmp
);
10931 /* arithmetic large immediate */
10932 op
= (insn
>> 11) & 3;
10933 rd
= (insn
>> 8) & 0x7;
10934 if (op
== 0) { /* mov */
10935 tmp
= tcg_temp_new_i32();
10936 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10937 if (!s
->condexec_mask
)
10939 store_reg(s
, rd
, tmp
);
10941 tmp
= load_reg(s
, rd
);
10942 tmp2
= tcg_temp_new_i32();
10943 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10946 gen_sub_CC(tmp
, tmp
, tmp2
);
10947 tcg_temp_free_i32(tmp
);
10948 tcg_temp_free_i32(tmp2
);
10951 if (s
->condexec_mask
)
10952 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10954 gen_add_CC(tmp
, tmp
, tmp2
);
10955 tcg_temp_free_i32(tmp2
);
10956 store_reg(s
, rd
, tmp
);
10959 if (s
->condexec_mask
)
10960 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10962 gen_sub_CC(tmp
, tmp
, tmp2
);
10963 tcg_temp_free_i32(tmp2
);
10964 store_reg(s
, rd
, tmp
);
10970 if (insn
& (1 << 11)) {
10971 rd
= (insn
>> 8) & 7;
10972 /* load pc-relative. Bit 1 of PC is ignored. */
10973 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10974 val
&= ~(uint32_t)2;
10975 addr
= tcg_temp_new_i32();
10976 tcg_gen_movi_i32(addr
, val
);
10977 tmp
= tcg_temp_new_i32();
10978 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10979 tcg_temp_free_i32(addr
);
10980 store_reg(s
, rd
, tmp
);
10983 if (insn
& (1 << 10)) {
10984 /* data processing extended or blx */
10985 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10986 rm
= (insn
>> 3) & 0xf;
10987 op
= (insn
>> 8) & 3;
10990 tmp
= load_reg(s
, rd
);
10991 tmp2
= load_reg(s
, rm
);
10992 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10993 tcg_temp_free_i32(tmp2
);
10994 store_reg(s
, rd
, tmp
);
10997 tmp
= load_reg(s
, rd
);
10998 tmp2
= load_reg(s
, rm
);
10999 gen_sub_CC(tmp
, tmp
, tmp2
);
11000 tcg_temp_free_i32(tmp2
);
11001 tcg_temp_free_i32(tmp
);
11003 case 2: /* mov/cpy */
11004 tmp
= load_reg(s
, rm
);
11005 store_reg(s
, rd
, tmp
);
11007 case 3:/* branch [and link] exchange thumb register */
11008 tmp
= load_reg(s
, rm
);
11009 if (insn
& (1 << 7)) {
11011 val
= (uint32_t)s
->pc
| 1;
11012 tmp2
= tcg_temp_new_i32();
11013 tcg_gen_movi_i32(tmp2
, val
);
11014 store_reg(s
, 14, tmp2
);
11016 /* already thumb, no need to check */
11023 /* data processing register */
11025 rm
= (insn
>> 3) & 7;
11026 op
= (insn
>> 6) & 0xf;
11027 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11028 /* the shift/rotate ops want the operands backwards */
11037 if (op
== 9) { /* neg */
11038 tmp
= tcg_temp_new_i32();
11039 tcg_gen_movi_i32(tmp
, 0);
11040 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11041 tmp
= load_reg(s
, rd
);
11043 TCGV_UNUSED_I32(tmp
);
11046 tmp2
= load_reg(s
, rm
);
11048 case 0x0: /* and */
11049 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11050 if (!s
->condexec_mask
)
11053 case 0x1: /* eor */
11054 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11055 if (!s
->condexec_mask
)
11058 case 0x2: /* lsl */
11059 if (s
->condexec_mask
) {
11060 gen_shl(tmp2
, tmp2
, tmp
);
11062 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11063 gen_logic_CC(tmp2
);
11066 case 0x3: /* lsr */
11067 if (s
->condexec_mask
) {
11068 gen_shr(tmp2
, tmp2
, tmp
);
11070 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11071 gen_logic_CC(tmp2
);
11074 case 0x4: /* asr */
11075 if (s
->condexec_mask
) {
11076 gen_sar(tmp2
, tmp2
, tmp
);
11078 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11079 gen_logic_CC(tmp2
);
11082 case 0x5: /* adc */
11083 if (s
->condexec_mask
) {
11084 gen_adc(tmp
, tmp2
);
11086 gen_adc_CC(tmp
, tmp
, tmp2
);
11089 case 0x6: /* sbc */
11090 if (s
->condexec_mask
) {
11091 gen_sub_carry(tmp
, tmp
, tmp2
);
11093 gen_sbc_CC(tmp
, tmp
, tmp2
);
11096 case 0x7: /* ror */
11097 if (s
->condexec_mask
) {
11098 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11099 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11101 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11102 gen_logic_CC(tmp2
);
11105 case 0x8: /* tst */
11106 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11110 case 0x9: /* neg */
11111 if (s
->condexec_mask
)
11112 tcg_gen_neg_i32(tmp
, tmp2
);
11114 gen_sub_CC(tmp
, tmp
, tmp2
);
11116 case 0xa: /* cmp */
11117 gen_sub_CC(tmp
, tmp
, tmp2
);
11120 case 0xb: /* cmn */
11121 gen_add_CC(tmp
, tmp
, tmp2
);
11124 case 0xc: /* orr */
11125 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11126 if (!s
->condexec_mask
)
11129 case 0xd: /* mul */
11130 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11131 if (!s
->condexec_mask
)
11134 case 0xe: /* bic */
11135 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11136 if (!s
->condexec_mask
)
11139 case 0xf: /* mvn */
11140 tcg_gen_not_i32(tmp2
, tmp2
);
11141 if (!s
->condexec_mask
)
11142 gen_logic_CC(tmp2
);
11149 store_reg(s
, rm
, tmp2
);
11151 tcg_temp_free_i32(tmp
);
11153 store_reg(s
, rd
, tmp
);
11154 tcg_temp_free_i32(tmp2
);
11157 tcg_temp_free_i32(tmp
);
11158 tcg_temp_free_i32(tmp2
);
11163 /* load/store register offset. */
11165 rn
= (insn
>> 3) & 7;
11166 rm
= (insn
>> 6) & 7;
11167 op
= (insn
>> 9) & 7;
11168 addr
= load_reg(s
, rn
);
11169 tmp
= load_reg(s
, rm
);
11170 tcg_gen_add_i32(addr
, addr
, tmp
);
11171 tcg_temp_free_i32(tmp
);
11173 if (op
< 3) { /* store */
11174 tmp
= load_reg(s
, rd
);
11176 tmp
= tcg_temp_new_i32();
11181 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11184 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11187 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11189 case 3: /* ldrsb */
11190 gen_aa32_ld8s(s
, tmp
, addr
, get_mem_index(s
));
11193 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11196 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11199 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11201 case 7: /* ldrsh */
11202 gen_aa32_ld16s(s
, tmp
, addr
, get_mem_index(s
));
11205 if (op
>= 3) { /* load */
11206 store_reg(s
, rd
, tmp
);
11208 tcg_temp_free_i32(tmp
);
11210 tcg_temp_free_i32(addr
);
11214 /* load/store word immediate offset */
11216 rn
= (insn
>> 3) & 7;
11217 addr
= load_reg(s
, rn
);
11218 val
= (insn
>> 4) & 0x7c;
11219 tcg_gen_addi_i32(addr
, addr
, val
);
11221 if (insn
& (1 << 11)) {
11223 tmp
= tcg_temp_new_i32();
11224 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11225 store_reg(s
, rd
, tmp
);
11228 tmp
= load_reg(s
, rd
);
11229 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11230 tcg_temp_free_i32(tmp
);
11232 tcg_temp_free_i32(addr
);
11236 /* load/store byte immediate offset */
11238 rn
= (insn
>> 3) & 7;
11239 addr
= load_reg(s
, rn
);
11240 val
= (insn
>> 6) & 0x1f;
11241 tcg_gen_addi_i32(addr
, addr
, val
);
11243 if (insn
& (1 << 11)) {
11245 tmp
= tcg_temp_new_i32();
11246 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
11247 store_reg(s
, rd
, tmp
);
11250 tmp
= load_reg(s
, rd
);
11251 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
11252 tcg_temp_free_i32(tmp
);
11254 tcg_temp_free_i32(addr
);
11258 /* load/store halfword immediate offset */
11260 rn
= (insn
>> 3) & 7;
11261 addr
= load_reg(s
, rn
);
11262 val
= (insn
>> 5) & 0x3e;
11263 tcg_gen_addi_i32(addr
, addr
, val
);
11265 if (insn
& (1 << 11)) {
11267 tmp
= tcg_temp_new_i32();
11268 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
11269 store_reg(s
, rd
, tmp
);
11272 tmp
= load_reg(s
, rd
);
11273 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
11274 tcg_temp_free_i32(tmp
);
11276 tcg_temp_free_i32(addr
);
11280 /* load/store from stack */
11281 rd
= (insn
>> 8) & 7;
11282 addr
= load_reg(s
, 13);
11283 val
= (insn
& 0xff) * 4;
11284 tcg_gen_addi_i32(addr
, addr
, val
);
11286 if (insn
& (1 << 11)) {
11288 tmp
= tcg_temp_new_i32();
11289 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11290 store_reg(s
, rd
, tmp
);
11293 tmp
= load_reg(s
, rd
);
11294 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11295 tcg_temp_free_i32(tmp
);
11297 tcg_temp_free_i32(addr
);
11301 /* add to high reg */
11302 rd
= (insn
>> 8) & 7;
11303 if (insn
& (1 << 11)) {
11305 tmp
= load_reg(s
, 13);
11307 /* PC. bit 1 is ignored. */
11308 tmp
= tcg_temp_new_i32();
11309 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11311 val
= (insn
& 0xff) * 4;
11312 tcg_gen_addi_i32(tmp
, tmp
, val
);
11313 store_reg(s
, rd
, tmp
);
11318 op
= (insn
>> 8) & 0xf;
11321 /* adjust stack pointer */
11322 tmp
= load_reg(s
, 13);
11323 val
= (insn
& 0x7f) * 4;
11324 if (insn
& (1 << 7))
11325 val
= -(int32_t)val
;
11326 tcg_gen_addi_i32(tmp
, tmp
, val
);
11327 store_reg(s
, 13, tmp
);
11330 case 2: /* sign/zero extend. */
11333 rm
= (insn
>> 3) & 7;
11334 tmp
= load_reg(s
, rm
);
11335 switch ((insn
>> 6) & 3) {
11336 case 0: gen_sxth(tmp
); break;
11337 case 1: gen_sxtb(tmp
); break;
11338 case 2: gen_uxth(tmp
); break;
11339 case 3: gen_uxtb(tmp
); break;
11341 store_reg(s
, rd
, tmp
);
11343 case 4: case 5: case 0xc: case 0xd:
11345 addr
= load_reg(s
, 13);
11346 if (insn
& (1 << 8))
11350 for (i
= 0; i
< 8; i
++) {
11351 if (insn
& (1 << i
))
11354 if ((insn
& (1 << 11)) == 0) {
11355 tcg_gen_addi_i32(addr
, addr
, -offset
);
11357 for (i
= 0; i
< 8; i
++) {
11358 if (insn
& (1 << i
)) {
11359 if (insn
& (1 << 11)) {
11361 tmp
= tcg_temp_new_i32();
11362 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11363 store_reg(s
, i
, tmp
);
11366 tmp
= load_reg(s
, i
);
11367 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11368 tcg_temp_free_i32(tmp
);
11370 /* advance to the next address. */
11371 tcg_gen_addi_i32(addr
, addr
, 4);
11374 TCGV_UNUSED_I32(tmp
);
11375 if (insn
& (1 << 8)) {
11376 if (insn
& (1 << 11)) {
11378 tmp
= tcg_temp_new_i32();
11379 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11380 /* don't set the pc until the rest of the instruction
11384 tmp
= load_reg(s
, 14);
11385 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11386 tcg_temp_free_i32(tmp
);
11388 tcg_gen_addi_i32(addr
, addr
, 4);
11390 if ((insn
& (1 << 11)) == 0) {
11391 tcg_gen_addi_i32(addr
, addr
, -offset
);
11393 /* write back the new stack pointer */
11394 store_reg(s
, 13, addr
);
11395 /* set the new PC value */
11396 if ((insn
& 0x0900) == 0x0900) {
11397 store_reg_from_load(s
, 15, tmp
);
11401 case 1: case 3: case 9: case 11: /* czb */
11403 tmp
= load_reg(s
, rm
);
11404 s
->condlabel
= gen_new_label();
11406 if (insn
& (1 << 11))
11407 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11409 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11410 tcg_temp_free_i32(tmp
);
11411 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11412 val
= (uint32_t)s
->pc
+ 2;
11417 case 15: /* IT, nop-hint. */
11418 if ((insn
& 0xf) == 0) {
11419 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11423 s
->condexec_cond
= (insn
>> 4) & 0xe;
11424 s
->condexec_mask
= insn
& 0x1f;
11425 /* No actual code generated for this insn, just setup state. */
11428 case 0xe: /* bkpt */
11430 int imm8
= extract32(insn
, 0, 8);
11432 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11433 default_exception_el(s
));
11437 case 0xa: /* rev */
11439 rn
= (insn
>> 3) & 0x7;
11441 tmp
= load_reg(s
, rn
);
11442 switch ((insn
>> 6) & 3) {
11443 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11444 case 1: gen_rev16(tmp
); break;
11445 case 3: gen_revsh(tmp
); break;
11446 default: goto illegal_op
;
11448 store_reg(s
, rd
, tmp
);
11452 switch ((insn
>> 5) & 7) {
11456 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11457 gen_helper_setend(cpu_env
);
11458 s
->is_jmp
= DISAS_UPDATE
;
11467 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11468 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11471 addr
= tcg_const_i32(19);
11472 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11473 tcg_temp_free_i32(addr
);
11477 addr
= tcg_const_i32(16);
11478 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11479 tcg_temp_free_i32(addr
);
11481 tcg_temp_free_i32(tmp
);
11484 if (insn
& (1 << 4)) {
11485 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11489 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11504 /* load/store multiple */
11505 TCGv_i32 loaded_var
;
11506 TCGV_UNUSED_I32(loaded_var
);
11507 rn
= (insn
>> 8) & 0x7;
11508 addr
= load_reg(s
, rn
);
11509 for (i
= 0; i
< 8; i
++) {
11510 if (insn
& (1 << i
)) {
11511 if (insn
& (1 << 11)) {
11513 tmp
= tcg_temp_new_i32();
11514 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11518 store_reg(s
, i
, tmp
);
11522 tmp
= load_reg(s
, i
);
11523 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11524 tcg_temp_free_i32(tmp
);
11526 /* advance to the next address */
11527 tcg_gen_addi_i32(addr
, addr
, 4);
11530 if ((insn
& (1 << rn
)) == 0) {
11531 /* base reg not in list: base register writeback */
11532 store_reg(s
, rn
, addr
);
11534 /* base reg in list: if load, complete it now */
11535 if (insn
& (1 << 11)) {
11536 store_reg(s
, rn
, loaded_var
);
11538 tcg_temp_free_i32(addr
);
11543 /* conditional branch or swi */
11544 cond
= (insn
>> 8) & 0xf;
11550 gen_set_pc_im(s
, s
->pc
);
11551 s
->svc_imm
= extract32(insn
, 0, 8);
11552 s
->is_jmp
= DISAS_SWI
;
11555 /* generate a conditional jump to next instruction */
11556 s
->condlabel
= gen_new_label();
11557 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11560 /* jump to the offset */
11561 val
= (uint32_t)s
->pc
+ 2;
11562 offset
= ((int32_t)insn
<< 24) >> 24;
11563 val
+= offset
<< 1;
11568 if (insn
& (1 << 11)) {
11569 if (disas_thumb2_insn(env
, s
, insn
))
11573 /* unconditional branch */
11574 val
= (uint32_t)s
->pc
;
11575 offset
= ((int32_t)insn
<< 21) >> 21;
11576 val
+= (offset
<< 1) + 2;
11581 if (disas_thumb2_insn(env
, s
, insn
))
11587 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11588 default_exception_el(s
));
11592 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11593 default_exception_el(s
));
11596 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11598 /* Return true if the insn at dc->pc might cross a page boundary.
11599 * (False positives are OK, false negatives are not.)
11603 if ((s
->pc
& 3) == 0) {
11604 /* At a 4-aligned address we can't be crossing a page */
11608 /* This must be a Thumb insn */
11609 insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11611 if ((insn
>> 11) >= 0x1d) {
11612 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11613 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11614 * end up actually treating this as two 16-bit insns (see the
11615 * code at the start of disas_thumb2_insn()) but we don't bother
11616 * to check for that as it is unlikely, and false positives here
11621 /* Definitely a 16-bit insn, can't be crossing a page. */
11625 /* generate intermediate code for basic block 'tb'. */
11626 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11628 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11629 CPUState
*cs
= CPU(cpu
);
11630 DisasContext dc1
, *dc
= &dc1
;
11631 target_ulong pc_start
;
11632 target_ulong next_page_start
;
11637 /* generate intermediate code */
11639 /* The A64 decoder has its own top level loop, because it doesn't need
11640 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11642 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11643 gen_intermediate_code_a64(cpu
, tb
);
11651 dc
->is_jmp
= DISAS_NEXT
;
11653 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11657 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11658 * there is no secure EL1, so we route exceptions to EL3.
11660 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11661 !arm_el_is_aa64(env
, 3);
11662 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11663 dc
->sctlr_b
= ARM_TBFLAG_SCTLR_B(tb
->flags
);
11664 dc
->be_data
= ARM_TBFLAG_BE_DATA(tb
->flags
) ? MO_BE
: MO_LE
;
11665 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11666 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11667 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11668 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11669 #if !defined(CONFIG_USER_ONLY)
11670 dc
->user
= (dc
->current_el
== 0);
11672 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11673 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11674 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11675 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11676 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11677 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11678 dc
->cp_regs
= cpu
->cp_regs
;
11679 dc
->features
= env
->features
;
11681 /* Single step state. The code-generation logic here is:
11683 * generate code with no special handling for single-stepping (except
11684 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11685 * this happens anyway because those changes are all system register or
11687 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11688 * emit code for one insn
11689 * emit code to clear PSTATE.SS
11690 * emit code to generate software step exception for completed step
11691 * end TB (as usual for having generated an exception)
11692 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11693 * emit code to generate a software step exception
11696 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11697 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11698 dc
->is_ldex
= false;
11699 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11701 cpu_F0s
= tcg_temp_new_i32();
11702 cpu_F1s
= tcg_temp_new_i32();
11703 cpu_F0d
= tcg_temp_new_i64();
11704 cpu_F1d
= tcg_temp_new_i64();
11707 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11708 cpu_M0
= tcg_temp_new_i64();
11709 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11711 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11712 if (max_insns
== 0) {
11713 max_insns
= CF_COUNT_MASK
;
11715 if (max_insns
> TCG_MAX_INSNS
) {
11716 max_insns
= TCG_MAX_INSNS
;
11721 tcg_clear_temp_count();
11723 /* A note on handling of the condexec (IT) bits:
11725 * We want to avoid the overhead of having to write the updated condexec
11726 * bits back to the CPUARMState for every instruction in an IT block. So:
11727 * (1) if the condexec bits are not already zero then we write
11728 * zero back into the CPUARMState now. This avoids complications trying
11729 * to do it at the end of the block. (For example if we don't do this
11730 * it's hard to identify whether we can safely skip writing condexec
11731 * at the end of the TB, which we definitely want to do for the case
11732 * where a TB doesn't do anything with the IT state at all.)
11733 * (2) if we are going to leave the TB then we call gen_set_condexec()
11734 * which will write the correct value into CPUARMState if zero is wrong.
11735 * This is done both for leaving the TB at the end, and for leaving
11736 * it because of an exception we know will happen, which is done in
11737 * gen_exception_insn(). The latter is necessary because we need to
11738 * leave the TB with the PC/IT state just prior to execution of the
11739 * instruction which caused the exception.
11740 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11741 * then the CPUARMState will be wrong and we need to reset it.
11742 * This is handled in the same way as restoration of the
11743 * PC in these situations; we save the value of the condexec bits
11744 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11745 * then uses this to restore them after an exception.
11747 * Note that there are no instructions which can read the condexec
11748 * bits, and none which can write non-static values to them, so
11749 * we don't need to care about whether CPUARMState is correct in the
11753 /* Reset the conditional execution bits immediately. This avoids
11754 complications trying to do it at the end of the block. */
11755 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11757 TCGv_i32 tmp
= tcg_temp_new_i32();
11758 tcg_gen_movi_i32(tmp
, 0);
11759 store_cpu_field(tmp
, condexec_bits
);
11762 tcg_gen_insn_start(dc
->pc
,
11763 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11767 #ifdef CONFIG_USER_ONLY
11768 /* Intercept jump to the magic kernel page. */
11769 if (dc
->pc
>= 0xffff0000) {
11770 /* We always get here via a jump, so know we are not in a
11771 conditional execution block. */
11772 gen_exception_internal(EXCP_KERNEL_TRAP
);
11773 dc
->is_jmp
= DISAS_EXC
;
11777 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11778 /* We always get here via a jump, so know we are not in a
11779 conditional execution block. */
11780 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11781 dc
->is_jmp
= DISAS_EXC
;
11786 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11788 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11789 if (bp
->pc
== dc
->pc
) {
11790 if (bp
->flags
& BP_CPU
) {
11791 gen_set_condexec(dc
);
11792 gen_set_pc_im(dc
, dc
->pc
);
11793 gen_helper_check_breakpoints(cpu_env
);
11794 /* End the TB early; it's likely not going to be executed */
11795 dc
->is_jmp
= DISAS_UPDATE
;
11797 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11798 /* The address covered by the breakpoint must be
11799 included in [tb->pc, tb->pc + tb->size) in order
11800 to for it to be properly cleared -- thus we
11801 increment the PC here so that the logic setting
11802 tb->size below does the right thing. */
11803 /* TODO: Advance PC by correct instruction length to
11804 * avoid disassembler error messages */
11806 goto done_generating
;
11813 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11817 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11818 /* Singlestep state is Active-pending.
11819 * If we're in this state at the start of a TB then either
11820 * a) we just took an exception to an EL which is being debugged
11821 * and this is the first insn in the exception handler
11822 * b) debug exceptions were masked and we just unmasked them
11823 * without changing EL (eg by clearing PSTATE.D)
11824 * In either case we're going to take a swstep exception in the
11825 * "did not step an insn" case, and so the syndrome ISV and EX
11826 * bits should be zero.
11828 assert(num_insns
== 1);
11829 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11830 default_exception_el(dc
));
11831 goto done_generating
;
11835 disas_thumb_insn(env
, dc
);
11836 if (dc
->condexec_mask
) {
11837 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11838 | ((dc
->condexec_mask
>> 4) & 1);
11839 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11840 if (dc
->condexec_mask
== 0) {
11841 dc
->condexec_cond
= 0;
11845 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
11847 disas_arm_insn(dc
, insn
);
11850 if (dc
->condjmp
&& !dc
->is_jmp
) {
11851 gen_set_label(dc
->condlabel
);
11855 if (tcg_check_temp_count()) {
11856 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11860 /* Translation stops when a conditional branch is encountered.
11861 * Otherwise the subsequent code could get translated several times.
11862 * Also stop translation when a page boundary is reached. This
11863 * ensures prefetch aborts occur at the right place. */
11865 /* We want to stop the TB if the next insn starts in a new page,
11866 * or if it spans between this page and the next. This means that
11867 * if we're looking at the last halfword in the page we need to
11868 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11869 * or a 32-bit Thumb insn (which won't).
11870 * This is to avoid generating a silly TB with a single 16-bit insn
11871 * in it at the end of this page (which would execute correctly
11872 * but isn't very efficient).
11874 end_of_page
= (dc
->pc
>= next_page_start
) ||
11875 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
11877 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11878 !cs
->singlestep_enabled
&&
11882 num_insns
< max_insns
);
11884 if (tb
->cflags
& CF_LAST_IO
) {
11886 /* FIXME: This can theoretically happen with self-modifying
11888 cpu_abort(cs
, "IO on conditional branch instruction");
11893 /* At this stage dc->condjmp will only be set when the skipped
11894 instruction was a conditional branch or trap, and the PC has
11895 already been written. */
11896 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11897 /* Unconditional and "condition passed" instruction codepath. */
11898 gen_set_condexec(dc
);
11899 switch (dc
->is_jmp
) {
11901 gen_ss_advance(dc
);
11902 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11903 default_exception_el(dc
));
11906 gen_ss_advance(dc
);
11907 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11910 gen_ss_advance(dc
);
11911 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11915 gen_set_pc_im(dc
, dc
->pc
);
11918 if (dc
->ss_active
) {
11919 gen_step_complete_exception(dc
);
11921 /* FIXME: Single stepping a WFI insn will not halt
11923 gen_exception_internal(EXCP_DEBUG
);
11927 /* "Condition failed" instruction codepath. */
11928 gen_set_label(dc
->condlabel
);
11929 gen_set_condexec(dc
);
11930 gen_set_pc_im(dc
, dc
->pc
);
11931 if (dc
->ss_active
) {
11932 gen_step_complete_exception(dc
);
11934 gen_exception_internal(EXCP_DEBUG
);
11938 /* While branches must always occur at the end of an IT block,
11939 there are a few other things that can cause us to terminate
11940 the TB in the middle of an IT block:
11941 - Exception generating instructions (bkpt, swi, undefined).
11943 - Hardware watchpoints.
11944 Hardware breakpoints have already been handled and skip this code.
11946 gen_set_condexec(dc
);
11947 switch(dc
->is_jmp
) {
11949 gen_goto_tb(dc
, 1, dc
->pc
);
11952 gen_set_pc_im(dc
, dc
->pc
);
11956 /* indicate that the hash table must be used to find the next TB */
11957 tcg_gen_exit_tb(0);
11959 case DISAS_TB_JUMP
:
11960 /* nothing more to generate */
11963 gen_helper_wfi(cpu_env
);
11964 /* The helper doesn't necessarily throw an exception, but we
11965 * must go back to the main loop to check for interrupts anyway.
11967 tcg_gen_exit_tb(0);
11970 gen_helper_wfe(cpu_env
);
11973 gen_helper_yield(cpu_env
);
11976 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11977 default_exception_el(dc
));
11980 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11983 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11987 gen_set_label(dc
->condlabel
);
11988 gen_set_condexec(dc
);
11989 gen_goto_tb(dc
, 1, dc
->pc
);
11995 gen_tb_end(tb
, num_insns
);
11998 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
) &&
11999 qemu_log_in_addr_range(pc_start
)) {
12000 qemu_log("----------------\n");
12001 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
12002 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
12003 dc
->thumb
| (dc
->sctlr_b
<< 1));
12007 tb
->size
= dc
->pc
- pc_start
;
12008 tb
->icount
= num_insns
;
12011 static const char *cpu_mode_names
[16] = {
12012 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12013 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12016 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
12019 ARMCPU
*cpu
= ARM_CPU(cs
);
12020 CPUARMState
*env
= &cpu
->env
;
12023 const char *ns_status
;
12026 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
12030 for(i
=0;i
<16;i
++) {
12031 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
12033 cpu_fprintf(f
, "\n");
12035 cpu_fprintf(f
, " ");
12037 psr
= cpsr_read(env
);
12039 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
12040 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
12041 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
12046 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12048 psr
& (1 << 31) ? 'N' : '-',
12049 psr
& (1 << 30) ? 'Z' : '-',
12050 psr
& (1 << 29) ? 'C' : '-',
12051 psr
& (1 << 28) ? 'V' : '-',
12052 psr
& CPSR_T
? 'T' : 'A',
12054 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
12056 if (flags
& CPU_DUMP_FPU
) {
12057 int numvfpregs
= 0;
12058 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
12061 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
12064 for (i
= 0; i
< numvfpregs
; i
++) {
12065 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
12066 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
12067 i
* 2, (uint32_t)v
,
12068 i
* 2 + 1, (uint32_t)(v
>> 32),
12071 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
12075 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12076 target_ulong
*data
)
12080 env
->condexec_bits
= 0;
12081 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12083 env
->regs
[15] = data
[0];
12084 env
->condexec_bits
= data
[1];
12085 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;