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 TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
68 TCGv_i64 cpu_exclusive_addr
;
69 TCGv_i64 cpu_exclusive_val
;
70 #ifdef CONFIG_USER_ONLY
71 TCGv_i64 cpu_exclusive_test
;
72 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 based on ARM condition code cc.
742 * This is common between ARM and Aarch64 targets.
744 void arm_test_cc(DisasCompare
*cmp
, int cc
)
775 case 8: /* hi: C && !Z */
776 case 9: /* ls: !C || Z -> !(C && !Z) */
778 value
= tcg_temp_new_i32();
780 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
781 ZF is non-zero for !Z; so AND the two subexpressions. */
782 tcg_gen_neg_i32(value
, cpu_CF
);
783 tcg_gen_and_i32(value
, value
, cpu_ZF
);
786 case 10: /* ge: N == V -> N ^ V == 0 */
787 case 11: /* lt: N != V -> N ^ V != 0 */
788 /* Since we're only interested in the sign bit, == 0 is >= 0. */
790 value
= tcg_temp_new_i32();
792 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
795 case 12: /* gt: !Z && N == V */
796 case 13: /* le: Z || N != V */
798 value
= tcg_temp_new_i32();
800 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
801 * the sign bit then AND with ZF to yield the result. */
802 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
803 tcg_gen_sari_i32(value
, value
, 31);
804 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
807 case 14: /* always */
808 case 15: /* always */
809 /* Use the ALWAYS condition, which will fold early.
810 * It doesn't matter what we use for the value. */
811 cond
= TCG_COND_ALWAYS
;
816 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
821 cond
= tcg_invert_cond(cond
);
827 cmp
->value_global
= global
;
830 void arm_free_cc(DisasCompare
*cmp
)
832 if (!cmp
->value_global
) {
833 tcg_temp_free_i32(cmp
->value
);
837 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
839 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
842 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
845 arm_test_cc(&cmp
, cc
);
846 arm_jump_cc(&cmp
, label
);
850 static const uint8_t table_logic_cc
[16] = {
869 /* Set PC and Thumb state from an immediate address. */
870 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
874 s
->is_jmp
= DISAS_UPDATE
;
875 if (s
->thumb
!= (addr
& 1)) {
876 tmp
= tcg_temp_new_i32();
877 tcg_gen_movi_i32(tmp
, addr
& 1);
878 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
879 tcg_temp_free_i32(tmp
);
881 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
884 /* Set PC and Thumb state from var. var is marked as dead. */
885 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
887 s
->is_jmp
= DISAS_UPDATE
;
888 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
889 tcg_gen_andi_i32(var
, var
, 1);
890 store_cpu_field(var
, thumb
);
893 /* Variant of store_reg which uses branch&exchange logic when storing
894 to r15 in ARM architecture v7 and above. The source must be a temporary
895 and will be marked as dead. */
896 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
898 if (reg
== 15 && ENABLE_ARCH_7
) {
901 store_reg(s
, reg
, var
);
905 /* Variant of store_reg which uses branch&exchange logic when storing
906 * to r15 in ARM architecture v5T and above. This is used for storing
907 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
908 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
909 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
911 if (reg
== 15 && ENABLE_ARCH_5
) {
914 store_reg(s
, reg
, var
);
918 /* Abstractions of "generate code to do a guest load/store for
919 * AArch32", where a vaddr is always 32 bits (and is zero
920 * extended if we're a 64 bit core) and data is also
921 * 32 bits unless specifically doing a 64 bit access.
922 * These functions work like tcg_gen_qemu_{ld,st}* except
923 * that the address argument is TCGv_i32 rather than TCGv.
925 #if TARGET_LONG_BITS == 32
927 #define DO_GEN_LD(SUFF, OPC) \
928 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
930 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
933 #define DO_GEN_ST(SUFF, OPC) \
934 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
936 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
939 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
941 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
944 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
946 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
951 #define DO_GEN_LD(SUFF, OPC) \
952 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
954 TCGv addr64 = tcg_temp_new(); \
955 tcg_gen_extu_i32_i64(addr64, addr); \
956 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
957 tcg_temp_free(addr64); \
960 #define DO_GEN_ST(SUFF, OPC) \
961 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
963 TCGv addr64 = tcg_temp_new(); \
964 tcg_gen_extu_i32_i64(addr64, addr); \
965 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
966 tcg_temp_free(addr64); \
969 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
971 TCGv addr64
= tcg_temp_new();
972 tcg_gen_extu_i32_i64(addr64
, addr
);
973 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
974 tcg_temp_free(addr64
);
977 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
979 TCGv addr64
= tcg_temp_new();
980 tcg_gen_extu_i32_i64(addr64
, addr
);
981 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
982 tcg_temp_free(addr64
);
989 DO_GEN_LD(16s
, MO_TESW
)
990 DO_GEN_LD(16u, MO_TEUW
)
991 DO_GEN_LD(32u, MO_TEUL
)
993 DO_GEN_ST(16, MO_TEUW
)
994 DO_GEN_ST(32, MO_TEUL
)
996 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
998 tcg_gen_movi_i32(cpu_R
[15], val
);
1001 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1003 /* The pre HVC helper handles cases when HVC gets trapped
1004 * as an undefined insn by runtime configuration (ie before
1005 * the insn really executes).
1007 gen_set_pc_im(s
, s
->pc
- 4);
1008 gen_helper_pre_hvc(cpu_env
);
1009 /* Otherwise we will treat this as a real exception which
1010 * happens after execution of the insn. (The distinction matters
1011 * for the PC value reported to the exception handler and also
1012 * for single stepping.)
1015 gen_set_pc_im(s
, s
->pc
);
1016 s
->is_jmp
= DISAS_HVC
;
1019 static inline void gen_smc(DisasContext
*s
)
1021 /* As with HVC, we may take an exception either before or after
1022 * the insn executes.
1026 gen_set_pc_im(s
, s
->pc
- 4);
1027 tmp
= tcg_const_i32(syn_aa32_smc());
1028 gen_helper_pre_smc(cpu_env
, tmp
);
1029 tcg_temp_free_i32(tmp
);
1030 gen_set_pc_im(s
, s
->pc
);
1031 s
->is_jmp
= DISAS_SMC
;
1035 gen_set_condexec (DisasContext
*s
)
1037 if (s
->condexec_mask
) {
1038 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
1039 TCGv_i32 tmp
= tcg_temp_new_i32();
1040 tcg_gen_movi_i32(tmp
, val
);
1041 store_cpu_field(tmp
, condexec_bits
);
1045 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1047 gen_set_condexec(s
);
1048 gen_set_pc_im(s
, s
->pc
- offset
);
1049 gen_exception_internal(excp
);
1050 s
->is_jmp
= DISAS_JUMP
;
1053 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1054 int syn
, uint32_t target_el
)
1056 gen_set_condexec(s
);
1057 gen_set_pc_im(s
, s
->pc
- offset
);
1058 gen_exception(excp
, syn
, target_el
);
1059 s
->is_jmp
= DISAS_JUMP
;
1062 /* Force a TB lookup after an instruction that changes the CPU state. */
1063 static inline void gen_lookup_tb(DisasContext
*s
)
1065 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1066 s
->is_jmp
= DISAS_UPDATE
;
1069 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1072 int val
, rm
, shift
, shiftop
;
1075 if (!(insn
& (1 << 25))) {
1078 if (!(insn
& (1 << 23)))
1081 tcg_gen_addi_i32(var
, var
, val
);
1083 /* shift/register */
1085 shift
= (insn
>> 7) & 0x1f;
1086 shiftop
= (insn
>> 5) & 3;
1087 offset
= load_reg(s
, rm
);
1088 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1089 if (!(insn
& (1 << 23)))
1090 tcg_gen_sub_i32(var
, var
, offset
);
1092 tcg_gen_add_i32(var
, var
, offset
);
1093 tcg_temp_free_i32(offset
);
1097 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1098 int extra
, TCGv_i32 var
)
1103 if (insn
& (1 << 22)) {
1105 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1106 if (!(insn
& (1 << 23)))
1110 tcg_gen_addi_i32(var
, var
, val
);
1114 tcg_gen_addi_i32(var
, var
, extra
);
1116 offset
= load_reg(s
, rm
);
1117 if (!(insn
& (1 << 23)))
1118 tcg_gen_sub_i32(var
, var
, offset
);
1120 tcg_gen_add_i32(var
, var
, offset
);
1121 tcg_temp_free_i32(offset
);
1125 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1127 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1130 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1132 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1134 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1138 #define VFP_OP2(name) \
1139 static inline void gen_vfp_##name(int dp) \
1141 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1143 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1145 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1147 tcg_temp_free_ptr(fpst); \
1157 static inline void gen_vfp_F1_mul(int dp
)
1159 /* Like gen_vfp_mul() but put result in F1 */
1160 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1162 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1164 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1166 tcg_temp_free_ptr(fpst
);
1169 static inline void gen_vfp_F1_neg(int dp
)
1171 /* Like gen_vfp_neg() but put result in F1 */
1173 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1175 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1179 static inline void gen_vfp_abs(int dp
)
1182 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1184 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1187 static inline void gen_vfp_neg(int dp
)
1190 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1192 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1195 static inline void gen_vfp_sqrt(int dp
)
1198 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1200 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1203 static inline void gen_vfp_cmp(int dp
)
1206 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1208 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1211 static inline void gen_vfp_cmpe(int dp
)
1214 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1216 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1219 static inline void gen_vfp_F1_ld0(int dp
)
1222 tcg_gen_movi_i64(cpu_F1d
, 0);
1224 tcg_gen_movi_i32(cpu_F1s
, 0);
1227 #define VFP_GEN_ITOF(name) \
1228 static inline void gen_vfp_##name(int dp, int neon) \
1230 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1232 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1234 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1236 tcg_temp_free_ptr(statusptr); \
1243 #define VFP_GEN_FTOI(name) \
1244 static inline void gen_vfp_##name(int dp, int neon) \
1246 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1248 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1250 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1252 tcg_temp_free_ptr(statusptr); \
1261 #define VFP_GEN_FIX(name, round) \
1262 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1264 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1265 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1267 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1270 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1273 tcg_temp_free_i32(tmp_shift); \
1274 tcg_temp_free_ptr(statusptr); \
1276 VFP_GEN_FIX(tosh
, _round_to_zero
)
1277 VFP_GEN_FIX(tosl
, _round_to_zero
)
1278 VFP_GEN_FIX(touh
, _round_to_zero
)
1279 VFP_GEN_FIX(toul
, _round_to_zero
)
1286 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1289 gen_aa32_ld64(cpu_F0d
, addr
, get_mem_index(s
));
1291 gen_aa32_ld32u(cpu_F0s
, addr
, get_mem_index(s
));
1295 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1298 gen_aa32_st64(cpu_F0d
, addr
, get_mem_index(s
));
1300 gen_aa32_st32(cpu_F0s
, addr
, get_mem_index(s
));
1305 vfp_reg_offset (int dp
, int reg
)
1308 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1310 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1311 + offsetof(CPU_DoubleU
, l
.upper
);
1313 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1314 + offsetof(CPU_DoubleU
, l
.lower
);
1318 /* Return the offset of a 32-bit piece of a NEON register.
1319 zero is the least significant end of the register. */
1321 neon_reg_offset (int reg
, int n
)
1325 return vfp_reg_offset(0, sreg
);
1328 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1330 TCGv_i32 tmp
= tcg_temp_new_i32();
1331 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1335 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1337 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1338 tcg_temp_free_i32(var
);
1341 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1343 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1346 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1348 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1351 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1352 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1353 #define tcg_gen_st_f32 tcg_gen_st_i32
1354 #define tcg_gen_st_f64 tcg_gen_st_i64
1356 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1359 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1361 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1364 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1367 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1369 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1372 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1375 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1377 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1380 #define ARM_CP_RW_BIT (1 << 20)
1382 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1384 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1387 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1389 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1392 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1394 TCGv_i32 var
= tcg_temp_new_i32();
1395 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1399 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1401 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1402 tcg_temp_free_i32(var
);
1405 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1407 iwmmxt_store_reg(cpu_M0
, rn
);
1410 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1412 iwmmxt_load_reg(cpu_M0
, rn
);
1415 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1417 iwmmxt_load_reg(cpu_V1
, rn
);
1418 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1421 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1423 iwmmxt_load_reg(cpu_V1
, rn
);
1424 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1427 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1429 iwmmxt_load_reg(cpu_V1
, rn
);
1430 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1433 #define IWMMXT_OP(name) \
1434 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1436 iwmmxt_load_reg(cpu_V1, rn); \
1437 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1440 #define IWMMXT_OP_ENV(name) \
1441 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1443 iwmmxt_load_reg(cpu_V1, rn); \
1444 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1447 #define IWMMXT_OP_ENV_SIZE(name) \
1448 IWMMXT_OP_ENV(name##b) \
1449 IWMMXT_OP_ENV(name##w) \
1450 IWMMXT_OP_ENV(name##l)
1452 #define IWMMXT_OP_ENV1(name) \
1453 static inline void gen_op_iwmmxt_##name##_M0(void) \
1455 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1469 IWMMXT_OP_ENV_SIZE(unpackl
)
1470 IWMMXT_OP_ENV_SIZE(unpackh
)
1472 IWMMXT_OP_ENV1(unpacklub
)
1473 IWMMXT_OP_ENV1(unpackluw
)
1474 IWMMXT_OP_ENV1(unpacklul
)
1475 IWMMXT_OP_ENV1(unpackhub
)
1476 IWMMXT_OP_ENV1(unpackhuw
)
1477 IWMMXT_OP_ENV1(unpackhul
)
1478 IWMMXT_OP_ENV1(unpacklsb
)
1479 IWMMXT_OP_ENV1(unpacklsw
)
1480 IWMMXT_OP_ENV1(unpacklsl
)
1481 IWMMXT_OP_ENV1(unpackhsb
)
1482 IWMMXT_OP_ENV1(unpackhsw
)
1483 IWMMXT_OP_ENV1(unpackhsl
)
1485 IWMMXT_OP_ENV_SIZE(cmpeq
)
1486 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1487 IWMMXT_OP_ENV_SIZE(cmpgts
)
1489 IWMMXT_OP_ENV_SIZE(mins
)
1490 IWMMXT_OP_ENV_SIZE(minu
)
1491 IWMMXT_OP_ENV_SIZE(maxs
)
1492 IWMMXT_OP_ENV_SIZE(maxu
)
1494 IWMMXT_OP_ENV_SIZE(subn
)
1495 IWMMXT_OP_ENV_SIZE(addn
)
1496 IWMMXT_OP_ENV_SIZE(subu
)
1497 IWMMXT_OP_ENV_SIZE(addu
)
1498 IWMMXT_OP_ENV_SIZE(subs
)
1499 IWMMXT_OP_ENV_SIZE(adds
)
1501 IWMMXT_OP_ENV(avgb0
)
1502 IWMMXT_OP_ENV(avgb1
)
1503 IWMMXT_OP_ENV(avgw0
)
1504 IWMMXT_OP_ENV(avgw1
)
1506 IWMMXT_OP_ENV(packuw
)
1507 IWMMXT_OP_ENV(packul
)
1508 IWMMXT_OP_ENV(packuq
)
1509 IWMMXT_OP_ENV(packsw
)
1510 IWMMXT_OP_ENV(packsl
)
1511 IWMMXT_OP_ENV(packsq
)
1513 static void gen_op_iwmmxt_set_mup(void)
1516 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1517 tcg_gen_ori_i32(tmp
, tmp
, 2);
1518 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1521 static void gen_op_iwmmxt_set_cup(void)
1524 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1525 tcg_gen_ori_i32(tmp
, tmp
, 1);
1526 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1529 static void gen_op_iwmmxt_setpsr_nz(void)
1531 TCGv_i32 tmp
= tcg_temp_new_i32();
1532 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1533 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1536 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1538 iwmmxt_load_reg(cpu_V1
, rn
);
1539 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1540 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1543 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1550 rd
= (insn
>> 16) & 0xf;
1551 tmp
= load_reg(s
, rd
);
1553 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1554 if (insn
& (1 << 24)) {
1556 if (insn
& (1 << 23))
1557 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1559 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1560 tcg_gen_mov_i32(dest
, tmp
);
1561 if (insn
& (1 << 21))
1562 store_reg(s
, rd
, tmp
);
1564 tcg_temp_free_i32(tmp
);
1565 } else if (insn
& (1 << 21)) {
1567 tcg_gen_mov_i32(dest
, tmp
);
1568 if (insn
& (1 << 23))
1569 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1571 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1572 store_reg(s
, rd
, tmp
);
1573 } else if (!(insn
& (1 << 23)))
1578 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1580 int rd
= (insn
>> 0) & 0xf;
1583 if (insn
& (1 << 8)) {
1584 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1587 tmp
= iwmmxt_load_creg(rd
);
1590 tmp
= tcg_temp_new_i32();
1591 iwmmxt_load_reg(cpu_V0
, rd
);
1592 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1594 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1595 tcg_gen_mov_i32(dest
, tmp
);
1596 tcg_temp_free_i32(tmp
);
1600 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1601 (ie. an undefined instruction). */
1602 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1605 int rdhi
, rdlo
, rd0
, rd1
, i
;
1607 TCGv_i32 tmp
, tmp2
, tmp3
;
1609 if ((insn
& 0x0e000e00) == 0x0c000000) {
1610 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1612 rdlo
= (insn
>> 12) & 0xf;
1613 rdhi
= (insn
>> 16) & 0xf;
1614 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1615 iwmmxt_load_reg(cpu_V0
, wrd
);
1616 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1617 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1618 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1619 } else { /* TMCRR */
1620 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1621 iwmmxt_store_reg(cpu_V0
, wrd
);
1622 gen_op_iwmmxt_set_mup();
1627 wrd
= (insn
>> 12) & 0xf;
1628 addr
= tcg_temp_new_i32();
1629 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1630 tcg_temp_free_i32(addr
);
1633 if (insn
& ARM_CP_RW_BIT
) {
1634 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1635 tmp
= tcg_temp_new_i32();
1636 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1637 iwmmxt_store_creg(wrd
, tmp
);
1640 if (insn
& (1 << 8)) {
1641 if (insn
& (1 << 22)) { /* WLDRD */
1642 gen_aa32_ld64(cpu_M0
, addr
, get_mem_index(s
));
1644 } else { /* WLDRW wRd */
1645 tmp
= tcg_temp_new_i32();
1646 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
1649 tmp
= tcg_temp_new_i32();
1650 if (insn
& (1 << 22)) { /* WLDRH */
1651 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
1652 } else { /* WLDRB */
1653 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
1657 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1658 tcg_temp_free_i32(tmp
);
1660 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1663 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1664 tmp
= iwmmxt_load_creg(wrd
);
1665 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1667 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1668 tmp
= tcg_temp_new_i32();
1669 if (insn
& (1 << 8)) {
1670 if (insn
& (1 << 22)) { /* WSTRD */
1671 gen_aa32_st64(cpu_M0
, addr
, get_mem_index(s
));
1672 } else { /* WSTRW wRd */
1673 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1674 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
1677 if (insn
& (1 << 22)) { /* WSTRH */
1678 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1679 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
1680 } else { /* WSTRB */
1681 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1682 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
1686 tcg_temp_free_i32(tmp
);
1688 tcg_temp_free_i32(addr
);
1692 if ((insn
& 0x0f000000) != 0x0e000000)
1695 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1696 case 0x000: /* WOR */
1697 wrd
= (insn
>> 12) & 0xf;
1698 rd0
= (insn
>> 0) & 0xf;
1699 rd1
= (insn
>> 16) & 0xf;
1700 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1701 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1702 gen_op_iwmmxt_setpsr_nz();
1703 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1704 gen_op_iwmmxt_set_mup();
1705 gen_op_iwmmxt_set_cup();
1707 case 0x011: /* TMCR */
1710 rd
= (insn
>> 12) & 0xf;
1711 wrd
= (insn
>> 16) & 0xf;
1713 case ARM_IWMMXT_wCID
:
1714 case ARM_IWMMXT_wCASF
:
1716 case ARM_IWMMXT_wCon
:
1717 gen_op_iwmmxt_set_cup();
1719 case ARM_IWMMXT_wCSSF
:
1720 tmp
= iwmmxt_load_creg(wrd
);
1721 tmp2
= load_reg(s
, rd
);
1722 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1723 tcg_temp_free_i32(tmp2
);
1724 iwmmxt_store_creg(wrd
, tmp
);
1726 case ARM_IWMMXT_wCGR0
:
1727 case ARM_IWMMXT_wCGR1
:
1728 case ARM_IWMMXT_wCGR2
:
1729 case ARM_IWMMXT_wCGR3
:
1730 gen_op_iwmmxt_set_cup();
1731 tmp
= load_reg(s
, rd
);
1732 iwmmxt_store_creg(wrd
, tmp
);
1738 case 0x100: /* WXOR */
1739 wrd
= (insn
>> 12) & 0xf;
1740 rd0
= (insn
>> 0) & 0xf;
1741 rd1
= (insn
>> 16) & 0xf;
1742 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1743 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1744 gen_op_iwmmxt_setpsr_nz();
1745 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1746 gen_op_iwmmxt_set_mup();
1747 gen_op_iwmmxt_set_cup();
1749 case 0x111: /* TMRC */
1752 rd
= (insn
>> 12) & 0xf;
1753 wrd
= (insn
>> 16) & 0xf;
1754 tmp
= iwmmxt_load_creg(wrd
);
1755 store_reg(s
, rd
, tmp
);
1757 case 0x300: /* WANDN */
1758 wrd
= (insn
>> 12) & 0xf;
1759 rd0
= (insn
>> 0) & 0xf;
1760 rd1
= (insn
>> 16) & 0xf;
1761 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1762 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1763 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1764 gen_op_iwmmxt_setpsr_nz();
1765 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1766 gen_op_iwmmxt_set_mup();
1767 gen_op_iwmmxt_set_cup();
1769 case 0x200: /* WAND */
1770 wrd
= (insn
>> 12) & 0xf;
1771 rd0
= (insn
>> 0) & 0xf;
1772 rd1
= (insn
>> 16) & 0xf;
1773 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1774 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1775 gen_op_iwmmxt_setpsr_nz();
1776 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1777 gen_op_iwmmxt_set_mup();
1778 gen_op_iwmmxt_set_cup();
1780 case 0x810: case 0xa10: /* WMADD */
1781 wrd
= (insn
>> 12) & 0xf;
1782 rd0
= (insn
>> 0) & 0xf;
1783 rd1
= (insn
>> 16) & 0xf;
1784 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1785 if (insn
& (1 << 21))
1786 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1788 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1789 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1790 gen_op_iwmmxt_set_mup();
1792 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1793 wrd
= (insn
>> 12) & 0xf;
1794 rd0
= (insn
>> 16) & 0xf;
1795 rd1
= (insn
>> 0) & 0xf;
1796 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1797 switch ((insn
>> 22) & 3) {
1799 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1802 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1805 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1810 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1811 gen_op_iwmmxt_set_mup();
1812 gen_op_iwmmxt_set_cup();
1814 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1815 wrd
= (insn
>> 12) & 0xf;
1816 rd0
= (insn
>> 16) & 0xf;
1817 rd1
= (insn
>> 0) & 0xf;
1818 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1819 switch ((insn
>> 22) & 3) {
1821 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1824 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1827 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1832 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1833 gen_op_iwmmxt_set_mup();
1834 gen_op_iwmmxt_set_cup();
1836 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1837 wrd
= (insn
>> 12) & 0xf;
1838 rd0
= (insn
>> 16) & 0xf;
1839 rd1
= (insn
>> 0) & 0xf;
1840 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1841 if (insn
& (1 << 22))
1842 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1844 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1845 if (!(insn
& (1 << 20)))
1846 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1847 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1848 gen_op_iwmmxt_set_mup();
1850 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1851 wrd
= (insn
>> 12) & 0xf;
1852 rd0
= (insn
>> 16) & 0xf;
1853 rd1
= (insn
>> 0) & 0xf;
1854 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1855 if (insn
& (1 << 21)) {
1856 if (insn
& (1 << 20))
1857 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1859 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1861 if (insn
& (1 << 20))
1862 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1864 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1866 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1867 gen_op_iwmmxt_set_mup();
1869 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1870 wrd
= (insn
>> 12) & 0xf;
1871 rd0
= (insn
>> 16) & 0xf;
1872 rd1
= (insn
>> 0) & 0xf;
1873 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1874 if (insn
& (1 << 21))
1875 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1877 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1878 if (!(insn
& (1 << 20))) {
1879 iwmmxt_load_reg(cpu_V1
, wrd
);
1880 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1882 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1883 gen_op_iwmmxt_set_mup();
1885 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1886 wrd
= (insn
>> 12) & 0xf;
1887 rd0
= (insn
>> 16) & 0xf;
1888 rd1
= (insn
>> 0) & 0xf;
1889 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1890 switch ((insn
>> 22) & 3) {
1892 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1895 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1898 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1903 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1904 gen_op_iwmmxt_set_mup();
1905 gen_op_iwmmxt_set_cup();
1907 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1908 wrd
= (insn
>> 12) & 0xf;
1909 rd0
= (insn
>> 16) & 0xf;
1910 rd1
= (insn
>> 0) & 0xf;
1911 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1912 if (insn
& (1 << 22)) {
1913 if (insn
& (1 << 20))
1914 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1916 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1918 if (insn
& (1 << 20))
1919 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1921 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1923 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1924 gen_op_iwmmxt_set_mup();
1925 gen_op_iwmmxt_set_cup();
1927 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1928 wrd
= (insn
>> 12) & 0xf;
1929 rd0
= (insn
>> 16) & 0xf;
1930 rd1
= (insn
>> 0) & 0xf;
1931 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1932 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1933 tcg_gen_andi_i32(tmp
, tmp
, 7);
1934 iwmmxt_load_reg(cpu_V1
, rd1
);
1935 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1936 tcg_temp_free_i32(tmp
);
1937 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1938 gen_op_iwmmxt_set_mup();
1940 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1941 if (((insn
>> 6) & 3) == 3)
1943 rd
= (insn
>> 12) & 0xf;
1944 wrd
= (insn
>> 16) & 0xf;
1945 tmp
= load_reg(s
, rd
);
1946 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1947 switch ((insn
>> 6) & 3) {
1949 tmp2
= tcg_const_i32(0xff);
1950 tmp3
= tcg_const_i32((insn
& 7) << 3);
1953 tmp2
= tcg_const_i32(0xffff);
1954 tmp3
= tcg_const_i32((insn
& 3) << 4);
1957 tmp2
= tcg_const_i32(0xffffffff);
1958 tmp3
= tcg_const_i32((insn
& 1) << 5);
1961 TCGV_UNUSED_I32(tmp2
);
1962 TCGV_UNUSED_I32(tmp3
);
1964 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1965 tcg_temp_free_i32(tmp3
);
1966 tcg_temp_free_i32(tmp2
);
1967 tcg_temp_free_i32(tmp
);
1968 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1969 gen_op_iwmmxt_set_mup();
1971 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1972 rd
= (insn
>> 12) & 0xf;
1973 wrd
= (insn
>> 16) & 0xf;
1974 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1976 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1977 tmp
= tcg_temp_new_i32();
1978 switch ((insn
>> 22) & 3) {
1980 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1981 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1983 tcg_gen_ext8s_i32(tmp
, tmp
);
1985 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1989 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1990 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1992 tcg_gen_ext16s_i32(tmp
, tmp
);
1994 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1998 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1999 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2002 store_reg(s
, rd
, tmp
);
2004 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2005 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2007 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2008 switch ((insn
>> 22) & 3) {
2010 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2013 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2016 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2019 tcg_gen_shli_i32(tmp
, tmp
, 28);
2021 tcg_temp_free_i32(tmp
);
2023 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2024 if (((insn
>> 6) & 3) == 3)
2026 rd
= (insn
>> 12) & 0xf;
2027 wrd
= (insn
>> 16) & 0xf;
2028 tmp
= load_reg(s
, rd
);
2029 switch ((insn
>> 6) & 3) {
2031 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2034 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2037 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2040 tcg_temp_free_i32(tmp
);
2041 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2042 gen_op_iwmmxt_set_mup();
2044 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2045 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2047 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2048 tmp2
= tcg_temp_new_i32();
2049 tcg_gen_mov_i32(tmp2
, tmp
);
2050 switch ((insn
>> 22) & 3) {
2052 for (i
= 0; i
< 7; i
++) {
2053 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2054 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2058 for (i
= 0; i
< 3; i
++) {
2059 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2060 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2064 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2065 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2069 tcg_temp_free_i32(tmp2
);
2070 tcg_temp_free_i32(tmp
);
2072 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2073 wrd
= (insn
>> 12) & 0xf;
2074 rd0
= (insn
>> 16) & 0xf;
2075 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2076 switch ((insn
>> 22) & 3) {
2078 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2081 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2084 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2089 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2090 gen_op_iwmmxt_set_mup();
2092 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2093 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2095 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2096 tmp2
= tcg_temp_new_i32();
2097 tcg_gen_mov_i32(tmp2
, tmp
);
2098 switch ((insn
>> 22) & 3) {
2100 for (i
= 0; i
< 7; i
++) {
2101 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2102 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2106 for (i
= 0; i
< 3; i
++) {
2107 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2108 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2112 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2113 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2117 tcg_temp_free_i32(tmp2
);
2118 tcg_temp_free_i32(tmp
);
2120 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2121 rd
= (insn
>> 12) & 0xf;
2122 rd0
= (insn
>> 16) & 0xf;
2123 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2125 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2126 tmp
= tcg_temp_new_i32();
2127 switch ((insn
>> 22) & 3) {
2129 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2132 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2135 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2138 store_reg(s
, rd
, tmp
);
2140 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2141 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2142 wrd
= (insn
>> 12) & 0xf;
2143 rd0
= (insn
>> 16) & 0xf;
2144 rd1
= (insn
>> 0) & 0xf;
2145 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2146 switch ((insn
>> 22) & 3) {
2148 if (insn
& (1 << 21))
2149 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2151 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2154 if (insn
& (1 << 21))
2155 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2157 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2160 if (insn
& (1 << 21))
2161 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2163 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2168 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2169 gen_op_iwmmxt_set_mup();
2170 gen_op_iwmmxt_set_cup();
2172 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2173 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2174 wrd
= (insn
>> 12) & 0xf;
2175 rd0
= (insn
>> 16) & 0xf;
2176 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2177 switch ((insn
>> 22) & 3) {
2179 if (insn
& (1 << 21))
2180 gen_op_iwmmxt_unpacklsb_M0();
2182 gen_op_iwmmxt_unpacklub_M0();
2185 if (insn
& (1 << 21))
2186 gen_op_iwmmxt_unpacklsw_M0();
2188 gen_op_iwmmxt_unpackluw_M0();
2191 if (insn
& (1 << 21))
2192 gen_op_iwmmxt_unpacklsl_M0();
2194 gen_op_iwmmxt_unpacklul_M0();
2199 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2200 gen_op_iwmmxt_set_mup();
2201 gen_op_iwmmxt_set_cup();
2203 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2204 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2205 wrd
= (insn
>> 12) & 0xf;
2206 rd0
= (insn
>> 16) & 0xf;
2207 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2208 switch ((insn
>> 22) & 3) {
2210 if (insn
& (1 << 21))
2211 gen_op_iwmmxt_unpackhsb_M0();
2213 gen_op_iwmmxt_unpackhub_M0();
2216 if (insn
& (1 << 21))
2217 gen_op_iwmmxt_unpackhsw_M0();
2219 gen_op_iwmmxt_unpackhuw_M0();
2222 if (insn
& (1 << 21))
2223 gen_op_iwmmxt_unpackhsl_M0();
2225 gen_op_iwmmxt_unpackhul_M0();
2230 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2231 gen_op_iwmmxt_set_mup();
2232 gen_op_iwmmxt_set_cup();
2234 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2235 case 0x214: case 0x614: case 0xa14: case 0xe14:
2236 if (((insn
>> 22) & 3) == 0)
2238 wrd
= (insn
>> 12) & 0xf;
2239 rd0
= (insn
>> 16) & 0xf;
2240 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2241 tmp
= tcg_temp_new_i32();
2242 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2243 tcg_temp_free_i32(tmp
);
2246 switch ((insn
>> 22) & 3) {
2248 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2251 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2254 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2257 tcg_temp_free_i32(tmp
);
2258 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2259 gen_op_iwmmxt_set_mup();
2260 gen_op_iwmmxt_set_cup();
2262 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2263 case 0x014: case 0x414: case 0x814: case 0xc14:
2264 if (((insn
>> 22) & 3) == 0)
2266 wrd
= (insn
>> 12) & 0xf;
2267 rd0
= (insn
>> 16) & 0xf;
2268 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2269 tmp
= tcg_temp_new_i32();
2270 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2271 tcg_temp_free_i32(tmp
);
2274 switch ((insn
>> 22) & 3) {
2276 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2279 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2282 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2285 tcg_temp_free_i32(tmp
);
2286 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2287 gen_op_iwmmxt_set_mup();
2288 gen_op_iwmmxt_set_cup();
2290 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2291 case 0x114: case 0x514: case 0x914: case 0xd14:
2292 if (((insn
>> 22) & 3) == 0)
2294 wrd
= (insn
>> 12) & 0xf;
2295 rd0
= (insn
>> 16) & 0xf;
2296 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2297 tmp
= tcg_temp_new_i32();
2298 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2299 tcg_temp_free_i32(tmp
);
2302 switch ((insn
>> 22) & 3) {
2304 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2307 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2310 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2313 tcg_temp_free_i32(tmp
);
2314 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2315 gen_op_iwmmxt_set_mup();
2316 gen_op_iwmmxt_set_cup();
2318 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2319 case 0x314: case 0x714: case 0xb14: case 0xf14:
2320 if (((insn
>> 22) & 3) == 0)
2322 wrd
= (insn
>> 12) & 0xf;
2323 rd0
= (insn
>> 16) & 0xf;
2324 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2325 tmp
= tcg_temp_new_i32();
2326 switch ((insn
>> 22) & 3) {
2328 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2329 tcg_temp_free_i32(tmp
);
2332 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2335 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2336 tcg_temp_free_i32(tmp
);
2339 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2342 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2343 tcg_temp_free_i32(tmp
);
2346 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2349 tcg_temp_free_i32(tmp
);
2350 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2351 gen_op_iwmmxt_set_mup();
2352 gen_op_iwmmxt_set_cup();
2354 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2355 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2356 wrd
= (insn
>> 12) & 0xf;
2357 rd0
= (insn
>> 16) & 0xf;
2358 rd1
= (insn
>> 0) & 0xf;
2359 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2360 switch ((insn
>> 22) & 3) {
2362 if (insn
& (1 << 21))
2363 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2365 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2368 if (insn
& (1 << 21))
2369 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2371 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2374 if (insn
& (1 << 21))
2375 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2377 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2382 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2383 gen_op_iwmmxt_set_mup();
2385 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2386 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2387 wrd
= (insn
>> 12) & 0xf;
2388 rd0
= (insn
>> 16) & 0xf;
2389 rd1
= (insn
>> 0) & 0xf;
2390 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2391 switch ((insn
>> 22) & 3) {
2393 if (insn
& (1 << 21))
2394 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2396 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2399 if (insn
& (1 << 21))
2400 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2402 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2405 if (insn
& (1 << 21))
2406 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2408 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2413 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2414 gen_op_iwmmxt_set_mup();
2416 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2417 case 0x402: case 0x502: case 0x602: case 0x702:
2418 wrd
= (insn
>> 12) & 0xf;
2419 rd0
= (insn
>> 16) & 0xf;
2420 rd1
= (insn
>> 0) & 0xf;
2421 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2422 tmp
= tcg_const_i32((insn
>> 20) & 3);
2423 iwmmxt_load_reg(cpu_V1
, rd1
);
2424 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2425 tcg_temp_free_i32(tmp
);
2426 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2427 gen_op_iwmmxt_set_mup();
2429 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2430 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2431 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2432 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2433 wrd
= (insn
>> 12) & 0xf;
2434 rd0
= (insn
>> 16) & 0xf;
2435 rd1
= (insn
>> 0) & 0xf;
2436 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2437 switch ((insn
>> 20) & 0xf) {
2439 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2442 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2445 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2448 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2451 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2454 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2457 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2460 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2463 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2468 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2469 gen_op_iwmmxt_set_mup();
2470 gen_op_iwmmxt_set_cup();
2472 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2473 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2474 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2475 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2476 wrd
= (insn
>> 12) & 0xf;
2477 rd0
= (insn
>> 16) & 0xf;
2478 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2479 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2480 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2481 tcg_temp_free_i32(tmp
);
2482 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2483 gen_op_iwmmxt_set_mup();
2484 gen_op_iwmmxt_set_cup();
2486 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2487 case 0x418: case 0x518: case 0x618: case 0x718:
2488 case 0x818: case 0x918: case 0xa18: case 0xb18:
2489 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2490 wrd
= (insn
>> 12) & 0xf;
2491 rd0
= (insn
>> 16) & 0xf;
2492 rd1
= (insn
>> 0) & 0xf;
2493 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2494 switch ((insn
>> 20) & 0xf) {
2496 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2499 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2502 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2505 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2508 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2511 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2514 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2517 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2520 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2525 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2526 gen_op_iwmmxt_set_mup();
2527 gen_op_iwmmxt_set_cup();
2529 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2530 case 0x408: case 0x508: case 0x608: case 0x708:
2531 case 0x808: case 0x908: case 0xa08: case 0xb08:
2532 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2533 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2535 wrd
= (insn
>> 12) & 0xf;
2536 rd0
= (insn
>> 16) & 0xf;
2537 rd1
= (insn
>> 0) & 0xf;
2538 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2539 switch ((insn
>> 22) & 3) {
2541 if (insn
& (1 << 21))
2542 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2544 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2547 if (insn
& (1 << 21))
2548 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2550 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2553 if (insn
& (1 << 21))
2554 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2556 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2559 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2560 gen_op_iwmmxt_set_mup();
2561 gen_op_iwmmxt_set_cup();
2563 case 0x201: case 0x203: case 0x205: case 0x207:
2564 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2565 case 0x211: case 0x213: case 0x215: case 0x217:
2566 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2567 wrd
= (insn
>> 5) & 0xf;
2568 rd0
= (insn
>> 12) & 0xf;
2569 rd1
= (insn
>> 0) & 0xf;
2570 if (rd0
== 0xf || rd1
== 0xf)
2572 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2573 tmp
= load_reg(s
, rd0
);
2574 tmp2
= load_reg(s
, rd1
);
2575 switch ((insn
>> 16) & 0xf) {
2576 case 0x0: /* TMIA */
2577 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2579 case 0x8: /* TMIAPH */
2580 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2582 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2583 if (insn
& (1 << 16))
2584 tcg_gen_shri_i32(tmp
, tmp
, 16);
2585 if (insn
& (1 << 17))
2586 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2587 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2590 tcg_temp_free_i32(tmp2
);
2591 tcg_temp_free_i32(tmp
);
2594 tcg_temp_free_i32(tmp2
);
2595 tcg_temp_free_i32(tmp
);
2596 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2597 gen_op_iwmmxt_set_mup();
2606 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2607 (ie. an undefined instruction). */
2608 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2610 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2613 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2614 /* Multiply with Internal Accumulate Format */
2615 rd0
= (insn
>> 12) & 0xf;
2617 acc
= (insn
>> 5) & 7;
2622 tmp
= load_reg(s
, rd0
);
2623 tmp2
= load_reg(s
, rd1
);
2624 switch ((insn
>> 16) & 0xf) {
2626 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2628 case 0x8: /* MIAPH */
2629 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2631 case 0xc: /* MIABB */
2632 case 0xd: /* MIABT */
2633 case 0xe: /* MIATB */
2634 case 0xf: /* MIATT */
2635 if (insn
& (1 << 16))
2636 tcg_gen_shri_i32(tmp
, tmp
, 16);
2637 if (insn
& (1 << 17))
2638 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2639 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2644 tcg_temp_free_i32(tmp2
);
2645 tcg_temp_free_i32(tmp
);
2647 gen_op_iwmmxt_movq_wRn_M0(acc
);
2651 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2652 /* Internal Accumulator Access Format */
2653 rdhi
= (insn
>> 16) & 0xf;
2654 rdlo
= (insn
>> 12) & 0xf;
2660 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2661 iwmmxt_load_reg(cpu_V0
, acc
);
2662 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2663 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2664 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2665 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2667 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2668 iwmmxt_store_reg(cpu_V0
, acc
);
2676 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2677 #define VFP_SREG(insn, bigbit, smallbit) \
2678 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2679 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2680 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2681 reg = (((insn) >> (bigbit)) & 0x0f) \
2682 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2684 if (insn & (1 << (smallbit))) \
2686 reg = ((insn) >> (bigbit)) & 0x0f; \
2689 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2690 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2691 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2692 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2693 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2694 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2696 /* Move between integer and VFP cores. */
2697 static TCGv_i32
gen_vfp_mrs(void)
2699 TCGv_i32 tmp
= tcg_temp_new_i32();
2700 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2704 static void gen_vfp_msr(TCGv_i32 tmp
)
2706 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2707 tcg_temp_free_i32(tmp
);
2710 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2712 TCGv_i32 tmp
= tcg_temp_new_i32();
2714 tcg_gen_shri_i32(var
, var
, shift
);
2715 tcg_gen_ext8u_i32(var
, var
);
2716 tcg_gen_shli_i32(tmp
, var
, 8);
2717 tcg_gen_or_i32(var
, var
, tmp
);
2718 tcg_gen_shli_i32(tmp
, var
, 16);
2719 tcg_gen_or_i32(var
, var
, tmp
);
2720 tcg_temp_free_i32(tmp
);
2723 static void gen_neon_dup_low16(TCGv_i32 var
)
2725 TCGv_i32 tmp
= tcg_temp_new_i32();
2726 tcg_gen_ext16u_i32(var
, var
);
2727 tcg_gen_shli_i32(tmp
, var
, 16);
2728 tcg_gen_or_i32(var
, var
, tmp
);
2729 tcg_temp_free_i32(tmp
);
2732 static void gen_neon_dup_high16(TCGv_i32 var
)
2734 TCGv_i32 tmp
= tcg_temp_new_i32();
2735 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2736 tcg_gen_shri_i32(tmp
, var
, 16);
2737 tcg_gen_or_i32(var
, var
, tmp
);
2738 tcg_temp_free_i32(tmp
);
2741 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2743 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2744 TCGv_i32 tmp
= tcg_temp_new_i32();
2747 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
2748 gen_neon_dup_u8(tmp
, 0);
2751 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
2752 gen_neon_dup_low16(tmp
);
2755 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
2757 default: /* Avoid compiler warnings. */
2763 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2766 uint32_t cc
= extract32(insn
, 20, 2);
2769 TCGv_i64 frn
, frm
, dest
;
2770 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2772 zero
= tcg_const_i64(0);
2774 frn
= tcg_temp_new_i64();
2775 frm
= tcg_temp_new_i64();
2776 dest
= tcg_temp_new_i64();
2778 zf
= tcg_temp_new_i64();
2779 nf
= tcg_temp_new_i64();
2780 vf
= tcg_temp_new_i64();
2782 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2783 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2784 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2786 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2787 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2790 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2794 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2797 case 2: /* ge: N == V -> N ^ V == 0 */
2798 tmp
= tcg_temp_new_i64();
2799 tcg_gen_xor_i64(tmp
, vf
, nf
);
2800 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2802 tcg_temp_free_i64(tmp
);
2804 case 3: /* gt: !Z && N == V */
2805 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2807 tmp
= tcg_temp_new_i64();
2808 tcg_gen_xor_i64(tmp
, vf
, nf
);
2809 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2811 tcg_temp_free_i64(tmp
);
2814 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2815 tcg_temp_free_i64(frn
);
2816 tcg_temp_free_i64(frm
);
2817 tcg_temp_free_i64(dest
);
2819 tcg_temp_free_i64(zf
);
2820 tcg_temp_free_i64(nf
);
2821 tcg_temp_free_i64(vf
);
2823 tcg_temp_free_i64(zero
);
2825 TCGv_i32 frn
, frm
, dest
;
2828 zero
= tcg_const_i32(0);
2830 frn
= tcg_temp_new_i32();
2831 frm
= tcg_temp_new_i32();
2832 dest
= tcg_temp_new_i32();
2833 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2834 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2837 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2841 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2844 case 2: /* ge: N == V -> N ^ V == 0 */
2845 tmp
= tcg_temp_new_i32();
2846 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2847 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2849 tcg_temp_free_i32(tmp
);
2851 case 3: /* gt: !Z && N == V */
2852 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2854 tmp
= tcg_temp_new_i32();
2855 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2856 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2858 tcg_temp_free_i32(tmp
);
2861 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2862 tcg_temp_free_i32(frn
);
2863 tcg_temp_free_i32(frm
);
2864 tcg_temp_free_i32(dest
);
2866 tcg_temp_free_i32(zero
);
2872 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2873 uint32_t rm
, uint32_t dp
)
2875 uint32_t vmin
= extract32(insn
, 6, 1);
2876 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2879 TCGv_i64 frn
, frm
, dest
;
2881 frn
= tcg_temp_new_i64();
2882 frm
= tcg_temp_new_i64();
2883 dest
= tcg_temp_new_i64();
2885 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2886 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2888 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2890 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2892 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2893 tcg_temp_free_i64(frn
);
2894 tcg_temp_free_i64(frm
);
2895 tcg_temp_free_i64(dest
);
2897 TCGv_i32 frn
, frm
, dest
;
2899 frn
= tcg_temp_new_i32();
2900 frm
= tcg_temp_new_i32();
2901 dest
= tcg_temp_new_i32();
2903 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2904 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2906 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2908 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2910 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2911 tcg_temp_free_i32(frn
);
2912 tcg_temp_free_i32(frm
);
2913 tcg_temp_free_i32(dest
);
2916 tcg_temp_free_ptr(fpst
);
2920 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2923 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2926 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2927 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2932 tcg_op
= tcg_temp_new_i64();
2933 tcg_res
= tcg_temp_new_i64();
2934 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2935 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2936 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2937 tcg_temp_free_i64(tcg_op
);
2938 tcg_temp_free_i64(tcg_res
);
2942 tcg_op
= tcg_temp_new_i32();
2943 tcg_res
= tcg_temp_new_i32();
2944 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2945 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2946 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2947 tcg_temp_free_i32(tcg_op
);
2948 tcg_temp_free_i32(tcg_res
);
2951 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2952 tcg_temp_free_i32(tcg_rmode
);
2954 tcg_temp_free_ptr(fpst
);
2958 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2961 bool is_signed
= extract32(insn
, 7, 1);
2962 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2963 TCGv_i32 tcg_rmode
, tcg_shift
;
2965 tcg_shift
= tcg_const_i32(0);
2967 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2968 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2971 TCGv_i64 tcg_double
, tcg_res
;
2973 /* Rd is encoded as a single precision register even when the source
2974 * is double precision.
2976 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2977 tcg_double
= tcg_temp_new_i64();
2978 tcg_res
= tcg_temp_new_i64();
2979 tcg_tmp
= tcg_temp_new_i32();
2980 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2982 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2984 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2986 tcg_gen_extrl_i64_i32(tcg_tmp
, tcg_res
);
2987 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2988 tcg_temp_free_i32(tcg_tmp
);
2989 tcg_temp_free_i64(tcg_res
);
2990 tcg_temp_free_i64(tcg_double
);
2992 TCGv_i32 tcg_single
, tcg_res
;
2993 tcg_single
= tcg_temp_new_i32();
2994 tcg_res
= tcg_temp_new_i32();
2995 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2997 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2999 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
3001 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
3002 tcg_temp_free_i32(tcg_res
);
3003 tcg_temp_free_i32(tcg_single
);
3006 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3007 tcg_temp_free_i32(tcg_rmode
);
3009 tcg_temp_free_i32(tcg_shift
);
3011 tcg_temp_free_ptr(fpst
);
3016 /* Table for converting the most common AArch32 encoding of
3017 * rounding mode to arm_fprounding order (which matches the
3018 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3020 static const uint8_t fp_decode_rm
[] = {
3027 static int disas_vfp_v8_insn(DisasContext
*s
, uint32_t insn
)
3029 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
3031 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3036 VFP_DREG_D(rd
, insn
);
3037 VFP_DREG_N(rn
, insn
);
3038 VFP_DREG_M(rm
, insn
);
3040 rd
= VFP_SREG_D(insn
);
3041 rn
= VFP_SREG_N(insn
);
3042 rm
= VFP_SREG_M(insn
);
3045 if ((insn
& 0x0f800e50) == 0x0e000a00) {
3046 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
3047 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
3048 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
3049 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
3050 /* VRINTA, VRINTN, VRINTP, VRINTM */
3051 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3052 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
3053 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
3054 /* VCVTA, VCVTN, VCVTP, VCVTM */
3055 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
3056 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
3061 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3062 (ie. an undefined instruction). */
3063 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
3065 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
3071 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
3075 /* FIXME: this access check should not take precedence over UNDEF
3076 * for invalid encodings; we will generate incorrect syndrome information
3077 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3079 if (s
->fp_excp_el
) {
3080 gen_exception_insn(s
, 4, EXCP_UDEF
,
3081 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
3085 if (!s
->vfp_enabled
) {
3086 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3087 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
3089 rn
= (insn
>> 16) & 0xf;
3090 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
&& rn
!= ARM_VFP_MVFR2
3091 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
) {
3096 if (extract32(insn
, 28, 4) == 0xf) {
3097 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3098 * only used in v8 and above.
3100 return disas_vfp_v8_insn(s
, insn
);
3103 dp
= ((insn
& 0xf00) == 0xb00);
3104 switch ((insn
>> 24) & 0xf) {
3106 if (insn
& (1 << 4)) {
3107 /* single register transfer */
3108 rd
= (insn
>> 12) & 0xf;
3113 VFP_DREG_N(rn
, insn
);
3116 if (insn
& 0x00c00060
3117 && !arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
3121 pass
= (insn
>> 21) & 1;
3122 if (insn
& (1 << 22)) {
3124 offset
= ((insn
>> 5) & 3) * 8;
3125 } else if (insn
& (1 << 5)) {
3127 offset
= (insn
& (1 << 6)) ? 16 : 0;
3132 if (insn
& ARM_CP_RW_BIT
) {
3134 tmp
= neon_load_reg(rn
, pass
);
3138 tcg_gen_shri_i32(tmp
, tmp
, offset
);
3139 if (insn
& (1 << 23))
3145 if (insn
& (1 << 23)) {
3147 tcg_gen_shri_i32(tmp
, tmp
, 16);
3153 tcg_gen_sari_i32(tmp
, tmp
, 16);
3162 store_reg(s
, rd
, tmp
);
3165 tmp
= load_reg(s
, rd
);
3166 if (insn
& (1 << 23)) {
3169 gen_neon_dup_u8(tmp
, 0);
3170 } else if (size
== 1) {
3171 gen_neon_dup_low16(tmp
);
3173 for (n
= 0; n
<= pass
* 2; n
++) {
3174 tmp2
= tcg_temp_new_i32();
3175 tcg_gen_mov_i32(tmp2
, tmp
);
3176 neon_store_reg(rn
, n
, tmp2
);
3178 neon_store_reg(rn
, n
, tmp
);
3183 tmp2
= neon_load_reg(rn
, pass
);
3184 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3185 tcg_temp_free_i32(tmp2
);
3188 tmp2
= neon_load_reg(rn
, pass
);
3189 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3190 tcg_temp_free_i32(tmp2
);
3195 neon_store_reg(rn
, pass
, tmp
);
3199 if ((insn
& 0x6f) != 0x00)
3201 rn
= VFP_SREG_N(insn
);
3202 if (insn
& ARM_CP_RW_BIT
) {
3204 if (insn
& (1 << 21)) {
3205 /* system register */
3210 /* VFP2 allows access to FSID from userspace.
3211 VFP3 restricts all id registers to privileged
3214 && arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3217 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3222 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3224 case ARM_VFP_FPINST
:
3225 case ARM_VFP_FPINST2
:
3226 /* Not present in VFP3. */
3228 || arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3231 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3235 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3236 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3238 tmp
= tcg_temp_new_i32();
3239 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3243 if (!arm_dc_feature(s
, ARM_FEATURE_V8
)) {
3250 || !arm_dc_feature(s
, ARM_FEATURE_MVFR
)) {
3253 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3259 gen_mov_F0_vreg(0, rn
);
3260 tmp
= gen_vfp_mrs();
3263 /* Set the 4 flag bits in the CPSR. */
3265 tcg_temp_free_i32(tmp
);
3267 store_reg(s
, rd
, tmp
);
3271 if (insn
& (1 << 21)) {
3273 /* system register */
3278 /* Writes are ignored. */
3281 tmp
= load_reg(s
, rd
);
3282 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3283 tcg_temp_free_i32(tmp
);
3289 /* TODO: VFP subarchitecture support.
3290 * For now, keep the EN bit only */
3291 tmp
= load_reg(s
, rd
);
3292 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3293 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3296 case ARM_VFP_FPINST
:
3297 case ARM_VFP_FPINST2
:
3301 tmp
= load_reg(s
, rd
);
3302 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3308 tmp
= load_reg(s
, rd
);
3310 gen_mov_vreg_F0(0, rn
);
3315 /* data processing */
3316 /* The opcode is in bits 23, 21, 20 and 6. */
3317 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3321 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3323 /* rn is register number */
3324 VFP_DREG_N(rn
, insn
);
3327 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18) ||
3328 ((rn
& 0x1e) == 0x6))) {
3329 /* Integer or single/half precision destination. */
3330 rd
= VFP_SREG_D(insn
);
3332 VFP_DREG_D(rd
, insn
);
3335 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3336 ((rn
& 0x1e) == 0x4))) {
3337 /* VCVT from int or half precision is always from S reg
3338 * regardless of dp bit. VCVT with immediate frac_bits
3339 * has same format as SREG_M.
3341 rm
= VFP_SREG_M(insn
);
3343 VFP_DREG_M(rm
, insn
);
3346 rn
= VFP_SREG_N(insn
);
3347 if (op
== 15 && rn
== 15) {
3348 /* Double precision destination. */
3349 VFP_DREG_D(rd
, insn
);
3351 rd
= VFP_SREG_D(insn
);
3353 /* NB that we implicitly rely on the encoding for the frac_bits
3354 * in VCVT of fixed to float being the same as that of an SREG_M
3356 rm
= VFP_SREG_M(insn
);
3359 veclen
= s
->vec_len
;
3360 if (op
== 15 && rn
> 3)
3363 /* Shut up compiler warnings. */
3374 /* Figure out what type of vector operation this is. */
3375 if ((rd
& bank_mask
) == 0) {
3380 delta_d
= (s
->vec_stride
>> 1) + 1;
3382 delta_d
= s
->vec_stride
+ 1;
3384 if ((rm
& bank_mask
) == 0) {
3385 /* mixed scalar/vector */
3394 /* Load the initial operands. */
3399 /* Integer source */
3400 gen_mov_F0_vreg(0, rm
);
3405 gen_mov_F0_vreg(dp
, rd
);
3406 gen_mov_F1_vreg(dp
, rm
);
3410 /* Compare with zero */
3411 gen_mov_F0_vreg(dp
, rd
);
3422 /* Source and destination the same. */
3423 gen_mov_F0_vreg(dp
, rd
);
3429 /* VCVTB, VCVTT: only present with the halfprec extension
3430 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3431 * (we choose to UNDEF)
3433 if ((dp
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) ||
3434 !arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
)) {
3437 if (!extract32(rn
, 1, 1)) {
3438 /* Half precision source. */
3439 gen_mov_F0_vreg(0, rm
);
3442 /* Otherwise fall through */
3444 /* One source operand. */
3445 gen_mov_F0_vreg(dp
, rm
);
3449 /* Two source operands. */
3450 gen_mov_F0_vreg(dp
, rn
);
3451 gen_mov_F1_vreg(dp
, rm
);
3455 /* Perform the calculation. */
3457 case 0: /* VMLA: fd + (fn * fm) */
3458 /* Note that order of inputs to the add matters for NaNs */
3460 gen_mov_F0_vreg(dp
, rd
);
3463 case 1: /* VMLS: fd + -(fn * fm) */
3466 gen_mov_F0_vreg(dp
, rd
);
3469 case 2: /* VNMLS: -fd + (fn * fm) */
3470 /* Note that it isn't valid to replace (-A + B) with (B - A)
3471 * or similar plausible looking simplifications
3472 * because this will give wrong results for NaNs.
3475 gen_mov_F0_vreg(dp
, rd
);
3479 case 3: /* VNMLA: -fd + -(fn * fm) */
3482 gen_mov_F0_vreg(dp
, rd
);
3486 case 4: /* mul: fn * fm */
3489 case 5: /* nmul: -(fn * fm) */
3493 case 6: /* add: fn + fm */
3496 case 7: /* sub: fn - fm */
3499 case 8: /* div: fn / fm */
3502 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3503 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3504 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3505 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3506 /* These are fused multiply-add, and must be done as one
3507 * floating point operation with no rounding between the
3508 * multiplication and addition steps.
3509 * NB that doing the negations here as separate steps is
3510 * correct : an input NaN should come out with its sign bit
3511 * flipped if it is a negated-input.
3513 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
3521 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3523 frd
= tcg_temp_new_i64();
3524 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3527 gen_helper_vfp_negd(frd
, frd
);
3529 fpst
= get_fpstatus_ptr(0);
3530 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3531 cpu_F1d
, frd
, fpst
);
3532 tcg_temp_free_ptr(fpst
);
3533 tcg_temp_free_i64(frd
);
3539 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3541 frd
= tcg_temp_new_i32();
3542 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3544 gen_helper_vfp_negs(frd
, frd
);
3546 fpst
= get_fpstatus_ptr(0);
3547 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3548 cpu_F1s
, frd
, fpst
);
3549 tcg_temp_free_ptr(fpst
);
3550 tcg_temp_free_i32(frd
);
3553 case 14: /* fconst */
3554 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3558 n
= (insn
<< 12) & 0x80000000;
3559 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3566 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3573 tcg_gen_movi_i32(cpu_F0s
, n
);
3576 case 15: /* extension space */
3590 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3591 tmp
= gen_vfp_mrs();
3592 tcg_gen_ext16u_i32(tmp
, tmp
);
3594 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3597 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3600 tcg_temp_free_i32(tmp
);
3602 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3603 tmp
= gen_vfp_mrs();
3604 tcg_gen_shri_i32(tmp
, tmp
, 16);
3606 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3609 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3612 tcg_temp_free_i32(tmp
);
3614 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3615 tmp
= tcg_temp_new_i32();
3617 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3620 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3623 gen_mov_F0_vreg(0, rd
);
3624 tmp2
= gen_vfp_mrs();
3625 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3626 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3627 tcg_temp_free_i32(tmp2
);
3630 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3631 tmp
= tcg_temp_new_i32();
3633 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3636 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3639 tcg_gen_shli_i32(tmp
, tmp
, 16);
3640 gen_mov_F0_vreg(0, rd
);
3641 tmp2
= gen_vfp_mrs();
3642 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3643 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3644 tcg_temp_free_i32(tmp2
);
3656 case 11: /* cmpez */
3660 case 12: /* vrintr */
3662 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3664 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3666 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3668 tcg_temp_free_ptr(fpst
);
3671 case 13: /* vrintz */
3673 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3675 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3676 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3678 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3680 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3682 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3683 tcg_temp_free_i32(tcg_rmode
);
3684 tcg_temp_free_ptr(fpst
);
3687 case 14: /* vrintx */
3689 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3691 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3693 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3695 tcg_temp_free_ptr(fpst
);
3698 case 15: /* single<->double conversion */
3700 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3702 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3704 case 16: /* fuito */
3705 gen_vfp_uito(dp
, 0);
3707 case 17: /* fsito */
3708 gen_vfp_sito(dp
, 0);
3710 case 20: /* fshto */
3711 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3714 gen_vfp_shto(dp
, 16 - rm
, 0);
3716 case 21: /* fslto */
3717 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3720 gen_vfp_slto(dp
, 32 - rm
, 0);
3722 case 22: /* fuhto */
3723 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3726 gen_vfp_uhto(dp
, 16 - rm
, 0);
3728 case 23: /* fulto */
3729 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3732 gen_vfp_ulto(dp
, 32 - rm
, 0);
3734 case 24: /* ftoui */
3735 gen_vfp_toui(dp
, 0);
3737 case 25: /* ftouiz */
3738 gen_vfp_touiz(dp
, 0);
3740 case 26: /* ftosi */
3741 gen_vfp_tosi(dp
, 0);
3743 case 27: /* ftosiz */
3744 gen_vfp_tosiz(dp
, 0);
3746 case 28: /* ftosh */
3747 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3750 gen_vfp_tosh(dp
, 16 - rm
, 0);
3752 case 29: /* ftosl */
3753 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3756 gen_vfp_tosl(dp
, 32 - rm
, 0);
3758 case 30: /* ftouh */
3759 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3762 gen_vfp_touh(dp
, 16 - rm
, 0);
3764 case 31: /* ftoul */
3765 if (!arm_dc_feature(s
, ARM_FEATURE_VFP3
)) {
3768 gen_vfp_toul(dp
, 32 - rm
, 0);
3770 default: /* undefined */
3774 default: /* undefined */
3778 /* Write back the result. */
3779 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3780 /* Comparison, do nothing. */
3781 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3782 (rn
& 0x1e) == 0x6)) {
3783 /* VCVT double to int: always integer result.
3784 * VCVT double to half precision is always a single
3787 gen_mov_vreg_F0(0, rd
);
3788 } else if (op
== 15 && rn
== 15) {
3790 gen_mov_vreg_F0(!dp
, rd
);
3792 gen_mov_vreg_F0(dp
, rd
);
3795 /* break out of the loop if we have finished */
3799 if (op
== 15 && delta_m
== 0) {
3800 /* single source one-many */
3802 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3804 gen_mov_vreg_F0(dp
, rd
);
3808 /* Setup the next operands. */
3810 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3814 /* One source operand. */
3815 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3817 gen_mov_F0_vreg(dp
, rm
);
3819 /* Two source operands. */
3820 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3822 gen_mov_F0_vreg(dp
, rn
);
3824 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3826 gen_mov_F1_vreg(dp
, rm
);
3834 if ((insn
& 0x03e00000) == 0x00400000) {
3835 /* two-register transfer */
3836 rn
= (insn
>> 16) & 0xf;
3837 rd
= (insn
>> 12) & 0xf;
3839 VFP_DREG_M(rm
, insn
);
3841 rm
= VFP_SREG_M(insn
);
3844 if (insn
& ARM_CP_RW_BIT
) {
3847 gen_mov_F0_vreg(0, rm
* 2);
3848 tmp
= gen_vfp_mrs();
3849 store_reg(s
, rd
, tmp
);
3850 gen_mov_F0_vreg(0, rm
* 2 + 1);
3851 tmp
= gen_vfp_mrs();
3852 store_reg(s
, rn
, tmp
);
3854 gen_mov_F0_vreg(0, rm
);
3855 tmp
= gen_vfp_mrs();
3856 store_reg(s
, rd
, tmp
);
3857 gen_mov_F0_vreg(0, rm
+ 1);
3858 tmp
= gen_vfp_mrs();
3859 store_reg(s
, rn
, tmp
);
3864 tmp
= load_reg(s
, rd
);
3866 gen_mov_vreg_F0(0, rm
* 2);
3867 tmp
= load_reg(s
, rn
);
3869 gen_mov_vreg_F0(0, rm
* 2 + 1);
3871 tmp
= load_reg(s
, rd
);
3873 gen_mov_vreg_F0(0, rm
);
3874 tmp
= load_reg(s
, rn
);
3876 gen_mov_vreg_F0(0, rm
+ 1);
3881 rn
= (insn
>> 16) & 0xf;
3883 VFP_DREG_D(rd
, insn
);
3885 rd
= VFP_SREG_D(insn
);
3886 if ((insn
& 0x01200000) == 0x01000000) {
3887 /* Single load/store */
3888 offset
= (insn
& 0xff) << 2;
3889 if ((insn
& (1 << 23)) == 0)
3891 if (s
->thumb
&& rn
== 15) {
3892 /* This is actually UNPREDICTABLE */
3893 addr
= tcg_temp_new_i32();
3894 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3896 addr
= load_reg(s
, rn
);
3898 tcg_gen_addi_i32(addr
, addr
, offset
);
3899 if (insn
& (1 << 20)) {
3900 gen_vfp_ld(s
, dp
, addr
);
3901 gen_mov_vreg_F0(dp
, rd
);
3903 gen_mov_F0_vreg(dp
, rd
);
3904 gen_vfp_st(s
, dp
, addr
);
3906 tcg_temp_free_i32(addr
);
3908 /* load/store multiple */
3909 int w
= insn
& (1 << 21);
3911 n
= (insn
>> 1) & 0x7f;
3915 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3916 /* P == U , W == 1 => UNDEF */
3919 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3920 /* UNPREDICTABLE cases for bad immediates: we choose to
3921 * UNDEF to avoid generating huge numbers of TCG ops
3925 if (rn
== 15 && w
) {
3926 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3930 if (s
->thumb
&& rn
== 15) {
3931 /* This is actually UNPREDICTABLE */
3932 addr
= tcg_temp_new_i32();
3933 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3935 addr
= load_reg(s
, rn
);
3937 if (insn
& (1 << 24)) /* pre-decrement */
3938 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3944 for (i
= 0; i
< n
; i
++) {
3945 if (insn
& ARM_CP_RW_BIT
) {
3947 gen_vfp_ld(s
, dp
, addr
);
3948 gen_mov_vreg_F0(dp
, rd
+ i
);
3951 gen_mov_F0_vreg(dp
, rd
+ i
);
3952 gen_vfp_st(s
, dp
, addr
);
3954 tcg_gen_addi_i32(addr
, addr
, offset
);
3958 if (insn
& (1 << 24))
3959 offset
= -offset
* n
;
3960 else if (dp
&& (insn
& 1))
3966 tcg_gen_addi_i32(addr
, addr
, offset
);
3967 store_reg(s
, rn
, addr
);
3969 tcg_temp_free_i32(addr
);
3975 /* Should never happen. */
3981 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3983 TranslationBlock
*tb
;
3986 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3988 gen_set_pc_im(s
, dest
);
3989 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3991 gen_set_pc_im(s
, dest
);
3996 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3998 if (unlikely(s
->singlestep_enabled
|| s
->ss_active
)) {
3999 /* An indirect jump so that we still trigger the debug exception. */
4004 gen_goto_tb(s
, 0, dest
);
4005 s
->is_jmp
= DISAS_TB_JUMP
;
4009 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
4012 tcg_gen_sari_i32(t0
, t0
, 16);
4016 tcg_gen_sari_i32(t1
, t1
, 16);
4019 tcg_gen_mul_i32(t0
, t0
, t1
);
4022 /* Return the mask of PSR bits set by a MSR instruction. */
4023 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
4028 if (flags
& (1 << 0))
4030 if (flags
& (1 << 1))
4032 if (flags
& (1 << 2))
4034 if (flags
& (1 << 3))
4037 /* Mask out undefined bits. */
4038 mask
&= ~CPSR_RESERVED
;
4039 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
4042 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
4043 mask
&= ~CPSR_Q
; /* V5TE in reality*/
4045 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
4046 mask
&= ~(CPSR_E
| CPSR_GE
);
4048 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
4051 /* Mask out execution state and reserved bits. */
4053 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
4055 /* Mask out privileged bits. */
4061 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4062 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
4066 /* ??? This is also undefined in system mode. */
4070 tmp
= load_cpu_field(spsr
);
4071 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
4072 tcg_gen_andi_i32(t0
, t0
, mask
);
4073 tcg_gen_or_i32(tmp
, tmp
, t0
);
4074 store_cpu_field(tmp
, spsr
);
4076 gen_set_cpsr(t0
, mask
);
4078 tcg_temp_free_i32(t0
);
4083 /* Returns nonzero if access to the PSR is not permitted. */
4084 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
4087 tmp
= tcg_temp_new_i32();
4088 tcg_gen_movi_i32(tmp
, val
);
4089 return gen_set_psr(s
, mask
, spsr
, tmp
);
4092 /* Generate an old-style exception return. Marks pc as dead. */
4093 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
4096 store_reg(s
, 15, pc
);
4097 tmp
= load_cpu_field(spsr
);
4098 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
4099 tcg_temp_free_i32(tmp
);
4100 s
->is_jmp
= DISAS_UPDATE
;
4103 /* Generate a v6 exception return. Marks both values as dead. */
4104 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
4106 gen_set_cpsr(cpsr
, CPSR_ERET_MASK
);
4107 tcg_temp_free_i32(cpsr
);
4108 store_reg(s
, 15, pc
);
4109 s
->is_jmp
= DISAS_UPDATE
;
4112 static void gen_nop_hint(DisasContext
*s
, int val
)
4116 gen_set_pc_im(s
, s
->pc
);
4117 s
->is_jmp
= DISAS_YIELD
;
4120 gen_set_pc_im(s
, s
->pc
);
4121 s
->is_jmp
= DISAS_WFI
;
4124 gen_set_pc_im(s
, s
->pc
);
4125 s
->is_jmp
= DISAS_WFE
;
4129 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4135 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4137 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4140 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
4141 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
4142 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
4147 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
4150 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
4151 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
4152 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
4157 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4158 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4159 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4160 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4161 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4163 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4164 switch ((size << 1) | u) { \
4166 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4169 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4172 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4175 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4178 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4181 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4183 default: return 1; \
4186 #define GEN_NEON_INTEGER_OP(name) do { \
4187 switch ((size << 1) | u) { \
4189 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4192 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4195 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4198 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4201 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4204 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4206 default: return 1; \
4209 static TCGv_i32
neon_load_scratch(int scratch
)
4211 TCGv_i32 tmp
= tcg_temp_new_i32();
4212 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4216 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4218 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4219 tcg_temp_free_i32(var
);
4222 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4226 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4228 gen_neon_dup_high16(tmp
);
4230 gen_neon_dup_low16(tmp
);
4233 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4238 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4241 if (!q
&& size
== 2) {
4244 tmp
= tcg_const_i32(rd
);
4245 tmp2
= tcg_const_i32(rm
);
4249 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4252 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4255 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4263 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4266 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4272 tcg_temp_free_i32(tmp
);
4273 tcg_temp_free_i32(tmp2
);
4277 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4280 if (!q
&& size
== 2) {
4283 tmp
= tcg_const_i32(rd
);
4284 tmp2
= tcg_const_i32(rm
);
4288 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4291 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4294 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4302 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4305 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4311 tcg_temp_free_i32(tmp
);
4312 tcg_temp_free_i32(tmp2
);
4316 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4320 rd
= tcg_temp_new_i32();
4321 tmp
= tcg_temp_new_i32();
4323 tcg_gen_shli_i32(rd
, t0
, 8);
4324 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4325 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4326 tcg_gen_or_i32(rd
, rd
, tmp
);
4328 tcg_gen_shri_i32(t1
, t1
, 8);
4329 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4330 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4331 tcg_gen_or_i32(t1
, t1
, tmp
);
4332 tcg_gen_mov_i32(t0
, rd
);
4334 tcg_temp_free_i32(tmp
);
4335 tcg_temp_free_i32(rd
);
4338 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4342 rd
= tcg_temp_new_i32();
4343 tmp
= tcg_temp_new_i32();
4345 tcg_gen_shli_i32(rd
, t0
, 16);
4346 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4347 tcg_gen_or_i32(rd
, rd
, tmp
);
4348 tcg_gen_shri_i32(t1
, t1
, 16);
4349 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4350 tcg_gen_or_i32(t1
, t1
, tmp
);
4351 tcg_gen_mov_i32(t0
, rd
);
4353 tcg_temp_free_i32(tmp
);
4354 tcg_temp_free_i32(rd
);
4362 } neon_ls_element_type
[11] = {
4376 /* Translate a NEON load/store element instruction. Return nonzero if the
4377 instruction is invalid. */
4378 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
4397 /* FIXME: this access check should not take precedence over UNDEF
4398 * for invalid encodings; we will generate incorrect syndrome information
4399 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4401 if (s
->fp_excp_el
) {
4402 gen_exception_insn(s
, 4, EXCP_UDEF
,
4403 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
4407 if (!s
->vfp_enabled
)
4409 VFP_DREG_D(rd
, insn
);
4410 rn
= (insn
>> 16) & 0xf;
4412 load
= (insn
& (1 << 21)) != 0;
4413 if ((insn
& (1 << 23)) == 0) {
4414 /* Load store all elements. */
4415 op
= (insn
>> 8) & 0xf;
4416 size
= (insn
>> 6) & 3;
4419 /* Catch UNDEF cases for bad values of align field */
4422 if (((insn
>> 5) & 1) == 1) {
4427 if (((insn
>> 4) & 3) == 3) {
4434 nregs
= neon_ls_element_type
[op
].nregs
;
4435 interleave
= neon_ls_element_type
[op
].interleave
;
4436 spacing
= neon_ls_element_type
[op
].spacing
;
4437 if (size
== 3 && (interleave
| spacing
) != 1)
4439 addr
= tcg_temp_new_i32();
4440 load_reg_var(s
, addr
, rn
);
4441 stride
= (1 << size
) * interleave
;
4442 for (reg
= 0; reg
< nregs
; reg
++) {
4443 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4444 load_reg_var(s
, addr
, rn
);
4445 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4446 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4447 load_reg_var(s
, addr
, rn
);
4448 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4451 tmp64
= tcg_temp_new_i64();
4453 gen_aa32_ld64(tmp64
, addr
, get_mem_index(s
));
4454 neon_store_reg64(tmp64
, rd
);
4456 neon_load_reg64(tmp64
, rd
);
4457 gen_aa32_st64(tmp64
, addr
, get_mem_index(s
));
4459 tcg_temp_free_i64(tmp64
);
4460 tcg_gen_addi_i32(addr
, addr
, stride
);
4462 for (pass
= 0; pass
< 2; pass
++) {
4465 tmp
= tcg_temp_new_i32();
4466 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4467 neon_store_reg(rd
, pass
, tmp
);
4469 tmp
= neon_load_reg(rd
, pass
);
4470 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4471 tcg_temp_free_i32(tmp
);
4473 tcg_gen_addi_i32(addr
, addr
, stride
);
4474 } else if (size
== 1) {
4476 tmp
= tcg_temp_new_i32();
4477 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4478 tcg_gen_addi_i32(addr
, addr
, stride
);
4479 tmp2
= tcg_temp_new_i32();
4480 gen_aa32_ld16u(tmp2
, addr
, get_mem_index(s
));
4481 tcg_gen_addi_i32(addr
, addr
, stride
);
4482 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4483 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4484 tcg_temp_free_i32(tmp2
);
4485 neon_store_reg(rd
, pass
, tmp
);
4487 tmp
= neon_load_reg(rd
, pass
);
4488 tmp2
= tcg_temp_new_i32();
4489 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4490 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4491 tcg_temp_free_i32(tmp
);
4492 tcg_gen_addi_i32(addr
, addr
, stride
);
4493 gen_aa32_st16(tmp2
, addr
, get_mem_index(s
));
4494 tcg_temp_free_i32(tmp2
);
4495 tcg_gen_addi_i32(addr
, addr
, stride
);
4497 } else /* size == 0 */ {
4499 TCGV_UNUSED_I32(tmp2
);
4500 for (n
= 0; n
< 4; n
++) {
4501 tmp
= tcg_temp_new_i32();
4502 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4503 tcg_gen_addi_i32(addr
, addr
, stride
);
4507 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4508 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4509 tcg_temp_free_i32(tmp
);
4512 neon_store_reg(rd
, pass
, tmp2
);
4514 tmp2
= neon_load_reg(rd
, pass
);
4515 for (n
= 0; n
< 4; n
++) {
4516 tmp
= tcg_temp_new_i32();
4518 tcg_gen_mov_i32(tmp
, tmp2
);
4520 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4522 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4523 tcg_temp_free_i32(tmp
);
4524 tcg_gen_addi_i32(addr
, addr
, stride
);
4526 tcg_temp_free_i32(tmp2
);
4533 tcg_temp_free_i32(addr
);
4536 size
= (insn
>> 10) & 3;
4538 /* Load single element to all lanes. */
4539 int a
= (insn
>> 4) & 1;
4543 size
= (insn
>> 6) & 3;
4544 nregs
= ((insn
>> 8) & 3) + 1;
4547 if (nregs
!= 4 || a
== 0) {
4550 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4553 if (nregs
== 1 && a
== 1 && size
== 0) {
4556 if (nregs
== 3 && a
== 1) {
4559 addr
= tcg_temp_new_i32();
4560 load_reg_var(s
, addr
, rn
);
4562 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4563 tmp
= gen_load_and_replicate(s
, addr
, size
);
4564 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4565 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4566 if (insn
& (1 << 5)) {
4567 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4568 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4570 tcg_temp_free_i32(tmp
);
4572 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4573 stride
= (insn
& (1 << 5)) ? 2 : 1;
4574 for (reg
= 0; reg
< nregs
; reg
++) {
4575 tmp
= gen_load_and_replicate(s
, addr
, size
);
4576 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4577 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4578 tcg_temp_free_i32(tmp
);
4579 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4583 tcg_temp_free_i32(addr
);
4584 stride
= (1 << size
) * nregs
;
4586 /* Single element. */
4587 int idx
= (insn
>> 4) & 0xf;
4588 pass
= (insn
>> 7) & 1;
4591 shift
= ((insn
>> 5) & 3) * 8;
4595 shift
= ((insn
>> 6) & 1) * 16;
4596 stride
= (insn
& (1 << 5)) ? 2 : 1;
4600 stride
= (insn
& (1 << 6)) ? 2 : 1;
4605 nregs
= ((insn
>> 8) & 3) + 1;
4606 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4609 if (((idx
& (1 << size
)) != 0) ||
4610 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4615 if ((idx
& 1) != 0) {
4620 if (size
== 2 && (idx
& 2) != 0) {
4625 if ((size
== 2) && ((idx
& 3) == 3)) {
4632 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4633 /* Attempts to write off the end of the register file
4634 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4635 * the neon_load_reg() would write off the end of the array.
4639 addr
= tcg_temp_new_i32();
4640 load_reg_var(s
, addr
, rn
);
4641 for (reg
= 0; reg
< nregs
; reg
++) {
4643 tmp
= tcg_temp_new_i32();
4646 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
4649 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
4652 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
4654 default: /* Avoid compiler warnings. */
4658 tmp2
= neon_load_reg(rd
, pass
);
4659 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4660 shift
, size
? 16 : 8);
4661 tcg_temp_free_i32(tmp2
);
4663 neon_store_reg(rd
, pass
, tmp
);
4664 } else { /* Store */
4665 tmp
= neon_load_reg(rd
, pass
);
4667 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4670 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
4673 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
4676 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
4679 tcg_temp_free_i32(tmp
);
4682 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4684 tcg_temp_free_i32(addr
);
4685 stride
= nregs
* (1 << size
);
4691 base
= load_reg(s
, rn
);
4693 tcg_gen_addi_i32(base
, base
, stride
);
4696 index
= load_reg(s
, rm
);
4697 tcg_gen_add_i32(base
, base
, index
);
4698 tcg_temp_free_i32(index
);
4700 store_reg(s
, rn
, base
);
4705 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4706 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4708 tcg_gen_and_i32(t
, t
, c
);
4709 tcg_gen_andc_i32(f
, f
, c
);
4710 tcg_gen_or_i32(dest
, t
, f
);
4713 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4716 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4717 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4718 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
4723 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4726 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4727 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4728 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4733 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4736 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4737 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4738 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4743 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4746 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4747 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4748 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4753 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4759 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4760 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4765 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4766 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4773 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4774 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4779 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4780 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4787 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4791 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4792 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4793 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4798 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4799 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4800 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4804 tcg_temp_free_i32(src
);
4807 static inline void gen_neon_addl(int size
)
4810 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4811 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4812 case 2: tcg_gen_add_i64(CPU_V001
); break;
4817 static inline void gen_neon_subl(int size
)
4820 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4821 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4822 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4827 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4830 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4831 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4833 tcg_gen_neg_i64(var
, var
);
4839 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4842 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4843 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4848 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4853 switch ((size
<< 1) | u
) {
4854 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4855 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4856 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4857 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4859 tmp
= gen_muls_i64_i32(a
, b
);
4860 tcg_gen_mov_i64(dest
, tmp
);
4861 tcg_temp_free_i64(tmp
);
4864 tmp
= gen_mulu_i64_i32(a
, b
);
4865 tcg_gen_mov_i64(dest
, tmp
);
4866 tcg_temp_free_i64(tmp
);
4871 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4872 Don't forget to clean them now. */
4874 tcg_temp_free_i32(a
);
4875 tcg_temp_free_i32(b
);
4879 static void gen_neon_narrow_op(int op
, int u
, int size
,
4880 TCGv_i32 dest
, TCGv_i64 src
)
4884 gen_neon_unarrow_sats(size
, dest
, src
);
4886 gen_neon_narrow(size
, dest
, src
);
4890 gen_neon_narrow_satu(size
, dest
, src
);
4892 gen_neon_narrow_sats(size
, dest
, src
);
4897 /* Symbolic constants for op fields for Neon 3-register same-length.
4898 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4901 #define NEON_3R_VHADD 0
4902 #define NEON_3R_VQADD 1
4903 #define NEON_3R_VRHADD 2
4904 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4905 #define NEON_3R_VHSUB 4
4906 #define NEON_3R_VQSUB 5
4907 #define NEON_3R_VCGT 6
4908 #define NEON_3R_VCGE 7
4909 #define NEON_3R_VSHL 8
4910 #define NEON_3R_VQSHL 9
4911 #define NEON_3R_VRSHL 10
4912 #define NEON_3R_VQRSHL 11
4913 #define NEON_3R_VMAX 12
4914 #define NEON_3R_VMIN 13
4915 #define NEON_3R_VABD 14
4916 #define NEON_3R_VABA 15
4917 #define NEON_3R_VADD_VSUB 16
4918 #define NEON_3R_VTST_VCEQ 17
4919 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4920 #define NEON_3R_VMUL 19
4921 #define NEON_3R_VPMAX 20
4922 #define NEON_3R_VPMIN 21
4923 #define NEON_3R_VQDMULH_VQRDMULH 22
4924 #define NEON_3R_VPADD 23
4925 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4926 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4927 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4928 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4929 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4930 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4931 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4932 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4934 static const uint8_t neon_3r_sizes
[] = {
4935 [NEON_3R_VHADD
] = 0x7,
4936 [NEON_3R_VQADD
] = 0xf,
4937 [NEON_3R_VRHADD
] = 0x7,
4938 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4939 [NEON_3R_VHSUB
] = 0x7,
4940 [NEON_3R_VQSUB
] = 0xf,
4941 [NEON_3R_VCGT
] = 0x7,
4942 [NEON_3R_VCGE
] = 0x7,
4943 [NEON_3R_VSHL
] = 0xf,
4944 [NEON_3R_VQSHL
] = 0xf,
4945 [NEON_3R_VRSHL
] = 0xf,
4946 [NEON_3R_VQRSHL
] = 0xf,
4947 [NEON_3R_VMAX
] = 0x7,
4948 [NEON_3R_VMIN
] = 0x7,
4949 [NEON_3R_VABD
] = 0x7,
4950 [NEON_3R_VABA
] = 0x7,
4951 [NEON_3R_VADD_VSUB
] = 0xf,
4952 [NEON_3R_VTST_VCEQ
] = 0x7,
4953 [NEON_3R_VML
] = 0x7,
4954 [NEON_3R_VMUL
] = 0x7,
4955 [NEON_3R_VPMAX
] = 0x7,
4956 [NEON_3R_VPMIN
] = 0x7,
4957 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4958 [NEON_3R_VPADD
] = 0x7,
4959 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4960 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4961 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4962 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4963 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4964 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4965 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4966 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4969 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4970 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4973 #define NEON_2RM_VREV64 0
4974 #define NEON_2RM_VREV32 1
4975 #define NEON_2RM_VREV16 2
4976 #define NEON_2RM_VPADDL 4
4977 #define NEON_2RM_VPADDL_U 5
4978 #define NEON_2RM_AESE 6 /* Includes AESD */
4979 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4980 #define NEON_2RM_VCLS 8
4981 #define NEON_2RM_VCLZ 9
4982 #define NEON_2RM_VCNT 10
4983 #define NEON_2RM_VMVN 11
4984 #define NEON_2RM_VPADAL 12
4985 #define NEON_2RM_VPADAL_U 13
4986 #define NEON_2RM_VQABS 14
4987 #define NEON_2RM_VQNEG 15
4988 #define NEON_2RM_VCGT0 16
4989 #define NEON_2RM_VCGE0 17
4990 #define NEON_2RM_VCEQ0 18
4991 #define NEON_2RM_VCLE0 19
4992 #define NEON_2RM_VCLT0 20
4993 #define NEON_2RM_SHA1H 21
4994 #define NEON_2RM_VABS 22
4995 #define NEON_2RM_VNEG 23
4996 #define NEON_2RM_VCGT0_F 24
4997 #define NEON_2RM_VCGE0_F 25
4998 #define NEON_2RM_VCEQ0_F 26
4999 #define NEON_2RM_VCLE0_F 27
5000 #define NEON_2RM_VCLT0_F 28
5001 #define NEON_2RM_VABS_F 30
5002 #define NEON_2RM_VNEG_F 31
5003 #define NEON_2RM_VSWP 32
5004 #define NEON_2RM_VTRN 33
5005 #define NEON_2RM_VUZP 34
5006 #define NEON_2RM_VZIP 35
5007 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5008 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5009 #define NEON_2RM_VSHLL 38
5010 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5011 #define NEON_2RM_VRINTN 40
5012 #define NEON_2RM_VRINTX 41
5013 #define NEON_2RM_VRINTA 42
5014 #define NEON_2RM_VRINTZ 43
5015 #define NEON_2RM_VCVT_F16_F32 44
5016 #define NEON_2RM_VRINTM 45
5017 #define NEON_2RM_VCVT_F32_F16 46
5018 #define NEON_2RM_VRINTP 47
5019 #define NEON_2RM_VCVTAU 48
5020 #define NEON_2RM_VCVTAS 49
5021 #define NEON_2RM_VCVTNU 50
5022 #define NEON_2RM_VCVTNS 51
5023 #define NEON_2RM_VCVTPU 52
5024 #define NEON_2RM_VCVTPS 53
5025 #define NEON_2RM_VCVTMU 54
5026 #define NEON_2RM_VCVTMS 55
5027 #define NEON_2RM_VRECPE 56
5028 #define NEON_2RM_VRSQRTE 57
5029 #define NEON_2RM_VRECPE_F 58
5030 #define NEON_2RM_VRSQRTE_F 59
5031 #define NEON_2RM_VCVT_FS 60
5032 #define NEON_2RM_VCVT_FU 61
5033 #define NEON_2RM_VCVT_SF 62
5034 #define NEON_2RM_VCVT_UF 63
5036 static int neon_2rm_is_float_op(int op
)
5038 /* Return true if this neon 2reg-misc op is float-to-float */
5039 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
5040 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
5041 op
== NEON_2RM_VRINTM
||
5042 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
5043 op
>= NEON_2RM_VRECPE_F
);
5046 /* Each entry in this array has bit n set if the insn allows
5047 * size value n (otherwise it will UNDEF). Since unallocated
5048 * op values will have no bits set they always UNDEF.
5050 static const uint8_t neon_2rm_sizes
[] = {
5051 [NEON_2RM_VREV64
] = 0x7,
5052 [NEON_2RM_VREV32
] = 0x3,
5053 [NEON_2RM_VREV16
] = 0x1,
5054 [NEON_2RM_VPADDL
] = 0x7,
5055 [NEON_2RM_VPADDL_U
] = 0x7,
5056 [NEON_2RM_AESE
] = 0x1,
5057 [NEON_2RM_AESMC
] = 0x1,
5058 [NEON_2RM_VCLS
] = 0x7,
5059 [NEON_2RM_VCLZ
] = 0x7,
5060 [NEON_2RM_VCNT
] = 0x1,
5061 [NEON_2RM_VMVN
] = 0x1,
5062 [NEON_2RM_VPADAL
] = 0x7,
5063 [NEON_2RM_VPADAL_U
] = 0x7,
5064 [NEON_2RM_VQABS
] = 0x7,
5065 [NEON_2RM_VQNEG
] = 0x7,
5066 [NEON_2RM_VCGT0
] = 0x7,
5067 [NEON_2RM_VCGE0
] = 0x7,
5068 [NEON_2RM_VCEQ0
] = 0x7,
5069 [NEON_2RM_VCLE0
] = 0x7,
5070 [NEON_2RM_VCLT0
] = 0x7,
5071 [NEON_2RM_SHA1H
] = 0x4,
5072 [NEON_2RM_VABS
] = 0x7,
5073 [NEON_2RM_VNEG
] = 0x7,
5074 [NEON_2RM_VCGT0_F
] = 0x4,
5075 [NEON_2RM_VCGE0_F
] = 0x4,
5076 [NEON_2RM_VCEQ0_F
] = 0x4,
5077 [NEON_2RM_VCLE0_F
] = 0x4,
5078 [NEON_2RM_VCLT0_F
] = 0x4,
5079 [NEON_2RM_VABS_F
] = 0x4,
5080 [NEON_2RM_VNEG_F
] = 0x4,
5081 [NEON_2RM_VSWP
] = 0x1,
5082 [NEON_2RM_VTRN
] = 0x7,
5083 [NEON_2RM_VUZP
] = 0x7,
5084 [NEON_2RM_VZIP
] = 0x7,
5085 [NEON_2RM_VMOVN
] = 0x7,
5086 [NEON_2RM_VQMOVN
] = 0x7,
5087 [NEON_2RM_VSHLL
] = 0x7,
5088 [NEON_2RM_SHA1SU1
] = 0x4,
5089 [NEON_2RM_VRINTN
] = 0x4,
5090 [NEON_2RM_VRINTX
] = 0x4,
5091 [NEON_2RM_VRINTA
] = 0x4,
5092 [NEON_2RM_VRINTZ
] = 0x4,
5093 [NEON_2RM_VCVT_F16_F32
] = 0x2,
5094 [NEON_2RM_VRINTM
] = 0x4,
5095 [NEON_2RM_VCVT_F32_F16
] = 0x2,
5096 [NEON_2RM_VRINTP
] = 0x4,
5097 [NEON_2RM_VCVTAU
] = 0x4,
5098 [NEON_2RM_VCVTAS
] = 0x4,
5099 [NEON_2RM_VCVTNU
] = 0x4,
5100 [NEON_2RM_VCVTNS
] = 0x4,
5101 [NEON_2RM_VCVTPU
] = 0x4,
5102 [NEON_2RM_VCVTPS
] = 0x4,
5103 [NEON_2RM_VCVTMU
] = 0x4,
5104 [NEON_2RM_VCVTMS
] = 0x4,
5105 [NEON_2RM_VRECPE
] = 0x4,
5106 [NEON_2RM_VRSQRTE
] = 0x4,
5107 [NEON_2RM_VRECPE_F
] = 0x4,
5108 [NEON_2RM_VRSQRTE_F
] = 0x4,
5109 [NEON_2RM_VCVT_FS
] = 0x4,
5110 [NEON_2RM_VCVT_FU
] = 0x4,
5111 [NEON_2RM_VCVT_SF
] = 0x4,
5112 [NEON_2RM_VCVT_UF
] = 0x4,
5115 /* Translate a NEON data processing instruction. Return nonzero if the
5116 instruction is invalid.
5117 We process data in a mixture of 32-bit and 64-bit chunks.
5118 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5120 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
5132 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
5135 /* FIXME: this access check should not take precedence over UNDEF
5136 * for invalid encodings; we will generate incorrect syndrome information
5137 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5139 if (s
->fp_excp_el
) {
5140 gen_exception_insn(s
, 4, EXCP_UDEF
,
5141 syn_fp_access_trap(1, 0xe, s
->thumb
), s
->fp_excp_el
);
5145 if (!s
->vfp_enabled
)
5147 q
= (insn
& (1 << 6)) != 0;
5148 u
= (insn
>> 24) & 1;
5149 VFP_DREG_D(rd
, insn
);
5150 VFP_DREG_N(rn
, insn
);
5151 VFP_DREG_M(rm
, insn
);
5152 size
= (insn
>> 20) & 3;
5153 if ((insn
& (1 << 23)) == 0) {
5154 /* Three register same length. */
5155 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
5156 /* Catch invalid op and bad size combinations: UNDEF */
5157 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
5160 /* All insns of this form UNDEF for either this condition or the
5161 * superset of cases "Q==1"; we catch the latter later.
5163 if (q
&& ((rd
| rn
| rm
) & 1)) {
5167 * The SHA-1/SHA-256 3-register instructions require special treatment
5168 * here, as their size field is overloaded as an op type selector, and
5169 * they all consume their input in a single pass.
5171 if (op
== NEON_3R_SHA
) {
5175 if (!u
) { /* SHA-1 */
5176 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
5179 tmp
= tcg_const_i32(rd
);
5180 tmp2
= tcg_const_i32(rn
);
5181 tmp3
= tcg_const_i32(rm
);
5182 tmp4
= tcg_const_i32(size
);
5183 gen_helper_crypto_sha1_3reg(cpu_env
, tmp
, tmp2
, tmp3
, tmp4
);
5184 tcg_temp_free_i32(tmp4
);
5185 } else { /* SHA-256 */
5186 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
) || size
== 3) {
5189 tmp
= tcg_const_i32(rd
);
5190 tmp2
= tcg_const_i32(rn
);
5191 tmp3
= tcg_const_i32(rm
);
5194 gen_helper_crypto_sha256h(cpu_env
, tmp
, tmp2
, tmp3
);
5197 gen_helper_crypto_sha256h2(cpu_env
, tmp
, tmp2
, tmp3
);
5200 gen_helper_crypto_sha256su1(cpu_env
, tmp
, tmp2
, tmp3
);
5204 tcg_temp_free_i32(tmp
);
5205 tcg_temp_free_i32(tmp2
);
5206 tcg_temp_free_i32(tmp3
);
5209 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
5210 /* 64-bit element instructions. */
5211 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5212 neon_load_reg64(cpu_V0
, rn
+ pass
);
5213 neon_load_reg64(cpu_V1
, rm
+ pass
);
5217 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
5220 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
5226 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
5229 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
5235 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5237 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5242 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5245 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5251 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5253 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5256 case NEON_3R_VQRSHL
:
5258 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5261 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5265 case NEON_3R_VADD_VSUB
:
5267 tcg_gen_sub_i64(CPU_V001
);
5269 tcg_gen_add_i64(CPU_V001
);
5275 neon_store_reg64(cpu_V0
, rd
+ pass
);
5284 case NEON_3R_VQRSHL
:
5287 /* Shift instruction operands are reversed. */
5302 case NEON_3R_FLOAT_ARITH
:
5303 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5305 case NEON_3R_FLOAT_MINMAX
:
5306 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5308 case NEON_3R_FLOAT_CMP
:
5310 /* no encoding for U=0 C=1x */
5314 case NEON_3R_FLOAT_ACMP
:
5319 case NEON_3R_FLOAT_MISC
:
5320 /* VMAXNM/VMINNM in ARMv8 */
5321 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5326 if (u
&& (size
!= 0)) {
5327 /* UNDEF on invalid size for polynomial subcase */
5332 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
) || u
) {
5340 if (pairwise
&& q
) {
5341 /* All the pairwise insns UNDEF if Q is set */
5345 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5350 tmp
= neon_load_reg(rn
, 0);
5351 tmp2
= neon_load_reg(rn
, 1);
5353 tmp
= neon_load_reg(rm
, 0);
5354 tmp2
= neon_load_reg(rm
, 1);
5358 tmp
= neon_load_reg(rn
, pass
);
5359 tmp2
= neon_load_reg(rm
, pass
);
5363 GEN_NEON_INTEGER_OP(hadd
);
5366 GEN_NEON_INTEGER_OP_ENV(qadd
);
5368 case NEON_3R_VRHADD
:
5369 GEN_NEON_INTEGER_OP(rhadd
);
5371 case NEON_3R_LOGIC
: /* Logic ops. */
5372 switch ((u
<< 2) | size
) {
5374 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5377 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5380 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5383 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5386 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5389 tmp3
= neon_load_reg(rd
, pass
);
5390 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5391 tcg_temp_free_i32(tmp3
);
5394 tmp3
= neon_load_reg(rd
, pass
);
5395 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5396 tcg_temp_free_i32(tmp3
);
5399 tmp3
= neon_load_reg(rd
, pass
);
5400 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5401 tcg_temp_free_i32(tmp3
);
5406 GEN_NEON_INTEGER_OP(hsub
);
5409 GEN_NEON_INTEGER_OP_ENV(qsub
);
5412 GEN_NEON_INTEGER_OP(cgt
);
5415 GEN_NEON_INTEGER_OP(cge
);
5418 GEN_NEON_INTEGER_OP(shl
);
5421 GEN_NEON_INTEGER_OP_ENV(qshl
);
5424 GEN_NEON_INTEGER_OP(rshl
);
5426 case NEON_3R_VQRSHL
:
5427 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5430 GEN_NEON_INTEGER_OP(max
);
5433 GEN_NEON_INTEGER_OP(min
);
5436 GEN_NEON_INTEGER_OP(abd
);
5439 GEN_NEON_INTEGER_OP(abd
);
5440 tcg_temp_free_i32(tmp2
);
5441 tmp2
= neon_load_reg(rd
, pass
);
5442 gen_neon_add(size
, tmp
, tmp2
);
5444 case NEON_3R_VADD_VSUB
:
5445 if (!u
) { /* VADD */
5446 gen_neon_add(size
, tmp
, tmp2
);
5449 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5450 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5451 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5456 case NEON_3R_VTST_VCEQ
:
5457 if (!u
) { /* VTST */
5459 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5460 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5461 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5466 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5467 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5468 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5473 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5475 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5476 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5477 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5480 tcg_temp_free_i32(tmp2
);
5481 tmp2
= neon_load_reg(rd
, pass
);
5483 gen_neon_rsb(size
, tmp
, tmp2
);
5485 gen_neon_add(size
, tmp
, tmp2
);
5489 if (u
) { /* polynomial */
5490 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5491 } else { /* Integer */
5493 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5494 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5495 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5501 GEN_NEON_INTEGER_OP(pmax
);
5504 GEN_NEON_INTEGER_OP(pmin
);
5506 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5507 if (!u
) { /* VQDMULH */
5510 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5513 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5517 } else { /* VQRDMULH */
5520 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5523 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5531 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5532 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5533 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5537 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5539 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5540 switch ((u
<< 2) | size
) {
5543 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5546 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5549 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5554 tcg_temp_free_ptr(fpstatus
);
5557 case NEON_3R_FLOAT_MULTIPLY
:
5559 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5560 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5562 tcg_temp_free_i32(tmp2
);
5563 tmp2
= neon_load_reg(rd
, pass
);
5565 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5567 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5570 tcg_temp_free_ptr(fpstatus
);
5573 case NEON_3R_FLOAT_CMP
:
5575 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5577 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5580 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5582 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5585 tcg_temp_free_ptr(fpstatus
);
5588 case NEON_3R_FLOAT_ACMP
:
5590 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5592 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5594 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5596 tcg_temp_free_ptr(fpstatus
);
5599 case NEON_3R_FLOAT_MINMAX
:
5601 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5603 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5605 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5607 tcg_temp_free_ptr(fpstatus
);
5610 case NEON_3R_FLOAT_MISC
:
5613 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5615 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5617 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5619 tcg_temp_free_ptr(fpstatus
);
5622 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5624 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5630 /* VFMA, VFMS: fused multiply-add */
5631 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5632 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5635 gen_helper_vfp_negs(tmp
, tmp
);
5637 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5638 tcg_temp_free_i32(tmp3
);
5639 tcg_temp_free_ptr(fpstatus
);
5645 tcg_temp_free_i32(tmp2
);
5647 /* Save the result. For elementwise operations we can put it
5648 straight into the destination register. For pairwise operations
5649 we have to be careful to avoid clobbering the source operands. */
5650 if (pairwise
&& rd
== rm
) {
5651 neon_store_scratch(pass
, tmp
);
5653 neon_store_reg(rd
, pass
, tmp
);
5657 if (pairwise
&& rd
== rm
) {
5658 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5659 tmp
= neon_load_scratch(pass
);
5660 neon_store_reg(rd
, pass
, tmp
);
5663 /* End of 3 register same size operations. */
5664 } else if (insn
& (1 << 4)) {
5665 if ((insn
& 0x00380080) != 0) {
5666 /* Two registers and shift. */
5667 op
= (insn
>> 8) & 0xf;
5668 if (insn
& (1 << 7)) {
5676 while ((insn
& (1 << (size
+ 19))) == 0)
5679 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5680 /* To avoid excessive duplication of ops we implement shift
5681 by immediate using the variable shift operations. */
5683 /* Shift by immediate:
5684 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5685 if (q
&& ((rd
| rm
) & 1)) {
5688 if (!u
&& (op
== 4 || op
== 6)) {
5691 /* Right shifts are encoded as N - shift, where N is the
5692 element size in bits. */
5694 shift
= shift
- (1 << (size
+ 3));
5702 imm
= (uint8_t) shift
;
5707 imm
= (uint16_t) shift
;
5718 for (pass
= 0; pass
< count
; pass
++) {
5720 neon_load_reg64(cpu_V0
, rm
+ pass
);
5721 tcg_gen_movi_i64(cpu_V1
, imm
);
5726 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5728 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5733 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5735 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5738 case 5: /* VSHL, VSLI */
5739 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5741 case 6: /* VQSHLU */
5742 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5747 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5750 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5755 if (op
== 1 || op
== 3) {
5757 neon_load_reg64(cpu_V1
, rd
+ pass
);
5758 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5759 } else if (op
== 4 || (op
== 5 && u
)) {
5761 neon_load_reg64(cpu_V1
, rd
+ pass
);
5763 if (shift
< -63 || shift
> 63) {
5767 mask
= 0xffffffffffffffffull
>> -shift
;
5769 mask
= 0xffffffffffffffffull
<< shift
;
5772 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5773 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5775 neon_store_reg64(cpu_V0
, rd
+ pass
);
5776 } else { /* size < 3 */
5777 /* Operands in T0 and T1. */
5778 tmp
= neon_load_reg(rm
, pass
);
5779 tmp2
= tcg_temp_new_i32();
5780 tcg_gen_movi_i32(tmp2
, imm
);
5784 GEN_NEON_INTEGER_OP(shl
);
5788 GEN_NEON_INTEGER_OP(rshl
);
5791 case 5: /* VSHL, VSLI */
5793 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5794 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5795 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5799 case 6: /* VQSHLU */
5802 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5806 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5810 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5818 GEN_NEON_INTEGER_OP_ENV(qshl
);
5821 tcg_temp_free_i32(tmp2
);
5823 if (op
== 1 || op
== 3) {
5825 tmp2
= neon_load_reg(rd
, pass
);
5826 gen_neon_add(size
, tmp
, tmp2
);
5827 tcg_temp_free_i32(tmp2
);
5828 } else if (op
== 4 || (op
== 5 && u
)) {
5833 mask
= 0xff >> -shift
;
5835 mask
= (uint8_t)(0xff << shift
);
5841 mask
= 0xffff >> -shift
;
5843 mask
= (uint16_t)(0xffff << shift
);
5847 if (shift
< -31 || shift
> 31) {
5851 mask
= 0xffffffffu
>> -shift
;
5853 mask
= 0xffffffffu
<< shift
;
5859 tmp2
= neon_load_reg(rd
, pass
);
5860 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5861 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5862 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5863 tcg_temp_free_i32(tmp2
);
5865 neon_store_reg(rd
, pass
, tmp
);
5868 } else if (op
< 10) {
5869 /* Shift by immediate and narrow:
5870 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5871 int input_unsigned
= (op
== 8) ? !u
: u
;
5875 shift
= shift
- (1 << (size
+ 3));
5878 tmp64
= tcg_const_i64(shift
);
5879 neon_load_reg64(cpu_V0
, rm
);
5880 neon_load_reg64(cpu_V1
, rm
+ 1);
5881 for (pass
= 0; pass
< 2; pass
++) {
5889 if (input_unsigned
) {
5890 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5892 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5895 if (input_unsigned
) {
5896 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5898 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5901 tmp
= tcg_temp_new_i32();
5902 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5903 neon_store_reg(rd
, pass
, tmp
);
5905 tcg_temp_free_i64(tmp64
);
5908 imm
= (uint16_t)shift
;
5912 imm
= (uint32_t)shift
;
5914 tmp2
= tcg_const_i32(imm
);
5915 tmp4
= neon_load_reg(rm
+ 1, 0);
5916 tmp5
= neon_load_reg(rm
+ 1, 1);
5917 for (pass
= 0; pass
< 2; pass
++) {
5919 tmp
= neon_load_reg(rm
, 0);
5923 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5926 tmp3
= neon_load_reg(rm
, 1);
5930 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5932 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5933 tcg_temp_free_i32(tmp
);
5934 tcg_temp_free_i32(tmp3
);
5935 tmp
= tcg_temp_new_i32();
5936 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5937 neon_store_reg(rd
, pass
, tmp
);
5939 tcg_temp_free_i32(tmp2
);
5941 } else if (op
== 10) {
5943 if (q
|| (rd
& 1)) {
5946 tmp
= neon_load_reg(rm
, 0);
5947 tmp2
= neon_load_reg(rm
, 1);
5948 for (pass
= 0; pass
< 2; pass
++) {
5952 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5955 /* The shift is less than the width of the source
5956 type, so we can just shift the whole register. */
5957 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5958 /* Widen the result of shift: we need to clear
5959 * the potential overflow bits resulting from
5960 * left bits of the narrow input appearing as
5961 * right bits of left the neighbour narrow
5963 if (size
< 2 || !u
) {
5966 imm
= (0xffu
>> (8 - shift
));
5968 } else if (size
== 1) {
5969 imm
= 0xffff >> (16 - shift
);
5972 imm
= 0xffffffff >> (32 - shift
);
5975 imm64
= imm
| (((uint64_t)imm
) << 32);
5979 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5982 neon_store_reg64(cpu_V0
, rd
+ pass
);
5984 } else if (op
>= 14) {
5985 /* VCVT fixed-point. */
5986 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5989 /* We have already masked out the must-be-1 top bit of imm6,
5990 * hence this 32-shift where the ARM ARM has 64-imm6.
5993 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5994 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5997 gen_vfp_ulto(0, shift
, 1);
5999 gen_vfp_slto(0, shift
, 1);
6002 gen_vfp_toul(0, shift
, 1);
6004 gen_vfp_tosl(0, shift
, 1);
6006 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
6011 } else { /* (insn & 0x00380080) == 0 */
6013 if (q
&& (rd
& 1)) {
6017 op
= (insn
>> 8) & 0xf;
6018 /* One register and immediate. */
6019 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
6020 invert
= (insn
& (1 << 5)) != 0;
6021 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6022 * We choose to not special-case this and will behave as if a
6023 * valid constant encoding of 0 had been given.
6042 imm
= (imm
<< 8) | (imm
<< 24);
6045 imm
= (imm
<< 8) | 0xff;
6048 imm
= (imm
<< 16) | 0xffff;
6051 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
6059 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
6060 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
6066 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6067 if (op
& 1 && op
< 12) {
6068 tmp
= neon_load_reg(rd
, pass
);
6070 /* The immediate value has already been inverted, so
6072 tcg_gen_andi_i32(tmp
, tmp
, imm
);
6074 tcg_gen_ori_i32(tmp
, tmp
, imm
);
6078 tmp
= tcg_temp_new_i32();
6079 if (op
== 14 && invert
) {
6083 for (n
= 0; n
< 4; n
++) {
6084 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
6085 val
|= 0xff << (n
* 8);
6087 tcg_gen_movi_i32(tmp
, val
);
6089 tcg_gen_movi_i32(tmp
, imm
);
6092 neon_store_reg(rd
, pass
, tmp
);
6095 } else { /* (insn & 0x00800010 == 0x00800000) */
6097 op
= (insn
>> 8) & 0xf;
6098 if ((insn
& (1 << 6)) == 0) {
6099 /* Three registers of different lengths. */
6103 /* undefreq: bit 0 : UNDEF if size == 0
6104 * bit 1 : UNDEF if size == 1
6105 * bit 2 : UNDEF if size == 2
6106 * bit 3 : UNDEF if U == 1
6107 * Note that [2:0] set implies 'always UNDEF'
6110 /* prewiden, src1_wide, src2_wide, undefreq */
6111 static const int neon_3reg_wide
[16][4] = {
6112 {1, 0, 0, 0}, /* VADDL */
6113 {1, 1, 0, 0}, /* VADDW */
6114 {1, 0, 0, 0}, /* VSUBL */
6115 {1, 1, 0, 0}, /* VSUBW */
6116 {0, 1, 1, 0}, /* VADDHN */
6117 {0, 0, 0, 0}, /* VABAL */
6118 {0, 1, 1, 0}, /* VSUBHN */
6119 {0, 0, 0, 0}, /* VABDL */
6120 {0, 0, 0, 0}, /* VMLAL */
6121 {0, 0, 0, 9}, /* VQDMLAL */
6122 {0, 0, 0, 0}, /* VMLSL */
6123 {0, 0, 0, 9}, /* VQDMLSL */
6124 {0, 0, 0, 0}, /* Integer VMULL */
6125 {0, 0, 0, 1}, /* VQDMULL */
6126 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6127 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6130 prewiden
= neon_3reg_wide
[op
][0];
6131 src1_wide
= neon_3reg_wide
[op
][1];
6132 src2_wide
= neon_3reg_wide
[op
][2];
6133 undefreq
= neon_3reg_wide
[op
][3];
6135 if ((undefreq
& (1 << size
)) ||
6136 ((undefreq
& 8) && u
)) {
6139 if ((src1_wide
&& (rn
& 1)) ||
6140 (src2_wide
&& (rm
& 1)) ||
6141 (!src2_wide
&& (rd
& 1))) {
6145 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6146 * outside the loop below as it only performs a single pass.
6148 if (op
== 14 && size
== 2) {
6149 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
6151 if (!arm_dc_feature(s
, ARM_FEATURE_V8_PMULL
)) {
6154 tcg_rn
= tcg_temp_new_i64();
6155 tcg_rm
= tcg_temp_new_i64();
6156 tcg_rd
= tcg_temp_new_i64();
6157 neon_load_reg64(tcg_rn
, rn
);
6158 neon_load_reg64(tcg_rm
, rm
);
6159 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
6160 neon_store_reg64(tcg_rd
, rd
);
6161 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
6162 neon_store_reg64(tcg_rd
, rd
+ 1);
6163 tcg_temp_free_i64(tcg_rn
);
6164 tcg_temp_free_i64(tcg_rm
);
6165 tcg_temp_free_i64(tcg_rd
);
6169 /* Avoid overlapping operands. Wide source operands are
6170 always aligned so will never overlap with wide
6171 destinations in problematic ways. */
6172 if (rd
== rm
&& !src2_wide
) {
6173 tmp
= neon_load_reg(rm
, 1);
6174 neon_store_scratch(2, tmp
);
6175 } else if (rd
== rn
&& !src1_wide
) {
6176 tmp
= neon_load_reg(rn
, 1);
6177 neon_store_scratch(2, tmp
);
6179 TCGV_UNUSED_I32(tmp3
);
6180 for (pass
= 0; pass
< 2; pass
++) {
6182 neon_load_reg64(cpu_V0
, rn
+ pass
);
6183 TCGV_UNUSED_I32(tmp
);
6185 if (pass
== 1 && rd
== rn
) {
6186 tmp
= neon_load_scratch(2);
6188 tmp
= neon_load_reg(rn
, pass
);
6191 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
6195 neon_load_reg64(cpu_V1
, rm
+ pass
);
6196 TCGV_UNUSED_I32(tmp2
);
6198 if (pass
== 1 && rd
== rm
) {
6199 tmp2
= neon_load_scratch(2);
6201 tmp2
= neon_load_reg(rm
, pass
);
6204 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
6208 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6209 gen_neon_addl(size
);
6211 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6212 gen_neon_subl(size
);
6214 case 5: case 7: /* VABAL, VABDL */
6215 switch ((size
<< 1) | u
) {
6217 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
6220 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
6223 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
6226 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
6229 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
6232 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
6236 tcg_temp_free_i32(tmp2
);
6237 tcg_temp_free_i32(tmp
);
6239 case 8: case 9: case 10: case 11: case 12: case 13:
6240 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6241 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6243 case 14: /* Polynomial VMULL */
6244 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
6245 tcg_temp_free_i32(tmp2
);
6246 tcg_temp_free_i32(tmp
);
6248 default: /* 15 is RESERVED: caught earlier */
6253 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6254 neon_store_reg64(cpu_V0
, rd
+ pass
);
6255 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
6257 neon_load_reg64(cpu_V1
, rd
+ pass
);
6259 case 10: /* VMLSL */
6260 gen_neon_negl(cpu_V0
, size
);
6262 case 5: case 8: /* VABAL, VMLAL */
6263 gen_neon_addl(size
);
6265 case 9: case 11: /* VQDMLAL, VQDMLSL */
6266 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6268 gen_neon_negl(cpu_V0
, size
);
6270 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6275 neon_store_reg64(cpu_V0
, rd
+ pass
);
6276 } else if (op
== 4 || op
== 6) {
6277 /* Narrowing operation. */
6278 tmp
= tcg_temp_new_i32();
6282 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6285 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6288 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6289 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6296 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6299 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6302 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6303 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6304 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6312 neon_store_reg(rd
, 0, tmp3
);
6313 neon_store_reg(rd
, 1, tmp
);
6316 /* Write back the result. */
6317 neon_store_reg64(cpu_V0
, rd
+ pass
);
6321 /* Two registers and a scalar. NB that for ops of this form
6322 * the ARM ARM labels bit 24 as Q, but it is in our variable
6329 case 1: /* Float VMLA scalar */
6330 case 5: /* Floating point VMLS scalar */
6331 case 9: /* Floating point VMUL scalar */
6336 case 0: /* Integer VMLA scalar */
6337 case 4: /* Integer VMLS scalar */
6338 case 8: /* Integer VMUL scalar */
6339 case 12: /* VQDMULH scalar */
6340 case 13: /* VQRDMULH scalar */
6341 if (u
&& ((rd
| rn
) & 1)) {
6344 tmp
= neon_get_scalar(size
, rm
);
6345 neon_store_scratch(0, tmp
);
6346 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6347 tmp
= neon_load_scratch(0);
6348 tmp2
= neon_load_reg(rn
, pass
);
6351 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6353 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6355 } else if (op
== 13) {
6357 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6359 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6361 } else if (op
& 1) {
6362 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6363 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6364 tcg_temp_free_ptr(fpstatus
);
6367 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6368 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6369 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6373 tcg_temp_free_i32(tmp2
);
6376 tmp2
= neon_load_reg(rd
, pass
);
6379 gen_neon_add(size
, tmp
, tmp2
);
6383 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6384 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6385 tcg_temp_free_ptr(fpstatus
);
6389 gen_neon_rsb(size
, tmp
, tmp2
);
6393 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6394 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6395 tcg_temp_free_ptr(fpstatus
);
6401 tcg_temp_free_i32(tmp2
);
6403 neon_store_reg(rd
, pass
, tmp
);
6406 case 3: /* VQDMLAL scalar */
6407 case 7: /* VQDMLSL scalar */
6408 case 11: /* VQDMULL scalar */
6413 case 2: /* VMLAL sclar */
6414 case 6: /* VMLSL scalar */
6415 case 10: /* VMULL scalar */
6419 tmp2
= neon_get_scalar(size
, rm
);
6420 /* We need a copy of tmp2 because gen_neon_mull
6421 * deletes it during pass 0. */
6422 tmp4
= tcg_temp_new_i32();
6423 tcg_gen_mov_i32(tmp4
, tmp2
);
6424 tmp3
= neon_load_reg(rn
, 1);
6426 for (pass
= 0; pass
< 2; pass
++) {
6428 tmp
= neon_load_reg(rn
, 0);
6433 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6435 neon_load_reg64(cpu_V1
, rd
+ pass
);
6439 gen_neon_negl(cpu_V0
, size
);
6442 gen_neon_addl(size
);
6445 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6447 gen_neon_negl(cpu_V0
, size
);
6449 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6455 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6460 neon_store_reg64(cpu_V0
, rd
+ pass
);
6465 default: /* 14 and 15 are RESERVED */
6469 } else { /* size == 3 */
6472 imm
= (insn
>> 8) & 0xf;
6477 if (q
&& ((rd
| rn
| rm
) & 1)) {
6482 neon_load_reg64(cpu_V0
, rn
);
6484 neon_load_reg64(cpu_V1
, rn
+ 1);
6486 } else if (imm
== 8) {
6487 neon_load_reg64(cpu_V0
, rn
+ 1);
6489 neon_load_reg64(cpu_V1
, rm
);
6492 tmp64
= tcg_temp_new_i64();
6494 neon_load_reg64(cpu_V0
, rn
);
6495 neon_load_reg64(tmp64
, rn
+ 1);
6497 neon_load_reg64(cpu_V0
, rn
+ 1);
6498 neon_load_reg64(tmp64
, rm
);
6500 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6501 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6502 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6504 neon_load_reg64(cpu_V1
, rm
);
6506 neon_load_reg64(cpu_V1
, rm
+ 1);
6509 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6510 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6511 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6512 tcg_temp_free_i64(tmp64
);
6515 neon_load_reg64(cpu_V0
, rn
);
6516 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6517 neon_load_reg64(cpu_V1
, rm
);
6518 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6519 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6521 neon_store_reg64(cpu_V0
, rd
);
6523 neon_store_reg64(cpu_V1
, rd
+ 1);
6525 } else if ((insn
& (1 << 11)) == 0) {
6526 /* Two register misc. */
6527 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6528 size
= (insn
>> 18) & 3;
6529 /* UNDEF for unknown op values and bad op-size combinations */
6530 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6533 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6534 q
&& ((rm
| rd
) & 1)) {
6538 case NEON_2RM_VREV64
:
6539 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6540 tmp
= neon_load_reg(rm
, pass
* 2);
6541 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6543 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6544 case 1: gen_swap_half(tmp
); break;
6545 case 2: /* no-op */ break;
6548 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6550 neon_store_reg(rd
, pass
* 2, tmp2
);
6553 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6554 case 1: gen_swap_half(tmp2
); break;
6557 neon_store_reg(rd
, pass
* 2, tmp2
);
6561 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6562 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6563 for (pass
= 0; pass
< q
+ 1; pass
++) {
6564 tmp
= neon_load_reg(rm
, pass
* 2);
6565 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6566 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6567 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6569 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6570 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6571 case 2: tcg_gen_add_i64(CPU_V001
); break;
6574 if (op
>= NEON_2RM_VPADAL
) {
6576 neon_load_reg64(cpu_V1
, rd
+ pass
);
6577 gen_neon_addl(size
);
6579 neon_store_reg64(cpu_V0
, rd
+ pass
);
6585 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6586 tmp
= neon_load_reg(rm
, n
);
6587 tmp2
= neon_load_reg(rd
, n
+ 1);
6588 neon_store_reg(rm
, n
, tmp2
);
6589 neon_store_reg(rd
, n
+ 1, tmp
);
6596 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6601 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6605 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6606 /* also VQMOVUN; op field and mnemonics don't line up */
6610 TCGV_UNUSED_I32(tmp2
);
6611 for (pass
= 0; pass
< 2; pass
++) {
6612 neon_load_reg64(cpu_V0
, rm
+ pass
);
6613 tmp
= tcg_temp_new_i32();
6614 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6619 neon_store_reg(rd
, 0, tmp2
);
6620 neon_store_reg(rd
, 1, tmp
);
6624 case NEON_2RM_VSHLL
:
6625 if (q
|| (rd
& 1)) {
6628 tmp
= neon_load_reg(rm
, 0);
6629 tmp2
= neon_load_reg(rm
, 1);
6630 for (pass
= 0; pass
< 2; pass
++) {
6633 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6634 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6635 neon_store_reg64(cpu_V0
, rd
+ pass
);
6638 case NEON_2RM_VCVT_F16_F32
:
6639 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6643 tmp
= tcg_temp_new_i32();
6644 tmp2
= tcg_temp_new_i32();
6645 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6646 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6647 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6648 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6649 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6650 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6651 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6652 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6653 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6654 neon_store_reg(rd
, 0, tmp2
);
6655 tmp2
= tcg_temp_new_i32();
6656 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6657 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6658 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6659 neon_store_reg(rd
, 1, tmp2
);
6660 tcg_temp_free_i32(tmp
);
6662 case NEON_2RM_VCVT_F32_F16
:
6663 if (!arm_dc_feature(s
, ARM_FEATURE_VFP_FP16
) ||
6667 tmp3
= tcg_temp_new_i32();
6668 tmp
= neon_load_reg(rm
, 0);
6669 tmp2
= neon_load_reg(rm
, 1);
6670 tcg_gen_ext16u_i32(tmp3
, tmp
);
6671 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6672 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6673 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6674 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6675 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6676 tcg_temp_free_i32(tmp
);
6677 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6678 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6679 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6680 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6681 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6682 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6683 tcg_temp_free_i32(tmp2
);
6684 tcg_temp_free_i32(tmp3
);
6686 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6687 if (!arm_dc_feature(s
, ARM_FEATURE_V8_AES
)
6688 || ((rm
| rd
) & 1)) {
6691 tmp
= tcg_const_i32(rd
);
6692 tmp2
= tcg_const_i32(rm
);
6694 /* Bit 6 is the lowest opcode bit; it distinguishes between
6695 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6697 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6699 if (op
== NEON_2RM_AESE
) {
6700 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6702 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6704 tcg_temp_free_i32(tmp
);
6705 tcg_temp_free_i32(tmp2
);
6706 tcg_temp_free_i32(tmp3
);
6708 case NEON_2RM_SHA1H
:
6709 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)
6710 || ((rm
| rd
) & 1)) {
6713 tmp
= tcg_const_i32(rd
);
6714 tmp2
= tcg_const_i32(rm
);
6716 gen_helper_crypto_sha1h(cpu_env
, tmp
, tmp2
);
6718 tcg_temp_free_i32(tmp
);
6719 tcg_temp_free_i32(tmp2
);
6721 case NEON_2RM_SHA1SU1
:
6722 if ((rm
| rd
) & 1) {
6725 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6727 if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA256
)) {
6730 } else if (!arm_dc_feature(s
, ARM_FEATURE_V8_SHA1
)) {
6733 tmp
= tcg_const_i32(rd
);
6734 tmp2
= tcg_const_i32(rm
);
6736 gen_helper_crypto_sha256su0(cpu_env
, tmp
, tmp2
);
6738 gen_helper_crypto_sha1su1(cpu_env
, tmp
, tmp2
);
6740 tcg_temp_free_i32(tmp
);
6741 tcg_temp_free_i32(tmp2
);
6745 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6746 if (neon_2rm_is_float_op(op
)) {
6747 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6748 neon_reg_offset(rm
, pass
));
6749 TCGV_UNUSED_I32(tmp
);
6751 tmp
= neon_load_reg(rm
, pass
);
6754 case NEON_2RM_VREV32
:
6756 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6757 case 1: gen_swap_half(tmp
); break;
6761 case NEON_2RM_VREV16
:
6766 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6767 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6768 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6774 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6775 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6776 case 2: gen_helper_clz(tmp
, tmp
); break;
6781 gen_helper_neon_cnt_u8(tmp
, tmp
);
6784 tcg_gen_not_i32(tmp
, tmp
);
6786 case NEON_2RM_VQABS
:
6789 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6792 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6795 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6800 case NEON_2RM_VQNEG
:
6803 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6806 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6809 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6814 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6815 tmp2
= tcg_const_i32(0);
6817 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6818 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6819 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6822 tcg_temp_free_i32(tmp2
);
6823 if (op
== NEON_2RM_VCLE0
) {
6824 tcg_gen_not_i32(tmp
, tmp
);
6827 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6828 tmp2
= tcg_const_i32(0);
6830 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6831 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6832 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6835 tcg_temp_free_i32(tmp2
);
6836 if (op
== NEON_2RM_VCLT0
) {
6837 tcg_gen_not_i32(tmp
, tmp
);
6840 case NEON_2RM_VCEQ0
:
6841 tmp2
= tcg_const_i32(0);
6843 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6844 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6845 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6848 tcg_temp_free_i32(tmp2
);
6852 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6853 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6854 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6859 tmp2
= tcg_const_i32(0);
6860 gen_neon_rsb(size
, tmp
, tmp2
);
6861 tcg_temp_free_i32(tmp2
);
6863 case NEON_2RM_VCGT0_F
:
6865 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6866 tmp2
= tcg_const_i32(0);
6867 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6868 tcg_temp_free_i32(tmp2
);
6869 tcg_temp_free_ptr(fpstatus
);
6872 case NEON_2RM_VCGE0_F
:
6874 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6875 tmp2
= tcg_const_i32(0);
6876 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6877 tcg_temp_free_i32(tmp2
);
6878 tcg_temp_free_ptr(fpstatus
);
6881 case NEON_2RM_VCEQ0_F
:
6883 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6884 tmp2
= tcg_const_i32(0);
6885 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6886 tcg_temp_free_i32(tmp2
);
6887 tcg_temp_free_ptr(fpstatus
);
6890 case NEON_2RM_VCLE0_F
:
6892 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6893 tmp2
= tcg_const_i32(0);
6894 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6895 tcg_temp_free_i32(tmp2
);
6896 tcg_temp_free_ptr(fpstatus
);
6899 case NEON_2RM_VCLT0_F
:
6901 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6902 tmp2
= tcg_const_i32(0);
6903 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6904 tcg_temp_free_i32(tmp2
);
6905 tcg_temp_free_ptr(fpstatus
);
6908 case NEON_2RM_VABS_F
:
6911 case NEON_2RM_VNEG_F
:
6915 tmp2
= neon_load_reg(rd
, pass
);
6916 neon_store_reg(rm
, pass
, tmp2
);
6919 tmp2
= neon_load_reg(rd
, pass
);
6921 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6922 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6925 neon_store_reg(rm
, pass
, tmp2
);
6927 case NEON_2RM_VRINTN
:
6928 case NEON_2RM_VRINTA
:
6929 case NEON_2RM_VRINTM
:
6930 case NEON_2RM_VRINTP
:
6931 case NEON_2RM_VRINTZ
:
6934 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6937 if (op
== NEON_2RM_VRINTZ
) {
6938 rmode
= FPROUNDING_ZERO
;
6940 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6943 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6944 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6946 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6947 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6949 tcg_temp_free_ptr(fpstatus
);
6950 tcg_temp_free_i32(tcg_rmode
);
6953 case NEON_2RM_VRINTX
:
6955 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6956 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6957 tcg_temp_free_ptr(fpstatus
);
6960 case NEON_2RM_VCVTAU
:
6961 case NEON_2RM_VCVTAS
:
6962 case NEON_2RM_VCVTNU
:
6963 case NEON_2RM_VCVTNS
:
6964 case NEON_2RM_VCVTPU
:
6965 case NEON_2RM_VCVTPS
:
6966 case NEON_2RM_VCVTMU
:
6967 case NEON_2RM_VCVTMS
:
6969 bool is_signed
= !extract32(insn
, 7, 1);
6970 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6971 TCGv_i32 tcg_rmode
, tcg_shift
;
6972 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6974 tcg_shift
= tcg_const_i32(0);
6975 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6976 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6980 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6983 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6987 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6989 tcg_temp_free_i32(tcg_rmode
);
6990 tcg_temp_free_i32(tcg_shift
);
6991 tcg_temp_free_ptr(fpst
);
6994 case NEON_2RM_VRECPE
:
6996 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6997 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6998 tcg_temp_free_ptr(fpstatus
);
7001 case NEON_2RM_VRSQRTE
:
7003 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7004 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
7005 tcg_temp_free_ptr(fpstatus
);
7008 case NEON_2RM_VRECPE_F
:
7010 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7011 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7012 tcg_temp_free_ptr(fpstatus
);
7015 case NEON_2RM_VRSQRTE_F
:
7017 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
7018 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
7019 tcg_temp_free_ptr(fpstatus
);
7022 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
7025 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
7028 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
7029 gen_vfp_tosiz(0, 1);
7031 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
7032 gen_vfp_touiz(0, 1);
7035 /* Reserved op values were caught by the
7036 * neon_2rm_sizes[] check earlier.
7040 if (neon_2rm_is_float_op(op
)) {
7041 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
7042 neon_reg_offset(rd
, pass
));
7044 neon_store_reg(rd
, pass
, tmp
);
7049 } else if ((insn
& (1 << 10)) == 0) {
7051 int n
= ((insn
>> 8) & 3) + 1;
7052 if ((rn
+ n
) > 32) {
7053 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7054 * helper function running off the end of the register file.
7059 if (insn
& (1 << 6)) {
7060 tmp
= neon_load_reg(rd
, 0);
7062 tmp
= tcg_temp_new_i32();
7063 tcg_gen_movi_i32(tmp
, 0);
7065 tmp2
= neon_load_reg(rm
, 0);
7066 tmp4
= tcg_const_i32(rn
);
7067 tmp5
= tcg_const_i32(n
);
7068 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
7069 tcg_temp_free_i32(tmp
);
7070 if (insn
& (1 << 6)) {
7071 tmp
= neon_load_reg(rd
, 1);
7073 tmp
= tcg_temp_new_i32();
7074 tcg_gen_movi_i32(tmp
, 0);
7076 tmp3
= neon_load_reg(rm
, 1);
7077 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
7078 tcg_temp_free_i32(tmp5
);
7079 tcg_temp_free_i32(tmp4
);
7080 neon_store_reg(rd
, 0, tmp2
);
7081 neon_store_reg(rd
, 1, tmp3
);
7082 tcg_temp_free_i32(tmp
);
7083 } else if ((insn
& 0x380) == 0) {
7085 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
7088 if (insn
& (1 << 19)) {
7089 tmp
= neon_load_reg(rm
, 1);
7091 tmp
= neon_load_reg(rm
, 0);
7093 if (insn
& (1 << 16)) {
7094 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
7095 } else if (insn
& (1 << 17)) {
7096 if ((insn
>> 18) & 1)
7097 gen_neon_dup_high16(tmp
);
7099 gen_neon_dup_low16(tmp
);
7101 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
7102 tmp2
= tcg_temp_new_i32();
7103 tcg_gen_mov_i32(tmp2
, tmp
);
7104 neon_store_reg(rd
, pass
, tmp2
);
7106 tcg_temp_free_i32(tmp
);
7115 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7117 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7118 const ARMCPRegInfo
*ri
;
7120 cpnum
= (insn
>> 8) & 0xf;
7122 /* First check for coprocessor space used for XScale/iwMMXt insns */
7123 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7124 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7127 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7128 return disas_iwmmxt_insn(s
, insn
);
7129 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7130 return disas_dsp_insn(s
, insn
);
7135 /* Otherwise treat as a generic register access */
7136 is64
= (insn
& (1 << 25)) == 0;
7137 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7145 opc1
= (insn
>> 4) & 0xf;
7147 rt2
= (insn
>> 16) & 0xf;
7149 crn
= (insn
>> 16) & 0xf;
7150 opc1
= (insn
>> 21) & 7;
7151 opc2
= (insn
>> 5) & 7;
7154 isread
= (insn
>> 20) & 1;
7155 rt
= (insn
>> 12) & 0xf;
7157 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7158 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7160 /* Check access permissions */
7161 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7166 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7167 /* Emit code to perform further access permissions checks at
7168 * runtime; this may result in an exception.
7169 * Note that on XScale all cp0..c13 registers do an access check
7170 * call in order to handle c15_cpar.
7176 /* Note that since we are an implementation which takes an
7177 * exception on a trapped conditional instruction only if the
7178 * instruction passes its condition code check, we can take
7179 * advantage of the clause in the ARM ARM that allows us to set
7180 * the COND field in the instruction to 0xE in all cases.
7181 * We could fish the actual condition out of the insn (ARM)
7182 * or the condexec bits (Thumb) but it isn't necessary.
7187 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7190 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7191 rt
, isread
, s
->thumb
);
7196 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7199 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7200 rt
, isread
, s
->thumb
);
7204 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7205 * so this can only happen if this is an ARMv7 or earlier CPU,
7206 * in which case the syndrome information won't actually be
7209 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7210 syndrome
= syn_uncategorized();
7214 gen_set_pc_im(s
, s
->pc
- 4);
7215 tmpptr
= tcg_const_ptr(ri
);
7216 tcg_syn
= tcg_const_i32(syndrome
);
7217 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
);
7218 tcg_temp_free_ptr(tmpptr
);
7219 tcg_temp_free_i32(tcg_syn
);
7222 /* Handle special cases first */
7223 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7230 gen_set_pc_im(s
, s
->pc
);
7231 s
->is_jmp
= DISAS_WFI
;
7237 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7246 if (ri
->type
& ARM_CP_CONST
) {
7247 tmp64
= tcg_const_i64(ri
->resetvalue
);
7248 } else if (ri
->readfn
) {
7250 tmp64
= tcg_temp_new_i64();
7251 tmpptr
= tcg_const_ptr(ri
);
7252 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7253 tcg_temp_free_ptr(tmpptr
);
7255 tmp64
= tcg_temp_new_i64();
7256 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7258 tmp
= tcg_temp_new_i32();
7259 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7260 store_reg(s
, rt
, tmp
);
7261 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7262 tmp
= tcg_temp_new_i32();
7263 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7264 tcg_temp_free_i64(tmp64
);
7265 store_reg(s
, rt2
, tmp
);
7268 if (ri
->type
& ARM_CP_CONST
) {
7269 tmp
= tcg_const_i32(ri
->resetvalue
);
7270 } else if (ri
->readfn
) {
7272 tmp
= tcg_temp_new_i32();
7273 tmpptr
= tcg_const_ptr(ri
);
7274 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7275 tcg_temp_free_ptr(tmpptr
);
7277 tmp
= load_cpu_offset(ri
->fieldoffset
);
7280 /* Destination register of r15 for 32 bit loads sets
7281 * the condition codes from the high 4 bits of the value
7284 tcg_temp_free_i32(tmp
);
7286 store_reg(s
, rt
, tmp
);
7291 if (ri
->type
& ARM_CP_CONST
) {
7292 /* If not forbidden by access permissions, treat as WI */
7297 TCGv_i32 tmplo
, tmphi
;
7298 TCGv_i64 tmp64
= tcg_temp_new_i64();
7299 tmplo
= load_reg(s
, rt
);
7300 tmphi
= load_reg(s
, rt2
);
7301 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7302 tcg_temp_free_i32(tmplo
);
7303 tcg_temp_free_i32(tmphi
);
7305 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7306 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7307 tcg_temp_free_ptr(tmpptr
);
7309 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7311 tcg_temp_free_i64(tmp64
);
7316 tmp
= load_reg(s
, rt
);
7317 tmpptr
= tcg_const_ptr(ri
);
7318 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7319 tcg_temp_free_ptr(tmpptr
);
7320 tcg_temp_free_i32(tmp
);
7322 TCGv_i32 tmp
= load_reg(s
, rt
);
7323 store_cpu_offset(tmp
, ri
->fieldoffset
);
7328 if ((s
->tb
->cflags
& CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7329 /* I/O operations must end the TB here (whether read or write) */
7332 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7333 /* We default to ending the TB on a coprocessor register write,
7334 * but allow this to be suppressed by the register definition
7335 * (usually only necessary to work around guest bugs).
7343 /* Unknown register; this might be a guest error or a QEMU
7344 * unimplemented feature.
7347 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7348 "64 bit system register cp:%d opc1: %d crm:%d "
7350 isread
? "read" : "write", cpnum
, opc1
, crm
,
7351 s
->ns
? "non-secure" : "secure");
7353 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7354 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7356 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7357 s
->ns
? "non-secure" : "secure");
7364 /* Store a 64-bit value to a register pair. Clobbers val. */
7365 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7368 tmp
= tcg_temp_new_i32();
7369 tcg_gen_extrl_i64_i32(tmp
, val
);
7370 store_reg(s
, rlow
, tmp
);
7371 tmp
= tcg_temp_new_i32();
7372 tcg_gen_shri_i64(val
, val
, 32);
7373 tcg_gen_extrl_i64_i32(tmp
, val
);
7374 store_reg(s
, rhigh
, tmp
);
7377 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7378 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7383 /* Load value and extend to 64 bits. */
7384 tmp
= tcg_temp_new_i64();
7385 tmp2
= load_reg(s
, rlow
);
7386 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7387 tcg_temp_free_i32(tmp2
);
7388 tcg_gen_add_i64(val
, val
, tmp
);
7389 tcg_temp_free_i64(tmp
);
7392 /* load and add a 64-bit value from a register pair. */
7393 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7399 /* Load 64-bit value rd:rn. */
7400 tmpl
= load_reg(s
, rlow
);
7401 tmph
= load_reg(s
, rhigh
);
7402 tmp
= tcg_temp_new_i64();
7403 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7404 tcg_temp_free_i32(tmpl
);
7405 tcg_temp_free_i32(tmph
);
7406 tcg_gen_add_i64(val
, val
, tmp
);
7407 tcg_temp_free_i64(tmp
);
7410 /* Set N and Z flags from hi|lo. */
7411 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7413 tcg_gen_mov_i32(cpu_NF
, hi
);
7414 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7417 /* Load/Store exclusive instructions are implemented by remembering
7418 the value/address loaded, and seeing if these are the same
7419 when the store is performed. This should be sufficient to implement
7420 the architecturally mandated semantics, and avoids having to monitor
7423 In system emulation mode only one CPU will be running at once, so
7424 this sequence is effectively atomic. In user emulation mode we
7425 throw an exception and handle the atomic operation elsewhere. */
7426 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7427 TCGv_i32 addr
, int size
)
7429 TCGv_i32 tmp
= tcg_temp_new_i32();
7435 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7438 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7442 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7449 TCGv_i32 tmp2
= tcg_temp_new_i32();
7450 TCGv_i32 tmp3
= tcg_temp_new_i32();
7452 tcg_gen_addi_i32(tmp2
, addr
, 4);
7453 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7454 tcg_temp_free_i32(tmp2
);
7455 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7456 store_reg(s
, rt2
, tmp3
);
7458 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7461 store_reg(s
, rt
, tmp
);
7462 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7465 static void gen_clrex(DisasContext
*s
)
7467 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7470 #ifdef CONFIG_USER_ONLY
7471 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7472 TCGv_i32 addr
, int size
)
7474 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7475 tcg_gen_movi_i32(cpu_exclusive_info
,
7476 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7477 gen_exception_internal_insn(s
, 4, EXCP_STREX
);
7480 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7481 TCGv_i32 addr
, int size
)
7484 TCGv_i64 val64
, extaddr
;
7485 TCGLabel
*done_label
;
7486 TCGLabel
*fail_label
;
7488 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7494 fail_label
= gen_new_label();
7495 done_label
= gen_new_label();
7496 extaddr
= tcg_temp_new_i64();
7497 tcg_gen_extu_i32_i64(extaddr
, addr
);
7498 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7499 tcg_temp_free_i64(extaddr
);
7501 tmp
= tcg_temp_new_i32();
7504 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
7507 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
7511 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7517 val64
= tcg_temp_new_i64();
7519 TCGv_i32 tmp2
= tcg_temp_new_i32();
7520 TCGv_i32 tmp3
= tcg_temp_new_i32();
7521 tcg_gen_addi_i32(tmp2
, addr
, 4);
7522 gen_aa32_ld32u(tmp3
, tmp2
, get_mem_index(s
));
7523 tcg_temp_free_i32(tmp2
);
7524 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7525 tcg_temp_free_i32(tmp3
);
7527 tcg_gen_extu_i32_i64(val64
, tmp
);
7529 tcg_temp_free_i32(tmp
);
7531 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7532 tcg_temp_free_i64(val64
);
7534 tmp
= load_reg(s
, rt
);
7537 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
7540 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
7544 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7549 tcg_temp_free_i32(tmp
);
7551 tcg_gen_addi_i32(addr
, addr
, 4);
7552 tmp
= load_reg(s
, rt2
);
7553 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7554 tcg_temp_free_i32(tmp
);
7556 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7557 tcg_gen_br(done_label
);
7558 gen_set_label(fail_label
);
7559 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7560 gen_set_label(done_label
);
7561 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7568 * @mode: mode field from insn (which stack to store to)
7569 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7570 * @writeback: true if writeback bit set
7572 * Generate code for the SRS (Store Return State) insn.
7574 static void gen_srs(DisasContext
*s
,
7575 uint32_t mode
, uint32_t amode
, bool writeback
)
7578 TCGv_i32 addr
= tcg_temp_new_i32();
7579 TCGv_i32 tmp
= tcg_const_i32(mode
);
7580 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7581 tcg_temp_free_i32(tmp
);
7598 tcg_gen_addi_i32(addr
, addr
, offset
);
7599 tmp
= load_reg(s
, 14);
7600 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7601 tcg_temp_free_i32(tmp
);
7602 tmp
= load_cpu_field(spsr
);
7603 tcg_gen_addi_i32(addr
, addr
, 4);
7604 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
7605 tcg_temp_free_i32(tmp
);
7623 tcg_gen_addi_i32(addr
, addr
, offset
);
7624 tmp
= tcg_const_i32(mode
);
7625 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7626 tcg_temp_free_i32(tmp
);
7628 tcg_temp_free_i32(addr
);
7631 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7633 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7640 /* M variants do not implement ARM mode. */
7641 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7646 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7647 * choose to UNDEF. In ARMv5 and above the space is used
7648 * for miscellaneous unconditional instructions.
7652 /* Unconditional instructions. */
7653 if (((insn
>> 25) & 7) == 1) {
7654 /* NEON Data processing. */
7655 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7659 if (disas_neon_data_insn(s
, insn
)) {
7664 if ((insn
& 0x0f100000) == 0x04000000) {
7665 /* NEON load/store. */
7666 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7670 if (disas_neon_ls_insn(s
, insn
)) {
7675 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7677 if (disas_vfp_insn(s
, insn
)) {
7682 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7683 ((insn
& 0x0f30f010) == 0x0710f000)) {
7684 if ((insn
& (1 << 22)) == 0) {
7686 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7690 /* Otherwise PLD; v5TE+ */
7694 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7695 ((insn
& 0x0f70f010) == 0x0650f000)) {
7697 return; /* PLI; V7 */
7699 if (((insn
& 0x0f700000) == 0x04100000) ||
7700 ((insn
& 0x0f700010) == 0x06100000)) {
7701 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7704 return; /* v7MP: Unallocated memory hint: must NOP */
7707 if ((insn
& 0x0ffffdff) == 0x01010000) {
7710 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7711 /* Dynamic endianness switching not implemented. */
7712 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7716 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7717 switch ((insn
>> 4) & 0xf) {
7726 /* We don't emulate caches so these are a no-op. */
7731 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7737 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7739 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7745 rn
= (insn
>> 16) & 0xf;
7746 addr
= load_reg(s
, rn
);
7747 i
= (insn
>> 23) & 3;
7749 case 0: offset
= -4; break; /* DA */
7750 case 1: offset
= 0; break; /* IA */
7751 case 2: offset
= -8; break; /* DB */
7752 case 3: offset
= 4; break; /* IB */
7756 tcg_gen_addi_i32(addr
, addr
, offset
);
7757 /* Load PC into tmp and CPSR into tmp2. */
7758 tmp
= tcg_temp_new_i32();
7759 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
7760 tcg_gen_addi_i32(addr
, addr
, 4);
7761 tmp2
= tcg_temp_new_i32();
7762 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
7763 if (insn
& (1 << 21)) {
7764 /* Base writeback. */
7766 case 0: offset
= -8; break;
7767 case 1: offset
= 4; break;
7768 case 2: offset
= -4; break;
7769 case 3: offset
= 0; break;
7773 tcg_gen_addi_i32(addr
, addr
, offset
);
7774 store_reg(s
, rn
, addr
);
7776 tcg_temp_free_i32(addr
);
7778 gen_rfe(s
, tmp
, tmp2
);
7780 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7781 /* branch link and change to thumb (blx <offset>) */
7784 val
= (uint32_t)s
->pc
;
7785 tmp
= tcg_temp_new_i32();
7786 tcg_gen_movi_i32(tmp
, val
);
7787 store_reg(s
, 14, tmp
);
7788 /* Sign-extend the 24-bit offset */
7789 offset
= (((int32_t)insn
) << 8) >> 8;
7790 /* offset * 4 + bit24 * 2 + (thumb bit) */
7791 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7792 /* pipeline offset */
7794 /* protected by ARCH(5); above, near the start of uncond block */
7797 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7798 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7799 /* iWMMXt register transfer. */
7800 if (extract32(s
->c15_cpar
, 1, 1)) {
7801 if (!disas_iwmmxt_insn(s
, insn
)) {
7806 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7807 /* Coprocessor double register transfer. */
7809 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7810 /* Additional coprocessor register transfer. */
7811 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7814 /* cps (privileged) */
7818 if (insn
& (1 << 19)) {
7819 if (insn
& (1 << 8))
7821 if (insn
& (1 << 7))
7823 if (insn
& (1 << 6))
7825 if (insn
& (1 << 18))
7828 if (insn
& (1 << 17)) {
7830 val
|= (insn
& 0x1f);
7833 gen_set_psr_im(s
, mask
, 0, val
);
7840 /* if not always execute, we generate a conditional jump to
7842 s
->condlabel
= gen_new_label();
7843 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7846 if ((insn
& 0x0f900000) == 0x03000000) {
7847 if ((insn
& (1 << 21)) == 0) {
7849 rd
= (insn
>> 12) & 0xf;
7850 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7851 if ((insn
& (1 << 22)) == 0) {
7853 tmp
= tcg_temp_new_i32();
7854 tcg_gen_movi_i32(tmp
, val
);
7857 tmp
= load_reg(s
, rd
);
7858 tcg_gen_ext16u_i32(tmp
, tmp
);
7859 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7861 store_reg(s
, rd
, tmp
);
7863 if (((insn
>> 12) & 0xf) != 0xf)
7865 if (((insn
>> 16) & 0xf) == 0) {
7866 gen_nop_hint(s
, insn
& 0xff);
7868 /* CPSR = immediate */
7870 shift
= ((insn
>> 8) & 0xf) * 2;
7872 val
= (val
>> shift
) | (val
<< (32 - shift
));
7873 i
= ((insn
& (1 << 22)) != 0);
7874 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
7880 } else if ((insn
& 0x0f900000) == 0x01000000
7881 && (insn
& 0x00000090) != 0x00000090) {
7882 /* miscellaneous instructions */
7883 op1
= (insn
>> 21) & 3;
7884 sh
= (insn
>> 4) & 0xf;
7887 case 0x0: /* move program status register */
7890 tmp
= load_reg(s
, rm
);
7891 i
= ((op1
& 2) != 0);
7892 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7896 rd
= (insn
>> 12) & 0xf;
7900 tmp
= load_cpu_field(spsr
);
7902 tmp
= tcg_temp_new_i32();
7903 gen_helper_cpsr_read(tmp
, cpu_env
);
7905 store_reg(s
, rd
, tmp
);
7910 /* branch/exchange thumb (bx). */
7912 tmp
= load_reg(s
, rm
);
7914 } else if (op1
== 3) {
7917 rd
= (insn
>> 12) & 0xf;
7918 tmp
= load_reg(s
, rm
);
7919 gen_helper_clz(tmp
, tmp
);
7920 store_reg(s
, rd
, tmp
);
7928 /* Trivial implementation equivalent to bx. */
7929 tmp
= load_reg(s
, rm
);
7940 /* branch link/exchange thumb (blx) */
7941 tmp
= load_reg(s
, rm
);
7942 tmp2
= tcg_temp_new_i32();
7943 tcg_gen_movi_i32(tmp2
, s
->pc
);
7944 store_reg(s
, 14, tmp2
);
7950 uint32_t c
= extract32(insn
, 8, 4);
7952 /* Check this CPU supports ARMv8 CRC instructions.
7953 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7954 * Bits 8, 10 and 11 should be zero.
7956 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7961 rn
= extract32(insn
, 16, 4);
7962 rd
= extract32(insn
, 12, 4);
7964 tmp
= load_reg(s
, rn
);
7965 tmp2
= load_reg(s
, rm
);
7967 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
7968 } else if (op1
== 1) {
7969 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
7971 tmp3
= tcg_const_i32(1 << op1
);
7973 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7975 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7977 tcg_temp_free_i32(tmp2
);
7978 tcg_temp_free_i32(tmp3
);
7979 store_reg(s
, rd
, tmp
);
7982 case 0x5: /* saturating add/subtract */
7984 rd
= (insn
>> 12) & 0xf;
7985 rn
= (insn
>> 16) & 0xf;
7986 tmp
= load_reg(s
, rm
);
7987 tmp2
= load_reg(s
, rn
);
7989 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7991 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7993 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7994 tcg_temp_free_i32(tmp2
);
7995 store_reg(s
, rd
, tmp
);
7999 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8004 gen_exception_insn(s
, 4, EXCP_BKPT
,
8005 syn_aa32_bkpt(imm16
, false),
8006 default_exception_el(s
));
8009 /* Hypervisor call (v7) */
8017 /* Secure monitor call (v6+) */
8029 case 0x8: /* signed multiply */
8034 rs
= (insn
>> 8) & 0xf;
8035 rn
= (insn
>> 12) & 0xf;
8036 rd
= (insn
>> 16) & 0xf;
8038 /* (32 * 16) >> 16 */
8039 tmp
= load_reg(s
, rm
);
8040 tmp2
= load_reg(s
, rs
);
8042 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8045 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8046 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8047 tmp
= tcg_temp_new_i32();
8048 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8049 tcg_temp_free_i64(tmp64
);
8050 if ((sh
& 2) == 0) {
8051 tmp2
= load_reg(s
, rn
);
8052 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8053 tcg_temp_free_i32(tmp2
);
8055 store_reg(s
, rd
, tmp
);
8058 tmp
= load_reg(s
, rm
);
8059 tmp2
= load_reg(s
, rs
);
8060 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8061 tcg_temp_free_i32(tmp2
);
8063 tmp64
= tcg_temp_new_i64();
8064 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8065 tcg_temp_free_i32(tmp
);
8066 gen_addq(s
, tmp64
, rn
, rd
);
8067 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8068 tcg_temp_free_i64(tmp64
);
8071 tmp2
= load_reg(s
, rn
);
8072 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8073 tcg_temp_free_i32(tmp2
);
8075 store_reg(s
, rd
, tmp
);
8082 } else if (((insn
& 0x0e000000) == 0 &&
8083 (insn
& 0x00000090) != 0x90) ||
8084 ((insn
& 0x0e000000) == (1 << 25))) {
8085 int set_cc
, logic_cc
, shiftop
;
8087 op1
= (insn
>> 21) & 0xf;
8088 set_cc
= (insn
>> 20) & 1;
8089 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8091 /* data processing instruction */
8092 if (insn
& (1 << 25)) {
8093 /* immediate operand */
8095 shift
= ((insn
>> 8) & 0xf) * 2;
8097 val
= (val
>> shift
) | (val
<< (32 - shift
));
8099 tmp2
= tcg_temp_new_i32();
8100 tcg_gen_movi_i32(tmp2
, val
);
8101 if (logic_cc
&& shift
) {
8102 gen_set_CF_bit31(tmp2
);
8107 tmp2
= load_reg(s
, rm
);
8108 shiftop
= (insn
>> 5) & 3;
8109 if (!(insn
& (1 << 4))) {
8110 shift
= (insn
>> 7) & 0x1f;
8111 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8113 rs
= (insn
>> 8) & 0xf;
8114 tmp
= load_reg(s
, rs
);
8115 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8118 if (op1
!= 0x0f && op1
!= 0x0d) {
8119 rn
= (insn
>> 16) & 0xf;
8120 tmp
= load_reg(s
, rn
);
8122 TCGV_UNUSED_I32(tmp
);
8124 rd
= (insn
>> 12) & 0xf;
8127 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8131 store_reg_bx(s
, rd
, tmp
);
8134 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8138 store_reg_bx(s
, rd
, tmp
);
8141 if (set_cc
&& rd
== 15) {
8142 /* SUBS r15, ... is used for exception return. */
8146 gen_sub_CC(tmp
, tmp
, tmp2
);
8147 gen_exception_return(s
, tmp
);
8150 gen_sub_CC(tmp
, tmp
, tmp2
);
8152 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8154 store_reg_bx(s
, rd
, tmp
);
8159 gen_sub_CC(tmp
, tmp2
, tmp
);
8161 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8163 store_reg_bx(s
, rd
, tmp
);
8167 gen_add_CC(tmp
, tmp
, tmp2
);
8169 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8171 store_reg_bx(s
, rd
, tmp
);
8175 gen_adc_CC(tmp
, tmp
, tmp2
);
8177 gen_add_carry(tmp
, tmp
, tmp2
);
8179 store_reg_bx(s
, rd
, tmp
);
8183 gen_sbc_CC(tmp
, tmp
, tmp2
);
8185 gen_sub_carry(tmp
, tmp
, tmp2
);
8187 store_reg_bx(s
, rd
, tmp
);
8191 gen_sbc_CC(tmp
, tmp2
, tmp
);
8193 gen_sub_carry(tmp
, tmp2
, tmp
);
8195 store_reg_bx(s
, rd
, tmp
);
8199 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8202 tcg_temp_free_i32(tmp
);
8206 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8209 tcg_temp_free_i32(tmp
);
8213 gen_sub_CC(tmp
, tmp
, tmp2
);
8215 tcg_temp_free_i32(tmp
);
8219 gen_add_CC(tmp
, tmp
, tmp2
);
8221 tcg_temp_free_i32(tmp
);
8224 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8228 store_reg_bx(s
, rd
, tmp
);
8231 if (logic_cc
&& rd
== 15) {
8232 /* MOVS r15, ... is used for exception return. */
8236 gen_exception_return(s
, tmp2
);
8241 store_reg_bx(s
, rd
, tmp2
);
8245 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8249 store_reg_bx(s
, rd
, tmp
);
8253 tcg_gen_not_i32(tmp2
, tmp2
);
8257 store_reg_bx(s
, rd
, tmp2
);
8260 if (op1
!= 0x0f && op1
!= 0x0d) {
8261 tcg_temp_free_i32(tmp2
);
8264 /* other instructions */
8265 op1
= (insn
>> 24) & 0xf;
8269 /* multiplies, extra load/stores */
8270 sh
= (insn
>> 5) & 3;
8273 rd
= (insn
>> 16) & 0xf;
8274 rn
= (insn
>> 12) & 0xf;
8275 rs
= (insn
>> 8) & 0xf;
8277 op1
= (insn
>> 20) & 0xf;
8279 case 0: case 1: case 2: case 3: case 6:
8281 tmp
= load_reg(s
, rs
);
8282 tmp2
= load_reg(s
, rm
);
8283 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8284 tcg_temp_free_i32(tmp2
);
8285 if (insn
& (1 << 22)) {
8286 /* Subtract (mls) */
8288 tmp2
= load_reg(s
, rn
);
8289 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8290 tcg_temp_free_i32(tmp2
);
8291 } else if (insn
& (1 << 21)) {
8293 tmp2
= load_reg(s
, rn
);
8294 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8295 tcg_temp_free_i32(tmp2
);
8297 if (insn
& (1 << 20))
8299 store_reg(s
, rd
, tmp
);
8302 /* 64 bit mul double accumulate (UMAAL) */
8304 tmp
= load_reg(s
, rs
);
8305 tmp2
= load_reg(s
, rm
);
8306 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8307 gen_addq_lo(s
, tmp64
, rn
);
8308 gen_addq_lo(s
, tmp64
, rd
);
8309 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8310 tcg_temp_free_i64(tmp64
);
8312 case 8: case 9: case 10: case 11:
8313 case 12: case 13: case 14: case 15:
8314 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8315 tmp
= load_reg(s
, rs
);
8316 tmp2
= load_reg(s
, rm
);
8317 if (insn
& (1 << 22)) {
8318 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8320 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8322 if (insn
& (1 << 21)) { /* mult accumulate */
8323 TCGv_i32 al
= load_reg(s
, rn
);
8324 TCGv_i32 ah
= load_reg(s
, rd
);
8325 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8326 tcg_temp_free_i32(al
);
8327 tcg_temp_free_i32(ah
);
8329 if (insn
& (1 << 20)) {
8330 gen_logicq_cc(tmp
, tmp2
);
8332 store_reg(s
, rn
, tmp
);
8333 store_reg(s
, rd
, tmp2
);
8339 rn
= (insn
>> 16) & 0xf;
8340 rd
= (insn
>> 12) & 0xf;
8341 if (insn
& (1 << 23)) {
8342 /* load/store exclusive */
8343 int op2
= (insn
>> 8) & 3;
8344 op1
= (insn
>> 21) & 0x3;
8347 case 0: /* lda/stl */
8353 case 1: /* reserved */
8355 case 2: /* ldaex/stlex */
8358 case 3: /* ldrex/strex */
8367 addr
= tcg_temp_local_new_i32();
8368 load_reg_var(s
, addr
, rn
);
8370 /* Since the emulation does not have barriers,
8371 the acquire/release semantics need no special
8374 if (insn
& (1 << 20)) {
8375 tmp
= tcg_temp_new_i32();
8378 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8381 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
8384 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8389 store_reg(s
, rd
, tmp
);
8392 tmp
= load_reg(s
, rm
);
8395 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8398 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8401 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8406 tcg_temp_free_i32(tmp
);
8408 } else if (insn
& (1 << 20)) {
8411 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8413 case 1: /* ldrexd */
8414 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8416 case 2: /* ldrexb */
8417 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8419 case 3: /* ldrexh */
8420 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8429 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8431 case 1: /* strexd */
8432 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8434 case 2: /* strexb */
8435 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8437 case 3: /* strexh */
8438 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8444 tcg_temp_free_i32(addr
);
8446 /* SWP instruction */
8449 /* ??? This is not really atomic. However we know
8450 we never have multiple CPUs running in parallel,
8451 so it is good enough. */
8452 addr
= load_reg(s
, rn
);
8453 tmp
= load_reg(s
, rm
);
8454 tmp2
= tcg_temp_new_i32();
8455 if (insn
& (1 << 22)) {
8456 gen_aa32_ld8u(tmp2
, addr
, get_mem_index(s
));
8457 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
8459 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
8460 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8462 tcg_temp_free_i32(tmp
);
8463 tcg_temp_free_i32(addr
);
8464 store_reg(s
, rd
, tmp2
);
8469 bool load
= insn
& (1 << 20);
8470 bool doubleword
= false;
8471 /* Misc load/store */
8472 rn
= (insn
>> 16) & 0xf;
8473 rd
= (insn
>> 12) & 0xf;
8475 if (!load
&& (sh
& 2)) {
8479 /* UNPREDICTABLE; we choose to UNDEF */
8482 load
= (sh
& 1) == 0;
8486 addr
= load_reg(s
, rn
);
8487 if (insn
& (1 << 24))
8488 gen_add_datah_offset(s
, insn
, 0, addr
);
8494 tmp
= load_reg(s
, rd
);
8495 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8496 tcg_temp_free_i32(tmp
);
8497 tcg_gen_addi_i32(addr
, addr
, 4);
8498 tmp
= load_reg(s
, rd
+ 1);
8499 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8500 tcg_temp_free_i32(tmp
);
8503 tmp
= tcg_temp_new_i32();
8504 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8505 store_reg(s
, rd
, tmp
);
8506 tcg_gen_addi_i32(addr
, addr
, 4);
8507 tmp
= tcg_temp_new_i32();
8508 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8511 address_offset
= -4;
8514 tmp
= tcg_temp_new_i32();
8517 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
8520 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
8524 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
8529 tmp
= load_reg(s
, rd
);
8530 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
8531 tcg_temp_free_i32(tmp
);
8533 /* Perform base writeback before the loaded value to
8534 ensure correct behavior with overlapping index registers.
8535 ldrd with base writeback is undefined if the
8536 destination and index registers overlap. */
8537 if (!(insn
& (1 << 24))) {
8538 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8539 store_reg(s
, rn
, addr
);
8540 } else if (insn
& (1 << 21)) {
8542 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8543 store_reg(s
, rn
, addr
);
8545 tcg_temp_free_i32(addr
);
8548 /* Complete the load. */
8549 store_reg(s
, rd
, tmp
);
8558 if (insn
& (1 << 4)) {
8560 /* Armv6 Media instructions. */
8562 rn
= (insn
>> 16) & 0xf;
8563 rd
= (insn
>> 12) & 0xf;
8564 rs
= (insn
>> 8) & 0xf;
8565 switch ((insn
>> 23) & 3) {
8566 case 0: /* Parallel add/subtract. */
8567 op1
= (insn
>> 20) & 7;
8568 tmp
= load_reg(s
, rn
);
8569 tmp2
= load_reg(s
, rm
);
8570 sh
= (insn
>> 5) & 7;
8571 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8573 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8574 tcg_temp_free_i32(tmp2
);
8575 store_reg(s
, rd
, tmp
);
8578 if ((insn
& 0x00700020) == 0) {
8579 /* Halfword pack. */
8580 tmp
= load_reg(s
, rn
);
8581 tmp2
= load_reg(s
, rm
);
8582 shift
= (insn
>> 7) & 0x1f;
8583 if (insn
& (1 << 6)) {
8587 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8588 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8589 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8593 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8594 tcg_gen_ext16u_i32(tmp
, tmp
);
8595 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8597 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8598 tcg_temp_free_i32(tmp2
);
8599 store_reg(s
, rd
, tmp
);
8600 } else if ((insn
& 0x00200020) == 0x00200000) {
8602 tmp
= load_reg(s
, rm
);
8603 shift
= (insn
>> 7) & 0x1f;
8604 if (insn
& (1 << 6)) {
8607 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8609 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8611 sh
= (insn
>> 16) & 0x1f;
8612 tmp2
= tcg_const_i32(sh
);
8613 if (insn
& (1 << 22))
8614 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8616 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8617 tcg_temp_free_i32(tmp2
);
8618 store_reg(s
, rd
, tmp
);
8619 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8621 tmp
= load_reg(s
, rm
);
8622 sh
= (insn
>> 16) & 0x1f;
8623 tmp2
= tcg_const_i32(sh
);
8624 if (insn
& (1 << 22))
8625 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8627 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8628 tcg_temp_free_i32(tmp2
);
8629 store_reg(s
, rd
, tmp
);
8630 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8632 tmp
= load_reg(s
, rn
);
8633 tmp2
= load_reg(s
, rm
);
8634 tmp3
= tcg_temp_new_i32();
8635 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8636 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8637 tcg_temp_free_i32(tmp3
);
8638 tcg_temp_free_i32(tmp2
);
8639 store_reg(s
, rd
, tmp
);
8640 } else if ((insn
& 0x000003e0) == 0x00000060) {
8641 tmp
= load_reg(s
, rm
);
8642 shift
= (insn
>> 10) & 3;
8643 /* ??? In many cases it's not necessary to do a
8644 rotate, a shift is sufficient. */
8646 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8647 op1
= (insn
>> 20) & 7;
8649 case 0: gen_sxtb16(tmp
); break;
8650 case 2: gen_sxtb(tmp
); break;
8651 case 3: gen_sxth(tmp
); break;
8652 case 4: gen_uxtb16(tmp
); break;
8653 case 6: gen_uxtb(tmp
); break;
8654 case 7: gen_uxth(tmp
); break;
8655 default: goto illegal_op
;
8658 tmp2
= load_reg(s
, rn
);
8659 if ((op1
& 3) == 0) {
8660 gen_add16(tmp
, tmp2
);
8662 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8663 tcg_temp_free_i32(tmp2
);
8666 store_reg(s
, rd
, tmp
);
8667 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8669 tmp
= load_reg(s
, rm
);
8670 if (insn
& (1 << 22)) {
8671 if (insn
& (1 << 7)) {
8675 gen_helper_rbit(tmp
, tmp
);
8678 if (insn
& (1 << 7))
8681 tcg_gen_bswap32_i32(tmp
, tmp
);
8683 store_reg(s
, rd
, tmp
);
8688 case 2: /* Multiplies (Type 3). */
8689 switch ((insn
>> 20) & 0x7) {
8691 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8692 /* op2 not 00x or 11x : UNDEF */
8695 /* Signed multiply most significant [accumulate].
8696 (SMMUL, SMMLA, SMMLS) */
8697 tmp
= load_reg(s
, rm
);
8698 tmp2
= load_reg(s
, rs
);
8699 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8702 tmp
= load_reg(s
, rd
);
8703 if (insn
& (1 << 6)) {
8704 tmp64
= gen_subq_msw(tmp64
, tmp
);
8706 tmp64
= gen_addq_msw(tmp64
, tmp
);
8709 if (insn
& (1 << 5)) {
8710 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8712 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8713 tmp
= tcg_temp_new_i32();
8714 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8715 tcg_temp_free_i64(tmp64
);
8716 store_reg(s
, rn
, tmp
);
8720 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8721 if (insn
& (1 << 7)) {
8724 tmp
= load_reg(s
, rm
);
8725 tmp2
= load_reg(s
, rs
);
8726 if (insn
& (1 << 5))
8727 gen_swap_half(tmp2
);
8728 gen_smul_dual(tmp
, tmp2
);
8729 if (insn
& (1 << 22)) {
8730 /* smlald, smlsld */
8733 tmp64
= tcg_temp_new_i64();
8734 tmp64_2
= tcg_temp_new_i64();
8735 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8736 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8737 tcg_temp_free_i32(tmp
);
8738 tcg_temp_free_i32(tmp2
);
8739 if (insn
& (1 << 6)) {
8740 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8742 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8744 tcg_temp_free_i64(tmp64_2
);
8745 gen_addq(s
, tmp64
, rd
, rn
);
8746 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8747 tcg_temp_free_i64(tmp64
);
8749 /* smuad, smusd, smlad, smlsd */
8750 if (insn
& (1 << 6)) {
8751 /* This subtraction cannot overflow. */
8752 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8754 /* This addition cannot overflow 32 bits;
8755 * however it may overflow considered as a
8756 * signed operation, in which case we must set
8759 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8761 tcg_temp_free_i32(tmp2
);
8764 tmp2
= load_reg(s
, rd
);
8765 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8766 tcg_temp_free_i32(tmp2
);
8768 store_reg(s
, rn
, tmp
);
8774 if (!arm_dc_feature(s
, ARM_FEATURE_ARM_DIV
)) {
8777 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8780 tmp
= load_reg(s
, rm
);
8781 tmp2
= load_reg(s
, rs
);
8782 if (insn
& (1 << 21)) {
8783 gen_helper_udiv(tmp
, tmp
, tmp2
);
8785 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8787 tcg_temp_free_i32(tmp2
);
8788 store_reg(s
, rn
, tmp
);
8795 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8797 case 0: /* Unsigned sum of absolute differences. */
8799 tmp
= load_reg(s
, rm
);
8800 tmp2
= load_reg(s
, rs
);
8801 gen_helper_usad8(tmp
, tmp
, tmp2
);
8802 tcg_temp_free_i32(tmp2
);
8804 tmp2
= load_reg(s
, rd
);
8805 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8806 tcg_temp_free_i32(tmp2
);
8808 store_reg(s
, rn
, tmp
);
8810 case 0x20: case 0x24: case 0x28: case 0x2c:
8811 /* Bitfield insert/clear. */
8813 shift
= (insn
>> 7) & 0x1f;
8814 i
= (insn
>> 16) & 0x1f;
8816 /* UNPREDICTABLE; we choose to UNDEF */
8821 tmp
= tcg_temp_new_i32();
8822 tcg_gen_movi_i32(tmp
, 0);
8824 tmp
= load_reg(s
, rm
);
8827 tmp2
= load_reg(s
, rd
);
8828 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8829 tcg_temp_free_i32(tmp2
);
8831 store_reg(s
, rd
, tmp
);
8833 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8834 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8836 tmp
= load_reg(s
, rm
);
8837 shift
= (insn
>> 7) & 0x1f;
8838 i
= ((insn
>> 16) & 0x1f) + 1;
8843 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8845 gen_sbfx(tmp
, shift
, i
);
8848 store_reg(s
, rd
, tmp
);
8858 /* Check for undefined extension instructions
8859 * per the ARM Bible IE:
8860 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8862 sh
= (0xf << 20) | (0xf << 4);
8863 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8867 /* load/store byte/word */
8868 rn
= (insn
>> 16) & 0xf;
8869 rd
= (insn
>> 12) & 0xf;
8870 tmp2
= load_reg(s
, rn
);
8871 if ((insn
& 0x01200000) == 0x00200000) {
8873 i
= get_a32_user_mem_index(s
);
8875 i
= get_mem_index(s
);
8877 if (insn
& (1 << 24))
8878 gen_add_data_offset(s
, insn
, tmp2
);
8879 if (insn
& (1 << 20)) {
8881 tmp
= tcg_temp_new_i32();
8882 if (insn
& (1 << 22)) {
8883 gen_aa32_ld8u(tmp
, tmp2
, i
);
8885 gen_aa32_ld32u(tmp
, tmp2
, i
);
8889 tmp
= load_reg(s
, rd
);
8890 if (insn
& (1 << 22)) {
8891 gen_aa32_st8(tmp
, tmp2
, i
);
8893 gen_aa32_st32(tmp
, tmp2
, i
);
8895 tcg_temp_free_i32(tmp
);
8897 if (!(insn
& (1 << 24))) {
8898 gen_add_data_offset(s
, insn
, tmp2
);
8899 store_reg(s
, rn
, tmp2
);
8900 } else if (insn
& (1 << 21)) {
8901 store_reg(s
, rn
, tmp2
);
8903 tcg_temp_free_i32(tmp2
);
8905 if (insn
& (1 << 20)) {
8906 /* Complete the load. */
8907 store_reg_from_load(s
, rd
, tmp
);
8913 int j
, n
, loaded_base
;
8914 bool exc_return
= false;
8915 bool is_load
= extract32(insn
, 20, 1);
8917 TCGv_i32 loaded_var
;
8918 /* load/store multiple words */
8919 /* XXX: store correct base if write back */
8920 if (insn
& (1 << 22)) {
8921 /* LDM (user), LDM (exception return) and STM (user) */
8923 goto illegal_op
; /* only usable in supervisor mode */
8925 if (is_load
&& extract32(insn
, 15, 1)) {
8931 rn
= (insn
>> 16) & 0xf;
8932 addr
= load_reg(s
, rn
);
8934 /* compute total size */
8936 TCGV_UNUSED_I32(loaded_var
);
8939 if (insn
& (1 << i
))
8942 /* XXX: test invalid n == 0 case ? */
8943 if (insn
& (1 << 23)) {
8944 if (insn
& (1 << 24)) {
8946 tcg_gen_addi_i32(addr
, addr
, 4);
8948 /* post increment */
8951 if (insn
& (1 << 24)) {
8953 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8955 /* post decrement */
8957 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8962 if (insn
& (1 << i
)) {
8965 tmp
= tcg_temp_new_i32();
8966 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
8968 tmp2
= tcg_const_i32(i
);
8969 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8970 tcg_temp_free_i32(tmp2
);
8971 tcg_temp_free_i32(tmp
);
8972 } else if (i
== rn
) {
8976 store_reg_from_load(s
, i
, tmp
);
8981 /* special case: r15 = PC + 8 */
8982 val
= (long)s
->pc
+ 4;
8983 tmp
= tcg_temp_new_i32();
8984 tcg_gen_movi_i32(tmp
, val
);
8986 tmp
= tcg_temp_new_i32();
8987 tmp2
= tcg_const_i32(i
);
8988 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8989 tcg_temp_free_i32(tmp2
);
8991 tmp
= load_reg(s
, i
);
8993 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
8994 tcg_temp_free_i32(tmp
);
8997 /* no need to add after the last transfer */
8999 tcg_gen_addi_i32(addr
, addr
, 4);
9002 if (insn
& (1 << 21)) {
9004 if (insn
& (1 << 23)) {
9005 if (insn
& (1 << 24)) {
9008 /* post increment */
9009 tcg_gen_addi_i32(addr
, addr
, 4);
9012 if (insn
& (1 << 24)) {
9015 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9017 /* post decrement */
9018 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9021 store_reg(s
, rn
, addr
);
9023 tcg_temp_free_i32(addr
);
9026 store_reg(s
, rn
, loaded_var
);
9029 /* Restore CPSR from SPSR. */
9030 tmp
= load_cpu_field(spsr
);
9031 gen_set_cpsr(tmp
, CPSR_ERET_MASK
);
9032 tcg_temp_free_i32(tmp
);
9033 s
->is_jmp
= DISAS_UPDATE
;
9042 /* branch (and link) */
9043 val
= (int32_t)s
->pc
;
9044 if (insn
& (1 << 24)) {
9045 tmp
= tcg_temp_new_i32();
9046 tcg_gen_movi_i32(tmp
, val
);
9047 store_reg(s
, 14, tmp
);
9049 offset
= sextract32(insn
<< 2, 0, 26);
9057 if (((insn
>> 8) & 0xe) == 10) {
9059 if (disas_vfp_insn(s
, insn
)) {
9062 } else if (disas_coproc_insn(s
, insn
)) {
9069 gen_set_pc_im(s
, s
->pc
);
9070 s
->svc_imm
= extract32(insn
, 0, 24);
9071 s
->is_jmp
= DISAS_SWI
;
9075 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9076 default_exception_el(s
));
9082 /* Return true if this is a Thumb-2 logical op. */
9084 thumb2_logic_op(int op
)
9089 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9090 then set condition code flags based on the result of the operation.
9091 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9092 to the high bit of T1.
9093 Returns zero if the opcode is valid. */
9096 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9097 TCGv_i32 t0
, TCGv_i32 t1
)
9104 tcg_gen_and_i32(t0
, t0
, t1
);
9108 tcg_gen_andc_i32(t0
, t0
, t1
);
9112 tcg_gen_or_i32(t0
, t0
, t1
);
9116 tcg_gen_orc_i32(t0
, t0
, t1
);
9120 tcg_gen_xor_i32(t0
, t0
, t1
);
9125 gen_add_CC(t0
, t0
, t1
);
9127 tcg_gen_add_i32(t0
, t0
, t1
);
9131 gen_adc_CC(t0
, t0
, t1
);
9137 gen_sbc_CC(t0
, t0
, t1
);
9139 gen_sub_carry(t0
, t0
, t1
);
9144 gen_sub_CC(t0
, t0
, t1
);
9146 tcg_gen_sub_i32(t0
, t0
, t1
);
9150 gen_sub_CC(t0
, t1
, t0
);
9152 tcg_gen_sub_i32(t0
, t1
, t0
);
9154 default: /* 5, 6, 7, 9, 12, 15. */
9160 gen_set_CF_bit31(t1
);
9165 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9167 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
9169 uint32_t insn
, imm
, shift
, offset
;
9170 uint32_t rd
, rn
, rm
, rs
;
9181 if (!(arm_dc_feature(s
, ARM_FEATURE_THUMB2
)
9182 || arm_dc_feature(s
, ARM_FEATURE_M
))) {
9183 /* Thumb-1 cores may need to treat bl and blx as a pair of
9184 16-bit instructions to get correct prefetch abort behavior. */
9186 if ((insn
& (1 << 12)) == 0) {
9188 /* Second half of blx. */
9189 offset
= ((insn
& 0x7ff) << 1);
9190 tmp
= load_reg(s
, 14);
9191 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9192 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
9194 tmp2
= tcg_temp_new_i32();
9195 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9196 store_reg(s
, 14, tmp2
);
9200 if (insn
& (1 << 11)) {
9201 /* Second half of bl. */
9202 offset
= ((insn
& 0x7ff) << 1) | 1;
9203 tmp
= load_reg(s
, 14);
9204 tcg_gen_addi_i32(tmp
, tmp
, offset
);
9206 tmp2
= tcg_temp_new_i32();
9207 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
9208 store_reg(s
, 14, tmp2
);
9212 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
9213 /* Instruction spans a page boundary. Implement it as two
9214 16-bit instructions in case the second half causes an
9216 offset
= ((int32_t)insn
<< 21) >> 9;
9217 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
9220 /* Fall through to 32-bit decode. */
9223 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9225 insn
|= (uint32_t)insn_hw1
<< 16;
9227 if ((insn
& 0xf800e800) != 0xf000e800) {
9231 rn
= (insn
>> 16) & 0xf;
9232 rs
= (insn
>> 12) & 0xf;
9233 rd
= (insn
>> 8) & 0xf;
9235 switch ((insn
>> 25) & 0xf) {
9236 case 0: case 1: case 2: case 3:
9237 /* 16-bit instructions. Should never happen. */
9240 if (insn
& (1 << 22)) {
9241 /* Other load/store, table branch. */
9242 if (insn
& 0x01200000) {
9243 /* Load/store doubleword. */
9245 addr
= tcg_temp_new_i32();
9246 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9248 addr
= load_reg(s
, rn
);
9250 offset
= (insn
& 0xff) * 4;
9251 if ((insn
& (1 << 23)) == 0)
9253 if (insn
& (1 << 24)) {
9254 tcg_gen_addi_i32(addr
, addr
, offset
);
9257 if (insn
& (1 << 20)) {
9259 tmp
= tcg_temp_new_i32();
9260 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9261 store_reg(s
, rs
, tmp
);
9262 tcg_gen_addi_i32(addr
, addr
, 4);
9263 tmp
= tcg_temp_new_i32();
9264 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9265 store_reg(s
, rd
, tmp
);
9268 tmp
= load_reg(s
, rs
);
9269 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9270 tcg_temp_free_i32(tmp
);
9271 tcg_gen_addi_i32(addr
, addr
, 4);
9272 tmp
= load_reg(s
, rd
);
9273 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9274 tcg_temp_free_i32(tmp
);
9276 if (insn
& (1 << 21)) {
9277 /* Base writeback. */
9280 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9281 store_reg(s
, rn
, addr
);
9283 tcg_temp_free_i32(addr
);
9285 } else if ((insn
& (1 << 23)) == 0) {
9286 /* Load/store exclusive word. */
9287 addr
= tcg_temp_local_new_i32();
9288 load_reg_var(s
, addr
, rn
);
9289 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9290 if (insn
& (1 << 20)) {
9291 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9293 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9295 tcg_temp_free_i32(addr
);
9296 } else if ((insn
& (7 << 5)) == 0) {
9299 addr
= tcg_temp_new_i32();
9300 tcg_gen_movi_i32(addr
, s
->pc
);
9302 addr
= load_reg(s
, rn
);
9304 tmp
= load_reg(s
, rm
);
9305 tcg_gen_add_i32(addr
, addr
, tmp
);
9306 if (insn
& (1 << 4)) {
9308 tcg_gen_add_i32(addr
, addr
, tmp
);
9309 tcg_temp_free_i32(tmp
);
9310 tmp
= tcg_temp_new_i32();
9311 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9313 tcg_temp_free_i32(tmp
);
9314 tmp
= tcg_temp_new_i32();
9315 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9317 tcg_temp_free_i32(addr
);
9318 tcg_gen_shli_i32(tmp
, tmp
, 1);
9319 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9320 store_reg(s
, 15, tmp
);
9322 int op2
= (insn
>> 6) & 0x3;
9323 op
= (insn
>> 4) & 0x3;
9328 /* Load/store exclusive byte/halfword/doubleword */
9335 /* Load-acquire/store-release */
9341 /* Load-acquire/store-release exclusive */
9345 addr
= tcg_temp_local_new_i32();
9346 load_reg_var(s
, addr
, rn
);
9348 if (insn
& (1 << 20)) {
9349 tmp
= tcg_temp_new_i32();
9352 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
9355 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
9358 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9363 store_reg(s
, rs
, tmp
);
9365 tmp
= load_reg(s
, rs
);
9368 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
9371 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
9374 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9379 tcg_temp_free_i32(tmp
);
9381 } else if (insn
& (1 << 20)) {
9382 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9384 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9386 tcg_temp_free_i32(addr
);
9389 /* Load/store multiple, RFE, SRS. */
9390 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9391 /* RFE, SRS: not available in user mode or on M profile */
9392 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9395 if (insn
& (1 << 20)) {
9397 addr
= load_reg(s
, rn
);
9398 if ((insn
& (1 << 24)) == 0)
9399 tcg_gen_addi_i32(addr
, addr
, -8);
9400 /* Load PC into tmp and CPSR into tmp2. */
9401 tmp
= tcg_temp_new_i32();
9402 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9403 tcg_gen_addi_i32(addr
, addr
, 4);
9404 tmp2
= tcg_temp_new_i32();
9405 gen_aa32_ld32u(tmp2
, addr
, get_mem_index(s
));
9406 if (insn
& (1 << 21)) {
9407 /* Base writeback. */
9408 if (insn
& (1 << 24)) {
9409 tcg_gen_addi_i32(addr
, addr
, 4);
9411 tcg_gen_addi_i32(addr
, addr
, -4);
9413 store_reg(s
, rn
, addr
);
9415 tcg_temp_free_i32(addr
);
9417 gen_rfe(s
, tmp
, tmp2
);
9420 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9424 int i
, loaded_base
= 0;
9425 TCGv_i32 loaded_var
;
9426 /* Load/store multiple. */
9427 addr
= load_reg(s
, rn
);
9429 for (i
= 0; i
< 16; i
++) {
9430 if (insn
& (1 << i
))
9433 if (insn
& (1 << 24)) {
9434 tcg_gen_addi_i32(addr
, addr
, -offset
);
9437 TCGV_UNUSED_I32(loaded_var
);
9438 for (i
= 0; i
< 16; i
++) {
9439 if ((insn
& (1 << i
)) == 0)
9441 if (insn
& (1 << 20)) {
9443 tmp
= tcg_temp_new_i32();
9444 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
9447 } else if (i
== rn
) {
9451 store_reg(s
, i
, tmp
);
9455 tmp
= load_reg(s
, i
);
9456 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
9457 tcg_temp_free_i32(tmp
);
9459 tcg_gen_addi_i32(addr
, addr
, 4);
9462 store_reg(s
, rn
, loaded_var
);
9464 if (insn
& (1 << 21)) {
9465 /* Base register writeback. */
9466 if (insn
& (1 << 24)) {
9467 tcg_gen_addi_i32(addr
, addr
, -offset
);
9469 /* Fault if writeback register is in register list. */
9470 if (insn
& (1 << rn
))
9472 store_reg(s
, rn
, addr
);
9474 tcg_temp_free_i32(addr
);
9481 op
= (insn
>> 21) & 0xf;
9483 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9486 /* Halfword pack. */
9487 tmp
= load_reg(s
, rn
);
9488 tmp2
= load_reg(s
, rm
);
9489 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9490 if (insn
& (1 << 5)) {
9494 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9495 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9496 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9500 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9501 tcg_gen_ext16u_i32(tmp
, tmp
);
9502 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9504 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9505 tcg_temp_free_i32(tmp2
);
9506 store_reg(s
, rd
, tmp
);
9508 /* Data processing register constant shift. */
9510 tmp
= tcg_temp_new_i32();
9511 tcg_gen_movi_i32(tmp
, 0);
9513 tmp
= load_reg(s
, rn
);
9515 tmp2
= load_reg(s
, rm
);
9517 shiftop
= (insn
>> 4) & 3;
9518 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9519 conds
= (insn
& (1 << 20)) != 0;
9520 logic_cc
= (conds
&& thumb2_logic_op(op
));
9521 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9522 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9524 tcg_temp_free_i32(tmp2
);
9526 store_reg(s
, rd
, tmp
);
9528 tcg_temp_free_i32(tmp
);
9532 case 13: /* Misc data processing. */
9533 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9534 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9537 case 0: /* Register controlled shift. */
9538 tmp
= load_reg(s
, rn
);
9539 tmp2
= load_reg(s
, rm
);
9540 if ((insn
& 0x70) != 0)
9542 op
= (insn
>> 21) & 3;
9543 logic_cc
= (insn
& (1 << 20)) != 0;
9544 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9547 store_reg_bx(s
, rd
, tmp
);
9549 case 1: /* Sign/zero extend. */
9550 op
= (insn
>> 20) & 7;
9552 case 0: /* SXTAH, SXTH */
9553 case 1: /* UXTAH, UXTH */
9554 case 4: /* SXTAB, SXTB */
9555 case 5: /* UXTAB, UXTB */
9557 case 2: /* SXTAB16, SXTB16 */
9558 case 3: /* UXTAB16, UXTB16 */
9559 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9567 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9571 tmp
= load_reg(s
, rm
);
9572 shift
= (insn
>> 4) & 3;
9573 /* ??? In many cases it's not necessary to do a
9574 rotate, a shift is sufficient. */
9576 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9577 op
= (insn
>> 20) & 7;
9579 case 0: gen_sxth(tmp
); break;
9580 case 1: gen_uxth(tmp
); break;
9581 case 2: gen_sxtb16(tmp
); break;
9582 case 3: gen_uxtb16(tmp
); break;
9583 case 4: gen_sxtb(tmp
); break;
9584 case 5: gen_uxtb(tmp
); break;
9586 g_assert_not_reached();
9589 tmp2
= load_reg(s
, rn
);
9590 if ((op
>> 1) == 1) {
9591 gen_add16(tmp
, tmp2
);
9593 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9594 tcg_temp_free_i32(tmp2
);
9597 store_reg(s
, rd
, tmp
);
9599 case 2: /* SIMD add/subtract. */
9600 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9603 op
= (insn
>> 20) & 7;
9604 shift
= (insn
>> 4) & 7;
9605 if ((op
& 3) == 3 || (shift
& 3) == 3)
9607 tmp
= load_reg(s
, rn
);
9608 tmp2
= load_reg(s
, rm
);
9609 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9610 tcg_temp_free_i32(tmp2
);
9611 store_reg(s
, rd
, tmp
);
9613 case 3: /* Other data processing. */
9614 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9616 /* Saturating add/subtract. */
9617 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9620 tmp
= load_reg(s
, rn
);
9621 tmp2
= load_reg(s
, rm
);
9623 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9625 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9627 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9628 tcg_temp_free_i32(tmp2
);
9631 case 0x0a: /* rbit */
9632 case 0x08: /* rev */
9633 case 0x09: /* rev16 */
9634 case 0x0b: /* revsh */
9635 case 0x18: /* clz */
9637 case 0x10: /* sel */
9638 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9642 case 0x20: /* crc32/crc32c */
9648 if (!arm_dc_feature(s
, ARM_FEATURE_CRC
)) {
9655 tmp
= load_reg(s
, rn
);
9657 case 0x0a: /* rbit */
9658 gen_helper_rbit(tmp
, tmp
);
9660 case 0x08: /* rev */
9661 tcg_gen_bswap32_i32(tmp
, tmp
);
9663 case 0x09: /* rev16 */
9666 case 0x0b: /* revsh */
9669 case 0x10: /* sel */
9670 tmp2
= load_reg(s
, rm
);
9671 tmp3
= tcg_temp_new_i32();
9672 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9673 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9674 tcg_temp_free_i32(tmp3
);
9675 tcg_temp_free_i32(tmp2
);
9677 case 0x18: /* clz */
9678 gen_helper_clz(tmp
, tmp
);
9688 uint32_t sz
= op
& 0x3;
9689 uint32_t c
= op
& 0x8;
9691 tmp2
= load_reg(s
, rm
);
9693 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
9694 } else if (sz
== 1) {
9695 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
9697 tmp3
= tcg_const_i32(1 << sz
);
9699 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9701 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9703 tcg_temp_free_i32(tmp2
);
9704 tcg_temp_free_i32(tmp3
);
9708 g_assert_not_reached();
9711 store_reg(s
, rd
, tmp
);
9713 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9714 switch ((insn
>> 20) & 7) {
9715 case 0: /* 32 x 32 -> 32 */
9716 case 7: /* Unsigned sum of absolute differences. */
9718 case 1: /* 16 x 16 -> 32 */
9719 case 2: /* Dual multiply add. */
9720 case 3: /* 32 * 16 -> 32msb */
9721 case 4: /* Dual multiply subtract. */
9722 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9723 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9728 op
= (insn
>> 4) & 0xf;
9729 tmp
= load_reg(s
, rn
);
9730 tmp2
= load_reg(s
, rm
);
9731 switch ((insn
>> 20) & 7) {
9732 case 0: /* 32 x 32 -> 32 */
9733 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9734 tcg_temp_free_i32(tmp2
);
9736 tmp2
= load_reg(s
, rs
);
9738 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9740 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9741 tcg_temp_free_i32(tmp2
);
9744 case 1: /* 16 x 16 -> 32 */
9745 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9746 tcg_temp_free_i32(tmp2
);
9748 tmp2
= load_reg(s
, rs
);
9749 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9750 tcg_temp_free_i32(tmp2
);
9753 case 2: /* Dual multiply add. */
9754 case 4: /* Dual multiply subtract. */
9756 gen_swap_half(tmp2
);
9757 gen_smul_dual(tmp
, tmp2
);
9758 if (insn
& (1 << 22)) {
9759 /* This subtraction cannot overflow. */
9760 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9762 /* This addition cannot overflow 32 bits;
9763 * however it may overflow considered as a signed
9764 * operation, in which case we must set the Q flag.
9766 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9768 tcg_temp_free_i32(tmp2
);
9771 tmp2
= load_reg(s
, rs
);
9772 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9773 tcg_temp_free_i32(tmp2
);
9776 case 3: /* 32 * 16 -> 32msb */
9778 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9781 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9782 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9783 tmp
= tcg_temp_new_i32();
9784 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9785 tcg_temp_free_i64(tmp64
);
9788 tmp2
= load_reg(s
, rs
);
9789 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9790 tcg_temp_free_i32(tmp2
);
9793 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9794 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9796 tmp
= load_reg(s
, rs
);
9797 if (insn
& (1 << 20)) {
9798 tmp64
= gen_addq_msw(tmp64
, tmp
);
9800 tmp64
= gen_subq_msw(tmp64
, tmp
);
9803 if (insn
& (1 << 4)) {
9804 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9806 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9807 tmp
= tcg_temp_new_i32();
9808 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
9809 tcg_temp_free_i64(tmp64
);
9811 case 7: /* Unsigned sum of absolute differences. */
9812 gen_helper_usad8(tmp
, tmp
, tmp2
);
9813 tcg_temp_free_i32(tmp2
);
9815 tmp2
= load_reg(s
, rs
);
9816 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9817 tcg_temp_free_i32(tmp2
);
9821 store_reg(s
, rd
, tmp
);
9823 case 6: case 7: /* 64-bit multiply, Divide. */
9824 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9825 tmp
= load_reg(s
, rn
);
9826 tmp2
= load_reg(s
, rm
);
9827 if ((op
& 0x50) == 0x10) {
9829 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DIV
)) {
9833 gen_helper_udiv(tmp
, tmp
, tmp2
);
9835 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9836 tcg_temp_free_i32(tmp2
);
9837 store_reg(s
, rd
, tmp
);
9838 } else if ((op
& 0xe) == 0xc) {
9839 /* Dual multiply accumulate long. */
9840 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9841 tcg_temp_free_i32(tmp
);
9842 tcg_temp_free_i32(tmp2
);
9846 gen_swap_half(tmp2
);
9847 gen_smul_dual(tmp
, tmp2
);
9849 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9851 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9853 tcg_temp_free_i32(tmp2
);
9855 tmp64
= tcg_temp_new_i64();
9856 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9857 tcg_temp_free_i32(tmp
);
9858 gen_addq(s
, tmp64
, rs
, rd
);
9859 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9860 tcg_temp_free_i64(tmp64
);
9863 /* Unsigned 64-bit multiply */
9864 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9868 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9869 tcg_temp_free_i32(tmp2
);
9870 tcg_temp_free_i32(tmp
);
9873 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9874 tcg_temp_free_i32(tmp2
);
9875 tmp64
= tcg_temp_new_i64();
9876 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9877 tcg_temp_free_i32(tmp
);
9879 /* Signed 64-bit multiply */
9880 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9885 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9886 tcg_temp_free_i64(tmp64
);
9889 gen_addq_lo(s
, tmp64
, rs
);
9890 gen_addq_lo(s
, tmp64
, rd
);
9891 } else if (op
& 0x40) {
9892 /* 64-bit accumulate. */
9893 gen_addq(s
, tmp64
, rs
, rd
);
9895 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9896 tcg_temp_free_i64(tmp64
);
9901 case 6: case 7: case 14: case 15:
9903 if (((insn
>> 24) & 3) == 3) {
9904 /* Translate into the equivalent ARM encoding. */
9905 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9906 if (disas_neon_data_insn(s
, insn
)) {
9909 } else if (((insn
>> 8) & 0xe) == 10) {
9910 if (disas_vfp_insn(s
, insn
)) {
9914 if (insn
& (1 << 28))
9916 if (disas_coproc_insn(s
, insn
)) {
9921 case 8: case 9: case 10: case 11:
9922 if (insn
& (1 << 15)) {
9923 /* Branches, misc control. */
9924 if (insn
& 0x5000) {
9925 /* Unconditional branch. */
9926 /* signextend(hw1[10:0]) -> offset[:12]. */
9927 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9928 /* hw1[10:0] -> offset[11:1]. */
9929 offset
|= (insn
& 0x7ff) << 1;
9930 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9931 offset[24:22] already have the same value because of the
9932 sign extension above. */
9933 offset
^= ((~insn
) & (1 << 13)) << 10;
9934 offset
^= ((~insn
) & (1 << 11)) << 11;
9936 if (insn
& (1 << 14)) {
9937 /* Branch and link. */
9938 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9942 if (insn
& (1 << 12)) {
9947 offset
&= ~(uint32_t)2;
9948 /* thumb2 bx, no need to check */
9949 gen_bx_im(s
, offset
);
9951 } else if (((insn
>> 23) & 7) == 7) {
9953 if (insn
& (1 << 13))
9956 if (insn
& (1 << 26)) {
9957 if (!(insn
& (1 << 20))) {
9958 /* Hypervisor call (v7) */
9959 int imm16
= extract32(insn
, 16, 4) << 12
9960 | extract32(insn
, 0, 12);
9967 /* Secure monitor call (v6+) */
9975 op
= (insn
>> 20) & 7;
9977 case 0: /* msr cpsr. */
9978 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9979 tmp
= load_reg(s
, rn
);
9980 addr
= tcg_const_i32(insn
& 0xff);
9981 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9982 tcg_temp_free_i32(addr
);
9983 tcg_temp_free_i32(tmp
);
9988 case 1: /* msr spsr. */
9989 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
9992 tmp
= load_reg(s
, rn
);
9994 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
9998 case 2: /* cps, nop-hint. */
9999 if (((insn
>> 8) & 7) == 0) {
10000 gen_nop_hint(s
, insn
& 0xff);
10002 /* Implemented as NOP in user mode. */
10007 if (insn
& (1 << 10)) {
10008 if (insn
& (1 << 7))
10010 if (insn
& (1 << 6))
10012 if (insn
& (1 << 5))
10014 if (insn
& (1 << 9))
10015 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10017 if (insn
& (1 << 8)) {
10019 imm
|= (insn
& 0x1f);
10022 gen_set_psr_im(s
, offset
, 0, imm
);
10025 case 3: /* Special control operations. */
10027 op
= (insn
>> 4) & 0xf;
10029 case 2: /* clrex */
10035 /* These execute as NOPs. */
10042 /* Trivial implementation equivalent to bx. */
10043 tmp
= load_reg(s
, rn
);
10046 case 5: /* Exception return. */
10050 if (rn
!= 14 || rd
!= 15) {
10053 tmp
= load_reg(s
, rn
);
10054 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10055 gen_exception_return(s
, tmp
);
10057 case 6: /* mrs cpsr. */
10058 tmp
= tcg_temp_new_i32();
10059 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10060 addr
= tcg_const_i32(insn
& 0xff);
10061 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10062 tcg_temp_free_i32(addr
);
10064 gen_helper_cpsr_read(tmp
, cpu_env
);
10066 store_reg(s
, rd
, tmp
);
10068 case 7: /* mrs spsr. */
10069 /* Not accessible in user mode. */
10070 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10073 tmp
= load_cpu_field(spsr
);
10074 store_reg(s
, rd
, tmp
);
10079 /* Conditional branch. */
10080 op
= (insn
>> 22) & 0xf;
10081 /* Generate a conditional jump to next instruction. */
10082 s
->condlabel
= gen_new_label();
10083 arm_gen_test_cc(op
^ 1, s
->condlabel
);
10086 /* offset[11:1] = insn[10:0] */
10087 offset
= (insn
& 0x7ff) << 1;
10088 /* offset[17:12] = insn[21:16]. */
10089 offset
|= (insn
& 0x003f0000) >> 4;
10090 /* offset[31:20] = insn[26]. */
10091 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10092 /* offset[18] = insn[13]. */
10093 offset
|= (insn
& (1 << 13)) << 5;
10094 /* offset[19] = insn[11]. */
10095 offset
|= (insn
& (1 << 11)) << 8;
10097 /* jump to the offset */
10098 gen_jmp(s
, s
->pc
+ offset
);
10101 /* Data processing immediate. */
10102 if (insn
& (1 << 25)) {
10103 if (insn
& (1 << 24)) {
10104 if (insn
& (1 << 20))
10106 /* Bitfield/Saturate. */
10107 op
= (insn
>> 21) & 7;
10109 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10111 tmp
= tcg_temp_new_i32();
10112 tcg_gen_movi_i32(tmp
, 0);
10114 tmp
= load_reg(s
, rn
);
10117 case 2: /* Signed bitfield extract. */
10119 if (shift
+ imm
> 32)
10122 gen_sbfx(tmp
, shift
, imm
);
10124 case 6: /* Unsigned bitfield extract. */
10126 if (shift
+ imm
> 32)
10129 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
10131 case 3: /* Bitfield insert/clear. */
10134 imm
= imm
+ 1 - shift
;
10136 tmp2
= load_reg(s
, rd
);
10137 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10138 tcg_temp_free_i32(tmp2
);
10143 default: /* Saturate. */
10146 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10148 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10150 tmp2
= tcg_const_i32(imm
);
10153 if ((op
& 1) && shift
== 0) {
10154 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10155 tcg_temp_free_i32(tmp
);
10156 tcg_temp_free_i32(tmp2
);
10159 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10161 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10165 if ((op
& 1) && shift
== 0) {
10166 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10167 tcg_temp_free_i32(tmp
);
10168 tcg_temp_free_i32(tmp2
);
10171 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10173 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10176 tcg_temp_free_i32(tmp2
);
10179 store_reg(s
, rd
, tmp
);
10181 imm
= ((insn
& 0x04000000) >> 15)
10182 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10183 if (insn
& (1 << 22)) {
10184 /* 16-bit immediate. */
10185 imm
|= (insn
>> 4) & 0xf000;
10186 if (insn
& (1 << 23)) {
10188 tmp
= load_reg(s
, rd
);
10189 tcg_gen_ext16u_i32(tmp
, tmp
);
10190 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10193 tmp
= tcg_temp_new_i32();
10194 tcg_gen_movi_i32(tmp
, imm
);
10197 /* Add/sub 12-bit immediate. */
10199 offset
= s
->pc
& ~(uint32_t)3;
10200 if (insn
& (1 << 23))
10204 tmp
= tcg_temp_new_i32();
10205 tcg_gen_movi_i32(tmp
, offset
);
10207 tmp
= load_reg(s
, rn
);
10208 if (insn
& (1 << 23))
10209 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10211 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10214 store_reg(s
, rd
, tmp
);
10217 int shifter_out
= 0;
10218 /* modified 12-bit immediate. */
10219 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10220 imm
= (insn
& 0xff);
10223 /* Nothing to do. */
10225 case 1: /* 00XY00XY */
10228 case 2: /* XY00XY00 */
10232 case 3: /* XYXYXYXY */
10236 default: /* Rotated constant. */
10237 shift
= (shift
<< 1) | (imm
>> 7);
10239 imm
= imm
<< (32 - shift
);
10243 tmp2
= tcg_temp_new_i32();
10244 tcg_gen_movi_i32(tmp2
, imm
);
10245 rn
= (insn
>> 16) & 0xf;
10247 tmp
= tcg_temp_new_i32();
10248 tcg_gen_movi_i32(tmp
, 0);
10250 tmp
= load_reg(s
, rn
);
10252 op
= (insn
>> 21) & 0xf;
10253 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10254 shifter_out
, tmp
, tmp2
))
10256 tcg_temp_free_i32(tmp2
);
10257 rd
= (insn
>> 8) & 0xf;
10259 store_reg(s
, rd
, tmp
);
10261 tcg_temp_free_i32(tmp
);
10266 case 12: /* Load/store single data item. */
10271 if ((insn
& 0x01100000) == 0x01000000) {
10272 if (disas_neon_ls_insn(s
, insn
)) {
10277 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10279 if (!(insn
& (1 << 20))) {
10283 /* Byte or halfword load space with dest == r15 : memory hints.
10284 * Catch them early so we don't emit pointless addressing code.
10285 * This space is a mix of:
10286 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10287 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10289 * unallocated hints, which must be treated as NOPs
10290 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10291 * which is easiest for the decoding logic
10292 * Some space which must UNDEF
10294 int op1
= (insn
>> 23) & 3;
10295 int op2
= (insn
>> 6) & 0x3f;
10300 /* UNPREDICTABLE, unallocated hint or
10301 * PLD/PLDW/PLI (literal)
10306 return 0; /* PLD/PLDW/PLI or unallocated hint */
10308 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10309 return 0; /* PLD/PLDW/PLI or unallocated hint */
10311 /* UNDEF space, or an UNPREDICTABLE */
10315 memidx
= get_mem_index(s
);
10317 addr
= tcg_temp_new_i32();
10319 /* s->pc has already been incremented by 4. */
10320 imm
= s
->pc
& 0xfffffffc;
10321 if (insn
& (1 << 23))
10322 imm
+= insn
& 0xfff;
10324 imm
-= insn
& 0xfff;
10325 tcg_gen_movi_i32(addr
, imm
);
10327 addr
= load_reg(s
, rn
);
10328 if (insn
& (1 << 23)) {
10329 /* Positive offset. */
10330 imm
= insn
& 0xfff;
10331 tcg_gen_addi_i32(addr
, addr
, imm
);
10334 switch ((insn
>> 8) & 0xf) {
10335 case 0x0: /* Shifted Register. */
10336 shift
= (insn
>> 4) & 0xf;
10338 tcg_temp_free_i32(addr
);
10341 tmp
= load_reg(s
, rm
);
10343 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10344 tcg_gen_add_i32(addr
, addr
, tmp
);
10345 tcg_temp_free_i32(tmp
);
10347 case 0xc: /* Negative offset. */
10348 tcg_gen_addi_i32(addr
, addr
, -imm
);
10350 case 0xe: /* User privilege. */
10351 tcg_gen_addi_i32(addr
, addr
, imm
);
10352 memidx
= get_a32_user_mem_index(s
);
10354 case 0x9: /* Post-decrement. */
10356 /* Fall through. */
10357 case 0xb: /* Post-increment. */
10361 case 0xd: /* Pre-decrement. */
10363 /* Fall through. */
10364 case 0xf: /* Pre-increment. */
10365 tcg_gen_addi_i32(addr
, addr
, imm
);
10369 tcg_temp_free_i32(addr
);
10374 if (insn
& (1 << 20)) {
10376 tmp
= tcg_temp_new_i32();
10379 gen_aa32_ld8u(tmp
, addr
, memidx
);
10382 gen_aa32_ld8s(tmp
, addr
, memidx
);
10385 gen_aa32_ld16u(tmp
, addr
, memidx
);
10388 gen_aa32_ld16s(tmp
, addr
, memidx
);
10391 gen_aa32_ld32u(tmp
, addr
, memidx
);
10394 tcg_temp_free_i32(tmp
);
10395 tcg_temp_free_i32(addr
);
10401 store_reg(s
, rs
, tmp
);
10405 tmp
= load_reg(s
, rs
);
10408 gen_aa32_st8(tmp
, addr
, memidx
);
10411 gen_aa32_st16(tmp
, addr
, memidx
);
10414 gen_aa32_st32(tmp
, addr
, memidx
);
10417 tcg_temp_free_i32(tmp
);
10418 tcg_temp_free_i32(addr
);
10421 tcg_temp_free_i32(tmp
);
10424 tcg_gen_addi_i32(addr
, addr
, imm
);
10426 store_reg(s
, rn
, addr
);
10428 tcg_temp_free_i32(addr
);
10440 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
10442 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
10449 if (s
->condexec_mask
) {
10450 cond
= s
->condexec_cond
;
10451 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
10452 s
->condlabel
= gen_new_label();
10453 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10458 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
10461 switch (insn
>> 12) {
10465 op
= (insn
>> 11) & 3;
10468 rn
= (insn
>> 3) & 7;
10469 tmp
= load_reg(s
, rn
);
10470 if (insn
& (1 << 10)) {
10472 tmp2
= tcg_temp_new_i32();
10473 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10476 rm
= (insn
>> 6) & 7;
10477 tmp2
= load_reg(s
, rm
);
10479 if (insn
& (1 << 9)) {
10480 if (s
->condexec_mask
)
10481 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10483 gen_sub_CC(tmp
, tmp
, tmp2
);
10485 if (s
->condexec_mask
)
10486 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10488 gen_add_CC(tmp
, tmp
, tmp2
);
10490 tcg_temp_free_i32(tmp2
);
10491 store_reg(s
, rd
, tmp
);
10493 /* shift immediate */
10494 rm
= (insn
>> 3) & 7;
10495 shift
= (insn
>> 6) & 0x1f;
10496 tmp
= load_reg(s
, rm
);
10497 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10498 if (!s
->condexec_mask
)
10500 store_reg(s
, rd
, tmp
);
10504 /* arithmetic large immediate */
10505 op
= (insn
>> 11) & 3;
10506 rd
= (insn
>> 8) & 0x7;
10507 if (op
== 0) { /* mov */
10508 tmp
= tcg_temp_new_i32();
10509 tcg_gen_movi_i32(tmp
, insn
& 0xff);
10510 if (!s
->condexec_mask
)
10512 store_reg(s
, rd
, tmp
);
10514 tmp
= load_reg(s
, rd
);
10515 tmp2
= tcg_temp_new_i32();
10516 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
10519 gen_sub_CC(tmp
, tmp
, tmp2
);
10520 tcg_temp_free_i32(tmp
);
10521 tcg_temp_free_i32(tmp2
);
10524 if (s
->condexec_mask
)
10525 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10527 gen_add_CC(tmp
, tmp
, tmp2
);
10528 tcg_temp_free_i32(tmp2
);
10529 store_reg(s
, rd
, tmp
);
10532 if (s
->condexec_mask
)
10533 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10535 gen_sub_CC(tmp
, tmp
, tmp2
);
10536 tcg_temp_free_i32(tmp2
);
10537 store_reg(s
, rd
, tmp
);
10543 if (insn
& (1 << 11)) {
10544 rd
= (insn
>> 8) & 7;
10545 /* load pc-relative. Bit 1 of PC is ignored. */
10546 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
10547 val
&= ~(uint32_t)2;
10548 addr
= tcg_temp_new_i32();
10549 tcg_gen_movi_i32(addr
, val
);
10550 tmp
= tcg_temp_new_i32();
10551 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10552 tcg_temp_free_i32(addr
);
10553 store_reg(s
, rd
, tmp
);
10556 if (insn
& (1 << 10)) {
10557 /* data processing extended or blx */
10558 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10559 rm
= (insn
>> 3) & 0xf;
10560 op
= (insn
>> 8) & 3;
10563 tmp
= load_reg(s
, rd
);
10564 tmp2
= load_reg(s
, rm
);
10565 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10566 tcg_temp_free_i32(tmp2
);
10567 store_reg(s
, rd
, tmp
);
10570 tmp
= load_reg(s
, rd
);
10571 tmp2
= load_reg(s
, rm
);
10572 gen_sub_CC(tmp
, tmp
, tmp2
);
10573 tcg_temp_free_i32(tmp2
);
10574 tcg_temp_free_i32(tmp
);
10576 case 2: /* mov/cpy */
10577 tmp
= load_reg(s
, rm
);
10578 store_reg(s
, rd
, tmp
);
10580 case 3:/* branch [and link] exchange thumb register */
10581 tmp
= load_reg(s
, rm
);
10582 if (insn
& (1 << 7)) {
10584 val
= (uint32_t)s
->pc
| 1;
10585 tmp2
= tcg_temp_new_i32();
10586 tcg_gen_movi_i32(tmp2
, val
);
10587 store_reg(s
, 14, tmp2
);
10589 /* already thumb, no need to check */
10596 /* data processing register */
10598 rm
= (insn
>> 3) & 7;
10599 op
= (insn
>> 6) & 0xf;
10600 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10601 /* the shift/rotate ops want the operands backwards */
10610 if (op
== 9) { /* neg */
10611 tmp
= tcg_temp_new_i32();
10612 tcg_gen_movi_i32(tmp
, 0);
10613 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10614 tmp
= load_reg(s
, rd
);
10616 TCGV_UNUSED_I32(tmp
);
10619 tmp2
= load_reg(s
, rm
);
10621 case 0x0: /* and */
10622 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10623 if (!s
->condexec_mask
)
10626 case 0x1: /* eor */
10627 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10628 if (!s
->condexec_mask
)
10631 case 0x2: /* lsl */
10632 if (s
->condexec_mask
) {
10633 gen_shl(tmp2
, tmp2
, tmp
);
10635 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10636 gen_logic_CC(tmp2
);
10639 case 0x3: /* lsr */
10640 if (s
->condexec_mask
) {
10641 gen_shr(tmp2
, tmp2
, tmp
);
10643 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10644 gen_logic_CC(tmp2
);
10647 case 0x4: /* asr */
10648 if (s
->condexec_mask
) {
10649 gen_sar(tmp2
, tmp2
, tmp
);
10651 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10652 gen_logic_CC(tmp2
);
10655 case 0x5: /* adc */
10656 if (s
->condexec_mask
) {
10657 gen_adc(tmp
, tmp2
);
10659 gen_adc_CC(tmp
, tmp
, tmp2
);
10662 case 0x6: /* sbc */
10663 if (s
->condexec_mask
) {
10664 gen_sub_carry(tmp
, tmp
, tmp2
);
10666 gen_sbc_CC(tmp
, tmp
, tmp2
);
10669 case 0x7: /* ror */
10670 if (s
->condexec_mask
) {
10671 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10672 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10674 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10675 gen_logic_CC(tmp2
);
10678 case 0x8: /* tst */
10679 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10683 case 0x9: /* neg */
10684 if (s
->condexec_mask
)
10685 tcg_gen_neg_i32(tmp
, tmp2
);
10687 gen_sub_CC(tmp
, tmp
, tmp2
);
10689 case 0xa: /* cmp */
10690 gen_sub_CC(tmp
, tmp
, tmp2
);
10693 case 0xb: /* cmn */
10694 gen_add_CC(tmp
, tmp
, tmp2
);
10697 case 0xc: /* orr */
10698 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10699 if (!s
->condexec_mask
)
10702 case 0xd: /* mul */
10703 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10704 if (!s
->condexec_mask
)
10707 case 0xe: /* bic */
10708 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10709 if (!s
->condexec_mask
)
10712 case 0xf: /* mvn */
10713 tcg_gen_not_i32(tmp2
, tmp2
);
10714 if (!s
->condexec_mask
)
10715 gen_logic_CC(tmp2
);
10722 store_reg(s
, rm
, tmp2
);
10724 tcg_temp_free_i32(tmp
);
10726 store_reg(s
, rd
, tmp
);
10727 tcg_temp_free_i32(tmp2
);
10730 tcg_temp_free_i32(tmp
);
10731 tcg_temp_free_i32(tmp2
);
10736 /* load/store register offset. */
10738 rn
= (insn
>> 3) & 7;
10739 rm
= (insn
>> 6) & 7;
10740 op
= (insn
>> 9) & 7;
10741 addr
= load_reg(s
, rn
);
10742 tmp
= load_reg(s
, rm
);
10743 tcg_gen_add_i32(addr
, addr
, tmp
);
10744 tcg_temp_free_i32(tmp
);
10746 if (op
< 3) { /* store */
10747 tmp
= load_reg(s
, rd
);
10749 tmp
= tcg_temp_new_i32();
10754 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10757 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10760 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10762 case 3: /* ldrsb */
10763 gen_aa32_ld8s(tmp
, addr
, get_mem_index(s
));
10766 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10769 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10772 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10774 case 7: /* ldrsh */
10775 gen_aa32_ld16s(tmp
, addr
, get_mem_index(s
));
10778 if (op
>= 3) { /* load */
10779 store_reg(s
, rd
, tmp
);
10781 tcg_temp_free_i32(tmp
);
10783 tcg_temp_free_i32(addr
);
10787 /* load/store word immediate offset */
10789 rn
= (insn
>> 3) & 7;
10790 addr
= load_reg(s
, rn
);
10791 val
= (insn
>> 4) & 0x7c;
10792 tcg_gen_addi_i32(addr
, addr
, val
);
10794 if (insn
& (1 << 11)) {
10796 tmp
= tcg_temp_new_i32();
10797 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10798 store_reg(s
, rd
, tmp
);
10801 tmp
= load_reg(s
, rd
);
10802 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10803 tcg_temp_free_i32(tmp
);
10805 tcg_temp_free_i32(addr
);
10809 /* load/store byte immediate offset */
10811 rn
= (insn
>> 3) & 7;
10812 addr
= load_reg(s
, rn
);
10813 val
= (insn
>> 6) & 0x1f;
10814 tcg_gen_addi_i32(addr
, addr
, val
);
10816 if (insn
& (1 << 11)) {
10818 tmp
= tcg_temp_new_i32();
10819 gen_aa32_ld8u(tmp
, addr
, get_mem_index(s
));
10820 store_reg(s
, rd
, tmp
);
10823 tmp
= load_reg(s
, rd
);
10824 gen_aa32_st8(tmp
, addr
, get_mem_index(s
));
10825 tcg_temp_free_i32(tmp
);
10827 tcg_temp_free_i32(addr
);
10831 /* load/store halfword immediate offset */
10833 rn
= (insn
>> 3) & 7;
10834 addr
= load_reg(s
, rn
);
10835 val
= (insn
>> 5) & 0x3e;
10836 tcg_gen_addi_i32(addr
, addr
, val
);
10838 if (insn
& (1 << 11)) {
10840 tmp
= tcg_temp_new_i32();
10841 gen_aa32_ld16u(tmp
, addr
, get_mem_index(s
));
10842 store_reg(s
, rd
, tmp
);
10845 tmp
= load_reg(s
, rd
);
10846 gen_aa32_st16(tmp
, addr
, get_mem_index(s
));
10847 tcg_temp_free_i32(tmp
);
10849 tcg_temp_free_i32(addr
);
10853 /* load/store from stack */
10854 rd
= (insn
>> 8) & 7;
10855 addr
= load_reg(s
, 13);
10856 val
= (insn
& 0xff) * 4;
10857 tcg_gen_addi_i32(addr
, addr
, val
);
10859 if (insn
& (1 << 11)) {
10861 tmp
= tcg_temp_new_i32();
10862 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10863 store_reg(s
, rd
, tmp
);
10866 tmp
= load_reg(s
, rd
);
10867 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10868 tcg_temp_free_i32(tmp
);
10870 tcg_temp_free_i32(addr
);
10874 /* add to high reg */
10875 rd
= (insn
>> 8) & 7;
10876 if (insn
& (1 << 11)) {
10878 tmp
= load_reg(s
, 13);
10880 /* PC. bit 1 is ignored. */
10881 tmp
= tcg_temp_new_i32();
10882 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10884 val
= (insn
& 0xff) * 4;
10885 tcg_gen_addi_i32(tmp
, tmp
, val
);
10886 store_reg(s
, rd
, tmp
);
10891 op
= (insn
>> 8) & 0xf;
10894 /* adjust stack pointer */
10895 tmp
= load_reg(s
, 13);
10896 val
= (insn
& 0x7f) * 4;
10897 if (insn
& (1 << 7))
10898 val
= -(int32_t)val
;
10899 tcg_gen_addi_i32(tmp
, tmp
, val
);
10900 store_reg(s
, 13, tmp
);
10903 case 2: /* sign/zero extend. */
10906 rm
= (insn
>> 3) & 7;
10907 tmp
= load_reg(s
, rm
);
10908 switch ((insn
>> 6) & 3) {
10909 case 0: gen_sxth(tmp
); break;
10910 case 1: gen_sxtb(tmp
); break;
10911 case 2: gen_uxth(tmp
); break;
10912 case 3: gen_uxtb(tmp
); break;
10914 store_reg(s
, rd
, tmp
);
10916 case 4: case 5: case 0xc: case 0xd:
10918 addr
= load_reg(s
, 13);
10919 if (insn
& (1 << 8))
10923 for (i
= 0; i
< 8; i
++) {
10924 if (insn
& (1 << i
))
10927 if ((insn
& (1 << 11)) == 0) {
10928 tcg_gen_addi_i32(addr
, addr
, -offset
);
10930 for (i
= 0; i
< 8; i
++) {
10931 if (insn
& (1 << i
)) {
10932 if (insn
& (1 << 11)) {
10934 tmp
= tcg_temp_new_i32();
10935 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10936 store_reg(s
, i
, tmp
);
10939 tmp
= load_reg(s
, i
);
10940 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10941 tcg_temp_free_i32(tmp
);
10943 /* advance to the next address. */
10944 tcg_gen_addi_i32(addr
, addr
, 4);
10947 TCGV_UNUSED_I32(tmp
);
10948 if (insn
& (1 << 8)) {
10949 if (insn
& (1 << 11)) {
10951 tmp
= tcg_temp_new_i32();
10952 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
10953 /* don't set the pc until the rest of the instruction
10957 tmp
= load_reg(s
, 14);
10958 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
10959 tcg_temp_free_i32(tmp
);
10961 tcg_gen_addi_i32(addr
, addr
, 4);
10963 if ((insn
& (1 << 11)) == 0) {
10964 tcg_gen_addi_i32(addr
, addr
, -offset
);
10966 /* write back the new stack pointer */
10967 store_reg(s
, 13, addr
);
10968 /* set the new PC value */
10969 if ((insn
& 0x0900) == 0x0900) {
10970 store_reg_from_load(s
, 15, tmp
);
10974 case 1: case 3: case 9: case 11: /* czb */
10976 tmp
= load_reg(s
, rm
);
10977 s
->condlabel
= gen_new_label();
10979 if (insn
& (1 << 11))
10980 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10982 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10983 tcg_temp_free_i32(tmp
);
10984 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10985 val
= (uint32_t)s
->pc
+ 2;
10990 case 15: /* IT, nop-hint. */
10991 if ((insn
& 0xf) == 0) {
10992 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10996 s
->condexec_cond
= (insn
>> 4) & 0xe;
10997 s
->condexec_mask
= insn
& 0x1f;
10998 /* No actual code generated for this insn, just setup state. */
11001 case 0xe: /* bkpt */
11003 int imm8
= extract32(insn
, 0, 8);
11005 gen_exception_insn(s
, 2, EXCP_BKPT
, syn_aa32_bkpt(imm8
, true),
11006 default_exception_el(s
));
11010 case 0xa: /* rev */
11012 rn
= (insn
>> 3) & 0x7;
11014 tmp
= load_reg(s
, rn
);
11015 switch ((insn
>> 6) & 3) {
11016 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11017 case 1: gen_rev16(tmp
); break;
11018 case 3: gen_revsh(tmp
); break;
11019 default: goto illegal_op
;
11021 store_reg(s
, rd
, tmp
);
11025 switch ((insn
>> 5) & 7) {
11029 if (((insn
>> 3) & 1) != s
->bswap_code
) {
11030 /* Dynamic endianness switching not implemented. */
11031 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
11041 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11042 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11045 addr
= tcg_const_i32(19);
11046 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11047 tcg_temp_free_i32(addr
);
11051 addr
= tcg_const_i32(16);
11052 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11053 tcg_temp_free_i32(addr
);
11055 tcg_temp_free_i32(tmp
);
11058 if (insn
& (1 << 4)) {
11059 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11063 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11078 /* load/store multiple */
11079 TCGv_i32 loaded_var
;
11080 TCGV_UNUSED_I32(loaded_var
);
11081 rn
= (insn
>> 8) & 0x7;
11082 addr
= load_reg(s
, rn
);
11083 for (i
= 0; i
< 8; i
++) {
11084 if (insn
& (1 << i
)) {
11085 if (insn
& (1 << 11)) {
11087 tmp
= tcg_temp_new_i32();
11088 gen_aa32_ld32u(tmp
, addr
, get_mem_index(s
));
11092 store_reg(s
, i
, tmp
);
11096 tmp
= load_reg(s
, i
);
11097 gen_aa32_st32(tmp
, addr
, get_mem_index(s
));
11098 tcg_temp_free_i32(tmp
);
11100 /* advance to the next address */
11101 tcg_gen_addi_i32(addr
, addr
, 4);
11104 if ((insn
& (1 << rn
)) == 0) {
11105 /* base reg not in list: base register writeback */
11106 store_reg(s
, rn
, addr
);
11108 /* base reg in list: if load, complete it now */
11109 if (insn
& (1 << 11)) {
11110 store_reg(s
, rn
, loaded_var
);
11112 tcg_temp_free_i32(addr
);
11117 /* conditional branch or swi */
11118 cond
= (insn
>> 8) & 0xf;
11124 gen_set_pc_im(s
, s
->pc
);
11125 s
->svc_imm
= extract32(insn
, 0, 8);
11126 s
->is_jmp
= DISAS_SWI
;
11129 /* generate a conditional jump to next instruction */
11130 s
->condlabel
= gen_new_label();
11131 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
11134 /* jump to the offset */
11135 val
= (uint32_t)s
->pc
+ 2;
11136 offset
= ((int32_t)insn
<< 24) >> 24;
11137 val
+= offset
<< 1;
11142 if (insn
& (1 << 11)) {
11143 if (disas_thumb2_insn(env
, s
, insn
))
11147 /* unconditional branch */
11148 val
= (uint32_t)s
->pc
;
11149 offset
= ((int32_t)insn
<< 21) >> 21;
11150 val
+= (offset
<< 1) + 2;
11155 if (disas_thumb2_insn(env
, s
, insn
))
11161 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
11162 default_exception_el(s
));
11166 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11167 default_exception_el(s
));
11170 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
11171 basic block 'tb'. If search_pc is TRUE, also generate PC
11172 information for each intermediate instruction. */
11173 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
11174 TranslationBlock
*tb
,
11177 CPUState
*cs
= CPU(cpu
);
11178 CPUARMState
*env
= &cpu
->env
;
11179 DisasContext dc1
, *dc
= &dc1
;
11182 target_ulong pc_start
;
11183 target_ulong next_page_start
;
11187 /* generate intermediate code */
11189 /* The A64 decoder has its own top level loop, because it doesn't need
11190 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11192 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
11193 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
11201 dc
->is_jmp
= DISAS_NEXT
;
11203 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
11207 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11208 * there is no secure EL1, so we route exceptions to EL3.
11210 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11211 !arm_el_is_aa64(env
, 3);
11212 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
11213 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
11214 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
11215 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
11216 dc
->mmu_idx
= ARM_TBFLAG_MMUIDX(tb
->flags
);
11217 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11218 #if !defined(CONFIG_USER_ONLY)
11219 dc
->user
= (dc
->current_el
== 0);
11221 dc
->ns
= ARM_TBFLAG_NS(tb
->flags
);
11222 dc
->fp_excp_el
= ARM_TBFLAG_FPEXC_EL(tb
->flags
);
11223 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
11224 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
11225 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
11226 dc
->c15_cpar
= ARM_TBFLAG_XSCALE_CPAR(tb
->flags
);
11227 dc
->cp_regs
= cpu
->cp_regs
;
11228 dc
->features
= env
->features
;
11230 /* Single step state. The code-generation logic here is:
11232 * generate code with no special handling for single-stepping (except
11233 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11234 * this happens anyway because those changes are all system register or
11236 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11237 * emit code for one insn
11238 * emit code to clear PSTATE.SS
11239 * emit code to generate software step exception for completed step
11240 * end TB (as usual for having generated an exception)
11241 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11242 * emit code to generate a software step exception
11245 dc
->ss_active
= ARM_TBFLAG_SS_ACTIVE(tb
->flags
);
11246 dc
->pstate_ss
= ARM_TBFLAG_PSTATE_SS(tb
->flags
);
11247 dc
->is_ldex
= false;
11248 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11250 cpu_F0s
= tcg_temp_new_i32();
11251 cpu_F1s
= tcg_temp_new_i32();
11252 cpu_F0d
= tcg_temp_new_i64();
11253 cpu_F1d
= tcg_temp_new_i64();
11256 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11257 cpu_M0
= tcg_temp_new_i64();
11258 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
11261 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
11262 if (max_insns
== 0)
11263 max_insns
= CF_COUNT_MASK
;
11267 tcg_clear_temp_count();
11269 /* A note on handling of the condexec (IT) bits:
11271 * We want to avoid the overhead of having to write the updated condexec
11272 * bits back to the CPUARMState for every instruction in an IT block. So:
11273 * (1) if the condexec bits are not already zero then we write
11274 * zero back into the CPUARMState now. This avoids complications trying
11275 * to do it at the end of the block. (For example if we don't do this
11276 * it's hard to identify whether we can safely skip writing condexec
11277 * at the end of the TB, which we definitely want to do for the case
11278 * where a TB doesn't do anything with the IT state at all.)
11279 * (2) if we are going to leave the TB then we call gen_set_condexec()
11280 * which will write the correct value into CPUARMState if zero is wrong.
11281 * This is done both for leaving the TB at the end, and for leaving
11282 * it because of an exception we know will happen, which is done in
11283 * gen_exception_insn(). The latter is necessary because we need to
11284 * leave the TB with the PC/IT state just prior to execution of the
11285 * instruction which caused the exception.
11286 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11287 * then the CPUARMState will be wrong and we need to reset it.
11288 * This is handled in the same way as restoration of the
11289 * PC in these situations: we will be called again with search_pc=1
11290 * and generate a mapping of the condexec bits for each PC in
11291 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11292 * this to restore the condexec bits.
11294 * Note that there are no instructions which can read the condexec
11295 * bits, and none which can write non-static values to them, so
11296 * we don't need to care about whether CPUARMState is correct in the
11300 /* Reset the conditional execution bits immediately. This avoids
11301 complications trying to do it at the end of the block. */
11302 if (dc
->condexec_mask
|| dc
->condexec_cond
)
11304 TCGv_i32 tmp
= tcg_temp_new_i32();
11305 tcg_gen_movi_i32(tmp
, 0);
11306 store_cpu_field(tmp
, condexec_bits
);
11309 #ifdef CONFIG_USER_ONLY
11310 /* Intercept jump to the magic kernel page. */
11311 if (dc
->pc
>= 0xffff0000) {
11312 /* We always get here via a jump, so know we are not in a
11313 conditional execution block. */
11314 gen_exception_internal(EXCP_KERNEL_TRAP
);
11315 dc
->is_jmp
= DISAS_UPDATE
;
11319 if (dc
->pc
>= 0xfffffff0 && arm_dc_feature(dc
, ARM_FEATURE_M
)) {
11320 /* We always get here via a jump, so know we are not in a
11321 conditional execution block. */
11322 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
11323 dc
->is_jmp
= DISAS_UPDATE
;
11328 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
11329 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
11330 if (bp
->pc
== dc
->pc
) {
11331 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11332 /* Advance PC so that clearing the breakpoint will
11333 invalidate this TB. */
11335 goto done_generating
;
11340 j
= tcg_op_buf_count();
11344 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11346 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
11347 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
11348 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
11349 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
11352 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
11355 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
11356 tcg_gen_debug_insn_start(dc
->pc
);
11359 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11360 /* Singlestep state is Active-pending.
11361 * If we're in this state at the start of a TB then either
11362 * a) we just took an exception to an EL which is being debugged
11363 * and this is the first insn in the exception handler
11364 * b) debug exceptions were masked and we just unmasked them
11365 * without changing EL (eg by clearing PSTATE.D)
11366 * In either case we're going to take a swstep exception in the
11367 * "did not step an insn" case, and so the syndrome ISV and EX
11368 * bits should be zero.
11370 assert(num_insns
== 0);
11371 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
11372 default_exception_el(dc
));
11373 goto done_generating
;
11377 disas_thumb_insn(env
, dc
);
11378 if (dc
->condexec_mask
) {
11379 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
11380 | ((dc
->condexec_mask
>> 4) & 1);
11381 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11382 if (dc
->condexec_mask
== 0) {
11383 dc
->condexec_cond
= 0;
11387 unsigned int insn
= arm_ldl_code(env
, dc
->pc
, dc
->bswap_code
);
11389 disas_arm_insn(dc
, insn
);
11392 if (dc
->condjmp
&& !dc
->is_jmp
) {
11393 gen_set_label(dc
->condlabel
);
11397 if (tcg_check_temp_count()) {
11398 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
11402 /* Translation stops when a conditional branch is encountered.
11403 * Otherwise the subsequent code could get translated several times.
11404 * Also stop translation when a page boundary is reached. This
11405 * ensures prefetch aborts occur at the right place. */
11407 } while (!dc
->is_jmp
&& !tcg_op_buf_full() &&
11408 !cs
->singlestep_enabled
&&
11411 dc
->pc
< next_page_start
&&
11412 num_insns
< max_insns
);
11414 if (tb
->cflags
& CF_LAST_IO
) {
11416 /* FIXME: This can theoretically happen with self-modifying
11418 cpu_abort(cs
, "IO on conditional branch instruction");
11423 /* At this stage dc->condjmp will only be set when the skipped
11424 instruction was a conditional branch or trap, and the PC has
11425 already been written. */
11426 if (unlikely(cs
->singlestep_enabled
|| dc
->ss_active
)) {
11427 /* Make sure the pc is updated, and raise a debug exception. */
11429 gen_set_condexec(dc
);
11430 if (dc
->is_jmp
== DISAS_SWI
) {
11431 gen_ss_advance(dc
);
11432 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11433 default_exception_el(dc
));
11434 } else if (dc
->is_jmp
== DISAS_HVC
) {
11435 gen_ss_advance(dc
);
11436 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11437 } else if (dc
->is_jmp
== DISAS_SMC
) {
11438 gen_ss_advance(dc
);
11439 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11440 } else if (dc
->ss_active
) {
11441 gen_step_complete_exception(dc
);
11443 gen_exception_internal(EXCP_DEBUG
);
11445 gen_set_label(dc
->condlabel
);
11447 if (dc
->condjmp
|| !dc
->is_jmp
) {
11448 gen_set_pc_im(dc
, dc
->pc
);
11451 gen_set_condexec(dc
);
11452 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
11453 gen_ss_advance(dc
);
11454 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11455 default_exception_el(dc
));
11456 } else if (dc
->is_jmp
== DISAS_HVC
&& !dc
->condjmp
) {
11457 gen_ss_advance(dc
);
11458 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11459 } else if (dc
->is_jmp
== DISAS_SMC
&& !dc
->condjmp
) {
11460 gen_ss_advance(dc
);
11461 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11462 } else if (dc
->ss_active
) {
11463 gen_step_complete_exception(dc
);
11465 /* FIXME: Single stepping a WFI insn will not halt
11467 gen_exception_internal(EXCP_DEBUG
);
11470 /* While branches must always occur at the end of an IT block,
11471 there are a few other things that can cause us to terminate
11472 the TB in the middle of an IT block:
11473 - Exception generating instructions (bkpt, swi, undefined).
11475 - Hardware watchpoints.
11476 Hardware breakpoints have already been handled and skip this code.
11478 gen_set_condexec(dc
);
11479 switch(dc
->is_jmp
) {
11481 gen_goto_tb(dc
, 1, dc
->pc
);
11486 /* indicate that the hash table must be used to find the next TB */
11487 tcg_gen_exit_tb(0);
11489 case DISAS_TB_JUMP
:
11490 /* nothing more to generate */
11493 gen_helper_wfi(cpu_env
);
11494 /* The helper doesn't necessarily throw an exception, but we
11495 * must go back to the main loop to check for interrupts anyway.
11497 tcg_gen_exit_tb(0);
11500 gen_helper_wfe(cpu_env
);
11503 gen_helper_yield(cpu_env
);
11506 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11507 default_exception_el(dc
));
11510 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11513 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11517 gen_set_label(dc
->condlabel
);
11518 gen_set_condexec(dc
);
11519 gen_goto_tb(dc
, 1, dc
->pc
);
11525 gen_tb_end(tb
, num_insns
);
11528 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
11529 qemu_log("----------------\n");
11530 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
11531 log_target_disas(cs
, pc_start
, dc
->pc
- pc_start
,
11532 dc
->thumb
| (dc
->bswap_code
<< 1));
11537 j
= tcg_op_buf_count();
11540 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
11542 tb
->size
= dc
->pc
- pc_start
;
11543 tb
->icount
= num_insns
;
11547 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
11549 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
11552 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
11554 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
11557 static const char *cpu_mode_names
[16] = {
11558 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11559 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11562 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
11565 ARMCPU
*cpu
= ARM_CPU(cs
);
11566 CPUARMState
*env
= &cpu
->env
;
11571 aarch64_cpu_dump_state(cs
, f
, cpu_fprintf
, flags
);
11575 for(i
=0;i
<16;i
++) {
11576 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
11578 cpu_fprintf(f
, "\n");
11580 cpu_fprintf(f
, " ");
11582 psr
= cpsr_read(env
);
11583 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
11585 psr
& (1 << 31) ? 'N' : '-',
11586 psr
& (1 << 30) ? 'Z' : '-',
11587 psr
& (1 << 29) ? 'C' : '-',
11588 psr
& (1 << 28) ? 'V' : '-',
11589 psr
& CPSR_T
? 'T' : 'A',
11590 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
11592 if (flags
& CPU_DUMP_FPU
) {
11593 int numvfpregs
= 0;
11594 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
11597 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
11600 for (i
= 0; i
< numvfpregs
; i
++) {
11601 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
11602 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
11603 i
* 2, (uint32_t)v
,
11604 i
* 2 + 1, (uint32_t)(v
>> 32),
11607 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
11611 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
11614 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
11615 env
->condexec_bits
= 0;
11617 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
11618 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];