4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 #include "internals.h"
29 #include "disas/disas.h"
32 #include "qemu/bitops.h"
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
38 #include "trace-tcg.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J 0
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
55 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
57 #if defined(CONFIG_USER_ONLY)
60 #define IS_USER(s) (s->user)
64 /* We reuse the same 64-bit temporaries for efficiency. */
65 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
66 static TCGv_i32 cpu_R
[16];
67 static TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
68 static TCGv_i64 cpu_exclusive_addr
;
69 static TCGv_i64 cpu_exclusive_val
;
70 #ifdef CONFIG_USER_ONLY
71 static TCGv_i64 cpu_exclusive_test
;
72 static TCGv_i32 cpu_exclusive_info
;
75 /* FIXME: These should be removed. */
76 static TCGv_i32 cpu_F0s
, cpu_F1s
;
77 static TCGv_i64 cpu_F0d
, cpu_F1d
;
79 #include "exec/gen-icount.h"
81 static const char *regnames
[] =
82 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
83 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
85 /* initialize TCG globals. */
86 void arm_translate_init(void)
90 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
92 for (i
= 0; i
< 16; i
++) {
93 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
94 offsetof(CPUARMState
, regs
[i
]),
97 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
98 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
99 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
100 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
102 cpu_exclusive_addr
= tcg_global_mem_new_i64(TCG_AREG0
,
103 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
104 cpu_exclusive_val
= tcg_global_mem_new_i64(TCG_AREG0
,
105 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
106 #ifdef CONFIG_USER_ONLY
107 cpu_exclusive_test
= tcg_global_mem_new_i64(TCG_AREG0
,
108 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
109 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
110 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
113 a64_translate_init();
116 static inline ARMMMUIdx
get_a32_user_mem_index(DisasContext
*s
)
118 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
120 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
121 * otherwise, access as if at PL0.
123 switch (s
->mmu_idx
) {
124 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
125 case ARMMMUIdx_S12NSE0
:
126 case ARMMMUIdx_S12NSE1
:
127 return ARMMMUIdx_S12NSE0
;
129 case ARMMMUIdx_S1SE0
:
130 case ARMMMUIdx_S1SE1
:
131 return ARMMMUIdx_S1SE0
;
134 g_assert_not_reached();
138 static inline TCGv_i32
load_cpu_offset(int offset
)
140 TCGv_i32 tmp
= tcg_temp_new_i32();
141 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
145 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
147 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
149 tcg_gen_st_i32(var
, cpu_env
, offset
);
150 tcg_temp_free_i32(var
);
153 #define store_cpu_field(var, name) \
154 store_cpu_offset(var, offsetof(CPUARMState, name))
156 /* Set a variable to the value of a CPU register. */
157 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
161 /* normally, since we updated PC, we need only to add one insn */
163 addr
= (long)s
->pc
+ 2;
165 addr
= (long)s
->pc
+ 4;
166 tcg_gen_movi_i32(var
, addr
);
168 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
172 /* Create a new temporary and set it to the value of a CPU register. */
173 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
175 TCGv_i32 tmp
= tcg_temp_new_i32();
176 load_reg_var(s
, tmp
, reg
);
180 /* Set a CPU register. The source must be a temporary and will be
182 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
185 tcg_gen_andi_i32(var
, var
, ~1);
186 s
->is_jmp
= DISAS_JUMP
;
188 tcg_gen_mov_i32(cpu_R
[reg
], var
);
189 tcg_temp_free_i32(var
);
192 /* Value extensions. */
193 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
194 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
195 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
196 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
198 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
199 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
202 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
204 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
205 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
206 tcg_temp_free_i32(tmp_mask
);
208 /* Set NZCV flags from the high 4 bits of var. */
209 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
211 static void gen_exception_internal(int excp
)
213 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
215 assert(excp_is_internal(excp
));
216 gen_helper_exception_internal(cpu_env
, tcg_excp
);
217 tcg_temp_free_i32(tcg_excp
);
220 static void gen_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
222 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
223 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
224 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
226 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
229 tcg_temp_free_i32(tcg_el
);
230 tcg_temp_free_i32(tcg_syn
);
231 tcg_temp_free_i32(tcg_excp
);
234 static void gen_ss_advance(DisasContext
*s
)
236 /* If the singlestep state is Active-not-pending, advance to
241 gen_helper_clear_pstate_ss(cpu_env
);
245 static void gen_step_complete_exception(DisasContext
*s
)
247 /* We just completed step of an insn. Move from Active-not-pending
248 * to Active-pending, and then also take the swstep exception.
249 * This corresponds to making the (IMPDEF) choice to prioritize
250 * swstep exceptions over asynchronous exceptions taken to an exception
251 * level where debug is disabled. This choice has the advantage that
252 * we do not need to maintain internal state corresponding to the
253 * ISV/EX syndrome bits between completion of the step and generation
254 * of the exception, and our syndrome information is always correct.
257 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
258 default_exception_el(s
));
259 s
->is_jmp
= DISAS_EXC
;
262 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
264 TCGv_i32 tmp1
= tcg_temp_new_i32();
265 TCGv_i32 tmp2
= tcg_temp_new_i32();
266 tcg_gen_ext16s_i32(tmp1
, a
);
267 tcg_gen_ext16s_i32(tmp2
, b
);
268 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
269 tcg_temp_free_i32(tmp2
);
270 tcg_gen_sari_i32(a
, a
, 16);
271 tcg_gen_sari_i32(b
, b
, 16);
272 tcg_gen_mul_i32(b
, b
, a
);
273 tcg_gen_mov_i32(a
, tmp1
);
274 tcg_temp_free_i32(tmp1
);
277 /* Byteswap each halfword. */
278 static void gen_rev16(TCGv_i32 var
)
280 TCGv_i32 tmp
= tcg_temp_new_i32();
281 tcg_gen_shri_i32(tmp
, var
, 8);
282 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
283 tcg_gen_shli_i32(var
, var
, 8);
284 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
285 tcg_gen_or_i32(var
, var
, tmp
);
286 tcg_temp_free_i32(tmp
);
289 /* Byteswap low halfword and sign extend. */
290 static void gen_revsh(TCGv_i32 var
)
292 tcg_gen_ext16u_i32(var
, var
);
293 tcg_gen_bswap16_i32(var
, var
);
294 tcg_gen_ext16s_i32(var
, var
);
297 /* Unsigned bitfield extract. */
298 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
301 tcg_gen_shri_i32(var
, var
, shift
);
302 tcg_gen_andi_i32(var
, var
, mask
);
305 /* Signed bitfield extract. */
306 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
311 tcg_gen_sari_i32(var
, var
, shift
);
312 if (shift
+ width
< 32) {
313 signbit
= 1u << (width
- 1);
314 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
315 tcg_gen_xori_i32(var
, var
, signbit
);
316 tcg_gen_subi_i32(var
, var
, signbit
);
320 /* Return (b << 32) + a. Mark inputs as dead */
321 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
323 TCGv_i64 tmp64
= tcg_temp_new_i64();
325 tcg_gen_extu_i32_i64(tmp64
, b
);
326 tcg_temp_free_i32(b
);
327 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
328 tcg_gen_add_i64(a
, tmp64
, a
);
330 tcg_temp_free_i64(tmp64
);
334 /* Return (b << 32) - a. Mark inputs as dead. */
335 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
337 TCGv_i64 tmp64
= tcg_temp_new_i64();
339 tcg_gen_extu_i32_i64(tmp64
, b
);
340 tcg_temp_free_i32(b
);
341 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
342 tcg_gen_sub_i64(a
, tmp64
, a
);
344 tcg_temp_free_i64(tmp64
);
348 /* 32x32->64 multiply. Marks inputs as dead. */
349 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
351 TCGv_i32 lo
= tcg_temp_new_i32();
352 TCGv_i32 hi
= tcg_temp_new_i32();
355 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
356 tcg_temp_free_i32(a
);
357 tcg_temp_free_i32(b
);
359 ret
= tcg_temp_new_i64();
360 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
361 tcg_temp_free_i32(lo
);
362 tcg_temp_free_i32(hi
);
367 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
369 TCGv_i32 lo
= tcg_temp_new_i32();
370 TCGv_i32 hi
= tcg_temp_new_i32();
373 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
374 tcg_temp_free_i32(a
);
375 tcg_temp_free_i32(b
);
377 ret
= tcg_temp_new_i64();
378 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
379 tcg_temp_free_i32(lo
);
380 tcg_temp_free_i32(hi
);
385 /* Swap low and high halfwords. */
386 static void gen_swap_half(TCGv_i32 var
)
388 TCGv_i32 tmp
= tcg_temp_new_i32();
389 tcg_gen_shri_i32(tmp
, var
, 16);
390 tcg_gen_shli_i32(var
, var
, 16);
391 tcg_gen_or_i32(var
, var
, tmp
);
392 tcg_temp_free_i32(tmp
);
395 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
396 tmp = (t0 ^ t1) & 0x8000;
399 t0 = (t0 + t1) ^ tmp;
402 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
404 TCGv_i32 tmp
= tcg_temp_new_i32();
405 tcg_gen_xor_i32(tmp
, t0
, t1
);
406 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
407 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
408 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
409 tcg_gen_add_i32(t0
, t0
, t1
);
410 tcg_gen_xor_i32(t0
, t0
, tmp
);
411 tcg_temp_free_i32(tmp
);
412 tcg_temp_free_i32(t1
);
415 /* Set CF to the top bit of var. */
416 static void gen_set_CF_bit31(TCGv_i32 var
)
418 tcg_gen_shri_i32(cpu_CF
, var
, 31);
421 /* Set N and Z flags from var. */
422 static inline void gen_logic_CC(TCGv_i32 var
)
424 tcg_gen_mov_i32(cpu_NF
, var
);
425 tcg_gen_mov_i32(cpu_ZF
, var
);
429 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
431 tcg_gen_add_i32(t0
, t0
, t1
);
432 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
435 /* dest = T0 + T1 + CF. */
436 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
438 tcg_gen_add_i32(dest
, t0
, t1
);
439 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
442 /* dest = T0 - T1 + CF - 1. */
443 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
445 tcg_gen_sub_i32(dest
, t0
, t1
);
446 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
447 tcg_gen_subi_i32(dest
, dest
, 1);
450 /* dest = T0 + T1. Compute C, N, V and Z flags */
451 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
453 TCGv_i32 tmp
= tcg_temp_new_i32();
454 tcg_gen_movi_i32(tmp
, 0);
455 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
456 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
457 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
458 tcg_gen_xor_i32(tmp
, t0
, t1
);
459 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
460 tcg_temp_free_i32(tmp
);
461 tcg_gen_mov_i32(dest
, cpu_NF
);
464 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
465 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
467 TCGv_i32 tmp
= tcg_temp_new_i32();
468 if (TCG_TARGET_HAS_add2_i32
) {
469 tcg_gen_movi_i32(tmp
, 0);
470 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
471 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
473 TCGv_i64 q0
= tcg_temp_new_i64();
474 TCGv_i64 q1
= tcg_temp_new_i64();
475 tcg_gen_extu_i32_i64(q0
, t0
);
476 tcg_gen_extu_i32_i64(q1
, t1
);
477 tcg_gen_add_i64(q0
, q0
, q1
);
478 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
479 tcg_gen_add_i64(q0
, q0
, q1
);
480 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
481 tcg_temp_free_i64(q0
);
482 tcg_temp_free_i64(q1
);
484 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
485 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
486 tcg_gen_xor_i32(tmp
, t0
, t1
);
487 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
488 tcg_temp_free_i32(tmp
);
489 tcg_gen_mov_i32(dest
, cpu_NF
);
492 /* dest = T0 - T1. Compute C, N, V and Z flags */
493 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
496 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
497 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
498 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
499 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
500 tmp
= tcg_temp_new_i32();
501 tcg_gen_xor_i32(tmp
, t0
, t1
);
502 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
503 tcg_temp_free_i32(tmp
);
504 tcg_gen_mov_i32(dest
, cpu_NF
);
507 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
508 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
510 TCGv_i32 tmp
= tcg_temp_new_i32();
511 tcg_gen_not_i32(tmp
, t1
);
512 gen_adc_CC(dest
, t0
, tmp
);
513 tcg_temp_free_i32(tmp
);
516 #define GEN_SHIFT(name) \
517 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
519 TCGv_i32 tmp1, tmp2, tmp3; \
520 tmp1 = tcg_temp_new_i32(); \
521 tcg_gen_andi_i32(tmp1, t1, 0xff); \
522 tmp2 = tcg_const_i32(0); \
523 tmp3 = tcg_const_i32(0x1f); \
524 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
525 tcg_temp_free_i32(tmp3); \
526 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
527 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
528 tcg_temp_free_i32(tmp2); \
529 tcg_temp_free_i32(tmp1); \
535 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
538 tmp1
= tcg_temp_new_i32();
539 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
540 tmp2
= tcg_const_i32(0x1f);
541 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
542 tcg_temp_free_i32(tmp2
);
543 tcg_gen_sar_i32(dest
, t0
, tmp1
);
544 tcg_temp_free_i32(tmp1
);
547 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
549 TCGv_i32 c0
= tcg_const_i32(0);
550 TCGv_i32 tmp
= tcg_temp_new_i32();
551 tcg_gen_neg_i32(tmp
, src
);
552 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
553 tcg_temp_free_i32(c0
);
554 tcg_temp_free_i32(tmp
);
557 static void shifter_out_im(TCGv_i32 var
, int shift
)
560 tcg_gen_andi_i32(cpu_CF
, var
, 1);
562 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
564 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
569 /* Shift by immediate. Includes special handling for shift == 0. */
570 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
571 int shift
, int flags
)
577 shifter_out_im(var
, 32 - shift
);
578 tcg_gen_shli_i32(var
, var
, shift
);
584 tcg_gen_shri_i32(cpu_CF
, var
, 31);
586 tcg_gen_movi_i32(var
, 0);
589 shifter_out_im(var
, shift
- 1);
590 tcg_gen_shri_i32(var
, var
, shift
);
597 shifter_out_im(var
, shift
- 1);
600 tcg_gen_sari_i32(var
, var
, shift
);
602 case 3: /* ROR/RRX */
605 shifter_out_im(var
, shift
- 1);
606 tcg_gen_rotri_i32(var
, var
, shift
); break;
608 TCGv_i32 tmp
= tcg_temp_new_i32();
609 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
611 shifter_out_im(var
, 0);
612 tcg_gen_shri_i32(var
, var
, 1);
613 tcg_gen_or_i32(var
, var
, tmp
);
614 tcg_temp_free_i32(tmp
);
619 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
620 TCGv_i32 shift
, int flags
)
624 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
625 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
626 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
627 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
632 gen_shl(var
, var
, shift
);
635 gen_shr(var
, var
, shift
);
638 gen_sar(var
, var
, shift
);
640 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
641 tcg_gen_rotr_i32(var
, var
, shift
); break;
644 tcg_temp_free_i32(shift
);
647 #define PAS_OP(pfx) \
649 case 0: gen_pas_helper(glue(pfx,add16)); break; \
650 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
651 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
652 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
653 case 4: gen_pas_helper(glue(pfx,add8)); break; \
654 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
656 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
661 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
663 tmp
= tcg_temp_new_ptr();
664 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
666 tcg_temp_free_ptr(tmp
);
669 tmp
= tcg_temp_new_ptr();
670 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
672 tcg_temp_free_ptr(tmp
);
674 #undef gen_pas_helper
675 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
688 #undef gen_pas_helper
693 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
694 #define PAS_OP(pfx) \
696 case 0: gen_pas_helper(glue(pfx,add8)); break; \
697 case 1: gen_pas_helper(glue(pfx,add16)); break; \
698 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
699 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
700 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
701 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
703 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
708 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
710 tmp
= tcg_temp_new_ptr();
711 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
713 tcg_temp_free_ptr(tmp
);
716 tmp
= tcg_temp_new_ptr();
717 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
719 tcg_temp_free_ptr(tmp
);
721 #undef gen_pas_helper
722 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
735 #undef gen_pas_helper
741 * generate a conditional branch based on ARM condition code cc.
742 * This is common between ARM and Aarch64 targets.
744 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
751 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
754 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
757 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
760 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
763 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
766 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
769 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
772 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
774 case 8: /* hi: C && !Z */
775 inv
= gen_new_label();
776 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
777 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
780 case 9: /* ls: !C || Z */
781 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
782 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
784 case 10: /* ge: N == V -> N ^ V == 0 */
785 tmp
= tcg_temp_new_i32();
786 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
787 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
788 tcg_temp_free_i32(tmp
);
790 case 11: /* lt: N != V -> N ^ V != 0 */
791 tmp
= tcg_temp_new_i32();
792 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
793 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
794 tcg_temp_free_i32(tmp
);
796 case 12: /* gt: !Z && N == V */
797 inv
= gen_new_label();
798 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
799 tmp
= tcg_temp_new_i32();
800 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
801 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
802 tcg_temp_free_i32(tmp
);
805 case 13: /* le: Z || N != V */
806 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
807 tmp
= tcg_temp_new_i32();
808 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
809 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
810 tcg_temp_free_i32(tmp
);
813 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
818 static const uint8_t table_logic_cc
[16] = {
837 /* Set PC and Thumb state from an immediate address. */
838 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
842 s
->is_jmp
= DISAS_UPDATE
;
843 if (s
->thumb
!= (addr
& 1)) {
844 tmp
= tcg_temp_new_i32();
845 tcg_gen_movi_i32(tmp
, addr
& 1);
846 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
847 tcg_temp_free_i32(tmp
);
849 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
852 /* Set PC and Thumb state from var. var is marked as dead. */
853 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
855 s
->is_jmp
= DISAS_UPDATE
;
856 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
857 tcg_gen_andi_i32(var
, var
, 1);
858 store_cpu_field(var
, thumb
);
861 /* Variant of store_reg which uses branch&exchange logic when storing
862 to r15 in ARM architecture v7 and above. The source must be a temporary
863 and will be marked as dead. */
864 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
866 if (reg
== 15 && ENABLE_ARCH_7
) {
869 store_reg(s
, reg
, var
);
873 /* Variant of store_reg which uses branch&exchange logic when storing
874 * to r15 in ARM architecture v5T and above. This is used for storing
875 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
876 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
877 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
879 if (reg
== 15 && ENABLE_ARCH_5
) {
882 store_reg(s
, reg
, var
);
886 /* Abstractions of "generate code to do a guest load/store for
887 * AArch32", where a vaddr is always 32 bits (and is zero
888 * extended if we're a 64 bit core) and data is also
889 * 32 bits unless specifically doing a 64 bit access.
890 * These functions work like tcg_gen_qemu_{ld,st}* except
891 * that the address argument is TCGv_i32 rather than TCGv.
893 #if TARGET_LONG_BITS == 32
895 #define DO_GEN_LD(SUFF, OPC) \
896 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
898 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
901 #define DO_GEN_ST(SUFF, OPC) \
902 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
904 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
907 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
909 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
912 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
914 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
919 #define DO_GEN_LD(SUFF, OPC) \
920 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
922 TCGv addr64 = tcg_temp_new(); \
923 tcg_gen_extu_i32_i64(addr64, addr); \
924 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
925 tcg_temp_free(addr64); \
928 #define DO_GEN_ST(SUFF, OPC) \
929 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
931 TCGv addr64 = tcg_temp_new(); \
932 tcg_gen_extu_i32_i64(addr64, addr); \
933 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
934 tcg_temp_free(addr64); \
937 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
939 TCGv addr64
= tcg_temp_new();
940 tcg_gen_extu_i32_i64(addr64
, addr
);
941 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
942 tcg_temp_free(addr64
);
945 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
947 TCGv addr64
= tcg_temp_new();
948 tcg_gen_extu_i32_i64(addr64
, addr
);
949 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
950 tcg_temp_free(addr64
);
957 DO_GEN_LD(16s
, MO_TESW
)
958 DO_GEN_LD(16u, MO_TEUW
)
959 DO_GEN_LD(32u, MO_TEUL
)
961 DO_GEN_ST(16, MO_TEUW
)
962 DO_GEN_ST(32, MO_TEUL
)
964 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
966 tcg_gen_movi_i32(cpu_R
[15], val
);
969 static inline void gen_hvc(DisasContext
*s
, int imm16
)
971 /* The pre HVC helper handles cases when HVC gets trapped
972 * as an undefined insn by runtime configuration (ie before
973 * the insn really executes).
975 gen_set_pc_im(s
, s
->pc
- 4);
976 gen_helper_pre_hvc(cpu_env
);
977 /* Otherwise we will treat this as a real exception which
978 * happens after execution of the insn. (The distinction matters
979 * for the PC value reported to the exception handler and also
980 * for single stepping.)
983 gen_set_pc_im(s
, s
->pc
);
984 s
->is_jmp
= DISAS_HVC
;
987 static inline void gen_smc(DisasContext
*s
)
989 /* As with HVC, we may take an exception either before or after
994 gen_set_pc_im(s
, s
->pc
- 4);
995 tmp
= tcg_const_i32(syn_aa32_smc());
996 gen_helper_pre_smc(cpu_env
, tmp
);
997 tcg_temp_free_i32(tmp
);
998 gen_set_pc_im(s
, s
->pc
);
999 s
->is_jmp
= DISAS_SMC
;
1003 gen_set_condexec (DisasContext
*s
)
1005 if (s
->condexec_mask
) {
1006 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1007 TCGv_i32 tmp
= tcg_temp_new_i32();
1008 tcg_gen_movi_i32(tmp
, val
);
1009 store_cpu_field(tmp
, condexec_bits
);
1013 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1015 gen_set_condexec(s
);
1016 gen_set_pc_im(s
, s
->pc
- offset
);
1017 gen_exception_internal(excp
);
1018 s
->is_jmp
= DISAS_JUMP
;
1021 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1022 int syn
, uint32_t target_el
)
1024 gen_set_condexec(s
);
1025 gen_set_pc_im(s
, s
->pc
- offset
);
1026 gen_exception(excp
, syn
, target_el
);
1027 s
->is_jmp
= DISAS_JUMP
;
1030 /* Force a TB lookup after an instruction that changes the CPU state. */
1031 static inline void gen_lookup_tb(DisasContext
*s
)
1033 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1034 s
->is_jmp
= DISAS_UPDATE
;
1037 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1040 int val
, rm
, shift
, shiftop
;
1043 if (!(insn
& (1 << 25))) {
1046 if (!(insn
& (1 << 23)))
1049 tcg_gen_addi_i32(var
, var
, val
);
1051 /* shift/register */
1053 shift
= (insn
>> 7) & 0x1f;
1054 shiftop
= (insn
>> 5) & 3;
1055 offset
= load_reg(s
, rm
);
1056 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1057 if (!(insn
& (1 << 23)))
1058 tcg_gen_sub_i32(var
, var
, offset
);
1060 tcg_gen_add_i32(var
, var
, offset
);
1061 tcg_temp_free_i32(offset
);
1065 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1066 int extra
, TCGv_i32 var
)
1071 if (insn
& (1 << 22)) {
1073 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1074 if (!(insn
& (1 << 23)))
1078 tcg_gen_addi_i32(var
, var
, val
);
1082 tcg_gen_addi_i32(var
, var
, extra
);
1084 offset
= load_reg(s
, rm
);
1085 if (!(insn
& (1 << 23)))
1086 tcg_gen_sub_i32(var
, var
, offset
);
1088 tcg_gen_add_i32(var
, var
, offset
);
1089 tcg_temp_free_i32(offset
);
1093 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1095 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1098 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1100 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1102 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1106 #define VFP_OP2(name) \
1107 static inline void gen_vfp_##name(int dp) \
1109 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1111 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1113 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1115 tcg_temp_free_ptr(fpst); \
1125 static inline void gen_vfp_F1_mul(int dp
)
1127 /* Like gen_vfp_mul() but put result in F1 */
1128 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1130 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1132 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1134 tcg_temp_free_ptr(fpst
);
1137 static inline void gen_vfp_F1_neg(int dp
)
1139 /* Like gen_vfp_neg() but put result in F1 */
1141 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1143 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1147 static inline void gen_vfp_abs(int dp
)
1150 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1152 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1155 static inline void gen_vfp_neg(int dp
)
1158 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1160 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1163 static inline void gen_vfp_sqrt(int dp
)
1166 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1168 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1171 static inline void gen_vfp_cmp(int dp
)
1174 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1176 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1179 static inline void gen_vfp_cmpe(int dp
)
1182 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1184 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1187 static inline void gen_vfp_F1_ld0(int dp
)
1190 tcg_gen_movi_i64(cpu_F1d
, 0);
1192 tcg_gen_movi_i32(cpu_F1s
, 0);
1195 #define VFP_GEN_ITOF(name) \
1196 static inline void gen_vfp_##name(int dp, int neon) \
1198 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1200 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1202 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1204 tcg_temp_free_ptr(statusptr); \
1211 #define VFP_GEN_FTOI(name) \
1212 static inline void gen_vfp_##name(int dp, int neon) \
1214 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1216 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1218 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1220 tcg_temp_free_ptr(statusptr); \
1229 #define VFP_GEN_FIX(name, round) \
1230 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1232 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1233 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1235 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1238 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1241 tcg_temp_free_i32(tmp_shift); \
1242 tcg_temp_free_ptr(statusptr); \
1244 VFP_GEN_FIX(tosh
, _round_to_zero
)
1245 VFP_GEN_FIX(tosl
, _round_to_zero
)
1246 VFP_GEN_FIX(touh
, _round_to_zero
)
1247 VFP_GEN_FIX(toul
, _round_to_zero
)
1254 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1257 gen_aa32_ld64(cpu_F0d
, addr
, get_mem_index(s
));
1259 gen_aa32_ld32u(cpu_F0s
, addr
, get_mem_index(s
));
1263 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1266 gen_aa32_st64(cpu_F0d
, addr
, get_mem_index(s
));
1268 gen_aa32_st32(cpu_F0s
, addr
, get_mem_index(s
));
1273 vfp_reg_offset (int dp
, int reg
)
1276 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1278 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1279 + offsetof(CPU_DoubleU
, l
.upper
);
1281 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1282 + offsetof(CPU_DoubleU
, l
.lower
);
1286 /* Return the offset of a 32-bit piece of a NEON register.
1287 zero is the least significant end of the register. */
1289 neon_reg_offset (int reg
, int n
)
1293 return vfp_reg_offset(0, sreg
);
1296 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1298 TCGv_i32 tmp
= tcg_temp_new_i32();
1299 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1303 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1305 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1306 tcg_temp_free_i32(var
);
1309 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1311 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1314 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1316 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1319 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1320 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1321 #define tcg_gen_st_f32 tcg_gen_st_i32
1322 #define tcg_gen_st_f64 tcg_gen_st_i64
1324 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1327 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1329 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1332 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1335 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1337 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1340 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1343 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1345 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1348 #define ARM_CP_RW_BIT (1 << 20)
1350 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1352 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1355 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1357 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1360 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1362 TCGv_i32 var
= tcg_temp_new_i32();
1363 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1367 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1369 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1370 tcg_temp_free_i32(var
);
1373 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1375 iwmmxt_store_reg(cpu_M0
, rn
);
1378 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1380 iwmmxt_load_reg(cpu_M0
, rn
);
1383 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1385 iwmmxt_load_reg(cpu_V1
, rn
);
1386 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1389 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1391 iwmmxt_load_reg(cpu_V1
, rn
);
1392 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1395 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1397 iwmmxt_load_reg(cpu_V1
, rn
);
1398 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1401 #define IWMMXT_OP(name) \
1402 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1404 iwmmxt_load_reg(cpu_V1, rn); \
1405 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1408 #define IWMMXT_OP_ENV(name) \
1409 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1411 iwmmxt_load_reg(cpu_V1, rn); \
1412 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1415 #define IWMMXT_OP_ENV_SIZE(name) \
1416 IWMMXT_OP_ENV(name##b) \
1417 IWMMXT_OP_ENV(name##w) \
1418 IWMMXT_OP_ENV(name##l)
1420 #define IWMMXT_OP_ENV1(name) \
1421 static inline void gen_op_iwmmxt_##name##_M0(void) \
1423 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1437 IWMMXT_OP_ENV_SIZE(unpackl
)
1438 IWMMXT_OP_ENV_SIZE(unpackh
)
1440 IWMMXT_OP_ENV1(unpacklub
)
1441 IWMMXT_OP_ENV1(unpackluw
)
1442 IWMMXT_OP_ENV1(unpacklul
)
1443 IWMMXT_OP_ENV1(unpackhub
)
1444 IWMMXT_OP_ENV1(unpackhuw
)
1445 IWMMXT_OP_ENV1(unpackhul
)
1446 IWMMXT_OP_ENV1(unpacklsb
)
1447 IWMMXT_OP_ENV1(unpacklsw
)
1448 IWMMXT_OP_ENV1(unpacklsl
)
1449 IWMMXT_OP_ENV1(unpackhsb
)
1450 IWMMXT_OP_ENV1(unpackhsw
)
1451 IWMMXT_OP_ENV1(unpackhsl
)
1453 IWMMXT_OP_ENV_SIZE(cmpeq
)
1454 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1455 IWMMXT_OP_ENV_SIZE(cmpgts
)
1457 IWMMXT_OP_ENV_SIZE(mins
)
1458 IWMMXT_OP_ENV_SIZE(minu
)
1459 IWMMXT_OP_ENV_SIZE(maxs
)
1460 IWMMXT_OP_ENV_SIZE(maxu
)
1462 IWMMXT_OP_ENV_SIZE(subn
)
1463 IWMMXT_OP_ENV_SIZE(addn
)
1464 IWMMXT_OP_ENV_SIZE(subu
)
1465 IWMMXT_OP_ENV_SIZE(addu
)
1466 IWMMXT_OP_ENV_SIZE(subs
)
1467 IWMMXT_OP_ENV_SIZE(adds
)
1469 IWMMXT_OP_ENV(avgb0
)
1470 IWMMXT_OP_ENV(avgb1
)
1471 IWMMXT_OP_ENV(avgw0
)
1472 IWMMXT_OP_ENV(avgw1
)
1474 IWMMXT_OP_ENV(packuw
)
1475 IWMMXT_OP_ENV(packul
)
1476 IWMMXT_OP_ENV(packuq
)
1477 IWMMXT_OP_ENV(packsw
)
1478 IWMMXT_OP_ENV(packsl
)
1479 IWMMXT_OP_ENV(packsq
)
1481 static void gen_op_iwmmxt_set_mup(void)
1484 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1485 tcg_gen_ori_i32(tmp
, tmp
, 2);
1486 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1489 static void gen_op_iwmmxt_set_cup(void)
1492 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1493 tcg_gen_ori_i32(tmp
, tmp
, 1);
1494 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1497 static void gen_op_iwmmxt_setpsr_nz(void)
1499 TCGv_i32 tmp
= tcg_temp_new_i32();
1500 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1501 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1504 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1506 iwmmxt_load_reg(cpu_V1
, rn
);
1507 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1508 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1511 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1518 rd
= (insn
>> 16) & 0xf;
1519 tmp
= load_reg(s
, rd
);
1521 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1522 if (insn
& (1 << 24)) {
1524 if (insn
& (1 << 23))
1525 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1527 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1528 tcg_gen_mov_i32(dest
, tmp
);
1529 if (insn
& (1 << 21))
1530 store_reg(s
, rd
, tmp
);
1532 tcg_temp_free_i32(tmp
);
1533 } else if (insn
& (1 << 21)) {
1535 tcg_gen_mov_i32(dest
, tmp
);
1536 if (insn
& (1 << 23))
1537 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1539 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1540 store_reg(s
, rd
, tmp
);
1541 } else if (!(insn
& (1 << 23)))
1546 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1548 int rd
= (insn
>> 0) & 0xf;
1551 if (insn
& (1 << 8)) {
1552 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1555 tmp
= iwmmxt_load_creg(rd
);
1558 tmp
= tcg_temp_new_i32();
1559 iwmmxt_load_reg(cpu_V0
, rd
);
1560 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1562 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1563 tcg_gen_mov_i32(dest
, tmp
);
1564 tcg_temp_free_i32(tmp
);
1568 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1569 (ie. an undefined instruction). */
1570 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1573 int rdhi
, rdlo
, rd0
, rd1
, i
;
1575 TCGv_i32 tmp
, tmp2
, tmp3
;
1577 if ((insn
& 0x0e000e00) == 0x0c000000) {
1578 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1580 rdlo
= (insn
>> 12) & 0xf;
1581 rdhi
= (insn
>> 16) & 0xf;
1582 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1583 iwmmxt_load_reg(cpu_V0
, wrd
);
1584 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1585 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1586 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1587 } else { /* TMCRR */
1588 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1589 iwmmxt_store_reg(cpu_V0
, wrd
);
1590 gen_op_iwmmxt_set_mup();
1595 wrd
= (insn
>> 12) & 0xf;
1596 addr
= tcg_temp_new_i32();
1597 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1598 tcg_temp_free_i32(addr
);
1601 if (insn
& ARM_CP_RW_BIT
) {
1602 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1603 tmp
= tcg_temp_new_i32();
1604 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1605 iwmmxt_store_creg(wrd
, tmp
);
1608 if (insn
& (1 << 8)) {
1609 if (insn
& (1 << 22)) { /* WLDRD */
1610 gen_aa32_ld64(cpu_M0
, addr
, get_mem_index(s
));
1612 } else { /* WLDRW wRd */
1613 tmp
= tcg_temp_new_i32();
1614 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1617 tmp
= tcg_temp_new_i32();
1618 if (insn
& (1 << 22)) { /* WLDRH */
1619 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
1620 } else { /* WLDRB */
1621 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
1625 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1626 tcg_temp_free_i32(tmp
);
1628 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1631 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1632 tmp
= iwmmxt_load_creg(wrd
);
1633 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1635 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1636 tmp
= tcg_temp_new_i32();
1637 if (insn
& (1 << 8)) {
1638 if (insn
& (1 << 22)) { /* WSTRD */
1639 gen_aa32_st64(cpu_M0
, addr
, get_mem_index(s
));
1640 } else { /* WSTRW wRd */
1641 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1642 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1645 if (insn
& (1 << 22)) { /* WSTRH */
1646 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1647 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
1648 } else { /* WSTRB */
1649 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1650 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
1654 tcg_temp_free_i32(tmp
);
1656 tcg_temp_free_i32(addr
);
1660 if ((insn
& 0x0f000000) != 0x0e000000)
1663 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1664 case 0x000: /* WOR */
1665 wrd
= (insn
>> 12) & 0xf;
1666 rd0
= (insn
>> 0) & 0xf;
1667 rd1
= (insn
>> 16) & 0xf;
1668 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1669 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1670 gen_op_iwmmxt_setpsr_nz();
1671 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1672 gen_op_iwmmxt_set_mup();
1673 gen_op_iwmmxt_set_cup();
1675 case 0x011: /* TMCR */
1678 rd
= (insn
>> 12) & 0xf;
1679 wrd
= (insn
>> 16) & 0xf;
1681 case ARM_IWMMXT_wCID
:
1682 case ARM_IWMMXT_wCASF
:
1684 case ARM_IWMMXT_wCon
:
1685 gen_op_iwmmxt_set_cup();
1687 case ARM_IWMMXT_wCSSF
:
1688 tmp
= iwmmxt_load_creg(wrd
);
1689 tmp2
= load_reg(s
, rd
);
1690 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1691 tcg_temp_free_i32(tmp2
);
1692 iwmmxt_store_creg(wrd
, tmp
);
1694 case ARM_IWMMXT_wCGR0
:
1695 case ARM_IWMMXT_wCGR1
:
1696 case ARM_IWMMXT_wCGR2
:
1697 case ARM_IWMMXT_wCGR3
:
1698 gen_op_iwmmxt_set_cup();
1699 tmp
= load_reg(s
, rd
);
1700 iwmmxt_store_creg(wrd
, tmp
);
1706 case 0x100: /* WXOR */
1707 wrd
= (insn
>> 12) & 0xf;
1708 rd0
= (insn
>> 0) & 0xf;
1709 rd1
= (insn
>> 16) & 0xf;
1710 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1711 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1712 gen_op_iwmmxt_setpsr_nz();
1713 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1714 gen_op_iwmmxt_set_mup();
1715 gen_op_iwmmxt_set_cup();
1717 case 0x111: /* TMRC */
1720 rd
= (insn
>> 12) & 0xf;
1721 wrd
= (insn
>> 16) & 0xf;
1722 tmp
= iwmmxt_load_creg(wrd
);
1723 store_reg(s
, rd
, tmp
);
1725 case 0x300: /* WANDN */
1726 wrd
= (insn
>> 12) & 0xf;
1727 rd0
= (insn
>> 0) & 0xf;
1728 rd1
= (insn
>> 16) & 0xf;
1729 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1730 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1731 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1732 gen_op_iwmmxt_setpsr_nz();
1733 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1734 gen_op_iwmmxt_set_mup();
1735 gen_op_iwmmxt_set_cup();
1737 case 0x200: /* WAND */
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_andq_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 0x810: case 0xa10: /* WMADD */
1749 wrd
= (insn
>> 12) & 0xf;
1750 rd0
= (insn
>> 0) & 0xf;
1751 rd1
= (insn
>> 16) & 0xf;
1752 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1753 if (insn
& (1 << 21))
1754 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1756 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1757 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1758 gen_op_iwmmxt_set_mup();
1760 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1761 wrd
= (insn
>> 12) & 0xf;
1762 rd0
= (insn
>> 16) & 0xf;
1763 rd1
= (insn
>> 0) & 0xf;
1764 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1765 switch ((insn
>> 22) & 3) {
1767 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1770 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1773 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1778 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1779 gen_op_iwmmxt_set_mup();
1780 gen_op_iwmmxt_set_cup();
1782 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1783 wrd
= (insn
>> 12) & 0xf;
1784 rd0
= (insn
>> 16) & 0xf;
1785 rd1
= (insn
>> 0) & 0xf;
1786 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1787 switch ((insn
>> 22) & 3) {
1789 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1792 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1795 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1800 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1801 gen_op_iwmmxt_set_mup();
1802 gen_op_iwmmxt_set_cup();
1804 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1805 wrd
= (insn
>> 12) & 0xf;
1806 rd0
= (insn
>> 16) & 0xf;
1807 rd1
= (insn
>> 0) & 0xf;
1808 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1809 if (insn
& (1 << 22))
1810 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1812 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1813 if (!(insn
& (1 << 20)))
1814 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1815 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1816 gen_op_iwmmxt_set_mup();
1818 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1819 wrd
= (insn
>> 12) & 0xf;
1820 rd0
= (insn
>> 16) & 0xf;
1821 rd1
= (insn
>> 0) & 0xf;
1822 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1823 if (insn
& (1 << 21)) {
1824 if (insn
& (1 << 20))
1825 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1827 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1829 if (insn
& (1 << 20))
1830 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1832 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1834 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1835 gen_op_iwmmxt_set_mup();
1837 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1838 wrd
= (insn
>> 12) & 0xf;
1839 rd0
= (insn
>> 16) & 0xf;
1840 rd1
= (insn
>> 0) & 0xf;
1841 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1842 if (insn
& (1 << 21))
1843 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1845 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1846 if (!(insn
& (1 << 20))) {
1847 iwmmxt_load_reg(cpu_V1
, wrd
);
1848 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1850 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1851 gen_op_iwmmxt_set_mup();
1853 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1854 wrd
= (insn
>> 12) & 0xf;
1855 rd0
= (insn
>> 16) & 0xf;
1856 rd1
= (insn
>> 0) & 0xf;
1857 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1858 switch ((insn
>> 22) & 3) {
1860 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1863 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1866 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1871 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1872 gen_op_iwmmxt_set_mup();
1873 gen_op_iwmmxt_set_cup();
1875 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1876 wrd
= (insn
>> 12) & 0xf;
1877 rd0
= (insn
>> 16) & 0xf;
1878 rd1
= (insn
>> 0) & 0xf;
1879 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1880 if (insn
& (1 << 22)) {
1881 if (insn
& (1 << 20))
1882 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1884 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1886 if (insn
& (1 << 20))
1887 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1889 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1891 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1892 gen_op_iwmmxt_set_mup();
1893 gen_op_iwmmxt_set_cup();
1895 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1896 wrd
= (insn
>> 12) & 0xf;
1897 rd0
= (insn
>> 16) & 0xf;
1898 rd1
= (insn
>> 0) & 0xf;
1899 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1900 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1901 tcg_gen_andi_i32(tmp
, tmp
, 7);
1902 iwmmxt_load_reg(cpu_V1
, rd1
);
1903 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1904 tcg_temp_free_i32(tmp
);
1905 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1906 gen_op_iwmmxt_set_mup();
1908 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1909 if (((insn
>> 6) & 3) == 3)
1911 rd
= (insn
>> 12) & 0xf;
1912 wrd
= (insn
>> 16) & 0xf;
1913 tmp
= load_reg(s
, rd
);
1914 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1915 switch ((insn
>> 6) & 3) {
1917 tmp2
= tcg_const_i32(0xff);
1918 tmp3
= tcg_const_i32((insn
& 7) << 3);
1921 tmp2
= tcg_const_i32(0xffff);
1922 tmp3
= tcg_const_i32((insn
& 3) << 4);
1925 tmp2
= tcg_const_i32(0xffffffff);
1926 tmp3
= tcg_const_i32((insn
& 1) << 5);
1929 TCGV_UNUSED_I32(tmp2
);
1930 TCGV_UNUSED_I32(tmp3
);
1932 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1933 tcg_temp_free_i32(tmp3
);
1934 tcg_temp_free_i32(tmp2
);
1935 tcg_temp_free_i32(tmp
);
1936 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1937 gen_op_iwmmxt_set_mup();
1939 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1940 rd
= (insn
>> 12) & 0xf;
1941 wrd
= (insn
>> 16) & 0xf;
1942 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1944 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1945 tmp
= tcg_temp_new_i32();
1946 switch ((insn
>> 22) & 3) {
1948 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1949 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1951 tcg_gen_ext8s_i32(tmp
, tmp
);
1953 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1957 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1958 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1960 tcg_gen_ext16s_i32(tmp
, tmp
);
1962 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1966 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1967 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1970 store_reg(s
, rd
, tmp
);
1972 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1973 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1975 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1976 switch ((insn
>> 22) & 3) {
1978 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1981 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1984 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1987 tcg_gen_shli_i32(tmp
, tmp
, 28);
1989 tcg_temp_free_i32(tmp
);
1991 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1992 if (((insn
>> 6) & 3) == 3)
1994 rd
= (insn
>> 12) & 0xf;
1995 wrd
= (insn
>> 16) & 0xf;
1996 tmp
= load_reg(s
, rd
);
1997 switch ((insn
>> 6) & 3) {
1999 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2002 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2005 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2008 tcg_temp_free_i32(tmp
);
2009 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2010 gen_op_iwmmxt_set_mup();
2012 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2013 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2015 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2016 tmp2
= tcg_temp_new_i32();
2017 tcg_gen_mov_i32(tmp2
, tmp
);
2018 switch ((insn
>> 22) & 3) {
2020 for (i
= 0; i
< 7; i
++) {
2021 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2022 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2026 for (i
= 0; i
< 3; i
++) {
2027 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2028 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2032 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2033 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2037 tcg_temp_free_i32(tmp2
);
2038 tcg_temp_free_i32(tmp
);
2040 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2041 wrd
= (insn
>> 12) & 0xf;
2042 rd0
= (insn
>> 16) & 0xf;
2043 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2044 switch ((insn
>> 22) & 3) {
2046 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2049 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2052 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2057 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2058 gen_op_iwmmxt_set_mup();
2060 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2061 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2063 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2064 tmp2
= tcg_temp_new_i32();
2065 tcg_gen_mov_i32(tmp2
, tmp
);
2066 switch ((insn
>> 22) & 3) {
2068 for (i
= 0; i
< 7; i
++) {
2069 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2070 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2074 for (i
= 0; i
< 3; i
++) {
2075 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2076 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2080 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2081 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2085 tcg_temp_free_i32(tmp2
);
2086 tcg_temp_free_i32(tmp
);
2088 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2089 rd
= (insn
>> 12) & 0xf;
2090 rd0
= (insn
>> 16) & 0xf;
2091 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2093 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2094 tmp
= tcg_temp_new_i32();
2095 switch ((insn
>> 22) & 3) {
2097 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2100 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2103 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2106 store_reg(s
, rd
, tmp
);
2108 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2109 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2110 wrd
= (insn
>> 12) & 0xf;
2111 rd0
= (insn
>> 16) & 0xf;
2112 rd1
= (insn
>> 0) & 0xf;
2113 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2114 switch ((insn
>> 22) & 3) {
2116 if (insn
& (1 << 21))
2117 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2119 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2122 if (insn
& (1 << 21))
2123 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2125 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2128 if (insn
& (1 << 21))
2129 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2131 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2136 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2137 gen_op_iwmmxt_set_mup();
2138 gen_op_iwmmxt_set_cup();
2140 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2141 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2142 wrd
= (insn
>> 12) & 0xf;
2143 rd0
= (insn
>> 16) & 0xf;
2144 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2145 switch ((insn
>> 22) & 3) {
2147 if (insn
& (1 << 21))
2148 gen_op_iwmmxt_unpacklsb_M0();
2150 gen_op_iwmmxt_unpacklub_M0();
2153 if (insn
& (1 << 21))
2154 gen_op_iwmmxt_unpacklsw_M0();
2156 gen_op_iwmmxt_unpackluw_M0();
2159 if (insn
& (1 << 21))
2160 gen_op_iwmmxt_unpacklsl_M0();
2162 gen_op_iwmmxt_unpacklul_M0();
2167 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2168 gen_op_iwmmxt_set_mup();
2169 gen_op_iwmmxt_set_cup();
2171 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2172 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
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_unpackhsb_M0();
2181 gen_op_iwmmxt_unpackhub_M0();
2184 if (insn
& (1 << 21))
2185 gen_op_iwmmxt_unpackhsw_M0();
2187 gen_op_iwmmxt_unpackhuw_M0();
2190 if (insn
& (1 << 21))
2191 gen_op_iwmmxt_unpackhsl_M0();
2193 gen_op_iwmmxt_unpackhul_M0();
2198 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2199 gen_op_iwmmxt_set_mup();
2200 gen_op_iwmmxt_set_cup();
2202 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2203 case 0x214: case 0x614: case 0xa14: case 0xe14:
2204 if (((insn
>> 22) & 3) == 0)
2206 wrd
= (insn
>> 12) & 0xf;
2207 rd0
= (insn
>> 16) & 0xf;
2208 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2209 tmp
= tcg_temp_new_i32();
2210 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2211 tcg_temp_free_i32(tmp
);
2214 switch ((insn
>> 22) & 3) {
2216 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2219 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2222 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2225 tcg_temp_free_i32(tmp
);
2226 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2227 gen_op_iwmmxt_set_mup();
2228 gen_op_iwmmxt_set_cup();
2230 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2231 case 0x014: case 0x414: case 0x814: case 0xc14:
2232 if (((insn
>> 22) & 3) == 0)
2234 wrd
= (insn
>> 12) & 0xf;
2235 rd0
= (insn
>> 16) & 0xf;
2236 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2237 tmp
= tcg_temp_new_i32();
2238 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2239 tcg_temp_free_i32(tmp
);
2242 switch ((insn
>> 22) & 3) {
2244 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2247 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2250 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2253 tcg_temp_free_i32(tmp
);
2254 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2255 gen_op_iwmmxt_set_mup();
2256 gen_op_iwmmxt_set_cup();
2258 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2259 case 0x114: case 0x514: case 0x914: case 0xd14:
2260 if (((insn
>> 22) & 3) == 0)
2262 wrd
= (insn
>> 12) & 0xf;
2263 rd0
= (insn
>> 16) & 0xf;
2264 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2265 tmp
= tcg_temp_new_i32();
2266 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2267 tcg_temp_free_i32(tmp
);
2270 switch ((insn
>> 22) & 3) {
2272 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2275 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2278 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2281 tcg_temp_free_i32(tmp
);
2282 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2283 gen_op_iwmmxt_set_mup();
2284 gen_op_iwmmxt_set_cup();
2286 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2287 case 0x314: case 0x714: case 0xb14: case 0xf14:
2288 if (((insn
>> 22) & 3) == 0)
2290 wrd
= (insn
>> 12) & 0xf;
2291 rd0
= (insn
>> 16) & 0xf;
2292 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2293 tmp
= tcg_temp_new_i32();
2294 switch ((insn
>> 22) & 3) {
2296 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2297 tcg_temp_free_i32(tmp
);
2300 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2303 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2304 tcg_temp_free_i32(tmp
);
2307 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2310 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2311 tcg_temp_free_i32(tmp
);
2314 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2317 tcg_temp_free_i32(tmp
);
2318 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2319 gen_op_iwmmxt_set_mup();
2320 gen_op_iwmmxt_set_cup();
2322 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2323 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2324 wrd
= (insn
>> 12) & 0xf;
2325 rd0
= (insn
>> 16) & 0xf;
2326 rd1
= (insn
>> 0) & 0xf;
2327 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2328 switch ((insn
>> 22) & 3) {
2330 if (insn
& (1 << 21))
2331 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2333 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2336 if (insn
& (1 << 21))
2337 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2339 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2342 if (insn
& (1 << 21))
2343 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2345 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2350 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2351 gen_op_iwmmxt_set_mup();
2353 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2354 case 0x816: case 0xa16: case 0xc16: case 0xe16:
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_maxsb_M0_wRn(rd1
);
2364 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2367 if (insn
& (1 << 21))
2368 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2370 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2373 if (insn
& (1 << 21))
2374 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2376 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2381 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2382 gen_op_iwmmxt_set_mup();
2384 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2385 case 0x402: case 0x502: case 0x602: case 0x702:
2386 wrd
= (insn
>> 12) & 0xf;
2387 rd0
= (insn
>> 16) & 0xf;
2388 rd1
= (insn
>> 0) & 0xf;
2389 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2390 tmp
= tcg_const_i32((insn
>> 20) & 3);
2391 iwmmxt_load_reg(cpu_V1
, rd1
);
2392 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2393 tcg_temp_free_i32(tmp
);
2394 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2395 gen_op_iwmmxt_set_mup();
2397 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2398 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2399 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2400 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2401 wrd
= (insn
>> 12) & 0xf;
2402 rd0
= (insn
>> 16) & 0xf;
2403 rd1
= (insn
>> 0) & 0xf;
2404 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2405 switch ((insn
>> 20) & 0xf) {
2407 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2410 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2413 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2416 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2419 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2422 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2425 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2428 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2431 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2436 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2437 gen_op_iwmmxt_set_mup();
2438 gen_op_iwmmxt_set_cup();
2440 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2441 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2442 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2443 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2444 wrd
= (insn
>> 12) & 0xf;
2445 rd0
= (insn
>> 16) & 0xf;
2446 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2447 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2448 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2449 tcg_temp_free_i32(tmp
);
2450 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2451 gen_op_iwmmxt_set_mup();
2452 gen_op_iwmmxt_set_cup();
2454 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2455 case 0x418: case 0x518: case 0x618: case 0x718:
2456 case 0x818: case 0x918: case 0xa18: case 0xb18:
2457 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2458 wrd
= (insn
>> 12) & 0xf;
2459 rd0
= (insn
>> 16) & 0xf;
2460 rd1
= (insn
>> 0) & 0xf;
2461 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2462 switch ((insn
>> 20) & 0xf) {
2464 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2467 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2470 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2473 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2476 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2479 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2482 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2485 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2488 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2493 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2494 gen_op_iwmmxt_set_mup();
2495 gen_op_iwmmxt_set_cup();
2497 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2498 case 0x408: case 0x508: case 0x608: case 0x708:
2499 case 0x808: case 0x908: case 0xa08: case 0xb08:
2500 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2501 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2503 wrd
= (insn
>> 12) & 0xf;
2504 rd0
= (insn
>> 16) & 0xf;
2505 rd1
= (insn
>> 0) & 0xf;
2506 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2507 switch ((insn
>> 22) & 3) {
2509 if (insn
& (1 << 21))
2510 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2512 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2515 if (insn
& (1 << 21))
2516 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2518 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2521 if (insn
& (1 << 21))
2522 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2524 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2527 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2528 gen_op_iwmmxt_set_mup();
2529 gen_op_iwmmxt_set_cup();
2531 case 0x201: case 0x203: case 0x205: case 0x207:
2532 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2533 case 0x211: case 0x213: case 0x215: case 0x217:
2534 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2535 wrd
= (insn
>> 5) & 0xf;
2536 rd0
= (insn
>> 12) & 0xf;
2537 rd1
= (insn
>> 0) & 0xf;
2538 if (rd0
== 0xf || rd1
== 0xf)
2540 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2541 tmp
= load_reg(s
, rd0
);
2542 tmp2
= load_reg(s
, rd1
);
2543 switch ((insn
>> 16) & 0xf) {
2544 case 0x0: /* TMIA */
2545 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2547 case 0x8: /* TMIAPH */
2548 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2550 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2551 if (insn
& (1 << 16))
2552 tcg_gen_shri_i32(tmp
, tmp
, 16);
2553 if (insn
& (1 << 17))
2554 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2555 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2558 tcg_temp_free_i32(tmp2
);
2559 tcg_temp_free_i32(tmp
);
2562 tcg_temp_free_i32(tmp2
);
2563 tcg_temp_free_i32(tmp
);
2564 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2565 gen_op_iwmmxt_set_mup();
2574 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2575 (ie. an undefined instruction). */
2576 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2578 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2581 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2582 /* Multiply with Internal Accumulate Format */
2583 rd0
= (insn
>> 12) & 0xf;
2585 acc
= (insn
>> 5) & 7;
2590 tmp
= load_reg(s
, rd0
);
2591 tmp2
= load_reg(s
, rd1
);
2592 switch ((insn
>> 16) & 0xf) {
2594 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2596 case 0x8: /* MIAPH */
2597 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2599 case 0xc: /* MIABB */
2600 case 0xd: /* MIABT */
2601 case 0xe: /* MIATB */
2602 case 0xf: /* MIATT */
2603 if (insn
& (1 << 16))
2604 tcg_gen_shri_i32(tmp
, tmp
, 16);
2605 if (insn
& (1 << 17))
2606 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2607 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2612 tcg_temp_free_i32(tmp2
);
2613 tcg_temp_free_i32(tmp
);
2615 gen_op_iwmmxt_movq_wRn_M0(acc
);
2619 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2620 /* Internal Accumulator Access Format */
2621 rdhi
= (insn
>> 16) & 0xf;
2622 rdlo
= (insn
>> 12) & 0xf;
2628 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2629 iwmmxt_load_reg(cpu_V0
, acc
);
2630 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2631 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2632 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2633 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2635 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2636 iwmmxt_store_reg(cpu_V0
, acc
);
2644 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2645 #define VFP_SREG(insn, bigbit, smallbit) \
2646 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2647 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2648 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2649 reg = (((insn) >> (bigbit)) & 0x0f) \
2650 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2652 if (insn & (1 << (smallbit))) \
2654 reg = ((insn) >> (bigbit)) & 0x0f; \
2657 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2658 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2659 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2660 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2661 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2662 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2664 /* Move between integer and VFP cores. */
2665 static TCGv_i32
gen_vfp_mrs(void)
2667 TCGv_i32 tmp
= tcg_temp_new_i32();
2668 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2672 static void gen_vfp_msr(TCGv_i32 tmp
)
2674 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2675 tcg_temp_free_i32(tmp
);
2678 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2680 TCGv_i32 tmp
= tcg_temp_new_i32();
2682 tcg_gen_shri_i32(var
, var
, shift
);
2683 tcg_gen_ext8u_i32(var
, var
);
2684 tcg_gen_shli_i32(tmp
, var
, 8);
2685 tcg_gen_or_i32(var
, var
, tmp
);
2686 tcg_gen_shli_i32(tmp
, var
, 16);
2687 tcg_gen_or_i32(var
, var
, tmp
);
2688 tcg_temp_free_i32(tmp
);
2691 static void gen_neon_dup_low16(TCGv_i32 var
)
2693 TCGv_i32 tmp
= tcg_temp_new_i32();
2694 tcg_gen_ext16u_i32(var
, var
);
2695 tcg_gen_shli_i32(tmp
, var
, 16);
2696 tcg_gen_or_i32(var
, var
, tmp
);
2697 tcg_temp_free_i32(tmp
);
2700 static void gen_neon_dup_high16(TCGv_i32 var
)
2702 TCGv_i32 tmp
= tcg_temp_new_i32();
2703 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2704 tcg_gen_shri_i32(tmp
, var
, 16);
2705 tcg_gen_or_i32(var
, var
, tmp
);
2706 tcg_temp_free_i32(tmp
);
2709 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2711 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2712 TCGv_i32 tmp
= tcg_temp_new_i32();
2715 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
2716 gen_neon_dup_u8(tmp
, 0);
2719 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
2720 gen_neon_dup_low16(tmp
);
2723 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
2725 default: /* Avoid compiler warnings. */
2731 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2734 uint32_t cc
= extract32(insn
, 20, 2);
2737 TCGv_i64 frn
, frm
, dest
;
2738 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2740 zero
= tcg_const_i64(0);
2742 frn
= tcg_temp_new_i64();
2743 frm
= tcg_temp_new_i64();
2744 dest
= tcg_temp_new_i64();
2746 zf
= tcg_temp_new_i64();
2747 nf
= tcg_temp_new_i64();
2748 vf
= tcg_temp_new_i64();
2750 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2751 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2752 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2754 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2755 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2758 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2762 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2765 case 2: /* ge: N == V -> N ^ V == 0 */
2766 tmp
= tcg_temp_new_i64();
2767 tcg_gen_xor_i64(tmp
, vf
, nf
);
2768 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2770 tcg_temp_free_i64(tmp
);
2772 case 3: /* gt: !Z && N == V */
2773 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2775 tmp
= tcg_temp_new_i64();
2776 tcg_gen_xor_i64(tmp
, vf
, nf
);
2777 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2779 tcg_temp_free_i64(tmp
);
2782 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2783 tcg_temp_free_i64(frn
);
2784 tcg_temp_free_i64(frm
);
2785 tcg_temp_free_i64(dest
);
2787 tcg_temp_free_i64(zf
);
2788 tcg_temp_free_i64(nf
);
2789 tcg_temp_free_i64(vf
);
2791 tcg_temp_free_i64(zero
);
2793 TCGv_i32 frn
, frm
, dest
;
2796 zero
= tcg_const_i32(0);
2798 frn
= tcg_temp_new_i32();
2799 frm
= tcg_temp_new_i32();
2800 dest
= tcg_temp_new_i32();
2801 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2802 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2805 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2809 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2812 case 2: /* ge: N == V -> N ^ V == 0 */
2813 tmp
= tcg_temp_new_i32();
2814 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2815 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2817 tcg_temp_free_i32(tmp
);
2819 case 3: /* gt: !Z && N == V */
2820 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2822 tmp
= tcg_temp_new_i32();
2823 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2824 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2826 tcg_temp_free_i32(tmp
);
2829 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2830 tcg_temp_free_i32(frn
);
2831 tcg_temp_free_i32(frm
);
2832 tcg_temp_free_i32(dest
);
2834 tcg_temp_free_i32(zero
);
2840 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2841 uint32_t rm
, uint32_t dp
)
2843 uint32_t vmin
= extract32(insn
, 6, 1);
2844 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2847 TCGv_i64 frn
, frm
, dest
;
2849 frn
= tcg_temp_new_i64();
2850 frm
= tcg_temp_new_i64();
2851 dest
= tcg_temp_new_i64();
2853 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2854 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2856 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2858 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2860 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2861 tcg_temp_free_i64(frn
);
2862 tcg_temp_free_i64(frm
);
2863 tcg_temp_free_i64(dest
);
2865 TCGv_i32 frn
, frm
, dest
;
2867 frn
= tcg_temp_new_i32();
2868 frm
= tcg_temp_new_i32();
2869 dest
= tcg_temp_new_i32();
2871 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2872 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2874 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2876 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2878 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2879 tcg_temp_free_i32(frn
);
2880 tcg_temp_free_i32(frm
);
2881 tcg_temp_free_i32(dest
);
2884 tcg_temp_free_ptr(fpst
);
2888 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2891 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2894 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2895 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2900 tcg_op
= tcg_temp_new_i64();
2901 tcg_res
= tcg_temp_new_i64();
2902 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2903 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2904 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2905 tcg_temp_free_i64(tcg_op
);
2906 tcg_temp_free_i64(tcg_res
);
2910 tcg_op
= tcg_temp_new_i32();
2911 tcg_res
= tcg_temp_new_i32();
2912 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2913 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2914 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2915 tcg_temp_free_i32(tcg_op
);
2916 tcg_temp_free_i32(tcg_res
);
2919 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2920 tcg_temp_free_i32(tcg_rmode
);
2922 tcg_temp_free_ptr(fpst
);
2926 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2929 bool is_signed
= extract32(insn
, 7, 1);
2930 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2931 TCGv_i32 tcg_rmode
, tcg_shift
;
2933 tcg_shift
= tcg_const_i32(0);
2935 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2936 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2939 TCGv_i64 tcg_double
, tcg_res
;
2941 /* Rd is encoded as a single precision register even when the source
2942 * is double precision.
2944 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2945 tcg_double
= tcg_temp_new_i64();
2946 tcg_res
= tcg_temp_new_i64();
2947 tcg_tmp
= tcg_temp_new_i32();
2948 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2950 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2952 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2954 tcg_gen_trunc_i64_i32(tcg_tmp
, tcg_res
);
2955 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2956 tcg_temp_free_i32(tcg_tmp
);
2957 tcg_temp_free_i64(tcg_res
);
2958 tcg_temp_free_i64(tcg_double
);
2960 TCGv_i32 tcg_single
, tcg_res
;
2961 tcg_single
= tcg_temp_new_i32();
2962 tcg_res
= tcg_temp_new_i32();
2963 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2965 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2967 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2969 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
2970 tcg_temp_free_i32(tcg_res
);
2971 tcg_temp_free_i32(tcg_single
);
2974 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2975 tcg_temp_free_i32(tcg_rmode
);
2977 tcg_temp_free_i32(tcg_shift
);
2979 tcg_temp_free_ptr(fpst
);
2984 /* Table for converting the most common AArch32 encoding of
2985 * rounding mode to arm_fprounding order (which matches the
2986 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2988 static const uint8_t fp_decode_rm
[] = {
2995 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
2997 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
2999 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3004 VFP_DREG_D(rd
, insn
);
3005 VFP_DREG_N(rn
, insn
);
3006 VFP_DREG_M(rm
, insn
);
3008 rd
= VFP_SREG_D(insn
);
3009 rn
= VFP_SREG_N(insn
);
3010 rm
= VFP_SREG_M(insn
);
3013 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3014 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3015 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3016 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3017 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3018 /* VRINTA, VRINTN, VRINTP, VRINTM */
3019 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3020 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3021 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3022 /* VCVTA, VCVTN, VCVTP, VCVTM */
3023 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3024 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3029 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3030 (ie. an undefined instruction). */
3031 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3033 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3039 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3043 /* FIXME: this access check should not take precedence over UNDEF
3044 * for invalid encodings; we will generate incorrect syndrome information
3045 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3047 if (s
->fp_excp_el
) {
3048 gen_exception_insn(s
, 4, EXCP_UDEF
,
3049 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
3053 if (!s
->vfp_enabled
) {
3054 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3055 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3057 rn
= (insn
>> 16) & 0xf;
3058 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3059 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3064 if (extract32(insn
, 28, 4) == 0xf) {
3065 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3066 * only used in v8 and above.
3068 return disas_vfp_v8_insn(s
, insn
);
3071 dp
= ((insn
& 0xf00) == 0xb00);
3072 switch ((insn
>> 24) & 0xf) {
3074 if (insn
& (1 << 4)) {
3075 /* single register transfer */
3076 rd
= (insn
>> 12) & 0xf;
3081 VFP_DREG_N(rn
, insn
);
3084 if (insn
& 0x00c00060
3085 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3089 pass
= (insn
>> 21) & 1;
3090 if (insn
& (1 << 22)) {
3092 offset
= ((insn
>> 5) & 3) * 8;
3093 } else if (insn
& (1 << 5)) {
3095 offset
= (insn
& (1 << 6)) ? 16 : 0;
3100 if (insn
& ARM_CP_RW_BIT
) {
3102 tmp
= neon_load_reg(rn
, pass
);
3106 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3107 if (insn
& (1 << 23))
3113 if (insn
& (1 << 23)) {
3115 tcg_gen_shri_i32(tmp
, tmp
, 16);
3121 tcg_gen_sari_i32(tmp
, tmp
, 16);
3130 store_reg(s
, rd
, tmp
);
3133 tmp
= load_reg(s
, rd
);
3134 if (insn
& (1 << 23)) {
3137 gen_neon_dup_u8(tmp
, 0);
3138 } else if (size
== 1) {
3139 gen_neon_dup_low16(tmp
);
3141 for (n
= 0; n
<= pass
* 2; n
++) {
3142 tmp2
= tcg_temp_new_i32();
3143 tcg_gen_mov_i32(tmp2
, tmp
);
3144 neon_store_reg(rn
, n
, tmp2
);
3146 neon_store_reg(rn
, n
, tmp
);
3151 tmp2
= neon_load_reg(rn
, pass
);
3152 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3153 tcg_temp_free_i32(tmp2
);
3156 tmp2
= neon_load_reg(rn
, pass
);
3157 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3158 tcg_temp_free_i32(tmp2
);
3163 neon_store_reg(rn
, pass
, tmp
);
3167 if ((insn
& 0x6f) != 0x00)
3169 rn
= VFP_SREG_N(insn
);
3170 if (insn
& ARM_CP_RW_BIT
) {
3172 if (insn
& (1 << 21)) {
3173 /* system register */
3178 /* VFP2 allows access to FSID from userspace.
3179 VFP3 restricts all id registers to privileged
3182 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3185 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3190 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3192 case ARM_VFP_FPINST
:
3193 case ARM_VFP_FPINST2
:
3194 /* Not present in VFP3. */
3196 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3199 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3203 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3204 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3206 tmp
= tcg_temp_new_i32();
3207 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3211 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3218 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3221 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3227 gen_mov_F0_vreg(0, rn
);
3228 tmp
= gen_vfp_mrs();
3231 /* Set the 4 flag bits in the CPSR. */
3233 tcg_temp_free_i32(tmp
);
3235 store_reg(s
, rd
, tmp
);
3239 if (insn
& (1 << 21)) {
3241 /* system register */
3246 /* Writes are ignored. */
3249 tmp
= load_reg(s
, rd
);
3250 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3251 tcg_temp_free_i32(tmp
);
3257 /* TODO: VFP subarchitecture support.
3258 * For now, keep the EN bit only */
3259 tmp
= load_reg(s
, rd
);
3260 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3261 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3264 case ARM_VFP_FPINST
:
3265 case ARM_VFP_FPINST2
:
3269 tmp
= load_reg(s
, rd
);
3270 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3276 tmp
= load_reg(s
, rd
);
3278 gen_mov_vreg_F0(0, rn
);
3283 /* data processing */
3284 /* The opcode is in bits 23, 21, 20 and 6. */
3285 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3289 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3291 /* rn is register number */
3292 VFP_DREG_N(rn
, insn
);
3295 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3296 ((rn
& 0x1e) == 0x6))) {
3297 /* Integer or single/half precision destination. */
3298 rd
= VFP_SREG_D(insn
);
3300 VFP_DREG_D(rd
, insn
);
3303 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3304 ((rn
& 0x1e) == 0x4))) {
3305 /* VCVT from int or half precision is always from S reg
3306 * regardless of dp bit. VCVT with immediate frac_bits
3307 * has same format as SREG_M.
3309 rm
= VFP_SREG_M(insn
);
3311 VFP_DREG_M(rm
, insn
);
3314 rn
= VFP_SREG_N(insn
);
3315 if (op
== 15 && rn
== 15) {
3316 /* Double precision destination. */
3317 VFP_DREG_D(rd
, insn
);
3319 rd
= VFP_SREG_D(insn
);
3321 /* NB that we implicitly rely on the encoding for the frac_bits
3322 * in VCVT of fixed to float being the same as that of an SREG_M
3324 rm
= VFP_SREG_M(insn
);
3327 veclen
= s
->vec_len
;
3328 if (op
== 15 && rn
> 3)
3331 /* Shut up compiler warnings. */
3342 /* Figure out what type of vector operation this is. */
3343 if ((rd
& bank_mask
) == 0) {
3348 delta_d
= (s
->vec_stride
>> 1) + 1;
3350 delta_d
= s
->vec_stride
+ 1;
3352 if ((rm
& bank_mask
) == 0) {
3353 /* mixed scalar/vector */
3362 /* Load the initial operands. */
3367 /* Integer source */
3368 gen_mov_F0_vreg(0, rm
);
3373 gen_mov_F0_vreg(dp
, rd
);
3374 gen_mov_F1_vreg(dp
, rm
);
3378 /* Compare with zero */
3379 gen_mov_F0_vreg(dp
, rd
);
3390 /* Source and destination the same. */
3391 gen_mov_F0_vreg(dp
, rd
);
3397 /* VCVTB, VCVTT: only present with the halfprec extension
3398 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3399 * (we choose to UNDEF)
3401 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3402 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3405 if (!extract32(rn
, 1, 1)) {
3406 /* Half precision source. */
3407 gen_mov_F0_vreg(0, rm
);
3410 /* Otherwise fall through */
3412 /* One source operand. */
3413 gen_mov_F0_vreg(dp
, rm
);
3417 /* Two source operands. */
3418 gen_mov_F0_vreg(dp
, rn
);
3419 gen_mov_F1_vreg(dp
, rm
);
3423 /* Perform the calculation. */
3425 case 0: /* VMLA: fd + (fn * fm) */
3426 /* Note that order of inputs to the add matters for NaNs */
3428 gen_mov_F0_vreg(dp
, rd
);
3431 case 1: /* VMLS: fd + -(fn * fm) */
3434 gen_mov_F0_vreg(dp
, rd
);
3437 case 2: /* VNMLS: -fd + (fn * fm) */
3438 /* Note that it isn't valid to replace (-A + B) with (B - A)
3439 * or similar plausible looking simplifications
3440 * because this will give wrong results for NaNs.
3443 gen_mov_F0_vreg(dp
, rd
);
3447 case 3: /* VNMLA: -fd + -(fn * fm) */
3450 gen_mov_F0_vreg(dp
, rd
);
3454 case 4: /* mul: fn * fm */
3457 case 5: /* nmul: -(fn * fm) */
3461 case 6: /* add: fn + fm */
3464 case 7: /* sub: fn - fm */
3467 case 8: /* div: fn / fm */
3470 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3471 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3472 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3473 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3474 /* These are fused multiply-add, and must be done as one
3475 * floating point operation with no rounding between the
3476 * multiplication and addition steps.
3477 * NB that doing the negations here as separate steps is
3478 * correct : an input NaN should come out with its sign bit
3479 * flipped if it is a negated-input.
3481 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3489 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3491 frd
= tcg_temp_new_i64();
3492 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3495 gen_helper_vfp_negd(frd
, frd
);
3497 fpst
= get_fpstatus_ptr(0);
3498 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3499 cpu_F1d
, frd
, fpst
);
3500 tcg_temp_free_ptr(fpst
);
3501 tcg_temp_free_i64(frd
);
3507 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3509 frd
= tcg_temp_new_i32();
3510 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3512 gen_helper_vfp_negs(frd
, frd
);
3514 fpst
= get_fpstatus_ptr(0);
3515 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3516 cpu_F1s
, frd
, fpst
);
3517 tcg_temp_free_ptr(fpst
);
3518 tcg_temp_free_i32(frd
);
3521 case 14: /* fconst */
3522 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3526 n
= (insn
<< 12) & 0x80000000;
3527 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3534 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3541 tcg_gen_movi_i32(cpu_F0s
, n
);
3544 case 15: /* extension space */
3558 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3559 tmp
= gen_vfp_mrs();
3560 tcg_gen_ext16u_i32(tmp
, tmp
);
3562 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3565 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3568 tcg_temp_free_i32(tmp
);
3570 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3571 tmp
= gen_vfp_mrs();
3572 tcg_gen_shri_i32(tmp
, tmp
, 16);
3574 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3577 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3580 tcg_temp_free_i32(tmp
);
3582 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3583 tmp
= tcg_temp_new_i32();
3585 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3588 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3591 gen_mov_F0_vreg(0, rd
);
3592 tmp2
= gen_vfp_mrs();
3593 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3594 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3595 tcg_temp_free_i32(tmp2
);
3598 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3599 tmp
= tcg_temp_new_i32();
3601 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3604 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3607 tcg_gen_shli_i32(tmp
, tmp
, 16);
3608 gen_mov_F0_vreg(0, rd
);
3609 tmp2
= gen_vfp_mrs();
3610 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3611 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3612 tcg_temp_free_i32(tmp2
);
3624 case 11: /* cmpez */
3628 case 12: /* vrintr */
3630 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3632 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3634 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3636 tcg_temp_free_ptr(fpst
);
3639 case 13: /* vrintz */
3641 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3643 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3644 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3646 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3648 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3650 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3651 tcg_temp_free_i32(tcg_rmode
);
3652 tcg_temp_free_ptr(fpst
);
3655 case 14: /* vrintx */
3657 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3659 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3661 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3663 tcg_temp_free_ptr(fpst
);
3666 case 15: /* single<->double conversion */
3668 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3670 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3672 case 16: /* fuito */
3673 gen_vfp_uito(dp
, 0);
3675 case 17: /* fsito */
3676 gen_vfp_sito(dp
, 0);
3678 case 20: /* fshto */
3679 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3682 gen_vfp_shto(dp
, 16 - rm
, 0);
3684 case 21: /* fslto */
3685 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3688 gen_vfp_slto(dp
, 32 - rm
, 0);
3690 case 22: /* fuhto */
3691 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3694 gen_vfp_uhto(dp
, 16 - rm
, 0);
3696 case 23: /* fulto */
3697 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3700 gen_vfp_ulto(dp
, 32 - rm
, 0);
3702 case 24: /* ftoui */
3703 gen_vfp_toui(dp
, 0);
3705 case 25: /* ftouiz */
3706 gen_vfp_touiz(dp
, 0);
3708 case 26: /* ftosi */
3709 gen_vfp_tosi(dp
, 0);
3711 case 27: /* ftosiz */
3712 gen_vfp_tosiz(dp
, 0);
3714 case 28: /* ftosh */
3715 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3718 gen_vfp_tosh(dp
, 16 - rm
, 0);
3720 case 29: /* ftosl */
3721 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3724 gen_vfp_tosl(dp
, 32 - rm
, 0);
3726 case 30: /* ftouh */
3727 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3730 gen_vfp_touh(dp
, 16 - rm
, 0);
3732 case 31: /* ftoul */
3733 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3736 gen_vfp_toul(dp
, 32 - rm
, 0);
3738 default: /* undefined */
3742 default: /* undefined */
3746 /* Write back the result. */
3747 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3748 /* Comparison, do nothing. */
3749 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3750 (rn
& 0x1e) == 0x6)) {
3751 /* VCVT double to int: always integer result.
3752 * VCVT double to half precision is always a single
3755 gen_mov_vreg_F0(0, rd
);
3756 } else if (op
== 15 && rn
== 15) {
3758 gen_mov_vreg_F0(!dp
, rd
);
3760 gen_mov_vreg_F0(dp
, rd
);
3763 /* break out of the loop if we have finished */
3767 if (op
== 15 && delta_m
== 0) {
3768 /* single source one-many */
3770 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3772 gen_mov_vreg_F0(dp
, rd
);
3776 /* Setup the next operands. */
3778 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3782 /* One source operand. */
3783 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3785 gen_mov_F0_vreg(dp
, rm
);
3787 /* Two source operands. */
3788 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3790 gen_mov_F0_vreg(dp
, rn
);
3792 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3794 gen_mov_F1_vreg(dp
, rm
);
3802 if ((insn
& 0x03e00000) == 0x00400000) {
3803 /* two-register transfer */
3804 rn
= (insn
>> 16) & 0xf;
3805 rd
= (insn
>> 12) & 0xf;
3807 VFP_DREG_M(rm
, insn
);
3809 rm
= VFP_SREG_M(insn
);
3812 if (insn
& ARM_CP_RW_BIT
) {
3815 gen_mov_F0_vreg(0, rm
* 2);
3816 tmp
= gen_vfp_mrs();
3817 store_reg(s
, rd
, tmp
);
3818 gen_mov_F0_vreg(0, rm
* 2 + 1);
3819 tmp
= gen_vfp_mrs();
3820 store_reg(s
, rn
, tmp
);
3822 gen_mov_F0_vreg(0, rm
);
3823 tmp
= gen_vfp_mrs();
3824 store_reg(s
, rd
, tmp
);
3825 gen_mov_F0_vreg(0, rm
+ 1);
3826 tmp
= gen_vfp_mrs();
3827 store_reg(s
, rn
, tmp
);
3832 tmp
= load_reg(s
, rd
);
3834 gen_mov_vreg_F0(0, rm
* 2);
3835 tmp
= load_reg(s
, rn
);
3837 gen_mov_vreg_F0(0, rm
* 2 + 1);
3839 tmp
= load_reg(s
, rd
);
3841 gen_mov_vreg_F0(0, rm
);
3842 tmp
= load_reg(s
, rn
);
3844 gen_mov_vreg_F0(0, rm
+ 1);
3849 rn
= (insn
>> 16) & 0xf;
3851 VFP_DREG_D(rd
, insn
);
3853 rd
= VFP_SREG_D(insn
);
3854 if ((insn
& 0x01200000) == 0x01000000) {
3855 /* Single load/store */
3856 offset
= (insn
& 0xff) << 2;
3857 if ((insn
& (1 << 23)) == 0)
3859 if (s
->thumb
&& rn
== 15) {
3860 /* This is actually UNPREDICTABLE */
3861 addr
= tcg_temp_new_i32();
3862 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3864 addr
= load_reg(s
, rn
);
3866 tcg_gen_addi_i32(addr
, addr
, offset
);
3867 if (insn
& (1 << 20)) {
3868 gen_vfp_ld(s
, dp
, addr
);
3869 gen_mov_vreg_F0(dp
, rd
);
3871 gen_mov_F0_vreg(dp
, rd
);
3872 gen_vfp_st(s
, dp
, addr
);
3874 tcg_temp_free_i32(addr
);
3876 /* load/store multiple */
3877 int w
= insn
& (1 << 21);
3879 n
= (insn
>> 1) & 0x7f;
3883 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3884 /* P == U , W == 1 => UNDEF */
3887 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3888 /* UNPREDICTABLE cases for bad immediates: we choose to
3889 * UNDEF to avoid generating huge numbers of TCG ops
3893 if (rn
== 15 && w
) {
3894 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3898 if (s
->thumb
&& rn
== 15) {
3899 /* This is actually UNPREDICTABLE */
3900 addr
= tcg_temp_new_i32();
3901 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3903 addr
= load_reg(s
, rn
);
3905 if (insn
& (1 << 24)) /* pre-decrement */
3906 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3912 for (i
= 0; i
< n
; i
++) {
3913 if (insn
& ARM_CP_RW_BIT
) {
3915 gen_vfp_ld(s
, dp
, addr
);
3916 gen_mov_vreg_F0(dp
, rd
+ i
);
3919 gen_mov_F0_vreg(dp
, rd
+ i
);
3920 gen_vfp_st(s
, dp
, addr
);
3922 tcg_gen_addi_i32(addr
, addr
, offset
);
3926 if (insn
& (1 << 24))
3927 offset
= -offset
* n
;
3928 else if (dp
&& (insn
& 1))
3934 tcg_gen_addi_i32(addr
, addr
, offset
);
3935 store_reg(s
, rn
, addr
);
3937 tcg_temp_free_i32(addr
);
3943 /* Should never happen. */
3949 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3951 TranslationBlock
*tb
;
3954 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3956 gen_set_pc_im(s
, dest
);
3957 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3959 gen_set_pc_im(s
, dest
);
3964 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3966 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
3967 /* An indirect jump so that we still trigger the debug exception. */
3972 gen_goto_tb(s
, 0, dest
);
3973 s
->is_jmp
= DISAS_TB_JUMP
;
3977 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3980 tcg_gen_sari_i32(t0
, t0
, 16);
3984 tcg_gen_sari_i32(t1
, t1
, 16);
3987 tcg_gen_mul_i32(t0
, t0
, t1
);
3990 /* Return the mask of PSR bits set by a MSR instruction. */
3991 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
3996 if (flags
& (1 << 0))
3998 if (flags
& (1 << 1))
4000 if (flags
& (1 << 2))
4002 if (flags
& (1 << 3))
4005 /* Mask out undefined bits. */
4006 mask
&= ~CPSR_RESERVED
;
4007 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4010 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4011 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4013 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4014 mask
&= ~(CPSR_E
| CPSR_GE
);
4016 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4019 /* Mask out execution state and reserved bits. */
4021 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4023 /* Mask out privileged bits. */
4029 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4030 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4034 /* ??? This is also undefined in system mode. */
4038 tmp
= load_cpu_field(spsr
);
4039 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4040 tcg_gen_andi_i32(t0
, t0
, mask
);
4041 tcg_gen_or_i32(tmp
, tmp
, t0
);
4042 store_cpu_field(tmp
, spsr
);
4044 gen_set_cpsr(t0
, mask
);
4046 tcg_temp_free_i32(t0
);
4051 /* Returns nonzero if access to the PSR is not permitted. */
4052 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4055 tmp
= tcg_temp_new_i32();
4056 tcg_gen_movi_i32(tmp
, val
);
4057 return gen_set_psr(s
, mask
, spsr
, tmp
);
4060 /* Generate an old-style exception return. Marks pc as dead. */
4061 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4064 store_reg(s
, 15, pc
);
4065 tmp
= load_cpu_field(spsr
);
4066 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
4067 tcg_temp_free_i32(tmp
);
4068 s
->is_jmp
= DISAS_UPDATE
;
4071 /* Generate a v6 exception return. Marks both values as dead. */
4072 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4074 gen_set_cpsr(cpsr
, CPSR_ERET_MASK
);
4075 tcg_temp_free_i32(cpsr
);
4076 store_reg(s
, 15, pc
);
4077 s
->is_jmp
= DISAS_UPDATE
;
4080 static void gen_nop_hint(DisasContext
*s
, int val
)
4084 gen_set_pc_im(s
, s
->pc
);
4085 s
->is_jmp
= DISAS_WFI
;
4088 gen_set_pc_im(s
, s
->pc
);
4089 s
->is_jmp
= DISAS_WFE
;
4093 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4099 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4101 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4104 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4105 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4106 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4111 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4114 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4115 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4116 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4121 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4122 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4123 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4124 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4125 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4127 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4128 switch ((size << 1) | u) { \
4130 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4133 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4136 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4139 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4142 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4145 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4147 default: return 1; \
4150 #define GEN_NEON_INTEGER_OP(name) do { \
4151 switch ((size << 1) | u) { \
4153 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4156 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4159 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4162 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4165 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4168 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4170 default: return 1; \
4173 static TCGv_i32
neon_load_scratch(int scratch
)
4175 TCGv_i32 tmp
= tcg_temp_new_i32();
4176 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4180 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4182 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4183 tcg_temp_free_i32(var
);
4186 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4190 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4192 gen_neon_dup_high16(tmp
);
4194 gen_neon_dup_low16(tmp
);
4197 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4202 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4205 if (!q
&& size
== 2) {
4208 tmp
= tcg_const_i32(rd
);
4209 tmp2
= tcg_const_i32(rm
);
4213 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4216 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4219 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4227 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4230 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4236 tcg_temp_free_i32(tmp
);
4237 tcg_temp_free_i32(tmp2
);
4241 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4244 if (!q
&& size
== 2) {
4247 tmp
= tcg_const_i32(rd
);
4248 tmp2
= tcg_const_i32(rm
);
4252 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4255 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4258 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4266 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4269 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4275 tcg_temp_free_i32(tmp
);
4276 tcg_temp_free_i32(tmp2
);
4280 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4284 rd
= tcg_temp_new_i32();
4285 tmp
= tcg_temp_new_i32();
4287 tcg_gen_shli_i32(rd
, t0
, 8);
4288 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4289 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4290 tcg_gen_or_i32(rd
, rd
, tmp
);
4292 tcg_gen_shri_i32(t1
, t1
, 8);
4293 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4294 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4295 tcg_gen_or_i32(t1
, t1
, tmp
);
4296 tcg_gen_mov_i32(t0
, rd
);
4298 tcg_temp_free_i32(tmp
);
4299 tcg_temp_free_i32(rd
);
4302 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4306 rd
= tcg_temp_new_i32();
4307 tmp
= tcg_temp_new_i32();
4309 tcg_gen_shli_i32(rd
, t0
, 16);
4310 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4311 tcg_gen_or_i32(rd
, rd
, tmp
);
4312 tcg_gen_shri_i32(t1
, t1
, 16);
4313 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4314 tcg_gen_or_i32(t1
, t1
, tmp
);
4315 tcg_gen_mov_i32(t0
, rd
);
4317 tcg_temp_free_i32(tmp
);
4318 tcg_temp_free_i32(rd
);
4326 } neon_ls_element_type
[11] = {
4340 /* Translate a NEON load/store element instruction. Return nonzero if the
4341 instruction is invalid. */
4342 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4361 /* FIXME: this access check should not take precedence over UNDEF
4362 * for invalid encodings; we will generate incorrect syndrome information
4363 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4365 if (s
->fp_excp_el
) {
4366 gen_exception_insn(s
, 4, EXCP_UDEF
,
4367 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
4371 if (!s
->vfp_enabled
)
4373 VFP_DREG_D(rd
, insn
);
4374 rn
= (insn
>> 16) & 0xf;
4376 load
= (insn
& (1 << 21)) != 0;
4377 if ((insn
& (1 << 23)) == 0) {
4378 /* Load store all elements. */
4379 op
= (insn
>> 8) & 0xf;
4380 size
= (insn
>> 6) & 3;
4383 /* Catch UNDEF cases for bad values of align field */
4386 if (((insn
>> 5) & 1) == 1) {
4391 if (((insn
>> 4) & 3) == 3) {
4398 nregs
= neon_ls_element_type
[op
].nregs
;
4399 interleave
= neon_ls_element_type
[op
].interleave
;
4400 spacing
= neon_ls_element_type
[op
].spacing
;
4401 if (size
== 3 && (interleave
| spacing
) != 1)
4403 addr
= tcg_temp_new_i32();
4404 load_reg_var(s
, addr
, rn
);
4405 stride
= (1 << size
) * interleave
;
4406 for (reg
= 0; reg
< nregs
; reg
++) {
4407 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4408 load_reg_var(s
, addr
, rn
);
4409 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4410 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4411 load_reg_var(s
, addr
, rn
);
4412 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4415 tmp64
= tcg_temp_new_i64();
4417 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4418 neon_store_reg64(tmp64
, rd
);
4420 neon_load_reg64(tmp64
, rd
);
4421 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4423 tcg_temp_free_i64(tmp64
);
4424 tcg_gen_addi_i32(addr
, addr
, stride
);
4426 for (pass
= 0; pass
< 2; pass
++) {
4429 tmp
= tcg_temp_new_i32();
4430 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4431 neon_store_reg(rd
, pass
, tmp
);
4433 tmp
= neon_load_reg(rd
, pass
);
4434 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4435 tcg_temp_free_i32(tmp
);
4437 tcg_gen_addi_i32(addr
, addr
, stride
);
4438 } else if (size
== 1) {
4440 tmp
= tcg_temp_new_i32();
4441 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4442 tcg_gen_addi_i32(addr
, addr
, stride
);
4443 tmp2
= tcg_temp_new_i32();
4444 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4445 tcg_gen_addi_i32(addr
, addr
, stride
);
4446 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4447 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4448 tcg_temp_free_i32(tmp2
);
4449 neon_store_reg(rd
, pass
, tmp
);
4451 tmp
= neon_load_reg(rd
, pass
);
4452 tmp2
= tcg_temp_new_i32();
4453 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4454 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4455 tcg_temp_free_i32(tmp
);
4456 tcg_gen_addi_i32(addr
, addr
, stride
);
4457 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4458 tcg_temp_free_i32(tmp2
);
4459 tcg_gen_addi_i32(addr
, addr
, stride
);
4461 } else /* size == 0 */ {
4463 TCGV_UNUSED_I32(tmp2
);
4464 for (n
= 0; n
< 4; n
++) {
4465 tmp
= tcg_temp_new_i32();
4466 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4467 tcg_gen_addi_i32(addr
, addr
, stride
);
4471 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4472 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4473 tcg_temp_free_i32(tmp
);
4476 neon_store_reg(rd
, pass
, tmp2
);
4478 tmp2
= neon_load_reg(rd
, pass
);
4479 for (n
= 0; n
< 4; n
++) {
4480 tmp
= tcg_temp_new_i32();
4482 tcg_gen_mov_i32(tmp
, tmp2
);
4484 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4486 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4487 tcg_temp_free_i32(tmp
);
4488 tcg_gen_addi_i32(addr
, addr
, stride
);
4490 tcg_temp_free_i32(tmp2
);
4497 tcg_temp_free_i32(addr
);
4500 size
= (insn
>> 10) & 3;
4502 /* Load single element to all lanes. */
4503 int a
= (insn
>> 4) & 1;
4507 size
= (insn
>> 6) & 3;
4508 nregs
= ((insn
>> 8) & 3) + 1;
4511 if (nregs
!= 4 || a
== 0) {
4514 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4517 if (nregs
== 1 && a
== 1 && size
== 0) {
4520 if (nregs
== 3 && a
== 1) {
4523 addr
= tcg_temp_new_i32();
4524 load_reg_var(s
, addr
, rn
);
4526 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4527 tmp
= gen_load_and_replicate(s
, addr
, size
);
4528 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4529 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4530 if (insn
& (1 << 5)) {
4531 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4532 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4534 tcg_temp_free_i32(tmp
);
4536 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4537 stride
= (insn
& (1 << 5)) ? 2 : 1;
4538 for (reg
= 0; reg
< nregs
; reg
++) {
4539 tmp
= gen_load_and_replicate(s
, addr
, size
);
4540 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4541 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4542 tcg_temp_free_i32(tmp
);
4543 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4547 tcg_temp_free_i32(addr
);
4548 stride
= (1 << size
) * nregs
;
4550 /* Single element. */
4551 int idx
= (insn
>> 4) & 0xf;
4552 pass
= (insn
>> 7) & 1;
4555 shift
= ((insn
>> 5) & 3) * 8;
4559 shift
= ((insn
>> 6) & 1) * 16;
4560 stride
= (insn
& (1 << 5)) ? 2 : 1;
4564 stride
= (insn
& (1 << 6)) ? 2 : 1;
4569 nregs
= ((insn
>> 8) & 3) + 1;
4570 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4573 if (((idx
& (1 << size
)) != 0) ||
4574 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4579 if ((idx
& 1) != 0) {
4584 if (size
== 2 && (idx
& 2) != 0) {
4589 if ((size
== 2) && ((idx
& 3) == 3)) {
4596 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4597 /* Attempts to write off the end of the register file
4598 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4599 * the neon_load_reg() would write off the end of the array.
4603 addr
= tcg_temp_new_i32();
4604 load_reg_var(s
, addr
, rn
);
4605 for (reg
= 0; reg
< nregs
; reg
++) {
4607 tmp
= tcg_temp_new_i32();
4610 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4613 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4616 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4618 default: /* Avoid compiler warnings. */
4622 tmp2
= neon_load_reg(rd
, pass
);
4623 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4624 shift
, size
? 16 : 8);
4625 tcg_temp_free_i32(tmp2
);
4627 neon_store_reg(rd
, pass
, tmp
);
4628 } else { /* Store */
4629 tmp
= neon_load_reg(rd
, pass
);
4631 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4634 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4637 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4640 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4643 tcg_temp_free_i32(tmp
);
4646 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4648 tcg_temp_free_i32(addr
);
4649 stride
= nregs
* (1 << size
);
4655 base
= load_reg(s
, rn
);
4657 tcg_gen_addi_i32(base
, base
, stride
);
4660 index
= load_reg(s
, rm
);
4661 tcg_gen_add_i32(base
, base
, index
);
4662 tcg_temp_free_i32(index
);
4664 store_reg(s
, rn
, base
);
4669 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4670 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4672 tcg_gen_and_i32(t
, t
, c
);
4673 tcg_gen_andc_i32(f
, f
, c
);
4674 tcg_gen_or_i32(dest
, t
, f
);
4677 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4680 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4681 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4682 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4687 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4690 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4691 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4692 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4697 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4700 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4701 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4702 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4707 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4710 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4711 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4712 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4717 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4723 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4724 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4729 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4730 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4737 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4738 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4743 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4744 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4751 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4755 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4756 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4757 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4762 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4763 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4764 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4768 tcg_temp_free_i32(src
);
4771 static inline void gen_neon_addl(int size
)
4774 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4775 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4776 case 2: tcg_gen_add_i64(CPU_V001
); break;
4781 static inline void gen_neon_subl(int size
)
4784 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4785 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4786 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4791 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4794 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4795 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4797 tcg_gen_neg_i64(var
, var
);
4803 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4806 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4807 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4812 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4817 switch ((size
<< 1) | u
) {
4818 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4819 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4820 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4821 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4823 tmp
= gen_muls_i64_i32(a
, b
);
4824 tcg_gen_mov_i64(dest
, tmp
);
4825 tcg_temp_free_i64(tmp
);
4828 tmp
= gen_mulu_i64_i32(a
, b
);
4829 tcg_gen_mov_i64(dest
, tmp
);
4830 tcg_temp_free_i64(tmp
);
4835 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4836 Don't forget to clean them now. */
4838 tcg_temp_free_i32(a
);
4839 tcg_temp_free_i32(b
);
4843 static void gen_neon_narrow_op(int op
, int u
, int size
,
4844 TCGv_i32 dest
, TCGv_i64 src
)
4848 gen_neon_unarrow_sats(size
, dest
, src
);
4850 gen_neon_narrow(size
, dest
, src
);
4854 gen_neon_narrow_satu(size
, dest
, src
);
4856 gen_neon_narrow_sats(size
, dest
, src
);
4861 /* Symbolic constants for op fields for Neon 3-register same-length.
4862 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4865 #define NEON_3R_VHADD 0
4866 #define NEON_3R_VQADD 1
4867 #define NEON_3R_VRHADD 2
4868 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4869 #define NEON_3R_VHSUB 4
4870 #define NEON_3R_VQSUB 5
4871 #define NEON_3R_VCGT 6
4872 #define NEON_3R_VCGE 7
4873 #define NEON_3R_VSHL 8
4874 #define NEON_3R_VQSHL 9
4875 #define NEON_3R_VRSHL 10
4876 #define NEON_3R_VQRSHL 11
4877 #define NEON_3R_VMAX 12
4878 #define NEON_3R_VMIN 13
4879 #define NEON_3R_VABD 14
4880 #define NEON_3R_VABA 15
4881 #define NEON_3R_VADD_VSUB 16
4882 #define NEON_3R_VTST_VCEQ 17
4883 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4884 #define NEON_3R_VMUL 19
4885 #define NEON_3R_VPMAX 20
4886 #define NEON_3R_VPMIN 21
4887 #define NEON_3R_VQDMULH_VQRDMULH 22
4888 #define NEON_3R_VPADD 23
4889 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4890 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4891 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4892 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4893 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4894 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4895 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4896 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4898 static const uint8_t neon_3r_sizes
[] = {
4899 [NEON_3R_VHADD
] = 0x7,
4900 [NEON_3R_VQADD
] = 0xf,
4901 [NEON_3R_VRHADD
] = 0x7,
4902 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4903 [NEON_3R_VHSUB
] = 0x7,
4904 [NEON_3R_VQSUB
] = 0xf,
4905 [NEON_3R_VCGT
] = 0x7,
4906 [NEON_3R_VCGE
] = 0x7,
4907 [NEON_3R_VSHL
] = 0xf,
4908 [NEON_3R_VQSHL
] = 0xf,
4909 [NEON_3R_VRSHL
] = 0xf,
4910 [NEON_3R_VQRSHL
] = 0xf,
4911 [NEON_3R_VMAX
] = 0x7,
4912 [NEON_3R_VMIN
] = 0x7,
4913 [NEON_3R_VABD
] = 0x7,
4914 [NEON_3R_VABA
] = 0x7,
4915 [NEON_3R_VADD_VSUB
] = 0xf,
4916 [NEON_3R_VTST_VCEQ
] = 0x7,
4917 [NEON_3R_VML
] = 0x7,
4918 [NEON_3R_VMUL
] = 0x7,
4919 [NEON_3R_VPMAX
] = 0x7,
4920 [NEON_3R_VPMIN
] = 0x7,
4921 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4922 [NEON_3R_VPADD
] = 0x7,
4923 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4924 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4925 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4926 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4927 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4928 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4929 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4930 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4933 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4934 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4937 #define NEON_2RM_VREV64 0
4938 #define NEON_2RM_VREV32 1
4939 #define NEON_2RM_VREV16 2
4940 #define NEON_2RM_VPADDL 4
4941 #define NEON_2RM_VPADDL_U 5
4942 #define NEON_2RM_AESE 6 /* Includes AESD */
4943 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4944 #define NEON_2RM_VCLS 8
4945 #define NEON_2RM_VCLZ 9
4946 #define NEON_2RM_VCNT 10
4947 #define NEON_2RM_VMVN 11
4948 #define NEON_2RM_VPADAL 12
4949 #define NEON_2RM_VPADAL_U 13
4950 #define NEON_2RM_VQABS 14
4951 #define NEON_2RM_VQNEG 15
4952 #define NEON_2RM_VCGT0 16
4953 #define NEON_2RM_VCGE0 17
4954 #define NEON_2RM_VCEQ0 18
4955 #define NEON_2RM_VCLE0 19
4956 #define NEON_2RM_VCLT0 20
4957 #define NEON_2RM_SHA1H 21
4958 #define NEON_2RM_VABS 22
4959 #define NEON_2RM_VNEG 23
4960 #define NEON_2RM_VCGT0_F 24
4961 #define NEON_2RM_VCGE0_F 25
4962 #define NEON_2RM_VCEQ0_F 26
4963 #define NEON_2RM_VCLE0_F 27
4964 #define NEON_2RM_VCLT0_F 28
4965 #define NEON_2RM_VABS_F 30
4966 #define NEON_2RM_VNEG_F 31
4967 #define NEON_2RM_VSWP 32
4968 #define NEON_2RM_VTRN 33
4969 #define NEON_2RM_VUZP 34
4970 #define NEON_2RM_VZIP 35
4971 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4972 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4973 #define NEON_2RM_VSHLL 38
4974 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4975 #define NEON_2RM_VRINTN 40
4976 #define NEON_2RM_VRINTX 41
4977 #define NEON_2RM_VRINTA 42
4978 #define NEON_2RM_VRINTZ 43
4979 #define NEON_2RM_VCVT_F16_F32 44
4980 #define NEON_2RM_VRINTM 45
4981 #define NEON_2RM_VCVT_F32_F16 46
4982 #define NEON_2RM_VRINTP 47
4983 #define NEON_2RM_VCVTAU 48
4984 #define NEON_2RM_VCVTAS 49
4985 #define NEON_2RM_VCVTNU 50
4986 #define NEON_2RM_VCVTNS 51
4987 #define NEON_2RM_VCVTPU 52
4988 #define NEON_2RM_VCVTPS 53
4989 #define NEON_2RM_VCVTMU 54
4990 #define NEON_2RM_VCVTMS 55
4991 #define NEON_2RM_VRECPE 56
4992 #define NEON_2RM_VRSQRTE 57
4993 #define NEON_2RM_VRECPE_F 58
4994 #define NEON_2RM_VRSQRTE_F 59
4995 #define NEON_2RM_VCVT_FS 60
4996 #define NEON_2RM_VCVT_FU 61
4997 #define NEON_2RM_VCVT_SF 62
4998 #define NEON_2RM_VCVT_UF 63
5000 static int neon_2rm_is_float_op(int op
)
5002 /* Return true if this neon 2reg-misc op is float-to-float */
5003 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5004 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5005 op
== NEON_2RM_VRINTM
||
5006 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5007 op
>= NEON_2RM_VRECPE_F
);
5010 /* Each entry in this array has bit n set if the insn allows
5011 * size value n (otherwise it will UNDEF). Since unallocated
5012 * op values will have no bits set they always UNDEF.
5014 static const uint8_t neon_2rm_sizes
[] = {
5015 [NEON_2RM_VREV64
] = 0x7,
5016 [NEON_2RM_VREV32
] = 0x3,
5017 [NEON_2RM_VREV16
] = 0x1,
5018 [NEON_2RM_VPADDL
] = 0x7,
5019 [NEON_2RM_VPADDL_U
] = 0x7,
5020 [NEON_2RM_AESE
] = 0x1,
5021 [NEON_2RM_AESMC
] = 0x1,
5022 [NEON_2RM_VCLS
] = 0x7,
5023 [NEON_2RM_VCLZ
] = 0x7,
5024 [NEON_2RM_VCNT
] = 0x1,
5025 [NEON_2RM_VMVN
] = 0x1,
5026 [NEON_2RM_VPADAL
] = 0x7,
5027 [NEON_2RM_VPADAL_U
] = 0x7,
5028 [NEON_2RM_VQABS
] = 0x7,
5029 [NEON_2RM_VQNEG
] = 0x7,
5030 [NEON_2RM_VCGT0
] = 0x7,
5031 [NEON_2RM_VCGE0
] = 0x7,
5032 [NEON_2RM_VCEQ0
] = 0x7,
5033 [NEON_2RM_VCLE0
] = 0x7,
5034 [NEON_2RM_VCLT0
] = 0x7,
5035 [NEON_2RM_SHA1H
] = 0x4,
5036 [NEON_2RM_VABS
] = 0x7,
5037 [NEON_2RM_VNEG
] = 0x7,
5038 [NEON_2RM_VCGT0_F
] = 0x4,
5039 [NEON_2RM_VCGE0_F
] = 0x4,
5040 [NEON_2RM_VCEQ0_F
] = 0x4,
5041 [NEON_2RM_VCLE0_F
] = 0x4,
5042 [NEON_2RM_VCLT0_F
] = 0x4,
5043 [NEON_2RM_VABS_F
] = 0x4,
5044 [NEON_2RM_VNEG_F
] = 0x4,
5045 [NEON_2RM_VSWP
] = 0x1,
5046 [NEON_2RM_VTRN
] = 0x7,
5047 [NEON_2RM_VUZP
] = 0x7,
5048 [NEON_2RM_VZIP
] = 0x7,
5049 [NEON_2RM_VMOVN
] = 0x7,
5050 [NEON_2RM_VQMOVN
] = 0x7,
5051 [NEON_2RM_VSHLL
] = 0x7,
5052 [NEON_2RM_SHA1SU1
] = 0x4,
5053 [NEON_2RM_VRINTN
] = 0x4,
5054 [NEON_2RM_VRINTX
] = 0x4,
5055 [NEON_2RM_VRINTA
] = 0x4,
5056 [NEON_2RM_VRINTZ
] = 0x4,
5057 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5058 [NEON_2RM_VRINTM
] = 0x4,
5059 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5060 [NEON_2RM_VRINTP
] = 0x4,
5061 [NEON_2RM_VCVTAU
] = 0x4,
5062 [NEON_2RM_VCVTAS
] = 0x4,
5063 [NEON_2RM_VCVTNU
] = 0x4,
5064 [NEON_2RM_VCVTNS
] = 0x4,
5065 [NEON_2RM_VCVTPU
] = 0x4,
5066 [NEON_2RM_VCVTPS
] = 0x4,
5067 [NEON_2RM_VCVTMU
] = 0x4,
5068 [NEON_2RM_VCVTMS
] = 0x4,
5069 [NEON_2RM_VRECPE
] = 0x4,
5070 [NEON_2RM_VRSQRTE
] = 0x4,
5071 [NEON_2RM_VRECPE_F
] = 0x4,
5072 [NEON_2RM_VRSQRTE_F
] = 0x4,
5073 [NEON_2RM_VCVT_FS
] = 0x4,
5074 [NEON_2RM_VCVT_FU
] = 0x4,
5075 [NEON_2RM_VCVT_SF
] = 0x4,
5076 [NEON_2RM_VCVT_UF
] = 0x4,
5079 /* Translate a NEON data processing instruction. Return nonzero if the
5080 instruction is invalid.
5081 We process data in a mixture of 32-bit and 64-bit chunks.
5082 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5084 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5096 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5099 /* FIXME: this access check should not take precedence over UNDEF
5100 * for invalid encodings; we will generate incorrect syndrome information
5101 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5103 if (s
->fp_excp_el
) {
5104 gen_exception_insn(s
, 4, EXCP_UDEF
,
5105 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
5109 if (!s
->vfp_enabled
)
5111 q
= (insn
& (1 << 6)) != 0;
5112 u
= (insn
>> 24) & 1;
5113 VFP_DREG_D(rd
, insn
);
5114 VFP_DREG_N(rn
, insn
);
5115 VFP_DREG_M(rm
, insn
);
5116 size
= (insn
>> 20) & 3;
5117 if ((insn
& (1 << 23)) == 0) {
5118 /* Three register same length. */
5119 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5120 /* Catch invalid op and bad size combinations: UNDEF */
5121 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5124 /* All insns of this form UNDEF for either this condition or the
5125 * superset of cases "Q==1"; we catch the latter later.
5127 if (q
&& ((rd
| rn
| rm
) & 1)) {
5131 * The SHA-1/SHA-256 3-register instructions require special treatment
5132 * here, as their size field is overloaded as an op type selector, and
5133 * they all consume their input in a single pass.
5135 if (op
== NEON_3R_SHA
) {
5139 if (!u
) { /* SHA-1 */
5140 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5143 tmp
= tcg_const_i32(rd
);
5144 tmp2
= tcg_const_i32(rn
);
5145 tmp3
= tcg_const_i32(rm
);
5146 tmp4
= tcg_const_i32(size
);
5147 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5148 tcg_temp_free_i32(tmp4
);
5149 } else { /* SHA-256 */
5150 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5153 tmp
= tcg_const_i32(rd
);
5154 tmp2
= tcg_const_i32(rn
);
5155 tmp3
= tcg_const_i32(rm
);
5158 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5161 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5164 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5168 tcg_temp_free_i32(tmp
);
5169 tcg_temp_free_i32(tmp2
);
5170 tcg_temp_free_i32(tmp3
);
5173 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5174 /* 64-bit element instructions. */
5175 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5176 neon_load_reg64(cpu_V0
, rn
+ pass
);
5177 neon_load_reg64(cpu_V1
, rm
+ pass
);
5181 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5184 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5190 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5193 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5199 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5201 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5206 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5209 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5215 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5217 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5220 case NEON_3R_VQRSHL
:
5222 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5225 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5229 case NEON_3R_VADD_VSUB
:
5231 tcg_gen_sub_i64(CPU_V001
);
5233 tcg_gen_add_i64(CPU_V001
);
5239 neon_store_reg64(cpu_V0
, rd
+ pass
);
5248 case NEON_3R_VQRSHL
:
5251 /* Shift instruction operands are reversed. */
5266 case NEON_3R_FLOAT_ARITH
:
5267 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5269 case NEON_3R_FLOAT_MINMAX
:
5270 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5272 case NEON_3R_FLOAT_CMP
:
5274 /* no encoding for U=0 C=1x */
5278 case NEON_3R_FLOAT_ACMP
:
5283 case NEON_3R_FLOAT_MISC
:
5284 /* VMAXNM/VMINNM in ARMv8 */
5285 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5290 if (u
&& (size
!= 0)) {
5291 /* UNDEF on invalid size for polynomial subcase */
5296 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5304 if (pairwise
&& q
) {
5305 /* All the pairwise insns UNDEF if Q is set */
5309 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5314 tmp
= neon_load_reg(rn
, 0);
5315 tmp2
= neon_load_reg(rn
, 1);
5317 tmp
= neon_load_reg(rm
, 0);
5318 tmp2
= neon_load_reg(rm
, 1);
5322 tmp
= neon_load_reg(rn
, pass
);
5323 tmp2
= neon_load_reg(rm
, pass
);
5327 GEN_NEON_INTEGER_OP(hadd
);
5330 GEN_NEON_INTEGER_OP_ENV(qadd
);
5332 case NEON_3R_VRHADD
:
5333 GEN_NEON_INTEGER_OP(rhadd
);
5335 case NEON_3R_LOGIC
: /* Logic ops. */
5336 switch ((u
<< 2) | size
) {
5338 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5341 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5344 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5347 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5350 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5353 tmp3
= neon_load_reg(rd
, pass
);
5354 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5355 tcg_temp_free_i32(tmp3
);
5358 tmp3
= neon_load_reg(rd
, pass
);
5359 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5360 tcg_temp_free_i32(tmp3
);
5363 tmp3
= neon_load_reg(rd
, pass
);
5364 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5365 tcg_temp_free_i32(tmp3
);
5370 GEN_NEON_INTEGER_OP(hsub
);
5373 GEN_NEON_INTEGER_OP_ENV(qsub
);
5376 GEN_NEON_INTEGER_OP(cgt
);
5379 GEN_NEON_INTEGER_OP(cge
);
5382 GEN_NEON_INTEGER_OP(shl
);
5385 GEN_NEON_INTEGER_OP_ENV(qshl
);
5388 GEN_NEON_INTEGER_OP(rshl
);
5390 case NEON_3R_VQRSHL
:
5391 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5394 GEN_NEON_INTEGER_OP(max
);
5397 GEN_NEON_INTEGER_OP(min
);
5400 GEN_NEON_INTEGER_OP(abd
);
5403 GEN_NEON_INTEGER_OP(abd
);
5404 tcg_temp_free_i32(tmp2
);
5405 tmp2
= neon_load_reg(rd
, pass
);
5406 gen_neon_add(size
, tmp
, tmp2
);
5408 case NEON_3R_VADD_VSUB
:
5409 if (!u
) { /* VADD */
5410 gen_neon_add(size
, tmp
, tmp2
);
5413 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5414 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5415 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5420 case NEON_3R_VTST_VCEQ
:
5421 if (!u
) { /* VTST */
5423 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5424 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5425 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5430 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5431 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5432 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5437 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5439 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5440 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5441 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5444 tcg_temp_free_i32(tmp2
);
5445 tmp2
= neon_load_reg(rd
, pass
);
5447 gen_neon_rsb(size
, tmp
, tmp2
);
5449 gen_neon_add(size
, tmp
, tmp2
);
5453 if (u
) { /* polynomial */
5454 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5455 } else { /* Integer */
5457 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5458 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5459 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5465 GEN_NEON_INTEGER_OP(pmax
);
5468 GEN_NEON_INTEGER_OP(pmin
);
5470 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5471 if (!u
) { /* VQDMULH */
5474 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5477 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5481 } else { /* VQRDMULH */
5484 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5487 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5495 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5496 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5497 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5501 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5503 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5504 switch ((u
<< 2) | size
) {
5507 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5510 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5513 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5518 tcg_temp_free_ptr(fpstatus
);
5521 case NEON_3R_FLOAT_MULTIPLY
:
5523 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5524 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5526 tcg_temp_free_i32(tmp2
);
5527 tmp2
= neon_load_reg(rd
, pass
);
5529 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5531 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5534 tcg_temp_free_ptr(fpstatus
);
5537 case NEON_3R_FLOAT_CMP
:
5539 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5541 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5544 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5546 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5549 tcg_temp_free_ptr(fpstatus
);
5552 case NEON_3R_FLOAT_ACMP
:
5554 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5556 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5558 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5560 tcg_temp_free_ptr(fpstatus
);
5563 case NEON_3R_FLOAT_MINMAX
:
5565 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5567 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5569 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5571 tcg_temp_free_ptr(fpstatus
);
5574 case NEON_3R_FLOAT_MISC
:
5577 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5579 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5581 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5583 tcg_temp_free_ptr(fpstatus
);
5586 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5588 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5594 /* VFMA, VFMS: fused multiply-add */
5595 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5596 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5599 gen_helper_vfp_negs(tmp
, tmp
);
5601 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5602 tcg_temp_free_i32(tmp3
);
5603 tcg_temp_free_ptr(fpstatus
);
5609 tcg_temp_free_i32(tmp2
);
5611 /* Save the result. For elementwise operations we can put it
5612 straight into the destination register. For pairwise operations
5613 we have to be careful to avoid clobbering the source operands. */
5614 if (pairwise
&& rd
== rm
) {
5615 neon_store_scratch(pass
, tmp
);
5617 neon_store_reg(rd
, pass
, tmp
);
5621 if (pairwise
&& rd
== rm
) {
5622 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5623 tmp
= neon_load_scratch(pass
);
5624 neon_store_reg(rd
, pass
, tmp
);
5627 /* End of 3 register same size operations. */
5628 } else if (insn
& (1 << 4)) {
5629 if ((insn
& 0x00380080) != 0) {
5630 /* Two registers and shift. */
5631 op
= (insn
>> 8) & 0xf;
5632 if (insn
& (1 << 7)) {
5640 while ((insn
& (1 << (size
+ 19))) == 0)
5643 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5644 /* To avoid excessive duplication of ops we implement shift
5645 by immediate using the variable shift operations. */
5647 /* Shift by immediate:
5648 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5649 if (q
&& ((rd
| rm
) & 1)) {
5652 if (!u
&& (op
== 4 || op
== 6)) {
5655 /* Right shifts are encoded as N - shift, where N is the
5656 element size in bits. */
5658 shift
= shift
- (1 << (size
+ 3));
5666 imm
= (uint8_t) shift
;
5671 imm
= (uint16_t) shift
;
5682 for (pass
= 0; pass
< count
; pass
++) {
5684 neon_load_reg64(cpu_V0
, rm
+ pass
);
5685 tcg_gen_movi_i64(cpu_V1
, imm
);
5690 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5692 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5697 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5699 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5702 case 5: /* VSHL, VSLI */
5703 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5705 case 6: /* VQSHLU */
5706 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5711 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5714 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5719 if (op
== 1 || op
== 3) {
5721 neon_load_reg64(cpu_V1
, rd
+ pass
);
5722 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5723 } else if (op
== 4 || (op
== 5 && u
)) {
5725 neon_load_reg64(cpu_V1
, rd
+ pass
);
5727 if (shift
< -63 || shift
> 63) {
5731 mask
= 0xffffffffffffffffull
>> -shift
;
5733 mask
= 0xffffffffffffffffull
<< shift
;
5736 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5737 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5739 neon_store_reg64(cpu_V0
, rd
+ pass
);
5740 } else { /* size < 3 */
5741 /* Operands in T0 and T1. */
5742 tmp
= neon_load_reg(rm
, pass
);
5743 tmp2
= tcg_temp_new_i32();
5744 tcg_gen_movi_i32(tmp2
, imm
);
5748 GEN_NEON_INTEGER_OP(shl
);
5752 GEN_NEON_INTEGER_OP(rshl
);
5755 case 5: /* VSHL, VSLI */
5757 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5758 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5759 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5763 case 6: /* VQSHLU */
5766 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5770 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5774 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5782 GEN_NEON_INTEGER_OP_ENV(qshl
);
5785 tcg_temp_free_i32(tmp2
);
5787 if (op
== 1 || op
== 3) {
5789 tmp2
= neon_load_reg(rd
, pass
);
5790 gen_neon_add(size
, tmp
, tmp2
);
5791 tcg_temp_free_i32(tmp2
);
5792 } else if (op
== 4 || (op
== 5 && u
)) {
5797 mask
= 0xff >> -shift
;
5799 mask
= (uint8_t)(0xff << shift
);
5805 mask
= 0xffff >> -shift
;
5807 mask
= (uint16_t)(0xffff << shift
);
5811 if (shift
< -31 || shift
> 31) {
5815 mask
= 0xffffffffu
>> -shift
;
5817 mask
= 0xffffffffu
<< shift
;
5823 tmp2
= neon_load_reg(rd
, pass
);
5824 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5825 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5826 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5827 tcg_temp_free_i32(tmp2
);
5829 neon_store_reg(rd
, pass
, tmp
);
5832 } else if (op
< 10) {
5833 /* Shift by immediate and narrow:
5834 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5835 int input_unsigned
= (op
== 8) ? !u
: u
;
5839 shift
= shift
- (1 << (size
+ 3));
5842 tmp64
= tcg_const_i64(shift
);
5843 neon_load_reg64(cpu_V0
, rm
);
5844 neon_load_reg64(cpu_V1
, rm
+ 1);
5845 for (pass
= 0; pass
< 2; pass
++) {
5853 if (input_unsigned
) {
5854 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5856 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5859 if (input_unsigned
) {
5860 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5862 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5865 tmp
= tcg_temp_new_i32();
5866 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5867 neon_store_reg(rd
, pass
, tmp
);
5869 tcg_temp_free_i64(tmp64
);
5872 imm
= (uint16_t)shift
;
5876 imm
= (uint32_t)shift
;
5878 tmp2
= tcg_const_i32(imm
);
5879 tmp4
= neon_load_reg(rm
+ 1, 0);
5880 tmp5
= neon_load_reg(rm
+ 1, 1);
5881 for (pass
= 0; pass
< 2; pass
++) {
5883 tmp
= neon_load_reg(rm
, 0);
5887 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5890 tmp3
= neon_load_reg(rm
, 1);
5894 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5896 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5897 tcg_temp_free_i32(tmp
);
5898 tcg_temp_free_i32(tmp3
);
5899 tmp
= tcg_temp_new_i32();
5900 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5901 neon_store_reg(rd
, pass
, tmp
);
5903 tcg_temp_free_i32(tmp2
);
5905 } else if (op
== 10) {
5907 if (q
|| (rd
& 1)) {
5910 tmp
= neon_load_reg(rm
, 0);
5911 tmp2
= neon_load_reg(rm
, 1);
5912 for (pass
= 0; pass
< 2; pass
++) {
5916 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5919 /* The shift is less than the width of the source
5920 type, so we can just shift the whole register. */
5921 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5922 /* Widen the result of shift: we need to clear
5923 * the potential overflow bits resulting from
5924 * left bits of the narrow input appearing as
5925 * right bits of left the neighbour narrow
5927 if (size
< 2 || !u
) {
5930 imm
= (0xffu
>> (8 - shift
));
5932 } else if (size
== 1) {
5933 imm
= 0xffff >> (16 - shift
);
5936 imm
= 0xffffffff >> (32 - shift
);
5939 imm64
= imm
| (((uint64_t)imm
) << 32);
5943 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5946 neon_store_reg64(cpu_V0
, rd
+ pass
);
5948 } else if (op
>= 14) {
5949 /* VCVT fixed-point. */
5950 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5953 /* We have already masked out the must-be-1 top bit of imm6,
5954 * hence this 32-shift where the ARM ARM has 64-imm6.
5957 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5958 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5961 gen_vfp_ulto(0, shift
, 1);
5963 gen_vfp_slto(0, shift
, 1);
5966 gen_vfp_toul(0, shift
, 1);
5968 gen_vfp_tosl(0, shift
, 1);
5970 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5975 } else { /* (insn & 0x00380080) == 0 */
5977 if (q
&& (rd
& 1)) {
5981 op
= (insn
>> 8) & 0xf;
5982 /* One register and immediate. */
5983 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5984 invert
= (insn
& (1 << 5)) != 0;
5985 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5986 * We choose to not special-case this and will behave as if a
5987 * valid constant encoding of 0 had been given.
6006 imm
= (imm
<< 8) | (imm
<< 24);
6009 imm
= (imm
<< 8) | 0xff;
6012 imm
= (imm
<< 16) | 0xffff;
6015 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6023 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6024 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6030 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6031 if (op
& 1 && op
< 12) {
6032 tmp
= neon_load_reg(rd
, pass
);
6034 /* The immediate value has already been inverted, so
6036 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6038 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6042 tmp
= tcg_temp_new_i32();
6043 if (op
== 14 && invert
) {
6047 for (n
= 0; n
< 4; n
++) {
6048 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6049 val
|= 0xff << (n
* 8);
6051 tcg_gen_movi_i32(tmp
, val
);
6053 tcg_gen_movi_i32(tmp
, imm
);
6056 neon_store_reg(rd
, pass
, tmp
);
6059 } else { /* (insn & 0x00800010 == 0x00800000) */
6061 op
= (insn
>> 8) & 0xf;
6062 if ((insn
& (1 << 6)) == 0) {
6063 /* Three registers of different lengths. */
6067 /* undefreq: bit 0 : UNDEF if size == 0
6068 * bit 1 : UNDEF if size == 1
6069 * bit 2 : UNDEF if size == 2
6070 * bit 3 : UNDEF if U == 1
6071 * Note that [2:0] set implies 'always UNDEF'
6074 /* prewiden, src1_wide, src2_wide, undefreq */
6075 static const int neon_3reg_wide
[16][4] = {
6076 {1, 0, 0, 0}, /* VADDL */
6077 {1, 1, 0, 0}, /* VADDW */
6078 {1, 0, 0, 0}, /* VSUBL */
6079 {1, 1, 0, 0}, /* VSUBW */
6080 {0, 1, 1, 0}, /* VADDHN */
6081 {0, 0, 0, 0}, /* VABAL */
6082 {0, 1, 1, 0}, /* VSUBHN */
6083 {0, 0, 0, 0}, /* VABDL */
6084 {0, 0, 0, 0}, /* VMLAL */
6085 {0, 0, 0, 9}, /* VQDMLAL */
6086 {0, 0, 0, 0}, /* VMLSL */
6087 {0, 0, 0, 9}, /* VQDMLSL */
6088 {0, 0, 0, 0}, /* Integer VMULL */
6089 {0, 0, 0, 1}, /* VQDMULL */
6090 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6091 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6094 prewiden
= neon_3reg_wide
[op
][0];
6095 src1_wide
= neon_3reg_wide
[op
][1];
6096 src2_wide
= neon_3reg_wide
[op
][2];
6097 undefreq
= neon_3reg_wide
[op
][3];
6099 if ((undefreq
& (1 << size
)) ||
6100 ((undefreq
& 8) && u
)) {
6103 if ((src1_wide
&& (rn
& 1)) ||
6104 (src2_wide
&& (rm
& 1)) ||
6105 (!src2_wide
&& (rd
& 1))) {
6109 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6110 * outside the loop below as it only performs a single pass.
6112 if (op
== 14 && size
== 2) {
6113 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6115 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6118 tcg_rn
= tcg_temp_new_i64();
6119 tcg_rm
= tcg_temp_new_i64();
6120 tcg_rd
= tcg_temp_new_i64();
6121 neon_load_reg64(tcg_rn
, rn
);
6122 neon_load_reg64(tcg_rm
, rm
);
6123 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6124 neon_store_reg64(tcg_rd
, rd
);
6125 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6126 neon_store_reg64(tcg_rd
, rd
+ 1);
6127 tcg_temp_free_i64(tcg_rn
);
6128 tcg_temp_free_i64(tcg_rm
);
6129 tcg_temp_free_i64(tcg_rd
);
6133 /* Avoid overlapping operands. Wide source operands are
6134 always aligned so will never overlap with wide
6135 destinations in problematic ways. */
6136 if (rd
== rm
&& !src2_wide
) {
6137 tmp
= neon_load_reg(rm
, 1);
6138 neon_store_scratch(2, tmp
);
6139 } else if (rd
== rn
&& !src1_wide
) {
6140 tmp
= neon_load_reg(rn
, 1);
6141 neon_store_scratch(2, tmp
);
6143 TCGV_UNUSED_I32(tmp3
);
6144 for (pass
= 0; pass
< 2; pass
++) {
6146 neon_load_reg64(cpu_V0
, rn
+ pass
);
6147 TCGV_UNUSED_I32(tmp
);
6149 if (pass
== 1 && rd
== rn
) {
6150 tmp
= neon_load_scratch(2);
6152 tmp
= neon_load_reg(rn
, pass
);
6155 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6159 neon_load_reg64(cpu_V1
, rm
+ pass
);
6160 TCGV_UNUSED_I32(tmp2
);
6162 if (pass
== 1 && rd
== rm
) {
6163 tmp2
= neon_load_scratch(2);
6165 tmp2
= neon_load_reg(rm
, pass
);
6168 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6172 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6173 gen_neon_addl(size
);
6175 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6176 gen_neon_subl(size
);
6178 case 5: case 7: /* VABAL, VABDL */
6179 switch ((size
<< 1) | u
) {
6181 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6184 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6187 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6190 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6193 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6196 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6200 tcg_temp_free_i32(tmp2
);
6201 tcg_temp_free_i32(tmp
);
6203 case 8: case 9: case 10: case 11: case 12: case 13:
6204 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6205 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6207 case 14: /* Polynomial VMULL */
6208 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6209 tcg_temp_free_i32(tmp2
);
6210 tcg_temp_free_i32(tmp
);
6212 default: /* 15 is RESERVED: caught earlier */
6217 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6218 neon_store_reg64(cpu_V0
, rd
+ pass
);
6219 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6221 neon_load_reg64(cpu_V1
, rd
+ pass
);
6223 case 10: /* VMLSL */
6224 gen_neon_negl(cpu_V0
, size
);
6226 case 5: case 8: /* VABAL, VMLAL */
6227 gen_neon_addl(size
);
6229 case 9: case 11: /* VQDMLAL, VQDMLSL */
6230 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6232 gen_neon_negl(cpu_V0
, size
);
6234 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6239 neon_store_reg64(cpu_V0
, rd
+ pass
);
6240 } else if (op
== 4 || op
== 6) {
6241 /* Narrowing operation. */
6242 tmp
= tcg_temp_new_i32();
6246 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6249 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6252 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6253 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6260 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6263 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6266 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6267 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6268 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6276 neon_store_reg(rd
, 0, tmp3
);
6277 neon_store_reg(rd
, 1, tmp
);
6280 /* Write back the result. */
6281 neon_store_reg64(cpu_V0
, rd
+ pass
);
6285 /* Two registers and a scalar. NB that for ops of this form
6286 * the ARM ARM labels bit 24 as Q, but it is in our variable
6293 case 1: /* Float VMLA scalar */
6294 case 5: /* Floating point VMLS scalar */
6295 case 9: /* Floating point VMUL scalar */
6300 case 0: /* Integer VMLA scalar */
6301 case 4: /* Integer VMLS scalar */
6302 case 8: /* Integer VMUL scalar */
6303 case 12: /* VQDMULH scalar */
6304 case 13: /* VQRDMULH scalar */
6305 if (u
&& ((rd
| rn
) & 1)) {
6308 tmp
= neon_get_scalar(size
, rm
);
6309 neon_store_scratch(0, tmp
);
6310 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6311 tmp
= neon_load_scratch(0);
6312 tmp2
= neon_load_reg(rn
, pass
);
6315 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6317 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6319 } else if (op
== 13) {
6321 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6323 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6325 } else if (op
& 1) {
6326 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6327 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6328 tcg_temp_free_ptr(fpstatus
);
6331 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6332 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6333 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6337 tcg_temp_free_i32(tmp2
);
6340 tmp2
= neon_load_reg(rd
, pass
);
6343 gen_neon_add(size
, tmp
, tmp2
);
6347 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6348 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6349 tcg_temp_free_ptr(fpstatus
);
6353 gen_neon_rsb(size
, tmp
, tmp2
);
6357 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6358 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6359 tcg_temp_free_ptr(fpstatus
);
6365 tcg_temp_free_i32(tmp2
);
6367 neon_store_reg(rd
, pass
, tmp
);
6370 case 3: /* VQDMLAL scalar */
6371 case 7: /* VQDMLSL scalar */
6372 case 11: /* VQDMULL scalar */
6377 case 2: /* VMLAL sclar */
6378 case 6: /* VMLSL scalar */
6379 case 10: /* VMULL scalar */
6383 tmp2
= neon_get_scalar(size
, rm
);
6384 /* We need a copy of tmp2 because gen_neon_mull
6385 * deletes it during pass 0. */
6386 tmp4
= tcg_temp_new_i32();
6387 tcg_gen_mov_i32(tmp4
, tmp2
);
6388 tmp3
= neon_load_reg(rn
, 1);
6390 for (pass
= 0; pass
< 2; pass
++) {
6392 tmp
= neon_load_reg(rn
, 0);
6397 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6399 neon_load_reg64(cpu_V1
, rd
+ pass
);
6403 gen_neon_negl(cpu_V0
, size
);
6406 gen_neon_addl(size
);
6409 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6411 gen_neon_negl(cpu_V0
, size
);
6413 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6419 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6424 neon_store_reg64(cpu_V0
, rd
+ pass
);
6429 default: /* 14 and 15 are RESERVED */
6433 } else { /* size == 3 */
6436 imm
= (insn
>> 8) & 0xf;
6441 if (q
&& ((rd
| rn
| rm
) & 1)) {
6446 neon_load_reg64(cpu_V0
, rn
);
6448 neon_load_reg64(cpu_V1
, rn
+ 1);
6450 } else if (imm
== 8) {
6451 neon_load_reg64(cpu_V0
, rn
+ 1);
6453 neon_load_reg64(cpu_V1
, rm
);
6456 tmp64
= tcg_temp_new_i64();
6458 neon_load_reg64(cpu_V0
, rn
);
6459 neon_load_reg64(tmp64
, rn
+ 1);
6461 neon_load_reg64(cpu_V0
, rn
+ 1);
6462 neon_load_reg64(tmp64
, rm
);
6464 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6465 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6466 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6468 neon_load_reg64(cpu_V1
, rm
);
6470 neon_load_reg64(cpu_V1
, rm
+ 1);
6473 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6474 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6475 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6476 tcg_temp_free_i64(tmp64
);
6479 neon_load_reg64(cpu_V0
, rn
);
6480 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6481 neon_load_reg64(cpu_V1
, rm
);
6482 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6483 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6485 neon_store_reg64(cpu_V0
, rd
);
6487 neon_store_reg64(cpu_V1
, rd
+ 1);
6489 } else if ((insn
& (1 << 11)) == 0) {
6490 /* Two register misc. */
6491 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6492 size
= (insn
>> 18) & 3;
6493 /* UNDEF for unknown op values and bad op-size combinations */
6494 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6497 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6498 q
&& ((rm
| rd
) & 1)) {
6502 case NEON_2RM_VREV64
:
6503 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6504 tmp
= neon_load_reg(rm
, pass
* 2);
6505 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6507 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6508 case 1: gen_swap_half(tmp
); break;
6509 case 2: /* no-op */ break;
6512 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6514 neon_store_reg(rd
, pass
* 2, tmp2
);
6517 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6518 case 1: gen_swap_half(tmp2
); break;
6521 neon_store_reg(rd
, pass
* 2, tmp2
);
6525 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6526 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6527 for (pass
= 0; pass
< q
+ 1; pass
++) {
6528 tmp
= neon_load_reg(rm
, pass
* 2);
6529 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6530 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6531 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6533 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6534 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6535 case 2: tcg_gen_add_i64(CPU_V001
); break;
6538 if (op
>= NEON_2RM_VPADAL
) {
6540 neon_load_reg64(cpu_V1
, rd
+ pass
);
6541 gen_neon_addl(size
);
6543 neon_store_reg64(cpu_V0
, rd
+ pass
);
6549 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6550 tmp
= neon_load_reg(rm
, n
);
6551 tmp2
= neon_load_reg(rd
, n
+ 1);
6552 neon_store_reg(rm
, n
, tmp2
);
6553 neon_store_reg(rd
, n
+ 1, tmp
);
6560 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6565 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6569 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6570 /* also VQMOVUN; op field and mnemonics don't line up */
6574 TCGV_UNUSED_I32(tmp2
);
6575 for (pass
= 0; pass
< 2; pass
++) {
6576 neon_load_reg64(cpu_V0
, rm
+ pass
);
6577 tmp
= tcg_temp_new_i32();
6578 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6583 neon_store_reg(rd
, 0, tmp2
);
6584 neon_store_reg(rd
, 1, tmp
);
6588 case NEON_2RM_VSHLL
:
6589 if (q
|| (rd
& 1)) {
6592 tmp
= neon_load_reg(rm
, 0);
6593 tmp2
= neon_load_reg(rm
, 1);
6594 for (pass
= 0; pass
< 2; pass
++) {
6597 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6598 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6599 neon_store_reg64(cpu_V0
, rd
+ pass
);
6602 case NEON_2RM_VCVT_F16_F32
:
6603 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6607 tmp
= tcg_temp_new_i32();
6608 tmp2
= tcg_temp_new_i32();
6609 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6610 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6611 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6612 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6613 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6614 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6615 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6616 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6617 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6618 neon_store_reg(rd
, 0, tmp2
);
6619 tmp2
= tcg_temp_new_i32();
6620 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6621 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6622 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6623 neon_store_reg(rd
, 1, tmp2
);
6624 tcg_temp_free_i32(tmp
);
6626 case NEON_2RM_VCVT_F32_F16
:
6627 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6631 tmp3
= tcg_temp_new_i32();
6632 tmp
= neon_load_reg(rm
, 0);
6633 tmp2
= neon_load_reg(rm
, 1);
6634 tcg_gen_ext16u_i32(tmp3
, tmp
);
6635 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6636 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6637 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6638 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6639 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6640 tcg_temp_free_i32(tmp
);
6641 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6642 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6643 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6644 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6645 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6646 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6647 tcg_temp_free_i32(tmp2
);
6648 tcg_temp_free_i32(tmp3
);
6650 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6651 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6652 || ((rm
| rd
) & 1)) {
6655 tmp
= tcg_const_i32(rd
);
6656 tmp2
= tcg_const_i32(rm
);
6658 /* Bit 6 is the lowest opcode bit; it distinguishes between
6659 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6661 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6663 if (op
== NEON_2RM_AESE
) {
6664 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6666 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6668 tcg_temp_free_i32(tmp
);
6669 tcg_temp_free_i32(tmp2
);
6670 tcg_temp_free_i32(tmp3
);
6672 case NEON_2RM_SHA1H
:
6673 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
6674 || ((rm
| rd
) & 1)) {
6677 tmp
= tcg_const_i32(rd
);
6678 tmp2
= tcg_const_i32(rm
);
6680 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6682 tcg_temp_free_i32(tmp
);
6683 tcg_temp_free_i32(tmp2
);
6685 case NEON_2RM_SHA1SU1
:
6686 if ((rm
| rd
) & 1) {
6689 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6691 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
6694 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
6697 tmp
= tcg_const_i32(rd
);
6698 tmp2
= tcg_const_i32(rm
);
6700 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6702 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6704 tcg_temp_free_i32(tmp
);
6705 tcg_temp_free_i32(tmp2
);
6709 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6710 if (neon_2rm_is_float_op(op
)) {
6711 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6712 neon_reg_offset(rm
, pass
));
6713 TCGV_UNUSED_I32(tmp
);
6715 tmp
= neon_load_reg(rm
, pass
);
6718 case NEON_2RM_VREV32
:
6720 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6721 case 1: gen_swap_half(tmp
); break;
6725 case NEON_2RM_VREV16
:
6730 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6731 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6732 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6738 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6739 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6740 case 2: gen_helper_clz(tmp
, tmp
); break;
6745 gen_helper_neon_cnt_u8(tmp
, tmp
);
6748 tcg_gen_not_i32(tmp
, tmp
);
6750 case NEON_2RM_VQABS
:
6753 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6756 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6759 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6764 case NEON_2RM_VQNEG
:
6767 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6770 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6773 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6778 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6779 tmp2
= tcg_const_i32(0);
6781 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6782 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6783 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6786 tcg_temp_free_i32(tmp2
);
6787 if (op
== NEON_2RM_VCLE0
) {
6788 tcg_gen_not_i32(tmp
, tmp
);
6791 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6792 tmp2
= tcg_const_i32(0);
6794 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6795 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6796 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6799 tcg_temp_free_i32(tmp2
);
6800 if (op
== NEON_2RM_VCLT0
) {
6801 tcg_gen_not_i32(tmp
, tmp
);
6804 case NEON_2RM_VCEQ0
:
6805 tmp2
= tcg_const_i32(0);
6807 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6808 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6809 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6812 tcg_temp_free_i32(tmp2
);
6816 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6817 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6818 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6823 tmp2
= tcg_const_i32(0);
6824 gen_neon_rsb(size
, tmp
, tmp2
);
6825 tcg_temp_free_i32(tmp2
);
6827 case NEON_2RM_VCGT0_F
:
6829 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6830 tmp2
= tcg_const_i32(0);
6831 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6832 tcg_temp_free_i32(tmp2
);
6833 tcg_temp_free_ptr(fpstatus
);
6836 case NEON_2RM_VCGE0_F
:
6838 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6839 tmp2
= tcg_const_i32(0);
6840 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6841 tcg_temp_free_i32(tmp2
);
6842 tcg_temp_free_ptr(fpstatus
);
6845 case NEON_2RM_VCEQ0_F
:
6847 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6848 tmp2
= tcg_const_i32(0);
6849 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6850 tcg_temp_free_i32(tmp2
);
6851 tcg_temp_free_ptr(fpstatus
);
6854 case NEON_2RM_VCLE0_F
:
6856 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6857 tmp2
= tcg_const_i32(0);
6858 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6859 tcg_temp_free_i32(tmp2
);
6860 tcg_temp_free_ptr(fpstatus
);
6863 case NEON_2RM_VCLT0_F
:
6865 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6866 tmp2
= tcg_const_i32(0);
6867 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6868 tcg_temp_free_i32(tmp2
);
6869 tcg_temp_free_ptr(fpstatus
);
6872 case NEON_2RM_VABS_F
:
6875 case NEON_2RM_VNEG_F
:
6879 tmp2
= neon_load_reg(rd
, pass
);
6880 neon_store_reg(rm
, pass
, tmp2
);
6883 tmp2
= neon_load_reg(rd
, pass
);
6885 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6886 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6889 neon_store_reg(rm
, pass
, tmp2
);
6891 case NEON_2RM_VRINTN
:
6892 case NEON_2RM_VRINTA
:
6893 case NEON_2RM_VRINTM
:
6894 case NEON_2RM_VRINTP
:
6895 case NEON_2RM_VRINTZ
:
6898 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6901 if (op
== NEON_2RM_VRINTZ
) {
6902 rmode
= FPROUNDING_ZERO
;
6904 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6907 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6908 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6910 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6911 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6913 tcg_temp_free_ptr(fpstatus
);
6914 tcg_temp_free_i32(tcg_rmode
);
6917 case NEON_2RM_VRINTX
:
6919 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6920 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6921 tcg_temp_free_ptr(fpstatus
);
6924 case NEON_2RM_VCVTAU
:
6925 case NEON_2RM_VCVTAS
:
6926 case NEON_2RM_VCVTNU
:
6927 case NEON_2RM_VCVTNS
:
6928 case NEON_2RM_VCVTPU
:
6929 case NEON_2RM_VCVTPS
:
6930 case NEON_2RM_VCVTMU
:
6931 case NEON_2RM_VCVTMS
:
6933 bool is_signed
= !extract32(insn
, 7, 1);
6934 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6935 TCGv_i32 tcg_rmode
, tcg_shift
;
6936 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6938 tcg_shift
= tcg_const_i32(0);
6939 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6940 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6944 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6947 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6951 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6953 tcg_temp_free_i32(tcg_rmode
);
6954 tcg_temp_free_i32(tcg_shift
);
6955 tcg_temp_free_ptr(fpst
);
6958 case NEON_2RM_VRECPE
:
6960 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6961 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6962 tcg_temp_free_ptr(fpstatus
);
6965 case NEON_2RM_VRSQRTE
:
6967 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6968 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6969 tcg_temp_free_ptr(fpstatus
);
6972 case NEON_2RM_VRECPE_F
:
6974 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6975 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6976 tcg_temp_free_ptr(fpstatus
);
6979 case NEON_2RM_VRSQRTE_F
:
6981 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6982 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6983 tcg_temp_free_ptr(fpstatus
);
6986 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6989 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6992 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6993 gen_vfp_tosiz(0, 1);
6995 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6996 gen_vfp_touiz(0, 1);
6999 /* Reserved op values were caught by the
7000 * neon_2rm_sizes[] check earlier.
7004 if (neon_2rm_is_float_op(op
)) {
7005 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7006 neon_reg_offset(rd
, pass
));
7008 neon_store_reg(rd
, pass
, tmp
);
7013 } else if ((insn
& (1 << 10)) == 0) {
7015 int n
= ((insn
>> 8) & 3) + 1;
7016 if ((rn
+ n
) > 32) {
7017 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7018 * helper function running off the end of the register file.
7023 if (insn
& (1 << 6)) {
7024 tmp
= neon_load_reg(rd
, 0);
7026 tmp
= tcg_temp_new_i32();
7027 tcg_gen_movi_i32(tmp
, 0);
7029 tmp2
= neon_load_reg(rm
, 0);
7030 tmp4
= tcg_const_i32(rn
);
7031 tmp5
= tcg_const_i32(n
);
7032 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7033 tcg_temp_free_i32(tmp
);
7034 if (insn
& (1 << 6)) {
7035 tmp
= neon_load_reg(rd
, 1);
7037 tmp
= tcg_temp_new_i32();
7038 tcg_gen_movi_i32(tmp
, 0);
7040 tmp3
= neon_load_reg(rm
, 1);
7041 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7042 tcg_temp_free_i32(tmp5
);
7043 tcg_temp_free_i32(tmp4
);
7044 neon_store_reg(rd
, 0, tmp2
);
7045 neon_store_reg(rd
, 1, tmp3
);
7046 tcg_temp_free_i32(tmp
);
7047 } else if ((insn
& 0x380) == 0) {
7049 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7052 if (insn
& (1 << 19)) {
7053 tmp
= neon_load_reg(rm
, 1);
7055 tmp
= neon_load_reg(rm
, 0);
7057 if (insn
& (1 << 16)) {
7058 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7059 } else if (insn
& (1 << 17)) {
7060 if ((insn
>> 18) & 1)
7061 gen_neon_dup_high16(tmp
);
7063 gen_neon_dup_low16(tmp
);
7065 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7066 tmp2
= tcg_temp_new_i32();
7067 tcg_gen_mov_i32(tmp2
, tmp
);
7068 neon_store_reg(rd
, pass
, tmp2
);
7070 tcg_temp_free_i32(tmp
);
7079 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7081 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7082 const ARMCPRegInfo
*ri
;
7084 cpnum
= (insn
>> 8) & 0xf;
7086 /* First check for coprocessor space used for XScale/iwMMXt insns */
7087 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7088 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7091 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7092 return disas_iwmmxt_insn(s
, insn
);
7093 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7094 return disas_dsp_insn(s
, insn
);
7099 /* Otherwise treat as a generic register access */
7100 is64
= (insn
& (1 << 25)) == 0;
7101 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7109 opc1
= (insn
>> 4) & 0xf;
7111 rt2
= (insn
>> 16) & 0xf;
7113 crn
= (insn
>> 16) & 0xf;
7114 opc1
= (insn
>> 21) & 7;
7115 opc2
= (insn
>> 5) & 7;
7118 isread
= (insn
>> 20) & 1;
7119 rt
= (insn
>> 12) & 0xf;
7121 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7122 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7124 /* Check access permissions */
7125 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7130 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7131 /* Emit code to perform further access permissions checks at
7132 * runtime; this may result in an exception.
7133 * Note that on XScale all cp0..c13 registers do an access check
7134 * call in order to handle c15_cpar.
7140 /* Note that since we are an implementation which takes an
7141 * exception on a trapped conditional instruction only if the
7142 * instruction passes its condition code check, we can take
7143 * advantage of the clause in the ARM ARM that allows us to set
7144 * the COND field in the instruction to 0xE in all cases.
7145 * We could fish the actual condition out of the insn (ARM)
7146 * or the condexec bits (Thumb) but it isn't necessary.
7151 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7154 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7155 rt
, isread
, s
->thumb
);
7160 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7163 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7164 rt
, isread
, s
->thumb
);
7168 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7169 * so this can only happen if this is an ARMv7 or earlier CPU,
7170 * in which case the syndrome information won't actually be
7173 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7174 syndrome
= syn_uncategorized();
7178 gen_set_pc_im(s
, s
->pc
- 4);
7179 tmpptr
= tcg_const_ptr(ri
);
7180 tcg_syn
= tcg_const_i32(syndrome
);
7181 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7182 tcg_temp_free_ptr(tmpptr
);
7183 tcg_temp_free_i32(tcg_syn
);
7186 /* Handle special cases first */
7187 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7194 gen_set_pc_im(s
, s
->pc
);
7195 s
->is_jmp
= DISAS_WFI
;
7201 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7210 if (ri
->type
& ARM_CP_CONST
) {
7211 tmp64
= tcg_const_i64(ri
->resetvalue
);
7212 } else if (ri
->readfn
) {
7214 tmp64
= tcg_temp_new_i64();
7215 tmpptr
= tcg_const_ptr(ri
);
7216 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7217 tcg_temp_free_ptr(tmpptr
);
7219 tmp64
= tcg_temp_new_i64();
7220 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7222 tmp
= tcg_temp_new_i32();
7223 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7224 store_reg(s
, rt
, tmp
);
7225 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7226 tmp
= tcg_temp_new_i32();
7227 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7228 tcg_temp_free_i64(tmp64
);
7229 store_reg(s
, rt2
, tmp
);
7232 if (ri
->type
& ARM_CP_CONST
) {
7233 tmp
= tcg_const_i32(ri
->resetvalue
);
7234 } else if (ri
->readfn
) {
7236 tmp
= tcg_temp_new_i32();
7237 tmpptr
= tcg_const_ptr(ri
);
7238 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7239 tcg_temp_free_ptr(tmpptr
);
7241 tmp
= load_cpu_offset(ri
->fieldoffset
);
7244 /* Destination register of r15 for 32 bit loads sets
7245 * the condition codes from the high 4 bits of the value
7248 tcg_temp_free_i32(tmp
);
7250 store_reg(s
, rt
, tmp
);
7255 if (ri
->type
& ARM_CP_CONST
) {
7256 /* If not forbidden by access permissions, treat as WI */
7261 TCGv_i32 tmplo
, tmphi
;
7262 TCGv_i64 tmp64
= tcg_temp_new_i64();
7263 tmplo
= load_reg(s
, rt
);
7264 tmphi
= load_reg(s
, rt2
);
7265 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7266 tcg_temp_free_i32(tmplo
);
7267 tcg_temp_free_i32(tmphi
);
7269 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7270 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7271 tcg_temp_free_ptr(tmpptr
);
7273 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7275 tcg_temp_free_i64(tmp64
);
7280 tmp
= load_reg(s
, rt
);
7281 tmpptr
= tcg_const_ptr(ri
);
7282 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7283 tcg_temp_free_ptr(tmpptr
);
7284 tcg_temp_free_i32(tmp
);
7286 TCGv_i32 tmp
= load_reg(s
, rt
);
7287 store_cpu_offset(tmp
, ri
->fieldoffset
);
7292 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7293 /* I/O operations must end the TB here (whether read or write) */
7296 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7297 /* We default to ending the TB on a coprocessor register write,
7298 * but allow this to be suppressed by the register definition
7299 * (usually only necessary to work around guest bugs).
7307 /* Unknown register; this might be a guest error or a QEMU
7308 * unimplemented feature.
7311 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7312 "64 bit system register cp:%d opc1: %d crm:%d "
7314 isread
? "read" : "write", cpnum
, opc1
, crm
,
7315 s
->ns
? "non-secure" : "secure");
7317 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7318 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7320 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7321 s
->ns
? "non-secure" : "secure");
7328 /* Store a 64-bit value to a register pair. Clobbers val. */
7329 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7332 tmp
= tcg_temp_new_i32();
7333 tcg_gen_trunc_i64_i32(tmp
, val
);
7334 store_reg(s
, rlow
, tmp
);
7335 tmp
= tcg_temp_new_i32();
7336 tcg_gen_shri_i64(val
, val
, 32);
7337 tcg_gen_trunc_i64_i32(tmp
, val
);
7338 store_reg(s
, rhigh
, tmp
);
7341 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7342 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7347 /* Load value and extend to 64 bits. */
7348 tmp
= tcg_temp_new_i64();
7349 tmp2
= load_reg(s
, rlow
);
7350 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7351 tcg_temp_free_i32(tmp2
);
7352 tcg_gen_add_i64(val
, val
, tmp
);
7353 tcg_temp_free_i64(tmp
);
7356 /* load and add a 64-bit value from a register pair. */
7357 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7363 /* Load 64-bit value rd:rn. */
7364 tmpl
= load_reg(s
, rlow
);
7365 tmph
= load_reg(s
, rhigh
);
7366 tmp
= tcg_temp_new_i64();
7367 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7368 tcg_temp_free_i32(tmpl
);
7369 tcg_temp_free_i32(tmph
);
7370 tcg_gen_add_i64(val
, val
, tmp
);
7371 tcg_temp_free_i64(tmp
);
7374 /* Set N and Z flags from hi|lo. */
7375 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7377 tcg_gen_mov_i32(cpu_NF
, hi
);
7378 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7381 /* Load/Store exclusive instructions are implemented by remembering
7382 the value/address loaded, and seeing if these are the same
7383 when the store is performed. This should be sufficient to implement
7384 the architecturally mandated semantics, and avoids having to monitor
7387 In system emulation mode only one CPU will be running at once, so
7388 this sequence is effectively atomic. In user emulation mode we
7389 throw an exception and handle the atomic operation elsewhere. */
7390 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7391 TCGv_i32 addr
, int size
)
7393 TCGv_i32 tmp
= tcg_temp_new_i32();
7399 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7402 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7406 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7413 TCGv_i32 tmp2
= tcg_temp_new_i32();
7414 TCGv_i32 tmp3
= tcg_temp_new_i32();
7416 tcg_gen_addi_i32(tmp2
, addr
, 4);
7417 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7418 tcg_temp_free_i32(tmp2
);
7419 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7420 store_reg(s
, rt2
, tmp3
);
7422 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7425 store_reg(s
, rt
, tmp
);
7426 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7429 static void gen_clrex(DisasContext
*s
)
7431 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7434 #ifdef CONFIG_USER_ONLY
7435 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7436 TCGv_i32 addr
, int size
)
7438 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7439 tcg_gen_movi_i32(cpu_exclusive_info
,
7440 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7441 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7444 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7445 TCGv_i32 addr
, int size
)
7448 TCGv_i64 val64
, extaddr
;
7449 TCGLabel
*done_label
;
7450 TCGLabel
*fail_label
;
7452 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7458 fail_label
= gen_new_label();
7459 done_label
= gen_new_label();
7460 extaddr
= tcg_temp_new_i64();
7461 tcg_gen_extu_i32_i64(extaddr
, addr
);
7462 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7463 tcg_temp_free_i64(extaddr
);
7465 tmp
= tcg_temp_new_i32();
7468 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7471 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7475 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7481 val64
= tcg_temp_new_i64();
7483 TCGv_i32 tmp2
= tcg_temp_new_i32();
7484 TCGv_i32 tmp3
= tcg_temp_new_i32();
7485 tcg_gen_addi_i32(tmp2
, addr
, 4);
7486 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7487 tcg_temp_free_i32(tmp2
);
7488 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7489 tcg_temp_free_i32(tmp3
);
7491 tcg_gen_extu_i32_i64(val64
, tmp
);
7493 tcg_temp_free_i32(tmp
);
7495 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7496 tcg_temp_free_i64(val64
);
7498 tmp
= load_reg(s
, rt
);
7501 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7504 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7508 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7513 tcg_temp_free_i32(tmp
);
7515 tcg_gen_addi_i32(addr
, addr
, 4);
7516 tmp
= load_reg(s
, rt2
);
7517 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7518 tcg_temp_free_i32(tmp
);
7520 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7521 tcg_gen_br(done_label
);
7522 gen_set_label(fail_label
);
7523 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7524 gen_set_label(done_label
);
7525 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7532 * @mode: mode field from insn (which stack to store to)
7533 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7534 * @writeback: true if writeback bit set
7536 * Generate code for the SRS (Store Return State) insn.
7538 static void gen_srs(DisasContext
*s
,
7539 uint32_t mode
, uint32_t amode
, bool writeback
)
7542 TCGv_i32 addr
= tcg_temp_new_i32();
7543 TCGv_i32 tmp
= tcg_const_i32(mode
);
7544 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7545 tcg_temp_free_i32(tmp
);
7562 tcg_gen_addi_i32(addr
, addr
, offset
);
7563 tmp
= load_reg(s
, 14);
7564 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7565 tcg_temp_free_i32(tmp
);
7566 tmp
= load_cpu_field(spsr
);
7567 tcg_gen_addi_i32(addr
, addr
, 4);
7568 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7569 tcg_temp_free_i32(tmp
);
7587 tcg_gen_addi_i32(addr
, addr
, offset
);
7588 tmp
= tcg_const_i32(mode
);
7589 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7590 tcg_temp_free_i32(tmp
);
7592 tcg_temp_free_i32(addr
);
7595 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7597 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7604 /* M variants do not implement ARM mode. */
7605 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7610 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7611 * choose to UNDEF. In ARMv5 and above the space is used
7612 * for miscellaneous unconditional instructions.
7616 /* Unconditional instructions. */
7617 if (((insn
>> 25) & 7) == 1) {
7618 /* NEON Data processing. */
7619 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7623 if (disas_neon_data_insn(s
, insn
)) {
7628 if ((insn
& 0x0f100000) == 0x04000000) {
7629 /* NEON load/store. */
7630 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7634 if (disas_neon_ls_insn(s
, insn
)) {
7639 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7641 if (disas_vfp_insn(s
, insn
)) {
7646 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7647 ((insn
& 0x0f30f010) == 0x0710f000)) {
7648 if ((insn
& (1 << 22)) == 0) {
7650 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7654 /* Otherwise PLD; v5TE+ */
7658 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7659 ((insn
& 0x0f70f010) == 0x0650f000)) {
7661 return; /* PLI; V7 */
7663 if (((insn
& 0x0f700000) == 0x04100000) ||
7664 ((insn
& 0x0f700010) == 0x06100000)) {
7665 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7668 return; /* v7MP: Unallocated memory hint: must NOP */
7671 if ((insn
& 0x0ffffdff) == 0x01010000) {
7674 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7675 /* Dynamic endianness switching not implemented. */
7676 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7680 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7681 switch ((insn
>> 4) & 0xf) {
7690 /* We don't emulate caches so these are a no-op. */
7695 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7701 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7703 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7709 rn
= (insn
>> 16) & 0xf;
7710 addr
= load_reg(s
, rn
);
7711 i
= (insn
>> 23) & 3;
7713 case 0: offset
= -4; break; /* DA */
7714 case 1: offset
= 0; break; /* IA */
7715 case 2: offset
= -8; break; /* DB */
7716 case 3: offset
= 4; break; /* IB */
7720 tcg_gen_addi_i32(addr
, addr
, offset
);
7721 /* Load PC into tmp and CPSR into tmp2. */
7722 tmp
= tcg_temp_new_i32();
7723 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7724 tcg_gen_addi_i32(addr
, addr
, 4);
7725 tmp2
= tcg_temp_new_i32();
7726 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7727 if (insn
& (1 << 21)) {
7728 /* Base writeback. */
7730 case 0: offset
= -8; break;
7731 case 1: offset
= 4; break;
7732 case 2: offset
= -4; break;
7733 case 3: offset
= 0; break;
7737 tcg_gen_addi_i32(addr
, addr
, offset
);
7738 store_reg(s
, rn
, addr
);
7740 tcg_temp_free_i32(addr
);
7742 gen_rfe(s
, tmp
, tmp2
);
7744 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7745 /* branch link and change to thumb (blx <offset>) */
7748 val
= (uint32_t)s
->pc
;
7749 tmp
= tcg_temp_new_i32();
7750 tcg_gen_movi_i32(tmp
, val
);
7751 store_reg(s
, 14, tmp
);
7752 /* Sign-extend the 24-bit offset */
7753 offset
= (((int32_t)insn
) << 8) >> 8;
7754 /* offset * 4 + bit24 * 2 + (thumb bit) */
7755 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7756 /* pipeline offset */
7758 /* protected by ARCH(5); above, near the start of uncond block */
7761 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7762 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7763 /* iWMMXt register transfer. */
7764 if (extract32(s
->c15_cpar
, 1, 1)) {
7765 if (!disas_iwmmxt_insn(s
, insn
)) {
7770 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7771 /* Coprocessor double register transfer. */
7773 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7774 /* Additional coprocessor register transfer. */
7775 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7778 /* cps (privileged) */
7782 if (insn
& (1 << 19)) {
7783 if (insn
& (1 << 8))
7785 if (insn
& (1 << 7))
7787 if (insn
& (1 << 6))
7789 if (insn
& (1 << 18))
7792 if (insn
& (1 << 17)) {
7794 val
|= (insn
& 0x1f);
7797 gen_set_psr_im(s
, mask
, 0, val
);
7804 /* if not always execute, we generate a conditional jump to
7806 s
->condlabel
= gen_new_label();
7807 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7810 if ((insn
& 0x0f900000) == 0x03000000) {
7811 if ((insn
& (1 << 21)) == 0) {
7813 rd
= (insn
>> 12) & 0xf;
7814 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7815 if ((insn
& (1 << 22)) == 0) {
7817 tmp
= tcg_temp_new_i32();
7818 tcg_gen_movi_i32(tmp
, val
);
7821 tmp
= load_reg(s
, rd
);
7822 tcg_gen_ext16u_i32(tmp
, tmp
);
7823 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7825 store_reg(s
, rd
, tmp
);
7827 if (((insn
>> 12) & 0xf) != 0xf)
7829 if (((insn
>> 16) & 0xf) == 0) {
7830 gen_nop_hint(s
, insn
& 0xff);
7832 /* CPSR = immediate */
7834 shift
= ((insn
>> 8) & 0xf) * 2;
7836 val
= (val
>> shift
) | (val
<< (32 - shift
));
7837 i
= ((insn
& (1 << 22)) != 0);
7838 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
7844 } else if ((insn
& 0x0f900000) == 0x01000000
7845 && (insn
& 0x00000090) != 0x00000090) {
7846 /* miscellaneous instructions */
7847 op1
= (insn
>> 21) & 3;
7848 sh
= (insn
>> 4) & 0xf;
7851 case 0x0: /* move program status register */
7854 tmp
= load_reg(s
, rm
);
7855 i
= ((op1
& 2) != 0);
7856 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7860 rd
= (insn
>> 12) & 0xf;
7864 tmp
= load_cpu_field(spsr
);
7866 tmp
= tcg_temp_new_i32();
7867 gen_helper_cpsr_read(tmp
, cpu_env
);
7869 store_reg(s
, rd
, tmp
);
7874 /* branch/exchange thumb (bx). */
7876 tmp
= load_reg(s
, rm
);
7878 } else if (op1
== 3) {
7881 rd
= (insn
>> 12) & 0xf;
7882 tmp
= load_reg(s
, rm
);
7883 gen_helper_clz(tmp
, tmp
);
7884 store_reg(s
, rd
, tmp
);
7892 /* Trivial implementation equivalent to bx. */
7893 tmp
= load_reg(s
, rm
);
7904 /* branch link/exchange thumb (blx) */
7905 tmp
= load_reg(s
, rm
);
7906 tmp2
= tcg_temp_new_i32();
7907 tcg_gen_movi_i32(tmp2
, s
->pc
);
7908 store_reg(s
, 14, tmp2
);
7914 uint32_t c
= extract32(insn
, 8, 4);
7916 /* Check this CPU supports ARMv8 CRC instructions.
7917 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7918 * Bits 8, 10 and 11 should be zero.
7920 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7925 rn
= extract32(insn
, 16, 4);
7926 rd
= extract32(insn
, 12, 4);
7928 tmp
= load_reg(s
, rn
);
7929 tmp2
= load_reg(s
, rm
);
7931 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7932 } else if (op1
== 1) {
7933 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7935 tmp3
= tcg_const_i32(1 << op1
);
7937 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7939 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7941 tcg_temp_free_i32(tmp2
);
7942 tcg_temp_free_i32(tmp3
);
7943 store_reg(s
, rd
, tmp
);
7946 case 0x5: /* saturating add/subtract */
7948 rd
= (insn
>> 12) & 0xf;
7949 rn
= (insn
>> 16) & 0xf;
7950 tmp
= load_reg(s
, rm
);
7951 tmp2
= load_reg(s
, rn
);
7953 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7955 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7957 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7958 tcg_temp_free_i32(tmp2
);
7959 store_reg(s
, rd
, tmp
);
7963 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
7968 gen_exception_insn(s
, 4, EXCP_BKPT
,
7969 syn_aa32_bkpt(imm16
, false),
7970 default_exception_el(s
));
7973 /* Hypervisor call (v7) */
7981 /* Secure monitor call (v6+) */
7993 case 0x8: /* signed multiply */
7998 rs
= (insn
>> 8) & 0xf;
7999 rn
= (insn
>> 12) & 0xf;
8000 rd
= (insn
>> 16) & 0xf;
8002 /* (32 * 16) >> 16 */
8003 tmp
= load_reg(s
, rm
);
8004 tmp2
= load_reg(s
, rs
);
8006 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8009 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8010 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8011 tmp
= tcg_temp_new_i32();
8012 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8013 tcg_temp_free_i64(tmp64
);
8014 if ((sh
& 2) == 0) {
8015 tmp2
= load_reg(s
, rn
);
8016 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8017 tcg_temp_free_i32(tmp2
);
8019 store_reg(s
, rd
, tmp
);
8022 tmp
= load_reg(s
, rm
);
8023 tmp2
= load_reg(s
, rs
);
8024 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8025 tcg_temp_free_i32(tmp2
);
8027 tmp64
= tcg_temp_new_i64();
8028 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8029 tcg_temp_free_i32(tmp
);
8030 gen_addq(s
, tmp64
, rn
, rd
);
8031 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8032 tcg_temp_free_i64(tmp64
);
8035 tmp2
= load_reg(s
, rn
);
8036 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8037 tcg_temp_free_i32(tmp2
);
8039 store_reg(s
, rd
, tmp
);
8046 } else if (((insn
& 0x0e000000) == 0 &&
8047 (insn
& 0x00000090) != 0x90) ||
8048 ((insn
& 0x0e000000) == (1 << 25))) {
8049 int set_cc
, logic_cc
, shiftop
;
8051 op1
= (insn
>> 21) & 0xf;
8052 set_cc
= (insn
>> 20) & 1;
8053 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8055 /* data processing instruction */
8056 if (insn
& (1 << 25)) {
8057 /* immediate operand */
8059 shift
= ((insn
>> 8) & 0xf) * 2;
8061 val
= (val
>> shift
) | (val
<< (32 - shift
));
8063 tmp2
= tcg_temp_new_i32();
8064 tcg_gen_movi_i32(tmp2
, val
);
8065 if (logic_cc
&& shift
) {
8066 gen_set_CF_bit31(tmp2
);
8071 tmp2
= load_reg(s
, rm
);
8072 shiftop
= (insn
>> 5) & 3;
8073 if (!(insn
& (1 << 4))) {
8074 shift
= (insn
>> 7) & 0x1f;
8075 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8077 rs
= (insn
>> 8) & 0xf;
8078 tmp
= load_reg(s
, rs
);
8079 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8082 if (op1
!= 0x0f && op1
!= 0x0d) {
8083 rn
= (insn
>> 16) & 0xf;
8084 tmp
= load_reg(s
, rn
);
8086 TCGV_UNUSED_I32(tmp
);
8088 rd
= (insn
>> 12) & 0xf;
8091 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8095 store_reg_bx(s
, rd
, tmp
);
8098 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8102 store_reg_bx(s
, rd
, tmp
);
8105 if (set_cc
&& rd
== 15) {
8106 /* SUBS r15, ... is used for exception return. */
8110 gen_sub_CC(tmp
, tmp
, tmp2
);
8111 gen_exception_return(s
, tmp
);
8114 gen_sub_CC(tmp
, tmp
, tmp2
);
8116 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8118 store_reg_bx(s
, rd
, tmp
);
8123 gen_sub_CC(tmp
, tmp2
, tmp
);
8125 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8127 store_reg_bx(s
, rd
, tmp
);
8131 gen_add_CC(tmp
, tmp
, tmp2
);
8133 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8135 store_reg_bx(s
, rd
, tmp
);
8139 gen_adc_CC(tmp
, tmp
, tmp2
);
8141 gen_add_carry(tmp
, tmp
, tmp2
);
8143 store_reg_bx(s
, rd
, tmp
);
8147 gen_sbc_CC(tmp
, tmp
, tmp2
);
8149 gen_sub_carry(tmp
, tmp
, tmp2
);
8151 store_reg_bx(s
, rd
, tmp
);
8155 gen_sbc_CC(tmp
, tmp2
, tmp
);
8157 gen_sub_carry(tmp
, tmp2
, tmp
);
8159 store_reg_bx(s
, rd
, tmp
);
8163 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8166 tcg_temp_free_i32(tmp
);
8170 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8173 tcg_temp_free_i32(tmp
);
8177 gen_sub_CC(tmp
, tmp
, tmp2
);
8179 tcg_temp_free_i32(tmp
);
8183 gen_add_CC(tmp
, tmp
, tmp2
);
8185 tcg_temp_free_i32(tmp
);
8188 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8192 store_reg_bx(s
, rd
, tmp
);
8195 if (logic_cc
&& rd
== 15) {
8196 /* MOVS r15, ... is used for exception return. */
8200 gen_exception_return(s
, tmp2
);
8205 store_reg_bx(s
, rd
, tmp2
);
8209 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8213 store_reg_bx(s
, rd
, tmp
);
8217 tcg_gen_not_i32(tmp2
, tmp2
);
8221 store_reg_bx(s
, rd
, tmp2
);
8224 if (op1
!= 0x0f && op1
!= 0x0d) {
8225 tcg_temp_free_i32(tmp2
);
8228 /* other instructions */
8229 op1
= (insn
>> 24) & 0xf;
8233 /* multiplies, extra load/stores */
8234 sh
= (insn
>> 5) & 3;
8237 rd
= (insn
>> 16) & 0xf;
8238 rn
= (insn
>> 12) & 0xf;
8239 rs
= (insn
>> 8) & 0xf;
8241 op1
= (insn
>> 20) & 0xf;
8243 case 0: case 1: case 2: case 3: case 6:
8245 tmp
= load_reg(s
, rs
);
8246 tmp2
= load_reg(s
, rm
);
8247 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8248 tcg_temp_free_i32(tmp2
);
8249 if (insn
& (1 << 22)) {
8250 /* Subtract (mls) */
8252 tmp2
= load_reg(s
, rn
);
8253 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8254 tcg_temp_free_i32(tmp2
);
8255 } else if (insn
& (1 << 21)) {
8257 tmp2
= load_reg(s
, rn
);
8258 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8259 tcg_temp_free_i32(tmp2
);
8261 if (insn
& (1 << 20))
8263 store_reg(s
, rd
, tmp
);
8266 /* 64 bit mul double accumulate (UMAAL) */
8268 tmp
= load_reg(s
, rs
);
8269 tmp2
= load_reg(s
, rm
);
8270 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8271 gen_addq_lo(s
, tmp64
, rn
);
8272 gen_addq_lo(s
, tmp64
, rd
);
8273 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8274 tcg_temp_free_i64(tmp64
);
8276 case 8: case 9: case 10: case 11:
8277 case 12: case 13: case 14: case 15:
8278 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8279 tmp
= load_reg(s
, rs
);
8280 tmp2
= load_reg(s
, rm
);
8281 if (insn
& (1 << 22)) {
8282 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8284 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8286 if (insn
& (1 << 21)) { /* mult accumulate */
8287 TCGv_i32 al
= load_reg(s
, rn
);
8288 TCGv_i32 ah
= load_reg(s
, rd
);
8289 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8290 tcg_temp_free_i32(al
);
8291 tcg_temp_free_i32(ah
);
8293 if (insn
& (1 << 20)) {
8294 gen_logicq_cc(tmp
, tmp2
);
8296 store_reg(s
, rn
, tmp
);
8297 store_reg(s
, rd
, tmp2
);
8303 rn
= (insn
>> 16) & 0xf;
8304 rd
= (insn
>> 12) & 0xf;
8305 if (insn
& (1 << 23)) {
8306 /* load/store exclusive */
8307 int op2
= (insn
>> 8) & 3;
8308 op1
= (insn
>> 21) & 0x3;
8311 case 0: /* lda/stl */
8317 case 1: /* reserved */
8319 case 2: /* ldaex/stlex */
8322 case 3: /* ldrex/strex */
8331 addr
= tcg_temp_local_new_i32();
8332 load_reg_var(s
, addr
, rn
);
8334 /* Since the emulation does not have barriers,
8335 the acquire/release semantics need no special
8338 if (insn
& (1 << 20)) {
8339 tmp
= tcg_temp_new_i32();
8342 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8345 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8348 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8353 store_reg(s
, rd
, tmp
);
8356 tmp
= load_reg(s
, rm
);
8359 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8362 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8365 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8370 tcg_temp_free_i32(tmp
);
8372 } else if (insn
& (1 << 20)) {
8375 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8377 case 1: /* ldrexd */
8378 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8380 case 2: /* ldrexb */
8381 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8383 case 3: /* ldrexh */
8384 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8393 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8395 case 1: /* strexd */
8396 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8398 case 2: /* strexb */
8399 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8401 case 3: /* strexh */
8402 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8408 tcg_temp_free_i32(addr
);
8410 /* SWP instruction */
8413 /* ??? This is not really atomic. However we know
8414 we never have multiple CPUs running in parallel,
8415 so it is good enough. */
8416 addr
= load_reg(s
, rn
);
8417 tmp
= load_reg(s
, rm
);
8418 tmp2
= tcg_temp_new_i32();
8419 if (insn
& (1 << 22)) {
8420 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8421 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8423 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8424 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8426 tcg_temp_free_i32(tmp
);
8427 tcg_temp_free_i32(addr
);
8428 store_reg(s
, rd
, tmp2
);
8433 bool load
= insn
& (1 << 20);
8434 bool doubleword
= false;
8435 /* Misc load/store */
8436 rn
= (insn
>> 16) & 0xf;
8437 rd
= (insn
>> 12) & 0xf;
8439 if (!load
&& (sh
& 2)) {
8443 /* UNPREDICTABLE; we choose to UNDEF */
8446 load
= (sh
& 1) == 0;
8450 addr
= load_reg(s
, rn
);
8451 if (insn
& (1 << 24))
8452 gen_add_datah_offset(s
, insn
, 0, addr
);
8458 tmp
= load_reg(s
, rd
);
8459 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8460 tcg_temp_free_i32(tmp
);
8461 tcg_gen_addi_i32(addr
, addr
, 4);
8462 tmp
= load_reg(s
, rd
+ 1);
8463 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8464 tcg_temp_free_i32(tmp
);
8467 tmp
= tcg_temp_new_i32();
8468 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8469 store_reg(s
, rd
, tmp
);
8470 tcg_gen_addi_i32(addr
, addr
, 4);
8471 tmp
= tcg_temp_new_i32();
8472 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8475 address_offset
= -4;
8478 tmp
= tcg_temp_new_i32();
8481 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8484 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8488 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8493 tmp
= load_reg(s
, rd
);
8494 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8495 tcg_temp_free_i32(tmp
);
8497 /* Perform base writeback before the loaded value to
8498 ensure correct behavior with overlapping index registers.
8499 ldrd with base writeback is is undefined if the
8500 destination and index registers overlap. */
8501 if (!(insn
& (1 << 24))) {
8502 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8503 store_reg(s
, rn
, addr
);
8504 } else if (insn
& (1 << 21)) {
8506 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8507 store_reg(s
, rn
, addr
);
8509 tcg_temp_free_i32(addr
);
8512 /* Complete the load. */
8513 store_reg(s
, rd
, tmp
);
8522 if (insn
& (1 << 4)) {
8524 /* Armv6 Media instructions. */
8526 rn
= (insn
>> 16) & 0xf;
8527 rd
= (insn
>> 12) & 0xf;
8528 rs
= (insn
>> 8) & 0xf;
8529 switch ((insn
>> 23) & 3) {
8530 case 0: /* Parallel add/subtract. */
8531 op1
= (insn
>> 20) & 7;
8532 tmp
= load_reg(s
, rn
);
8533 tmp2
= load_reg(s
, rm
);
8534 sh
= (insn
>> 5) & 7;
8535 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8537 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8538 tcg_temp_free_i32(tmp2
);
8539 store_reg(s
, rd
, tmp
);
8542 if ((insn
& 0x00700020) == 0) {
8543 /* Halfword pack. */
8544 tmp
= load_reg(s
, rn
);
8545 tmp2
= load_reg(s
, rm
);
8546 shift
= (insn
>> 7) & 0x1f;
8547 if (insn
& (1 << 6)) {
8551 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8552 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8553 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8557 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8558 tcg_gen_ext16u_i32(tmp
, tmp
);
8559 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8561 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8562 tcg_temp_free_i32(tmp2
);
8563 store_reg(s
, rd
, tmp
);
8564 } else if ((insn
& 0x00200020) == 0x00200000) {
8566 tmp
= load_reg(s
, rm
);
8567 shift
= (insn
>> 7) & 0x1f;
8568 if (insn
& (1 << 6)) {
8571 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8573 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8575 sh
= (insn
>> 16) & 0x1f;
8576 tmp2
= tcg_const_i32(sh
);
8577 if (insn
& (1 << 22))
8578 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8580 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8581 tcg_temp_free_i32(tmp2
);
8582 store_reg(s
, rd
, tmp
);
8583 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8585 tmp
= load_reg(s
, rm
);
8586 sh
= (insn
>> 16) & 0x1f;
8587 tmp2
= tcg_const_i32(sh
);
8588 if (insn
& (1 << 22))
8589 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8591 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8592 tcg_temp_free_i32(tmp2
);
8593 store_reg(s
, rd
, tmp
);
8594 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8596 tmp
= load_reg(s
, rn
);
8597 tmp2
= load_reg(s
, rm
);
8598 tmp3
= tcg_temp_new_i32();
8599 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8600 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8601 tcg_temp_free_i32(tmp3
);
8602 tcg_temp_free_i32(tmp2
);
8603 store_reg(s
, rd
, tmp
);
8604 } else if ((insn
& 0x000003e0) == 0x00000060) {
8605 tmp
= load_reg(s
, rm
);
8606 shift
= (insn
>> 10) & 3;
8607 /* ??? In many cases it's not necessary to do a
8608 rotate, a shift is sufficient. */
8610 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8611 op1
= (insn
>> 20) & 7;
8613 case 0: gen_sxtb16(tmp
); break;
8614 case 2: gen_sxtb(tmp
); break;
8615 case 3: gen_sxth(tmp
); break;
8616 case 4: gen_uxtb16(tmp
); break;
8617 case 6: gen_uxtb(tmp
); break;
8618 case 7: gen_uxth(tmp
); break;
8619 default: goto illegal_op
;
8622 tmp2
= load_reg(s
, rn
);
8623 if ((op1
& 3) == 0) {
8624 gen_add16(tmp
, tmp2
);
8626 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8627 tcg_temp_free_i32(tmp2
);
8630 store_reg(s
, rd
, tmp
);
8631 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8633 tmp
= load_reg(s
, rm
);
8634 if (insn
& (1 << 22)) {
8635 if (insn
& (1 << 7)) {
8639 gen_helper_rbit(tmp
, tmp
);
8642 if (insn
& (1 << 7))
8645 tcg_gen_bswap32_i32(tmp
, tmp
);
8647 store_reg(s
, rd
, tmp
);
8652 case 2: /* Multiplies (Type 3). */
8653 switch ((insn
>> 20) & 0x7) {
8655 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8656 /* op2 not 00x or 11x : UNDEF */
8659 /* Signed multiply most significant [accumulate].
8660 (SMMUL, SMMLA, SMMLS) */
8661 tmp
= load_reg(s
, rm
);
8662 tmp2
= load_reg(s
, rs
);
8663 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8666 tmp
= load_reg(s
, rd
);
8667 if (insn
& (1 << 6)) {
8668 tmp64
= gen_subq_msw(tmp64
, tmp
);
8670 tmp64
= gen_addq_msw(tmp64
, tmp
);
8673 if (insn
& (1 << 5)) {
8674 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8676 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8677 tmp
= tcg_temp_new_i32();
8678 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8679 tcg_temp_free_i64(tmp64
);
8680 store_reg(s
, rn
, tmp
);
8684 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8685 if (insn
& (1 << 7)) {
8688 tmp
= load_reg(s
, rm
);
8689 tmp2
= load_reg(s
, rs
);
8690 if (insn
& (1 << 5))
8691 gen_swap_half(tmp2
);
8692 gen_smul_dual(tmp
, tmp2
);
8693 if (insn
& (1 << 22)) {
8694 /* smlald, smlsld */
8697 tmp64
= tcg_temp_new_i64();
8698 tmp64_2
= tcg_temp_new_i64();
8699 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8700 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8701 tcg_temp_free_i32(tmp
);
8702 tcg_temp_free_i32(tmp2
);
8703 if (insn
& (1 << 6)) {
8704 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8706 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8708 tcg_temp_free_i64(tmp64_2
);
8709 gen_addq(s
, tmp64
, rd
, rn
);
8710 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8711 tcg_temp_free_i64(tmp64
);
8713 /* smuad, smusd, smlad, smlsd */
8714 if (insn
& (1 << 6)) {
8715 /* This subtraction cannot overflow. */
8716 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8718 /* This addition cannot overflow 32 bits;
8719 * however it may overflow considered as a
8720 * signed operation, in which case we must set
8723 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8725 tcg_temp_free_i32(tmp2
);
8728 tmp2
= load_reg(s
, rd
);
8729 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8730 tcg_temp_free_i32(tmp2
);
8732 store_reg(s
, rn
, tmp
);
8738 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
8741 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8744 tmp
= load_reg(s
, rm
);
8745 tmp2
= load_reg(s
, rs
);
8746 if (insn
& (1 << 21)) {
8747 gen_helper_udiv(tmp
, tmp
, tmp2
);
8749 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8751 tcg_temp_free_i32(tmp2
);
8752 store_reg(s
, rn
, tmp
);
8759 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8761 case 0: /* Unsigned sum of absolute differences. */
8763 tmp
= load_reg(s
, rm
);
8764 tmp2
= load_reg(s
, rs
);
8765 gen_helper_usad8(tmp
, tmp
, tmp2
);
8766 tcg_temp_free_i32(tmp2
);
8768 tmp2
= load_reg(s
, rd
);
8769 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8770 tcg_temp_free_i32(tmp2
);
8772 store_reg(s
, rn
, tmp
);
8774 case 0x20: case 0x24: case 0x28: case 0x2c:
8775 /* Bitfield insert/clear. */
8777 shift
= (insn
>> 7) & 0x1f;
8778 i
= (insn
>> 16) & 0x1f;
8780 /* UNPREDICTABLE; we choose to UNDEF */
8785 tmp
= tcg_temp_new_i32();
8786 tcg_gen_movi_i32(tmp
, 0);
8788 tmp
= load_reg(s
, rm
);
8791 tmp2
= load_reg(s
, rd
);
8792 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8793 tcg_temp_free_i32(tmp2
);
8795 store_reg(s
, rd
, tmp
);
8797 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8798 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8800 tmp
= load_reg(s
, rm
);
8801 shift
= (insn
>> 7) & 0x1f;
8802 i
= ((insn
>> 16) & 0x1f) + 1;
8807 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8809 gen_sbfx(tmp
, shift
, i
);
8812 store_reg(s
, rd
, tmp
);
8822 /* Check for undefined extension instructions
8823 * per the ARM Bible IE:
8824 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8826 sh
= (0xf << 20) | (0xf << 4);
8827 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8831 /* load/store byte/word */
8832 rn
= (insn
>> 16) & 0xf;
8833 rd
= (insn
>> 12) & 0xf;
8834 tmp2
= load_reg(s
, rn
);
8835 if ((insn
& 0x01200000) == 0x00200000) {
8837 i
= get_a32_user_mem_index(s
);
8839 i
= get_mem_index(s
);
8841 if (insn
& (1 << 24))
8842 gen_add_data_offset(s
, insn
, tmp2
);
8843 if (insn
& (1 << 20)) {
8845 tmp
= tcg_temp_new_i32();
8846 if (insn
& (1 << 22)) {
8847 gen_aa32_ld8u(tmp
, tmp2
, i
);
8849 gen_aa32_ld32u(tmp
, tmp2
, i
);
8853 tmp
= load_reg(s
, rd
);
8854 if (insn
& (1 << 22)) {
8855 gen_aa32_st8(tmp
, tmp2
, i
);
8857 gen_aa32_st32(tmp
, tmp2
, i
);
8859 tcg_temp_free_i32(tmp
);
8861 if (!(insn
& (1 << 24))) {
8862 gen_add_data_offset(s
, insn
, tmp2
);
8863 store_reg(s
, rn
, tmp2
);
8864 } else if (insn
& (1 << 21)) {
8865 store_reg(s
, rn
, tmp2
);
8867 tcg_temp_free_i32(tmp2
);
8869 if (insn
& (1 << 20)) {
8870 /* Complete the load. */
8871 store_reg_from_load(s
, rd
, tmp
);
8877 int j
, n
, loaded_base
;
8878 bool exc_return
= false;
8879 bool is_load
= extract32(insn
, 20, 1);
8881 TCGv_i32 loaded_var
;
8882 /* load/store multiple words */
8883 /* XXX: store correct base if write back */
8884 if (insn
& (1 << 22)) {
8885 /* LDM (user), LDM (exception return) and STM (user) */
8887 goto illegal_op
; /* only usable in supervisor mode */
8889 if (is_load
&& extract32(insn
, 15, 1)) {
8895 rn
= (insn
>> 16) & 0xf;
8896 addr
= load_reg(s
, rn
);
8898 /* compute total size */
8900 TCGV_UNUSED_I32(loaded_var
);
8903 if (insn
& (1 << i
))
8906 /* XXX: test invalid n == 0 case ? */
8907 if (insn
& (1 << 23)) {
8908 if (insn
& (1 << 24)) {
8910 tcg_gen_addi_i32(addr
, addr
, 4);
8912 /* post increment */
8915 if (insn
& (1 << 24)) {
8917 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8919 /* post decrement */
8921 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8926 if (insn
& (1 << i
)) {
8929 tmp
= tcg_temp_new_i32();
8930 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8932 tmp2
= tcg_const_i32(i
);
8933 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8934 tcg_temp_free_i32(tmp2
);
8935 tcg_temp_free_i32(tmp
);
8936 } else if (i
== rn
) {
8940 store_reg_from_load(s
, i
, tmp
);
8945 /* special case: r15 = PC + 8 */
8946 val
= (long)s
->pc
+ 4;
8947 tmp
= tcg_temp_new_i32();
8948 tcg_gen_movi_i32(tmp
, val
);
8950 tmp
= tcg_temp_new_i32();
8951 tmp2
= tcg_const_i32(i
);
8952 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8953 tcg_temp_free_i32(tmp2
);
8955 tmp
= load_reg(s
, i
);
8957 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8958 tcg_temp_free_i32(tmp
);
8961 /* no need to add after the last transfer */
8963 tcg_gen_addi_i32(addr
, addr
, 4);
8966 if (insn
& (1 << 21)) {
8968 if (insn
& (1 << 23)) {
8969 if (insn
& (1 << 24)) {
8972 /* post increment */
8973 tcg_gen_addi_i32(addr
, addr
, 4);
8976 if (insn
& (1 << 24)) {
8979 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8981 /* post decrement */
8982 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8985 store_reg(s
, rn
, addr
);
8987 tcg_temp_free_i32(addr
);
8990 store_reg(s
, rn
, loaded_var
);
8993 /* Restore CPSR from SPSR. */
8994 tmp
= load_cpu_field(spsr
);
8995 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
8996 tcg_temp_free_i32(tmp
);
8997 s
->is_jmp
= DISAS_UPDATE
;
9006 /* branch (and link) */
9007 val
= (int32_t)s
->pc
;
9008 if (insn
& (1 << 24)) {
9009 tmp
= tcg_temp_new_i32();
9010 tcg_gen_movi_i32(tmp
, val
);
9011 store_reg(s
, 14, tmp
);
9013 offset
= sextract32(insn
<< 2, 0, 26);
9021 if (((insn
>> 8) & 0xe) == 10) {
9023 if (disas_vfp_insn(s
, insn
)) {
9026 } else if (disas_coproc_insn(s
, insn
)) {
9033 gen_set_pc_im(s
, s
->pc
);
9034 s
->svc_imm
= extract32(insn
, 0, 24);
9035 s
->is_jmp
= DISAS_SWI
;
9039 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9040 default_exception_el(s
));
9046 /* Return true if this is a Thumb-2 logical op. */
9048 thumb2_logic_op(int op
)
9053 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9054 then set condition code flags based on the result of the operation.
9055 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9056 to the high bit of T1.
9057 Returns zero if the opcode is valid. */
9060 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9061 TCGv_i32 t0
, TCGv_i32 t1
)
9068 tcg_gen_and_i32(t0
, t0
, t1
);
9072 tcg_gen_andc_i32(t0
, t0
, t1
);
9076 tcg_gen_or_i32(t0
, t0
, t1
);
9080 tcg_gen_orc_i32(t0
, t0
, t1
);
9084 tcg_gen_xor_i32(t0
, t0
, t1
);
9089 gen_add_CC(t0
, t0
, t1
);
9091 tcg_gen_add_i32(t0
, t0
, t1
);
9095 gen_adc_CC(t0
, t0
, t1
);
9101 gen_sbc_CC(t0
, t0
, t1
);
9103 gen_sub_carry(t0
, t0
, t1
);
9108 gen_sub_CC(t0
, t0
, t1
);
9110 tcg_gen_sub_i32(t0
, t0
, t1
);
9114 gen_sub_CC(t0
, t1
, t0
);
9116 tcg_gen_sub_i32(t0
, t1
, t0
);
9118 default: /* 5, 6, 7, 9, 12, 15. */
9124 gen_set_CF_bit31(t1
);
9129 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9131 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9133 uint32_t insn
, imm
, shift
, offset
;
9134 uint32_t rd
, rn
, rm
, rs
;
9145 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9146 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9147 /* Thumb-1 cores may need to treat bl and blx as a pair of
9148 16-bit instructions to get correct prefetch abort behavior. */
9150 if ((insn
& (1 << 12)) == 0) {
9152 /* Second half of blx. */
9153 offset
= ((insn
& 0x7ff) << 1);
9154 tmp
= load_reg(s
, 14);
9155 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9156 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9158 tmp2
= tcg_temp_new_i32();
9159 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9160 store_reg(s
, 14, tmp2
);
9164 if (insn
& (1 << 11)) {
9165 /* Second half of bl. */
9166 offset
= ((insn
& 0x7ff) << 1) | 1;
9167 tmp
= load_reg(s
, 14);
9168 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9170 tmp2
= tcg_temp_new_i32();
9171 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9172 store_reg(s
, 14, tmp2
);
9176 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9177 /* Instruction spans a page boundary. Implement it as two
9178 16-bit instructions in case the second half causes an
9180 offset
= ((int32_t)insn
<< 21) >> 9;
9181 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9184 /* Fall through to 32-bit decode. */
9187 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9189 insn
|= (uint32_t)insn_hw1
<< 16;
9191 if ((insn
& 0xf800e800) != 0xf000e800) {
9195 rn
= (insn
>> 16) & 0xf;
9196 rs
= (insn
>> 12) & 0xf;
9197 rd
= (insn
>> 8) & 0xf;
9199 switch ((insn
>> 25) & 0xf) {
9200 case 0: case 1: case 2: case 3:
9201 /* 16-bit instructions. Should never happen. */
9204 if (insn
& (1 << 22)) {
9205 /* Other load/store, table branch. */
9206 if (insn
& 0x01200000) {
9207 /* Load/store doubleword. */
9209 addr
= tcg_temp_new_i32();
9210 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9212 addr
= load_reg(s
, rn
);
9214 offset
= (insn
& 0xff) * 4;
9215 if ((insn
& (1 << 23)) == 0)
9217 if (insn
& (1 << 24)) {
9218 tcg_gen_addi_i32(addr
, addr
, offset
);
9221 if (insn
& (1 << 20)) {
9223 tmp
= tcg_temp_new_i32();
9224 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9225 store_reg(s
, rs
, tmp
);
9226 tcg_gen_addi_i32(addr
, addr
, 4);
9227 tmp
= tcg_temp_new_i32();
9228 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9229 store_reg(s
, rd
, tmp
);
9232 tmp
= load_reg(s
, rs
);
9233 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9234 tcg_temp_free_i32(tmp
);
9235 tcg_gen_addi_i32(addr
, addr
, 4);
9236 tmp
= load_reg(s
, rd
);
9237 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9238 tcg_temp_free_i32(tmp
);
9240 if (insn
& (1 << 21)) {
9241 /* Base writeback. */
9244 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9245 store_reg(s
, rn
, addr
);
9247 tcg_temp_free_i32(addr
);
9249 } else if ((insn
& (1 << 23)) == 0) {
9250 /* Load/store exclusive word. */
9251 addr
= tcg_temp_local_new_i32();
9252 load_reg_var(s
, addr
, rn
);
9253 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9254 if (insn
& (1 << 20)) {
9255 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9257 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9259 tcg_temp_free_i32(addr
);
9260 } else if ((insn
& (7 << 5)) == 0) {
9263 addr
= tcg_temp_new_i32();
9264 tcg_gen_movi_i32(addr
, s
->pc
);
9266 addr
= load_reg(s
, rn
);
9268 tmp
= load_reg(s
, rm
);
9269 tcg_gen_add_i32(addr
, addr
, tmp
);
9270 if (insn
& (1 << 4)) {
9272 tcg_gen_add_i32(addr
, addr
, tmp
);
9273 tcg_temp_free_i32(tmp
);
9274 tmp
= tcg_temp_new_i32();
9275 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9277 tcg_temp_free_i32(tmp
);
9278 tmp
= tcg_temp_new_i32();
9279 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9281 tcg_temp_free_i32(addr
);
9282 tcg_gen_shli_i32(tmp
, tmp
, 1);
9283 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9284 store_reg(s
, 15, tmp
);
9286 int op2
= (insn
>> 6) & 0x3;
9287 op
= (insn
>> 4) & 0x3;
9292 /* Load/store exclusive byte/halfword/doubleword */
9299 /* Load-acquire/store-release */
9305 /* Load-acquire/store-release exclusive */
9309 addr
= tcg_temp_local_new_i32();
9310 load_reg_var(s
, addr
, rn
);
9312 if (insn
& (1 << 20)) {
9313 tmp
= tcg_temp_new_i32();
9316 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9319 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9322 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9327 store_reg(s
, rs
, tmp
);
9329 tmp
= load_reg(s
, rs
);
9332 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9335 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9338 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9343 tcg_temp_free_i32(tmp
);
9345 } else if (insn
& (1 << 20)) {
9346 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9348 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9350 tcg_temp_free_i32(addr
);
9353 /* Load/store multiple, RFE, SRS. */
9354 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9355 /* RFE, SRS: not available in user mode or on M profile */
9356 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9359 if (insn
& (1 << 20)) {
9361 addr
= load_reg(s
, rn
);
9362 if ((insn
& (1 << 24)) == 0)
9363 tcg_gen_addi_i32(addr
, addr
, -8);
9364 /* Load PC into tmp and CPSR into tmp2. */
9365 tmp
= tcg_temp_new_i32();
9366 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9367 tcg_gen_addi_i32(addr
, addr
, 4);
9368 tmp2
= tcg_temp_new_i32();
9369 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9370 if (insn
& (1 << 21)) {
9371 /* Base writeback. */
9372 if (insn
& (1 << 24)) {
9373 tcg_gen_addi_i32(addr
, addr
, 4);
9375 tcg_gen_addi_i32(addr
, addr
, -4);
9377 store_reg(s
, rn
, addr
);
9379 tcg_temp_free_i32(addr
);
9381 gen_rfe(s
, tmp
, tmp2
);
9384 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9388 int i
, loaded_base
= 0;
9389 TCGv_i32 loaded_var
;
9390 /* Load/store multiple. */
9391 addr
= load_reg(s
, rn
);
9393 for (i
= 0; i
< 16; i
++) {
9394 if (insn
& (1 << i
))
9397 if (insn
& (1 << 24)) {
9398 tcg_gen_addi_i32(addr
, addr
, -offset
);
9401 TCGV_UNUSED_I32(loaded_var
);
9402 for (i
= 0; i
< 16; i
++) {
9403 if ((insn
& (1 << i
)) == 0)
9405 if (insn
& (1 << 20)) {
9407 tmp
= tcg_temp_new_i32();
9408 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9411 } else if (i
== rn
) {
9415 store_reg(s
, i
, tmp
);
9419 tmp
= load_reg(s
, i
);
9420 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9421 tcg_temp_free_i32(tmp
);
9423 tcg_gen_addi_i32(addr
, addr
, 4);
9426 store_reg(s
, rn
, loaded_var
);
9428 if (insn
& (1 << 21)) {
9429 /* Base register writeback. */
9430 if (insn
& (1 << 24)) {
9431 tcg_gen_addi_i32(addr
, addr
, -offset
);
9433 /* Fault if writeback register is in register list. */
9434 if (insn
& (1 << rn
))
9436 store_reg(s
, rn
, addr
);
9438 tcg_temp_free_i32(addr
);
9445 op
= (insn
>> 21) & 0xf;
9447 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9450 /* Halfword pack. */
9451 tmp
= load_reg(s
, rn
);
9452 tmp2
= load_reg(s
, rm
);
9453 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9454 if (insn
& (1 << 5)) {
9458 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9459 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9460 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9464 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9465 tcg_gen_ext16u_i32(tmp
, tmp
);
9466 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9468 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9469 tcg_temp_free_i32(tmp2
);
9470 store_reg(s
, rd
, tmp
);
9472 /* Data processing register constant shift. */
9474 tmp
= tcg_temp_new_i32();
9475 tcg_gen_movi_i32(tmp
, 0);
9477 tmp
= load_reg(s
, rn
);
9479 tmp2
= load_reg(s
, rm
);
9481 shiftop
= (insn
>> 4) & 3;
9482 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9483 conds
= (insn
& (1 << 20)) != 0;
9484 logic_cc
= (conds
&& thumb2_logic_op(op
));
9485 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9486 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9488 tcg_temp_free_i32(tmp2
);
9490 store_reg(s
, rd
, tmp
);
9492 tcg_temp_free_i32(tmp
);
9496 case 13: /* Misc data processing. */
9497 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9498 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9501 case 0: /* Register controlled shift. */
9502 tmp
= load_reg(s
, rn
);
9503 tmp2
= load_reg(s
, rm
);
9504 if ((insn
& 0x70) != 0)
9506 op
= (insn
>> 21) & 3;
9507 logic_cc
= (insn
& (1 << 20)) != 0;
9508 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9511 store_reg_bx(s
, rd
, tmp
);
9513 case 1: /* Sign/zero extend. */
9514 op
= (insn
>> 20) & 7;
9516 case 0: /* SXTAH, SXTH */
9517 case 1: /* UXTAH, UXTH */
9518 case 4: /* SXTAB, SXTB */
9519 case 5: /* UXTAB, UXTB */
9521 case 2: /* SXTAB16, SXTB16 */
9522 case 3: /* UXTAB16, UXTB16 */
9523 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9531 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9535 tmp
= load_reg(s
, rm
);
9536 shift
= (insn
>> 4) & 3;
9537 /* ??? In many cases it's not necessary to do a
9538 rotate, a shift is sufficient. */
9540 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9541 op
= (insn
>> 20) & 7;
9543 case 0: gen_sxth(tmp
); break;
9544 case 1: gen_uxth(tmp
); break;
9545 case 2: gen_sxtb16(tmp
); break;
9546 case 3: gen_uxtb16(tmp
); break;
9547 case 4: gen_sxtb(tmp
); break;
9548 case 5: gen_uxtb(tmp
); break;
9550 g_assert_not_reached();
9553 tmp2
= load_reg(s
, rn
);
9554 if ((op
>> 1) == 1) {
9555 gen_add16(tmp
, tmp2
);
9557 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9558 tcg_temp_free_i32(tmp2
);
9561 store_reg(s
, rd
, tmp
);
9563 case 2: /* SIMD add/subtract. */
9564 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9567 op
= (insn
>> 20) & 7;
9568 shift
= (insn
>> 4) & 7;
9569 if ((op
& 3) == 3 || (shift
& 3) == 3)
9571 tmp
= load_reg(s
, rn
);
9572 tmp2
= load_reg(s
, rm
);
9573 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9574 tcg_temp_free_i32(tmp2
);
9575 store_reg(s
, rd
, tmp
);
9577 case 3: /* Other data processing. */
9578 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9580 /* Saturating add/subtract. */
9581 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9584 tmp
= load_reg(s
, rn
);
9585 tmp2
= load_reg(s
, rm
);
9587 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9589 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9591 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9592 tcg_temp_free_i32(tmp2
);
9595 case 0x0a: /* rbit */
9596 case 0x08: /* rev */
9597 case 0x09: /* rev16 */
9598 case 0x0b: /* revsh */
9599 case 0x18: /* clz */
9601 case 0x10: /* sel */
9602 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9606 case 0x20: /* crc32/crc32c */
9612 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
9619 tmp
= load_reg(s
, rn
);
9621 case 0x0a: /* rbit */
9622 gen_helper_rbit(tmp
, tmp
);
9624 case 0x08: /* rev */
9625 tcg_gen_bswap32_i32(tmp
, tmp
);
9627 case 0x09: /* rev16 */
9630 case 0x0b: /* revsh */
9633 case 0x10: /* sel */
9634 tmp2
= load_reg(s
, rm
);
9635 tmp3
= tcg_temp_new_i32();
9636 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9637 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9638 tcg_temp_free_i32(tmp3
);
9639 tcg_temp_free_i32(tmp2
);
9641 case 0x18: /* clz */
9642 gen_helper_clz(tmp
, tmp
);
9652 uint32_t sz
= op
& 0x3;
9653 uint32_t c
= op
& 0x8;
9655 tmp2
= load_reg(s
, rm
);
9657 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9658 } else if (sz
== 1) {
9659 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9661 tmp3
= tcg_const_i32(1 << sz
);
9663 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9665 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9667 tcg_temp_free_i32(tmp2
);
9668 tcg_temp_free_i32(tmp3
);
9672 g_assert_not_reached();
9675 store_reg(s
, rd
, tmp
);
9677 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9678 switch ((insn
>> 20) & 7) {
9679 case 0: /* 32 x 32 -> 32 */
9680 case 7: /* Unsigned sum of absolute differences. */
9682 case 1: /* 16 x 16 -> 32 */
9683 case 2: /* Dual multiply add. */
9684 case 3: /* 32 * 16 -> 32msb */
9685 case 4: /* Dual multiply subtract. */
9686 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9687 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9692 op
= (insn
>> 4) & 0xf;
9693 tmp
= load_reg(s
, rn
);
9694 tmp2
= load_reg(s
, rm
);
9695 switch ((insn
>> 20) & 7) {
9696 case 0: /* 32 x 32 -> 32 */
9697 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9698 tcg_temp_free_i32(tmp2
);
9700 tmp2
= load_reg(s
, rs
);
9702 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9704 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9705 tcg_temp_free_i32(tmp2
);
9708 case 1: /* 16 x 16 -> 32 */
9709 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9710 tcg_temp_free_i32(tmp2
);
9712 tmp2
= load_reg(s
, rs
);
9713 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9714 tcg_temp_free_i32(tmp2
);
9717 case 2: /* Dual multiply add. */
9718 case 4: /* Dual multiply subtract. */
9720 gen_swap_half(tmp2
);
9721 gen_smul_dual(tmp
, tmp2
);
9722 if (insn
& (1 << 22)) {
9723 /* This subtraction cannot overflow. */
9724 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9726 /* This addition cannot overflow 32 bits;
9727 * however it may overflow considered as a signed
9728 * operation, in which case we must set the Q flag.
9730 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9732 tcg_temp_free_i32(tmp2
);
9735 tmp2
= load_reg(s
, rs
);
9736 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9737 tcg_temp_free_i32(tmp2
);
9740 case 3: /* 32 * 16 -> 32msb */
9742 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9745 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9746 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9747 tmp
= tcg_temp_new_i32();
9748 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9749 tcg_temp_free_i64(tmp64
);
9752 tmp2
= load_reg(s
, rs
);
9753 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9754 tcg_temp_free_i32(tmp2
);
9757 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9758 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9760 tmp
= load_reg(s
, rs
);
9761 if (insn
& (1 << 20)) {
9762 tmp64
= gen_addq_msw(tmp64
, tmp
);
9764 tmp64
= gen_subq_msw(tmp64
, tmp
);
9767 if (insn
& (1 << 4)) {
9768 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9770 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9771 tmp
= tcg_temp_new_i32();
9772 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9773 tcg_temp_free_i64(tmp64
);
9775 case 7: /* Unsigned sum of absolute differences. */
9776 gen_helper_usad8(tmp
, tmp
, tmp2
);
9777 tcg_temp_free_i32(tmp2
);
9779 tmp2
= load_reg(s
, rs
);
9780 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9781 tcg_temp_free_i32(tmp2
);
9785 store_reg(s
, rd
, tmp
);
9787 case 6: case 7: /* 64-bit multiply, Divide. */
9788 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9789 tmp
= load_reg(s
, rn
);
9790 tmp2
= load_reg(s
, rm
);
9791 if ((op
& 0x50) == 0x10) {
9793 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
9797 gen_helper_udiv(tmp
, tmp
, tmp2
);
9799 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9800 tcg_temp_free_i32(tmp2
);
9801 store_reg(s
, rd
, tmp
);
9802 } else if ((op
& 0xe) == 0xc) {
9803 /* Dual multiply accumulate long. */
9804 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9805 tcg_temp_free_i32(tmp
);
9806 tcg_temp_free_i32(tmp2
);
9810 gen_swap_half(tmp2
);
9811 gen_smul_dual(tmp
, tmp2
);
9813 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9815 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9817 tcg_temp_free_i32(tmp2
);
9819 tmp64
= tcg_temp_new_i64();
9820 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9821 tcg_temp_free_i32(tmp
);
9822 gen_addq(s
, tmp64
, rs
, rd
);
9823 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9824 tcg_temp_free_i64(tmp64
);
9827 /* Unsigned 64-bit multiply */
9828 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9832 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9833 tcg_temp_free_i32(tmp2
);
9834 tcg_temp_free_i32(tmp
);
9837 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9838 tcg_temp_free_i32(tmp2
);
9839 tmp64
= tcg_temp_new_i64();
9840 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9841 tcg_temp_free_i32(tmp
);
9843 /* Signed 64-bit multiply */
9844 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9849 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9850 tcg_temp_free_i64(tmp64
);
9853 gen_addq_lo(s
, tmp64
, rs
);
9854 gen_addq_lo(s
, tmp64
, rd
);
9855 } else if (op
& 0x40) {
9856 /* 64-bit accumulate. */
9857 gen_addq(s
, tmp64
, rs
, rd
);
9859 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9860 tcg_temp_free_i64(tmp64
);
9865 case 6: case 7: case 14: case 15:
9867 if (((insn
>> 24) & 3) == 3) {
9868 /* Translate into the equivalent ARM encoding. */
9869 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9870 if (disas_neon_data_insn(s
, insn
)) {
9873 } else if (((insn
>> 8) & 0xe) == 10) {
9874 if (disas_vfp_insn(s
, insn
)) {
9878 if (insn
& (1 << 28))
9880 if (disas_coproc_insn(s
, insn
)) {
9885 case 8: case 9: case 10: case 11:
9886 if (insn
& (1 << 15)) {
9887 /* Branches, misc control. */
9888 if (insn
& 0x5000) {
9889 /* Unconditional branch. */
9890 /* signextend(hw1[10:0]) -> offset[:12]. */
9891 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9892 /* hw1[10:0] -> offset[11:1]. */
9893 offset
|= (insn
& 0x7ff) << 1;
9894 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9895 offset[24:22] already have the same value because of the
9896 sign extension above. */
9897 offset
^= ((~insn
) & (1 << 13)) << 10;
9898 offset
^= ((~insn
) & (1 << 11)) << 11;
9900 if (insn
& (1 << 14)) {
9901 /* Branch and link. */
9902 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9906 if (insn
& (1 << 12)) {
9911 offset
&= ~(uint32_t)2;
9912 /* thumb2 bx, no need to check */
9913 gen_bx_im(s
, offset
);
9915 } else if (((insn
>> 23) & 7) == 7) {
9917 if (insn
& (1 << 13))
9920 if (insn
& (1 << 26)) {
9921 if (!(insn
& (1 << 20))) {
9922 /* Hypervisor call (v7) */
9923 int imm16
= extract32(insn
, 16, 4) << 12
9924 | extract32(insn
, 0, 12);
9931 /* Secure monitor call (v6+) */
9939 op
= (insn
>> 20) & 7;
9941 case 0: /* msr cpsr. */
9942 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9943 tmp
= load_reg(s
, rn
);
9944 addr
= tcg_const_i32(insn
& 0xff);
9945 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9946 tcg_temp_free_i32(addr
);
9947 tcg_temp_free_i32(tmp
);
9952 case 1: /* msr spsr. */
9953 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9956 tmp
= load_reg(s
, rn
);
9958 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
9962 case 2: /* cps, nop-hint. */
9963 if (((insn
>> 8) & 7) == 0) {
9964 gen_nop_hint(s
, insn
& 0xff);
9966 /* Implemented as NOP in user mode. */
9971 if (insn
& (1 << 10)) {
9972 if (insn
& (1 << 7))
9974 if (insn
& (1 << 6))
9976 if (insn
& (1 << 5))
9978 if (insn
& (1 << 9))
9979 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9981 if (insn
& (1 << 8)) {
9983 imm
|= (insn
& 0x1f);
9986 gen_set_psr_im(s
, offset
, 0, imm
);
9989 case 3: /* Special control operations. */
9991 op
= (insn
>> 4) & 0xf;
9999 /* These execute as NOPs. */
10006 /* Trivial implementation equivalent to bx. */
10007 tmp
= load_reg(s
, rn
);
10010 case 5: /* Exception return. */
10014 if (rn
!= 14 || rd
!= 15) {
10017 tmp
= load_reg(s
, rn
);
10018 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10019 gen_exception_return(s
, tmp
);
10021 case 6: /* mrs cpsr. */
10022 tmp
= tcg_temp_new_i32();
10023 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10024 addr
= tcg_const_i32(insn
& 0xff);
10025 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10026 tcg_temp_free_i32(addr
);
10028 gen_helper_cpsr_read(tmp
, cpu_env
);
10030 store_reg(s
, rd
, tmp
);
10032 case 7: /* mrs spsr. */
10033 /* Not accessible in user mode. */
10034 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10037 tmp
= load_cpu_field(spsr
);
10038 store_reg(s
, rd
, tmp
);
10043 /* Conditional branch. */
10044 op
= (insn
>> 22) & 0xf;
10045 /* Generate a conditional jump to next instruction. */
10046 s
->condlabel
= gen_new_label();
10047 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10050 /* offset[11:1] = insn[10:0] */
10051 offset
= (insn
& 0x7ff) << 1;
10052 /* offset[17:12] = insn[21:16]. */
10053 offset
|= (insn
& 0x003f0000) >> 4;
10054 /* offset[31:20] = insn[26]. */
10055 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10056 /* offset[18] = insn[13]. */
10057 offset
|= (insn
& (1 << 13)) << 5;
10058 /* offset[19] = insn[11]. */
10059 offset
|= (insn
& (1 << 11)) << 8;
10061 /* jump to the offset */
10062 gen_jmp(s
, s
->pc
+ offset
);
10065 /* Data processing immediate. */
10066 if (insn
& (1 << 25)) {
10067 if (insn
& (1 << 24)) {
10068 if (insn
& (1 << 20))
10070 /* Bitfield/Saturate. */
10071 op
= (insn
>> 21) & 7;
10073 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10075 tmp
= tcg_temp_new_i32();
10076 tcg_gen_movi_i32(tmp
, 0);
10078 tmp
= load_reg(s
, rn
);
10081 case 2: /* Signed bitfield extract. */
10083 if (shift
+ imm
> 32)
10086 gen_sbfx(tmp
, shift
, imm
);
10088 case 6: /* Unsigned bitfield extract. */
10090 if (shift
+ imm
> 32)
10093 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
10095 case 3: /* Bitfield insert/clear. */
10098 imm
= imm
+ 1 - shift
;
10100 tmp2
= load_reg(s
, rd
);
10101 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10102 tcg_temp_free_i32(tmp2
);
10107 default: /* Saturate. */
10110 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10112 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10114 tmp2
= tcg_const_i32(imm
);
10117 if ((op
& 1) && shift
== 0) {
10118 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10119 tcg_temp_free_i32(tmp
);
10120 tcg_temp_free_i32(tmp2
);
10123 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10125 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10129 if ((op
& 1) && shift
== 0) {
10130 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10131 tcg_temp_free_i32(tmp
);
10132 tcg_temp_free_i32(tmp2
);
10135 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10137 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10140 tcg_temp_free_i32(tmp2
);
10143 store_reg(s
, rd
, tmp
);
10145 imm
= ((insn
& 0x04000000) >> 15)
10146 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10147 if (insn
& (1 << 22)) {
10148 /* 16-bit immediate. */
10149 imm
|= (insn
>> 4) & 0xf000;
10150 if (insn
& (1 << 23)) {
10152 tmp
= load_reg(s
, rd
);
10153 tcg_gen_ext16u_i32(tmp
, tmp
);
10154 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10157 tmp
= tcg_temp_new_i32();
10158 tcg_gen_movi_i32(tmp
, imm
);
10161 /* Add/sub 12-bit immediate. */
10163 offset
= s
->pc
& ~(uint32_t)3;
10164 if (insn
& (1 << 23))
10168 tmp
= tcg_temp_new_i32();
10169 tcg_gen_movi_i32(tmp
, offset
);
10171 tmp
= load_reg(s
, rn
);
10172 if (insn
& (1 << 23))
10173 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10175 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10178 store_reg(s
, rd
, tmp
);
10181 int shifter_out
= 0;
10182 /* modified 12-bit immediate. */
10183 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10184 imm
= (insn
& 0xff);
10187 /* Nothing to do. */
10189 case 1: /* 00XY00XY */
10192 case 2: /* XY00XY00 */
10196 case 3: /* XYXYXYXY */
10200 default: /* Rotated constant. */
10201 shift
= (shift
<< 1) | (imm
>> 7);
10203 imm
= imm
<< (32 - shift
);
10207 tmp2
= tcg_temp_new_i32();
10208 tcg_gen_movi_i32(tmp2
, imm
);
10209 rn
= (insn
>> 16) & 0xf;
10211 tmp
= tcg_temp_new_i32();
10212 tcg_gen_movi_i32(tmp
, 0);
10214 tmp
= load_reg(s
, rn
);
10216 op
= (insn
>> 21) & 0xf;
10217 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10218 shifter_out
, tmp
, tmp2
))
10220 tcg_temp_free_i32(tmp2
);
10221 rd
= (insn
>> 8) & 0xf;
10223 store_reg(s
, rd
, tmp
);
10225 tcg_temp_free_i32(tmp
);
10230 case 12: /* Load/store single data item. */
10235 if ((insn
& 0x01100000) == 0x01000000) {
10236 if (disas_neon_ls_insn(s
, insn
)) {
10241 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10243 if (!(insn
& (1 << 20))) {
10247 /* Byte or halfword load space with dest == r15 : memory hints.
10248 * Catch them early so we don't emit pointless addressing code.
10249 * This space is a mix of:
10250 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10251 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10253 * unallocated hints, which must be treated as NOPs
10254 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10255 * which is easiest for the decoding logic
10256 * Some space which must UNDEF
10258 int op1
= (insn
>> 23) & 3;
10259 int op2
= (insn
>> 6) & 0x3f;
10264 /* UNPREDICTABLE, unallocated hint or
10265 * PLD/PLDW/PLI (literal)
10270 return 0; /* PLD/PLDW/PLI or unallocated hint */
10272 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10273 return 0; /* PLD/PLDW/PLI or unallocated hint */
10275 /* UNDEF space, or an UNPREDICTABLE */
10279 memidx
= get_mem_index(s
);
10281 addr
= tcg_temp_new_i32();
10283 /* s->pc has already been incremented by 4. */
10284 imm
= s
->pc
& 0xfffffffc;
10285 if (insn
& (1 << 23))
10286 imm
+= insn
& 0xfff;
10288 imm
-= insn
& 0xfff;
10289 tcg_gen_movi_i32(addr
, imm
);
10291 addr
= load_reg(s
, rn
);
10292 if (insn
& (1 << 23)) {
10293 /* Positive offset. */
10294 imm
= insn
& 0xfff;
10295 tcg_gen_addi_i32(addr
, addr
, imm
);
10298 switch ((insn
>> 8) & 0xf) {
10299 case 0x0: /* Shifted Register. */
10300 shift
= (insn
>> 4) & 0xf;
10302 tcg_temp_free_i32(addr
);
10305 tmp
= load_reg(s
, rm
);
10307 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10308 tcg_gen_add_i32(addr
, addr
, tmp
);
10309 tcg_temp_free_i32(tmp
);
10311 case 0xc: /* Negative offset. */
10312 tcg_gen_addi_i32(addr
, addr
, -imm
);
10314 case 0xe: /* User privilege. */
10315 tcg_gen_addi_i32(addr
, addr
, imm
);
10316 memidx
= get_a32_user_mem_index(s
);
10318 case 0x9: /* Post-decrement. */
10320 /* Fall through. */
10321 case 0xb: /* Post-increment. */
10325 case 0xd: /* Pre-decrement. */
10327 /* Fall through. */
10328 case 0xf: /* Pre-increment. */
10329 tcg_gen_addi_i32(addr
, addr
, imm
);
10333 tcg_temp_free_i32(addr
);
10338 if (insn
& (1 << 20)) {
10340 tmp
= tcg_temp_new_i32();
10343 gen_aa32_ld8u(tmp
, addr
, memidx
);
10346 gen_aa32_ld8s(tmp
, addr
, memidx
);
10349 gen_aa32_ld16u(tmp
, addr
, memidx
);
10352 gen_aa32_ld16s(tmp
, addr
, memidx
);
10355 gen_aa32_ld32u(tmp
, addr
, memidx
);
10358 tcg_temp_free_i32(tmp
);
10359 tcg_temp_free_i32(addr
);
10365 store_reg(s
, rs
, tmp
);
10369 tmp
= load_reg(s
, rs
);
10372 gen_aa32_st8(tmp
, addr
, memidx
);
10375 gen_aa32_st16(tmp
, addr
, memidx
);
10378 gen_aa32_st32(tmp
, addr
, memidx
);
10381 tcg_temp_free_i32(tmp
);
10382 tcg_temp_free_i32(addr
);
10385 tcg_temp_free_i32(tmp
);
10388 tcg_gen_addi_i32(addr
, addr
, imm
);
10390 store_reg(s
, rn
, addr
);
10392 tcg_temp_free_i32(addr
);
10404 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10406 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10413 if (s
->condexec_mask
) {
10414 cond
= s
->condexec_cond
;
10415 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10416 s
->condlabel
= gen_new_label();
10417 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10422 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10425 switch (insn
>> 12) {
10429 op
= (insn
>> 11) & 3;
10432 rn
= (insn
>> 3) & 7;
10433 tmp
= load_reg(s
, rn
);
10434 if (insn
& (1 << 10)) {
10436 tmp2
= tcg_temp_new_i32();
10437 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10440 rm
= (insn
>> 6) & 7;
10441 tmp2
= load_reg(s
, rm
);
10443 if (insn
& (1 << 9)) {
10444 if (s
->condexec_mask
)
10445 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10447 gen_sub_CC(tmp
, tmp
, tmp2
);
10449 if (s
->condexec_mask
)
10450 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10452 gen_add_CC(tmp
, tmp
, tmp2
);
10454 tcg_temp_free_i32(tmp2
);
10455 store_reg(s
, rd
, tmp
);
10457 /* shift immediate */
10458 rm
= (insn
>> 3) & 7;
10459 shift
= (insn
>> 6) & 0x1f;
10460 tmp
= load_reg(s
, rm
);
10461 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10462 if (!s
->condexec_mask
)
10464 store_reg(s
, rd
, tmp
);
10468 /* arithmetic large immediate */
10469 op
= (insn
>> 11) & 3;
10470 rd
= (insn
>> 8) & 0x7;
10471 if (op
== 0) { /* mov */
10472 tmp
= tcg_temp_new_i32();
10473 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10474 if (!s
->condexec_mask
)
10476 store_reg(s
, rd
, tmp
);
10478 tmp
= load_reg(s
, rd
);
10479 tmp2
= tcg_temp_new_i32();
10480 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10483 gen_sub_CC(tmp
, tmp
, tmp2
);
10484 tcg_temp_free_i32(tmp
);
10485 tcg_temp_free_i32(tmp2
);
10488 if (s
->condexec_mask
)
10489 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10491 gen_add_CC(tmp
, tmp
, tmp2
);
10492 tcg_temp_free_i32(tmp2
);
10493 store_reg(s
, rd
, tmp
);
10496 if (s
->condexec_mask
)
10497 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10499 gen_sub_CC(tmp
, tmp
, tmp2
);
10500 tcg_temp_free_i32(tmp2
);
10501 store_reg(s
, rd
, tmp
);
10507 if (insn
& (1 << 11)) {
10508 rd
= (insn
>> 8) & 7;
10509 /* load pc-relative. Bit 1 of PC is ignored. */
10510 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10511 val
&= ~(uint32_t)2;
10512 addr
= tcg_temp_new_i32();
10513 tcg_gen_movi_i32(addr
, val
);
10514 tmp
= tcg_temp_new_i32();
10515 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10516 tcg_temp_free_i32(addr
);
10517 store_reg(s
, rd
, tmp
);
10520 if (insn
& (1 << 10)) {
10521 /* data processing extended or blx */
10522 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10523 rm
= (insn
>> 3) & 0xf;
10524 op
= (insn
>> 8) & 3;
10527 tmp
= load_reg(s
, rd
);
10528 tmp2
= load_reg(s
, rm
);
10529 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10530 tcg_temp_free_i32(tmp2
);
10531 store_reg(s
, rd
, tmp
);
10534 tmp
= load_reg(s
, rd
);
10535 tmp2
= load_reg(s
, rm
);
10536 gen_sub_CC(tmp
, tmp
, tmp2
);
10537 tcg_temp_free_i32(tmp2
);
10538 tcg_temp_free_i32(tmp
);
10540 case 2: /* mov/cpy */
10541 tmp
= load_reg(s
, rm
);
10542 store_reg(s
, rd
, tmp
);
10544 case 3:/* branch [and link] exchange thumb register */
10545 tmp
= load_reg(s
, rm
);
10546 if (insn
& (1 << 7)) {
10548 val
= (uint32_t)s
->pc
| 1;
10549 tmp2
= tcg_temp_new_i32();
10550 tcg_gen_movi_i32(tmp2
, val
);
10551 store_reg(s
, 14, tmp2
);
10553 /* already thumb, no need to check */
10560 /* data processing register */
10562 rm
= (insn
>> 3) & 7;
10563 op
= (insn
>> 6) & 0xf;
10564 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10565 /* the shift/rotate ops want the operands backwards */
10574 if (op
== 9) { /* neg */
10575 tmp
= tcg_temp_new_i32();
10576 tcg_gen_movi_i32(tmp
, 0);
10577 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10578 tmp
= load_reg(s
, rd
);
10580 TCGV_UNUSED_I32(tmp
);
10583 tmp2
= load_reg(s
, rm
);
10585 case 0x0: /* and */
10586 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10587 if (!s
->condexec_mask
)
10590 case 0x1: /* eor */
10591 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10592 if (!s
->condexec_mask
)
10595 case 0x2: /* lsl */
10596 if (s
->condexec_mask
) {
10597 gen_shl(tmp2
, tmp2
, tmp
);
10599 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10600 gen_logic_CC(tmp2
);
10603 case 0x3: /* lsr */
10604 if (s
->condexec_mask
) {
10605 gen_shr(tmp2
, tmp2
, tmp
);
10607 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10608 gen_logic_CC(tmp2
);
10611 case 0x4: /* asr */
10612 if (s
->condexec_mask
) {
10613 gen_sar(tmp2
, tmp2
, tmp
);
10615 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10616 gen_logic_CC(tmp2
);
10619 case 0x5: /* adc */
10620 if (s
->condexec_mask
) {
10621 gen_adc(tmp
, tmp2
);
10623 gen_adc_CC(tmp
, tmp
, tmp2
);
10626 case 0x6: /* sbc */
10627 if (s
->condexec_mask
) {
10628 gen_sub_carry(tmp
, tmp
, tmp2
);
10630 gen_sbc_CC(tmp
, tmp
, tmp2
);
10633 case 0x7: /* ror */
10634 if (s
->condexec_mask
) {
10635 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10636 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10638 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10639 gen_logic_CC(tmp2
);
10642 case 0x8: /* tst */
10643 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10647 case 0x9: /* neg */
10648 if (s
->condexec_mask
)
10649 tcg_gen_neg_i32(tmp
, tmp2
);
10651 gen_sub_CC(tmp
, tmp
, tmp2
);
10653 case 0xa: /* cmp */
10654 gen_sub_CC(tmp
, tmp
, tmp2
);
10657 case 0xb: /* cmn */
10658 gen_add_CC(tmp
, tmp
, tmp2
);
10661 case 0xc: /* orr */
10662 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10663 if (!s
->condexec_mask
)
10666 case 0xd: /* mul */
10667 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10668 if (!s
->condexec_mask
)
10671 case 0xe: /* bic */
10672 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10673 if (!s
->condexec_mask
)
10676 case 0xf: /* mvn */
10677 tcg_gen_not_i32(tmp2
, tmp2
);
10678 if (!s
->condexec_mask
)
10679 gen_logic_CC(tmp2
);
10686 store_reg(s
, rm
, tmp2
);
10688 tcg_temp_free_i32(tmp
);
10690 store_reg(s
, rd
, tmp
);
10691 tcg_temp_free_i32(tmp2
);
10694 tcg_temp_free_i32(tmp
);
10695 tcg_temp_free_i32(tmp2
);
10700 /* load/store register offset. */
10702 rn
= (insn
>> 3) & 7;
10703 rm
= (insn
>> 6) & 7;
10704 op
= (insn
>> 9) & 7;
10705 addr
= load_reg(s
, rn
);
10706 tmp
= load_reg(s
, rm
);
10707 tcg_gen_add_i32(addr
, addr
, tmp
);
10708 tcg_temp_free_i32(tmp
);
10710 if (op
< 3) { /* store */
10711 tmp
= load_reg(s
, rd
);
10713 tmp
= tcg_temp_new_i32();
10718 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10721 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10724 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10726 case 3: /* ldrsb */
10727 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10730 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10733 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10736 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10738 case 7: /* ldrsh */
10739 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10742 if (op
>= 3) { /* load */
10743 store_reg(s
, rd
, tmp
);
10745 tcg_temp_free_i32(tmp
);
10747 tcg_temp_free_i32(addr
);
10751 /* load/store word immediate offset */
10753 rn
= (insn
>> 3) & 7;
10754 addr
= load_reg(s
, rn
);
10755 val
= (insn
>> 4) & 0x7c;
10756 tcg_gen_addi_i32(addr
, addr
, val
);
10758 if (insn
& (1 << 11)) {
10760 tmp
= tcg_temp_new_i32();
10761 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10762 store_reg(s
, rd
, tmp
);
10765 tmp
= load_reg(s
, rd
);
10766 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10767 tcg_temp_free_i32(tmp
);
10769 tcg_temp_free_i32(addr
);
10773 /* load/store byte immediate offset */
10775 rn
= (insn
>> 3) & 7;
10776 addr
= load_reg(s
, rn
);
10777 val
= (insn
>> 6) & 0x1f;
10778 tcg_gen_addi_i32(addr
, addr
, val
);
10780 if (insn
& (1 << 11)) {
10782 tmp
= tcg_temp_new_i32();
10783 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10784 store_reg(s
, rd
, tmp
);
10787 tmp
= load_reg(s
, rd
);
10788 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10789 tcg_temp_free_i32(tmp
);
10791 tcg_temp_free_i32(addr
);
10795 /* load/store halfword immediate offset */
10797 rn
= (insn
>> 3) & 7;
10798 addr
= load_reg(s
, rn
);
10799 val
= (insn
>> 5) & 0x3e;
10800 tcg_gen_addi_i32(addr
, addr
, val
);
10802 if (insn
& (1 << 11)) {
10804 tmp
= tcg_temp_new_i32();
10805 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10806 store_reg(s
, rd
, tmp
);
10809 tmp
= load_reg(s
, rd
);
10810 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10811 tcg_temp_free_i32(tmp
);
10813 tcg_temp_free_i32(addr
);
10817 /* load/store from stack */
10818 rd
= (insn
>> 8) & 7;
10819 addr
= load_reg(s
, 13);
10820 val
= (insn
& 0xff) * 4;
10821 tcg_gen_addi_i32(addr
, addr
, val
);
10823 if (insn
& (1 << 11)) {
10825 tmp
= tcg_temp_new_i32();
10826 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10827 store_reg(s
, rd
, tmp
);
10830 tmp
= load_reg(s
, rd
);
10831 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10832 tcg_temp_free_i32(tmp
);
10834 tcg_temp_free_i32(addr
);
10838 /* add to high reg */
10839 rd
= (insn
>> 8) & 7;
10840 if (insn
& (1 << 11)) {
10842 tmp
= load_reg(s
, 13);
10844 /* PC. bit 1 is ignored. */
10845 tmp
= tcg_temp_new_i32();
10846 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10848 val
= (insn
& 0xff) * 4;
10849 tcg_gen_addi_i32(tmp
, tmp
, val
);
10850 store_reg(s
, rd
, tmp
);
10855 op
= (insn
>> 8) & 0xf;
10858 /* adjust stack pointer */
10859 tmp
= load_reg(s
, 13);
10860 val
= (insn
& 0x7f) * 4;
10861 if (insn
& (1 << 7))
10862 val
= -(int32_t)val
;
10863 tcg_gen_addi_i32(tmp
, tmp
, val
);
10864 store_reg(s
, 13, tmp
);
10867 case 2: /* sign/zero extend. */
10870 rm
= (insn
>> 3) & 7;
10871 tmp
= load_reg(s
, rm
);
10872 switch ((insn
>> 6) & 3) {
10873 case 0: gen_sxth(tmp
); break;
10874 case 1: gen_sxtb(tmp
); break;
10875 case 2: gen_uxth(tmp
); break;
10876 case 3: gen_uxtb(tmp
); break;
10878 store_reg(s
, rd
, tmp
);
10880 case 4: case 5: case 0xc: case 0xd:
10882 addr
= load_reg(s
, 13);
10883 if (insn
& (1 << 8))
10887 for (i
= 0; i
< 8; i
++) {
10888 if (insn
& (1 << i
))
10891 if ((insn
& (1 << 11)) == 0) {
10892 tcg_gen_addi_i32(addr
, addr
, -offset
);
10894 for (i
= 0; i
< 8; i
++) {
10895 if (insn
& (1 << i
)) {
10896 if (insn
& (1 << 11)) {
10898 tmp
= tcg_temp_new_i32();
10899 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10900 store_reg(s
, i
, tmp
);
10903 tmp
= load_reg(s
, i
);
10904 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10905 tcg_temp_free_i32(tmp
);
10907 /* advance to the next address. */
10908 tcg_gen_addi_i32(addr
, addr
, 4);
10911 TCGV_UNUSED_I32(tmp
);
10912 if (insn
& (1 << 8)) {
10913 if (insn
& (1 << 11)) {
10915 tmp
= tcg_temp_new_i32();
10916 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10917 /* don't set the pc until the rest of the instruction
10921 tmp
= load_reg(s
, 14);
10922 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10923 tcg_temp_free_i32(tmp
);
10925 tcg_gen_addi_i32(addr
, addr
, 4);
10927 if ((insn
& (1 << 11)) == 0) {
10928 tcg_gen_addi_i32(addr
, addr
, -offset
);
10930 /* write back the new stack pointer */
10931 store_reg(s
, 13, addr
);
10932 /* set the new PC value */
10933 if ((insn
& 0x0900) == 0x0900) {
10934 store_reg_from_load(s
, 15, tmp
);
10938 case 1: case 3: case 9: case 11: /* czb */
10940 tmp
= load_reg(s
, rm
);
10941 s
->condlabel
= gen_new_label();
10943 if (insn
& (1 << 11))
10944 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10946 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10947 tcg_temp_free_i32(tmp
);
10948 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10949 val
= (uint32_t)s
->pc
+ 2;
10954 case 15: /* IT, nop-hint. */
10955 if ((insn
& 0xf) == 0) {
10956 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10960 s
->condexec_cond
= (insn
>> 4) & 0xe;
10961 s
->condexec_mask
= insn
& 0x1f;
10962 /* No actual code generated for this insn, just setup state. */
10965 case 0xe: /* bkpt */
10967 int imm8
= extract32(insn
, 0, 8);
10969 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
10970 default_exception_el(s
));
10974 case 0xa: /* rev */
10976 rn
= (insn
>> 3) & 0x7;
10978 tmp
= load_reg(s
, rn
);
10979 switch ((insn
>> 6) & 3) {
10980 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10981 case 1: gen_rev16(tmp
); break;
10982 case 3: gen_revsh(tmp
); break;
10983 default: goto illegal_op
;
10985 store_reg(s
, rd
, tmp
);
10989 switch ((insn
>> 5) & 7) {
10993 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10994 /* Dynamic endianness switching not implemented. */
10995 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
11005 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11006 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11009 addr
= tcg_const_i32(19);
11010 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11011 tcg_temp_free_i32(addr
);
11015 addr
= tcg_const_i32(16);
11016 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11017 tcg_temp_free_i32(addr
);
11019 tcg_temp_free_i32(tmp
);
11022 if (insn
& (1 << 4)) {
11023 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11027 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11042 /* load/store multiple */
11043 TCGv_i32 loaded_var
;
11044 TCGV_UNUSED_I32(loaded_var
);
11045 rn
= (insn
>> 8) & 0x7;
11046 addr
= load_reg(s
, rn
);
11047 for (i
= 0; i
< 8; i
++) {
11048 if (insn
& (1 << i
)) {
11049 if (insn
& (1 << 11)) {
11051 tmp
= tcg_temp_new_i32();
11052 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
11056 store_reg(s
, i
, tmp
);
11060 tmp
= load_reg(s
, i
);
11061 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
11062 tcg_temp_free_i32(tmp
);
11064 /* advance to the next address */
11065 tcg_gen_addi_i32(addr
, addr
, 4);
11068 if ((insn
& (1 << rn
)) == 0) {
11069 /* base reg not in list: base register writeback */
11070 store_reg(s
, rn
, addr
);
11072 /* base reg in list: if load, complete it now */
11073 if (insn
& (1 << 11)) {
11074 store_reg(s
, rn
, loaded_var
);
11076 tcg_temp_free_i32(addr
);
11081 /* conditional branch or swi */
11082 cond
= (insn
>> 8) & 0xf;
11088 gen_set_pc_im(s
, s
->pc
);
11089 s
->svc_imm
= extract32(insn
, 0, 8);
11090 s
->is_jmp
= DISAS_SWI
;
11093 /* generate a conditional jump to next instruction */
11094 s
->condlabel
= gen_new_label();
11095 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11098 /* jump to the offset */
11099 val
= (uint32_t)s
->pc
+ 2;
11100 offset
= ((int32_t)insn
<< 24) >> 24;
11101 val
+= offset
<< 1;
11106 if (insn
& (1 << 11)) {
11107 if (disas_thumb2_insn(env
, s
, insn
))
11111 /* unconditional branch */
11112 val
= (uint32_t)s
->pc
;
11113 offset
= ((int32_t)insn
<< 21) >> 21;
11114 val
+= (offset
<< 1) + 2;
11119 if (disas_thumb2_insn(env
, s
, insn
))
11125 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11126 default_exception_el(s
));
11130 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11131 default_exception_el(s
));
11134 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
11135 basic block 'tb'. If search_pc is TRUE, also generate PC
11136 information for each intermediate instruction. */
11137 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
11138 TranslationBlock
*tb
,
11141 CPUState
*cs
= CPU(cpu
);
11142 CPUARMState
*env
= &cpu
->env
;
11143 DisasContext dc1
, *dc
= &dc1
;
11146 target_ulong pc_start
;
11147 target_ulong next_page_start
;
11151 /* generate intermediate code */
11153 /* The A64 decoder has its own top level loop, because it doesn't need
11154 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11156 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11157 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
11165 dc
->is_jmp
= DISAS_NEXT
;
11167 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11171 dc
->el3_is_aa64
= arm_el_is_aa64(env
, 3);
11172 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11173 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
11174 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11175 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11176 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11177 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11178 #if !defined(CONFIG_USER_ONLY)
11179 dc
->user
= (dc
->current_el
== 0);
11181 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11182 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11183 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11184 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11185 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11186 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11187 dc
->cp_regs
= cpu
->cp_regs
;
11188 dc
->features
= env
->features
;
11190 /* Single step state. The code-generation logic here is:
11192 * generate code with no special handling for single-stepping (except
11193 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11194 * this happens anyway because those changes are all system register or
11196 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11197 * emit code for one insn
11198 * emit code to clear PSTATE.SS
11199 * emit code to generate software step exception for completed step
11200 * end TB (as usual for having generated an exception)
11201 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11202 * emit code to generate a software step exception
11205 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11206 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11207 dc
->is_ldex
= false;
11208 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11210 cpu_F0s
= tcg_temp_new_i32();
11211 cpu_F1s
= tcg_temp_new_i32();
11212 cpu_F0d
= tcg_temp_new_i64();
11213 cpu_F1d
= tcg_temp_new_i64();
11216 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11217 cpu_M0
= tcg_temp_new_i64();
11218 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11221 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11222 if (max_insns
== 0)
11223 max_insns
= CF_COUNT_MASK
;
11227 tcg_clear_temp_count();
11229 /* A note on handling of the condexec (IT) bits:
11231 * We want to avoid the overhead of having to write the updated condexec
11232 * bits back to the CPUARMState for every instruction in an IT block. So:
11233 * (1) if the condexec bits are not already zero then we write
11234 * zero back into the CPUARMState now. This avoids complications trying
11235 * to do it at the end of the block. (For example if we don't do this
11236 * it's hard to identify whether we can safely skip writing condexec
11237 * at the end of the TB, which we definitely want to do for the case
11238 * where a TB doesn't do anything with the IT state at all.)
11239 * (2) if we are going to leave the TB then we call gen_set_condexec()
11240 * which will write the correct value into CPUARMState if zero is wrong.
11241 * This is done both for leaving the TB at the end, and for leaving
11242 * it because of an exception we know will happen, which is done in
11243 * gen_exception_insn(). The latter is necessary because we need to
11244 * leave the TB with the PC/IT state just prior to execution of the
11245 * instruction which caused the exception.
11246 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11247 * then the CPUARMState will be wrong and we need to reset it.
11248 * This is handled in the same way as restoration of the
11249 * PC in these situations: we will be called again with search_pc=1
11250 * and generate a mapping of the condexec bits for each PC in
11251 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11252 * this to restore the condexec bits.
11254 * Note that there are no instructions which can read the condexec
11255 * bits, and none which can write non-static values to them, so
11256 * we don't need to care about whether CPUARMState is correct in the
11260 /* Reset the conditional execution bits immediately. This avoids
11261 complications trying to do it at the end of the block. */
11262 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11264 TCGv_i32 tmp
= tcg_temp_new_i32();
11265 tcg_gen_movi_i32(tmp
, 0);
11266 store_cpu_field(tmp
, condexec_bits
);
11269 #ifdef CONFIG_USER_ONLY
11270 /* Intercept jump to the magic kernel page. */
11271 if (dc
->pc
>= 0xffff0000) {
11272 /* We always get here via a jump, so know we are not in a
11273 conditional execution block. */
11274 gen_exception_internal(EXCP_KERNEL_TRAP
);
11275 dc
->is_jmp
= DISAS_UPDATE
;
11279 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11280 /* We always get here via a jump, so know we are not in a
11281 conditional execution block. */
11282 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11283 dc
->is_jmp
= DISAS_UPDATE
;
11288 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11289 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11290 if (bp
->pc
== dc
->pc
) {
11291 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11292 /* Advance PC so that clearing the breakpoint will
11293 invalidate this TB. */
11295 goto done_generating
;
11300 j
= tcg_op_buf_count();
11304 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11306 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
11307 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
11308 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
11309 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
11312 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
11315 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
11316 tcg_gen_debug_insn_start(dc
->pc
);
11319 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11320 /* Singlestep state is Active-pending.
11321 * If we're in this state at the start of a TB then either
11322 * a) we just took an exception to an EL which is being debugged
11323 * and this is the first insn in the exception handler
11324 * b) debug exceptions were masked and we just unmasked them
11325 * without changing EL (eg by clearing PSTATE.D)
11326 * In either case we're going to take a swstep exception in the
11327 * "did not step an insn" case, and so the syndrome ISV and EX
11328 * bits should be zero.
11330 assert(num_insns
== 0);
11331 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11332 default_exception_el(dc
));
11333 goto done_generating
;
11337 disas_thumb_insn(env
, dc
);
11338 if (dc
->condexec_mask
) {
11339 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11340 | ((dc
->condexec_mask
>> 4) & 1);
11341 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11342 if (dc
->condexec_mask
== 0) {
11343 dc
->condexec_cond
= 0;
11347 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->bswap_code
);
11349 disas_arm_insn(dc
, insn
);
11352 if (dc
->condjmp
&& !dc
->is_jmp
) {
11353 gen_set_label(dc
->condlabel
);
11357 if (tcg_check_temp_count()) {
11358 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11362 /* Translation stops when a conditional branch is encountered.
11363 * Otherwise the subsequent code could get translated several times.
11364 * Also stop translation when a page boundary is reached. This
11365 * ensures prefetch aborts occur at the right place. */
11367 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11368 !cs
->singlestep_enabled
&&
11371 dc
->pc
< next_page_start
&&
11372 num_insns
< max_insns
);
11374 if (tb
->cflags
& CF_LAST_IO
) {
11376 /* FIXME: This can theoretically happen with self-modifying
11378 cpu_abort(cs
, "IO on conditional branch instruction");
11383 /* At this stage dc->condjmp will only be set when the skipped
11384 instruction was a conditional branch or trap, and the PC has
11385 already been written. */
11386 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11387 /* Make sure the pc is updated, and raise a debug exception. */
11389 gen_set_condexec(dc
);
11390 if (dc
->is_jmp
== DISAS_SWI
) {
11391 gen_ss_advance(dc
);
11392 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11393 default_exception_el(dc
));
11394 } else if (dc
->is_jmp
== DISAS_HVC
) {
11395 gen_ss_advance(dc
);
11396 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11397 } else if (dc
->is_jmp
== DISAS_SMC
) {
11398 gen_ss_advance(dc
);
11399 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11400 } else if (dc
->ss_active
) {
11401 gen_step_complete_exception(dc
);
11403 gen_exception_internal(EXCP_DEBUG
);
11405 gen_set_label(dc
->condlabel
);
11407 if (dc
->condjmp
|| !dc
->is_jmp
) {
11408 gen_set_pc_im(dc
, dc
->pc
);
11411 gen_set_condexec(dc
);
11412 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11413 gen_ss_advance(dc
);
11414 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11415 default_exception_el(dc
));
11416 } else if (dc
->is_jmp
== DISAS_HVC
&& !dc
->condjmp
) {
11417 gen_ss_advance(dc
);
11418 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11419 } else if (dc
->is_jmp
== DISAS_SMC
&& !dc
->condjmp
) {
11420 gen_ss_advance(dc
);
11421 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11422 } else if (dc
->ss_active
) {
11423 gen_step_complete_exception(dc
);
11425 /* FIXME: Single stepping a WFI insn will not halt
11427 gen_exception_internal(EXCP_DEBUG
);
11430 /* While branches must always occur at the end of an IT block,
11431 there are a few other things that can cause us to terminate
11432 the TB in the middle of an IT block:
11433 - Exception generating instructions (bkpt, swi, undefined).
11435 - Hardware watchpoints.
11436 Hardware breakpoints have already been handled and skip this code.
11438 gen_set_condexec(dc
);
11439 switch(dc
->is_jmp
) {
11441 gen_goto_tb(dc
, 1, dc
->pc
);
11446 /* indicate that the hash table must be used to find the next TB */
11447 tcg_gen_exit_tb(0);
11449 case DISAS_TB_JUMP
:
11450 /* nothing more to generate */
11453 gen_helper_wfi(cpu_env
);
11454 /* The helper doesn't necessarily throw an exception, but we
11455 * must go back to the main loop to check for interrupts anyway.
11457 tcg_gen_exit_tb(0);
11460 gen_helper_wfe(cpu_env
);
11463 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11464 default_exception_el(dc
));
11467 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11470 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11474 gen_set_label(dc
->condlabel
);
11475 gen_set_condexec(dc
);
11476 gen_goto_tb(dc
, 1, dc
->pc
);
11482 gen_tb_end(tb
, num_insns
);
11485 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11486 qemu_log("----------------\n");
11487 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11488 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
11489 dc
->thumb
| (dc
->bswap_code
<< 1));
11494 j
= tcg_op_buf_count();
11497 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11499 tb
->size
= dc
->pc
- pc_start
;
11500 tb
->icount
= num_insns
;
11504 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11506 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11509 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11511 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11514 static const char *cpu_mode_names
[16] = {
11515 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11516 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11519 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11522 ARMCPU
*cpu
= ARM_CPU(cs
);
11523 CPUARMState
*env
= &cpu
->env
;
11528 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11532 for(i
=0;i
<16;i
++) {
11533 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11535 cpu_fprintf(f
, "\n");
11537 cpu_fprintf(f
, " ");
11539 psr
= cpsr_read(env
);
11540 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11542 psr
& (1 << 31) ? 'N' : '-',
11543 psr
& (1 << 30) ? 'Z' : '-',
11544 psr
& (1 << 29) ? 'C' : '-',
11545 psr
& (1 << 28) ? 'V' : '-',
11546 psr
& CPSR_T
? 'T' : 'A',
11547 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11549 if (flags
& CPU_DUMP_FPU
) {
11550 int numvfpregs
= 0;
11551 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11554 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11557 for (i
= 0; i
< numvfpregs
; i
++) {
11558 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11559 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11560 i
* 2, (uint32_t)v
,
11561 i
* 2 + 1, (uint32_t)(v
>> 32),
11564 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11568 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11571 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11572 env
->condexec_bits
= 0;
11574 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11575 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];