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"
28 #include "qemu/bitops.h"
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
34 #include "trace-tcg.h"
38 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
39 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
40 /* currently all emulated v5 cores are also v5TE, so don't bother */
41 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
42 #define ENABLE_ARCH_5J 0
43 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
44 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
45 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
46 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
47 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
49 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
51 #include "translate.h"
53 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) (s->user)
60 /* We reuse the same 64-bit temporaries for efficiency. */
61 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
62 static TCGv_i32 cpu_R
[16];
63 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
64 TCGv_i64 cpu_exclusive_addr
;
65 TCGv_i64 cpu_exclusive_val
;
66 #ifdef CONFIG_USER_ONLY
67 TCGv_i64 cpu_exclusive_test
;
68 TCGv_i32 cpu_exclusive_info
;
71 /* FIXME: These should be removed. */
72 static TCGv_i32 cpu_F0s
, cpu_F1s
;
73 static TCGv_i64 cpu_F0d
, cpu_F1d
;
75 #include "exec/gen-icount.h"
77 static const char *regnames
[] =
78 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
79 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
86 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
88 for (i
= 0; i
< 16; i
++) {
89 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
90 offsetof(CPUARMState
, regs
[i
]),
93 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
94 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
95 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
96 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
98 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
99 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
100 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
101 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
102 #ifdef CONFIG_USER_ONLY
103 cpu_exclusive_test
= tcg_global_mem_new_i64(cpu_env
,
104 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
105 cpu_exclusive_info
= tcg_global_mem_new_i32(cpu_env
,
106 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
109 a64_translate_init();
112 static inline ARMMMUIdx
get_a32_user_mem_index(DisasContext
*s
)
114 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
116 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
117 * otherwise, access as if at PL0.
119 switch (s
->mmu_idx
) {
120 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
121 case ARMMMUIdx_S12NSE0
:
122 case ARMMMUIdx_S12NSE1
:
123 return ARMMMUIdx_S12NSE0
;
125 case ARMMMUIdx_S1SE0
:
126 case ARMMMUIdx_S1SE1
:
127 return ARMMMUIdx_S1SE0
;
130 g_assert_not_reached();
134 static inline TCGv_i32
load_cpu_offset(int offset
)
136 TCGv_i32 tmp
= tcg_temp_new_i32();
137 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
141 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
143 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
145 tcg_gen_st_i32(var
, cpu_env
, offset
);
146 tcg_temp_free_i32(var
);
149 #define store_cpu_field(var, name) \
150 store_cpu_offset(var, offsetof(CPUARMState, name))
152 /* Set a variable to the value of a CPU register. */
153 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
157 /* normally, since we updated PC, we need only to add one insn */
159 addr
= (long)s
->pc
+ 2;
161 addr
= (long)s
->pc
+ 4;
162 tcg_gen_movi_i32(var
, addr
);
164 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
168 /* Create a new temporary and set it to the value of a CPU register. */
169 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
171 TCGv_i32 tmp
= tcg_temp_new_i32();
172 load_reg_var(s
, tmp
, reg
);
176 /* Set a CPU register. The source must be a temporary and will be
178 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
181 tcg_gen_andi_i32(var
, var
, ~1);
182 s
->is_jmp
= DISAS_JUMP
;
184 tcg_gen_mov_i32(cpu_R
[reg
], var
);
185 tcg_temp_free_i32(var
);
188 /* Value extensions. */
189 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
190 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
191 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
192 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
194 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
195 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
198 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
200 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
201 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
202 tcg_temp_free_i32(tmp_mask
);
204 /* Set NZCV flags from the high 4 bits of var. */
205 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
207 static void gen_exception_internal(int excp
)
209 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
211 assert(excp_is_internal(excp
));
212 gen_helper_exception_internal(cpu_env
, tcg_excp
);
213 tcg_temp_free_i32(tcg_excp
);
216 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
218 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
219 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
220 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
222 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
225 tcg_temp_free_i32(tcg_el
);
226 tcg_temp_free_i32(tcg_syn
);
227 tcg_temp_free_i32(tcg_excp
);
230 static void gen_ss_advance(DisasContext
*s
)
232 /* If the singlestep state is Active-not-pending, advance to
237 gen_helper_clear_pstate_ss(cpu_env
);
241 static void gen_step_complete_exception(DisasContext
*s
)
243 /* We just completed step of an insn. Move from Active-not-pending
244 * to Active-pending, and then also take the swstep exception.
245 * This corresponds to making the (IMPDEF) choice to prioritize
246 * swstep exceptions over asynchronous exceptions taken to an exception
247 * level where debug is disabled. This choice has the advantage that
248 * we do not need to maintain internal state corresponding to the
249 * ISV/EX syndrome bits between completion of the step and generation
250 * of the exception, and our syndrome information is always correct.
253 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
254 default_exception_el(s
));
255 s
->is_jmp
= DISAS_EXC
;
258 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
260 TCGv_i32 tmp1
= tcg_temp_new_i32();
261 TCGv_i32 tmp2
= tcg_temp_new_i32();
262 tcg_gen_ext16s_i32(tmp1
, a
);
263 tcg_gen_ext16s_i32(tmp2
, b
);
264 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
265 tcg_temp_free_i32(tmp2
);
266 tcg_gen_sari_i32(a
, a
, 16);
267 tcg_gen_sari_i32(b
, b
, 16);
268 tcg_gen_mul_i32(b
, b
, a
);
269 tcg_gen_mov_i32(a
, tmp1
);
270 tcg_temp_free_i32(tmp1
);
273 /* Byteswap each halfword. */
274 static void gen_rev16(TCGv_i32 var
)
276 TCGv_i32 tmp
= tcg_temp_new_i32();
277 tcg_gen_shri_i32(tmp
, var
, 8);
278 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
279 tcg_gen_shli_i32(var
, var
, 8);
280 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
281 tcg_gen_or_i32(var
, var
, tmp
);
282 tcg_temp_free_i32(tmp
);
285 /* Byteswap low halfword and sign extend. */
286 static void gen_revsh(TCGv_i32 var
)
288 tcg_gen_ext16u_i32(var
, var
);
289 tcg_gen_bswap16_i32(var
, var
);
290 tcg_gen_ext16s_i32(var
, var
);
293 /* Unsigned bitfield extract. */
294 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
297 tcg_gen_shri_i32(var
, var
, shift
);
298 tcg_gen_andi_i32(var
, var
, mask
);
301 /* Signed bitfield extract. */
302 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
307 tcg_gen_sari_i32(var
, var
, shift
);
308 if (shift
+ width
< 32) {
309 signbit
= 1u << (width
- 1);
310 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
311 tcg_gen_xori_i32(var
, var
, signbit
);
312 tcg_gen_subi_i32(var
, var
, signbit
);
316 /* Return (b << 32) + a. Mark inputs as dead */
317 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
319 TCGv_i64 tmp64
= tcg_temp_new_i64();
321 tcg_gen_extu_i32_i64(tmp64
, b
);
322 tcg_temp_free_i32(b
);
323 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
324 tcg_gen_add_i64(a
, tmp64
, a
);
326 tcg_temp_free_i64(tmp64
);
330 /* Return (b << 32) - a. Mark inputs as dead. */
331 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
333 TCGv_i64 tmp64
= tcg_temp_new_i64();
335 tcg_gen_extu_i32_i64(tmp64
, b
);
336 tcg_temp_free_i32(b
);
337 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
338 tcg_gen_sub_i64(a
, tmp64
, a
);
340 tcg_temp_free_i64(tmp64
);
344 /* 32x32->64 multiply. Marks inputs as dead. */
345 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
347 TCGv_i32 lo
= tcg_temp_new_i32();
348 TCGv_i32 hi
= tcg_temp_new_i32();
351 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
352 tcg_temp_free_i32(a
);
353 tcg_temp_free_i32(b
);
355 ret
= tcg_temp_new_i64();
356 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
357 tcg_temp_free_i32(lo
);
358 tcg_temp_free_i32(hi
);
363 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
365 TCGv_i32 lo
= tcg_temp_new_i32();
366 TCGv_i32 hi
= tcg_temp_new_i32();
369 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
370 tcg_temp_free_i32(a
);
371 tcg_temp_free_i32(b
);
373 ret
= tcg_temp_new_i64();
374 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
375 tcg_temp_free_i32(lo
);
376 tcg_temp_free_i32(hi
);
381 /* Swap low and high halfwords. */
382 static void gen_swap_half(TCGv_i32 var
)
384 TCGv_i32 tmp
= tcg_temp_new_i32();
385 tcg_gen_shri_i32(tmp
, var
, 16);
386 tcg_gen_shli_i32(var
, var
, 16);
387 tcg_gen_or_i32(var
, var
, tmp
);
388 tcg_temp_free_i32(tmp
);
391 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
392 tmp = (t0 ^ t1) & 0x8000;
395 t0 = (t0 + t1) ^ tmp;
398 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
400 TCGv_i32 tmp
= tcg_temp_new_i32();
401 tcg_gen_xor_i32(tmp
, t0
, t1
);
402 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
403 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
404 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
405 tcg_gen_add_i32(t0
, t0
, t1
);
406 tcg_gen_xor_i32(t0
, t0
, tmp
);
407 tcg_temp_free_i32(tmp
);
408 tcg_temp_free_i32(t1
);
411 /* Set CF to the top bit of var. */
412 static void gen_set_CF_bit31(TCGv_i32 var
)
414 tcg_gen_shri_i32(cpu_CF
, var
, 31);
417 /* Set N and Z flags from var. */
418 static inline void gen_logic_CC(TCGv_i32 var
)
420 tcg_gen_mov_i32(cpu_NF
, var
);
421 tcg_gen_mov_i32(cpu_ZF
, var
);
425 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
427 tcg_gen_add_i32(t0
, t0
, t1
);
428 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
431 /* dest = T0 + T1 + CF. */
432 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
434 tcg_gen_add_i32(dest
, t0
, t1
);
435 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
438 /* dest = T0 - T1 + CF - 1. */
439 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
441 tcg_gen_sub_i32(dest
, t0
, t1
);
442 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
443 tcg_gen_subi_i32(dest
, dest
, 1);
446 /* dest = T0 + T1. Compute C, N, V and Z flags */
447 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
449 TCGv_i32 tmp
= tcg_temp_new_i32();
450 tcg_gen_movi_i32(tmp
, 0);
451 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
452 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
453 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
454 tcg_gen_xor_i32(tmp
, t0
, t1
);
455 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
456 tcg_temp_free_i32(tmp
);
457 tcg_gen_mov_i32(dest
, cpu_NF
);
460 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
461 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
463 TCGv_i32 tmp
= tcg_temp_new_i32();
464 if (TCG_TARGET_HAS_add2_i32
) {
465 tcg_gen_movi_i32(tmp
, 0);
466 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
467 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
469 TCGv_i64 q0
= tcg_temp_new_i64();
470 TCGv_i64 q1
= tcg_temp_new_i64();
471 tcg_gen_extu_i32_i64(q0
, t0
);
472 tcg_gen_extu_i32_i64(q1
, t1
);
473 tcg_gen_add_i64(q0
, q0
, q1
);
474 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
475 tcg_gen_add_i64(q0
, q0
, q1
);
476 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
477 tcg_temp_free_i64(q0
);
478 tcg_temp_free_i64(q1
);
480 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
481 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
482 tcg_gen_xor_i32(tmp
, t0
, t1
);
483 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
484 tcg_temp_free_i32(tmp
);
485 tcg_gen_mov_i32(dest
, cpu_NF
);
488 /* dest = T0 - T1. Compute C, N, V and Z flags */
489 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
492 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
493 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
494 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
495 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
496 tmp
= tcg_temp_new_i32();
497 tcg_gen_xor_i32(tmp
, t0
, t1
);
498 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
499 tcg_temp_free_i32(tmp
);
500 tcg_gen_mov_i32(dest
, cpu_NF
);
503 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
504 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
506 TCGv_i32 tmp
= tcg_temp_new_i32();
507 tcg_gen_not_i32(tmp
, t1
);
508 gen_adc_CC(dest
, t0
, tmp
);
509 tcg_temp_free_i32(tmp
);
512 #define GEN_SHIFT(name) \
513 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
515 TCGv_i32 tmp1, tmp2, tmp3; \
516 tmp1 = tcg_temp_new_i32(); \
517 tcg_gen_andi_i32(tmp1, t1, 0xff); \
518 tmp2 = tcg_const_i32(0); \
519 tmp3 = tcg_const_i32(0x1f); \
520 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
521 tcg_temp_free_i32(tmp3); \
522 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
523 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
524 tcg_temp_free_i32(tmp2); \
525 tcg_temp_free_i32(tmp1); \
531 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
534 tmp1
= tcg_temp_new_i32();
535 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
536 tmp2
= tcg_const_i32(0x1f);
537 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
538 tcg_temp_free_i32(tmp2
);
539 tcg_gen_sar_i32(dest
, t0
, tmp1
);
540 tcg_temp_free_i32(tmp1
);
543 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
545 TCGv_i32 c0
= tcg_const_i32(0);
546 TCGv_i32 tmp
= tcg_temp_new_i32();
547 tcg_gen_neg_i32(tmp
, src
);
548 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
549 tcg_temp_free_i32(c0
);
550 tcg_temp_free_i32(tmp
);
553 static void shifter_out_im(TCGv_i32 var
, int shift
)
556 tcg_gen_andi_i32(cpu_CF
, var
, 1);
558 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
560 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
565 /* Shift by immediate. Includes special handling for shift == 0. */
566 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
567 int shift
, int flags
)
573 shifter_out_im(var
, 32 - shift
);
574 tcg_gen_shli_i32(var
, var
, shift
);
580 tcg_gen_shri_i32(cpu_CF
, var
, 31);
582 tcg_gen_movi_i32(var
, 0);
585 shifter_out_im(var
, shift
- 1);
586 tcg_gen_shri_i32(var
, var
, shift
);
593 shifter_out_im(var
, shift
- 1);
596 tcg_gen_sari_i32(var
, var
, shift
);
598 case 3: /* ROR/RRX */
601 shifter_out_im(var
, shift
- 1);
602 tcg_gen_rotri_i32(var
, var
, shift
); break;
604 TCGv_i32 tmp
= tcg_temp_new_i32();
605 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
607 shifter_out_im(var
, 0);
608 tcg_gen_shri_i32(var
, var
, 1);
609 tcg_gen_or_i32(var
, var
, tmp
);
610 tcg_temp_free_i32(tmp
);
615 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
616 TCGv_i32 shift
, int flags
)
620 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
621 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
622 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
623 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
628 gen_shl(var
, var
, shift
);
631 gen_shr(var
, var
, shift
);
634 gen_sar(var
, var
, shift
);
636 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
637 tcg_gen_rotr_i32(var
, var
, shift
); break;
640 tcg_temp_free_i32(shift
);
643 #define PAS_OP(pfx) \
645 case 0: gen_pas_helper(glue(pfx,add16)); break; \
646 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
647 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
648 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
649 case 4: gen_pas_helper(glue(pfx,add8)); break; \
650 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
652 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
657 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
659 tmp
= tcg_temp_new_ptr();
660 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
662 tcg_temp_free_ptr(tmp
);
665 tmp
= tcg_temp_new_ptr();
666 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
668 tcg_temp_free_ptr(tmp
);
670 #undef gen_pas_helper
671 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
684 #undef gen_pas_helper
689 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
690 #define PAS_OP(pfx) \
692 case 0: gen_pas_helper(glue(pfx,add8)); break; \
693 case 1: gen_pas_helper(glue(pfx,add16)); break; \
694 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
695 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
696 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
697 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
699 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
704 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
706 tmp
= tcg_temp_new_ptr();
707 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
709 tcg_temp_free_ptr(tmp
);
712 tmp
= tcg_temp_new_ptr();
713 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
715 tcg_temp_free_ptr(tmp
);
717 #undef gen_pas_helper
718 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
731 #undef gen_pas_helper
737 * Generate a conditional based on ARM condition code cc.
738 * This is common between ARM and Aarch64 targets.
740 void arm_test_cc(DisasCompare
*cmp
, int cc
)
771 case 8: /* hi: C && !Z */
772 case 9: /* ls: !C || Z -> !(C && !Z) */
774 value
= tcg_temp_new_i32();
776 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
777 ZF is non-zero for !Z; so AND the two subexpressions. */
778 tcg_gen_neg_i32(value
, cpu_CF
);
779 tcg_gen_and_i32(value
, value
, cpu_ZF
);
782 case 10: /* ge: N == V -> N ^ V == 0 */
783 case 11: /* lt: N != V -> N ^ V != 0 */
784 /* Since we're only interested in the sign bit, == 0 is >= 0. */
786 value
= tcg_temp_new_i32();
788 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
791 case 12: /* gt: !Z && N == V */
792 case 13: /* le: Z || N != V */
794 value
= tcg_temp_new_i32();
796 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
797 * the sign bit then AND with ZF to yield the result. */
798 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
799 tcg_gen_sari_i32(value
, value
, 31);
800 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
803 case 14: /* always */
804 case 15: /* always */
805 /* Use the ALWAYS condition, which will fold early.
806 * It doesn't matter what we use for the value. */
807 cond
= TCG_COND_ALWAYS
;
812 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
817 cond
= tcg_invert_cond(cond
);
823 cmp
->value_global
= global
;
826 void arm_free_cc(DisasCompare
*cmp
)
828 if (!cmp
->value_global
) {
829 tcg_temp_free_i32(cmp
->value
);
833 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
835 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
838 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
841 arm_test_cc(&cmp
, cc
);
842 arm_jump_cc(&cmp
, label
);
846 static const uint8_t table_logic_cc
[16] = {
865 /* Set PC and Thumb state from an immediate address. */
866 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
870 s
->is_jmp
= DISAS_JUMP
;
871 if (s
->thumb
!= (addr
& 1)) {
872 tmp
= tcg_temp_new_i32();
873 tcg_gen_movi_i32(tmp
, addr
& 1);
874 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
875 tcg_temp_free_i32(tmp
);
877 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
880 /* Set PC and Thumb state from var. var is marked as dead. */
881 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
883 s
->is_jmp
= DISAS_JUMP
;
884 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
885 tcg_gen_andi_i32(var
, var
, 1);
886 store_cpu_field(var
, thumb
);
889 /* Variant of store_reg which uses branch&exchange logic when storing
890 to r15 in ARM architecture v7 and above. The source must be a temporary
891 and will be marked as dead. */
892 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
894 if (reg
== 15 && ENABLE_ARCH_7
) {
897 store_reg(s
, reg
, var
);
901 /* Variant of store_reg which uses branch&exchange logic when storing
902 * to r15 in ARM architecture v5T and above. This is used for storing
903 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
904 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
905 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
907 if (reg
== 15 && ENABLE_ARCH_5
) {
910 store_reg(s
, reg
, var
);
914 /* Abstractions of "generate code to do a guest load/store for
915 * AArch32", where a vaddr is always 32 bits (and is zero
916 * extended if we're a 64 bit core) and data is also
917 * 32 bits unless specifically doing a 64 bit access.
918 * These functions work like tcg_gen_qemu_{ld,st}* except
919 * that the address argument is TCGv_i32 rather than TCGv.
921 #if TARGET_LONG_BITS == 32
923 #define DO_GEN_LD(SUFF, OPC) \
924 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
926 tcg_gen_qemu_ld_i32(val, addr, index, (OPC)); \
929 #define DO_GEN_ST(SUFF, OPC) \
930 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
932 tcg_gen_qemu_st_i32(val, addr, index, (OPC)); \
935 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
937 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
940 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
942 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
947 #define DO_GEN_LD(SUFF, OPC) \
948 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
950 TCGv addr64 = tcg_temp_new(); \
951 tcg_gen_extu_i32_i64(addr64, addr); \
952 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
953 tcg_temp_free(addr64); \
956 #define DO_GEN_ST(SUFF, OPC) \
957 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
959 TCGv addr64 = tcg_temp_new(); \
960 tcg_gen_extu_i32_i64(addr64, addr); \
961 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
962 tcg_temp_free(addr64); \
965 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
967 TCGv addr64
= tcg_temp_new();
968 tcg_gen_extu_i32_i64(addr64
, addr
);
969 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
970 tcg_temp_free(addr64
);
973 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
975 TCGv addr64
= tcg_temp_new();
976 tcg_gen_extu_i32_i64(addr64
, addr
);
977 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
978 tcg_temp_free(addr64
);
985 DO_GEN_LD(16s
, MO_TESW
)
986 DO_GEN_LD(16u, MO_TEUW
)
987 DO_GEN_LD(32u, MO_TEUL
)
988 /* 'a' variants include an alignment check */
989 DO_GEN_LD(16ua
, MO_TEUW
| MO_ALIGN
)
990 DO_GEN_LD(32ua
, MO_TEUL
| MO_ALIGN
)
992 DO_GEN_ST(16, MO_TEUW
)
993 DO_GEN_ST(32, MO_TEUL
)
995 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
997 tcg_gen_movi_i32(cpu_R
[15], val
);
1000 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1002 /* The pre HVC helper handles cases when HVC gets trapped
1003 * as an undefined insn by runtime configuration (ie before
1004 * the insn really executes).
1006 gen_set_pc_im(s
, s
->pc
- 4);
1007 gen_helper_pre_hvc(cpu_env
);
1008 /* Otherwise we will treat this as a real exception which
1009 * happens after execution of the insn. (The distinction matters
1010 * for the PC value reported to the exception handler and also
1011 * for single stepping.)
1014 gen_set_pc_im(s
, s
->pc
);
1015 s
->is_jmp
= DISAS_HVC
;
1018 static inline void gen_smc(DisasContext
*s
)
1020 /* As with HVC, we may take an exception either before or after
1021 * the insn executes.
1025 gen_set_pc_im(s
, s
->pc
- 4);
1026 tmp
= tcg_const_i32(syn_aa32_smc());
1027 gen_helper_pre_smc(cpu_env
, tmp
);
1028 tcg_temp_free_i32(tmp
);
1029 gen_set_pc_im(s
, s
->pc
);
1030 s
->is_jmp
= DISAS_SMC
;
1034 gen_set_condexec (DisasContext
*s
)
1036 if (s
->condexec_mask
) {
1037 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1038 TCGv_i32 tmp
= tcg_temp_new_i32();
1039 tcg_gen_movi_i32(tmp
, val
);
1040 store_cpu_field(tmp
, condexec_bits
);
1044 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1046 gen_set_condexec(s
);
1047 gen_set_pc_im(s
, s
->pc
- offset
);
1048 gen_exception_internal(excp
);
1049 s
->is_jmp
= DISAS_JUMP
;
1052 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1053 int syn
, uint32_t target_el
)
1055 gen_set_condexec(s
);
1056 gen_set_pc_im(s
, s
->pc
- offset
);
1057 gen_exception(excp
, syn
, target_el
);
1058 s
->is_jmp
= DISAS_JUMP
;
1061 /* Force a TB lookup after an instruction that changes the CPU state. */
1062 static inline void gen_lookup_tb(DisasContext
*s
)
1064 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1065 s
->is_jmp
= DISAS_JUMP
;
1068 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1071 int val
, rm
, shift
, shiftop
;
1074 if (!(insn
& (1 << 25))) {
1077 if (!(insn
& (1 << 23)))
1080 tcg_gen_addi_i32(var
, var
, val
);
1082 /* shift/register */
1084 shift
= (insn
>> 7) & 0x1f;
1085 shiftop
= (insn
>> 5) & 3;
1086 offset
= load_reg(s
, rm
);
1087 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1088 if (!(insn
& (1 << 23)))
1089 tcg_gen_sub_i32(var
, var
, offset
);
1091 tcg_gen_add_i32(var
, var
, offset
);
1092 tcg_temp_free_i32(offset
);
1096 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1097 int extra
, TCGv_i32 var
)
1102 if (insn
& (1 << 22)) {
1104 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1105 if (!(insn
& (1 << 23)))
1109 tcg_gen_addi_i32(var
, var
, val
);
1113 tcg_gen_addi_i32(var
, var
, extra
);
1115 offset
= load_reg(s
, rm
);
1116 if (!(insn
& (1 << 23)))
1117 tcg_gen_sub_i32(var
, var
, offset
);
1119 tcg_gen_add_i32(var
, var
, offset
);
1120 tcg_temp_free_i32(offset
);
1124 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1126 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1129 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1131 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1133 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1137 #define VFP_OP2(name) \
1138 static inline void gen_vfp_##name(int dp) \
1140 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1142 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1144 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1146 tcg_temp_free_ptr(fpst); \
1156 static inline void gen_vfp_F1_mul(int dp
)
1158 /* Like gen_vfp_mul() but put result in F1 */
1159 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1161 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1163 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1165 tcg_temp_free_ptr(fpst
);
1168 static inline void gen_vfp_F1_neg(int dp
)
1170 /* Like gen_vfp_neg() but put result in F1 */
1172 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1174 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1178 static inline void gen_vfp_abs(int dp
)
1181 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1183 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1186 static inline void gen_vfp_neg(int dp
)
1189 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1191 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1194 static inline void gen_vfp_sqrt(int dp
)
1197 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1199 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1202 static inline void gen_vfp_cmp(int dp
)
1205 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1207 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1210 static inline void gen_vfp_cmpe(int dp
)
1213 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1215 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1218 static inline void gen_vfp_F1_ld0(int dp
)
1221 tcg_gen_movi_i64(cpu_F1d
, 0);
1223 tcg_gen_movi_i32(cpu_F1s
, 0);
1226 #define VFP_GEN_ITOF(name) \
1227 static inline void gen_vfp_##name(int dp, int neon) \
1229 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1231 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1233 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1235 tcg_temp_free_ptr(statusptr); \
1242 #define VFP_GEN_FTOI(name) \
1243 static inline void gen_vfp_##name(int dp, int neon) \
1245 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1247 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1249 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1251 tcg_temp_free_ptr(statusptr); \
1260 #define VFP_GEN_FIX(name, round) \
1261 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1263 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1264 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1266 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1269 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1272 tcg_temp_free_i32(tmp_shift); \
1273 tcg_temp_free_ptr(statusptr); \
1275 VFP_GEN_FIX(tosh
, _round_to_zero
)
1276 VFP_GEN_FIX(tosl
, _round_to_zero
)
1277 VFP_GEN_FIX(touh
, _round_to_zero
)
1278 VFP_GEN_FIX(toul
, _round_to_zero
)
1285 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1288 gen_aa32_ld64(cpu_F0d
, addr
, get_mem_index(s
));
1290 gen_aa32_ld32u(cpu_F0s
, addr
, get_mem_index(s
));
1294 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1297 gen_aa32_st64(cpu_F0d
, addr
, get_mem_index(s
));
1299 gen_aa32_st32(cpu_F0s
, addr
, get_mem_index(s
));
1304 vfp_reg_offset (int dp
, int reg
)
1307 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1309 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1310 + offsetof(CPU_DoubleU
, l
.upper
);
1312 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1313 + offsetof(CPU_DoubleU
, l
.lower
);
1317 /* Return the offset of a 32-bit piece of a NEON register.
1318 zero is the least significant end of the register. */
1320 neon_reg_offset (int reg
, int n
)
1324 return vfp_reg_offset(0, sreg
);
1327 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1329 TCGv_i32 tmp
= tcg_temp_new_i32();
1330 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1334 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1336 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1337 tcg_temp_free_i32(var
);
1340 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1342 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1345 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1347 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1350 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1351 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1352 #define tcg_gen_st_f32 tcg_gen_st_i32
1353 #define tcg_gen_st_f64 tcg_gen_st_i64
1355 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1358 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1360 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1363 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1366 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1368 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1371 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1374 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1376 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1379 #define ARM_CP_RW_BIT (1 << 20)
1381 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1383 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1386 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1388 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1391 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1393 TCGv_i32 var
= tcg_temp_new_i32();
1394 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1398 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1400 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1401 tcg_temp_free_i32(var
);
1404 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1406 iwmmxt_store_reg(cpu_M0
, rn
);
1409 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1411 iwmmxt_load_reg(cpu_M0
, rn
);
1414 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1416 iwmmxt_load_reg(cpu_V1
, rn
);
1417 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1420 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1422 iwmmxt_load_reg(cpu_V1
, rn
);
1423 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1426 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1428 iwmmxt_load_reg(cpu_V1
, rn
);
1429 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1432 #define IWMMXT_OP(name) \
1433 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1435 iwmmxt_load_reg(cpu_V1, rn); \
1436 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1439 #define IWMMXT_OP_ENV(name) \
1440 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1442 iwmmxt_load_reg(cpu_V1, rn); \
1443 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1446 #define IWMMXT_OP_ENV_SIZE(name) \
1447 IWMMXT_OP_ENV(name##b) \
1448 IWMMXT_OP_ENV(name##w) \
1449 IWMMXT_OP_ENV(name##l)
1451 #define IWMMXT_OP_ENV1(name) \
1452 static inline void gen_op_iwmmxt_##name##_M0(void) \
1454 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1468 IWMMXT_OP_ENV_SIZE(unpackl
)
1469 IWMMXT_OP_ENV_SIZE(unpackh
)
1471 IWMMXT_OP_ENV1(unpacklub
)
1472 IWMMXT_OP_ENV1(unpackluw
)
1473 IWMMXT_OP_ENV1(unpacklul
)
1474 IWMMXT_OP_ENV1(unpackhub
)
1475 IWMMXT_OP_ENV1(unpackhuw
)
1476 IWMMXT_OP_ENV1(unpackhul
)
1477 IWMMXT_OP_ENV1(unpacklsb
)
1478 IWMMXT_OP_ENV1(unpacklsw
)
1479 IWMMXT_OP_ENV1(unpacklsl
)
1480 IWMMXT_OP_ENV1(unpackhsb
)
1481 IWMMXT_OP_ENV1(unpackhsw
)
1482 IWMMXT_OP_ENV1(unpackhsl
)
1484 IWMMXT_OP_ENV_SIZE(cmpeq
)
1485 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1486 IWMMXT_OP_ENV_SIZE(cmpgts
)
1488 IWMMXT_OP_ENV_SIZE(mins
)
1489 IWMMXT_OP_ENV_SIZE(minu
)
1490 IWMMXT_OP_ENV_SIZE(maxs
)
1491 IWMMXT_OP_ENV_SIZE(maxu
)
1493 IWMMXT_OP_ENV_SIZE(subn
)
1494 IWMMXT_OP_ENV_SIZE(addn
)
1495 IWMMXT_OP_ENV_SIZE(subu
)
1496 IWMMXT_OP_ENV_SIZE(addu
)
1497 IWMMXT_OP_ENV_SIZE(subs
)
1498 IWMMXT_OP_ENV_SIZE(adds
)
1500 IWMMXT_OP_ENV(avgb0
)
1501 IWMMXT_OP_ENV(avgb1
)
1502 IWMMXT_OP_ENV(avgw0
)
1503 IWMMXT_OP_ENV(avgw1
)
1505 IWMMXT_OP_ENV(packuw
)
1506 IWMMXT_OP_ENV(packul
)
1507 IWMMXT_OP_ENV(packuq
)
1508 IWMMXT_OP_ENV(packsw
)
1509 IWMMXT_OP_ENV(packsl
)
1510 IWMMXT_OP_ENV(packsq
)
1512 static void gen_op_iwmmxt_set_mup(void)
1515 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1516 tcg_gen_ori_i32(tmp
, tmp
, 2);
1517 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1520 static void gen_op_iwmmxt_set_cup(void)
1523 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1524 tcg_gen_ori_i32(tmp
, tmp
, 1);
1525 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1528 static void gen_op_iwmmxt_setpsr_nz(void)
1530 TCGv_i32 tmp
= tcg_temp_new_i32();
1531 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1532 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1535 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1537 iwmmxt_load_reg(cpu_V1
, rn
);
1538 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1539 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1542 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1549 rd
= (insn
>> 16) & 0xf;
1550 tmp
= load_reg(s
, rd
);
1552 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1553 if (insn
& (1 << 24)) {
1555 if (insn
& (1 << 23))
1556 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1558 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1559 tcg_gen_mov_i32(dest
, tmp
);
1560 if (insn
& (1 << 21))
1561 store_reg(s
, rd
, tmp
);
1563 tcg_temp_free_i32(tmp
);
1564 } else if (insn
& (1 << 21)) {
1566 tcg_gen_mov_i32(dest
, tmp
);
1567 if (insn
& (1 << 23))
1568 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1570 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1571 store_reg(s
, rd
, tmp
);
1572 } else if (!(insn
& (1 << 23)))
1577 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1579 int rd
= (insn
>> 0) & 0xf;
1582 if (insn
& (1 << 8)) {
1583 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1586 tmp
= iwmmxt_load_creg(rd
);
1589 tmp
= tcg_temp_new_i32();
1590 iwmmxt_load_reg(cpu_V0
, rd
);
1591 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1593 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1594 tcg_gen_mov_i32(dest
, tmp
);
1595 tcg_temp_free_i32(tmp
);
1599 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1600 (ie. an undefined instruction). */
1601 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1604 int rdhi
, rdlo
, rd0
, rd1
, i
;
1606 TCGv_i32 tmp
, tmp2
, tmp3
;
1608 if ((insn
& 0x0e000e00) == 0x0c000000) {
1609 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1611 rdlo
= (insn
>> 12) & 0xf;
1612 rdhi
= (insn
>> 16) & 0xf;
1613 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1614 iwmmxt_load_reg(cpu_V0
, wrd
);
1615 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1616 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1617 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1618 } else { /* TMCRR */
1619 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1620 iwmmxt_store_reg(cpu_V0
, wrd
);
1621 gen_op_iwmmxt_set_mup();
1626 wrd
= (insn
>> 12) & 0xf;
1627 addr
= tcg_temp_new_i32();
1628 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1629 tcg_temp_free_i32(addr
);
1632 if (insn
& ARM_CP_RW_BIT
) {
1633 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1634 tmp
= tcg_temp_new_i32();
1635 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1636 iwmmxt_store_creg(wrd
, tmp
);
1639 if (insn
& (1 << 8)) {
1640 if (insn
& (1 << 22)) { /* WLDRD */
1641 gen_aa32_ld64(cpu_M0
, addr
, get_mem_index(s
));
1643 } else { /* WLDRW wRd */
1644 tmp
= tcg_temp_new_i32();
1645 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1648 tmp
= tcg_temp_new_i32();
1649 if (insn
& (1 << 22)) { /* WLDRH */
1650 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
1651 } else { /* WLDRB */
1652 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
1656 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1657 tcg_temp_free_i32(tmp
);
1659 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1662 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1663 tmp
= iwmmxt_load_creg(wrd
);
1664 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1666 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1667 tmp
= tcg_temp_new_i32();
1668 if (insn
& (1 << 8)) {
1669 if (insn
& (1 << 22)) { /* WSTRD */
1670 gen_aa32_st64(cpu_M0
, addr
, get_mem_index(s
));
1671 } else { /* WSTRW wRd */
1672 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1673 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1676 if (insn
& (1 << 22)) { /* WSTRH */
1677 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1678 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
1679 } else { /* WSTRB */
1680 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1681 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
1685 tcg_temp_free_i32(tmp
);
1687 tcg_temp_free_i32(addr
);
1691 if ((insn
& 0x0f000000) != 0x0e000000)
1694 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1695 case 0x000: /* WOR */
1696 wrd
= (insn
>> 12) & 0xf;
1697 rd0
= (insn
>> 0) & 0xf;
1698 rd1
= (insn
>> 16) & 0xf;
1699 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1700 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1701 gen_op_iwmmxt_setpsr_nz();
1702 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1703 gen_op_iwmmxt_set_mup();
1704 gen_op_iwmmxt_set_cup();
1706 case 0x011: /* TMCR */
1709 rd
= (insn
>> 12) & 0xf;
1710 wrd
= (insn
>> 16) & 0xf;
1712 case ARM_IWMMXT_wCID
:
1713 case ARM_IWMMXT_wCASF
:
1715 case ARM_IWMMXT_wCon
:
1716 gen_op_iwmmxt_set_cup();
1718 case ARM_IWMMXT_wCSSF
:
1719 tmp
= iwmmxt_load_creg(wrd
);
1720 tmp2
= load_reg(s
, rd
);
1721 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1722 tcg_temp_free_i32(tmp2
);
1723 iwmmxt_store_creg(wrd
, tmp
);
1725 case ARM_IWMMXT_wCGR0
:
1726 case ARM_IWMMXT_wCGR1
:
1727 case ARM_IWMMXT_wCGR2
:
1728 case ARM_IWMMXT_wCGR3
:
1729 gen_op_iwmmxt_set_cup();
1730 tmp
= load_reg(s
, rd
);
1731 iwmmxt_store_creg(wrd
, tmp
);
1737 case 0x100: /* WXOR */
1738 wrd
= (insn
>> 12) & 0xf;
1739 rd0
= (insn
>> 0) & 0xf;
1740 rd1
= (insn
>> 16) & 0xf;
1741 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1742 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1743 gen_op_iwmmxt_setpsr_nz();
1744 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1745 gen_op_iwmmxt_set_mup();
1746 gen_op_iwmmxt_set_cup();
1748 case 0x111: /* TMRC */
1751 rd
= (insn
>> 12) & 0xf;
1752 wrd
= (insn
>> 16) & 0xf;
1753 tmp
= iwmmxt_load_creg(wrd
);
1754 store_reg(s
, rd
, tmp
);
1756 case 0x300: /* WANDN */
1757 wrd
= (insn
>> 12) & 0xf;
1758 rd0
= (insn
>> 0) & 0xf;
1759 rd1
= (insn
>> 16) & 0xf;
1760 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1761 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1762 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1763 gen_op_iwmmxt_setpsr_nz();
1764 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1765 gen_op_iwmmxt_set_mup();
1766 gen_op_iwmmxt_set_cup();
1768 case 0x200: /* WAND */
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_andq_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 0x810: case 0xa10: /* WMADD */
1780 wrd
= (insn
>> 12) & 0xf;
1781 rd0
= (insn
>> 0) & 0xf;
1782 rd1
= (insn
>> 16) & 0xf;
1783 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1784 if (insn
& (1 << 21))
1785 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1787 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1788 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1789 gen_op_iwmmxt_set_mup();
1791 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1792 wrd
= (insn
>> 12) & 0xf;
1793 rd0
= (insn
>> 16) & 0xf;
1794 rd1
= (insn
>> 0) & 0xf;
1795 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1796 switch ((insn
>> 22) & 3) {
1798 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1801 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1804 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1809 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1810 gen_op_iwmmxt_set_mup();
1811 gen_op_iwmmxt_set_cup();
1813 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1814 wrd
= (insn
>> 12) & 0xf;
1815 rd0
= (insn
>> 16) & 0xf;
1816 rd1
= (insn
>> 0) & 0xf;
1817 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1818 switch ((insn
>> 22) & 3) {
1820 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1823 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1826 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1831 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1832 gen_op_iwmmxt_set_mup();
1833 gen_op_iwmmxt_set_cup();
1835 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1836 wrd
= (insn
>> 12) & 0xf;
1837 rd0
= (insn
>> 16) & 0xf;
1838 rd1
= (insn
>> 0) & 0xf;
1839 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1840 if (insn
& (1 << 22))
1841 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1843 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1844 if (!(insn
& (1 << 20)))
1845 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1846 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1847 gen_op_iwmmxt_set_mup();
1849 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1850 wrd
= (insn
>> 12) & 0xf;
1851 rd0
= (insn
>> 16) & 0xf;
1852 rd1
= (insn
>> 0) & 0xf;
1853 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1854 if (insn
& (1 << 21)) {
1855 if (insn
& (1 << 20))
1856 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1858 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1860 if (insn
& (1 << 20))
1861 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1863 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1865 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1866 gen_op_iwmmxt_set_mup();
1868 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1869 wrd
= (insn
>> 12) & 0xf;
1870 rd0
= (insn
>> 16) & 0xf;
1871 rd1
= (insn
>> 0) & 0xf;
1872 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1873 if (insn
& (1 << 21))
1874 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1876 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1877 if (!(insn
& (1 << 20))) {
1878 iwmmxt_load_reg(cpu_V1
, wrd
);
1879 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1881 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1882 gen_op_iwmmxt_set_mup();
1884 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1885 wrd
= (insn
>> 12) & 0xf;
1886 rd0
= (insn
>> 16) & 0xf;
1887 rd1
= (insn
>> 0) & 0xf;
1888 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1889 switch ((insn
>> 22) & 3) {
1891 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1894 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1897 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1902 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1903 gen_op_iwmmxt_set_mup();
1904 gen_op_iwmmxt_set_cup();
1906 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1907 wrd
= (insn
>> 12) & 0xf;
1908 rd0
= (insn
>> 16) & 0xf;
1909 rd1
= (insn
>> 0) & 0xf;
1910 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1911 if (insn
& (1 << 22)) {
1912 if (insn
& (1 << 20))
1913 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1915 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1917 if (insn
& (1 << 20))
1918 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1920 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1922 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1923 gen_op_iwmmxt_set_mup();
1924 gen_op_iwmmxt_set_cup();
1926 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1927 wrd
= (insn
>> 12) & 0xf;
1928 rd0
= (insn
>> 16) & 0xf;
1929 rd1
= (insn
>> 0) & 0xf;
1930 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1931 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1932 tcg_gen_andi_i32(tmp
, tmp
, 7);
1933 iwmmxt_load_reg(cpu_V1
, rd1
);
1934 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1935 tcg_temp_free_i32(tmp
);
1936 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1937 gen_op_iwmmxt_set_mup();
1939 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1940 if (((insn
>> 6) & 3) == 3)
1942 rd
= (insn
>> 12) & 0xf;
1943 wrd
= (insn
>> 16) & 0xf;
1944 tmp
= load_reg(s
, rd
);
1945 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1946 switch ((insn
>> 6) & 3) {
1948 tmp2
= tcg_const_i32(0xff);
1949 tmp3
= tcg_const_i32((insn
& 7) << 3);
1952 tmp2
= tcg_const_i32(0xffff);
1953 tmp3
= tcg_const_i32((insn
& 3) << 4);
1956 tmp2
= tcg_const_i32(0xffffffff);
1957 tmp3
= tcg_const_i32((insn
& 1) << 5);
1960 TCGV_UNUSED_I32(tmp2
);
1961 TCGV_UNUSED_I32(tmp3
);
1963 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1964 tcg_temp_free_i32(tmp3
);
1965 tcg_temp_free_i32(tmp2
);
1966 tcg_temp_free_i32(tmp
);
1967 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1968 gen_op_iwmmxt_set_mup();
1970 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1971 rd
= (insn
>> 12) & 0xf;
1972 wrd
= (insn
>> 16) & 0xf;
1973 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1975 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1976 tmp
= tcg_temp_new_i32();
1977 switch ((insn
>> 22) & 3) {
1979 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1980 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1982 tcg_gen_ext8s_i32(tmp
, tmp
);
1984 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1988 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1989 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1991 tcg_gen_ext16s_i32(tmp
, tmp
);
1993 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1997 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1998 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2001 store_reg(s
, rd
, tmp
);
2003 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2004 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2006 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2007 switch ((insn
>> 22) & 3) {
2009 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2012 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2015 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2018 tcg_gen_shli_i32(tmp
, tmp
, 28);
2020 tcg_temp_free_i32(tmp
);
2022 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2023 if (((insn
>> 6) & 3) == 3)
2025 rd
= (insn
>> 12) & 0xf;
2026 wrd
= (insn
>> 16) & 0xf;
2027 tmp
= load_reg(s
, rd
);
2028 switch ((insn
>> 6) & 3) {
2030 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2033 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2036 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2039 tcg_temp_free_i32(tmp
);
2040 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2041 gen_op_iwmmxt_set_mup();
2043 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2044 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2046 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2047 tmp2
= tcg_temp_new_i32();
2048 tcg_gen_mov_i32(tmp2
, tmp
);
2049 switch ((insn
>> 22) & 3) {
2051 for (i
= 0; i
< 7; i
++) {
2052 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2053 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2057 for (i
= 0; i
< 3; i
++) {
2058 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2059 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2063 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2064 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2068 tcg_temp_free_i32(tmp2
);
2069 tcg_temp_free_i32(tmp
);
2071 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2072 wrd
= (insn
>> 12) & 0xf;
2073 rd0
= (insn
>> 16) & 0xf;
2074 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2075 switch ((insn
>> 22) & 3) {
2077 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2080 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2083 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2088 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2089 gen_op_iwmmxt_set_mup();
2091 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2092 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2094 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2095 tmp2
= tcg_temp_new_i32();
2096 tcg_gen_mov_i32(tmp2
, tmp
);
2097 switch ((insn
>> 22) & 3) {
2099 for (i
= 0; i
< 7; i
++) {
2100 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2101 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2105 for (i
= 0; i
< 3; i
++) {
2106 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2107 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2111 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2112 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2116 tcg_temp_free_i32(tmp2
);
2117 tcg_temp_free_i32(tmp
);
2119 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2120 rd
= (insn
>> 12) & 0xf;
2121 rd0
= (insn
>> 16) & 0xf;
2122 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2124 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2125 tmp
= tcg_temp_new_i32();
2126 switch ((insn
>> 22) & 3) {
2128 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2131 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2134 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2137 store_reg(s
, rd
, tmp
);
2139 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2140 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2141 wrd
= (insn
>> 12) & 0xf;
2142 rd0
= (insn
>> 16) & 0xf;
2143 rd1
= (insn
>> 0) & 0xf;
2144 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2145 switch ((insn
>> 22) & 3) {
2147 if (insn
& (1 << 21))
2148 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2150 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2153 if (insn
& (1 << 21))
2154 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2156 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2159 if (insn
& (1 << 21))
2160 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2162 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2167 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2168 gen_op_iwmmxt_set_mup();
2169 gen_op_iwmmxt_set_cup();
2171 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2172 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2173 wrd
= (insn
>> 12) & 0xf;
2174 rd0
= (insn
>> 16) & 0xf;
2175 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2176 switch ((insn
>> 22) & 3) {
2178 if (insn
& (1 << 21))
2179 gen_op_iwmmxt_unpacklsb_M0();
2181 gen_op_iwmmxt_unpacklub_M0();
2184 if (insn
& (1 << 21))
2185 gen_op_iwmmxt_unpacklsw_M0();
2187 gen_op_iwmmxt_unpackluw_M0();
2190 if (insn
& (1 << 21))
2191 gen_op_iwmmxt_unpacklsl_M0();
2193 gen_op_iwmmxt_unpacklul_M0();
2198 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2199 gen_op_iwmmxt_set_mup();
2200 gen_op_iwmmxt_set_cup();
2202 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2203 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2204 wrd
= (insn
>> 12) & 0xf;
2205 rd0
= (insn
>> 16) & 0xf;
2206 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2207 switch ((insn
>> 22) & 3) {
2209 if (insn
& (1 << 21))
2210 gen_op_iwmmxt_unpackhsb_M0();
2212 gen_op_iwmmxt_unpackhub_M0();
2215 if (insn
& (1 << 21))
2216 gen_op_iwmmxt_unpackhsw_M0();
2218 gen_op_iwmmxt_unpackhuw_M0();
2221 if (insn
& (1 << 21))
2222 gen_op_iwmmxt_unpackhsl_M0();
2224 gen_op_iwmmxt_unpackhul_M0();
2229 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2230 gen_op_iwmmxt_set_mup();
2231 gen_op_iwmmxt_set_cup();
2233 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2234 case 0x214: case 0x614: case 0xa14: case 0xe14:
2235 if (((insn
>> 22) & 3) == 0)
2237 wrd
= (insn
>> 12) & 0xf;
2238 rd0
= (insn
>> 16) & 0xf;
2239 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2240 tmp
= tcg_temp_new_i32();
2241 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2242 tcg_temp_free_i32(tmp
);
2245 switch ((insn
>> 22) & 3) {
2247 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2250 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2253 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2256 tcg_temp_free_i32(tmp
);
2257 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2258 gen_op_iwmmxt_set_mup();
2259 gen_op_iwmmxt_set_cup();
2261 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2262 case 0x014: case 0x414: case 0x814: case 0xc14:
2263 if (((insn
>> 22) & 3) == 0)
2265 wrd
= (insn
>> 12) & 0xf;
2266 rd0
= (insn
>> 16) & 0xf;
2267 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2268 tmp
= tcg_temp_new_i32();
2269 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2270 tcg_temp_free_i32(tmp
);
2273 switch ((insn
>> 22) & 3) {
2275 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2278 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2281 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2284 tcg_temp_free_i32(tmp
);
2285 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2286 gen_op_iwmmxt_set_mup();
2287 gen_op_iwmmxt_set_cup();
2289 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2290 case 0x114: case 0x514: case 0x914: case 0xd14:
2291 if (((insn
>> 22) & 3) == 0)
2293 wrd
= (insn
>> 12) & 0xf;
2294 rd0
= (insn
>> 16) & 0xf;
2295 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2296 tmp
= tcg_temp_new_i32();
2297 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2298 tcg_temp_free_i32(tmp
);
2301 switch ((insn
>> 22) & 3) {
2303 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2306 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2309 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2312 tcg_temp_free_i32(tmp
);
2313 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2314 gen_op_iwmmxt_set_mup();
2315 gen_op_iwmmxt_set_cup();
2317 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2318 case 0x314: case 0x714: case 0xb14: case 0xf14:
2319 if (((insn
>> 22) & 3) == 0)
2321 wrd
= (insn
>> 12) & 0xf;
2322 rd0
= (insn
>> 16) & 0xf;
2323 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2324 tmp
= tcg_temp_new_i32();
2325 switch ((insn
>> 22) & 3) {
2327 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2328 tcg_temp_free_i32(tmp
);
2331 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2334 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2335 tcg_temp_free_i32(tmp
);
2338 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2341 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2342 tcg_temp_free_i32(tmp
);
2345 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2348 tcg_temp_free_i32(tmp
);
2349 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2350 gen_op_iwmmxt_set_mup();
2351 gen_op_iwmmxt_set_cup();
2353 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2354 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2355 wrd
= (insn
>> 12) & 0xf;
2356 rd0
= (insn
>> 16) & 0xf;
2357 rd1
= (insn
>> 0) & 0xf;
2358 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2359 switch ((insn
>> 22) & 3) {
2361 if (insn
& (1 << 21))
2362 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2364 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2367 if (insn
& (1 << 21))
2368 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2370 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2373 if (insn
& (1 << 21))
2374 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2376 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2381 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2382 gen_op_iwmmxt_set_mup();
2384 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2385 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2386 wrd
= (insn
>> 12) & 0xf;
2387 rd0
= (insn
>> 16) & 0xf;
2388 rd1
= (insn
>> 0) & 0xf;
2389 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2390 switch ((insn
>> 22) & 3) {
2392 if (insn
& (1 << 21))
2393 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2395 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2398 if (insn
& (1 << 21))
2399 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2401 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2404 if (insn
& (1 << 21))
2405 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2407 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2412 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2413 gen_op_iwmmxt_set_mup();
2415 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2416 case 0x402: case 0x502: case 0x602: case 0x702:
2417 wrd
= (insn
>> 12) & 0xf;
2418 rd0
= (insn
>> 16) & 0xf;
2419 rd1
= (insn
>> 0) & 0xf;
2420 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2421 tmp
= tcg_const_i32((insn
>> 20) & 3);
2422 iwmmxt_load_reg(cpu_V1
, rd1
);
2423 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2424 tcg_temp_free_i32(tmp
);
2425 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2426 gen_op_iwmmxt_set_mup();
2428 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2429 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2430 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2431 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2432 wrd
= (insn
>> 12) & 0xf;
2433 rd0
= (insn
>> 16) & 0xf;
2434 rd1
= (insn
>> 0) & 0xf;
2435 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2436 switch ((insn
>> 20) & 0xf) {
2438 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2441 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2444 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2447 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2450 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2453 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2456 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2459 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2462 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2467 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2468 gen_op_iwmmxt_set_mup();
2469 gen_op_iwmmxt_set_cup();
2471 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2472 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2473 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2474 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2475 wrd
= (insn
>> 12) & 0xf;
2476 rd0
= (insn
>> 16) & 0xf;
2477 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2478 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2479 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2480 tcg_temp_free_i32(tmp
);
2481 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2482 gen_op_iwmmxt_set_mup();
2483 gen_op_iwmmxt_set_cup();
2485 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2486 case 0x418: case 0x518: case 0x618: case 0x718:
2487 case 0x818: case 0x918: case 0xa18: case 0xb18:
2488 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2489 wrd
= (insn
>> 12) & 0xf;
2490 rd0
= (insn
>> 16) & 0xf;
2491 rd1
= (insn
>> 0) & 0xf;
2492 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2493 switch ((insn
>> 20) & 0xf) {
2495 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2498 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2501 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2504 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2507 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2510 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2513 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2516 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2519 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2524 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2525 gen_op_iwmmxt_set_mup();
2526 gen_op_iwmmxt_set_cup();
2528 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2529 case 0x408: case 0x508: case 0x608: case 0x708:
2530 case 0x808: case 0x908: case 0xa08: case 0xb08:
2531 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2532 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2534 wrd
= (insn
>> 12) & 0xf;
2535 rd0
= (insn
>> 16) & 0xf;
2536 rd1
= (insn
>> 0) & 0xf;
2537 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2538 switch ((insn
>> 22) & 3) {
2540 if (insn
& (1 << 21))
2541 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2543 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2546 if (insn
& (1 << 21))
2547 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2549 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2552 if (insn
& (1 << 21))
2553 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2555 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2558 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2559 gen_op_iwmmxt_set_mup();
2560 gen_op_iwmmxt_set_cup();
2562 case 0x201: case 0x203: case 0x205: case 0x207:
2563 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2564 case 0x211: case 0x213: case 0x215: case 0x217:
2565 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2566 wrd
= (insn
>> 5) & 0xf;
2567 rd0
= (insn
>> 12) & 0xf;
2568 rd1
= (insn
>> 0) & 0xf;
2569 if (rd0
== 0xf || rd1
== 0xf)
2571 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2572 tmp
= load_reg(s
, rd0
);
2573 tmp2
= load_reg(s
, rd1
);
2574 switch ((insn
>> 16) & 0xf) {
2575 case 0x0: /* TMIA */
2576 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2578 case 0x8: /* TMIAPH */
2579 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2581 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2582 if (insn
& (1 << 16))
2583 tcg_gen_shri_i32(tmp
, tmp
, 16);
2584 if (insn
& (1 << 17))
2585 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2586 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2589 tcg_temp_free_i32(tmp2
);
2590 tcg_temp_free_i32(tmp
);
2593 tcg_temp_free_i32(tmp2
);
2594 tcg_temp_free_i32(tmp
);
2595 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2596 gen_op_iwmmxt_set_mup();
2605 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2606 (ie. an undefined instruction). */
2607 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2609 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2612 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2613 /* Multiply with Internal Accumulate Format */
2614 rd0
= (insn
>> 12) & 0xf;
2616 acc
= (insn
>> 5) & 7;
2621 tmp
= load_reg(s
, rd0
);
2622 tmp2
= load_reg(s
, rd1
);
2623 switch ((insn
>> 16) & 0xf) {
2625 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2627 case 0x8: /* MIAPH */
2628 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2630 case 0xc: /* MIABB */
2631 case 0xd: /* MIABT */
2632 case 0xe: /* MIATB */
2633 case 0xf: /* MIATT */
2634 if (insn
& (1 << 16))
2635 tcg_gen_shri_i32(tmp
, tmp
, 16);
2636 if (insn
& (1 << 17))
2637 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2638 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2643 tcg_temp_free_i32(tmp2
);
2644 tcg_temp_free_i32(tmp
);
2646 gen_op_iwmmxt_movq_wRn_M0(acc
);
2650 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2651 /* Internal Accumulator Access Format */
2652 rdhi
= (insn
>> 16) & 0xf;
2653 rdlo
= (insn
>> 12) & 0xf;
2659 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2660 iwmmxt_load_reg(cpu_V0
, acc
);
2661 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2662 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2663 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2664 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2666 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2667 iwmmxt_store_reg(cpu_V0
, acc
);
2675 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2676 #define VFP_SREG(insn, bigbit, smallbit) \
2677 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2678 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2679 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2680 reg = (((insn) >> (bigbit)) & 0x0f) \
2681 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2683 if (insn & (1 << (smallbit))) \
2685 reg = ((insn) >> (bigbit)) & 0x0f; \
2688 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2689 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2690 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2691 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2692 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2693 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2695 /* Move between integer and VFP cores. */
2696 static TCGv_i32
gen_vfp_mrs(void)
2698 TCGv_i32 tmp
= tcg_temp_new_i32();
2699 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2703 static void gen_vfp_msr(TCGv_i32 tmp
)
2705 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2706 tcg_temp_free_i32(tmp
);
2709 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2711 TCGv_i32 tmp
= tcg_temp_new_i32();
2713 tcg_gen_shri_i32(var
, var
, shift
);
2714 tcg_gen_ext8u_i32(var
, var
);
2715 tcg_gen_shli_i32(tmp
, var
, 8);
2716 tcg_gen_or_i32(var
, var
, tmp
);
2717 tcg_gen_shli_i32(tmp
, var
, 16);
2718 tcg_gen_or_i32(var
, var
, tmp
);
2719 tcg_temp_free_i32(tmp
);
2722 static void gen_neon_dup_low16(TCGv_i32 var
)
2724 TCGv_i32 tmp
= tcg_temp_new_i32();
2725 tcg_gen_ext16u_i32(var
, var
);
2726 tcg_gen_shli_i32(tmp
, var
, 16);
2727 tcg_gen_or_i32(var
, var
, tmp
);
2728 tcg_temp_free_i32(tmp
);
2731 static void gen_neon_dup_high16(TCGv_i32 var
)
2733 TCGv_i32 tmp
= tcg_temp_new_i32();
2734 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2735 tcg_gen_shri_i32(tmp
, var
, 16);
2736 tcg_gen_or_i32(var
, var
, tmp
);
2737 tcg_temp_free_i32(tmp
);
2740 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2742 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2743 TCGv_i32 tmp
= tcg_temp_new_i32();
2746 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
2747 gen_neon_dup_u8(tmp
, 0);
2750 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
2751 gen_neon_dup_low16(tmp
);
2754 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
2756 default: /* Avoid compiler warnings. */
2762 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2765 uint32_t cc
= extract32(insn
, 20, 2);
2768 TCGv_i64 frn
, frm
, dest
;
2769 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2771 zero
= tcg_const_i64(0);
2773 frn
= tcg_temp_new_i64();
2774 frm
= tcg_temp_new_i64();
2775 dest
= tcg_temp_new_i64();
2777 zf
= tcg_temp_new_i64();
2778 nf
= tcg_temp_new_i64();
2779 vf
= tcg_temp_new_i64();
2781 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2782 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2783 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2785 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2786 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2789 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2793 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2796 case 2: /* ge: N == V -> N ^ V == 0 */
2797 tmp
= tcg_temp_new_i64();
2798 tcg_gen_xor_i64(tmp
, vf
, nf
);
2799 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2801 tcg_temp_free_i64(tmp
);
2803 case 3: /* gt: !Z && N == V */
2804 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2806 tmp
= tcg_temp_new_i64();
2807 tcg_gen_xor_i64(tmp
, vf
, nf
);
2808 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2810 tcg_temp_free_i64(tmp
);
2813 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2814 tcg_temp_free_i64(frn
);
2815 tcg_temp_free_i64(frm
);
2816 tcg_temp_free_i64(dest
);
2818 tcg_temp_free_i64(zf
);
2819 tcg_temp_free_i64(nf
);
2820 tcg_temp_free_i64(vf
);
2822 tcg_temp_free_i64(zero
);
2824 TCGv_i32 frn
, frm
, dest
;
2827 zero
= tcg_const_i32(0);
2829 frn
= tcg_temp_new_i32();
2830 frm
= tcg_temp_new_i32();
2831 dest
= tcg_temp_new_i32();
2832 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2833 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2836 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2840 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2843 case 2: /* ge: N == V -> N ^ V == 0 */
2844 tmp
= tcg_temp_new_i32();
2845 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2846 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2848 tcg_temp_free_i32(tmp
);
2850 case 3: /* gt: !Z && N == V */
2851 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2853 tmp
= tcg_temp_new_i32();
2854 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2855 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2857 tcg_temp_free_i32(tmp
);
2860 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2861 tcg_temp_free_i32(frn
);
2862 tcg_temp_free_i32(frm
);
2863 tcg_temp_free_i32(dest
);
2865 tcg_temp_free_i32(zero
);
2871 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2872 uint32_t rm
, uint32_t dp
)
2874 uint32_t vmin
= extract32(insn
, 6, 1);
2875 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2878 TCGv_i64 frn
, frm
, dest
;
2880 frn
= tcg_temp_new_i64();
2881 frm
= tcg_temp_new_i64();
2882 dest
= tcg_temp_new_i64();
2884 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2885 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2887 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2889 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2891 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2892 tcg_temp_free_i64(frn
);
2893 tcg_temp_free_i64(frm
);
2894 tcg_temp_free_i64(dest
);
2896 TCGv_i32 frn
, frm
, dest
;
2898 frn
= tcg_temp_new_i32();
2899 frm
= tcg_temp_new_i32();
2900 dest
= tcg_temp_new_i32();
2902 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2903 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2905 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2907 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2909 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2910 tcg_temp_free_i32(frn
);
2911 tcg_temp_free_i32(frm
);
2912 tcg_temp_free_i32(dest
);
2915 tcg_temp_free_ptr(fpst
);
2919 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2922 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2925 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2926 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2931 tcg_op
= tcg_temp_new_i64();
2932 tcg_res
= tcg_temp_new_i64();
2933 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2934 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2935 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2936 tcg_temp_free_i64(tcg_op
);
2937 tcg_temp_free_i64(tcg_res
);
2941 tcg_op
= tcg_temp_new_i32();
2942 tcg_res
= tcg_temp_new_i32();
2943 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2944 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2945 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2946 tcg_temp_free_i32(tcg_op
);
2947 tcg_temp_free_i32(tcg_res
);
2950 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2951 tcg_temp_free_i32(tcg_rmode
);
2953 tcg_temp_free_ptr(fpst
);
2957 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2960 bool is_signed
= extract32(insn
, 7, 1);
2961 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2962 TCGv_i32 tcg_rmode
, tcg_shift
;
2964 tcg_shift
= tcg_const_i32(0);
2966 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2967 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2970 TCGv_i64 tcg_double
, tcg_res
;
2972 /* Rd is encoded as a single precision register even when the source
2973 * is double precision.
2975 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2976 tcg_double
= tcg_temp_new_i64();
2977 tcg_res
= tcg_temp_new_i64();
2978 tcg_tmp
= tcg_temp_new_i32();
2979 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2981 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2983 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2985 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
2986 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2987 tcg_temp_free_i32(tcg_tmp
);
2988 tcg_temp_free_i64(tcg_res
);
2989 tcg_temp_free_i64(tcg_double
);
2991 TCGv_i32 tcg_single
, tcg_res
;
2992 tcg_single
= tcg_temp_new_i32();
2993 tcg_res
= tcg_temp_new_i32();
2994 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2996 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2998 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3000 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3001 tcg_temp_free_i32(tcg_res
);
3002 tcg_temp_free_i32(tcg_single
);
3005 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3006 tcg_temp_free_i32(tcg_rmode
);
3008 tcg_temp_free_i32(tcg_shift
);
3010 tcg_temp_free_ptr(fpst
);
3015 /* Table for converting the most common AArch32 encoding of
3016 * rounding mode to arm_fprounding order (which matches the
3017 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3019 static const uint8_t fp_decode_rm
[] = {
3026 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3028 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3030 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3035 VFP_DREG_D(rd
, insn
);
3036 VFP_DREG_N(rn
, insn
);
3037 VFP_DREG_M(rm
, insn
);
3039 rd
= VFP_SREG_D(insn
);
3040 rn
= VFP_SREG_N(insn
);
3041 rm
= VFP_SREG_M(insn
);
3044 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3045 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3046 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3047 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3048 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3049 /* VRINTA, VRINTN, VRINTP, VRINTM */
3050 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3051 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3052 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3053 /* VCVTA, VCVTN, VCVTP, VCVTM */
3054 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3055 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3060 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3061 (ie. an undefined instruction). */
3062 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3064 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3070 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3074 /* FIXME: this access check should not take precedence over UNDEF
3075 * for invalid encodings; we will generate incorrect syndrome information
3076 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3078 if (s
->fp_excp_el
) {
3079 gen_exception_insn(s
, 4, EXCP_UDEF
,
3080 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
3084 if (!s
->vfp_enabled
) {
3085 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3086 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3088 rn
= (insn
>> 16) & 0xf;
3089 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3090 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3095 if (extract32(insn
, 28, 4) == 0xf) {
3096 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3097 * only used in v8 and above.
3099 return disas_vfp_v8_insn(s
, insn
);
3102 dp
= ((insn
& 0xf00) == 0xb00);
3103 switch ((insn
>> 24) & 0xf) {
3105 if (insn
& (1 << 4)) {
3106 /* single register transfer */
3107 rd
= (insn
>> 12) & 0xf;
3112 VFP_DREG_N(rn
, insn
);
3115 if (insn
& 0x00c00060
3116 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3120 pass
= (insn
>> 21) & 1;
3121 if (insn
& (1 << 22)) {
3123 offset
= ((insn
>> 5) & 3) * 8;
3124 } else if (insn
& (1 << 5)) {
3126 offset
= (insn
& (1 << 6)) ? 16 : 0;
3131 if (insn
& ARM_CP_RW_BIT
) {
3133 tmp
= neon_load_reg(rn
, pass
);
3137 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3138 if (insn
& (1 << 23))
3144 if (insn
& (1 << 23)) {
3146 tcg_gen_shri_i32(tmp
, tmp
, 16);
3152 tcg_gen_sari_i32(tmp
, tmp
, 16);
3161 store_reg(s
, rd
, tmp
);
3164 tmp
= load_reg(s
, rd
);
3165 if (insn
& (1 << 23)) {
3168 gen_neon_dup_u8(tmp
, 0);
3169 } else if (size
== 1) {
3170 gen_neon_dup_low16(tmp
);
3172 for (n
= 0; n
<= pass
* 2; n
++) {
3173 tmp2
= tcg_temp_new_i32();
3174 tcg_gen_mov_i32(tmp2
, tmp
);
3175 neon_store_reg(rn
, n
, tmp2
);
3177 neon_store_reg(rn
, n
, tmp
);
3182 tmp2
= neon_load_reg(rn
, pass
);
3183 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3184 tcg_temp_free_i32(tmp2
);
3187 tmp2
= neon_load_reg(rn
, pass
);
3188 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3189 tcg_temp_free_i32(tmp2
);
3194 neon_store_reg(rn
, pass
, tmp
);
3198 if ((insn
& 0x6f) != 0x00)
3200 rn
= VFP_SREG_N(insn
);
3201 if (insn
& ARM_CP_RW_BIT
) {
3203 if (insn
& (1 << 21)) {
3204 /* system register */
3209 /* VFP2 allows access to FSID from userspace.
3210 VFP3 restricts all id registers to privileged
3213 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3216 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3221 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3223 case ARM_VFP_FPINST
:
3224 case ARM_VFP_FPINST2
:
3225 /* Not present in VFP3. */
3227 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3230 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3234 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3235 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3237 tmp
= tcg_temp_new_i32();
3238 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3242 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3249 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3252 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3258 gen_mov_F0_vreg(0, rn
);
3259 tmp
= gen_vfp_mrs();
3262 /* Set the 4 flag bits in the CPSR. */
3264 tcg_temp_free_i32(tmp
);
3266 store_reg(s
, rd
, tmp
);
3270 if (insn
& (1 << 21)) {
3272 /* system register */
3277 /* Writes are ignored. */
3280 tmp
= load_reg(s
, rd
);
3281 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3282 tcg_temp_free_i32(tmp
);
3288 /* TODO: VFP subarchitecture support.
3289 * For now, keep the EN bit only */
3290 tmp
= load_reg(s
, rd
);
3291 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3292 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3295 case ARM_VFP_FPINST
:
3296 case ARM_VFP_FPINST2
:
3300 tmp
= load_reg(s
, rd
);
3301 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3307 tmp
= load_reg(s
, rd
);
3309 gen_mov_vreg_F0(0, rn
);
3314 /* data processing */
3315 /* The opcode is in bits 23, 21, 20 and 6. */
3316 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3320 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3322 /* rn is register number */
3323 VFP_DREG_N(rn
, insn
);
3326 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3327 ((rn
& 0x1e) == 0x6))) {
3328 /* Integer or single/half precision destination. */
3329 rd
= VFP_SREG_D(insn
);
3331 VFP_DREG_D(rd
, insn
);
3334 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3335 ((rn
& 0x1e) == 0x4))) {
3336 /* VCVT from int or half precision is always from S reg
3337 * regardless of dp bit. VCVT with immediate frac_bits
3338 * has same format as SREG_M.
3340 rm
= VFP_SREG_M(insn
);
3342 VFP_DREG_M(rm
, insn
);
3345 rn
= VFP_SREG_N(insn
);
3346 if (op
== 15 && rn
== 15) {
3347 /* Double precision destination. */
3348 VFP_DREG_D(rd
, insn
);
3350 rd
= VFP_SREG_D(insn
);
3352 /* NB that we implicitly rely on the encoding for the frac_bits
3353 * in VCVT of fixed to float being the same as that of an SREG_M
3355 rm
= VFP_SREG_M(insn
);
3358 veclen
= s
->vec_len
;
3359 if (op
== 15 && rn
> 3)
3362 /* Shut up compiler warnings. */
3373 /* Figure out what type of vector operation this is. */
3374 if ((rd
& bank_mask
) == 0) {
3379 delta_d
= (s
->vec_stride
>> 1) + 1;
3381 delta_d
= s
->vec_stride
+ 1;
3383 if ((rm
& bank_mask
) == 0) {
3384 /* mixed scalar/vector */
3393 /* Load the initial operands. */
3398 /* Integer source */
3399 gen_mov_F0_vreg(0, rm
);
3404 gen_mov_F0_vreg(dp
, rd
);
3405 gen_mov_F1_vreg(dp
, rm
);
3409 /* Compare with zero */
3410 gen_mov_F0_vreg(dp
, rd
);
3421 /* Source and destination the same. */
3422 gen_mov_F0_vreg(dp
, rd
);
3428 /* VCVTB, VCVTT: only present with the halfprec extension
3429 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3430 * (we choose to UNDEF)
3432 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3433 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3436 if (!extract32(rn
, 1, 1)) {
3437 /* Half precision source. */
3438 gen_mov_F0_vreg(0, rm
);
3441 /* Otherwise fall through */
3443 /* One source operand. */
3444 gen_mov_F0_vreg(dp
, rm
);
3448 /* Two source operands. */
3449 gen_mov_F0_vreg(dp
, rn
);
3450 gen_mov_F1_vreg(dp
, rm
);
3454 /* Perform the calculation. */
3456 case 0: /* VMLA: fd + (fn * fm) */
3457 /* Note that order of inputs to the add matters for NaNs */
3459 gen_mov_F0_vreg(dp
, rd
);
3462 case 1: /* VMLS: fd + -(fn * fm) */
3465 gen_mov_F0_vreg(dp
, rd
);
3468 case 2: /* VNMLS: -fd + (fn * fm) */
3469 /* Note that it isn't valid to replace (-A + B) with (B - A)
3470 * or similar plausible looking simplifications
3471 * because this will give wrong results for NaNs.
3474 gen_mov_F0_vreg(dp
, rd
);
3478 case 3: /* VNMLA: -fd + -(fn * fm) */
3481 gen_mov_F0_vreg(dp
, rd
);
3485 case 4: /* mul: fn * fm */
3488 case 5: /* nmul: -(fn * fm) */
3492 case 6: /* add: fn + fm */
3495 case 7: /* sub: fn - fm */
3498 case 8: /* div: fn / fm */
3501 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3502 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3503 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3504 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3505 /* These are fused multiply-add, and must be done as one
3506 * floating point operation with no rounding between the
3507 * multiplication and addition steps.
3508 * NB that doing the negations here as separate steps is
3509 * correct : an input NaN should come out with its sign bit
3510 * flipped if it is a negated-input.
3512 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3520 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3522 frd
= tcg_temp_new_i64();
3523 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3526 gen_helper_vfp_negd(frd
, frd
);
3528 fpst
= get_fpstatus_ptr(0);
3529 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3530 cpu_F1d
, frd
, fpst
);
3531 tcg_temp_free_ptr(fpst
);
3532 tcg_temp_free_i64(frd
);
3538 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3540 frd
= tcg_temp_new_i32();
3541 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3543 gen_helper_vfp_negs(frd
, frd
);
3545 fpst
= get_fpstatus_ptr(0);
3546 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3547 cpu_F1s
, frd
, fpst
);
3548 tcg_temp_free_ptr(fpst
);
3549 tcg_temp_free_i32(frd
);
3552 case 14: /* fconst */
3553 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3557 n
= (insn
<< 12) & 0x80000000;
3558 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3565 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3572 tcg_gen_movi_i32(cpu_F0s
, n
);
3575 case 15: /* extension space */
3589 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3590 tmp
= gen_vfp_mrs();
3591 tcg_gen_ext16u_i32(tmp
, tmp
);
3593 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3596 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3599 tcg_temp_free_i32(tmp
);
3601 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3602 tmp
= gen_vfp_mrs();
3603 tcg_gen_shri_i32(tmp
, tmp
, 16);
3605 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3608 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3611 tcg_temp_free_i32(tmp
);
3613 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3614 tmp
= tcg_temp_new_i32();
3616 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3619 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3622 gen_mov_F0_vreg(0, rd
);
3623 tmp2
= gen_vfp_mrs();
3624 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3625 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3626 tcg_temp_free_i32(tmp2
);
3629 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3630 tmp
= tcg_temp_new_i32();
3632 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3635 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3638 tcg_gen_shli_i32(tmp
, tmp
, 16);
3639 gen_mov_F0_vreg(0, rd
);
3640 tmp2
= gen_vfp_mrs();
3641 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3642 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3643 tcg_temp_free_i32(tmp2
);
3655 case 11: /* cmpez */
3659 case 12: /* vrintr */
3661 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3663 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3665 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3667 tcg_temp_free_ptr(fpst
);
3670 case 13: /* vrintz */
3672 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3674 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3675 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3677 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3679 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3681 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3682 tcg_temp_free_i32(tcg_rmode
);
3683 tcg_temp_free_ptr(fpst
);
3686 case 14: /* vrintx */
3688 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3690 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3692 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3694 tcg_temp_free_ptr(fpst
);
3697 case 15: /* single<->double conversion */
3699 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3701 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3703 case 16: /* fuito */
3704 gen_vfp_uito(dp
, 0);
3706 case 17: /* fsito */
3707 gen_vfp_sito(dp
, 0);
3709 case 20: /* fshto */
3710 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3713 gen_vfp_shto(dp
, 16 - rm
, 0);
3715 case 21: /* fslto */
3716 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3719 gen_vfp_slto(dp
, 32 - rm
, 0);
3721 case 22: /* fuhto */
3722 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3725 gen_vfp_uhto(dp
, 16 - rm
, 0);
3727 case 23: /* fulto */
3728 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3731 gen_vfp_ulto(dp
, 32 - rm
, 0);
3733 case 24: /* ftoui */
3734 gen_vfp_toui(dp
, 0);
3736 case 25: /* ftouiz */
3737 gen_vfp_touiz(dp
, 0);
3739 case 26: /* ftosi */
3740 gen_vfp_tosi(dp
, 0);
3742 case 27: /* ftosiz */
3743 gen_vfp_tosiz(dp
, 0);
3745 case 28: /* ftosh */
3746 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3749 gen_vfp_tosh(dp
, 16 - rm
, 0);
3751 case 29: /* ftosl */
3752 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3755 gen_vfp_tosl(dp
, 32 - rm
, 0);
3757 case 30: /* ftouh */
3758 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3761 gen_vfp_touh(dp
, 16 - rm
, 0);
3763 case 31: /* ftoul */
3764 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3767 gen_vfp_toul(dp
, 32 - rm
, 0);
3769 default: /* undefined */
3773 default: /* undefined */
3777 /* Write back the result. */
3778 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3779 /* Comparison, do nothing. */
3780 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3781 (rn
& 0x1e) == 0x6)) {
3782 /* VCVT double to int: always integer result.
3783 * VCVT double to half precision is always a single
3786 gen_mov_vreg_F0(0, rd
);
3787 } else if (op
== 15 && rn
== 15) {
3789 gen_mov_vreg_F0(!dp
, rd
);
3791 gen_mov_vreg_F0(dp
, rd
);
3794 /* break out of the loop if we have finished */
3798 if (op
== 15 && delta_m
== 0) {
3799 /* single source one-many */
3801 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3803 gen_mov_vreg_F0(dp
, rd
);
3807 /* Setup the next operands. */
3809 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3813 /* One source operand. */
3814 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3816 gen_mov_F0_vreg(dp
, rm
);
3818 /* Two source operands. */
3819 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3821 gen_mov_F0_vreg(dp
, rn
);
3823 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3825 gen_mov_F1_vreg(dp
, rm
);
3833 if ((insn
& 0x03e00000) == 0x00400000) {
3834 /* two-register transfer */
3835 rn
= (insn
>> 16) & 0xf;
3836 rd
= (insn
>> 12) & 0xf;
3838 VFP_DREG_M(rm
, insn
);
3840 rm
= VFP_SREG_M(insn
);
3843 if (insn
& ARM_CP_RW_BIT
) {
3846 gen_mov_F0_vreg(0, rm
* 2);
3847 tmp
= gen_vfp_mrs();
3848 store_reg(s
, rd
, tmp
);
3849 gen_mov_F0_vreg(0, rm
* 2 + 1);
3850 tmp
= gen_vfp_mrs();
3851 store_reg(s
, rn
, tmp
);
3853 gen_mov_F0_vreg(0, rm
);
3854 tmp
= gen_vfp_mrs();
3855 store_reg(s
, rd
, tmp
);
3856 gen_mov_F0_vreg(0, rm
+ 1);
3857 tmp
= gen_vfp_mrs();
3858 store_reg(s
, rn
, tmp
);
3863 tmp
= load_reg(s
, rd
);
3865 gen_mov_vreg_F0(0, rm
* 2);
3866 tmp
= load_reg(s
, rn
);
3868 gen_mov_vreg_F0(0, rm
* 2 + 1);
3870 tmp
= load_reg(s
, rd
);
3872 gen_mov_vreg_F0(0, rm
);
3873 tmp
= load_reg(s
, rn
);
3875 gen_mov_vreg_F0(0, rm
+ 1);
3880 rn
= (insn
>> 16) & 0xf;
3882 VFP_DREG_D(rd
, insn
);
3884 rd
= VFP_SREG_D(insn
);
3885 if ((insn
& 0x01200000) == 0x01000000) {
3886 /* Single load/store */
3887 offset
= (insn
& 0xff) << 2;
3888 if ((insn
& (1 << 23)) == 0)
3890 if (s
->thumb
&& rn
== 15) {
3891 /* This is actually UNPREDICTABLE */
3892 addr
= tcg_temp_new_i32();
3893 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3895 addr
= load_reg(s
, rn
);
3897 tcg_gen_addi_i32(addr
, addr
, offset
);
3898 if (insn
& (1 << 20)) {
3899 gen_vfp_ld(s
, dp
, addr
);
3900 gen_mov_vreg_F0(dp
, rd
);
3902 gen_mov_F0_vreg(dp
, rd
);
3903 gen_vfp_st(s
, dp
, addr
);
3905 tcg_temp_free_i32(addr
);
3907 /* load/store multiple */
3908 int w
= insn
& (1 << 21);
3910 n
= (insn
>> 1) & 0x7f;
3914 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3915 /* P == U , W == 1 => UNDEF */
3918 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3919 /* UNPREDICTABLE cases for bad immediates: we choose to
3920 * UNDEF to avoid generating huge numbers of TCG ops
3924 if (rn
== 15 && w
) {
3925 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3929 if (s
->thumb
&& rn
== 15) {
3930 /* This is actually UNPREDICTABLE */
3931 addr
= tcg_temp_new_i32();
3932 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3934 addr
= load_reg(s
, rn
);
3936 if (insn
& (1 << 24)) /* pre-decrement */
3937 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3943 for (i
= 0; i
< n
; i
++) {
3944 if (insn
& ARM_CP_RW_BIT
) {
3946 gen_vfp_ld(s
, dp
, addr
);
3947 gen_mov_vreg_F0(dp
, rd
+ i
);
3950 gen_mov_F0_vreg(dp
, rd
+ i
);
3951 gen_vfp_st(s
, dp
, addr
);
3953 tcg_gen_addi_i32(addr
, addr
, offset
);
3957 if (insn
& (1 << 24))
3958 offset
= -offset
* n
;
3959 else if (dp
&& (insn
& 1))
3965 tcg_gen_addi_i32(addr
, addr
, offset
);
3966 store_reg(s
, rn
, addr
);
3968 tcg_temp_free_i32(addr
);
3974 /* Should never happen. */
3980 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3982 TranslationBlock
*tb
;
3985 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3987 gen_set_pc_im(s
, dest
);
3988 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3990 gen_set_pc_im(s
, dest
);
3995 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3997 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
3998 /* An indirect jump so that we still trigger the debug exception. */
4003 gen_goto_tb(s
, 0, dest
);
4004 s
->is_jmp
= DISAS_TB_JUMP
;
4008 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4011 tcg_gen_sari_i32(t0
, t0
, 16);
4015 tcg_gen_sari_i32(t1
, t1
, 16);
4018 tcg_gen_mul_i32(t0
, t0
, t1
);
4021 /* Return the mask of PSR bits set by a MSR instruction. */
4022 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4027 if (flags
& (1 << 0))
4029 if (flags
& (1 << 1))
4031 if (flags
& (1 << 2))
4033 if (flags
& (1 << 3))
4036 /* Mask out undefined bits. */
4037 mask
&= ~CPSR_RESERVED
;
4038 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4041 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4042 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4044 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4045 mask
&= ~(CPSR_E
| CPSR_GE
);
4047 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4050 /* Mask out execution state and reserved bits. */
4052 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4054 /* Mask out privileged bits. */
4060 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4061 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4065 /* ??? This is also undefined in system mode. */
4069 tmp
= load_cpu_field(spsr
);
4070 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4071 tcg_gen_andi_i32(t0
, t0
, mask
);
4072 tcg_gen_or_i32(tmp
, tmp
, t0
);
4073 store_cpu_field(tmp
, spsr
);
4075 gen_set_cpsr(t0
, mask
);
4077 tcg_temp_free_i32(t0
);
4082 /* Returns nonzero if access to the PSR is not permitted. */
4083 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4086 tmp
= tcg_temp_new_i32();
4087 tcg_gen_movi_i32(tmp
, val
);
4088 return gen_set_psr(s
, mask
, spsr
, tmp
);
4091 /* Generate an old-style exception return. Marks pc as dead. */
4092 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4095 store_reg(s
, 15, pc
);
4096 tmp
= load_cpu_field(spsr
);
4097 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
4098 tcg_temp_free_i32(tmp
);
4099 s
->is_jmp
= DISAS_JUMP
;
4102 /* Generate a v6 exception return. Marks both values as dead. */
4103 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4105 gen_set_cpsr(cpsr
, CPSR_ERET_MASK
);
4106 tcg_temp_free_i32(cpsr
);
4107 store_reg(s
, 15, pc
);
4108 s
->is_jmp
= DISAS_JUMP
;
4111 static void gen_nop_hint(DisasContext
*s
, int val
)
4115 gen_set_pc_im(s
, s
->pc
);
4116 s
->is_jmp
= DISAS_YIELD
;
4119 gen_set_pc_im(s
, s
->pc
);
4120 s
->is_jmp
= DISAS_WFI
;
4123 gen_set_pc_im(s
, s
->pc
);
4124 s
->is_jmp
= DISAS_WFE
;
4128 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4134 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4136 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4139 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4140 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4141 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4146 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4149 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4150 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4151 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4156 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4157 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4158 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4159 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4160 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4162 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4163 switch ((size << 1) | u) { \
4165 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4168 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4171 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4174 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4177 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4180 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4182 default: return 1; \
4185 #define GEN_NEON_INTEGER_OP(name) do { \
4186 switch ((size << 1) | u) { \
4188 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4191 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4194 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4197 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4200 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4203 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4205 default: return 1; \
4208 static TCGv_i32
neon_load_scratch(int scratch
)
4210 TCGv_i32 tmp
= tcg_temp_new_i32();
4211 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4215 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4217 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4218 tcg_temp_free_i32(var
);
4221 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4225 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4227 gen_neon_dup_high16(tmp
);
4229 gen_neon_dup_low16(tmp
);
4232 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4237 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4240 if (!q
&& size
== 2) {
4243 tmp
= tcg_const_i32(rd
);
4244 tmp2
= tcg_const_i32(rm
);
4248 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4251 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4254 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4262 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4265 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4271 tcg_temp_free_i32(tmp
);
4272 tcg_temp_free_i32(tmp2
);
4276 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4279 if (!q
&& size
== 2) {
4282 tmp
= tcg_const_i32(rd
);
4283 tmp2
= tcg_const_i32(rm
);
4287 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4290 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4293 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4301 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4304 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4310 tcg_temp_free_i32(tmp
);
4311 tcg_temp_free_i32(tmp2
);
4315 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4319 rd
= tcg_temp_new_i32();
4320 tmp
= tcg_temp_new_i32();
4322 tcg_gen_shli_i32(rd
, t0
, 8);
4323 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4324 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4325 tcg_gen_or_i32(rd
, rd
, tmp
);
4327 tcg_gen_shri_i32(t1
, t1
, 8);
4328 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4329 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4330 tcg_gen_or_i32(t1
, t1
, tmp
);
4331 tcg_gen_mov_i32(t0
, rd
);
4333 tcg_temp_free_i32(tmp
);
4334 tcg_temp_free_i32(rd
);
4337 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4341 rd
= tcg_temp_new_i32();
4342 tmp
= tcg_temp_new_i32();
4344 tcg_gen_shli_i32(rd
, t0
, 16);
4345 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4346 tcg_gen_or_i32(rd
, rd
, tmp
);
4347 tcg_gen_shri_i32(t1
, t1
, 16);
4348 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4349 tcg_gen_or_i32(t1
, t1
, tmp
);
4350 tcg_gen_mov_i32(t0
, rd
);
4352 tcg_temp_free_i32(tmp
);
4353 tcg_temp_free_i32(rd
);
4361 } neon_ls_element_type
[11] = {
4375 /* Translate a NEON load/store element instruction. Return nonzero if the
4376 instruction is invalid. */
4377 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4396 /* FIXME: this access check should not take precedence over UNDEF
4397 * for invalid encodings; we will generate incorrect syndrome information
4398 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4400 if (s
->fp_excp_el
) {
4401 gen_exception_insn(s
, 4, EXCP_UDEF
,
4402 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
4406 if (!s
->vfp_enabled
)
4408 VFP_DREG_D(rd
, insn
);
4409 rn
= (insn
>> 16) & 0xf;
4411 load
= (insn
& (1 << 21)) != 0;
4412 if ((insn
& (1 << 23)) == 0) {
4413 /* Load store all elements. */
4414 op
= (insn
>> 8) & 0xf;
4415 size
= (insn
>> 6) & 3;
4418 /* Catch UNDEF cases for bad values of align field */
4421 if (((insn
>> 5) & 1) == 1) {
4426 if (((insn
>> 4) & 3) == 3) {
4433 nregs
= neon_ls_element_type
[op
].nregs
;
4434 interleave
= neon_ls_element_type
[op
].interleave
;
4435 spacing
= neon_ls_element_type
[op
].spacing
;
4436 if (size
== 3 && (interleave
| spacing
) != 1)
4438 addr
= tcg_temp_new_i32();
4439 load_reg_var(s
, addr
, rn
);
4440 stride
= (1 << size
) * interleave
;
4441 for (reg
= 0; reg
< nregs
; reg
++) {
4442 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4443 load_reg_var(s
, addr
, rn
);
4444 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4445 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4446 load_reg_var(s
, addr
, rn
);
4447 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4450 tmp64
= tcg_temp_new_i64();
4452 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4453 neon_store_reg64(tmp64
, rd
);
4455 neon_load_reg64(tmp64
, rd
);
4456 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4458 tcg_temp_free_i64(tmp64
);
4459 tcg_gen_addi_i32(addr
, addr
, stride
);
4461 for (pass
= 0; pass
< 2; pass
++) {
4464 tmp
= tcg_temp_new_i32();
4465 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4466 neon_store_reg(rd
, pass
, tmp
);
4468 tmp
= neon_load_reg(rd
, pass
);
4469 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4470 tcg_temp_free_i32(tmp
);
4472 tcg_gen_addi_i32(addr
, addr
, stride
);
4473 } else if (size
== 1) {
4475 tmp
= tcg_temp_new_i32();
4476 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4477 tcg_gen_addi_i32(addr
, addr
, stride
);
4478 tmp2
= tcg_temp_new_i32();
4479 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4480 tcg_gen_addi_i32(addr
, addr
, stride
);
4481 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4482 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4483 tcg_temp_free_i32(tmp2
);
4484 neon_store_reg(rd
, pass
, tmp
);
4486 tmp
= neon_load_reg(rd
, pass
);
4487 tmp2
= tcg_temp_new_i32();
4488 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4489 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4490 tcg_temp_free_i32(tmp
);
4491 tcg_gen_addi_i32(addr
, addr
, stride
);
4492 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4493 tcg_temp_free_i32(tmp2
);
4494 tcg_gen_addi_i32(addr
, addr
, stride
);
4496 } else /* size == 0 */ {
4498 TCGV_UNUSED_I32(tmp2
);
4499 for (n
= 0; n
< 4; n
++) {
4500 tmp
= tcg_temp_new_i32();
4501 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4502 tcg_gen_addi_i32(addr
, addr
, stride
);
4506 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4507 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4508 tcg_temp_free_i32(tmp
);
4511 neon_store_reg(rd
, pass
, tmp2
);
4513 tmp2
= neon_load_reg(rd
, pass
);
4514 for (n
= 0; n
< 4; n
++) {
4515 tmp
= tcg_temp_new_i32();
4517 tcg_gen_mov_i32(tmp
, tmp2
);
4519 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4521 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4522 tcg_temp_free_i32(tmp
);
4523 tcg_gen_addi_i32(addr
, addr
, stride
);
4525 tcg_temp_free_i32(tmp2
);
4532 tcg_temp_free_i32(addr
);
4535 size
= (insn
>> 10) & 3;
4537 /* Load single element to all lanes. */
4538 int a
= (insn
>> 4) & 1;
4542 size
= (insn
>> 6) & 3;
4543 nregs
= ((insn
>> 8) & 3) + 1;
4546 if (nregs
!= 4 || a
== 0) {
4549 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4552 if (nregs
== 1 && a
== 1 && size
== 0) {
4555 if (nregs
== 3 && a
== 1) {
4558 addr
= tcg_temp_new_i32();
4559 load_reg_var(s
, addr
, rn
);
4561 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4562 tmp
= gen_load_and_replicate(s
, addr
, size
);
4563 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4564 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4565 if (insn
& (1 << 5)) {
4566 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4567 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4569 tcg_temp_free_i32(tmp
);
4571 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4572 stride
= (insn
& (1 << 5)) ? 2 : 1;
4573 for (reg
= 0; reg
< nregs
; reg
++) {
4574 tmp
= gen_load_and_replicate(s
, addr
, size
);
4575 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4576 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4577 tcg_temp_free_i32(tmp
);
4578 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4582 tcg_temp_free_i32(addr
);
4583 stride
= (1 << size
) * nregs
;
4585 /* Single element. */
4586 int idx
= (insn
>> 4) & 0xf;
4587 pass
= (insn
>> 7) & 1;
4590 shift
= ((insn
>> 5) & 3) * 8;
4594 shift
= ((insn
>> 6) & 1) * 16;
4595 stride
= (insn
& (1 << 5)) ? 2 : 1;
4599 stride
= (insn
& (1 << 6)) ? 2 : 1;
4604 nregs
= ((insn
>> 8) & 3) + 1;
4605 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4608 if (((idx
& (1 << size
)) != 0) ||
4609 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4614 if ((idx
& 1) != 0) {
4619 if (size
== 2 && (idx
& 2) != 0) {
4624 if ((size
== 2) && ((idx
& 3) == 3)) {
4631 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4632 /* Attempts to write off the end of the register file
4633 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4634 * the neon_load_reg() would write off the end of the array.
4638 addr
= tcg_temp_new_i32();
4639 load_reg_var(s
, addr
, rn
);
4640 for (reg
= 0; reg
< nregs
; reg
++) {
4642 tmp
= tcg_temp_new_i32();
4645 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4648 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4651 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4653 default: /* Avoid compiler warnings. */
4657 tmp2
= neon_load_reg(rd
, pass
);
4658 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4659 shift
, size
? 16 : 8);
4660 tcg_temp_free_i32(tmp2
);
4662 neon_store_reg(rd
, pass
, tmp
);
4663 } else { /* Store */
4664 tmp
= neon_load_reg(rd
, pass
);
4666 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4669 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4672 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4675 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4678 tcg_temp_free_i32(tmp
);
4681 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4683 tcg_temp_free_i32(addr
);
4684 stride
= nregs
* (1 << size
);
4690 base
= load_reg(s
, rn
);
4692 tcg_gen_addi_i32(base
, base
, stride
);
4695 index
= load_reg(s
, rm
);
4696 tcg_gen_add_i32(base
, base
, index
);
4697 tcg_temp_free_i32(index
);
4699 store_reg(s
, rn
, base
);
4704 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4705 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4707 tcg_gen_and_i32(t
, t
, c
);
4708 tcg_gen_andc_i32(f
, f
, c
);
4709 tcg_gen_or_i32(dest
, t
, f
);
4712 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4715 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4716 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4717 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4722 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4725 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4726 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4727 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4732 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4735 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4736 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4737 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4742 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4745 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4746 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4747 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4752 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4758 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4759 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4764 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4765 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4772 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4773 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4778 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4779 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4786 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4790 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4791 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4792 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4797 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4798 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4799 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4803 tcg_temp_free_i32(src
);
4806 static inline void gen_neon_addl(int size
)
4809 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4810 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4811 case 2: tcg_gen_add_i64(CPU_V001
); break;
4816 static inline void gen_neon_subl(int size
)
4819 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4820 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4821 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4826 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4829 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4830 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4832 tcg_gen_neg_i64(var
, var
);
4838 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4841 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4842 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4847 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4852 switch ((size
<< 1) | u
) {
4853 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4854 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4855 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4856 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4858 tmp
= gen_muls_i64_i32(a
, b
);
4859 tcg_gen_mov_i64(dest
, tmp
);
4860 tcg_temp_free_i64(tmp
);
4863 tmp
= gen_mulu_i64_i32(a
, b
);
4864 tcg_gen_mov_i64(dest
, tmp
);
4865 tcg_temp_free_i64(tmp
);
4870 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4871 Don't forget to clean them now. */
4873 tcg_temp_free_i32(a
);
4874 tcg_temp_free_i32(b
);
4878 static void gen_neon_narrow_op(int op
, int u
, int size
,
4879 TCGv_i32 dest
, TCGv_i64 src
)
4883 gen_neon_unarrow_sats(size
, dest
, src
);
4885 gen_neon_narrow(size
, dest
, src
);
4889 gen_neon_narrow_satu(size
, dest
, src
);
4891 gen_neon_narrow_sats(size
, dest
, src
);
4896 /* Symbolic constants for op fields for Neon 3-register same-length.
4897 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4900 #define NEON_3R_VHADD 0
4901 #define NEON_3R_VQADD 1
4902 #define NEON_3R_VRHADD 2
4903 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4904 #define NEON_3R_VHSUB 4
4905 #define NEON_3R_VQSUB 5
4906 #define NEON_3R_VCGT 6
4907 #define NEON_3R_VCGE 7
4908 #define NEON_3R_VSHL 8
4909 #define NEON_3R_VQSHL 9
4910 #define NEON_3R_VRSHL 10
4911 #define NEON_3R_VQRSHL 11
4912 #define NEON_3R_VMAX 12
4913 #define NEON_3R_VMIN 13
4914 #define NEON_3R_VABD 14
4915 #define NEON_3R_VABA 15
4916 #define NEON_3R_VADD_VSUB 16
4917 #define NEON_3R_VTST_VCEQ 17
4918 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4919 #define NEON_3R_VMUL 19
4920 #define NEON_3R_VPMAX 20
4921 #define NEON_3R_VPMIN 21
4922 #define NEON_3R_VQDMULH_VQRDMULH 22
4923 #define NEON_3R_VPADD 23
4924 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4925 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4926 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4927 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4928 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4929 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4930 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4931 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4933 static const uint8_t neon_3r_sizes
[] = {
4934 [NEON_3R_VHADD
] = 0x7,
4935 [NEON_3R_VQADD
] = 0xf,
4936 [NEON_3R_VRHADD
] = 0x7,
4937 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4938 [NEON_3R_VHSUB
] = 0x7,
4939 [NEON_3R_VQSUB
] = 0xf,
4940 [NEON_3R_VCGT
] = 0x7,
4941 [NEON_3R_VCGE
] = 0x7,
4942 [NEON_3R_VSHL
] = 0xf,
4943 [NEON_3R_VQSHL
] = 0xf,
4944 [NEON_3R_VRSHL
] = 0xf,
4945 [NEON_3R_VQRSHL
] = 0xf,
4946 [NEON_3R_VMAX
] = 0x7,
4947 [NEON_3R_VMIN
] = 0x7,
4948 [NEON_3R_VABD
] = 0x7,
4949 [NEON_3R_VABA
] = 0x7,
4950 [NEON_3R_VADD_VSUB
] = 0xf,
4951 [NEON_3R_VTST_VCEQ
] = 0x7,
4952 [NEON_3R_VML
] = 0x7,
4953 [NEON_3R_VMUL
] = 0x7,
4954 [NEON_3R_VPMAX
] = 0x7,
4955 [NEON_3R_VPMIN
] = 0x7,
4956 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4957 [NEON_3R_VPADD
] = 0x7,
4958 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4959 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4960 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4961 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4962 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4963 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4964 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4965 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4968 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4969 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4972 #define NEON_2RM_VREV64 0
4973 #define NEON_2RM_VREV32 1
4974 #define NEON_2RM_VREV16 2
4975 #define NEON_2RM_VPADDL 4
4976 #define NEON_2RM_VPADDL_U 5
4977 #define NEON_2RM_AESE 6 /* Includes AESD */
4978 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4979 #define NEON_2RM_VCLS 8
4980 #define NEON_2RM_VCLZ 9
4981 #define NEON_2RM_VCNT 10
4982 #define NEON_2RM_VMVN 11
4983 #define NEON_2RM_VPADAL 12
4984 #define NEON_2RM_VPADAL_U 13
4985 #define NEON_2RM_VQABS 14
4986 #define NEON_2RM_VQNEG 15
4987 #define NEON_2RM_VCGT0 16
4988 #define NEON_2RM_VCGE0 17
4989 #define NEON_2RM_VCEQ0 18
4990 #define NEON_2RM_VCLE0 19
4991 #define NEON_2RM_VCLT0 20
4992 #define NEON_2RM_SHA1H 21
4993 #define NEON_2RM_VABS 22
4994 #define NEON_2RM_VNEG 23
4995 #define NEON_2RM_VCGT0_F 24
4996 #define NEON_2RM_VCGE0_F 25
4997 #define NEON_2RM_VCEQ0_F 26
4998 #define NEON_2RM_VCLE0_F 27
4999 #define NEON_2RM_VCLT0_F 28
5000 #define NEON_2RM_VABS_F 30
5001 #define NEON_2RM_VNEG_F 31
5002 #define NEON_2RM_VSWP 32
5003 #define NEON_2RM_VTRN 33
5004 #define NEON_2RM_VUZP 34
5005 #define NEON_2RM_VZIP 35
5006 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5007 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5008 #define NEON_2RM_VSHLL 38
5009 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5010 #define NEON_2RM_VRINTN 40
5011 #define NEON_2RM_VRINTX 41
5012 #define NEON_2RM_VRINTA 42
5013 #define NEON_2RM_VRINTZ 43
5014 #define NEON_2RM_VCVT_F16_F32 44
5015 #define NEON_2RM_VRINTM 45
5016 #define NEON_2RM_VCVT_F32_F16 46
5017 #define NEON_2RM_VRINTP 47
5018 #define NEON_2RM_VCVTAU 48
5019 #define NEON_2RM_VCVTAS 49
5020 #define NEON_2RM_VCVTNU 50
5021 #define NEON_2RM_VCVTNS 51
5022 #define NEON_2RM_VCVTPU 52
5023 #define NEON_2RM_VCVTPS 53
5024 #define NEON_2RM_VCVTMU 54
5025 #define NEON_2RM_VCVTMS 55
5026 #define NEON_2RM_VRECPE 56
5027 #define NEON_2RM_VRSQRTE 57
5028 #define NEON_2RM_VRECPE_F 58
5029 #define NEON_2RM_VRSQRTE_F 59
5030 #define NEON_2RM_VCVT_FS 60
5031 #define NEON_2RM_VCVT_FU 61
5032 #define NEON_2RM_VCVT_SF 62
5033 #define NEON_2RM_VCVT_UF 63
5035 static int neon_2rm_is_float_op(int op
)
5037 /* Return true if this neon 2reg-misc op is float-to-float */
5038 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5039 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5040 op
== NEON_2RM_VRINTM
||
5041 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5042 op
>= NEON_2RM_VRECPE_F
);
5045 /* Each entry in this array has bit n set if the insn allows
5046 * size value n (otherwise it will UNDEF). Since unallocated
5047 * op values will have no bits set they always UNDEF.
5049 static const uint8_t neon_2rm_sizes
[] = {
5050 [NEON_2RM_VREV64
] = 0x7,
5051 [NEON_2RM_VREV32
] = 0x3,
5052 [NEON_2RM_VREV16
] = 0x1,
5053 [NEON_2RM_VPADDL
] = 0x7,
5054 [NEON_2RM_VPADDL_U
] = 0x7,
5055 [NEON_2RM_AESE
] = 0x1,
5056 [NEON_2RM_AESMC
] = 0x1,
5057 [NEON_2RM_VCLS
] = 0x7,
5058 [NEON_2RM_VCLZ
] = 0x7,
5059 [NEON_2RM_VCNT
] = 0x1,
5060 [NEON_2RM_VMVN
] = 0x1,
5061 [NEON_2RM_VPADAL
] = 0x7,
5062 [NEON_2RM_VPADAL_U
] = 0x7,
5063 [NEON_2RM_VQABS
] = 0x7,
5064 [NEON_2RM_VQNEG
] = 0x7,
5065 [NEON_2RM_VCGT0
] = 0x7,
5066 [NEON_2RM_VCGE0
] = 0x7,
5067 [NEON_2RM_VCEQ0
] = 0x7,
5068 [NEON_2RM_VCLE0
] = 0x7,
5069 [NEON_2RM_VCLT0
] = 0x7,
5070 [NEON_2RM_SHA1H
] = 0x4,
5071 [NEON_2RM_VABS
] = 0x7,
5072 [NEON_2RM_VNEG
] = 0x7,
5073 [NEON_2RM_VCGT0_F
] = 0x4,
5074 [NEON_2RM_VCGE0_F
] = 0x4,
5075 [NEON_2RM_VCEQ0_F
] = 0x4,
5076 [NEON_2RM_VCLE0_F
] = 0x4,
5077 [NEON_2RM_VCLT0_F
] = 0x4,
5078 [NEON_2RM_VABS_F
] = 0x4,
5079 [NEON_2RM_VNEG_F
] = 0x4,
5080 [NEON_2RM_VSWP
] = 0x1,
5081 [NEON_2RM_VTRN
] = 0x7,
5082 [NEON_2RM_VUZP
] = 0x7,
5083 [NEON_2RM_VZIP
] = 0x7,
5084 [NEON_2RM_VMOVN
] = 0x7,
5085 [NEON_2RM_VQMOVN
] = 0x7,
5086 [NEON_2RM_VSHLL
] = 0x7,
5087 [NEON_2RM_SHA1SU1
] = 0x4,
5088 [NEON_2RM_VRINTN
] = 0x4,
5089 [NEON_2RM_VRINTX
] = 0x4,
5090 [NEON_2RM_VRINTA
] = 0x4,
5091 [NEON_2RM_VRINTZ
] = 0x4,
5092 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5093 [NEON_2RM_VRINTM
] = 0x4,
5094 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5095 [NEON_2RM_VRINTP
] = 0x4,
5096 [NEON_2RM_VCVTAU
] = 0x4,
5097 [NEON_2RM_VCVTAS
] = 0x4,
5098 [NEON_2RM_VCVTNU
] = 0x4,
5099 [NEON_2RM_VCVTNS
] = 0x4,
5100 [NEON_2RM_VCVTPU
] = 0x4,
5101 [NEON_2RM_VCVTPS
] = 0x4,
5102 [NEON_2RM_VCVTMU
] = 0x4,
5103 [NEON_2RM_VCVTMS
] = 0x4,
5104 [NEON_2RM_VRECPE
] = 0x4,
5105 [NEON_2RM_VRSQRTE
] = 0x4,
5106 [NEON_2RM_VRECPE_F
] = 0x4,
5107 [NEON_2RM_VRSQRTE_F
] = 0x4,
5108 [NEON_2RM_VCVT_FS
] = 0x4,
5109 [NEON_2RM_VCVT_FU
] = 0x4,
5110 [NEON_2RM_VCVT_SF
] = 0x4,
5111 [NEON_2RM_VCVT_UF
] = 0x4,
5114 /* Translate a NEON data processing instruction. Return nonzero if the
5115 instruction is invalid.
5116 We process data in a mixture of 32-bit and 64-bit chunks.
5117 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5119 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5131 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5134 /* FIXME: this access check should not take precedence over UNDEF
5135 * for invalid encodings; we will generate incorrect syndrome information
5136 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5138 if (s
->fp_excp_el
) {
5139 gen_exception_insn(s
, 4, EXCP_UDEF
,
5140 syn_fp_access_trap(1, 0xe, false), s
->fp_excp_el
);
5144 if (!s
->vfp_enabled
)
5146 q
= (insn
& (1 << 6)) != 0;
5147 u
= (insn
>> 24) & 1;
5148 VFP_DREG_D(rd
, insn
);
5149 VFP_DREG_N(rn
, insn
);
5150 VFP_DREG_M(rm
, insn
);
5151 size
= (insn
>> 20) & 3;
5152 if ((insn
& (1 << 23)) == 0) {
5153 /* Three register same length. */
5154 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5155 /* Catch invalid op and bad size combinations: UNDEF */
5156 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5159 /* All insns of this form UNDEF for either this condition or the
5160 * superset of cases "Q==1"; we catch the latter later.
5162 if (q
&& ((rd
| rn
| rm
) & 1)) {
5166 * The SHA-1/SHA-256 3-register instructions require special treatment
5167 * here, as their size field is overloaded as an op type selector, and
5168 * they all consume their input in a single pass.
5170 if (op
== NEON_3R_SHA
) {
5174 if (!u
) { /* SHA-1 */
5175 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5178 tmp
= tcg_const_i32(rd
);
5179 tmp2
= tcg_const_i32(rn
);
5180 tmp3
= tcg_const_i32(rm
);
5181 tmp4
= tcg_const_i32(size
);
5182 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5183 tcg_temp_free_i32(tmp4
);
5184 } else { /* SHA-256 */
5185 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5188 tmp
= tcg_const_i32(rd
);
5189 tmp2
= tcg_const_i32(rn
);
5190 tmp3
= tcg_const_i32(rm
);
5193 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5196 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5199 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5203 tcg_temp_free_i32(tmp
);
5204 tcg_temp_free_i32(tmp2
);
5205 tcg_temp_free_i32(tmp3
);
5208 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5209 /* 64-bit element instructions. */
5210 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5211 neon_load_reg64(cpu_V0
, rn
+ pass
);
5212 neon_load_reg64(cpu_V1
, rm
+ pass
);
5216 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5219 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5225 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5228 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5234 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5236 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5241 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5244 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5250 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5252 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5255 case NEON_3R_VQRSHL
:
5257 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5260 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5264 case NEON_3R_VADD_VSUB
:
5266 tcg_gen_sub_i64(CPU_V001
);
5268 tcg_gen_add_i64(CPU_V001
);
5274 neon_store_reg64(cpu_V0
, rd
+ pass
);
5283 case NEON_3R_VQRSHL
:
5286 /* Shift instruction operands are reversed. */
5301 case NEON_3R_FLOAT_ARITH
:
5302 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5304 case NEON_3R_FLOAT_MINMAX
:
5305 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5307 case NEON_3R_FLOAT_CMP
:
5309 /* no encoding for U=0 C=1x */
5313 case NEON_3R_FLOAT_ACMP
:
5318 case NEON_3R_FLOAT_MISC
:
5319 /* VMAXNM/VMINNM in ARMv8 */
5320 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5325 if (u
&& (size
!= 0)) {
5326 /* UNDEF on invalid size for polynomial subcase */
5331 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5339 if (pairwise
&& q
) {
5340 /* All the pairwise insns UNDEF if Q is set */
5344 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5349 tmp
= neon_load_reg(rn
, 0);
5350 tmp2
= neon_load_reg(rn
, 1);
5352 tmp
= neon_load_reg(rm
, 0);
5353 tmp2
= neon_load_reg(rm
, 1);
5357 tmp
= neon_load_reg(rn
, pass
);
5358 tmp2
= neon_load_reg(rm
, pass
);
5362 GEN_NEON_INTEGER_OP(hadd
);
5365 GEN_NEON_INTEGER_OP_ENV(qadd
);
5367 case NEON_3R_VRHADD
:
5368 GEN_NEON_INTEGER_OP(rhadd
);
5370 case NEON_3R_LOGIC
: /* Logic ops. */
5371 switch ((u
<< 2) | size
) {
5373 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5376 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5379 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5382 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5385 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5388 tmp3
= neon_load_reg(rd
, pass
);
5389 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5390 tcg_temp_free_i32(tmp3
);
5393 tmp3
= neon_load_reg(rd
, pass
);
5394 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5395 tcg_temp_free_i32(tmp3
);
5398 tmp3
= neon_load_reg(rd
, pass
);
5399 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5400 tcg_temp_free_i32(tmp3
);
5405 GEN_NEON_INTEGER_OP(hsub
);
5408 GEN_NEON_INTEGER_OP_ENV(qsub
);
5411 GEN_NEON_INTEGER_OP(cgt
);
5414 GEN_NEON_INTEGER_OP(cge
);
5417 GEN_NEON_INTEGER_OP(shl
);
5420 GEN_NEON_INTEGER_OP_ENV(qshl
);
5423 GEN_NEON_INTEGER_OP(rshl
);
5425 case NEON_3R_VQRSHL
:
5426 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5429 GEN_NEON_INTEGER_OP(max
);
5432 GEN_NEON_INTEGER_OP(min
);
5435 GEN_NEON_INTEGER_OP(abd
);
5438 GEN_NEON_INTEGER_OP(abd
);
5439 tcg_temp_free_i32(tmp2
);
5440 tmp2
= neon_load_reg(rd
, pass
);
5441 gen_neon_add(size
, tmp
, tmp2
);
5443 case NEON_3R_VADD_VSUB
:
5444 if (!u
) { /* VADD */
5445 gen_neon_add(size
, tmp
, tmp2
);
5448 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5449 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5450 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5455 case NEON_3R_VTST_VCEQ
:
5456 if (!u
) { /* VTST */
5458 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5459 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5460 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5465 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5466 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5467 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5472 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5474 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5475 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5476 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5479 tcg_temp_free_i32(tmp2
);
5480 tmp2
= neon_load_reg(rd
, pass
);
5482 gen_neon_rsb(size
, tmp
, tmp2
);
5484 gen_neon_add(size
, tmp
, tmp2
);
5488 if (u
) { /* polynomial */
5489 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5490 } else { /* Integer */
5492 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5493 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5494 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5500 GEN_NEON_INTEGER_OP(pmax
);
5503 GEN_NEON_INTEGER_OP(pmin
);
5505 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5506 if (!u
) { /* VQDMULH */
5509 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5512 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5516 } else { /* VQRDMULH */
5519 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5522 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5530 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5531 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5532 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5536 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5538 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5539 switch ((u
<< 2) | size
) {
5542 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5545 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5548 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5553 tcg_temp_free_ptr(fpstatus
);
5556 case NEON_3R_FLOAT_MULTIPLY
:
5558 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5559 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5561 tcg_temp_free_i32(tmp2
);
5562 tmp2
= neon_load_reg(rd
, pass
);
5564 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5566 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5569 tcg_temp_free_ptr(fpstatus
);
5572 case NEON_3R_FLOAT_CMP
:
5574 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5576 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5579 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5581 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5584 tcg_temp_free_ptr(fpstatus
);
5587 case NEON_3R_FLOAT_ACMP
:
5589 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5591 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5593 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5595 tcg_temp_free_ptr(fpstatus
);
5598 case NEON_3R_FLOAT_MINMAX
:
5600 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5602 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5604 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5606 tcg_temp_free_ptr(fpstatus
);
5609 case NEON_3R_FLOAT_MISC
:
5612 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5614 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5616 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5618 tcg_temp_free_ptr(fpstatus
);
5621 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5623 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5629 /* VFMA, VFMS: fused multiply-add */
5630 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5631 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5634 gen_helper_vfp_negs(tmp
, tmp
);
5636 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5637 tcg_temp_free_i32(tmp3
);
5638 tcg_temp_free_ptr(fpstatus
);
5644 tcg_temp_free_i32(tmp2
);
5646 /* Save the result. For elementwise operations we can put it
5647 straight into the destination register. For pairwise operations
5648 we have to be careful to avoid clobbering the source operands. */
5649 if (pairwise
&& rd
== rm
) {
5650 neon_store_scratch(pass
, tmp
);
5652 neon_store_reg(rd
, pass
, tmp
);
5656 if (pairwise
&& rd
== rm
) {
5657 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5658 tmp
= neon_load_scratch(pass
);
5659 neon_store_reg(rd
, pass
, tmp
);
5662 /* End of 3 register same size operations. */
5663 } else if (insn
& (1 << 4)) {
5664 if ((insn
& 0x00380080) != 0) {
5665 /* Two registers and shift. */
5666 op
= (insn
>> 8) & 0xf;
5667 if (insn
& (1 << 7)) {
5675 while ((insn
& (1 << (size
+ 19))) == 0)
5678 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5679 /* To avoid excessive duplication of ops we implement shift
5680 by immediate using the variable shift operations. */
5682 /* Shift by immediate:
5683 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5684 if (q
&& ((rd
| rm
) & 1)) {
5687 if (!u
&& (op
== 4 || op
== 6)) {
5690 /* Right shifts are encoded as N - shift, where N is the
5691 element size in bits. */
5693 shift
= shift
- (1 << (size
+ 3));
5701 imm
= (uint8_t) shift
;
5706 imm
= (uint16_t) shift
;
5717 for (pass
= 0; pass
< count
; pass
++) {
5719 neon_load_reg64(cpu_V0
, rm
+ pass
);
5720 tcg_gen_movi_i64(cpu_V1
, imm
);
5725 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5727 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5732 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5734 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5737 case 5: /* VSHL, VSLI */
5738 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5740 case 6: /* VQSHLU */
5741 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5746 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5749 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5754 if (op
== 1 || op
== 3) {
5756 neon_load_reg64(cpu_V1
, rd
+ pass
);
5757 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5758 } else if (op
== 4 || (op
== 5 && u
)) {
5760 neon_load_reg64(cpu_V1
, rd
+ pass
);
5762 if (shift
< -63 || shift
> 63) {
5766 mask
= 0xffffffffffffffffull
>> -shift
;
5768 mask
= 0xffffffffffffffffull
<< shift
;
5771 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5772 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5774 neon_store_reg64(cpu_V0
, rd
+ pass
);
5775 } else { /* size < 3 */
5776 /* Operands in T0 and T1. */
5777 tmp
= neon_load_reg(rm
, pass
);
5778 tmp2
= tcg_temp_new_i32();
5779 tcg_gen_movi_i32(tmp2
, imm
);
5783 GEN_NEON_INTEGER_OP(shl
);
5787 GEN_NEON_INTEGER_OP(rshl
);
5790 case 5: /* VSHL, VSLI */
5792 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5793 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5794 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5798 case 6: /* VQSHLU */
5801 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5805 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5809 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5817 GEN_NEON_INTEGER_OP_ENV(qshl
);
5820 tcg_temp_free_i32(tmp2
);
5822 if (op
== 1 || op
== 3) {
5824 tmp2
= neon_load_reg(rd
, pass
);
5825 gen_neon_add(size
, tmp
, tmp2
);
5826 tcg_temp_free_i32(tmp2
);
5827 } else if (op
== 4 || (op
== 5 && u
)) {
5832 mask
= 0xff >> -shift
;
5834 mask
= (uint8_t)(0xff << shift
);
5840 mask
= 0xffff >> -shift
;
5842 mask
= (uint16_t)(0xffff << shift
);
5846 if (shift
< -31 || shift
> 31) {
5850 mask
= 0xffffffffu
>> -shift
;
5852 mask
= 0xffffffffu
<< shift
;
5858 tmp2
= neon_load_reg(rd
, pass
);
5859 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5860 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5861 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5862 tcg_temp_free_i32(tmp2
);
5864 neon_store_reg(rd
, pass
, tmp
);
5867 } else if (op
< 10) {
5868 /* Shift by immediate and narrow:
5869 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5870 int input_unsigned
= (op
== 8) ? !u
: u
;
5874 shift
= shift
- (1 << (size
+ 3));
5877 tmp64
= tcg_const_i64(shift
);
5878 neon_load_reg64(cpu_V0
, rm
);
5879 neon_load_reg64(cpu_V1
, rm
+ 1);
5880 for (pass
= 0; pass
< 2; pass
++) {
5888 if (input_unsigned
) {
5889 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5891 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5894 if (input_unsigned
) {
5895 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5897 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5900 tmp
= tcg_temp_new_i32();
5901 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5902 neon_store_reg(rd
, pass
, tmp
);
5904 tcg_temp_free_i64(tmp64
);
5907 imm
= (uint16_t)shift
;
5911 imm
= (uint32_t)shift
;
5913 tmp2
= tcg_const_i32(imm
);
5914 tmp4
= neon_load_reg(rm
+ 1, 0);
5915 tmp5
= neon_load_reg(rm
+ 1, 1);
5916 for (pass
= 0; pass
< 2; pass
++) {
5918 tmp
= neon_load_reg(rm
, 0);
5922 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5925 tmp3
= neon_load_reg(rm
, 1);
5929 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5931 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5932 tcg_temp_free_i32(tmp
);
5933 tcg_temp_free_i32(tmp3
);
5934 tmp
= tcg_temp_new_i32();
5935 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5936 neon_store_reg(rd
, pass
, tmp
);
5938 tcg_temp_free_i32(tmp2
);
5940 } else if (op
== 10) {
5942 if (q
|| (rd
& 1)) {
5945 tmp
= neon_load_reg(rm
, 0);
5946 tmp2
= neon_load_reg(rm
, 1);
5947 for (pass
= 0; pass
< 2; pass
++) {
5951 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5954 /* The shift is less than the width of the source
5955 type, so we can just shift the whole register. */
5956 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5957 /* Widen the result of shift: we need to clear
5958 * the potential overflow bits resulting from
5959 * left bits of the narrow input appearing as
5960 * right bits of left the neighbour narrow
5962 if (size
< 2 || !u
) {
5965 imm
= (0xffu
>> (8 - shift
));
5967 } else if (size
== 1) {
5968 imm
= 0xffff >> (16 - shift
);
5971 imm
= 0xffffffff >> (32 - shift
);
5974 imm64
= imm
| (((uint64_t)imm
) << 32);
5978 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5981 neon_store_reg64(cpu_V0
, rd
+ pass
);
5983 } else if (op
>= 14) {
5984 /* VCVT fixed-point. */
5985 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5988 /* We have already masked out the must-be-1 top bit of imm6,
5989 * hence this 32-shift where the ARM ARM has 64-imm6.
5992 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5993 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5996 gen_vfp_ulto(0, shift
, 1);
5998 gen_vfp_slto(0, shift
, 1);
6001 gen_vfp_toul(0, shift
, 1);
6003 gen_vfp_tosl(0, shift
, 1);
6005 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6010 } else { /* (insn & 0x00380080) == 0 */
6012 if (q
&& (rd
& 1)) {
6016 op
= (insn
>> 8) & 0xf;
6017 /* One register and immediate. */
6018 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6019 invert
= (insn
& (1 << 5)) != 0;
6020 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6021 * We choose to not special-case this and will behave as if a
6022 * valid constant encoding of 0 had been given.
6041 imm
= (imm
<< 8) | (imm
<< 24);
6044 imm
= (imm
<< 8) | 0xff;
6047 imm
= (imm
<< 16) | 0xffff;
6050 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6058 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6059 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6065 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6066 if (op
& 1 && op
< 12) {
6067 tmp
= neon_load_reg(rd
, pass
);
6069 /* The immediate value has already been inverted, so
6071 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6073 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6077 tmp
= tcg_temp_new_i32();
6078 if (op
== 14 && invert
) {
6082 for (n
= 0; n
< 4; n
++) {
6083 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6084 val
|= 0xff << (n
* 8);
6086 tcg_gen_movi_i32(tmp
, val
);
6088 tcg_gen_movi_i32(tmp
, imm
);
6091 neon_store_reg(rd
, pass
, tmp
);
6094 } else { /* (insn & 0x00800010 == 0x00800000) */
6096 op
= (insn
>> 8) & 0xf;
6097 if ((insn
& (1 << 6)) == 0) {
6098 /* Three registers of different lengths. */
6102 /* undefreq: bit 0 : UNDEF if size == 0
6103 * bit 1 : UNDEF if size == 1
6104 * bit 2 : UNDEF if size == 2
6105 * bit 3 : UNDEF if U == 1
6106 * Note that [2:0] set implies 'always UNDEF'
6109 /* prewiden, src1_wide, src2_wide, undefreq */
6110 static const int neon_3reg_wide
[16][4] = {
6111 {1, 0, 0, 0}, /* VADDL */
6112 {1, 1, 0, 0}, /* VADDW */
6113 {1, 0, 0, 0}, /* VSUBL */
6114 {1, 1, 0, 0}, /* VSUBW */
6115 {0, 1, 1, 0}, /* VADDHN */
6116 {0, 0, 0, 0}, /* VABAL */
6117 {0, 1, 1, 0}, /* VSUBHN */
6118 {0, 0, 0, 0}, /* VABDL */
6119 {0, 0, 0, 0}, /* VMLAL */
6120 {0, 0, 0, 9}, /* VQDMLAL */
6121 {0, 0, 0, 0}, /* VMLSL */
6122 {0, 0, 0, 9}, /* VQDMLSL */
6123 {0, 0, 0, 0}, /* Integer VMULL */
6124 {0, 0, 0, 1}, /* VQDMULL */
6125 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6126 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6129 prewiden
= neon_3reg_wide
[op
][0];
6130 src1_wide
= neon_3reg_wide
[op
][1];
6131 src2_wide
= neon_3reg_wide
[op
][2];
6132 undefreq
= neon_3reg_wide
[op
][3];
6134 if ((undefreq
& (1 << size
)) ||
6135 ((undefreq
& 8) && u
)) {
6138 if ((src1_wide
&& (rn
& 1)) ||
6139 (src2_wide
&& (rm
& 1)) ||
6140 (!src2_wide
&& (rd
& 1))) {
6144 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6145 * outside the loop below as it only performs a single pass.
6147 if (op
== 14 && size
== 2) {
6148 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6150 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6153 tcg_rn
= tcg_temp_new_i64();
6154 tcg_rm
= tcg_temp_new_i64();
6155 tcg_rd
= tcg_temp_new_i64();
6156 neon_load_reg64(tcg_rn
, rn
);
6157 neon_load_reg64(tcg_rm
, rm
);
6158 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6159 neon_store_reg64(tcg_rd
, rd
);
6160 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6161 neon_store_reg64(tcg_rd
, rd
+ 1);
6162 tcg_temp_free_i64(tcg_rn
);
6163 tcg_temp_free_i64(tcg_rm
);
6164 tcg_temp_free_i64(tcg_rd
);
6168 /* Avoid overlapping operands. Wide source operands are
6169 always aligned so will never overlap with wide
6170 destinations in problematic ways. */
6171 if (rd
== rm
&& !src2_wide
) {
6172 tmp
= neon_load_reg(rm
, 1);
6173 neon_store_scratch(2, tmp
);
6174 } else if (rd
== rn
&& !src1_wide
) {
6175 tmp
= neon_load_reg(rn
, 1);
6176 neon_store_scratch(2, tmp
);
6178 TCGV_UNUSED_I32(tmp3
);
6179 for (pass
= 0; pass
< 2; pass
++) {
6181 neon_load_reg64(cpu_V0
, rn
+ pass
);
6182 TCGV_UNUSED_I32(tmp
);
6184 if (pass
== 1 && rd
== rn
) {
6185 tmp
= neon_load_scratch(2);
6187 tmp
= neon_load_reg(rn
, pass
);
6190 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6194 neon_load_reg64(cpu_V1
, rm
+ pass
);
6195 TCGV_UNUSED_I32(tmp2
);
6197 if (pass
== 1 && rd
== rm
) {
6198 tmp2
= neon_load_scratch(2);
6200 tmp2
= neon_load_reg(rm
, pass
);
6203 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6207 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6208 gen_neon_addl(size
);
6210 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6211 gen_neon_subl(size
);
6213 case 5: case 7: /* VABAL, VABDL */
6214 switch ((size
<< 1) | u
) {
6216 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6219 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6222 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6225 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6228 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6231 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6235 tcg_temp_free_i32(tmp2
);
6236 tcg_temp_free_i32(tmp
);
6238 case 8: case 9: case 10: case 11: case 12: case 13:
6239 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6240 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6242 case 14: /* Polynomial VMULL */
6243 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6244 tcg_temp_free_i32(tmp2
);
6245 tcg_temp_free_i32(tmp
);
6247 default: /* 15 is RESERVED: caught earlier */
6252 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6253 neon_store_reg64(cpu_V0
, rd
+ pass
);
6254 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6256 neon_load_reg64(cpu_V1
, rd
+ pass
);
6258 case 10: /* VMLSL */
6259 gen_neon_negl(cpu_V0
, size
);
6261 case 5: case 8: /* VABAL, VMLAL */
6262 gen_neon_addl(size
);
6264 case 9: case 11: /* VQDMLAL, VQDMLSL */
6265 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6267 gen_neon_negl(cpu_V0
, size
);
6269 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6274 neon_store_reg64(cpu_V0
, rd
+ pass
);
6275 } else if (op
== 4 || op
== 6) {
6276 /* Narrowing operation. */
6277 tmp
= tcg_temp_new_i32();
6281 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6284 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6287 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6288 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6295 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6298 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6301 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6302 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6303 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6311 neon_store_reg(rd
, 0, tmp3
);
6312 neon_store_reg(rd
, 1, tmp
);
6315 /* Write back the result. */
6316 neon_store_reg64(cpu_V0
, rd
+ pass
);
6320 /* Two registers and a scalar. NB that for ops of this form
6321 * the ARM ARM labels bit 24 as Q, but it is in our variable
6328 case 1: /* Float VMLA scalar */
6329 case 5: /* Floating point VMLS scalar */
6330 case 9: /* Floating point VMUL scalar */
6335 case 0: /* Integer VMLA scalar */
6336 case 4: /* Integer VMLS scalar */
6337 case 8: /* Integer VMUL scalar */
6338 case 12: /* VQDMULH scalar */
6339 case 13: /* VQRDMULH scalar */
6340 if (u
&& ((rd
| rn
) & 1)) {
6343 tmp
= neon_get_scalar(size
, rm
);
6344 neon_store_scratch(0, tmp
);
6345 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6346 tmp
= neon_load_scratch(0);
6347 tmp2
= neon_load_reg(rn
, pass
);
6350 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6352 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6354 } else if (op
== 13) {
6356 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6358 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6360 } else if (op
& 1) {
6361 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6362 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6363 tcg_temp_free_ptr(fpstatus
);
6366 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6367 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6368 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6372 tcg_temp_free_i32(tmp2
);
6375 tmp2
= neon_load_reg(rd
, pass
);
6378 gen_neon_add(size
, tmp
, tmp2
);
6382 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6383 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6384 tcg_temp_free_ptr(fpstatus
);
6388 gen_neon_rsb(size
, tmp
, tmp2
);
6392 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6393 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6394 tcg_temp_free_ptr(fpstatus
);
6400 tcg_temp_free_i32(tmp2
);
6402 neon_store_reg(rd
, pass
, tmp
);
6405 case 3: /* VQDMLAL scalar */
6406 case 7: /* VQDMLSL scalar */
6407 case 11: /* VQDMULL scalar */
6412 case 2: /* VMLAL sclar */
6413 case 6: /* VMLSL scalar */
6414 case 10: /* VMULL scalar */
6418 tmp2
= neon_get_scalar(size
, rm
);
6419 /* We need a copy of tmp2 because gen_neon_mull
6420 * deletes it during pass 0. */
6421 tmp4
= tcg_temp_new_i32();
6422 tcg_gen_mov_i32(tmp4
, tmp2
);
6423 tmp3
= neon_load_reg(rn
, 1);
6425 for (pass
= 0; pass
< 2; pass
++) {
6427 tmp
= neon_load_reg(rn
, 0);
6432 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6434 neon_load_reg64(cpu_V1
, rd
+ pass
);
6438 gen_neon_negl(cpu_V0
, size
);
6441 gen_neon_addl(size
);
6444 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6446 gen_neon_negl(cpu_V0
, size
);
6448 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6454 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6459 neon_store_reg64(cpu_V0
, rd
+ pass
);
6464 default: /* 14 and 15 are RESERVED */
6468 } else { /* size == 3 */
6471 imm
= (insn
>> 8) & 0xf;
6476 if (q
&& ((rd
| rn
| rm
) & 1)) {
6481 neon_load_reg64(cpu_V0
, rn
);
6483 neon_load_reg64(cpu_V1
, rn
+ 1);
6485 } else if (imm
== 8) {
6486 neon_load_reg64(cpu_V0
, rn
+ 1);
6488 neon_load_reg64(cpu_V1
, rm
);
6491 tmp64
= tcg_temp_new_i64();
6493 neon_load_reg64(cpu_V0
, rn
);
6494 neon_load_reg64(tmp64
, rn
+ 1);
6496 neon_load_reg64(cpu_V0
, rn
+ 1);
6497 neon_load_reg64(tmp64
, rm
);
6499 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6500 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6501 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6503 neon_load_reg64(cpu_V1
, rm
);
6505 neon_load_reg64(cpu_V1
, rm
+ 1);
6508 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6509 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6510 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6511 tcg_temp_free_i64(tmp64
);
6514 neon_load_reg64(cpu_V0
, rn
);
6515 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6516 neon_load_reg64(cpu_V1
, rm
);
6517 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6518 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6520 neon_store_reg64(cpu_V0
, rd
);
6522 neon_store_reg64(cpu_V1
, rd
+ 1);
6524 } else if ((insn
& (1 << 11)) == 0) {
6525 /* Two register misc. */
6526 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6527 size
= (insn
>> 18) & 3;
6528 /* UNDEF for unknown op values and bad op-size combinations */
6529 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6532 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6533 q
&& ((rm
| rd
) & 1)) {
6537 case NEON_2RM_VREV64
:
6538 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6539 tmp
= neon_load_reg(rm
, pass
* 2);
6540 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6542 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6543 case 1: gen_swap_half(tmp
); break;
6544 case 2: /* no-op */ break;
6547 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6549 neon_store_reg(rd
, pass
* 2, tmp2
);
6552 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6553 case 1: gen_swap_half(tmp2
); break;
6556 neon_store_reg(rd
, pass
* 2, tmp2
);
6560 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6561 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6562 for (pass
= 0; pass
< q
+ 1; pass
++) {
6563 tmp
= neon_load_reg(rm
, pass
* 2);
6564 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6565 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6566 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6568 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6569 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6570 case 2: tcg_gen_add_i64(CPU_V001
); break;
6573 if (op
>= NEON_2RM_VPADAL
) {
6575 neon_load_reg64(cpu_V1
, rd
+ pass
);
6576 gen_neon_addl(size
);
6578 neon_store_reg64(cpu_V0
, rd
+ pass
);
6584 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6585 tmp
= neon_load_reg(rm
, n
);
6586 tmp2
= neon_load_reg(rd
, n
+ 1);
6587 neon_store_reg(rm
, n
, tmp2
);
6588 neon_store_reg(rd
, n
+ 1, tmp
);
6595 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6600 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6604 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6605 /* also VQMOVUN; op field and mnemonics don't line up */
6609 TCGV_UNUSED_I32(tmp2
);
6610 for (pass
= 0; pass
< 2; pass
++) {
6611 neon_load_reg64(cpu_V0
, rm
+ pass
);
6612 tmp
= tcg_temp_new_i32();
6613 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6618 neon_store_reg(rd
, 0, tmp2
);
6619 neon_store_reg(rd
, 1, tmp
);
6623 case NEON_2RM_VSHLL
:
6624 if (q
|| (rd
& 1)) {
6627 tmp
= neon_load_reg(rm
, 0);
6628 tmp2
= neon_load_reg(rm
, 1);
6629 for (pass
= 0; pass
< 2; pass
++) {
6632 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6633 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6634 neon_store_reg64(cpu_V0
, rd
+ pass
);
6637 case NEON_2RM_VCVT_F16_F32
:
6638 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6642 tmp
= tcg_temp_new_i32();
6643 tmp2
= tcg_temp_new_i32();
6644 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6645 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6646 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6647 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6648 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6649 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6650 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6651 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6652 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6653 neon_store_reg(rd
, 0, tmp2
);
6654 tmp2
= tcg_temp_new_i32();
6655 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6656 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6657 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6658 neon_store_reg(rd
, 1, tmp2
);
6659 tcg_temp_free_i32(tmp
);
6661 case NEON_2RM_VCVT_F32_F16
:
6662 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6666 tmp3
= tcg_temp_new_i32();
6667 tmp
= neon_load_reg(rm
, 0);
6668 tmp2
= neon_load_reg(rm
, 1);
6669 tcg_gen_ext16u_i32(tmp3
, tmp
);
6670 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6671 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6672 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6673 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6674 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6675 tcg_temp_free_i32(tmp
);
6676 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6677 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6678 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6679 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6680 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6681 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6682 tcg_temp_free_i32(tmp2
);
6683 tcg_temp_free_i32(tmp3
);
6685 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6686 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6687 || ((rm
| rd
) & 1)) {
6690 tmp
= tcg_const_i32(rd
);
6691 tmp2
= tcg_const_i32(rm
);
6693 /* Bit 6 is the lowest opcode bit; it distinguishes between
6694 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6696 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6698 if (op
== NEON_2RM_AESE
) {
6699 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6701 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6703 tcg_temp_free_i32(tmp
);
6704 tcg_temp_free_i32(tmp2
);
6705 tcg_temp_free_i32(tmp3
);
6707 case NEON_2RM_SHA1H
:
6708 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
6709 || ((rm
| rd
) & 1)) {
6712 tmp
= tcg_const_i32(rd
);
6713 tmp2
= tcg_const_i32(rm
);
6715 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6717 tcg_temp_free_i32(tmp
);
6718 tcg_temp_free_i32(tmp2
);
6720 case NEON_2RM_SHA1SU1
:
6721 if ((rm
| rd
) & 1) {
6724 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6726 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
6729 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
6732 tmp
= tcg_const_i32(rd
);
6733 tmp2
= tcg_const_i32(rm
);
6735 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6737 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6739 tcg_temp_free_i32(tmp
);
6740 tcg_temp_free_i32(tmp2
);
6744 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6745 if (neon_2rm_is_float_op(op
)) {
6746 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6747 neon_reg_offset(rm
, pass
));
6748 TCGV_UNUSED_I32(tmp
);
6750 tmp
= neon_load_reg(rm
, pass
);
6753 case NEON_2RM_VREV32
:
6755 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6756 case 1: gen_swap_half(tmp
); break;
6760 case NEON_2RM_VREV16
:
6765 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6766 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6767 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6773 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6774 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6775 case 2: gen_helper_clz(tmp
, tmp
); break;
6780 gen_helper_neon_cnt_u8(tmp
, tmp
);
6783 tcg_gen_not_i32(tmp
, tmp
);
6785 case NEON_2RM_VQABS
:
6788 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6791 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6794 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6799 case NEON_2RM_VQNEG
:
6802 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6805 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6808 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6813 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6814 tmp2
= tcg_const_i32(0);
6816 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6817 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6818 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6821 tcg_temp_free_i32(tmp2
);
6822 if (op
== NEON_2RM_VCLE0
) {
6823 tcg_gen_not_i32(tmp
, tmp
);
6826 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6827 tmp2
= tcg_const_i32(0);
6829 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6830 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6831 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6834 tcg_temp_free_i32(tmp2
);
6835 if (op
== NEON_2RM_VCLT0
) {
6836 tcg_gen_not_i32(tmp
, tmp
);
6839 case NEON_2RM_VCEQ0
:
6840 tmp2
= tcg_const_i32(0);
6842 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6843 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6844 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6847 tcg_temp_free_i32(tmp2
);
6851 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6852 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6853 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6858 tmp2
= tcg_const_i32(0);
6859 gen_neon_rsb(size
, tmp
, tmp2
);
6860 tcg_temp_free_i32(tmp2
);
6862 case NEON_2RM_VCGT0_F
:
6864 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6865 tmp2
= tcg_const_i32(0);
6866 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6867 tcg_temp_free_i32(tmp2
);
6868 tcg_temp_free_ptr(fpstatus
);
6871 case NEON_2RM_VCGE0_F
:
6873 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6874 tmp2
= tcg_const_i32(0);
6875 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6876 tcg_temp_free_i32(tmp2
);
6877 tcg_temp_free_ptr(fpstatus
);
6880 case NEON_2RM_VCEQ0_F
:
6882 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6883 tmp2
= tcg_const_i32(0);
6884 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6885 tcg_temp_free_i32(tmp2
);
6886 tcg_temp_free_ptr(fpstatus
);
6889 case NEON_2RM_VCLE0_F
:
6891 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6892 tmp2
= tcg_const_i32(0);
6893 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6894 tcg_temp_free_i32(tmp2
);
6895 tcg_temp_free_ptr(fpstatus
);
6898 case NEON_2RM_VCLT0_F
:
6900 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6901 tmp2
= tcg_const_i32(0);
6902 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6903 tcg_temp_free_i32(tmp2
);
6904 tcg_temp_free_ptr(fpstatus
);
6907 case NEON_2RM_VABS_F
:
6910 case NEON_2RM_VNEG_F
:
6914 tmp2
= neon_load_reg(rd
, pass
);
6915 neon_store_reg(rm
, pass
, tmp2
);
6918 tmp2
= neon_load_reg(rd
, pass
);
6920 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6921 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6924 neon_store_reg(rm
, pass
, tmp2
);
6926 case NEON_2RM_VRINTN
:
6927 case NEON_2RM_VRINTA
:
6928 case NEON_2RM_VRINTM
:
6929 case NEON_2RM_VRINTP
:
6930 case NEON_2RM_VRINTZ
:
6933 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6936 if (op
== NEON_2RM_VRINTZ
) {
6937 rmode
= FPROUNDING_ZERO
;
6939 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6942 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6943 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6945 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6946 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6948 tcg_temp_free_ptr(fpstatus
);
6949 tcg_temp_free_i32(tcg_rmode
);
6952 case NEON_2RM_VRINTX
:
6954 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6955 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6956 tcg_temp_free_ptr(fpstatus
);
6959 case NEON_2RM_VCVTAU
:
6960 case NEON_2RM_VCVTAS
:
6961 case NEON_2RM_VCVTNU
:
6962 case NEON_2RM_VCVTNS
:
6963 case NEON_2RM_VCVTPU
:
6964 case NEON_2RM_VCVTPS
:
6965 case NEON_2RM_VCVTMU
:
6966 case NEON_2RM_VCVTMS
:
6968 bool is_signed
= !extract32(insn
, 7, 1);
6969 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6970 TCGv_i32 tcg_rmode
, tcg_shift
;
6971 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6973 tcg_shift
= tcg_const_i32(0);
6974 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6975 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6979 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6982 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6986 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6988 tcg_temp_free_i32(tcg_rmode
);
6989 tcg_temp_free_i32(tcg_shift
);
6990 tcg_temp_free_ptr(fpst
);
6993 case NEON_2RM_VRECPE
:
6995 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6996 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6997 tcg_temp_free_ptr(fpstatus
);
7000 case NEON_2RM_VRSQRTE
:
7002 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7003 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7004 tcg_temp_free_ptr(fpstatus
);
7007 case NEON_2RM_VRECPE_F
:
7009 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7010 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7011 tcg_temp_free_ptr(fpstatus
);
7014 case NEON_2RM_VRSQRTE_F
:
7016 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7017 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7018 tcg_temp_free_ptr(fpstatus
);
7021 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7024 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7027 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7028 gen_vfp_tosiz(0, 1);
7030 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7031 gen_vfp_touiz(0, 1);
7034 /* Reserved op values were caught by the
7035 * neon_2rm_sizes[] check earlier.
7039 if (neon_2rm_is_float_op(op
)) {
7040 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7041 neon_reg_offset(rd
, pass
));
7043 neon_store_reg(rd
, pass
, tmp
);
7048 } else if ((insn
& (1 << 10)) == 0) {
7050 int n
= ((insn
>> 8) & 3) + 1;
7051 if ((rn
+ n
) > 32) {
7052 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7053 * helper function running off the end of the register file.
7058 if (insn
& (1 << 6)) {
7059 tmp
= neon_load_reg(rd
, 0);
7061 tmp
= tcg_temp_new_i32();
7062 tcg_gen_movi_i32(tmp
, 0);
7064 tmp2
= neon_load_reg(rm
, 0);
7065 tmp4
= tcg_const_i32(rn
);
7066 tmp5
= tcg_const_i32(n
);
7067 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7068 tcg_temp_free_i32(tmp
);
7069 if (insn
& (1 << 6)) {
7070 tmp
= neon_load_reg(rd
, 1);
7072 tmp
= tcg_temp_new_i32();
7073 tcg_gen_movi_i32(tmp
, 0);
7075 tmp3
= neon_load_reg(rm
, 1);
7076 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7077 tcg_temp_free_i32(tmp5
);
7078 tcg_temp_free_i32(tmp4
);
7079 neon_store_reg(rd
, 0, tmp2
);
7080 neon_store_reg(rd
, 1, tmp3
);
7081 tcg_temp_free_i32(tmp
);
7082 } else if ((insn
& 0x380) == 0) {
7084 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7087 if (insn
& (1 << 19)) {
7088 tmp
= neon_load_reg(rm
, 1);
7090 tmp
= neon_load_reg(rm
, 0);
7092 if (insn
& (1 << 16)) {
7093 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7094 } else if (insn
& (1 << 17)) {
7095 if ((insn
>> 18) & 1)
7096 gen_neon_dup_high16(tmp
);
7098 gen_neon_dup_low16(tmp
);
7100 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7101 tmp2
= tcg_temp_new_i32();
7102 tcg_gen_mov_i32(tmp2
, tmp
);
7103 neon_store_reg(rd
, pass
, tmp2
);
7105 tcg_temp_free_i32(tmp
);
7114 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7116 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7117 const ARMCPRegInfo
*ri
;
7119 cpnum
= (insn
>> 8) & 0xf;
7121 /* First check for coprocessor space used for XScale/iwMMXt insns */
7122 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7123 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7126 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7127 return disas_iwmmxt_insn(s
, insn
);
7128 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7129 return disas_dsp_insn(s
, insn
);
7134 /* Otherwise treat as a generic register access */
7135 is64
= (insn
& (1 << 25)) == 0;
7136 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7144 opc1
= (insn
>> 4) & 0xf;
7146 rt2
= (insn
>> 16) & 0xf;
7148 crn
= (insn
>> 16) & 0xf;
7149 opc1
= (insn
>> 21) & 7;
7150 opc2
= (insn
>> 5) & 7;
7153 isread
= (insn
>> 20) & 1;
7154 rt
= (insn
>> 12) & 0xf;
7156 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7157 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7159 /* Check access permissions */
7160 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7165 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7166 /* Emit code to perform further access permissions checks at
7167 * runtime; this may result in an exception.
7168 * Note that on XScale all cp0..c13 registers do an access check
7169 * call in order to handle c15_cpar.
7172 TCGv_i32 tcg_syn
, tcg_isread
;
7175 /* Note that since we are an implementation which takes an
7176 * exception on a trapped conditional instruction only if the
7177 * instruction passes its condition code check, we can take
7178 * advantage of the clause in the ARM ARM that allows us to set
7179 * the COND field in the instruction to 0xE in all cases.
7180 * We could fish the actual condition out of the insn (ARM)
7181 * or the condexec bits (Thumb) but it isn't necessary.
7186 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7189 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7195 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7198 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7203 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7204 * so this can only happen if this is an ARMv7 or earlier CPU,
7205 * in which case the syndrome information won't actually be
7208 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7209 syndrome
= syn_uncategorized();
7213 gen_set_condexec(s
);
7214 gen_set_pc_im(s
, s
->pc
- 4);
7215 tmpptr
= tcg_const_ptr(ri
);
7216 tcg_syn
= tcg_const_i32(syndrome
);
7217 tcg_isread
= tcg_const_i32(isread
);
7218 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7220 tcg_temp_free_ptr(tmpptr
);
7221 tcg_temp_free_i32(tcg_syn
);
7222 tcg_temp_free_i32(tcg_isread
);
7225 /* Handle special cases first */
7226 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7233 gen_set_pc_im(s
, s
->pc
);
7234 s
->is_jmp
= DISAS_WFI
;
7240 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7249 if (ri
->type
& ARM_CP_CONST
) {
7250 tmp64
= tcg_const_i64(ri
->resetvalue
);
7251 } else if (ri
->readfn
) {
7253 tmp64
= tcg_temp_new_i64();
7254 tmpptr
= tcg_const_ptr(ri
);
7255 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7256 tcg_temp_free_ptr(tmpptr
);
7258 tmp64
= tcg_temp_new_i64();
7259 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7261 tmp
= tcg_temp_new_i32();
7262 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7263 store_reg(s
, rt
, tmp
);
7264 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7265 tmp
= tcg_temp_new_i32();
7266 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7267 tcg_temp_free_i64(tmp64
);
7268 store_reg(s
, rt2
, tmp
);
7271 if (ri
->type
& ARM_CP_CONST
) {
7272 tmp
= tcg_const_i32(ri
->resetvalue
);
7273 } else if (ri
->readfn
) {
7275 tmp
= tcg_temp_new_i32();
7276 tmpptr
= tcg_const_ptr(ri
);
7277 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7278 tcg_temp_free_ptr(tmpptr
);
7280 tmp
= load_cpu_offset(ri
->fieldoffset
);
7283 /* Destination register of r15 for 32 bit loads sets
7284 * the condition codes from the high 4 bits of the value
7287 tcg_temp_free_i32(tmp
);
7289 store_reg(s
, rt
, tmp
);
7294 if (ri
->type
& ARM_CP_CONST
) {
7295 /* If not forbidden by access permissions, treat as WI */
7300 TCGv_i32 tmplo
, tmphi
;
7301 TCGv_i64 tmp64
= tcg_temp_new_i64();
7302 tmplo
= load_reg(s
, rt
);
7303 tmphi
= load_reg(s
, rt2
);
7304 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7305 tcg_temp_free_i32(tmplo
);
7306 tcg_temp_free_i32(tmphi
);
7308 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7309 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7310 tcg_temp_free_ptr(tmpptr
);
7312 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7314 tcg_temp_free_i64(tmp64
);
7319 tmp
= load_reg(s
, rt
);
7320 tmpptr
= tcg_const_ptr(ri
);
7321 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7322 tcg_temp_free_ptr(tmpptr
);
7323 tcg_temp_free_i32(tmp
);
7325 TCGv_i32 tmp
= load_reg(s
, rt
);
7326 store_cpu_offset(tmp
, ri
->fieldoffset
);
7331 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7332 /* I/O operations must end the TB here (whether read or write) */
7335 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7336 /* We default to ending the TB on a coprocessor register write,
7337 * but allow this to be suppressed by the register definition
7338 * (usually only necessary to work around guest bugs).
7346 /* Unknown register; this might be a guest error or a QEMU
7347 * unimplemented feature.
7350 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7351 "64 bit system register cp:%d opc1: %d crm:%d "
7353 isread
? "read" : "write", cpnum
, opc1
, crm
,
7354 s
->ns
? "non-secure" : "secure");
7356 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7357 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7359 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7360 s
->ns
? "non-secure" : "secure");
7367 /* Store a 64-bit value to a register pair. Clobbers val. */
7368 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7371 tmp
= tcg_temp_new_i32();
7372 tcg_gen_extrl_i64_i32(tmp
, val
);
7373 store_reg(s
, rlow
, tmp
);
7374 tmp
= tcg_temp_new_i32();
7375 tcg_gen_shri_i64(val
, val
, 32);
7376 tcg_gen_extrl_i64_i32(tmp
, val
);
7377 store_reg(s
, rhigh
, tmp
);
7380 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7381 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7386 /* Load value and extend to 64 bits. */
7387 tmp
= tcg_temp_new_i64();
7388 tmp2
= load_reg(s
, rlow
);
7389 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7390 tcg_temp_free_i32(tmp2
);
7391 tcg_gen_add_i64(val
, val
, tmp
);
7392 tcg_temp_free_i64(tmp
);
7395 /* load and add a 64-bit value from a register pair. */
7396 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7402 /* Load 64-bit value rd:rn. */
7403 tmpl
= load_reg(s
, rlow
);
7404 tmph
= load_reg(s
, rhigh
);
7405 tmp
= tcg_temp_new_i64();
7406 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7407 tcg_temp_free_i32(tmpl
);
7408 tcg_temp_free_i32(tmph
);
7409 tcg_gen_add_i64(val
, val
, tmp
);
7410 tcg_temp_free_i64(tmp
);
7413 /* Set N and Z flags from hi|lo. */
7414 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7416 tcg_gen_mov_i32(cpu_NF
, hi
);
7417 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7420 /* Load/Store exclusive instructions are implemented by remembering
7421 the value/address loaded, and seeing if these are the same
7422 when the store is performed. This should be sufficient to implement
7423 the architecturally mandated semantics, and avoids having to monitor
7426 In system emulation mode only one CPU will be running at once, so
7427 this sequence is effectively atomic. In user emulation mode we
7428 throw an exception and handle the atomic operation elsewhere. */
7429 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7430 TCGv_i32 addr
, int size
)
7432 TCGv_i32 tmp
= tcg_temp_new_i32();
7438 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7441 gen_aa32_ld16ua(tmp
, addr
, get_mem_index(s
));
7445 gen_aa32_ld32ua(tmp
, addr
, get_mem_index(s
));
7452 TCGv_i32 tmp2
= tcg_temp_new_i32();
7453 TCGv_i32 tmp3
= tcg_temp_new_i32();
7455 tcg_gen_addi_i32(tmp2
, addr
, 4);
7456 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7457 tcg_temp_free_i32(tmp2
);
7458 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7459 store_reg(s
, rt2
, tmp3
);
7461 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7464 store_reg(s
, rt
, tmp
);
7465 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7468 static void gen_clrex(DisasContext
*s
)
7470 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7473 #ifdef CONFIG_USER_ONLY
7474 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7475 TCGv_i32 addr
, int size
)
7477 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7478 tcg_gen_movi_i32(cpu_exclusive_info
,
7479 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7480 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7483 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7484 TCGv_i32 addr
, int size
)
7487 TCGv_i64 val64
, extaddr
;
7488 TCGLabel
*done_label
;
7489 TCGLabel
*fail_label
;
7491 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7497 fail_label
= gen_new_label();
7498 done_label
= gen_new_label();
7499 extaddr
= tcg_temp_new_i64();
7500 tcg_gen_extu_i32_i64(extaddr
, addr
);
7501 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7502 tcg_temp_free_i64(extaddr
);
7504 tmp
= tcg_temp_new_i32();
7507 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7510 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7514 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7520 val64
= tcg_temp_new_i64();
7522 TCGv_i32 tmp2
= tcg_temp_new_i32();
7523 TCGv_i32 tmp3
= tcg_temp_new_i32();
7524 tcg_gen_addi_i32(tmp2
, addr
, 4);
7525 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7526 tcg_temp_free_i32(tmp2
);
7527 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7528 tcg_temp_free_i32(tmp3
);
7530 tcg_gen_extu_i32_i64(val64
, tmp
);
7532 tcg_temp_free_i32(tmp
);
7534 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7535 tcg_temp_free_i64(val64
);
7537 tmp
= load_reg(s
, rt
);
7540 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7543 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7547 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7552 tcg_temp_free_i32(tmp
);
7554 tcg_gen_addi_i32(addr
, addr
, 4);
7555 tmp
= load_reg(s
, rt2
);
7556 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7557 tcg_temp_free_i32(tmp
);
7559 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7560 tcg_gen_br(done_label
);
7561 gen_set_label(fail_label
);
7562 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7563 gen_set_label(done_label
);
7564 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7571 * @mode: mode field from insn (which stack to store to)
7572 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7573 * @writeback: true if writeback bit set
7575 * Generate code for the SRS (Store Return State) insn.
7577 static void gen_srs(DisasContext
*s
,
7578 uint32_t mode
, uint32_t amode
, bool writeback
)
7585 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7586 * - UNDEFINED in Hyp mode
7587 * - UNPREDICTABLE in User or System mode
7588 * - UNPREDICTABLE if the specified mode is:
7589 * -- not implemented
7590 * -- not a valid mode number
7591 * -- a mode that's at a higher exception level
7592 * -- Monitor, if we are Non-secure
7593 * For the UNPREDICTABLE cases we choose to UNDEF.
7595 if (s
->current_el
== 1 && !s
->ns
) {
7596 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7600 if (s
->current_el
== 0 || s
->current_el
== 2) {
7605 case ARM_CPU_MODE_USR
:
7606 case ARM_CPU_MODE_FIQ
:
7607 case ARM_CPU_MODE_IRQ
:
7608 case ARM_CPU_MODE_SVC
:
7609 case ARM_CPU_MODE_ABT
:
7610 case ARM_CPU_MODE_UND
:
7611 case ARM_CPU_MODE_SYS
:
7613 case ARM_CPU_MODE_HYP
:
7614 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7618 case ARM_CPU_MODE_MON
:
7619 /* No need to check specifically for "are we non-secure" because
7620 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7621 * so if this isn't EL3 then we must be non-secure.
7623 if (s
->current_el
!= 3) {
7632 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
7633 default_exception_el(s
));
7637 addr
= tcg_temp_new_i32();
7638 tmp
= tcg_const_i32(mode
);
7639 /* get_r13_banked() will raise an exception if called from System mode */
7640 gen_set_condexec(s
);
7641 gen_set_pc_im(s
, s
->pc
- 4);
7642 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7643 tcg_temp_free_i32(tmp
);
7660 tcg_gen_addi_i32(addr
, addr
, offset
);
7661 tmp
= load_reg(s
, 14);
7662 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7663 tcg_temp_free_i32(tmp
);
7664 tmp
= load_cpu_field(spsr
);
7665 tcg_gen_addi_i32(addr
, addr
, 4);
7666 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7667 tcg_temp_free_i32(tmp
);
7685 tcg_gen_addi_i32(addr
, addr
, offset
);
7686 tmp
= tcg_const_i32(mode
);
7687 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7688 tcg_temp_free_i32(tmp
);
7690 tcg_temp_free_i32(addr
);
7691 s
->is_jmp
= DISAS_UPDATE
;
7694 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7696 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7703 /* M variants do not implement ARM mode. */
7704 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7709 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7710 * choose to UNDEF. In ARMv5 and above the space is used
7711 * for miscellaneous unconditional instructions.
7715 /* Unconditional instructions. */
7716 if (((insn
>> 25) & 7) == 1) {
7717 /* NEON Data processing. */
7718 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7722 if (disas_neon_data_insn(s
, insn
)) {
7727 if ((insn
& 0x0f100000) == 0x04000000) {
7728 /* NEON load/store. */
7729 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7733 if (disas_neon_ls_insn(s
, insn
)) {
7738 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7740 if (disas_vfp_insn(s
, insn
)) {
7745 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7746 ((insn
& 0x0f30f010) == 0x0710f000)) {
7747 if ((insn
& (1 << 22)) == 0) {
7749 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7753 /* Otherwise PLD; v5TE+ */
7757 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7758 ((insn
& 0x0f70f010) == 0x0650f000)) {
7760 return; /* PLI; V7 */
7762 if (((insn
& 0x0f700000) == 0x04100000) ||
7763 ((insn
& 0x0f700010) == 0x06100000)) {
7764 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7767 return; /* v7MP: Unallocated memory hint: must NOP */
7770 if ((insn
& 0x0ffffdff) == 0x01010000) {
7773 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7774 /* Dynamic endianness switching not implemented. */
7775 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7779 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7780 switch ((insn
>> 4) & 0xf) {
7788 /* We don't emulate caches so these are a no-op. */
7791 /* We need to break the TB after this insn to execute
7792 * self-modifying code correctly and also to take
7793 * any pending interrupts immediately.
7800 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7803 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7805 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7811 rn
= (insn
>> 16) & 0xf;
7812 addr
= load_reg(s
, rn
);
7813 i
= (insn
>> 23) & 3;
7815 case 0: offset
= -4; break; /* DA */
7816 case 1: offset
= 0; break; /* IA */
7817 case 2: offset
= -8; break; /* DB */
7818 case 3: offset
= 4; break; /* IB */
7822 tcg_gen_addi_i32(addr
, addr
, offset
);
7823 /* Load PC into tmp and CPSR into tmp2. */
7824 tmp
= tcg_temp_new_i32();
7825 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7826 tcg_gen_addi_i32(addr
, addr
, 4);
7827 tmp2
= tcg_temp_new_i32();
7828 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7829 if (insn
& (1 << 21)) {
7830 /* Base writeback. */
7832 case 0: offset
= -8; break;
7833 case 1: offset
= 4; break;
7834 case 2: offset
= -4; break;
7835 case 3: offset
= 0; break;
7839 tcg_gen_addi_i32(addr
, addr
, offset
);
7840 store_reg(s
, rn
, addr
);
7842 tcg_temp_free_i32(addr
);
7844 gen_rfe(s
, tmp
, tmp2
);
7846 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7847 /* branch link and change to thumb (blx <offset>) */
7850 val
= (uint32_t)s
->pc
;
7851 tmp
= tcg_temp_new_i32();
7852 tcg_gen_movi_i32(tmp
, val
);
7853 store_reg(s
, 14, tmp
);
7854 /* Sign-extend the 24-bit offset */
7855 offset
= (((int32_t)insn
) << 8) >> 8;
7856 /* offset * 4 + bit24 * 2 + (thumb bit) */
7857 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7858 /* pipeline offset */
7860 /* protected by ARCH(5); above, near the start of uncond block */
7863 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7864 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7865 /* iWMMXt register transfer. */
7866 if (extract32(s
->c15_cpar
, 1, 1)) {
7867 if (!disas_iwmmxt_insn(s
, insn
)) {
7872 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7873 /* Coprocessor double register transfer. */
7875 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7876 /* Additional coprocessor register transfer. */
7877 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7880 /* cps (privileged) */
7884 if (insn
& (1 << 19)) {
7885 if (insn
& (1 << 8))
7887 if (insn
& (1 << 7))
7889 if (insn
& (1 << 6))
7891 if (insn
& (1 << 18))
7894 if (insn
& (1 << 17)) {
7896 val
|= (insn
& 0x1f);
7899 gen_set_psr_im(s
, mask
, 0, val
);
7906 /* if not always execute, we generate a conditional jump to
7908 s
->condlabel
= gen_new_label();
7909 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7912 if ((insn
& 0x0f900000) == 0x03000000) {
7913 if ((insn
& (1 << 21)) == 0) {
7915 rd
= (insn
>> 12) & 0xf;
7916 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7917 if ((insn
& (1 << 22)) == 0) {
7919 tmp
= tcg_temp_new_i32();
7920 tcg_gen_movi_i32(tmp
, val
);
7923 tmp
= load_reg(s
, rd
);
7924 tcg_gen_ext16u_i32(tmp
, tmp
);
7925 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7927 store_reg(s
, rd
, tmp
);
7929 if (((insn
>> 12) & 0xf) != 0xf)
7931 if (((insn
>> 16) & 0xf) == 0) {
7932 gen_nop_hint(s
, insn
& 0xff);
7934 /* CPSR = immediate */
7936 shift
= ((insn
>> 8) & 0xf) * 2;
7938 val
= (val
>> shift
) | (val
<< (32 - shift
));
7939 i
= ((insn
& (1 << 22)) != 0);
7940 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
7946 } else if ((insn
& 0x0f900000) == 0x01000000
7947 && (insn
& 0x00000090) != 0x00000090) {
7948 /* miscellaneous instructions */
7949 op1
= (insn
>> 21) & 3;
7950 sh
= (insn
>> 4) & 0xf;
7953 case 0x0: /* move program status register */
7956 tmp
= load_reg(s
, rm
);
7957 i
= ((op1
& 2) != 0);
7958 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7962 rd
= (insn
>> 12) & 0xf;
7966 tmp
= load_cpu_field(spsr
);
7968 tmp
= tcg_temp_new_i32();
7969 gen_helper_cpsr_read(tmp
, cpu_env
);
7971 store_reg(s
, rd
, tmp
);
7976 /* branch/exchange thumb (bx). */
7978 tmp
= load_reg(s
, rm
);
7980 } else if (op1
== 3) {
7983 rd
= (insn
>> 12) & 0xf;
7984 tmp
= load_reg(s
, rm
);
7985 gen_helper_clz(tmp
, tmp
);
7986 store_reg(s
, rd
, tmp
);
7994 /* Trivial implementation equivalent to bx. */
7995 tmp
= load_reg(s
, rm
);
8006 /* branch link/exchange thumb (blx) */
8007 tmp
= load_reg(s
, rm
);
8008 tmp2
= tcg_temp_new_i32();
8009 tcg_gen_movi_i32(tmp2
, s
->pc
);
8010 store_reg(s
, 14, tmp2
);
8016 uint32_t c
= extract32(insn
, 8, 4);
8018 /* Check this CPU supports ARMv8 CRC instructions.
8019 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8020 * Bits 8, 10 and 11 should be zero.
8022 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
8027 rn
= extract32(insn
, 16, 4);
8028 rd
= extract32(insn
, 12, 4);
8030 tmp
= load_reg(s
, rn
);
8031 tmp2
= load_reg(s
, rm
);
8033 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8034 } else if (op1
== 1) {
8035 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8037 tmp3
= tcg_const_i32(1 << op1
);
8039 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8041 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8043 tcg_temp_free_i32(tmp2
);
8044 tcg_temp_free_i32(tmp3
);
8045 store_reg(s
, rd
, tmp
);
8048 case 0x5: /* saturating add/subtract */
8050 rd
= (insn
>> 12) & 0xf;
8051 rn
= (insn
>> 16) & 0xf;
8052 tmp
= load_reg(s
, rm
);
8053 tmp2
= load_reg(s
, rn
);
8055 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8057 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8059 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8060 tcg_temp_free_i32(tmp2
);
8061 store_reg(s
, rd
, tmp
);
8065 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8070 gen_exception_insn(s
, 4, EXCP_BKPT
,
8071 syn_aa32_bkpt(imm16
, false),
8072 default_exception_el(s
));
8075 /* Hypervisor call (v7) */
8083 /* Secure monitor call (v6+) */
8095 case 0x8: /* signed multiply */
8100 rs
= (insn
>> 8) & 0xf;
8101 rn
= (insn
>> 12) & 0xf;
8102 rd
= (insn
>> 16) & 0xf;
8104 /* (32 * 16) >> 16 */
8105 tmp
= load_reg(s
, rm
);
8106 tmp2
= load_reg(s
, rs
);
8108 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8111 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8112 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8113 tmp
= tcg_temp_new_i32();
8114 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8115 tcg_temp_free_i64(tmp64
);
8116 if ((sh
& 2) == 0) {
8117 tmp2
= load_reg(s
, rn
);
8118 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8119 tcg_temp_free_i32(tmp2
);
8121 store_reg(s
, rd
, tmp
);
8124 tmp
= load_reg(s
, rm
);
8125 tmp2
= load_reg(s
, rs
);
8126 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8127 tcg_temp_free_i32(tmp2
);
8129 tmp64
= tcg_temp_new_i64();
8130 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8131 tcg_temp_free_i32(tmp
);
8132 gen_addq(s
, tmp64
, rn
, rd
);
8133 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8134 tcg_temp_free_i64(tmp64
);
8137 tmp2
= load_reg(s
, rn
);
8138 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8139 tcg_temp_free_i32(tmp2
);
8141 store_reg(s
, rd
, tmp
);
8148 } else if (((insn
& 0x0e000000) == 0 &&
8149 (insn
& 0x00000090) != 0x90) ||
8150 ((insn
& 0x0e000000) == (1 << 25))) {
8151 int set_cc
, logic_cc
, shiftop
;
8153 op1
= (insn
>> 21) & 0xf;
8154 set_cc
= (insn
>> 20) & 1;
8155 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8157 /* data processing instruction */
8158 if (insn
& (1 << 25)) {
8159 /* immediate operand */
8161 shift
= ((insn
>> 8) & 0xf) * 2;
8163 val
= (val
>> shift
) | (val
<< (32 - shift
));
8165 tmp2
= tcg_temp_new_i32();
8166 tcg_gen_movi_i32(tmp2
, val
);
8167 if (logic_cc
&& shift
) {
8168 gen_set_CF_bit31(tmp2
);
8173 tmp2
= load_reg(s
, rm
);
8174 shiftop
= (insn
>> 5) & 3;
8175 if (!(insn
& (1 << 4))) {
8176 shift
= (insn
>> 7) & 0x1f;
8177 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8179 rs
= (insn
>> 8) & 0xf;
8180 tmp
= load_reg(s
, rs
);
8181 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8184 if (op1
!= 0x0f && op1
!= 0x0d) {
8185 rn
= (insn
>> 16) & 0xf;
8186 tmp
= load_reg(s
, rn
);
8188 TCGV_UNUSED_I32(tmp
);
8190 rd
= (insn
>> 12) & 0xf;
8193 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8197 store_reg_bx(s
, rd
, tmp
);
8200 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8204 store_reg_bx(s
, rd
, tmp
);
8207 if (set_cc
&& rd
== 15) {
8208 /* SUBS r15, ... is used for exception return. */
8212 gen_sub_CC(tmp
, tmp
, tmp2
);
8213 gen_exception_return(s
, tmp
);
8216 gen_sub_CC(tmp
, tmp
, tmp2
);
8218 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8220 store_reg_bx(s
, rd
, tmp
);
8225 gen_sub_CC(tmp
, tmp2
, tmp
);
8227 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8229 store_reg_bx(s
, rd
, tmp
);
8233 gen_add_CC(tmp
, tmp
, tmp2
);
8235 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8237 store_reg_bx(s
, rd
, tmp
);
8241 gen_adc_CC(tmp
, tmp
, tmp2
);
8243 gen_add_carry(tmp
, tmp
, tmp2
);
8245 store_reg_bx(s
, rd
, tmp
);
8249 gen_sbc_CC(tmp
, tmp
, tmp2
);
8251 gen_sub_carry(tmp
, tmp
, tmp2
);
8253 store_reg_bx(s
, rd
, tmp
);
8257 gen_sbc_CC(tmp
, tmp2
, tmp
);
8259 gen_sub_carry(tmp
, tmp2
, tmp
);
8261 store_reg_bx(s
, rd
, tmp
);
8265 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8268 tcg_temp_free_i32(tmp
);
8272 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8275 tcg_temp_free_i32(tmp
);
8279 gen_sub_CC(tmp
, tmp
, tmp2
);
8281 tcg_temp_free_i32(tmp
);
8285 gen_add_CC(tmp
, tmp
, tmp2
);
8287 tcg_temp_free_i32(tmp
);
8290 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8294 store_reg_bx(s
, rd
, tmp
);
8297 if (logic_cc
&& rd
== 15) {
8298 /* MOVS r15, ... is used for exception return. */
8302 gen_exception_return(s
, tmp2
);
8307 store_reg_bx(s
, rd
, tmp2
);
8311 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8315 store_reg_bx(s
, rd
, tmp
);
8319 tcg_gen_not_i32(tmp2
, tmp2
);
8323 store_reg_bx(s
, rd
, tmp2
);
8326 if (op1
!= 0x0f && op1
!= 0x0d) {
8327 tcg_temp_free_i32(tmp2
);
8330 /* other instructions */
8331 op1
= (insn
>> 24) & 0xf;
8335 /* multiplies, extra load/stores */
8336 sh
= (insn
>> 5) & 3;
8339 rd
= (insn
>> 16) & 0xf;
8340 rn
= (insn
>> 12) & 0xf;
8341 rs
= (insn
>> 8) & 0xf;
8343 op1
= (insn
>> 20) & 0xf;
8345 case 0: case 1: case 2: case 3: case 6:
8347 tmp
= load_reg(s
, rs
);
8348 tmp2
= load_reg(s
, rm
);
8349 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8350 tcg_temp_free_i32(tmp2
);
8351 if (insn
& (1 << 22)) {
8352 /* Subtract (mls) */
8354 tmp2
= load_reg(s
, rn
);
8355 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8356 tcg_temp_free_i32(tmp2
);
8357 } else if (insn
& (1 << 21)) {
8359 tmp2
= load_reg(s
, rn
);
8360 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8361 tcg_temp_free_i32(tmp2
);
8363 if (insn
& (1 << 20))
8365 store_reg(s
, rd
, tmp
);
8368 /* 64 bit mul double accumulate (UMAAL) */
8370 tmp
= load_reg(s
, rs
);
8371 tmp2
= load_reg(s
, rm
);
8372 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8373 gen_addq_lo(s
, tmp64
, rn
);
8374 gen_addq_lo(s
, tmp64
, rd
);
8375 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8376 tcg_temp_free_i64(tmp64
);
8378 case 8: case 9: case 10: case 11:
8379 case 12: case 13: case 14: case 15:
8380 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8381 tmp
= load_reg(s
, rs
);
8382 tmp2
= load_reg(s
, rm
);
8383 if (insn
& (1 << 22)) {
8384 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8386 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8388 if (insn
& (1 << 21)) { /* mult accumulate */
8389 TCGv_i32 al
= load_reg(s
, rn
);
8390 TCGv_i32 ah
= load_reg(s
, rd
);
8391 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8392 tcg_temp_free_i32(al
);
8393 tcg_temp_free_i32(ah
);
8395 if (insn
& (1 << 20)) {
8396 gen_logicq_cc(tmp
, tmp2
);
8398 store_reg(s
, rn
, tmp
);
8399 store_reg(s
, rd
, tmp2
);
8405 rn
= (insn
>> 16) & 0xf;
8406 rd
= (insn
>> 12) & 0xf;
8407 if (insn
& (1 << 23)) {
8408 /* load/store exclusive */
8409 int op2
= (insn
>> 8) & 3;
8410 op1
= (insn
>> 21) & 0x3;
8413 case 0: /* lda/stl */
8419 case 1: /* reserved */
8421 case 2: /* ldaex/stlex */
8424 case 3: /* ldrex/strex */
8433 addr
= tcg_temp_local_new_i32();
8434 load_reg_var(s
, addr
, rn
);
8436 /* Since the emulation does not have barriers,
8437 the acquire/release semantics need no special
8440 if (insn
& (1 << 20)) {
8441 tmp
= tcg_temp_new_i32();
8444 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8447 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8450 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8455 store_reg(s
, rd
, tmp
);
8458 tmp
= load_reg(s
, rm
);
8461 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8464 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8467 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8472 tcg_temp_free_i32(tmp
);
8474 } else if (insn
& (1 << 20)) {
8477 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8479 case 1: /* ldrexd */
8480 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8482 case 2: /* ldrexb */
8483 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8485 case 3: /* ldrexh */
8486 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8495 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8497 case 1: /* strexd */
8498 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8500 case 2: /* strexb */
8501 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8503 case 3: /* strexh */
8504 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8510 tcg_temp_free_i32(addr
);
8512 /* SWP instruction */
8515 /* ??? This is not really atomic. However we know
8516 we never have multiple CPUs running in parallel,
8517 so it is good enough. */
8518 addr
= load_reg(s
, rn
);
8519 tmp
= load_reg(s
, rm
);
8520 tmp2
= tcg_temp_new_i32();
8521 if (insn
& (1 << 22)) {
8522 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8523 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8525 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8526 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8528 tcg_temp_free_i32(tmp
);
8529 tcg_temp_free_i32(addr
);
8530 store_reg(s
, rd
, tmp2
);
8535 bool load
= insn
& (1 << 20);
8536 bool doubleword
= false;
8537 /* Misc load/store */
8538 rn
= (insn
>> 16) & 0xf;
8539 rd
= (insn
>> 12) & 0xf;
8541 if (!load
&& (sh
& 2)) {
8545 /* UNPREDICTABLE; we choose to UNDEF */
8548 load
= (sh
& 1) == 0;
8552 addr
= load_reg(s
, rn
);
8553 if (insn
& (1 << 24))
8554 gen_add_datah_offset(s
, insn
, 0, addr
);
8560 tmp
= load_reg(s
, rd
);
8561 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8562 tcg_temp_free_i32(tmp
);
8563 tcg_gen_addi_i32(addr
, addr
, 4);
8564 tmp
= load_reg(s
, rd
+ 1);
8565 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8566 tcg_temp_free_i32(tmp
);
8569 tmp
= tcg_temp_new_i32();
8570 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8571 store_reg(s
, rd
, tmp
);
8572 tcg_gen_addi_i32(addr
, addr
, 4);
8573 tmp
= tcg_temp_new_i32();
8574 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8577 address_offset
= -4;
8580 tmp
= tcg_temp_new_i32();
8583 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8586 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8590 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8595 tmp
= load_reg(s
, rd
);
8596 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8597 tcg_temp_free_i32(tmp
);
8599 /* Perform base writeback before the loaded value to
8600 ensure correct behavior with overlapping index registers.
8601 ldrd with base writeback is undefined if the
8602 destination and index registers overlap. */
8603 if (!(insn
& (1 << 24))) {
8604 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8605 store_reg(s
, rn
, addr
);
8606 } else if (insn
& (1 << 21)) {
8608 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8609 store_reg(s
, rn
, addr
);
8611 tcg_temp_free_i32(addr
);
8614 /* Complete the load. */
8615 store_reg(s
, rd
, tmp
);
8624 if (insn
& (1 << 4)) {
8626 /* Armv6 Media instructions. */
8628 rn
= (insn
>> 16) & 0xf;
8629 rd
= (insn
>> 12) & 0xf;
8630 rs
= (insn
>> 8) & 0xf;
8631 switch ((insn
>> 23) & 3) {
8632 case 0: /* Parallel add/subtract. */
8633 op1
= (insn
>> 20) & 7;
8634 tmp
= load_reg(s
, rn
);
8635 tmp2
= load_reg(s
, rm
);
8636 sh
= (insn
>> 5) & 7;
8637 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8639 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8640 tcg_temp_free_i32(tmp2
);
8641 store_reg(s
, rd
, tmp
);
8644 if ((insn
& 0x00700020) == 0) {
8645 /* Halfword pack. */
8646 tmp
= load_reg(s
, rn
);
8647 tmp2
= load_reg(s
, rm
);
8648 shift
= (insn
>> 7) & 0x1f;
8649 if (insn
& (1 << 6)) {
8653 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8654 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8655 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8659 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8660 tcg_gen_ext16u_i32(tmp
, tmp
);
8661 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8663 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8664 tcg_temp_free_i32(tmp2
);
8665 store_reg(s
, rd
, tmp
);
8666 } else if ((insn
& 0x00200020) == 0x00200000) {
8668 tmp
= load_reg(s
, rm
);
8669 shift
= (insn
>> 7) & 0x1f;
8670 if (insn
& (1 << 6)) {
8673 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8675 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8677 sh
= (insn
>> 16) & 0x1f;
8678 tmp2
= tcg_const_i32(sh
);
8679 if (insn
& (1 << 22))
8680 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8682 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8683 tcg_temp_free_i32(tmp2
);
8684 store_reg(s
, rd
, tmp
);
8685 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8687 tmp
= load_reg(s
, rm
);
8688 sh
= (insn
>> 16) & 0x1f;
8689 tmp2
= tcg_const_i32(sh
);
8690 if (insn
& (1 << 22))
8691 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8693 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8694 tcg_temp_free_i32(tmp2
);
8695 store_reg(s
, rd
, tmp
);
8696 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8698 tmp
= load_reg(s
, rn
);
8699 tmp2
= load_reg(s
, rm
);
8700 tmp3
= tcg_temp_new_i32();
8701 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8702 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8703 tcg_temp_free_i32(tmp3
);
8704 tcg_temp_free_i32(tmp2
);
8705 store_reg(s
, rd
, tmp
);
8706 } else if ((insn
& 0x000003e0) == 0x00000060) {
8707 tmp
= load_reg(s
, rm
);
8708 shift
= (insn
>> 10) & 3;
8709 /* ??? In many cases it's not necessary to do a
8710 rotate, a shift is sufficient. */
8712 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8713 op1
= (insn
>> 20) & 7;
8715 case 0: gen_sxtb16(tmp
); break;
8716 case 2: gen_sxtb(tmp
); break;
8717 case 3: gen_sxth(tmp
); break;
8718 case 4: gen_uxtb16(tmp
); break;
8719 case 6: gen_uxtb(tmp
); break;
8720 case 7: gen_uxth(tmp
); break;
8721 default: goto illegal_op
;
8724 tmp2
= load_reg(s
, rn
);
8725 if ((op1
& 3) == 0) {
8726 gen_add16(tmp
, tmp2
);
8728 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8729 tcg_temp_free_i32(tmp2
);
8732 store_reg(s
, rd
, tmp
);
8733 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8735 tmp
= load_reg(s
, rm
);
8736 if (insn
& (1 << 22)) {
8737 if (insn
& (1 << 7)) {
8741 gen_helper_rbit(tmp
, tmp
);
8744 if (insn
& (1 << 7))
8747 tcg_gen_bswap32_i32(tmp
, tmp
);
8749 store_reg(s
, rd
, tmp
);
8754 case 2: /* Multiplies (Type 3). */
8755 switch ((insn
>> 20) & 0x7) {
8757 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8758 /* op2 not 00x or 11x : UNDEF */
8761 /* Signed multiply most significant [accumulate].
8762 (SMMUL, SMMLA, SMMLS) */
8763 tmp
= load_reg(s
, rm
);
8764 tmp2
= load_reg(s
, rs
);
8765 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8768 tmp
= load_reg(s
, rd
);
8769 if (insn
& (1 << 6)) {
8770 tmp64
= gen_subq_msw(tmp64
, tmp
);
8772 tmp64
= gen_addq_msw(tmp64
, tmp
);
8775 if (insn
& (1 << 5)) {
8776 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8778 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8779 tmp
= tcg_temp_new_i32();
8780 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8781 tcg_temp_free_i64(tmp64
);
8782 store_reg(s
, rn
, tmp
);
8786 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8787 if (insn
& (1 << 7)) {
8790 tmp
= load_reg(s
, rm
);
8791 tmp2
= load_reg(s
, rs
);
8792 if (insn
& (1 << 5))
8793 gen_swap_half(tmp2
);
8794 gen_smul_dual(tmp
, tmp2
);
8795 if (insn
& (1 << 22)) {
8796 /* smlald, smlsld */
8799 tmp64
= tcg_temp_new_i64();
8800 tmp64_2
= tcg_temp_new_i64();
8801 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8802 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8803 tcg_temp_free_i32(tmp
);
8804 tcg_temp_free_i32(tmp2
);
8805 if (insn
& (1 << 6)) {
8806 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8808 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8810 tcg_temp_free_i64(tmp64_2
);
8811 gen_addq(s
, tmp64
, rd
, rn
);
8812 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8813 tcg_temp_free_i64(tmp64
);
8815 /* smuad, smusd, smlad, smlsd */
8816 if (insn
& (1 << 6)) {
8817 /* This subtraction cannot overflow. */
8818 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8820 /* This addition cannot overflow 32 bits;
8821 * however it may overflow considered as a
8822 * signed operation, in which case we must set
8825 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8827 tcg_temp_free_i32(tmp2
);
8830 tmp2
= load_reg(s
, rd
);
8831 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8832 tcg_temp_free_i32(tmp2
);
8834 store_reg(s
, rn
, tmp
);
8840 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
8843 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8846 tmp
= load_reg(s
, rm
);
8847 tmp2
= load_reg(s
, rs
);
8848 if (insn
& (1 << 21)) {
8849 gen_helper_udiv(tmp
, tmp
, tmp2
);
8851 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8853 tcg_temp_free_i32(tmp2
);
8854 store_reg(s
, rn
, tmp
);
8861 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8863 case 0: /* Unsigned sum of absolute differences. */
8865 tmp
= load_reg(s
, rm
);
8866 tmp2
= load_reg(s
, rs
);
8867 gen_helper_usad8(tmp
, tmp
, tmp2
);
8868 tcg_temp_free_i32(tmp2
);
8870 tmp2
= load_reg(s
, rd
);
8871 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8872 tcg_temp_free_i32(tmp2
);
8874 store_reg(s
, rn
, tmp
);
8876 case 0x20: case 0x24: case 0x28: case 0x2c:
8877 /* Bitfield insert/clear. */
8879 shift
= (insn
>> 7) & 0x1f;
8880 i
= (insn
>> 16) & 0x1f;
8882 /* UNPREDICTABLE; we choose to UNDEF */
8887 tmp
= tcg_temp_new_i32();
8888 tcg_gen_movi_i32(tmp
, 0);
8890 tmp
= load_reg(s
, rm
);
8893 tmp2
= load_reg(s
, rd
);
8894 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8895 tcg_temp_free_i32(tmp2
);
8897 store_reg(s
, rd
, tmp
);
8899 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8900 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8902 tmp
= load_reg(s
, rm
);
8903 shift
= (insn
>> 7) & 0x1f;
8904 i
= ((insn
>> 16) & 0x1f) + 1;
8909 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8911 gen_sbfx(tmp
, shift
, i
);
8914 store_reg(s
, rd
, tmp
);
8924 /* Check for undefined extension instructions
8925 * per the ARM Bible IE:
8926 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8928 sh
= (0xf << 20) | (0xf << 4);
8929 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8933 /* load/store byte/word */
8934 rn
= (insn
>> 16) & 0xf;
8935 rd
= (insn
>> 12) & 0xf;
8936 tmp2
= load_reg(s
, rn
);
8937 if ((insn
& 0x01200000) == 0x00200000) {
8939 i
= get_a32_user_mem_index(s
);
8941 i
= get_mem_index(s
);
8943 if (insn
& (1 << 24))
8944 gen_add_data_offset(s
, insn
, tmp2
);
8945 if (insn
& (1 << 20)) {
8947 tmp
= tcg_temp_new_i32();
8948 if (insn
& (1 << 22)) {
8949 gen_aa32_ld8u(tmp
, tmp2
, i
);
8951 gen_aa32_ld32u(tmp
, tmp2
, i
);
8955 tmp
= load_reg(s
, rd
);
8956 if (insn
& (1 << 22)) {
8957 gen_aa32_st8(tmp
, tmp2
, i
);
8959 gen_aa32_st32(tmp
, tmp2
, i
);
8961 tcg_temp_free_i32(tmp
);
8963 if (!(insn
& (1 << 24))) {
8964 gen_add_data_offset(s
, insn
, tmp2
);
8965 store_reg(s
, rn
, tmp2
);
8966 } else if (insn
& (1 << 21)) {
8967 store_reg(s
, rn
, tmp2
);
8969 tcg_temp_free_i32(tmp2
);
8971 if (insn
& (1 << 20)) {
8972 /* Complete the load. */
8973 store_reg_from_load(s
, rd
, tmp
);
8979 int j
, n
, loaded_base
;
8980 bool exc_return
= false;
8981 bool is_load
= extract32(insn
, 20, 1);
8983 TCGv_i32 loaded_var
;
8984 /* load/store multiple words */
8985 /* XXX: store correct base if write back */
8986 if (insn
& (1 << 22)) {
8987 /* LDM (user), LDM (exception return) and STM (user) */
8989 goto illegal_op
; /* only usable in supervisor mode */
8991 if (is_load
&& extract32(insn
, 15, 1)) {
8997 rn
= (insn
>> 16) & 0xf;
8998 addr
= load_reg(s
, rn
);
9000 /* compute total size */
9002 TCGV_UNUSED_I32(loaded_var
);
9005 if (insn
& (1 << i
))
9008 /* XXX: test invalid n == 0 case ? */
9009 if (insn
& (1 << 23)) {
9010 if (insn
& (1 << 24)) {
9012 tcg_gen_addi_i32(addr
, addr
, 4);
9014 /* post increment */
9017 if (insn
& (1 << 24)) {
9019 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9021 /* post decrement */
9023 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9028 if (insn
& (1 << i
)) {
9031 tmp
= tcg_temp_new_i32();
9032 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9034 tmp2
= tcg_const_i32(i
);
9035 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9036 tcg_temp_free_i32(tmp2
);
9037 tcg_temp_free_i32(tmp
);
9038 } else if (i
== rn
) {
9042 store_reg_from_load(s
, i
, tmp
);
9047 /* special case: r15 = PC + 8 */
9048 val
= (long)s
->pc
+ 4;
9049 tmp
= tcg_temp_new_i32();
9050 tcg_gen_movi_i32(tmp
, val
);
9052 tmp
= tcg_temp_new_i32();
9053 tmp2
= tcg_const_i32(i
);
9054 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9055 tcg_temp_free_i32(tmp2
);
9057 tmp
= load_reg(s
, i
);
9059 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9060 tcg_temp_free_i32(tmp
);
9063 /* no need to add after the last transfer */
9065 tcg_gen_addi_i32(addr
, addr
, 4);
9068 if (insn
& (1 << 21)) {
9070 if (insn
& (1 << 23)) {
9071 if (insn
& (1 << 24)) {
9074 /* post increment */
9075 tcg_gen_addi_i32(addr
, addr
, 4);
9078 if (insn
& (1 << 24)) {
9081 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9083 /* post decrement */
9084 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9087 store_reg(s
, rn
, addr
);
9089 tcg_temp_free_i32(addr
);
9092 store_reg(s
, rn
, loaded_var
);
9095 /* Restore CPSR from SPSR. */
9096 tmp
= load_cpu_field(spsr
);
9097 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
9098 tcg_temp_free_i32(tmp
);
9099 s
->is_jmp
= DISAS_JUMP
;
9108 /* branch (and link) */
9109 val
= (int32_t)s
->pc
;
9110 if (insn
& (1 << 24)) {
9111 tmp
= tcg_temp_new_i32();
9112 tcg_gen_movi_i32(tmp
, val
);
9113 store_reg(s
, 14, tmp
);
9115 offset
= sextract32(insn
<< 2, 0, 26);
9123 if (((insn
>> 8) & 0xe) == 10) {
9125 if (disas_vfp_insn(s
, insn
)) {
9128 } else if (disas_coproc_insn(s
, insn
)) {
9135 gen_set_pc_im(s
, s
->pc
);
9136 s
->svc_imm
= extract32(insn
, 0, 24);
9137 s
->is_jmp
= DISAS_SWI
;
9141 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9142 default_exception_el(s
));
9148 /* Return true if this is a Thumb-2 logical op. */
9150 thumb2_logic_op(int op
)
9155 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9156 then set condition code flags based on the result of the operation.
9157 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9158 to the high bit of T1.
9159 Returns zero if the opcode is valid. */
9162 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9163 TCGv_i32 t0
, TCGv_i32 t1
)
9170 tcg_gen_and_i32(t0
, t0
, t1
);
9174 tcg_gen_andc_i32(t0
, t0
, t1
);
9178 tcg_gen_or_i32(t0
, t0
, t1
);
9182 tcg_gen_orc_i32(t0
, t0
, t1
);
9186 tcg_gen_xor_i32(t0
, t0
, t1
);
9191 gen_add_CC(t0
, t0
, t1
);
9193 tcg_gen_add_i32(t0
, t0
, t1
);
9197 gen_adc_CC(t0
, t0
, t1
);
9203 gen_sbc_CC(t0
, t0
, t1
);
9205 gen_sub_carry(t0
, t0
, t1
);
9210 gen_sub_CC(t0
, t0
, t1
);
9212 tcg_gen_sub_i32(t0
, t0
, t1
);
9216 gen_sub_CC(t0
, t1
, t0
);
9218 tcg_gen_sub_i32(t0
, t1
, t0
);
9220 default: /* 5, 6, 7, 9, 12, 15. */
9226 gen_set_CF_bit31(t1
);
9231 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9233 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9235 uint32_t insn
, imm
, shift
, offset
;
9236 uint32_t rd
, rn
, rm
, rs
;
9247 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9248 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9249 /* Thumb-1 cores may need to treat bl and blx as a pair of
9250 16-bit instructions to get correct prefetch abort behavior. */
9252 if ((insn
& (1 << 12)) == 0) {
9254 /* Second half of blx. */
9255 offset
= ((insn
& 0x7ff) << 1);
9256 tmp
= load_reg(s
, 14);
9257 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9258 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9260 tmp2
= tcg_temp_new_i32();
9261 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9262 store_reg(s
, 14, tmp2
);
9266 if (insn
& (1 << 11)) {
9267 /* Second half of bl. */
9268 offset
= ((insn
& 0x7ff) << 1) | 1;
9269 tmp
= load_reg(s
, 14);
9270 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9272 tmp2
= tcg_temp_new_i32();
9273 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9274 store_reg(s
, 14, tmp2
);
9278 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9279 /* Instruction spans a page boundary. Implement it as two
9280 16-bit instructions in case the second half causes an
9282 offset
= ((int32_t)insn
<< 21) >> 9;
9283 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9286 /* Fall through to 32-bit decode. */
9289 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9291 insn
|= (uint32_t)insn_hw1
<< 16;
9293 if ((insn
& 0xf800e800) != 0xf000e800) {
9297 rn
= (insn
>> 16) & 0xf;
9298 rs
= (insn
>> 12) & 0xf;
9299 rd
= (insn
>> 8) & 0xf;
9301 switch ((insn
>> 25) & 0xf) {
9302 case 0: case 1: case 2: case 3:
9303 /* 16-bit instructions. Should never happen. */
9306 if (insn
& (1 << 22)) {
9307 /* Other load/store, table branch. */
9308 if (insn
& 0x01200000) {
9309 /* Load/store doubleword. */
9311 addr
= tcg_temp_new_i32();
9312 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9314 addr
= load_reg(s
, rn
);
9316 offset
= (insn
& 0xff) * 4;
9317 if ((insn
& (1 << 23)) == 0)
9319 if (insn
& (1 << 24)) {
9320 tcg_gen_addi_i32(addr
, addr
, offset
);
9323 if (insn
& (1 << 20)) {
9325 tmp
= tcg_temp_new_i32();
9326 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9327 store_reg(s
, rs
, tmp
);
9328 tcg_gen_addi_i32(addr
, addr
, 4);
9329 tmp
= tcg_temp_new_i32();
9330 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9331 store_reg(s
, rd
, tmp
);
9334 tmp
= load_reg(s
, rs
);
9335 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9336 tcg_temp_free_i32(tmp
);
9337 tcg_gen_addi_i32(addr
, addr
, 4);
9338 tmp
= load_reg(s
, rd
);
9339 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9340 tcg_temp_free_i32(tmp
);
9342 if (insn
& (1 << 21)) {
9343 /* Base writeback. */
9346 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9347 store_reg(s
, rn
, addr
);
9349 tcg_temp_free_i32(addr
);
9351 } else if ((insn
& (1 << 23)) == 0) {
9352 /* Load/store exclusive word. */
9353 addr
= tcg_temp_local_new_i32();
9354 load_reg_var(s
, addr
, rn
);
9355 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9356 if (insn
& (1 << 20)) {
9357 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9359 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9361 tcg_temp_free_i32(addr
);
9362 } else if ((insn
& (7 << 5)) == 0) {
9365 addr
= tcg_temp_new_i32();
9366 tcg_gen_movi_i32(addr
, s
->pc
);
9368 addr
= load_reg(s
, rn
);
9370 tmp
= load_reg(s
, rm
);
9371 tcg_gen_add_i32(addr
, addr
, tmp
);
9372 if (insn
& (1 << 4)) {
9374 tcg_gen_add_i32(addr
, addr
, tmp
);
9375 tcg_temp_free_i32(tmp
);
9376 tmp
= tcg_temp_new_i32();
9377 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9379 tcg_temp_free_i32(tmp
);
9380 tmp
= tcg_temp_new_i32();
9381 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9383 tcg_temp_free_i32(addr
);
9384 tcg_gen_shli_i32(tmp
, tmp
, 1);
9385 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9386 store_reg(s
, 15, tmp
);
9388 int op2
= (insn
>> 6) & 0x3;
9389 op
= (insn
>> 4) & 0x3;
9394 /* Load/store exclusive byte/halfword/doubleword */
9401 /* Load-acquire/store-release */
9407 /* Load-acquire/store-release exclusive */
9411 addr
= tcg_temp_local_new_i32();
9412 load_reg_var(s
, addr
, rn
);
9414 if (insn
& (1 << 20)) {
9415 tmp
= tcg_temp_new_i32();
9418 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9421 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9424 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9429 store_reg(s
, rs
, tmp
);
9431 tmp
= load_reg(s
, rs
);
9434 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9437 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9440 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9445 tcg_temp_free_i32(tmp
);
9447 } else if (insn
& (1 << 20)) {
9448 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9450 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9452 tcg_temp_free_i32(addr
);
9455 /* Load/store multiple, RFE, SRS. */
9456 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9457 /* RFE, SRS: not available in user mode or on M profile */
9458 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9461 if (insn
& (1 << 20)) {
9463 addr
= load_reg(s
, rn
);
9464 if ((insn
& (1 << 24)) == 0)
9465 tcg_gen_addi_i32(addr
, addr
, -8);
9466 /* Load PC into tmp and CPSR into tmp2. */
9467 tmp
= tcg_temp_new_i32();
9468 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9469 tcg_gen_addi_i32(addr
, addr
, 4);
9470 tmp2
= tcg_temp_new_i32();
9471 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9472 if (insn
& (1 << 21)) {
9473 /* Base writeback. */
9474 if (insn
& (1 << 24)) {
9475 tcg_gen_addi_i32(addr
, addr
, 4);
9477 tcg_gen_addi_i32(addr
, addr
, -4);
9479 store_reg(s
, rn
, addr
);
9481 tcg_temp_free_i32(addr
);
9483 gen_rfe(s
, tmp
, tmp2
);
9486 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9490 int i
, loaded_base
= 0;
9491 TCGv_i32 loaded_var
;
9492 /* Load/store multiple. */
9493 addr
= load_reg(s
, rn
);
9495 for (i
= 0; i
< 16; i
++) {
9496 if (insn
& (1 << i
))
9499 if (insn
& (1 << 24)) {
9500 tcg_gen_addi_i32(addr
, addr
, -offset
);
9503 TCGV_UNUSED_I32(loaded_var
);
9504 for (i
= 0; i
< 16; i
++) {
9505 if ((insn
& (1 << i
)) == 0)
9507 if (insn
& (1 << 20)) {
9509 tmp
= tcg_temp_new_i32();
9510 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9513 } else if (i
== rn
) {
9517 store_reg(s
, i
, tmp
);
9521 tmp
= load_reg(s
, i
);
9522 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9523 tcg_temp_free_i32(tmp
);
9525 tcg_gen_addi_i32(addr
, addr
, 4);
9528 store_reg(s
, rn
, loaded_var
);
9530 if (insn
& (1 << 21)) {
9531 /* Base register writeback. */
9532 if (insn
& (1 << 24)) {
9533 tcg_gen_addi_i32(addr
, addr
, -offset
);
9535 /* Fault if writeback register is in register list. */
9536 if (insn
& (1 << rn
))
9538 store_reg(s
, rn
, addr
);
9540 tcg_temp_free_i32(addr
);
9547 op
= (insn
>> 21) & 0xf;
9549 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9552 /* Halfword pack. */
9553 tmp
= load_reg(s
, rn
);
9554 tmp2
= load_reg(s
, rm
);
9555 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9556 if (insn
& (1 << 5)) {
9560 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9561 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9562 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9566 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9567 tcg_gen_ext16u_i32(tmp
, tmp
);
9568 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9570 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9571 tcg_temp_free_i32(tmp2
);
9572 store_reg(s
, rd
, tmp
);
9574 /* Data processing register constant shift. */
9576 tmp
= tcg_temp_new_i32();
9577 tcg_gen_movi_i32(tmp
, 0);
9579 tmp
= load_reg(s
, rn
);
9581 tmp2
= load_reg(s
, rm
);
9583 shiftop
= (insn
>> 4) & 3;
9584 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9585 conds
= (insn
& (1 << 20)) != 0;
9586 logic_cc
= (conds
&& thumb2_logic_op(op
));
9587 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9588 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9590 tcg_temp_free_i32(tmp2
);
9592 store_reg(s
, rd
, tmp
);
9594 tcg_temp_free_i32(tmp
);
9598 case 13: /* Misc data processing. */
9599 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9600 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9603 case 0: /* Register controlled shift. */
9604 tmp
= load_reg(s
, rn
);
9605 tmp2
= load_reg(s
, rm
);
9606 if ((insn
& 0x70) != 0)
9608 op
= (insn
>> 21) & 3;
9609 logic_cc
= (insn
& (1 << 20)) != 0;
9610 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9613 store_reg_bx(s
, rd
, tmp
);
9615 case 1: /* Sign/zero extend. */
9616 op
= (insn
>> 20) & 7;
9618 case 0: /* SXTAH, SXTH */
9619 case 1: /* UXTAH, UXTH */
9620 case 4: /* SXTAB, SXTB */
9621 case 5: /* UXTAB, UXTB */
9623 case 2: /* SXTAB16, SXTB16 */
9624 case 3: /* UXTAB16, UXTB16 */
9625 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9633 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9637 tmp
= load_reg(s
, rm
);
9638 shift
= (insn
>> 4) & 3;
9639 /* ??? In many cases it's not necessary to do a
9640 rotate, a shift is sufficient. */
9642 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9643 op
= (insn
>> 20) & 7;
9645 case 0: gen_sxth(tmp
); break;
9646 case 1: gen_uxth(tmp
); break;
9647 case 2: gen_sxtb16(tmp
); break;
9648 case 3: gen_uxtb16(tmp
); break;
9649 case 4: gen_sxtb(tmp
); break;
9650 case 5: gen_uxtb(tmp
); break;
9652 g_assert_not_reached();
9655 tmp2
= load_reg(s
, rn
);
9656 if ((op
>> 1) == 1) {
9657 gen_add16(tmp
, tmp2
);
9659 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9660 tcg_temp_free_i32(tmp2
);
9663 store_reg(s
, rd
, tmp
);
9665 case 2: /* SIMD add/subtract. */
9666 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9669 op
= (insn
>> 20) & 7;
9670 shift
= (insn
>> 4) & 7;
9671 if ((op
& 3) == 3 || (shift
& 3) == 3)
9673 tmp
= load_reg(s
, rn
);
9674 tmp2
= load_reg(s
, rm
);
9675 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9676 tcg_temp_free_i32(tmp2
);
9677 store_reg(s
, rd
, tmp
);
9679 case 3: /* Other data processing. */
9680 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9682 /* Saturating add/subtract. */
9683 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9686 tmp
= load_reg(s
, rn
);
9687 tmp2
= load_reg(s
, rm
);
9689 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9691 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9693 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9694 tcg_temp_free_i32(tmp2
);
9697 case 0x0a: /* rbit */
9698 case 0x08: /* rev */
9699 case 0x09: /* rev16 */
9700 case 0x0b: /* revsh */
9701 case 0x18: /* clz */
9703 case 0x10: /* sel */
9704 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9708 case 0x20: /* crc32/crc32c */
9714 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
9721 tmp
= load_reg(s
, rn
);
9723 case 0x0a: /* rbit */
9724 gen_helper_rbit(tmp
, tmp
);
9726 case 0x08: /* rev */
9727 tcg_gen_bswap32_i32(tmp
, tmp
);
9729 case 0x09: /* rev16 */
9732 case 0x0b: /* revsh */
9735 case 0x10: /* sel */
9736 tmp2
= load_reg(s
, rm
);
9737 tmp3
= tcg_temp_new_i32();
9738 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9739 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9740 tcg_temp_free_i32(tmp3
);
9741 tcg_temp_free_i32(tmp2
);
9743 case 0x18: /* clz */
9744 gen_helper_clz(tmp
, tmp
);
9754 uint32_t sz
= op
& 0x3;
9755 uint32_t c
= op
& 0x8;
9757 tmp2
= load_reg(s
, rm
);
9759 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9760 } else if (sz
== 1) {
9761 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9763 tmp3
= tcg_const_i32(1 << sz
);
9765 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9767 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9769 tcg_temp_free_i32(tmp2
);
9770 tcg_temp_free_i32(tmp3
);
9774 g_assert_not_reached();
9777 store_reg(s
, rd
, tmp
);
9779 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9780 switch ((insn
>> 20) & 7) {
9781 case 0: /* 32 x 32 -> 32 */
9782 case 7: /* Unsigned sum of absolute differences. */
9784 case 1: /* 16 x 16 -> 32 */
9785 case 2: /* Dual multiply add. */
9786 case 3: /* 32 * 16 -> 32msb */
9787 case 4: /* Dual multiply subtract. */
9788 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9789 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9794 op
= (insn
>> 4) & 0xf;
9795 tmp
= load_reg(s
, rn
);
9796 tmp2
= load_reg(s
, rm
);
9797 switch ((insn
>> 20) & 7) {
9798 case 0: /* 32 x 32 -> 32 */
9799 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9800 tcg_temp_free_i32(tmp2
);
9802 tmp2
= load_reg(s
, rs
);
9804 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9806 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9807 tcg_temp_free_i32(tmp2
);
9810 case 1: /* 16 x 16 -> 32 */
9811 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9812 tcg_temp_free_i32(tmp2
);
9814 tmp2
= load_reg(s
, rs
);
9815 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9816 tcg_temp_free_i32(tmp2
);
9819 case 2: /* Dual multiply add. */
9820 case 4: /* Dual multiply subtract. */
9822 gen_swap_half(tmp2
);
9823 gen_smul_dual(tmp
, tmp2
);
9824 if (insn
& (1 << 22)) {
9825 /* This subtraction cannot overflow. */
9826 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9828 /* This addition cannot overflow 32 bits;
9829 * however it may overflow considered as a signed
9830 * operation, in which case we must set the Q flag.
9832 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9834 tcg_temp_free_i32(tmp2
);
9837 tmp2
= load_reg(s
, rs
);
9838 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9839 tcg_temp_free_i32(tmp2
);
9842 case 3: /* 32 * 16 -> 32msb */
9844 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9847 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9848 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9849 tmp
= tcg_temp_new_i32();
9850 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9851 tcg_temp_free_i64(tmp64
);
9854 tmp2
= load_reg(s
, rs
);
9855 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9856 tcg_temp_free_i32(tmp2
);
9859 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9860 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9862 tmp
= load_reg(s
, rs
);
9863 if (insn
& (1 << 20)) {
9864 tmp64
= gen_addq_msw(tmp64
, tmp
);
9866 tmp64
= gen_subq_msw(tmp64
, tmp
);
9869 if (insn
& (1 << 4)) {
9870 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9872 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9873 tmp
= tcg_temp_new_i32();
9874 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9875 tcg_temp_free_i64(tmp64
);
9877 case 7: /* Unsigned sum of absolute differences. */
9878 gen_helper_usad8(tmp
, tmp
, tmp2
);
9879 tcg_temp_free_i32(tmp2
);
9881 tmp2
= load_reg(s
, rs
);
9882 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9883 tcg_temp_free_i32(tmp2
);
9887 store_reg(s
, rd
, tmp
);
9889 case 6: case 7: /* 64-bit multiply, Divide. */
9890 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9891 tmp
= load_reg(s
, rn
);
9892 tmp2
= load_reg(s
, rm
);
9893 if ((op
& 0x50) == 0x10) {
9895 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
9899 gen_helper_udiv(tmp
, tmp
, tmp2
);
9901 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9902 tcg_temp_free_i32(tmp2
);
9903 store_reg(s
, rd
, tmp
);
9904 } else if ((op
& 0xe) == 0xc) {
9905 /* Dual multiply accumulate long. */
9906 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9907 tcg_temp_free_i32(tmp
);
9908 tcg_temp_free_i32(tmp2
);
9912 gen_swap_half(tmp2
);
9913 gen_smul_dual(tmp
, tmp2
);
9915 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9917 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9919 tcg_temp_free_i32(tmp2
);
9921 tmp64
= tcg_temp_new_i64();
9922 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9923 tcg_temp_free_i32(tmp
);
9924 gen_addq(s
, tmp64
, rs
, rd
);
9925 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9926 tcg_temp_free_i64(tmp64
);
9929 /* Unsigned 64-bit multiply */
9930 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9934 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9935 tcg_temp_free_i32(tmp2
);
9936 tcg_temp_free_i32(tmp
);
9939 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9940 tcg_temp_free_i32(tmp2
);
9941 tmp64
= tcg_temp_new_i64();
9942 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9943 tcg_temp_free_i32(tmp
);
9945 /* Signed 64-bit multiply */
9946 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9951 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9952 tcg_temp_free_i64(tmp64
);
9955 gen_addq_lo(s
, tmp64
, rs
);
9956 gen_addq_lo(s
, tmp64
, rd
);
9957 } else if (op
& 0x40) {
9958 /* 64-bit accumulate. */
9959 gen_addq(s
, tmp64
, rs
, rd
);
9961 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9962 tcg_temp_free_i64(tmp64
);
9967 case 6: case 7: case 14: case 15:
9969 if (((insn
>> 24) & 3) == 3) {
9970 /* Translate into the equivalent ARM encoding. */
9971 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9972 if (disas_neon_data_insn(s
, insn
)) {
9975 } else if (((insn
>> 8) & 0xe) == 10) {
9976 if (disas_vfp_insn(s
, insn
)) {
9980 if (insn
& (1 << 28))
9982 if (disas_coproc_insn(s
, insn
)) {
9987 case 8: case 9: case 10: case 11:
9988 if (insn
& (1 << 15)) {
9989 /* Branches, misc control. */
9990 if (insn
& 0x5000) {
9991 /* Unconditional branch. */
9992 /* signextend(hw1[10:0]) -> offset[:12]. */
9993 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9994 /* hw1[10:0] -> offset[11:1]. */
9995 offset
|= (insn
& 0x7ff) << 1;
9996 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9997 offset[24:22] already have the same value because of the
9998 sign extension above. */
9999 offset
^= ((~insn
) & (1 << 13)) << 10;
10000 offset
^= ((~insn
) & (1 << 11)) << 11;
10002 if (insn
& (1 << 14)) {
10003 /* Branch and link. */
10004 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10008 if (insn
& (1 << 12)) {
10010 gen_jmp(s
, offset
);
10013 offset
&= ~(uint32_t)2;
10014 /* thumb2 bx, no need to check */
10015 gen_bx_im(s
, offset
);
10017 } else if (((insn
>> 23) & 7) == 7) {
10019 if (insn
& (1 << 13))
10022 if (insn
& (1 << 26)) {
10023 if (!(insn
& (1 << 20))) {
10024 /* Hypervisor call (v7) */
10025 int imm16
= extract32(insn
, 16, 4) << 12
10026 | extract32(insn
, 0, 12);
10033 /* Secure monitor call (v6+) */
10041 op
= (insn
>> 20) & 7;
10043 case 0: /* msr cpsr. */
10044 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10045 tmp
= load_reg(s
, rn
);
10046 addr
= tcg_const_i32(insn
& 0xff);
10047 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10048 tcg_temp_free_i32(addr
);
10049 tcg_temp_free_i32(tmp
);
10054 case 1: /* msr spsr. */
10055 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10058 tmp
= load_reg(s
, rn
);
10060 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10064 case 2: /* cps, nop-hint. */
10065 if (((insn
>> 8) & 7) == 0) {
10066 gen_nop_hint(s
, insn
& 0xff);
10068 /* Implemented as NOP in user mode. */
10073 if (insn
& (1 << 10)) {
10074 if (insn
& (1 << 7))
10076 if (insn
& (1 << 6))
10078 if (insn
& (1 << 5))
10080 if (insn
& (1 << 9))
10081 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10083 if (insn
& (1 << 8)) {
10085 imm
|= (insn
& 0x1f);
10088 gen_set_psr_im(s
, offset
, 0, imm
);
10091 case 3: /* Special control operations. */
10093 op
= (insn
>> 4) & 0xf;
10095 case 2: /* clrex */
10100 /* These execute as NOPs. */
10103 /* We need to break the TB after this insn
10104 * to execute self-modifying code correctly
10105 * and also to take any pending interrupts
10115 /* Trivial implementation equivalent to bx. */
10116 tmp
= load_reg(s
, rn
);
10119 case 5: /* Exception return. */
10123 if (rn
!= 14 || rd
!= 15) {
10126 tmp
= load_reg(s
, rn
);
10127 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10128 gen_exception_return(s
, tmp
);
10130 case 6: /* mrs cpsr. */
10131 tmp
= tcg_temp_new_i32();
10132 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10133 addr
= tcg_const_i32(insn
& 0xff);
10134 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10135 tcg_temp_free_i32(addr
);
10137 gen_helper_cpsr_read(tmp
, cpu_env
);
10139 store_reg(s
, rd
, tmp
);
10141 case 7: /* mrs spsr. */
10142 /* Not accessible in user mode. */
10143 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10146 tmp
= load_cpu_field(spsr
);
10147 store_reg(s
, rd
, tmp
);
10152 /* Conditional branch. */
10153 op
= (insn
>> 22) & 0xf;
10154 /* Generate a conditional jump to next instruction. */
10155 s
->condlabel
= gen_new_label();
10156 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10159 /* offset[11:1] = insn[10:0] */
10160 offset
= (insn
& 0x7ff) << 1;
10161 /* offset[17:12] = insn[21:16]. */
10162 offset
|= (insn
& 0x003f0000) >> 4;
10163 /* offset[31:20] = insn[26]. */
10164 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10165 /* offset[18] = insn[13]. */
10166 offset
|= (insn
& (1 << 13)) << 5;
10167 /* offset[19] = insn[11]. */
10168 offset
|= (insn
& (1 << 11)) << 8;
10170 /* jump to the offset */
10171 gen_jmp(s
, s
->pc
+ offset
);
10174 /* Data processing immediate. */
10175 if (insn
& (1 << 25)) {
10176 if (insn
& (1 << 24)) {
10177 if (insn
& (1 << 20))
10179 /* Bitfield/Saturate. */
10180 op
= (insn
>> 21) & 7;
10182 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10184 tmp
= tcg_temp_new_i32();
10185 tcg_gen_movi_i32(tmp
, 0);
10187 tmp
= load_reg(s
, rn
);
10190 case 2: /* Signed bitfield extract. */
10192 if (shift
+ imm
> 32)
10195 gen_sbfx(tmp
, shift
, imm
);
10197 case 6: /* Unsigned bitfield extract. */
10199 if (shift
+ imm
> 32)
10202 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
10204 case 3: /* Bitfield insert/clear. */
10207 imm
= imm
+ 1 - shift
;
10209 tmp2
= load_reg(s
, rd
);
10210 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10211 tcg_temp_free_i32(tmp2
);
10216 default: /* Saturate. */
10219 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10221 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10223 tmp2
= tcg_const_i32(imm
);
10226 if ((op
& 1) && shift
== 0) {
10227 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10228 tcg_temp_free_i32(tmp
);
10229 tcg_temp_free_i32(tmp2
);
10232 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10234 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10238 if ((op
& 1) && shift
== 0) {
10239 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10240 tcg_temp_free_i32(tmp
);
10241 tcg_temp_free_i32(tmp2
);
10244 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10246 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10249 tcg_temp_free_i32(tmp2
);
10252 store_reg(s
, rd
, tmp
);
10254 imm
= ((insn
& 0x04000000) >> 15)
10255 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10256 if (insn
& (1 << 22)) {
10257 /* 16-bit immediate. */
10258 imm
|= (insn
>> 4) & 0xf000;
10259 if (insn
& (1 << 23)) {
10261 tmp
= load_reg(s
, rd
);
10262 tcg_gen_ext16u_i32(tmp
, tmp
);
10263 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10266 tmp
= tcg_temp_new_i32();
10267 tcg_gen_movi_i32(tmp
, imm
);
10270 /* Add/sub 12-bit immediate. */
10272 offset
= s
->pc
& ~(uint32_t)3;
10273 if (insn
& (1 << 23))
10277 tmp
= tcg_temp_new_i32();
10278 tcg_gen_movi_i32(tmp
, offset
);
10280 tmp
= load_reg(s
, rn
);
10281 if (insn
& (1 << 23))
10282 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10284 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10287 store_reg(s
, rd
, tmp
);
10290 int shifter_out
= 0;
10291 /* modified 12-bit immediate. */
10292 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10293 imm
= (insn
& 0xff);
10296 /* Nothing to do. */
10298 case 1: /* 00XY00XY */
10301 case 2: /* XY00XY00 */
10305 case 3: /* XYXYXYXY */
10309 default: /* Rotated constant. */
10310 shift
= (shift
<< 1) | (imm
>> 7);
10312 imm
= imm
<< (32 - shift
);
10316 tmp2
= tcg_temp_new_i32();
10317 tcg_gen_movi_i32(tmp2
, imm
);
10318 rn
= (insn
>> 16) & 0xf;
10320 tmp
= tcg_temp_new_i32();
10321 tcg_gen_movi_i32(tmp
, 0);
10323 tmp
= load_reg(s
, rn
);
10325 op
= (insn
>> 21) & 0xf;
10326 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10327 shifter_out
, tmp
, tmp2
))
10329 tcg_temp_free_i32(tmp2
);
10330 rd
= (insn
>> 8) & 0xf;
10332 store_reg(s
, rd
, tmp
);
10334 tcg_temp_free_i32(tmp
);
10339 case 12: /* Load/store single data item. */
10344 if ((insn
& 0x01100000) == 0x01000000) {
10345 if (disas_neon_ls_insn(s
, insn
)) {
10350 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10352 if (!(insn
& (1 << 20))) {
10356 /* Byte or halfword load space with dest == r15 : memory hints.
10357 * Catch them early so we don't emit pointless addressing code.
10358 * This space is a mix of:
10359 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10360 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10362 * unallocated hints, which must be treated as NOPs
10363 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10364 * which is easiest for the decoding logic
10365 * Some space which must UNDEF
10367 int op1
= (insn
>> 23) & 3;
10368 int op2
= (insn
>> 6) & 0x3f;
10373 /* UNPREDICTABLE, unallocated hint or
10374 * PLD/PLDW/PLI (literal)
10379 return 0; /* PLD/PLDW/PLI or unallocated hint */
10381 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10382 return 0; /* PLD/PLDW/PLI or unallocated hint */
10384 /* UNDEF space, or an UNPREDICTABLE */
10388 memidx
= get_mem_index(s
);
10390 addr
= tcg_temp_new_i32();
10392 /* s->pc has already been incremented by 4. */
10393 imm
= s
->pc
& 0xfffffffc;
10394 if (insn
& (1 << 23))
10395 imm
+= insn
& 0xfff;
10397 imm
-= insn
& 0xfff;
10398 tcg_gen_movi_i32(addr
, imm
);
10400 addr
= load_reg(s
, rn
);
10401 if (insn
& (1 << 23)) {
10402 /* Positive offset. */
10403 imm
= insn
& 0xfff;
10404 tcg_gen_addi_i32(addr
, addr
, imm
);
10407 switch ((insn
>> 8) & 0xf) {
10408 case 0x0: /* Shifted Register. */
10409 shift
= (insn
>> 4) & 0xf;
10411 tcg_temp_free_i32(addr
);
10414 tmp
= load_reg(s
, rm
);
10416 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10417 tcg_gen_add_i32(addr
, addr
, tmp
);
10418 tcg_temp_free_i32(tmp
);
10420 case 0xc: /* Negative offset. */
10421 tcg_gen_addi_i32(addr
, addr
, -imm
);
10423 case 0xe: /* User privilege. */
10424 tcg_gen_addi_i32(addr
, addr
, imm
);
10425 memidx
= get_a32_user_mem_index(s
);
10427 case 0x9: /* Post-decrement. */
10429 /* Fall through. */
10430 case 0xb: /* Post-increment. */
10434 case 0xd: /* Pre-decrement. */
10436 /* Fall through. */
10437 case 0xf: /* Pre-increment. */
10438 tcg_gen_addi_i32(addr
, addr
, imm
);
10442 tcg_temp_free_i32(addr
);
10447 if (insn
& (1 << 20)) {
10449 tmp
= tcg_temp_new_i32();
10452 gen_aa32_ld8u(tmp
, addr
, memidx
);
10455 gen_aa32_ld8s(tmp
, addr
, memidx
);
10458 gen_aa32_ld16u(tmp
, addr
, memidx
);
10461 gen_aa32_ld16s(tmp
, addr
, memidx
);
10464 gen_aa32_ld32u(tmp
, addr
, memidx
);
10467 tcg_temp_free_i32(tmp
);
10468 tcg_temp_free_i32(addr
);
10474 store_reg(s
, rs
, tmp
);
10478 tmp
= load_reg(s
, rs
);
10481 gen_aa32_st8(tmp
, addr
, memidx
);
10484 gen_aa32_st16(tmp
, addr
, memidx
);
10487 gen_aa32_st32(tmp
, addr
, memidx
);
10490 tcg_temp_free_i32(tmp
);
10491 tcg_temp_free_i32(addr
);
10494 tcg_temp_free_i32(tmp
);
10497 tcg_gen_addi_i32(addr
, addr
, imm
);
10499 store_reg(s
, rn
, addr
);
10501 tcg_temp_free_i32(addr
);
10513 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10515 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10522 if (s
->condexec_mask
) {
10523 cond
= s
->condexec_cond
;
10524 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10525 s
->condlabel
= gen_new_label();
10526 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10531 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10534 switch (insn
>> 12) {
10538 op
= (insn
>> 11) & 3;
10541 rn
= (insn
>> 3) & 7;
10542 tmp
= load_reg(s
, rn
);
10543 if (insn
& (1 << 10)) {
10545 tmp2
= tcg_temp_new_i32();
10546 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10549 rm
= (insn
>> 6) & 7;
10550 tmp2
= load_reg(s
, rm
);
10552 if (insn
& (1 << 9)) {
10553 if (s
->condexec_mask
)
10554 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10556 gen_sub_CC(tmp
, tmp
, tmp2
);
10558 if (s
->condexec_mask
)
10559 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10561 gen_add_CC(tmp
, tmp
, tmp2
);
10563 tcg_temp_free_i32(tmp2
);
10564 store_reg(s
, rd
, tmp
);
10566 /* shift immediate */
10567 rm
= (insn
>> 3) & 7;
10568 shift
= (insn
>> 6) & 0x1f;
10569 tmp
= load_reg(s
, rm
);
10570 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10571 if (!s
->condexec_mask
)
10573 store_reg(s
, rd
, tmp
);
10577 /* arithmetic large immediate */
10578 op
= (insn
>> 11) & 3;
10579 rd
= (insn
>> 8) & 0x7;
10580 if (op
== 0) { /* mov */
10581 tmp
= tcg_temp_new_i32();
10582 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10583 if (!s
->condexec_mask
)
10585 store_reg(s
, rd
, tmp
);
10587 tmp
= load_reg(s
, rd
);
10588 tmp2
= tcg_temp_new_i32();
10589 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10592 gen_sub_CC(tmp
, tmp
, tmp2
);
10593 tcg_temp_free_i32(tmp
);
10594 tcg_temp_free_i32(tmp2
);
10597 if (s
->condexec_mask
)
10598 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10600 gen_add_CC(tmp
, tmp
, tmp2
);
10601 tcg_temp_free_i32(tmp2
);
10602 store_reg(s
, rd
, tmp
);
10605 if (s
->condexec_mask
)
10606 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10608 gen_sub_CC(tmp
, tmp
, tmp2
);
10609 tcg_temp_free_i32(tmp2
);
10610 store_reg(s
, rd
, tmp
);
10616 if (insn
& (1 << 11)) {
10617 rd
= (insn
>> 8) & 7;
10618 /* load pc-relative. Bit 1 of PC is ignored. */
10619 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10620 val
&= ~(uint32_t)2;
10621 addr
= tcg_temp_new_i32();
10622 tcg_gen_movi_i32(addr
, val
);
10623 tmp
= tcg_temp_new_i32();
10624 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10625 tcg_temp_free_i32(addr
);
10626 store_reg(s
, rd
, tmp
);
10629 if (insn
& (1 << 10)) {
10630 /* data processing extended or blx */
10631 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10632 rm
= (insn
>> 3) & 0xf;
10633 op
= (insn
>> 8) & 3;
10636 tmp
= load_reg(s
, rd
);
10637 tmp2
= load_reg(s
, rm
);
10638 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10639 tcg_temp_free_i32(tmp2
);
10640 store_reg(s
, rd
, tmp
);
10643 tmp
= load_reg(s
, rd
);
10644 tmp2
= load_reg(s
, rm
);
10645 gen_sub_CC(tmp
, tmp
, tmp2
);
10646 tcg_temp_free_i32(tmp2
);
10647 tcg_temp_free_i32(tmp
);
10649 case 2: /* mov/cpy */
10650 tmp
= load_reg(s
, rm
);
10651 store_reg(s
, rd
, tmp
);
10653 case 3:/* branch [and link] exchange thumb register */
10654 tmp
= load_reg(s
, rm
);
10655 if (insn
& (1 << 7)) {
10657 val
= (uint32_t)s
->pc
| 1;
10658 tmp2
= tcg_temp_new_i32();
10659 tcg_gen_movi_i32(tmp2
, val
);
10660 store_reg(s
, 14, tmp2
);
10662 /* already thumb, no need to check */
10669 /* data processing register */
10671 rm
= (insn
>> 3) & 7;
10672 op
= (insn
>> 6) & 0xf;
10673 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10674 /* the shift/rotate ops want the operands backwards */
10683 if (op
== 9) { /* neg */
10684 tmp
= tcg_temp_new_i32();
10685 tcg_gen_movi_i32(tmp
, 0);
10686 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10687 tmp
= load_reg(s
, rd
);
10689 TCGV_UNUSED_I32(tmp
);
10692 tmp2
= load_reg(s
, rm
);
10694 case 0x0: /* and */
10695 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10696 if (!s
->condexec_mask
)
10699 case 0x1: /* eor */
10700 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10701 if (!s
->condexec_mask
)
10704 case 0x2: /* lsl */
10705 if (s
->condexec_mask
) {
10706 gen_shl(tmp2
, tmp2
, tmp
);
10708 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10709 gen_logic_CC(tmp2
);
10712 case 0x3: /* lsr */
10713 if (s
->condexec_mask
) {
10714 gen_shr(tmp2
, tmp2
, tmp
);
10716 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10717 gen_logic_CC(tmp2
);
10720 case 0x4: /* asr */
10721 if (s
->condexec_mask
) {
10722 gen_sar(tmp2
, tmp2
, tmp
);
10724 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10725 gen_logic_CC(tmp2
);
10728 case 0x5: /* adc */
10729 if (s
->condexec_mask
) {
10730 gen_adc(tmp
, tmp2
);
10732 gen_adc_CC(tmp
, tmp
, tmp2
);
10735 case 0x6: /* sbc */
10736 if (s
->condexec_mask
) {
10737 gen_sub_carry(tmp
, tmp
, tmp2
);
10739 gen_sbc_CC(tmp
, tmp
, tmp2
);
10742 case 0x7: /* ror */
10743 if (s
->condexec_mask
) {
10744 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10745 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10747 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10748 gen_logic_CC(tmp2
);
10751 case 0x8: /* tst */
10752 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10756 case 0x9: /* neg */
10757 if (s
->condexec_mask
)
10758 tcg_gen_neg_i32(tmp
, tmp2
);
10760 gen_sub_CC(tmp
, tmp
, tmp2
);
10762 case 0xa: /* cmp */
10763 gen_sub_CC(tmp
, tmp
, tmp2
);
10766 case 0xb: /* cmn */
10767 gen_add_CC(tmp
, tmp
, tmp2
);
10770 case 0xc: /* orr */
10771 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10772 if (!s
->condexec_mask
)
10775 case 0xd: /* mul */
10776 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10777 if (!s
->condexec_mask
)
10780 case 0xe: /* bic */
10781 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10782 if (!s
->condexec_mask
)
10785 case 0xf: /* mvn */
10786 tcg_gen_not_i32(tmp2
, tmp2
);
10787 if (!s
->condexec_mask
)
10788 gen_logic_CC(tmp2
);
10795 store_reg(s
, rm
, tmp2
);
10797 tcg_temp_free_i32(tmp
);
10799 store_reg(s
, rd
, tmp
);
10800 tcg_temp_free_i32(tmp2
);
10803 tcg_temp_free_i32(tmp
);
10804 tcg_temp_free_i32(tmp2
);
10809 /* load/store register offset. */
10811 rn
= (insn
>> 3) & 7;
10812 rm
= (insn
>> 6) & 7;
10813 op
= (insn
>> 9) & 7;
10814 addr
= load_reg(s
, rn
);
10815 tmp
= load_reg(s
, rm
);
10816 tcg_gen_add_i32(addr
, addr
, tmp
);
10817 tcg_temp_free_i32(tmp
);
10819 if (op
< 3) { /* store */
10820 tmp
= load_reg(s
, rd
);
10822 tmp
= tcg_temp_new_i32();
10827 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10830 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10833 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10835 case 3: /* ldrsb */
10836 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10839 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10842 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10845 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10847 case 7: /* ldrsh */
10848 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10851 if (op
>= 3) { /* load */
10852 store_reg(s
, rd
, tmp
);
10854 tcg_temp_free_i32(tmp
);
10856 tcg_temp_free_i32(addr
);
10860 /* load/store word immediate offset */
10862 rn
= (insn
>> 3) & 7;
10863 addr
= load_reg(s
, rn
);
10864 val
= (insn
>> 4) & 0x7c;
10865 tcg_gen_addi_i32(addr
, addr
, val
);
10867 if (insn
& (1 << 11)) {
10869 tmp
= tcg_temp_new_i32();
10870 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10871 store_reg(s
, rd
, tmp
);
10874 tmp
= load_reg(s
, rd
);
10875 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10876 tcg_temp_free_i32(tmp
);
10878 tcg_temp_free_i32(addr
);
10882 /* load/store byte immediate offset */
10884 rn
= (insn
>> 3) & 7;
10885 addr
= load_reg(s
, rn
);
10886 val
= (insn
>> 6) & 0x1f;
10887 tcg_gen_addi_i32(addr
, addr
, val
);
10889 if (insn
& (1 << 11)) {
10891 tmp
= tcg_temp_new_i32();
10892 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10893 store_reg(s
, rd
, tmp
);
10896 tmp
= load_reg(s
, rd
);
10897 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10898 tcg_temp_free_i32(tmp
);
10900 tcg_temp_free_i32(addr
);
10904 /* load/store halfword immediate offset */
10906 rn
= (insn
>> 3) & 7;
10907 addr
= load_reg(s
, rn
);
10908 val
= (insn
>> 5) & 0x3e;
10909 tcg_gen_addi_i32(addr
, addr
, val
);
10911 if (insn
& (1 << 11)) {
10913 tmp
= tcg_temp_new_i32();
10914 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10915 store_reg(s
, rd
, tmp
);
10918 tmp
= load_reg(s
, rd
);
10919 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10920 tcg_temp_free_i32(tmp
);
10922 tcg_temp_free_i32(addr
);
10926 /* load/store from stack */
10927 rd
= (insn
>> 8) & 7;
10928 addr
= load_reg(s
, 13);
10929 val
= (insn
& 0xff) * 4;
10930 tcg_gen_addi_i32(addr
, addr
, val
);
10932 if (insn
& (1 << 11)) {
10934 tmp
= tcg_temp_new_i32();
10935 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10936 store_reg(s
, rd
, tmp
);
10939 tmp
= load_reg(s
, rd
);
10940 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10941 tcg_temp_free_i32(tmp
);
10943 tcg_temp_free_i32(addr
);
10947 /* add to high reg */
10948 rd
= (insn
>> 8) & 7;
10949 if (insn
& (1 << 11)) {
10951 tmp
= load_reg(s
, 13);
10953 /* PC. bit 1 is ignored. */
10954 tmp
= tcg_temp_new_i32();
10955 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10957 val
= (insn
& 0xff) * 4;
10958 tcg_gen_addi_i32(tmp
, tmp
, val
);
10959 store_reg(s
, rd
, tmp
);
10964 op
= (insn
>> 8) & 0xf;
10967 /* adjust stack pointer */
10968 tmp
= load_reg(s
, 13);
10969 val
= (insn
& 0x7f) * 4;
10970 if (insn
& (1 << 7))
10971 val
= -(int32_t)val
;
10972 tcg_gen_addi_i32(tmp
, tmp
, val
);
10973 store_reg(s
, 13, tmp
);
10976 case 2: /* sign/zero extend. */
10979 rm
= (insn
>> 3) & 7;
10980 tmp
= load_reg(s
, rm
);
10981 switch ((insn
>> 6) & 3) {
10982 case 0: gen_sxth(tmp
); break;
10983 case 1: gen_sxtb(tmp
); break;
10984 case 2: gen_uxth(tmp
); break;
10985 case 3: gen_uxtb(tmp
); break;
10987 store_reg(s
, rd
, tmp
);
10989 case 4: case 5: case 0xc: case 0xd:
10991 addr
= load_reg(s
, 13);
10992 if (insn
& (1 << 8))
10996 for (i
= 0; i
< 8; i
++) {
10997 if (insn
& (1 << i
))
11000 if ((insn
& (1 << 11)) == 0) {
11001 tcg_gen_addi_i32(addr
, addr
, -offset
);
11003 for (i
= 0; i
< 8; i
++) {
11004 if (insn
& (1 << i
)) {
11005 if (insn
& (1 << 11)) {
11007 tmp
= tcg_temp_new_i32();
11008 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
11009 store_reg(s
, i
, tmp
);
11012 tmp
= load_reg(s
, i
);
11013 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
11014 tcg_temp_free_i32(tmp
);
11016 /* advance to the next address. */
11017 tcg_gen_addi_i32(addr
, addr
, 4);
11020 TCGV_UNUSED_I32(tmp
);
11021 if (insn
& (1 << 8)) {
11022 if (insn
& (1 << 11)) {
11024 tmp
= tcg_temp_new_i32();
11025 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
11026 /* don't set the pc until the rest of the instruction
11030 tmp
= load_reg(s
, 14);
11031 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
11032 tcg_temp_free_i32(tmp
);
11034 tcg_gen_addi_i32(addr
, addr
, 4);
11036 if ((insn
& (1 << 11)) == 0) {
11037 tcg_gen_addi_i32(addr
, addr
, -offset
);
11039 /* write back the new stack pointer */
11040 store_reg(s
, 13, addr
);
11041 /* set the new PC value */
11042 if ((insn
& 0x0900) == 0x0900) {
11043 store_reg_from_load(s
, 15, tmp
);
11047 case 1: case 3: case 9: case 11: /* czb */
11049 tmp
= load_reg(s
, rm
);
11050 s
->condlabel
= gen_new_label();
11052 if (insn
& (1 << 11))
11053 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11055 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11056 tcg_temp_free_i32(tmp
);
11057 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11058 val
= (uint32_t)s
->pc
+ 2;
11063 case 15: /* IT, nop-hint. */
11064 if ((insn
& 0xf) == 0) {
11065 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11069 s
->condexec_cond
= (insn
>> 4) & 0xe;
11070 s
->condexec_mask
= insn
& 0x1f;
11071 /* No actual code generated for this insn, just setup state. */
11074 case 0xe: /* bkpt */
11076 int imm8
= extract32(insn
, 0, 8);
11078 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11079 default_exception_el(s
));
11083 case 0xa: /* rev */
11085 rn
= (insn
>> 3) & 0x7;
11087 tmp
= load_reg(s
, rn
);
11088 switch ((insn
>> 6) & 3) {
11089 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11090 case 1: gen_rev16(tmp
); break;
11091 case 3: gen_revsh(tmp
); break;
11092 default: goto illegal_op
;
11094 store_reg(s
, rd
, tmp
);
11098 switch ((insn
>> 5) & 7) {
11102 if (((insn
>> 3) & 1) != s
->bswap_code
) {
11103 /* Dynamic endianness switching not implemented. */
11104 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
11114 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11115 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11118 addr
= tcg_const_i32(19);
11119 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11120 tcg_temp_free_i32(addr
);
11124 addr
= tcg_const_i32(16);
11125 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11126 tcg_temp_free_i32(addr
);
11128 tcg_temp_free_i32(tmp
);
11131 if (insn
& (1 << 4)) {
11132 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11136 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11151 /* load/store multiple */
11152 TCGv_i32 loaded_var
;
11153 TCGV_UNUSED_I32(loaded_var
);
11154 rn
= (insn
>> 8) & 0x7;
11155 addr
= load_reg(s
, rn
);
11156 for (i
= 0; i
< 8; i
++) {
11157 if (insn
& (1 << i
)) {
11158 if (insn
& (1 << 11)) {
11160 tmp
= tcg_temp_new_i32();
11161 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
11165 store_reg(s
, i
, tmp
);
11169 tmp
= load_reg(s
, i
);
11170 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
11171 tcg_temp_free_i32(tmp
);
11173 /* advance to the next address */
11174 tcg_gen_addi_i32(addr
, addr
, 4);
11177 if ((insn
& (1 << rn
)) == 0) {
11178 /* base reg not in list: base register writeback */
11179 store_reg(s
, rn
, addr
);
11181 /* base reg in list: if load, complete it now */
11182 if (insn
& (1 << 11)) {
11183 store_reg(s
, rn
, loaded_var
);
11185 tcg_temp_free_i32(addr
);
11190 /* conditional branch or swi */
11191 cond
= (insn
>> 8) & 0xf;
11197 gen_set_pc_im(s
, s
->pc
);
11198 s
->svc_imm
= extract32(insn
, 0, 8);
11199 s
->is_jmp
= DISAS_SWI
;
11202 /* generate a conditional jump to next instruction */
11203 s
->condlabel
= gen_new_label();
11204 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11207 /* jump to the offset */
11208 val
= (uint32_t)s
->pc
+ 2;
11209 offset
= ((int32_t)insn
<< 24) >> 24;
11210 val
+= offset
<< 1;
11215 if (insn
& (1 << 11)) {
11216 if (disas_thumb2_insn(env
, s
, insn
))
11220 /* unconditional branch */
11221 val
= (uint32_t)s
->pc
;
11222 offset
= ((int32_t)insn
<< 21) >> 21;
11223 val
+= (offset
<< 1) + 2;
11228 if (disas_thumb2_insn(env
, s
, insn
))
11234 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11235 default_exception_el(s
));
11239 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11240 default_exception_el(s
));
11243 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11245 /* Return true if the insn at dc->pc might cross a page boundary.
11246 * (False positives are OK, false negatives are not.)
11250 if ((s
->pc
& 3) == 0) {
11251 /* At a 4-aligned address we can't be crossing a page */
11255 /* This must be a Thumb insn */
11256 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
11258 if ((insn
>> 11) >= 0x1d) {
11259 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11260 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11261 * end up actually treating this as two 16-bit insns (see the
11262 * code at the start of disas_thumb2_insn()) but we don't bother
11263 * to check for that as it is unlikely, and false positives here
11268 /* Definitely a 16-bit insn, can't be crossing a page. */
11272 /* generate intermediate code for basic block 'tb'. */
11273 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11275 ARMCPU
*cpu
= arm_env_get_cpu(env
);
11276 CPUState
*cs
= CPU(cpu
);
11277 DisasContext dc1
, *dc
= &dc1
;
11278 target_ulong pc_start
;
11279 target_ulong next_page_start
;
11284 /* generate intermediate code */
11286 /* The A64 decoder has its own top level loop, because it doesn't need
11287 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11289 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11290 gen_intermediate_code_a64(cpu
, tb
);
11298 dc
->is_jmp
= DISAS_NEXT
;
11300 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11304 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11305 * there is no secure EL1, so we route exceptions to EL3.
11307 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11308 !arm_el_is_aa64(env
, 3);
11309 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11310 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
11311 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11312 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11313 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11314 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11315 #if !defined(CONFIG_USER_ONLY)
11316 dc
->user
= (dc
->current_el
== 0);
11318 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11319 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11320 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11321 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11322 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11323 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11324 dc
->cp_regs
= cpu
->cp_regs
;
11325 dc
->features
= env
->features
;
11327 /* Single step state. The code-generation logic here is:
11329 * generate code with no special handling for single-stepping (except
11330 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11331 * this happens anyway because those changes are all system register or
11333 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11334 * emit code for one insn
11335 * emit code to clear PSTATE.SS
11336 * emit code to generate software step exception for completed step
11337 * end TB (as usual for having generated an exception)
11338 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11339 * emit code to generate a software step exception
11342 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11343 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11344 dc
->is_ldex
= false;
11345 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11347 cpu_F0s
= tcg_temp_new_i32();
11348 cpu_F1s
= tcg_temp_new_i32();
11349 cpu_F0d
= tcg_temp_new_i64();
11350 cpu_F1d
= tcg_temp_new_i64();
11353 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11354 cpu_M0
= tcg_temp_new_i64();
11355 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11357 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11358 if (max_insns
== 0) {
11359 max_insns
= CF_COUNT_MASK
;
11361 if (max_insns
> TCG_MAX_INSNS
) {
11362 max_insns
= TCG_MAX_INSNS
;
11367 tcg_clear_temp_count();
11369 /* A note on handling of the condexec (IT) bits:
11371 * We want to avoid the overhead of having to write the updated condexec
11372 * bits back to the CPUARMState for every instruction in an IT block. So:
11373 * (1) if the condexec bits are not already zero then we write
11374 * zero back into the CPUARMState now. This avoids complications trying
11375 * to do it at the end of the block. (For example if we don't do this
11376 * it's hard to identify whether we can safely skip writing condexec
11377 * at the end of the TB, which we definitely want to do for the case
11378 * where a TB doesn't do anything with the IT state at all.)
11379 * (2) if we are going to leave the TB then we call gen_set_condexec()
11380 * which will write the correct value into CPUARMState if zero is wrong.
11381 * This is done both for leaving the TB at the end, and for leaving
11382 * it because of an exception we know will happen, which is done in
11383 * gen_exception_insn(). The latter is necessary because we need to
11384 * leave the TB with the PC/IT state just prior to execution of the
11385 * instruction which caused the exception.
11386 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11387 * then the CPUARMState will be wrong and we need to reset it.
11388 * This is handled in the same way as restoration of the
11389 * PC in these situations; we save the value of the condexec bits
11390 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11391 * then uses this to restore them after an exception.
11393 * Note that there are no instructions which can read the condexec
11394 * bits, and none which can write non-static values to them, so
11395 * we don't need to care about whether CPUARMState is correct in the
11399 /* Reset the conditional execution bits immediately. This avoids
11400 complications trying to do it at the end of the block. */
11401 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11403 TCGv_i32 tmp
= tcg_temp_new_i32();
11404 tcg_gen_movi_i32(tmp
, 0);
11405 store_cpu_field(tmp
, condexec_bits
);
11408 tcg_gen_insn_start(dc
->pc
,
11409 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1));
11412 #ifdef CONFIG_USER_ONLY
11413 /* Intercept jump to the magic kernel page. */
11414 if (dc
->pc
>= 0xffff0000) {
11415 /* We always get here via a jump, so know we are not in a
11416 conditional execution block. */
11417 gen_exception_internal(EXCP_KERNEL_TRAP
);
11418 dc
->is_jmp
= DISAS_EXC
;
11422 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11423 /* We always get here via a jump, so know we are not in a
11424 conditional execution block. */
11425 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11426 dc
->is_jmp
= DISAS_EXC
;
11431 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11433 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11434 if (bp
->pc
== dc
->pc
) {
11435 if (bp
->flags
& BP_CPU
) {
11436 gen_set_condexec(dc
);
11437 gen_set_pc_im(dc
, dc
->pc
);
11438 gen_helper_check_breakpoints(cpu_env
);
11439 /* End the TB early; it's likely not going to be executed */
11440 dc
->is_jmp
= DISAS_UPDATE
;
11442 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11443 /* The address covered by the breakpoint must be
11444 included in [tb->pc, tb->pc + tb->size) in order
11445 to for it to be properly cleared -- thus we
11446 increment the PC here so that the logic setting
11447 tb->size below does the right thing. */
11448 /* TODO: Advance PC by correct instruction length to
11449 * avoid disassembler error messages */
11451 goto done_generating
;
11458 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
11462 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11463 /* Singlestep state is Active-pending.
11464 * If we're in this state at the start of a TB then either
11465 * a) we just took an exception to an EL which is being debugged
11466 * and this is the first insn in the exception handler
11467 * b) debug exceptions were masked and we just unmasked them
11468 * without changing EL (eg by clearing PSTATE.D)
11469 * In either case we're going to take a swstep exception in the
11470 * "did not step an insn" case, and so the syndrome ISV and EX
11471 * bits should be zero.
11473 assert(num_insns
== 1);
11474 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11475 default_exception_el(dc
));
11476 goto done_generating
;
11480 disas_thumb_insn(env
, dc
);
11481 if (dc
->condexec_mask
) {
11482 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11483 | ((dc
->condexec_mask
>> 4) & 1);
11484 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11485 if (dc
->condexec_mask
== 0) {
11486 dc
->condexec_cond
= 0;
11490 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->bswap_code
);
11492 disas_arm_insn(dc
, insn
);
11495 if (dc
->condjmp
&& !dc
->is_jmp
) {
11496 gen_set_label(dc
->condlabel
);
11500 if (tcg_check_temp_count()) {
11501 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11505 /* Translation stops when a conditional branch is encountered.
11506 * Otherwise the subsequent code could get translated several times.
11507 * Also stop translation when a page boundary is reached. This
11508 * ensures prefetch aborts occur at the right place. */
11510 /* We want to stop the TB if the next insn starts in a new page,
11511 * or if it spans between this page and the next. This means that
11512 * if we're looking at the last halfword in the page we need to
11513 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11514 * or a 32-bit Thumb insn (which won't).
11515 * This is to avoid generating a silly TB with a single 16-bit insn
11516 * in it at the end of this page (which would execute correctly
11517 * but isn't very efficient).
11519 end_of_page
= (dc
->pc
>= next_page_start
) ||
11520 ((dc
->pc
>= next_page_start
- 3) && insn_crosses_page(env
, dc
));
11522 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11523 !cs
->singlestep_enabled
&&
11527 num_insns
< max_insns
);
11529 if (tb
->cflags
& CF_LAST_IO
) {
11531 /* FIXME: This can theoretically happen with self-modifying
11533 cpu_abort(cs
, "IO on conditional branch instruction");
11538 /* At this stage dc->condjmp will only be set when the skipped
11539 instruction was a conditional branch or trap, and the PC has
11540 already been written. */
11541 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11542 /* Unconditional and "condition passed" instruction codepath. */
11543 gen_set_condexec(dc
);
11544 switch (dc
->is_jmp
) {
11546 gen_ss_advance(dc
);
11547 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11548 default_exception_el(dc
));
11551 gen_ss_advance(dc
);
11552 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11555 gen_ss_advance(dc
);
11556 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11560 gen_set_pc_im(dc
, dc
->pc
);
11563 if (dc
->ss_active
) {
11564 gen_step_complete_exception(dc
);
11566 /* FIXME: Single stepping a WFI insn will not halt
11568 gen_exception_internal(EXCP_DEBUG
);
11572 /* "Condition failed" instruction codepath. */
11573 gen_set_label(dc
->condlabel
);
11574 gen_set_condexec(dc
);
11575 gen_set_pc_im(dc
, dc
->pc
);
11576 if (dc
->ss_active
) {
11577 gen_step_complete_exception(dc
);
11579 gen_exception_internal(EXCP_DEBUG
);
11583 /* While branches must always occur at the end of an IT block,
11584 there are a few other things that can cause us to terminate
11585 the TB in the middle of an IT block:
11586 - Exception generating instructions (bkpt, swi, undefined).
11588 - Hardware watchpoints.
11589 Hardware breakpoints have already been handled and skip this code.
11591 gen_set_condexec(dc
);
11592 switch(dc
->is_jmp
) {
11594 gen_goto_tb(dc
, 1, dc
->pc
);
11597 gen_set_pc_im(dc
, dc
->pc
);
11601 /* indicate that the hash table must be used to find the next TB */
11602 tcg_gen_exit_tb(0);
11604 case DISAS_TB_JUMP
:
11605 /* nothing more to generate */
11608 gen_helper_wfi(cpu_env
);
11609 /* The helper doesn't necessarily throw an exception, but we
11610 * must go back to the main loop to check for interrupts anyway.
11612 tcg_gen_exit_tb(0);
11615 gen_helper_wfe(cpu_env
);
11618 gen_helper_yield(cpu_env
);
11621 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11622 default_exception_el(dc
));
11625 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11628 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11632 gen_set_label(dc
->condlabel
);
11633 gen_set_condexec(dc
);
11634 gen_goto_tb(dc
, 1, dc
->pc
);
11640 gen_tb_end(tb
, num_insns
);
11643 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11644 qemu_log("----------------\n");
11645 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11646 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
11647 dc
->thumb
| (dc
->bswap_code
<< 1));
11651 tb
->size
= dc
->pc
- pc_start
;
11652 tb
->icount
= num_insns
;
11655 static const char *cpu_mode_names
[16] = {
11656 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11657 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11660 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11663 ARMCPU
*cpu
= ARM_CPU(cs
);
11664 CPUARMState
*env
= &cpu
->env
;
11667 const char *ns_status
;
11670 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11674 for(i
=0;i
<16;i
++) {
11675 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11677 cpu_fprintf(f
, "\n");
11679 cpu_fprintf(f
, " ");
11681 psr
= cpsr_read(env
);
11683 if (arm_feature(env
, ARM_FEATURE_EL3
) &&
11684 (psr
& CPSR_M
) != ARM_CPU_MODE_MON
) {
11685 ns_status
= env
->cp15
.scr_el3
& SCR_NS
? "NS " : "S ";
11690 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%s%d\n",
11692 psr
& (1 << 31) ? 'N' : '-',
11693 psr
& (1 << 30) ? 'Z' : '-',
11694 psr
& (1 << 29) ? 'C' : '-',
11695 psr
& (1 << 28) ? 'V' : '-',
11696 psr
& CPSR_T
? 'T' : 'A',
11698 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11700 if (flags
& CPU_DUMP_FPU
) {
11701 int numvfpregs
= 0;
11702 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11705 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11708 for (i
= 0; i
< numvfpregs
; i
++) {
11709 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11710 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11711 i
* 2, (uint32_t)v
,
11712 i
* 2 + 1, (uint32_t)(v
>> 32),
11715 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11719 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
11720 target_ulong
*data
)
11724 env
->condexec_bits
= 0;
11726 env
->regs
[15] = data
[0];
11727 env
->condexec_bits
= data
[1];