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 "disas/disas.h"
36 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
37 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
38 /* currently all emulated v5 cores are also v5TE, so don't bother */
39 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
40 #define ENABLE_ARCH_5J 0
41 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
42 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
43 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
44 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
48 /* internal defines */
49 typedef struct DisasContext
{
52 /* Nonzero if this instruction has been conditionally skipped. */
54 /* The label that will be jumped to when the instruction is skipped. */
56 /* Thumb-2 conditional execution bits. */
59 struct TranslationBlock
*tb
;
60 int singlestep_enabled
;
63 #if !defined(CONFIG_USER_ONLY)
71 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
73 #if defined(CONFIG_USER_ONLY)
76 #define IS_USER(s) (s->user)
79 /* These instructions trap after executing, so defer them until after the
80 conditional execution state has been updated. */
84 static TCGv_ptr cpu_env
;
85 /* We reuse the same 64-bit temporaries for efficiency. */
86 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
87 static TCGv_i32 cpu_R
[16];
88 static TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
89 static TCGv_i32 cpu_exclusive_addr
;
90 static TCGv_i32 cpu_exclusive_val
;
91 static TCGv_i32 cpu_exclusive_high
;
92 #ifdef CONFIG_USER_ONLY
93 static TCGv_i32 cpu_exclusive_test
;
94 static TCGv_i32 cpu_exclusive_info
;
97 /* FIXME: These should be removed. */
98 static TCGv cpu_F0s
, cpu_F1s
;
99 static TCGv_i64 cpu_F0d
, cpu_F1d
;
101 #include "exec/gen-icount.h"
103 static const char *regnames
[] =
104 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
105 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
107 /* initialize TCG globals. */
108 void arm_translate_init(void)
112 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
114 for (i
= 0; i
< 16; i
++) {
115 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
116 offsetof(CPUARMState
, regs
[i
]),
119 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
120 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
121 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
122 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
124 cpu_exclusive_addr
= tcg_global_mem_new_i32(TCG_AREG0
,
125 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
126 cpu_exclusive_val
= tcg_global_mem_new_i32(TCG_AREG0
,
127 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
128 cpu_exclusive_high
= tcg_global_mem_new_i32(TCG_AREG0
,
129 offsetof(CPUARMState
, exclusive_high
), "exclusive_high");
130 #ifdef CONFIG_USER_ONLY
131 cpu_exclusive_test
= tcg_global_mem_new_i32(TCG_AREG0
,
132 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
133 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
134 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
141 static inline TCGv
load_cpu_offset(int offset
)
143 TCGv tmp
= tcg_temp_new_i32();
144 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
148 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
150 static inline void store_cpu_offset(TCGv var
, int offset
)
152 tcg_gen_st_i32(var
, cpu_env
, offset
);
153 tcg_temp_free_i32(var
);
156 #define store_cpu_field(var, name) \
157 store_cpu_offset(var, offsetof(CPUARMState, name))
159 /* Set a variable to the value of a CPU register. */
160 static void load_reg_var(DisasContext
*s
, TCGv var
, int reg
)
164 /* normally, since we updated PC, we need only to add one insn */
166 addr
= (long)s
->pc
+ 2;
168 addr
= (long)s
->pc
+ 4;
169 tcg_gen_movi_i32(var
, addr
);
171 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
175 /* Create a new temporary and set it to the value of a CPU register. */
176 static inline TCGv
load_reg(DisasContext
*s
, int reg
)
178 TCGv tmp
= tcg_temp_new_i32();
179 load_reg_var(s
, tmp
, reg
);
183 /* Set a CPU register. The source must be a temporary and will be
185 static void store_reg(DisasContext
*s
, int reg
, TCGv var
)
188 tcg_gen_andi_i32(var
, var
, ~1);
189 s
->is_jmp
= DISAS_JUMP
;
191 tcg_gen_mov_i32(cpu_R
[reg
], var
);
192 tcg_temp_free_i32(var
);
195 /* Value extensions. */
196 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
197 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
198 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
199 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
201 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
202 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
205 static inline void gen_set_cpsr(TCGv var
, uint32_t mask
)
207 TCGv tmp_mask
= tcg_const_i32(mask
);
208 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
209 tcg_temp_free_i32(tmp_mask
);
211 /* Set NZCV flags from the high 4 bits of var. */
212 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
214 static void gen_exception(int excp
)
216 TCGv tmp
= tcg_temp_new_i32();
217 tcg_gen_movi_i32(tmp
, excp
);
218 gen_helper_exception(cpu_env
, tmp
);
219 tcg_temp_free_i32(tmp
);
222 static void gen_smul_dual(TCGv a
, TCGv b
)
224 TCGv tmp1
= tcg_temp_new_i32();
225 TCGv tmp2
= tcg_temp_new_i32();
226 tcg_gen_ext16s_i32(tmp1
, a
);
227 tcg_gen_ext16s_i32(tmp2
, b
);
228 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
229 tcg_temp_free_i32(tmp2
);
230 tcg_gen_sari_i32(a
, a
, 16);
231 tcg_gen_sari_i32(b
, b
, 16);
232 tcg_gen_mul_i32(b
, b
, a
);
233 tcg_gen_mov_i32(a
, tmp1
);
234 tcg_temp_free_i32(tmp1
);
237 /* Byteswap each halfword. */
238 static void gen_rev16(TCGv var
)
240 TCGv tmp
= tcg_temp_new_i32();
241 tcg_gen_shri_i32(tmp
, var
, 8);
242 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
243 tcg_gen_shli_i32(var
, var
, 8);
244 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
245 tcg_gen_or_i32(var
, var
, tmp
);
246 tcg_temp_free_i32(tmp
);
249 /* Byteswap low halfword and sign extend. */
250 static void gen_revsh(TCGv var
)
252 tcg_gen_ext16u_i32(var
, var
);
253 tcg_gen_bswap16_i32(var
, var
);
254 tcg_gen_ext16s_i32(var
, var
);
257 /* Unsigned bitfield extract. */
258 static void gen_ubfx(TCGv var
, int shift
, uint32_t mask
)
261 tcg_gen_shri_i32(var
, var
, shift
);
262 tcg_gen_andi_i32(var
, var
, mask
);
265 /* Signed bitfield extract. */
266 static void gen_sbfx(TCGv var
, int shift
, int width
)
271 tcg_gen_sari_i32(var
, var
, shift
);
272 if (shift
+ width
< 32) {
273 signbit
= 1u << (width
- 1);
274 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
275 tcg_gen_xori_i32(var
, var
, signbit
);
276 tcg_gen_subi_i32(var
, var
, signbit
);
280 /* Return (b << 32) + a. Mark inputs as dead */
281 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv b
)
283 TCGv_i64 tmp64
= tcg_temp_new_i64();
285 tcg_gen_extu_i32_i64(tmp64
, b
);
286 tcg_temp_free_i32(b
);
287 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
288 tcg_gen_add_i64(a
, tmp64
, a
);
290 tcg_temp_free_i64(tmp64
);
294 /* Return (b << 32) - a. Mark inputs as dead. */
295 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv b
)
297 TCGv_i64 tmp64
= tcg_temp_new_i64();
299 tcg_gen_extu_i32_i64(tmp64
, b
);
300 tcg_temp_free_i32(b
);
301 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
302 tcg_gen_sub_i64(a
, tmp64
, a
);
304 tcg_temp_free_i64(tmp64
);
308 /* 32x32->64 multiply. Marks inputs as dead. */
309 static TCGv_i64
gen_mulu_i64_i32(TCGv a
, TCGv b
)
311 TCGv lo
= tcg_temp_new_i32();
312 TCGv hi
= tcg_temp_new_i32();
315 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
316 tcg_temp_free_i32(a
);
317 tcg_temp_free_i32(b
);
319 ret
= tcg_temp_new_i64();
320 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
327 static TCGv_i64
gen_muls_i64_i32(TCGv a
, TCGv b
)
329 TCGv lo
= tcg_temp_new_i32();
330 TCGv hi
= tcg_temp_new_i32();
333 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
334 tcg_temp_free_i32(a
);
335 tcg_temp_free_i32(b
);
337 ret
= tcg_temp_new_i64();
338 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
345 /* Swap low and high halfwords. */
346 static void gen_swap_half(TCGv var
)
348 TCGv tmp
= tcg_temp_new_i32();
349 tcg_gen_shri_i32(tmp
, var
, 16);
350 tcg_gen_shli_i32(var
, var
, 16);
351 tcg_gen_or_i32(var
, var
, tmp
);
352 tcg_temp_free_i32(tmp
);
355 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
356 tmp = (t0 ^ t1) & 0x8000;
359 t0 = (t0 + t1) ^ tmp;
362 static void gen_add16(TCGv t0
, TCGv t1
)
364 TCGv tmp
= tcg_temp_new_i32();
365 tcg_gen_xor_i32(tmp
, t0
, t1
);
366 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
367 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
368 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
369 tcg_gen_add_i32(t0
, t0
, t1
);
370 tcg_gen_xor_i32(t0
, t0
, tmp
);
371 tcg_temp_free_i32(tmp
);
372 tcg_temp_free_i32(t1
);
375 /* Set CF to the top bit of var. */
376 static void gen_set_CF_bit31(TCGv var
)
378 tcg_gen_shri_i32(cpu_CF
, var
, 31);
381 /* Set N and Z flags from var. */
382 static inline void gen_logic_CC(TCGv var
)
384 tcg_gen_mov_i32(cpu_NF
, var
);
385 tcg_gen_mov_i32(cpu_ZF
, var
);
389 static void gen_adc(TCGv t0
, TCGv t1
)
391 tcg_gen_add_i32(t0
, t0
, t1
);
392 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
395 /* dest = T0 + T1 + CF. */
396 static void gen_add_carry(TCGv dest
, TCGv t0
, TCGv t1
)
398 tcg_gen_add_i32(dest
, t0
, t1
);
399 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
402 /* dest = T0 - T1 + CF - 1. */
403 static void gen_sub_carry(TCGv dest
, TCGv t0
, TCGv t1
)
405 tcg_gen_sub_i32(dest
, t0
, t1
);
406 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
407 tcg_gen_subi_i32(dest
, dest
, 1);
410 /* dest = T0 + T1. Compute C, N, V and Z flags */
411 static void gen_add_CC(TCGv dest
, TCGv t0
, TCGv t1
)
414 tcg_gen_add_i32(cpu_NF
, t0
, t1
);
415 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
416 tcg_gen_setcond_i32(TCG_COND_LTU
, cpu_CF
, cpu_NF
, t0
);
417 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
418 tmp
= tcg_temp_new_i32();
419 tcg_gen_xor_i32(tmp
, t0
, t1
);
420 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
421 tcg_temp_free_i32(tmp
);
422 tcg_gen_mov_i32(dest
, cpu_NF
);
425 /* dest = T0 - T1. Compute C, N, V and Z flags */
426 static void gen_sub_CC(TCGv dest
, TCGv t0
, TCGv t1
)
429 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
430 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
431 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
432 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
433 tmp
= tcg_temp_new_i32();
434 tcg_gen_xor_i32(tmp
, t0
, t1
);
435 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
436 tcg_temp_free_i32(tmp
);
437 tcg_gen_mov_i32(dest
, cpu_NF
);
440 #define GEN_SHIFT(name) \
441 static void gen_##name(TCGv dest, TCGv t0, TCGv t1) \
443 TCGv tmp1, tmp2, tmp3; \
444 tmp1 = tcg_temp_new_i32(); \
445 tcg_gen_andi_i32(tmp1, t1, 0xff); \
446 tmp2 = tcg_const_i32(0); \
447 tmp3 = tcg_const_i32(0x1f); \
448 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
449 tcg_temp_free_i32(tmp3); \
450 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
451 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
452 tcg_temp_free_i32(tmp2); \
453 tcg_temp_free_i32(tmp1); \
459 static void gen_sar(TCGv dest
, TCGv t0
, TCGv t1
)
462 tmp1
= tcg_temp_new_i32();
463 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
464 tmp2
= tcg_const_i32(0x1f);
465 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
466 tcg_temp_free_i32(tmp2
);
467 tcg_gen_sar_i32(dest
, t0
, tmp1
);
468 tcg_temp_free_i32(tmp1
);
471 static void tcg_gen_abs_i32(TCGv dest
, TCGv src
)
473 TCGv c0
= tcg_const_i32(0);
474 TCGv tmp
= tcg_temp_new_i32();
475 tcg_gen_neg_i32(tmp
, src
);
476 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
477 tcg_temp_free_i32(c0
);
478 tcg_temp_free_i32(tmp
);
481 static void shifter_out_im(TCGv var
, int shift
)
484 tcg_gen_andi_i32(cpu_CF
, var
, 1);
486 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
488 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
493 /* Shift by immediate. Includes special handling for shift == 0. */
494 static inline void gen_arm_shift_im(TCGv var
, int shiftop
, int shift
, int flags
)
500 shifter_out_im(var
, 32 - shift
);
501 tcg_gen_shli_i32(var
, var
, shift
);
507 tcg_gen_shri_i32(cpu_CF
, var
, 31);
509 tcg_gen_movi_i32(var
, 0);
512 shifter_out_im(var
, shift
- 1);
513 tcg_gen_shri_i32(var
, var
, shift
);
520 shifter_out_im(var
, shift
- 1);
523 tcg_gen_sari_i32(var
, var
, shift
);
525 case 3: /* ROR/RRX */
528 shifter_out_im(var
, shift
- 1);
529 tcg_gen_rotri_i32(var
, var
, shift
); break;
531 TCGv tmp
= tcg_temp_new_i32();
532 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
534 shifter_out_im(var
, 0);
535 tcg_gen_shri_i32(var
, var
, 1);
536 tcg_gen_or_i32(var
, var
, tmp
);
537 tcg_temp_free_i32(tmp
);
542 static inline void gen_arm_shift_reg(TCGv var
, int shiftop
,
543 TCGv shift
, int flags
)
547 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
548 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
549 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
550 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
555 gen_shl(var
, var
, shift
);
558 gen_shr(var
, var
, shift
);
561 gen_sar(var
, var
, shift
);
563 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
564 tcg_gen_rotr_i32(var
, var
, shift
); break;
567 tcg_temp_free_i32(shift
);
570 #define PAS_OP(pfx) \
572 case 0: gen_pas_helper(glue(pfx,add16)); break; \
573 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
574 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
575 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
576 case 4: gen_pas_helper(glue(pfx,add8)); break; \
577 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
579 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
584 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
586 tmp
= tcg_temp_new_ptr();
587 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
589 tcg_temp_free_ptr(tmp
);
592 tmp
= tcg_temp_new_ptr();
593 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
595 tcg_temp_free_ptr(tmp
);
597 #undef gen_pas_helper
598 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
611 #undef gen_pas_helper
616 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
617 #define PAS_OP(pfx) \
619 case 0: gen_pas_helper(glue(pfx,add8)); break; \
620 case 1: gen_pas_helper(glue(pfx,add16)); break; \
621 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
622 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
623 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
624 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
626 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
631 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
633 tmp
= tcg_temp_new_ptr();
634 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
636 tcg_temp_free_ptr(tmp
);
639 tmp
= tcg_temp_new_ptr();
640 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
642 tcg_temp_free_ptr(tmp
);
644 #undef gen_pas_helper
645 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
658 #undef gen_pas_helper
663 static void gen_test_cc(int cc
, int label
)
670 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
673 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
676 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
679 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
682 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
685 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
688 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
691 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
693 case 8: /* hi: C && !Z */
694 inv
= gen_new_label();
695 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
696 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
699 case 9: /* ls: !C || Z */
700 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
701 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
703 case 10: /* ge: N == V -> N ^ V == 0 */
704 tmp
= tcg_temp_new_i32();
705 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
706 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
707 tcg_temp_free_i32(tmp
);
709 case 11: /* lt: N != V -> N ^ V != 0 */
710 tmp
= tcg_temp_new_i32();
711 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
712 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
713 tcg_temp_free_i32(tmp
);
715 case 12: /* gt: !Z && N == V */
716 inv
= gen_new_label();
717 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
718 tmp
= tcg_temp_new_i32();
719 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
720 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
721 tcg_temp_free_i32(tmp
);
724 case 13: /* le: Z || N != V */
725 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
726 tmp
= tcg_temp_new_i32();
727 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
728 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
729 tcg_temp_free_i32(tmp
);
732 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
737 static const uint8_t table_logic_cc
[16] = {
756 /* Set PC and Thumb state from an immediate address. */
757 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
761 s
->is_jmp
= DISAS_UPDATE
;
762 if (s
->thumb
!= (addr
& 1)) {
763 tmp
= tcg_temp_new_i32();
764 tcg_gen_movi_i32(tmp
, addr
& 1);
765 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
766 tcg_temp_free_i32(tmp
);
768 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
771 /* Set PC and Thumb state from var. var is marked as dead. */
772 static inline void gen_bx(DisasContext
*s
, TCGv var
)
774 s
->is_jmp
= DISAS_UPDATE
;
775 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
776 tcg_gen_andi_i32(var
, var
, 1);
777 store_cpu_field(var
, thumb
);
780 /* Variant of store_reg which uses branch&exchange logic when storing
781 to r15 in ARM architecture v7 and above. The source must be a temporary
782 and will be marked as dead. */
783 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
786 if (reg
== 15 && ENABLE_ARCH_7
) {
789 store_reg(s
, reg
, var
);
793 /* Variant of store_reg which uses branch&exchange logic when storing
794 * to r15 in ARM architecture v5T and above. This is used for storing
795 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
796 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
797 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
800 if (reg
== 15 && ENABLE_ARCH_5
) {
803 store_reg(s
, reg
, var
);
807 static inline TCGv
gen_ld8s(TCGv addr
, int index
)
809 TCGv tmp
= tcg_temp_new_i32();
810 tcg_gen_qemu_ld8s(tmp
, addr
, index
);
813 static inline TCGv
gen_ld8u(TCGv addr
, int index
)
815 TCGv tmp
= tcg_temp_new_i32();
816 tcg_gen_qemu_ld8u(tmp
, addr
, index
);
819 static inline TCGv
gen_ld16s(TCGv addr
, int index
)
821 TCGv tmp
= tcg_temp_new_i32();
822 tcg_gen_qemu_ld16s(tmp
, addr
, index
);
825 static inline TCGv
gen_ld16u(TCGv addr
, int index
)
827 TCGv tmp
= tcg_temp_new_i32();
828 tcg_gen_qemu_ld16u(tmp
, addr
, index
);
831 static inline TCGv
gen_ld32(TCGv addr
, int index
)
833 TCGv tmp
= tcg_temp_new_i32();
834 tcg_gen_qemu_ld32u(tmp
, addr
, index
);
837 static inline TCGv_i64
gen_ld64(TCGv addr
, int index
)
839 TCGv_i64 tmp
= tcg_temp_new_i64();
840 tcg_gen_qemu_ld64(tmp
, addr
, index
);
843 static inline void gen_st8(TCGv val
, TCGv addr
, int index
)
845 tcg_gen_qemu_st8(val
, addr
, index
);
846 tcg_temp_free_i32(val
);
848 static inline void gen_st16(TCGv val
, TCGv addr
, int index
)
850 tcg_gen_qemu_st16(val
, addr
, index
);
851 tcg_temp_free_i32(val
);
853 static inline void gen_st32(TCGv val
, TCGv addr
, int index
)
855 tcg_gen_qemu_st32(val
, addr
, index
);
856 tcg_temp_free_i32(val
);
858 static inline void gen_st64(TCGv_i64 val
, TCGv addr
, int index
)
860 tcg_gen_qemu_st64(val
, addr
, index
);
861 tcg_temp_free_i64(val
);
864 static inline void gen_set_pc_im(uint32_t val
)
866 tcg_gen_movi_i32(cpu_R
[15], val
);
869 /* Force a TB lookup after an instruction that changes the CPU state. */
870 static inline void gen_lookup_tb(DisasContext
*s
)
872 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
873 s
->is_jmp
= DISAS_UPDATE
;
876 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
879 int val
, rm
, shift
, shiftop
;
882 if (!(insn
& (1 << 25))) {
885 if (!(insn
& (1 << 23)))
888 tcg_gen_addi_i32(var
, var
, val
);
892 shift
= (insn
>> 7) & 0x1f;
893 shiftop
= (insn
>> 5) & 3;
894 offset
= load_reg(s
, rm
);
895 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
896 if (!(insn
& (1 << 23)))
897 tcg_gen_sub_i32(var
, var
, offset
);
899 tcg_gen_add_i32(var
, var
, offset
);
900 tcg_temp_free_i32(offset
);
904 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
910 if (insn
& (1 << 22)) {
912 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
913 if (!(insn
& (1 << 23)))
917 tcg_gen_addi_i32(var
, var
, val
);
921 tcg_gen_addi_i32(var
, var
, extra
);
923 offset
= load_reg(s
, rm
);
924 if (!(insn
& (1 << 23)))
925 tcg_gen_sub_i32(var
, var
, offset
);
927 tcg_gen_add_i32(var
, var
, offset
);
928 tcg_temp_free_i32(offset
);
932 static TCGv_ptr
get_fpstatus_ptr(int neon
)
934 TCGv_ptr statusptr
= tcg_temp_new_ptr();
937 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
939 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
941 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
945 #define VFP_OP2(name) \
946 static inline void gen_vfp_##name(int dp) \
948 TCGv_ptr fpst = get_fpstatus_ptr(0); \
950 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
952 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
954 tcg_temp_free_ptr(fpst); \
964 static inline void gen_vfp_F1_mul(int dp
)
966 /* Like gen_vfp_mul() but put result in F1 */
967 TCGv_ptr fpst
= get_fpstatus_ptr(0);
969 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
971 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
973 tcg_temp_free_ptr(fpst
);
976 static inline void gen_vfp_F1_neg(int dp
)
978 /* Like gen_vfp_neg() but put result in F1 */
980 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
982 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
986 static inline void gen_vfp_abs(int dp
)
989 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
991 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
994 static inline void gen_vfp_neg(int dp
)
997 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
999 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1002 static inline void gen_vfp_sqrt(int dp
)
1005 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1007 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1010 static inline void gen_vfp_cmp(int dp
)
1013 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1015 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1018 static inline void gen_vfp_cmpe(int dp
)
1021 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1023 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1026 static inline void gen_vfp_F1_ld0(int dp
)
1029 tcg_gen_movi_i64(cpu_F1d
, 0);
1031 tcg_gen_movi_i32(cpu_F1s
, 0);
1034 #define VFP_GEN_ITOF(name) \
1035 static inline void gen_vfp_##name(int dp, int neon) \
1037 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1039 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1041 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1043 tcg_temp_free_ptr(statusptr); \
1050 #define VFP_GEN_FTOI(name) \
1051 static inline void gen_vfp_##name(int dp, int neon) \
1053 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1055 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1057 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1059 tcg_temp_free_ptr(statusptr); \
1068 #define VFP_GEN_FIX(name) \
1069 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1071 TCGv tmp_shift = tcg_const_i32(shift); \
1072 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1074 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1076 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1078 tcg_temp_free_i32(tmp_shift); \
1079 tcg_temp_free_ptr(statusptr); \
1091 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv addr
)
1094 tcg_gen_qemu_ld64(cpu_F0d
, addr
, IS_USER(s
));
1096 tcg_gen_qemu_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1099 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv addr
)
1102 tcg_gen_qemu_st64(cpu_F0d
, addr
, IS_USER(s
));
1104 tcg_gen_qemu_st32(cpu_F0s
, addr
, IS_USER(s
));
1108 vfp_reg_offset (int dp
, int reg
)
1111 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1113 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1114 + offsetof(CPU_DoubleU
, l
.upper
);
1116 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1117 + offsetof(CPU_DoubleU
, l
.lower
);
1121 /* Return the offset of a 32-bit piece of a NEON register.
1122 zero is the least significant end of the register. */
1124 neon_reg_offset (int reg
, int n
)
1128 return vfp_reg_offset(0, sreg
);
1131 static TCGv
neon_load_reg(int reg
, int pass
)
1133 TCGv tmp
= tcg_temp_new_i32();
1134 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1138 static void neon_store_reg(int reg
, int pass
, TCGv var
)
1140 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1141 tcg_temp_free_i32(var
);
1144 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1146 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1149 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1151 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1154 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1155 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1156 #define tcg_gen_st_f32 tcg_gen_st_i32
1157 #define tcg_gen_st_f64 tcg_gen_st_i64
1159 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1162 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1164 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1167 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1170 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1172 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1175 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1178 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1180 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1183 #define ARM_CP_RW_BIT (1 << 20)
1185 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1187 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1190 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1192 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1195 static inline TCGv
iwmmxt_load_creg(int reg
)
1197 TCGv var
= tcg_temp_new_i32();
1198 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1202 static inline void iwmmxt_store_creg(int reg
, TCGv var
)
1204 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1205 tcg_temp_free_i32(var
);
1208 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1210 iwmmxt_store_reg(cpu_M0
, rn
);
1213 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1215 iwmmxt_load_reg(cpu_M0
, rn
);
1218 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1220 iwmmxt_load_reg(cpu_V1
, rn
);
1221 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1224 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1226 iwmmxt_load_reg(cpu_V1
, rn
);
1227 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1230 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1232 iwmmxt_load_reg(cpu_V1
, rn
);
1233 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1236 #define IWMMXT_OP(name) \
1237 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1239 iwmmxt_load_reg(cpu_V1, rn); \
1240 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1243 #define IWMMXT_OP_ENV(name) \
1244 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1246 iwmmxt_load_reg(cpu_V1, rn); \
1247 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1250 #define IWMMXT_OP_ENV_SIZE(name) \
1251 IWMMXT_OP_ENV(name##b) \
1252 IWMMXT_OP_ENV(name##w) \
1253 IWMMXT_OP_ENV(name##l)
1255 #define IWMMXT_OP_ENV1(name) \
1256 static inline void gen_op_iwmmxt_##name##_M0(void) \
1258 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1272 IWMMXT_OP_ENV_SIZE(unpackl
)
1273 IWMMXT_OP_ENV_SIZE(unpackh
)
1275 IWMMXT_OP_ENV1(unpacklub
)
1276 IWMMXT_OP_ENV1(unpackluw
)
1277 IWMMXT_OP_ENV1(unpacklul
)
1278 IWMMXT_OP_ENV1(unpackhub
)
1279 IWMMXT_OP_ENV1(unpackhuw
)
1280 IWMMXT_OP_ENV1(unpackhul
)
1281 IWMMXT_OP_ENV1(unpacklsb
)
1282 IWMMXT_OP_ENV1(unpacklsw
)
1283 IWMMXT_OP_ENV1(unpacklsl
)
1284 IWMMXT_OP_ENV1(unpackhsb
)
1285 IWMMXT_OP_ENV1(unpackhsw
)
1286 IWMMXT_OP_ENV1(unpackhsl
)
1288 IWMMXT_OP_ENV_SIZE(cmpeq
)
1289 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1290 IWMMXT_OP_ENV_SIZE(cmpgts
)
1292 IWMMXT_OP_ENV_SIZE(mins
)
1293 IWMMXT_OP_ENV_SIZE(minu
)
1294 IWMMXT_OP_ENV_SIZE(maxs
)
1295 IWMMXT_OP_ENV_SIZE(maxu
)
1297 IWMMXT_OP_ENV_SIZE(subn
)
1298 IWMMXT_OP_ENV_SIZE(addn
)
1299 IWMMXT_OP_ENV_SIZE(subu
)
1300 IWMMXT_OP_ENV_SIZE(addu
)
1301 IWMMXT_OP_ENV_SIZE(subs
)
1302 IWMMXT_OP_ENV_SIZE(adds
)
1304 IWMMXT_OP_ENV(avgb0
)
1305 IWMMXT_OP_ENV(avgb1
)
1306 IWMMXT_OP_ENV(avgw0
)
1307 IWMMXT_OP_ENV(avgw1
)
1311 IWMMXT_OP_ENV(packuw
)
1312 IWMMXT_OP_ENV(packul
)
1313 IWMMXT_OP_ENV(packuq
)
1314 IWMMXT_OP_ENV(packsw
)
1315 IWMMXT_OP_ENV(packsl
)
1316 IWMMXT_OP_ENV(packsq
)
1318 static void gen_op_iwmmxt_set_mup(void)
1321 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1322 tcg_gen_ori_i32(tmp
, tmp
, 2);
1323 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1326 static void gen_op_iwmmxt_set_cup(void)
1329 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1330 tcg_gen_ori_i32(tmp
, tmp
, 1);
1331 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1334 static void gen_op_iwmmxt_setpsr_nz(void)
1336 TCGv tmp
= tcg_temp_new_i32();
1337 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1338 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1341 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1343 iwmmxt_load_reg(cpu_V1
, rn
);
1344 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1345 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1348 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1354 rd
= (insn
>> 16) & 0xf;
1355 tmp
= load_reg(s
, rd
);
1357 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1358 if (insn
& (1 << 24)) {
1360 if (insn
& (1 << 23))
1361 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1363 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1364 tcg_gen_mov_i32(dest
, tmp
);
1365 if (insn
& (1 << 21))
1366 store_reg(s
, rd
, tmp
);
1368 tcg_temp_free_i32(tmp
);
1369 } else if (insn
& (1 << 21)) {
1371 tcg_gen_mov_i32(dest
, tmp
);
1372 if (insn
& (1 << 23))
1373 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1375 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1376 store_reg(s
, rd
, tmp
);
1377 } else if (!(insn
& (1 << 23)))
1382 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1384 int rd
= (insn
>> 0) & 0xf;
1387 if (insn
& (1 << 8)) {
1388 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1391 tmp
= iwmmxt_load_creg(rd
);
1394 tmp
= tcg_temp_new_i32();
1395 iwmmxt_load_reg(cpu_V0
, rd
);
1396 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1398 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1399 tcg_gen_mov_i32(dest
, tmp
);
1400 tcg_temp_free_i32(tmp
);
1404 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1405 (ie. an undefined instruction). */
1406 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1409 int rdhi
, rdlo
, rd0
, rd1
, i
;
1411 TCGv tmp
, tmp2
, tmp3
;
1413 if ((insn
& 0x0e000e00) == 0x0c000000) {
1414 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1416 rdlo
= (insn
>> 12) & 0xf;
1417 rdhi
= (insn
>> 16) & 0xf;
1418 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1419 iwmmxt_load_reg(cpu_V0
, wrd
);
1420 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1421 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1422 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1423 } else { /* TMCRR */
1424 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1425 iwmmxt_store_reg(cpu_V0
, wrd
);
1426 gen_op_iwmmxt_set_mup();
1431 wrd
= (insn
>> 12) & 0xf;
1432 addr
= tcg_temp_new_i32();
1433 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1434 tcg_temp_free_i32(addr
);
1437 if (insn
& ARM_CP_RW_BIT
) {
1438 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1439 tmp
= tcg_temp_new_i32();
1440 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1441 iwmmxt_store_creg(wrd
, tmp
);
1444 if (insn
& (1 << 8)) {
1445 if (insn
& (1 << 22)) { /* WLDRD */
1446 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1448 } else { /* WLDRW wRd */
1449 tmp
= gen_ld32(addr
, IS_USER(s
));
1452 if (insn
& (1 << 22)) { /* WLDRH */
1453 tmp
= gen_ld16u(addr
, IS_USER(s
));
1454 } else { /* WLDRB */
1455 tmp
= gen_ld8u(addr
, IS_USER(s
));
1459 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1460 tcg_temp_free_i32(tmp
);
1462 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1465 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1466 tmp
= iwmmxt_load_creg(wrd
);
1467 gen_st32(tmp
, addr
, IS_USER(s
));
1469 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1470 tmp
= tcg_temp_new_i32();
1471 if (insn
& (1 << 8)) {
1472 if (insn
& (1 << 22)) { /* WSTRD */
1473 tcg_temp_free_i32(tmp
);
1474 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1475 } else { /* WSTRW wRd */
1476 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1477 gen_st32(tmp
, addr
, IS_USER(s
));
1480 if (insn
& (1 << 22)) { /* WSTRH */
1481 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1482 gen_st16(tmp
, addr
, IS_USER(s
));
1483 } else { /* WSTRB */
1484 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1485 gen_st8(tmp
, addr
, IS_USER(s
));
1490 tcg_temp_free_i32(addr
);
1494 if ((insn
& 0x0f000000) != 0x0e000000)
1497 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1498 case 0x000: /* WOR */
1499 wrd
= (insn
>> 12) & 0xf;
1500 rd0
= (insn
>> 0) & 0xf;
1501 rd1
= (insn
>> 16) & 0xf;
1502 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1503 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1504 gen_op_iwmmxt_setpsr_nz();
1505 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1506 gen_op_iwmmxt_set_mup();
1507 gen_op_iwmmxt_set_cup();
1509 case 0x011: /* TMCR */
1512 rd
= (insn
>> 12) & 0xf;
1513 wrd
= (insn
>> 16) & 0xf;
1515 case ARM_IWMMXT_wCID
:
1516 case ARM_IWMMXT_wCASF
:
1518 case ARM_IWMMXT_wCon
:
1519 gen_op_iwmmxt_set_cup();
1521 case ARM_IWMMXT_wCSSF
:
1522 tmp
= iwmmxt_load_creg(wrd
);
1523 tmp2
= load_reg(s
, rd
);
1524 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1525 tcg_temp_free_i32(tmp2
);
1526 iwmmxt_store_creg(wrd
, tmp
);
1528 case ARM_IWMMXT_wCGR0
:
1529 case ARM_IWMMXT_wCGR1
:
1530 case ARM_IWMMXT_wCGR2
:
1531 case ARM_IWMMXT_wCGR3
:
1532 gen_op_iwmmxt_set_cup();
1533 tmp
= load_reg(s
, rd
);
1534 iwmmxt_store_creg(wrd
, tmp
);
1540 case 0x100: /* WXOR */
1541 wrd
= (insn
>> 12) & 0xf;
1542 rd0
= (insn
>> 0) & 0xf;
1543 rd1
= (insn
>> 16) & 0xf;
1544 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1545 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1546 gen_op_iwmmxt_setpsr_nz();
1547 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1548 gen_op_iwmmxt_set_mup();
1549 gen_op_iwmmxt_set_cup();
1551 case 0x111: /* TMRC */
1554 rd
= (insn
>> 12) & 0xf;
1555 wrd
= (insn
>> 16) & 0xf;
1556 tmp
= iwmmxt_load_creg(wrd
);
1557 store_reg(s
, rd
, tmp
);
1559 case 0x300: /* WANDN */
1560 wrd
= (insn
>> 12) & 0xf;
1561 rd0
= (insn
>> 0) & 0xf;
1562 rd1
= (insn
>> 16) & 0xf;
1563 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1564 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1565 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1566 gen_op_iwmmxt_setpsr_nz();
1567 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1568 gen_op_iwmmxt_set_mup();
1569 gen_op_iwmmxt_set_cup();
1571 case 0x200: /* WAND */
1572 wrd
= (insn
>> 12) & 0xf;
1573 rd0
= (insn
>> 0) & 0xf;
1574 rd1
= (insn
>> 16) & 0xf;
1575 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1576 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1577 gen_op_iwmmxt_setpsr_nz();
1578 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1579 gen_op_iwmmxt_set_mup();
1580 gen_op_iwmmxt_set_cup();
1582 case 0x810: case 0xa10: /* WMADD */
1583 wrd
= (insn
>> 12) & 0xf;
1584 rd0
= (insn
>> 0) & 0xf;
1585 rd1
= (insn
>> 16) & 0xf;
1586 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1587 if (insn
& (1 << 21))
1588 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1590 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1591 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1592 gen_op_iwmmxt_set_mup();
1594 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1595 wrd
= (insn
>> 12) & 0xf;
1596 rd0
= (insn
>> 16) & 0xf;
1597 rd1
= (insn
>> 0) & 0xf;
1598 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1599 switch ((insn
>> 22) & 3) {
1601 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1604 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1607 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1612 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1613 gen_op_iwmmxt_set_mup();
1614 gen_op_iwmmxt_set_cup();
1616 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1617 wrd
= (insn
>> 12) & 0xf;
1618 rd0
= (insn
>> 16) & 0xf;
1619 rd1
= (insn
>> 0) & 0xf;
1620 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1621 switch ((insn
>> 22) & 3) {
1623 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1626 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1629 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1634 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1635 gen_op_iwmmxt_set_mup();
1636 gen_op_iwmmxt_set_cup();
1638 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1639 wrd
= (insn
>> 12) & 0xf;
1640 rd0
= (insn
>> 16) & 0xf;
1641 rd1
= (insn
>> 0) & 0xf;
1642 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1643 if (insn
& (1 << 22))
1644 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1646 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1647 if (!(insn
& (1 << 20)))
1648 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1649 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1650 gen_op_iwmmxt_set_mup();
1652 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1653 wrd
= (insn
>> 12) & 0xf;
1654 rd0
= (insn
>> 16) & 0xf;
1655 rd1
= (insn
>> 0) & 0xf;
1656 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1657 if (insn
& (1 << 21)) {
1658 if (insn
& (1 << 20))
1659 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1661 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1663 if (insn
& (1 << 20))
1664 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1666 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1668 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1669 gen_op_iwmmxt_set_mup();
1671 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1672 wrd
= (insn
>> 12) & 0xf;
1673 rd0
= (insn
>> 16) & 0xf;
1674 rd1
= (insn
>> 0) & 0xf;
1675 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1676 if (insn
& (1 << 21))
1677 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1679 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1680 if (!(insn
& (1 << 20))) {
1681 iwmmxt_load_reg(cpu_V1
, wrd
);
1682 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1684 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1685 gen_op_iwmmxt_set_mup();
1687 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1688 wrd
= (insn
>> 12) & 0xf;
1689 rd0
= (insn
>> 16) & 0xf;
1690 rd1
= (insn
>> 0) & 0xf;
1691 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1692 switch ((insn
>> 22) & 3) {
1694 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1697 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1700 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1705 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1706 gen_op_iwmmxt_set_mup();
1707 gen_op_iwmmxt_set_cup();
1709 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1710 wrd
= (insn
>> 12) & 0xf;
1711 rd0
= (insn
>> 16) & 0xf;
1712 rd1
= (insn
>> 0) & 0xf;
1713 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1714 if (insn
& (1 << 22)) {
1715 if (insn
& (1 << 20))
1716 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1718 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1720 if (insn
& (1 << 20))
1721 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1723 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1725 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1726 gen_op_iwmmxt_set_mup();
1727 gen_op_iwmmxt_set_cup();
1729 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1730 wrd
= (insn
>> 12) & 0xf;
1731 rd0
= (insn
>> 16) & 0xf;
1732 rd1
= (insn
>> 0) & 0xf;
1733 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1734 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1735 tcg_gen_andi_i32(tmp
, tmp
, 7);
1736 iwmmxt_load_reg(cpu_V1
, rd1
);
1737 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1738 tcg_temp_free_i32(tmp
);
1739 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1740 gen_op_iwmmxt_set_mup();
1742 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1743 if (((insn
>> 6) & 3) == 3)
1745 rd
= (insn
>> 12) & 0xf;
1746 wrd
= (insn
>> 16) & 0xf;
1747 tmp
= load_reg(s
, rd
);
1748 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1749 switch ((insn
>> 6) & 3) {
1751 tmp2
= tcg_const_i32(0xff);
1752 tmp3
= tcg_const_i32((insn
& 7) << 3);
1755 tmp2
= tcg_const_i32(0xffff);
1756 tmp3
= tcg_const_i32((insn
& 3) << 4);
1759 tmp2
= tcg_const_i32(0xffffffff);
1760 tmp3
= tcg_const_i32((insn
& 1) << 5);
1766 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1767 tcg_temp_free(tmp3
);
1768 tcg_temp_free(tmp2
);
1769 tcg_temp_free_i32(tmp
);
1770 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1771 gen_op_iwmmxt_set_mup();
1773 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1774 rd
= (insn
>> 12) & 0xf;
1775 wrd
= (insn
>> 16) & 0xf;
1776 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1778 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1779 tmp
= tcg_temp_new_i32();
1780 switch ((insn
>> 22) & 3) {
1782 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1783 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1785 tcg_gen_ext8s_i32(tmp
, tmp
);
1787 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1791 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1792 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1794 tcg_gen_ext16s_i32(tmp
, tmp
);
1796 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1800 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1801 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1804 store_reg(s
, rd
, tmp
);
1806 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1807 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1809 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1810 switch ((insn
>> 22) & 3) {
1812 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1815 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1818 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1821 tcg_gen_shli_i32(tmp
, tmp
, 28);
1823 tcg_temp_free_i32(tmp
);
1825 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1826 if (((insn
>> 6) & 3) == 3)
1828 rd
= (insn
>> 12) & 0xf;
1829 wrd
= (insn
>> 16) & 0xf;
1830 tmp
= load_reg(s
, rd
);
1831 switch ((insn
>> 6) & 3) {
1833 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1836 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1839 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1842 tcg_temp_free_i32(tmp
);
1843 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1844 gen_op_iwmmxt_set_mup();
1846 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1847 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1849 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1850 tmp2
= tcg_temp_new_i32();
1851 tcg_gen_mov_i32(tmp2
, tmp
);
1852 switch ((insn
>> 22) & 3) {
1854 for (i
= 0; i
< 7; i
++) {
1855 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1856 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1860 for (i
= 0; i
< 3; i
++) {
1861 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1862 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1866 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1867 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1871 tcg_temp_free_i32(tmp2
);
1872 tcg_temp_free_i32(tmp
);
1874 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1875 wrd
= (insn
>> 12) & 0xf;
1876 rd0
= (insn
>> 16) & 0xf;
1877 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1878 switch ((insn
>> 22) & 3) {
1880 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1883 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1886 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1891 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1892 gen_op_iwmmxt_set_mup();
1894 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1895 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1897 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1898 tmp2
= tcg_temp_new_i32();
1899 tcg_gen_mov_i32(tmp2
, tmp
);
1900 switch ((insn
>> 22) & 3) {
1902 for (i
= 0; i
< 7; i
++) {
1903 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1904 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1908 for (i
= 0; i
< 3; i
++) {
1909 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1910 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1914 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1915 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1919 tcg_temp_free_i32(tmp2
);
1920 tcg_temp_free_i32(tmp
);
1922 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1923 rd
= (insn
>> 12) & 0xf;
1924 rd0
= (insn
>> 16) & 0xf;
1925 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1927 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1928 tmp
= tcg_temp_new_i32();
1929 switch ((insn
>> 22) & 3) {
1931 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1934 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1937 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1940 store_reg(s
, rd
, tmp
);
1942 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1943 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1944 wrd
= (insn
>> 12) & 0xf;
1945 rd0
= (insn
>> 16) & 0xf;
1946 rd1
= (insn
>> 0) & 0xf;
1947 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1948 switch ((insn
>> 22) & 3) {
1950 if (insn
& (1 << 21))
1951 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1953 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1956 if (insn
& (1 << 21))
1957 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1959 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1962 if (insn
& (1 << 21))
1963 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1965 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1970 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1971 gen_op_iwmmxt_set_mup();
1972 gen_op_iwmmxt_set_cup();
1974 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1975 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1976 wrd
= (insn
>> 12) & 0xf;
1977 rd0
= (insn
>> 16) & 0xf;
1978 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1979 switch ((insn
>> 22) & 3) {
1981 if (insn
& (1 << 21))
1982 gen_op_iwmmxt_unpacklsb_M0();
1984 gen_op_iwmmxt_unpacklub_M0();
1987 if (insn
& (1 << 21))
1988 gen_op_iwmmxt_unpacklsw_M0();
1990 gen_op_iwmmxt_unpackluw_M0();
1993 if (insn
& (1 << 21))
1994 gen_op_iwmmxt_unpacklsl_M0();
1996 gen_op_iwmmxt_unpacklul_M0();
2001 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2002 gen_op_iwmmxt_set_mup();
2003 gen_op_iwmmxt_set_cup();
2005 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2006 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2007 wrd
= (insn
>> 12) & 0xf;
2008 rd0
= (insn
>> 16) & 0xf;
2009 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2010 switch ((insn
>> 22) & 3) {
2012 if (insn
& (1 << 21))
2013 gen_op_iwmmxt_unpackhsb_M0();
2015 gen_op_iwmmxt_unpackhub_M0();
2018 if (insn
& (1 << 21))
2019 gen_op_iwmmxt_unpackhsw_M0();
2021 gen_op_iwmmxt_unpackhuw_M0();
2024 if (insn
& (1 << 21))
2025 gen_op_iwmmxt_unpackhsl_M0();
2027 gen_op_iwmmxt_unpackhul_M0();
2032 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2033 gen_op_iwmmxt_set_mup();
2034 gen_op_iwmmxt_set_cup();
2036 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2037 case 0x214: case 0x614: case 0xa14: case 0xe14:
2038 if (((insn
>> 22) & 3) == 0)
2040 wrd
= (insn
>> 12) & 0xf;
2041 rd0
= (insn
>> 16) & 0xf;
2042 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2043 tmp
= tcg_temp_new_i32();
2044 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2045 tcg_temp_free_i32(tmp
);
2048 switch ((insn
>> 22) & 3) {
2050 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2053 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2056 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2059 tcg_temp_free_i32(tmp
);
2060 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2061 gen_op_iwmmxt_set_mup();
2062 gen_op_iwmmxt_set_cup();
2064 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2065 case 0x014: case 0x414: case 0x814: case 0xc14:
2066 if (((insn
>> 22) & 3) == 0)
2068 wrd
= (insn
>> 12) & 0xf;
2069 rd0
= (insn
>> 16) & 0xf;
2070 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2071 tmp
= tcg_temp_new_i32();
2072 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2073 tcg_temp_free_i32(tmp
);
2076 switch ((insn
>> 22) & 3) {
2078 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2081 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2084 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2087 tcg_temp_free_i32(tmp
);
2088 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2089 gen_op_iwmmxt_set_mup();
2090 gen_op_iwmmxt_set_cup();
2092 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2093 case 0x114: case 0x514: case 0x914: case 0xd14:
2094 if (((insn
>> 22) & 3) == 0)
2096 wrd
= (insn
>> 12) & 0xf;
2097 rd0
= (insn
>> 16) & 0xf;
2098 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2099 tmp
= tcg_temp_new_i32();
2100 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2101 tcg_temp_free_i32(tmp
);
2104 switch ((insn
>> 22) & 3) {
2106 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2109 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2112 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2115 tcg_temp_free_i32(tmp
);
2116 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2117 gen_op_iwmmxt_set_mup();
2118 gen_op_iwmmxt_set_cup();
2120 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2121 case 0x314: case 0x714: case 0xb14: case 0xf14:
2122 if (((insn
>> 22) & 3) == 0)
2124 wrd
= (insn
>> 12) & 0xf;
2125 rd0
= (insn
>> 16) & 0xf;
2126 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2127 tmp
= tcg_temp_new_i32();
2128 switch ((insn
>> 22) & 3) {
2130 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2131 tcg_temp_free_i32(tmp
);
2134 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2137 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2138 tcg_temp_free_i32(tmp
);
2141 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2144 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2145 tcg_temp_free_i32(tmp
);
2148 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2151 tcg_temp_free_i32(tmp
);
2152 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2153 gen_op_iwmmxt_set_mup();
2154 gen_op_iwmmxt_set_cup();
2156 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2157 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2158 wrd
= (insn
>> 12) & 0xf;
2159 rd0
= (insn
>> 16) & 0xf;
2160 rd1
= (insn
>> 0) & 0xf;
2161 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2162 switch ((insn
>> 22) & 3) {
2164 if (insn
& (1 << 21))
2165 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2167 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2170 if (insn
& (1 << 21))
2171 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2173 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2176 if (insn
& (1 << 21))
2177 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2179 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2184 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2185 gen_op_iwmmxt_set_mup();
2187 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2188 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2189 wrd
= (insn
>> 12) & 0xf;
2190 rd0
= (insn
>> 16) & 0xf;
2191 rd1
= (insn
>> 0) & 0xf;
2192 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2193 switch ((insn
>> 22) & 3) {
2195 if (insn
& (1 << 21))
2196 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2198 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2201 if (insn
& (1 << 21))
2202 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2204 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2207 if (insn
& (1 << 21))
2208 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2210 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2215 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2216 gen_op_iwmmxt_set_mup();
2218 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2219 case 0x402: case 0x502: case 0x602: case 0x702:
2220 wrd
= (insn
>> 12) & 0xf;
2221 rd0
= (insn
>> 16) & 0xf;
2222 rd1
= (insn
>> 0) & 0xf;
2223 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2224 tmp
= tcg_const_i32((insn
>> 20) & 3);
2225 iwmmxt_load_reg(cpu_V1
, rd1
);
2226 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2228 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2229 gen_op_iwmmxt_set_mup();
2231 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2232 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2233 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2234 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2235 wrd
= (insn
>> 12) & 0xf;
2236 rd0
= (insn
>> 16) & 0xf;
2237 rd1
= (insn
>> 0) & 0xf;
2238 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2239 switch ((insn
>> 20) & 0xf) {
2241 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2244 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2247 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2250 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2253 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2256 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2259 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2262 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2265 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2270 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2271 gen_op_iwmmxt_set_mup();
2272 gen_op_iwmmxt_set_cup();
2274 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2275 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2276 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2277 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2278 wrd
= (insn
>> 12) & 0xf;
2279 rd0
= (insn
>> 16) & 0xf;
2280 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2281 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2282 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2284 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2285 gen_op_iwmmxt_set_mup();
2286 gen_op_iwmmxt_set_cup();
2288 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2289 case 0x418: case 0x518: case 0x618: case 0x718:
2290 case 0x818: case 0x918: case 0xa18: case 0xb18:
2291 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2292 wrd
= (insn
>> 12) & 0xf;
2293 rd0
= (insn
>> 16) & 0xf;
2294 rd1
= (insn
>> 0) & 0xf;
2295 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2296 switch ((insn
>> 20) & 0xf) {
2298 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2301 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2304 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2307 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2310 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2313 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2316 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2319 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2322 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2327 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2328 gen_op_iwmmxt_set_mup();
2329 gen_op_iwmmxt_set_cup();
2331 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2332 case 0x408: case 0x508: case 0x608: case 0x708:
2333 case 0x808: case 0x908: case 0xa08: case 0xb08:
2334 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2335 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2337 wrd
= (insn
>> 12) & 0xf;
2338 rd0
= (insn
>> 16) & 0xf;
2339 rd1
= (insn
>> 0) & 0xf;
2340 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2341 switch ((insn
>> 22) & 3) {
2343 if (insn
& (1 << 21))
2344 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2346 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2349 if (insn
& (1 << 21))
2350 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2352 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2355 if (insn
& (1 << 21))
2356 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2358 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2361 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2362 gen_op_iwmmxt_set_mup();
2363 gen_op_iwmmxt_set_cup();
2365 case 0x201: case 0x203: case 0x205: case 0x207:
2366 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2367 case 0x211: case 0x213: case 0x215: case 0x217:
2368 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2369 wrd
= (insn
>> 5) & 0xf;
2370 rd0
= (insn
>> 12) & 0xf;
2371 rd1
= (insn
>> 0) & 0xf;
2372 if (rd0
== 0xf || rd1
== 0xf)
2374 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2375 tmp
= load_reg(s
, rd0
);
2376 tmp2
= load_reg(s
, rd1
);
2377 switch ((insn
>> 16) & 0xf) {
2378 case 0x0: /* TMIA */
2379 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2381 case 0x8: /* TMIAPH */
2382 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2384 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2385 if (insn
& (1 << 16))
2386 tcg_gen_shri_i32(tmp
, tmp
, 16);
2387 if (insn
& (1 << 17))
2388 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2389 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2392 tcg_temp_free_i32(tmp2
);
2393 tcg_temp_free_i32(tmp
);
2396 tcg_temp_free_i32(tmp2
);
2397 tcg_temp_free_i32(tmp
);
2398 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2399 gen_op_iwmmxt_set_mup();
2408 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2409 (ie. an undefined instruction). */
2410 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2412 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2415 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2416 /* Multiply with Internal Accumulate Format */
2417 rd0
= (insn
>> 12) & 0xf;
2419 acc
= (insn
>> 5) & 7;
2424 tmp
= load_reg(s
, rd0
);
2425 tmp2
= load_reg(s
, rd1
);
2426 switch ((insn
>> 16) & 0xf) {
2428 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2430 case 0x8: /* MIAPH */
2431 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2433 case 0xc: /* MIABB */
2434 case 0xd: /* MIABT */
2435 case 0xe: /* MIATB */
2436 case 0xf: /* MIATT */
2437 if (insn
& (1 << 16))
2438 tcg_gen_shri_i32(tmp
, tmp
, 16);
2439 if (insn
& (1 << 17))
2440 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2441 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2446 tcg_temp_free_i32(tmp2
);
2447 tcg_temp_free_i32(tmp
);
2449 gen_op_iwmmxt_movq_wRn_M0(acc
);
2453 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2454 /* Internal Accumulator Access Format */
2455 rdhi
= (insn
>> 16) & 0xf;
2456 rdlo
= (insn
>> 12) & 0xf;
2462 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2463 iwmmxt_load_reg(cpu_V0
, acc
);
2464 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2465 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2466 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2467 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2469 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2470 iwmmxt_store_reg(cpu_V0
, acc
);
2478 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2479 #define VFP_SREG(insn, bigbit, smallbit) \
2480 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2481 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2482 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2483 reg = (((insn) >> (bigbit)) & 0x0f) \
2484 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2486 if (insn & (1 << (smallbit))) \
2488 reg = ((insn) >> (bigbit)) & 0x0f; \
2491 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2492 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2493 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2494 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2495 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2496 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2498 /* Move between integer and VFP cores. */
2499 static TCGv
gen_vfp_mrs(void)
2501 TCGv tmp
= tcg_temp_new_i32();
2502 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2506 static void gen_vfp_msr(TCGv tmp
)
2508 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2509 tcg_temp_free_i32(tmp
);
2512 static void gen_neon_dup_u8(TCGv var
, int shift
)
2514 TCGv tmp
= tcg_temp_new_i32();
2516 tcg_gen_shri_i32(var
, var
, shift
);
2517 tcg_gen_ext8u_i32(var
, var
);
2518 tcg_gen_shli_i32(tmp
, var
, 8);
2519 tcg_gen_or_i32(var
, var
, tmp
);
2520 tcg_gen_shli_i32(tmp
, var
, 16);
2521 tcg_gen_or_i32(var
, var
, tmp
);
2522 tcg_temp_free_i32(tmp
);
2525 static void gen_neon_dup_low16(TCGv var
)
2527 TCGv tmp
= tcg_temp_new_i32();
2528 tcg_gen_ext16u_i32(var
, var
);
2529 tcg_gen_shli_i32(tmp
, var
, 16);
2530 tcg_gen_or_i32(var
, var
, tmp
);
2531 tcg_temp_free_i32(tmp
);
2534 static void gen_neon_dup_high16(TCGv var
)
2536 TCGv tmp
= tcg_temp_new_i32();
2537 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2538 tcg_gen_shri_i32(tmp
, var
, 16);
2539 tcg_gen_or_i32(var
, var
, tmp
);
2540 tcg_temp_free_i32(tmp
);
2543 static TCGv
gen_load_and_replicate(DisasContext
*s
, TCGv addr
, int size
)
2545 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2549 tmp
= gen_ld8u(addr
, IS_USER(s
));
2550 gen_neon_dup_u8(tmp
, 0);
2553 tmp
= gen_ld16u(addr
, IS_USER(s
));
2554 gen_neon_dup_low16(tmp
);
2557 tmp
= gen_ld32(addr
, IS_USER(s
));
2559 default: /* Avoid compiler warnings. */
2565 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2566 (ie. an undefined instruction). */
2567 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2569 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2575 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2578 if (!s
->vfp_enabled
) {
2579 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2580 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2582 rn
= (insn
>> 16) & 0xf;
2583 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2584 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2587 dp
= ((insn
& 0xf00) == 0xb00);
2588 switch ((insn
>> 24) & 0xf) {
2590 if (insn
& (1 << 4)) {
2591 /* single register transfer */
2592 rd
= (insn
>> 12) & 0xf;
2597 VFP_DREG_N(rn
, insn
);
2600 if (insn
& 0x00c00060
2601 && !arm_feature(env
, ARM_FEATURE_NEON
))
2604 pass
= (insn
>> 21) & 1;
2605 if (insn
& (1 << 22)) {
2607 offset
= ((insn
>> 5) & 3) * 8;
2608 } else if (insn
& (1 << 5)) {
2610 offset
= (insn
& (1 << 6)) ? 16 : 0;
2615 if (insn
& ARM_CP_RW_BIT
) {
2617 tmp
= neon_load_reg(rn
, pass
);
2621 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2622 if (insn
& (1 << 23))
2628 if (insn
& (1 << 23)) {
2630 tcg_gen_shri_i32(tmp
, tmp
, 16);
2636 tcg_gen_sari_i32(tmp
, tmp
, 16);
2645 store_reg(s
, rd
, tmp
);
2648 tmp
= load_reg(s
, rd
);
2649 if (insn
& (1 << 23)) {
2652 gen_neon_dup_u8(tmp
, 0);
2653 } else if (size
== 1) {
2654 gen_neon_dup_low16(tmp
);
2656 for (n
= 0; n
<= pass
* 2; n
++) {
2657 tmp2
= tcg_temp_new_i32();
2658 tcg_gen_mov_i32(tmp2
, tmp
);
2659 neon_store_reg(rn
, n
, tmp2
);
2661 neon_store_reg(rn
, n
, tmp
);
2666 tmp2
= neon_load_reg(rn
, pass
);
2667 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
2668 tcg_temp_free_i32(tmp2
);
2671 tmp2
= neon_load_reg(rn
, pass
);
2672 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
2673 tcg_temp_free_i32(tmp2
);
2678 neon_store_reg(rn
, pass
, tmp
);
2682 if ((insn
& 0x6f) != 0x00)
2684 rn
= VFP_SREG_N(insn
);
2685 if (insn
& ARM_CP_RW_BIT
) {
2687 if (insn
& (1 << 21)) {
2688 /* system register */
2693 /* VFP2 allows access to FSID from userspace.
2694 VFP3 restricts all id registers to privileged
2697 && arm_feature(env
, ARM_FEATURE_VFP3
))
2699 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2704 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2706 case ARM_VFP_FPINST
:
2707 case ARM_VFP_FPINST2
:
2708 /* Not present in VFP3. */
2710 || arm_feature(env
, ARM_FEATURE_VFP3
))
2712 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2716 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2717 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2719 tmp
= tcg_temp_new_i32();
2720 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2726 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2728 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2734 gen_mov_F0_vreg(0, rn
);
2735 tmp
= gen_vfp_mrs();
2738 /* Set the 4 flag bits in the CPSR. */
2740 tcg_temp_free_i32(tmp
);
2742 store_reg(s
, rd
, tmp
);
2746 if (insn
& (1 << 21)) {
2748 /* system register */
2753 /* Writes are ignored. */
2756 tmp
= load_reg(s
, rd
);
2757 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2758 tcg_temp_free_i32(tmp
);
2764 /* TODO: VFP subarchitecture support.
2765 * For now, keep the EN bit only */
2766 tmp
= load_reg(s
, rd
);
2767 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2768 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2771 case ARM_VFP_FPINST
:
2772 case ARM_VFP_FPINST2
:
2773 tmp
= load_reg(s
, rd
);
2774 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2780 tmp
= load_reg(s
, rd
);
2782 gen_mov_vreg_F0(0, rn
);
2787 /* data processing */
2788 /* The opcode is in bits 23, 21, 20 and 6. */
2789 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2793 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2795 /* rn is register number */
2796 VFP_DREG_N(rn
, insn
);
2799 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2800 /* Integer or single precision destination. */
2801 rd
= VFP_SREG_D(insn
);
2803 VFP_DREG_D(rd
, insn
);
2806 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2807 /* VCVT from int is always from S reg regardless of dp bit.
2808 * VCVT with immediate frac_bits has same format as SREG_M
2810 rm
= VFP_SREG_M(insn
);
2812 VFP_DREG_M(rm
, insn
);
2815 rn
= VFP_SREG_N(insn
);
2816 if (op
== 15 && rn
== 15) {
2817 /* Double precision destination. */
2818 VFP_DREG_D(rd
, insn
);
2820 rd
= VFP_SREG_D(insn
);
2822 /* NB that we implicitly rely on the encoding for the frac_bits
2823 * in VCVT of fixed to float being the same as that of an SREG_M
2825 rm
= VFP_SREG_M(insn
);
2828 veclen
= s
->vec_len
;
2829 if (op
== 15 && rn
> 3)
2832 /* Shut up compiler warnings. */
2843 /* Figure out what type of vector operation this is. */
2844 if ((rd
& bank_mask
) == 0) {
2849 delta_d
= (s
->vec_stride
>> 1) + 1;
2851 delta_d
= s
->vec_stride
+ 1;
2853 if ((rm
& bank_mask
) == 0) {
2854 /* mixed scalar/vector */
2863 /* Load the initial operands. */
2868 /* Integer source */
2869 gen_mov_F0_vreg(0, rm
);
2874 gen_mov_F0_vreg(dp
, rd
);
2875 gen_mov_F1_vreg(dp
, rm
);
2879 /* Compare with zero */
2880 gen_mov_F0_vreg(dp
, rd
);
2891 /* Source and destination the same. */
2892 gen_mov_F0_vreg(dp
, rd
);
2898 /* VCVTB, VCVTT: only present with the halfprec extension,
2899 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2901 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
2904 /* Otherwise fall through */
2906 /* One source operand. */
2907 gen_mov_F0_vreg(dp
, rm
);
2911 /* Two source operands. */
2912 gen_mov_F0_vreg(dp
, rn
);
2913 gen_mov_F1_vreg(dp
, rm
);
2917 /* Perform the calculation. */
2919 case 0: /* VMLA: fd + (fn * fm) */
2920 /* Note that order of inputs to the add matters for NaNs */
2922 gen_mov_F0_vreg(dp
, rd
);
2925 case 1: /* VMLS: fd + -(fn * fm) */
2928 gen_mov_F0_vreg(dp
, rd
);
2931 case 2: /* VNMLS: -fd + (fn * fm) */
2932 /* Note that it isn't valid to replace (-A + B) with (B - A)
2933 * or similar plausible looking simplifications
2934 * because this will give wrong results for NaNs.
2937 gen_mov_F0_vreg(dp
, rd
);
2941 case 3: /* VNMLA: -fd + -(fn * fm) */
2944 gen_mov_F0_vreg(dp
, rd
);
2948 case 4: /* mul: fn * fm */
2951 case 5: /* nmul: -(fn * fm) */
2955 case 6: /* add: fn + fm */
2958 case 7: /* sub: fn - fm */
2961 case 8: /* div: fn / fm */
2964 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
2965 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
2966 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
2967 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
2968 /* These are fused multiply-add, and must be done as one
2969 * floating point operation with no rounding between the
2970 * multiplication and addition steps.
2971 * NB that doing the negations here as separate steps is
2972 * correct : an input NaN should come out with its sign bit
2973 * flipped if it is a negated-input.
2975 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
2983 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
2985 frd
= tcg_temp_new_i64();
2986 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
2989 gen_helper_vfp_negd(frd
, frd
);
2991 fpst
= get_fpstatus_ptr(0);
2992 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
2993 cpu_F1d
, frd
, fpst
);
2994 tcg_temp_free_ptr(fpst
);
2995 tcg_temp_free_i64(frd
);
3001 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3003 frd
= tcg_temp_new_i32();
3004 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3006 gen_helper_vfp_negs(frd
, frd
);
3008 fpst
= get_fpstatus_ptr(0);
3009 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3010 cpu_F1s
, frd
, fpst
);
3011 tcg_temp_free_ptr(fpst
);
3012 tcg_temp_free_i32(frd
);
3015 case 14: /* fconst */
3016 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3019 n
= (insn
<< 12) & 0x80000000;
3020 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3027 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3034 tcg_gen_movi_i32(cpu_F0s
, n
);
3037 case 15: /* extension space */
3051 case 4: /* vcvtb.f32.f16 */
3052 tmp
= gen_vfp_mrs();
3053 tcg_gen_ext16u_i32(tmp
, tmp
);
3054 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3055 tcg_temp_free_i32(tmp
);
3057 case 5: /* vcvtt.f32.f16 */
3058 tmp
= gen_vfp_mrs();
3059 tcg_gen_shri_i32(tmp
, tmp
, 16);
3060 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3061 tcg_temp_free_i32(tmp
);
3063 case 6: /* vcvtb.f16.f32 */
3064 tmp
= tcg_temp_new_i32();
3065 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3066 gen_mov_F0_vreg(0, rd
);
3067 tmp2
= gen_vfp_mrs();
3068 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3069 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3070 tcg_temp_free_i32(tmp2
);
3073 case 7: /* vcvtt.f16.f32 */
3074 tmp
= tcg_temp_new_i32();
3075 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3076 tcg_gen_shli_i32(tmp
, tmp
, 16);
3077 gen_mov_F0_vreg(0, rd
);
3078 tmp2
= gen_vfp_mrs();
3079 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3080 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3081 tcg_temp_free_i32(tmp2
);
3093 case 11: /* cmpez */
3097 case 15: /* single<->double conversion */
3099 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3101 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3103 case 16: /* fuito */
3104 gen_vfp_uito(dp
, 0);
3106 case 17: /* fsito */
3107 gen_vfp_sito(dp
, 0);
3109 case 20: /* fshto */
3110 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3112 gen_vfp_shto(dp
, 16 - rm
, 0);
3114 case 21: /* fslto */
3115 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3117 gen_vfp_slto(dp
, 32 - rm
, 0);
3119 case 22: /* fuhto */
3120 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3122 gen_vfp_uhto(dp
, 16 - rm
, 0);
3124 case 23: /* fulto */
3125 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3127 gen_vfp_ulto(dp
, 32 - rm
, 0);
3129 case 24: /* ftoui */
3130 gen_vfp_toui(dp
, 0);
3132 case 25: /* ftouiz */
3133 gen_vfp_touiz(dp
, 0);
3135 case 26: /* ftosi */
3136 gen_vfp_tosi(dp
, 0);
3138 case 27: /* ftosiz */
3139 gen_vfp_tosiz(dp
, 0);
3141 case 28: /* ftosh */
3142 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3144 gen_vfp_tosh(dp
, 16 - rm
, 0);
3146 case 29: /* ftosl */
3147 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3149 gen_vfp_tosl(dp
, 32 - rm
, 0);
3151 case 30: /* ftouh */
3152 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3154 gen_vfp_touh(dp
, 16 - rm
, 0);
3156 case 31: /* ftoul */
3157 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3159 gen_vfp_toul(dp
, 32 - rm
, 0);
3161 default: /* undefined */
3165 default: /* undefined */
3169 /* Write back the result. */
3170 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3171 ; /* Comparison, do nothing. */
3172 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3173 /* VCVT double to int: always integer result. */
3174 gen_mov_vreg_F0(0, rd
);
3175 else if (op
== 15 && rn
== 15)
3177 gen_mov_vreg_F0(!dp
, rd
);
3179 gen_mov_vreg_F0(dp
, rd
);
3181 /* break out of the loop if we have finished */
3185 if (op
== 15 && delta_m
== 0) {
3186 /* single source one-many */
3188 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3190 gen_mov_vreg_F0(dp
, rd
);
3194 /* Setup the next operands. */
3196 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3200 /* One source operand. */
3201 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3203 gen_mov_F0_vreg(dp
, rm
);
3205 /* Two source operands. */
3206 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3208 gen_mov_F0_vreg(dp
, rn
);
3210 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3212 gen_mov_F1_vreg(dp
, rm
);
3220 if ((insn
& 0x03e00000) == 0x00400000) {
3221 /* two-register transfer */
3222 rn
= (insn
>> 16) & 0xf;
3223 rd
= (insn
>> 12) & 0xf;
3225 VFP_DREG_M(rm
, insn
);
3227 rm
= VFP_SREG_M(insn
);
3230 if (insn
& ARM_CP_RW_BIT
) {
3233 gen_mov_F0_vreg(0, rm
* 2);
3234 tmp
= gen_vfp_mrs();
3235 store_reg(s
, rd
, tmp
);
3236 gen_mov_F0_vreg(0, rm
* 2 + 1);
3237 tmp
= gen_vfp_mrs();
3238 store_reg(s
, rn
, tmp
);
3240 gen_mov_F0_vreg(0, rm
);
3241 tmp
= gen_vfp_mrs();
3242 store_reg(s
, rd
, tmp
);
3243 gen_mov_F0_vreg(0, rm
+ 1);
3244 tmp
= gen_vfp_mrs();
3245 store_reg(s
, rn
, tmp
);
3250 tmp
= load_reg(s
, rd
);
3252 gen_mov_vreg_F0(0, rm
* 2);
3253 tmp
= load_reg(s
, rn
);
3255 gen_mov_vreg_F0(0, rm
* 2 + 1);
3257 tmp
= load_reg(s
, rd
);
3259 gen_mov_vreg_F0(0, rm
);
3260 tmp
= load_reg(s
, rn
);
3262 gen_mov_vreg_F0(0, rm
+ 1);
3267 rn
= (insn
>> 16) & 0xf;
3269 VFP_DREG_D(rd
, insn
);
3271 rd
= VFP_SREG_D(insn
);
3272 if ((insn
& 0x01200000) == 0x01000000) {
3273 /* Single load/store */
3274 offset
= (insn
& 0xff) << 2;
3275 if ((insn
& (1 << 23)) == 0)
3277 if (s
->thumb
&& rn
== 15) {
3278 /* This is actually UNPREDICTABLE */
3279 addr
= tcg_temp_new_i32();
3280 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3282 addr
= load_reg(s
, rn
);
3284 tcg_gen_addi_i32(addr
, addr
, offset
);
3285 if (insn
& (1 << 20)) {
3286 gen_vfp_ld(s
, dp
, addr
);
3287 gen_mov_vreg_F0(dp
, rd
);
3289 gen_mov_F0_vreg(dp
, rd
);
3290 gen_vfp_st(s
, dp
, addr
);
3292 tcg_temp_free_i32(addr
);
3294 /* load/store multiple */
3295 int w
= insn
& (1 << 21);
3297 n
= (insn
>> 1) & 0x7f;
3301 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3302 /* P == U , W == 1 => UNDEF */
3305 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3306 /* UNPREDICTABLE cases for bad immediates: we choose to
3307 * UNDEF to avoid generating huge numbers of TCG ops
3311 if (rn
== 15 && w
) {
3312 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3316 if (s
->thumb
&& rn
== 15) {
3317 /* This is actually UNPREDICTABLE */
3318 addr
= tcg_temp_new_i32();
3319 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3321 addr
= load_reg(s
, rn
);
3323 if (insn
& (1 << 24)) /* pre-decrement */
3324 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3330 for (i
= 0; i
< n
; i
++) {
3331 if (insn
& ARM_CP_RW_BIT
) {
3333 gen_vfp_ld(s
, dp
, addr
);
3334 gen_mov_vreg_F0(dp
, rd
+ i
);
3337 gen_mov_F0_vreg(dp
, rd
+ i
);
3338 gen_vfp_st(s
, dp
, addr
);
3340 tcg_gen_addi_i32(addr
, addr
, offset
);
3344 if (insn
& (1 << 24))
3345 offset
= -offset
* n
;
3346 else if (dp
&& (insn
& 1))
3352 tcg_gen_addi_i32(addr
, addr
, offset
);
3353 store_reg(s
, rn
, addr
);
3355 tcg_temp_free_i32(addr
);
3361 /* Should never happen. */
3367 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3369 TranslationBlock
*tb
;
3372 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3374 gen_set_pc_im(dest
);
3375 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3377 gen_set_pc_im(dest
);
3382 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3384 if (unlikely(s
->singlestep_enabled
)) {
3385 /* An indirect jump so that we still trigger the debug exception. */
3390 gen_goto_tb(s
, 0, dest
);
3391 s
->is_jmp
= DISAS_TB_JUMP
;
3395 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3398 tcg_gen_sari_i32(t0
, t0
, 16);
3402 tcg_gen_sari_i32(t1
, t1
, 16);
3405 tcg_gen_mul_i32(t0
, t0
, t1
);
3408 /* Return the mask of PSR bits set by a MSR instruction. */
3409 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3413 if (flags
& (1 << 0))
3415 if (flags
& (1 << 1))
3417 if (flags
& (1 << 2))
3419 if (flags
& (1 << 3))
3422 /* Mask out undefined bits. */
3423 mask
&= ~CPSR_RESERVED
;
3424 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3426 if (!arm_feature(env
, ARM_FEATURE_V5
))
3427 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3428 if (!arm_feature(env
, ARM_FEATURE_V6
))
3429 mask
&= ~(CPSR_E
| CPSR_GE
);
3430 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3432 /* Mask out execution state bits. */
3435 /* Mask out privileged bits. */
3441 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3442 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3446 /* ??? This is also undefined in system mode. */
3450 tmp
= load_cpu_field(spsr
);
3451 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3452 tcg_gen_andi_i32(t0
, t0
, mask
);
3453 tcg_gen_or_i32(tmp
, tmp
, t0
);
3454 store_cpu_field(tmp
, spsr
);
3456 gen_set_cpsr(t0
, mask
);
3458 tcg_temp_free_i32(t0
);
3463 /* Returns nonzero if access to the PSR is not permitted. */
3464 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3467 tmp
= tcg_temp_new_i32();
3468 tcg_gen_movi_i32(tmp
, val
);
3469 return gen_set_psr(s
, mask
, spsr
, tmp
);
3472 /* Generate an old-style exception return. Marks pc as dead. */
3473 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3476 store_reg(s
, 15, pc
);
3477 tmp
= load_cpu_field(spsr
);
3478 gen_set_cpsr(tmp
, 0xffffffff);
3479 tcg_temp_free_i32(tmp
);
3480 s
->is_jmp
= DISAS_UPDATE
;
3483 /* Generate a v6 exception return. Marks both values as dead. */
3484 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3486 gen_set_cpsr(cpsr
, 0xffffffff);
3487 tcg_temp_free_i32(cpsr
);
3488 store_reg(s
, 15, pc
);
3489 s
->is_jmp
= DISAS_UPDATE
;
3493 gen_set_condexec (DisasContext
*s
)
3495 if (s
->condexec_mask
) {
3496 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3497 TCGv tmp
= tcg_temp_new_i32();
3498 tcg_gen_movi_i32(tmp
, val
);
3499 store_cpu_field(tmp
, condexec_bits
);
3503 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3505 gen_set_condexec(s
);
3506 gen_set_pc_im(s
->pc
- offset
);
3507 gen_exception(excp
);
3508 s
->is_jmp
= DISAS_JUMP
;
3511 static void gen_nop_hint(DisasContext
*s
, int val
)
3515 gen_set_pc_im(s
->pc
);
3516 s
->is_jmp
= DISAS_WFI
;
3520 /* TODO: Implement SEV and WFE. May help SMP performance. */
3526 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3528 static inline void gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3531 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3532 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3533 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3538 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3541 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3542 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3543 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3548 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3549 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3550 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3551 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3552 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3554 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3555 switch ((size << 1) | u) { \
3557 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3560 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3563 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3566 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3569 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3572 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3574 default: return 1; \
3577 #define GEN_NEON_INTEGER_OP(name) do { \
3578 switch ((size << 1) | u) { \
3580 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3583 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3586 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3589 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3592 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3595 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3597 default: return 1; \
3600 static TCGv
neon_load_scratch(int scratch
)
3602 TCGv tmp
= tcg_temp_new_i32();
3603 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3607 static void neon_store_scratch(int scratch
, TCGv var
)
3609 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3610 tcg_temp_free_i32(var
);
3613 static inline TCGv
neon_get_scalar(int size
, int reg
)
3617 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3619 gen_neon_dup_high16(tmp
);
3621 gen_neon_dup_low16(tmp
);
3624 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3629 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3632 if (!q
&& size
== 2) {
3635 tmp
= tcg_const_i32(rd
);
3636 tmp2
= tcg_const_i32(rm
);
3640 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3643 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3646 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3654 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3657 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3663 tcg_temp_free_i32(tmp
);
3664 tcg_temp_free_i32(tmp2
);
3668 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3671 if (!q
&& size
== 2) {
3674 tmp
= tcg_const_i32(rd
);
3675 tmp2
= tcg_const_i32(rm
);
3679 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3682 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3685 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3693 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3696 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3702 tcg_temp_free_i32(tmp
);
3703 tcg_temp_free_i32(tmp2
);
3707 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3711 rd
= tcg_temp_new_i32();
3712 tmp
= tcg_temp_new_i32();
3714 tcg_gen_shli_i32(rd
, t0
, 8);
3715 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3716 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3717 tcg_gen_or_i32(rd
, rd
, tmp
);
3719 tcg_gen_shri_i32(t1
, t1
, 8);
3720 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3721 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3722 tcg_gen_or_i32(t1
, t1
, tmp
);
3723 tcg_gen_mov_i32(t0
, rd
);
3725 tcg_temp_free_i32(tmp
);
3726 tcg_temp_free_i32(rd
);
3729 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3733 rd
= tcg_temp_new_i32();
3734 tmp
= tcg_temp_new_i32();
3736 tcg_gen_shli_i32(rd
, t0
, 16);
3737 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3738 tcg_gen_or_i32(rd
, rd
, tmp
);
3739 tcg_gen_shri_i32(t1
, t1
, 16);
3740 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3741 tcg_gen_or_i32(t1
, t1
, tmp
);
3742 tcg_gen_mov_i32(t0
, rd
);
3744 tcg_temp_free_i32(tmp
);
3745 tcg_temp_free_i32(rd
);
3753 } neon_ls_element_type
[11] = {
3767 /* Translate a NEON load/store element instruction. Return nonzero if the
3768 instruction is invalid. */
3769 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3788 if (!s
->vfp_enabled
)
3790 VFP_DREG_D(rd
, insn
);
3791 rn
= (insn
>> 16) & 0xf;
3793 load
= (insn
& (1 << 21)) != 0;
3794 if ((insn
& (1 << 23)) == 0) {
3795 /* Load store all elements. */
3796 op
= (insn
>> 8) & 0xf;
3797 size
= (insn
>> 6) & 3;
3800 /* Catch UNDEF cases for bad values of align field */
3803 if (((insn
>> 5) & 1) == 1) {
3808 if (((insn
>> 4) & 3) == 3) {
3815 nregs
= neon_ls_element_type
[op
].nregs
;
3816 interleave
= neon_ls_element_type
[op
].interleave
;
3817 spacing
= neon_ls_element_type
[op
].spacing
;
3818 if (size
== 3 && (interleave
| spacing
) != 1)
3820 addr
= tcg_temp_new_i32();
3821 load_reg_var(s
, addr
, rn
);
3822 stride
= (1 << size
) * interleave
;
3823 for (reg
= 0; reg
< nregs
; reg
++) {
3824 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3825 load_reg_var(s
, addr
, rn
);
3826 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3827 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3828 load_reg_var(s
, addr
, rn
);
3829 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3833 tmp64
= gen_ld64(addr
, IS_USER(s
));
3834 neon_store_reg64(tmp64
, rd
);
3835 tcg_temp_free_i64(tmp64
);
3837 tmp64
= tcg_temp_new_i64();
3838 neon_load_reg64(tmp64
, rd
);
3839 gen_st64(tmp64
, addr
, IS_USER(s
));
3841 tcg_gen_addi_i32(addr
, addr
, stride
);
3843 for (pass
= 0; pass
< 2; pass
++) {
3846 tmp
= gen_ld32(addr
, IS_USER(s
));
3847 neon_store_reg(rd
, pass
, tmp
);
3849 tmp
= neon_load_reg(rd
, pass
);
3850 gen_st32(tmp
, addr
, IS_USER(s
));
3852 tcg_gen_addi_i32(addr
, addr
, stride
);
3853 } else if (size
== 1) {
3855 tmp
= gen_ld16u(addr
, IS_USER(s
));
3856 tcg_gen_addi_i32(addr
, addr
, stride
);
3857 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3858 tcg_gen_addi_i32(addr
, addr
, stride
);
3859 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3860 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3861 tcg_temp_free_i32(tmp2
);
3862 neon_store_reg(rd
, pass
, tmp
);
3864 tmp
= neon_load_reg(rd
, pass
);
3865 tmp2
= tcg_temp_new_i32();
3866 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3867 gen_st16(tmp
, addr
, IS_USER(s
));
3868 tcg_gen_addi_i32(addr
, addr
, stride
);
3869 gen_st16(tmp2
, addr
, IS_USER(s
));
3870 tcg_gen_addi_i32(addr
, addr
, stride
);
3872 } else /* size == 0 */ {
3875 for (n
= 0; n
< 4; n
++) {
3876 tmp
= gen_ld8u(addr
, IS_USER(s
));
3877 tcg_gen_addi_i32(addr
, addr
, stride
);
3881 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3882 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3883 tcg_temp_free_i32(tmp
);
3886 neon_store_reg(rd
, pass
, tmp2
);
3888 tmp2
= neon_load_reg(rd
, pass
);
3889 for (n
= 0; n
< 4; n
++) {
3890 tmp
= tcg_temp_new_i32();
3892 tcg_gen_mov_i32(tmp
, tmp2
);
3894 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3896 gen_st8(tmp
, addr
, IS_USER(s
));
3897 tcg_gen_addi_i32(addr
, addr
, stride
);
3899 tcg_temp_free_i32(tmp2
);
3906 tcg_temp_free_i32(addr
);
3909 size
= (insn
>> 10) & 3;
3911 /* Load single element to all lanes. */
3912 int a
= (insn
>> 4) & 1;
3916 size
= (insn
>> 6) & 3;
3917 nregs
= ((insn
>> 8) & 3) + 1;
3920 if (nregs
!= 4 || a
== 0) {
3923 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3926 if (nregs
== 1 && a
== 1 && size
== 0) {
3929 if (nregs
== 3 && a
== 1) {
3932 addr
= tcg_temp_new_i32();
3933 load_reg_var(s
, addr
, rn
);
3935 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3936 tmp
= gen_load_and_replicate(s
, addr
, size
);
3937 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3938 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3939 if (insn
& (1 << 5)) {
3940 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
3941 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
3943 tcg_temp_free_i32(tmp
);
3945 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
3946 stride
= (insn
& (1 << 5)) ? 2 : 1;
3947 for (reg
= 0; reg
< nregs
; reg
++) {
3948 tmp
= gen_load_and_replicate(s
, addr
, size
);
3949 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3950 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3951 tcg_temp_free_i32(tmp
);
3952 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3956 tcg_temp_free_i32(addr
);
3957 stride
= (1 << size
) * nregs
;
3959 /* Single element. */
3960 int idx
= (insn
>> 4) & 0xf;
3961 pass
= (insn
>> 7) & 1;
3964 shift
= ((insn
>> 5) & 3) * 8;
3968 shift
= ((insn
>> 6) & 1) * 16;
3969 stride
= (insn
& (1 << 5)) ? 2 : 1;
3973 stride
= (insn
& (1 << 6)) ? 2 : 1;
3978 nregs
= ((insn
>> 8) & 3) + 1;
3979 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3982 if (((idx
& (1 << size
)) != 0) ||
3983 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
3988 if ((idx
& 1) != 0) {
3993 if (size
== 2 && (idx
& 2) != 0) {
3998 if ((size
== 2) && ((idx
& 3) == 3)) {
4005 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4006 /* Attempts to write off the end of the register file
4007 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4008 * the neon_load_reg() would write off the end of the array.
4012 addr
= tcg_temp_new_i32();
4013 load_reg_var(s
, addr
, rn
);
4014 for (reg
= 0; reg
< nregs
; reg
++) {
4018 tmp
= gen_ld8u(addr
, IS_USER(s
));
4021 tmp
= gen_ld16u(addr
, IS_USER(s
));
4024 tmp
= gen_ld32(addr
, IS_USER(s
));
4026 default: /* Avoid compiler warnings. */
4030 tmp2
= neon_load_reg(rd
, pass
);
4031 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4032 shift
, size
? 16 : 8);
4033 tcg_temp_free_i32(tmp2
);
4035 neon_store_reg(rd
, pass
, tmp
);
4036 } else { /* Store */
4037 tmp
= neon_load_reg(rd
, pass
);
4039 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4042 gen_st8(tmp
, addr
, IS_USER(s
));
4045 gen_st16(tmp
, addr
, IS_USER(s
));
4048 gen_st32(tmp
, addr
, IS_USER(s
));
4053 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4055 tcg_temp_free_i32(addr
);
4056 stride
= nregs
* (1 << size
);
4062 base
= load_reg(s
, rn
);
4064 tcg_gen_addi_i32(base
, base
, stride
);
4067 index
= load_reg(s
, rm
);
4068 tcg_gen_add_i32(base
, base
, index
);
4069 tcg_temp_free_i32(index
);
4071 store_reg(s
, rn
, base
);
4076 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4077 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4079 tcg_gen_and_i32(t
, t
, c
);
4080 tcg_gen_andc_i32(f
, f
, c
);
4081 tcg_gen_or_i32(dest
, t
, f
);
4084 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4087 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4088 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4089 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4094 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4097 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4098 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4099 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4104 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4107 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4108 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4109 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4114 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4117 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4118 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4119 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4124 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4130 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4131 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4136 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4137 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4144 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4145 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4150 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4151 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4158 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4162 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4163 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4164 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4169 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4170 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4171 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4175 tcg_temp_free_i32(src
);
4178 static inline void gen_neon_addl(int size
)
4181 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4182 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4183 case 2: tcg_gen_add_i64(CPU_V001
); break;
4188 static inline void gen_neon_subl(int size
)
4191 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4192 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4193 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4198 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4201 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4202 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4204 tcg_gen_neg_i64(var
, var
);
4210 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4213 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4214 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4219 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4223 switch ((size
<< 1) | u
) {
4224 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4225 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4226 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4227 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4229 tmp
= gen_muls_i64_i32(a
, b
);
4230 tcg_gen_mov_i64(dest
, tmp
);
4231 tcg_temp_free_i64(tmp
);
4234 tmp
= gen_mulu_i64_i32(a
, b
);
4235 tcg_gen_mov_i64(dest
, tmp
);
4236 tcg_temp_free_i64(tmp
);
4241 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4242 Don't forget to clean them now. */
4244 tcg_temp_free_i32(a
);
4245 tcg_temp_free_i32(b
);
4249 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4253 gen_neon_unarrow_sats(size
, dest
, src
);
4255 gen_neon_narrow(size
, dest
, src
);
4259 gen_neon_narrow_satu(size
, dest
, src
);
4261 gen_neon_narrow_sats(size
, dest
, src
);
4266 /* Symbolic constants for op fields for Neon 3-register same-length.
4267 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4270 #define NEON_3R_VHADD 0
4271 #define NEON_3R_VQADD 1
4272 #define NEON_3R_VRHADD 2
4273 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4274 #define NEON_3R_VHSUB 4
4275 #define NEON_3R_VQSUB 5
4276 #define NEON_3R_VCGT 6
4277 #define NEON_3R_VCGE 7
4278 #define NEON_3R_VSHL 8
4279 #define NEON_3R_VQSHL 9
4280 #define NEON_3R_VRSHL 10
4281 #define NEON_3R_VQRSHL 11
4282 #define NEON_3R_VMAX 12
4283 #define NEON_3R_VMIN 13
4284 #define NEON_3R_VABD 14
4285 #define NEON_3R_VABA 15
4286 #define NEON_3R_VADD_VSUB 16
4287 #define NEON_3R_VTST_VCEQ 17
4288 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4289 #define NEON_3R_VMUL 19
4290 #define NEON_3R_VPMAX 20
4291 #define NEON_3R_VPMIN 21
4292 #define NEON_3R_VQDMULH_VQRDMULH 22
4293 #define NEON_3R_VPADD 23
4294 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4295 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4296 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4297 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4298 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4299 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4300 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4302 static const uint8_t neon_3r_sizes
[] = {
4303 [NEON_3R_VHADD
] = 0x7,
4304 [NEON_3R_VQADD
] = 0xf,
4305 [NEON_3R_VRHADD
] = 0x7,
4306 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4307 [NEON_3R_VHSUB
] = 0x7,
4308 [NEON_3R_VQSUB
] = 0xf,
4309 [NEON_3R_VCGT
] = 0x7,
4310 [NEON_3R_VCGE
] = 0x7,
4311 [NEON_3R_VSHL
] = 0xf,
4312 [NEON_3R_VQSHL
] = 0xf,
4313 [NEON_3R_VRSHL
] = 0xf,
4314 [NEON_3R_VQRSHL
] = 0xf,
4315 [NEON_3R_VMAX
] = 0x7,
4316 [NEON_3R_VMIN
] = 0x7,
4317 [NEON_3R_VABD
] = 0x7,
4318 [NEON_3R_VABA
] = 0x7,
4319 [NEON_3R_VADD_VSUB
] = 0xf,
4320 [NEON_3R_VTST_VCEQ
] = 0x7,
4321 [NEON_3R_VML
] = 0x7,
4322 [NEON_3R_VMUL
] = 0x7,
4323 [NEON_3R_VPMAX
] = 0x7,
4324 [NEON_3R_VPMIN
] = 0x7,
4325 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4326 [NEON_3R_VPADD
] = 0x7,
4327 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4328 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4329 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4330 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4331 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4332 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4333 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4336 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4337 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4340 #define NEON_2RM_VREV64 0
4341 #define NEON_2RM_VREV32 1
4342 #define NEON_2RM_VREV16 2
4343 #define NEON_2RM_VPADDL 4
4344 #define NEON_2RM_VPADDL_U 5
4345 #define NEON_2RM_VCLS 8
4346 #define NEON_2RM_VCLZ 9
4347 #define NEON_2RM_VCNT 10
4348 #define NEON_2RM_VMVN 11
4349 #define NEON_2RM_VPADAL 12
4350 #define NEON_2RM_VPADAL_U 13
4351 #define NEON_2RM_VQABS 14
4352 #define NEON_2RM_VQNEG 15
4353 #define NEON_2RM_VCGT0 16
4354 #define NEON_2RM_VCGE0 17
4355 #define NEON_2RM_VCEQ0 18
4356 #define NEON_2RM_VCLE0 19
4357 #define NEON_2RM_VCLT0 20
4358 #define NEON_2RM_VABS 22
4359 #define NEON_2RM_VNEG 23
4360 #define NEON_2RM_VCGT0_F 24
4361 #define NEON_2RM_VCGE0_F 25
4362 #define NEON_2RM_VCEQ0_F 26
4363 #define NEON_2RM_VCLE0_F 27
4364 #define NEON_2RM_VCLT0_F 28
4365 #define NEON_2RM_VABS_F 30
4366 #define NEON_2RM_VNEG_F 31
4367 #define NEON_2RM_VSWP 32
4368 #define NEON_2RM_VTRN 33
4369 #define NEON_2RM_VUZP 34
4370 #define NEON_2RM_VZIP 35
4371 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4372 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4373 #define NEON_2RM_VSHLL 38
4374 #define NEON_2RM_VCVT_F16_F32 44
4375 #define NEON_2RM_VCVT_F32_F16 46
4376 #define NEON_2RM_VRECPE 56
4377 #define NEON_2RM_VRSQRTE 57
4378 #define NEON_2RM_VRECPE_F 58
4379 #define NEON_2RM_VRSQRTE_F 59
4380 #define NEON_2RM_VCVT_FS 60
4381 #define NEON_2RM_VCVT_FU 61
4382 #define NEON_2RM_VCVT_SF 62
4383 #define NEON_2RM_VCVT_UF 63
4385 static int neon_2rm_is_float_op(int op
)
4387 /* Return true if this neon 2reg-misc op is float-to-float */
4388 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4389 op
>= NEON_2RM_VRECPE_F
);
4392 /* Each entry in this array has bit n set if the insn allows
4393 * size value n (otherwise it will UNDEF). Since unallocated
4394 * op values will have no bits set they always UNDEF.
4396 static const uint8_t neon_2rm_sizes
[] = {
4397 [NEON_2RM_VREV64
] = 0x7,
4398 [NEON_2RM_VREV32
] = 0x3,
4399 [NEON_2RM_VREV16
] = 0x1,
4400 [NEON_2RM_VPADDL
] = 0x7,
4401 [NEON_2RM_VPADDL_U
] = 0x7,
4402 [NEON_2RM_VCLS
] = 0x7,
4403 [NEON_2RM_VCLZ
] = 0x7,
4404 [NEON_2RM_VCNT
] = 0x1,
4405 [NEON_2RM_VMVN
] = 0x1,
4406 [NEON_2RM_VPADAL
] = 0x7,
4407 [NEON_2RM_VPADAL_U
] = 0x7,
4408 [NEON_2RM_VQABS
] = 0x7,
4409 [NEON_2RM_VQNEG
] = 0x7,
4410 [NEON_2RM_VCGT0
] = 0x7,
4411 [NEON_2RM_VCGE0
] = 0x7,
4412 [NEON_2RM_VCEQ0
] = 0x7,
4413 [NEON_2RM_VCLE0
] = 0x7,
4414 [NEON_2RM_VCLT0
] = 0x7,
4415 [NEON_2RM_VABS
] = 0x7,
4416 [NEON_2RM_VNEG
] = 0x7,
4417 [NEON_2RM_VCGT0_F
] = 0x4,
4418 [NEON_2RM_VCGE0_F
] = 0x4,
4419 [NEON_2RM_VCEQ0_F
] = 0x4,
4420 [NEON_2RM_VCLE0_F
] = 0x4,
4421 [NEON_2RM_VCLT0_F
] = 0x4,
4422 [NEON_2RM_VABS_F
] = 0x4,
4423 [NEON_2RM_VNEG_F
] = 0x4,
4424 [NEON_2RM_VSWP
] = 0x1,
4425 [NEON_2RM_VTRN
] = 0x7,
4426 [NEON_2RM_VUZP
] = 0x7,
4427 [NEON_2RM_VZIP
] = 0x7,
4428 [NEON_2RM_VMOVN
] = 0x7,
4429 [NEON_2RM_VQMOVN
] = 0x7,
4430 [NEON_2RM_VSHLL
] = 0x7,
4431 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4432 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4433 [NEON_2RM_VRECPE
] = 0x4,
4434 [NEON_2RM_VRSQRTE
] = 0x4,
4435 [NEON_2RM_VRECPE_F
] = 0x4,
4436 [NEON_2RM_VRSQRTE_F
] = 0x4,
4437 [NEON_2RM_VCVT_FS
] = 0x4,
4438 [NEON_2RM_VCVT_FU
] = 0x4,
4439 [NEON_2RM_VCVT_SF
] = 0x4,
4440 [NEON_2RM_VCVT_UF
] = 0x4,
4443 /* Translate a NEON data processing instruction. Return nonzero if the
4444 instruction is invalid.
4445 We process data in a mixture of 32-bit and 64-bit chunks.
4446 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4448 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4460 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4463 if (!s
->vfp_enabled
)
4465 q
= (insn
& (1 << 6)) != 0;
4466 u
= (insn
>> 24) & 1;
4467 VFP_DREG_D(rd
, insn
);
4468 VFP_DREG_N(rn
, insn
);
4469 VFP_DREG_M(rm
, insn
);
4470 size
= (insn
>> 20) & 3;
4471 if ((insn
& (1 << 23)) == 0) {
4472 /* Three register same length. */
4473 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4474 /* Catch invalid op and bad size combinations: UNDEF */
4475 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4478 /* All insns of this form UNDEF for either this condition or the
4479 * superset of cases "Q==1"; we catch the latter later.
4481 if (q
&& ((rd
| rn
| rm
) & 1)) {
4484 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4485 /* 64-bit element instructions. */
4486 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4487 neon_load_reg64(cpu_V0
, rn
+ pass
);
4488 neon_load_reg64(cpu_V1
, rm
+ pass
);
4492 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4495 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4501 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4504 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4510 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4512 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4517 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4520 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4526 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4528 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4531 case NEON_3R_VQRSHL
:
4533 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4536 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4540 case NEON_3R_VADD_VSUB
:
4542 tcg_gen_sub_i64(CPU_V001
);
4544 tcg_gen_add_i64(CPU_V001
);
4550 neon_store_reg64(cpu_V0
, rd
+ pass
);
4559 case NEON_3R_VQRSHL
:
4562 /* Shift instruction operands are reversed. */
4577 case NEON_3R_FLOAT_ARITH
:
4578 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4580 case NEON_3R_FLOAT_MINMAX
:
4581 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4583 case NEON_3R_FLOAT_CMP
:
4585 /* no encoding for U=0 C=1x */
4589 case NEON_3R_FLOAT_ACMP
:
4594 case NEON_3R_VRECPS_VRSQRTS
:
4600 if (u
&& (size
!= 0)) {
4601 /* UNDEF on invalid size for polynomial subcase */
4606 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4614 if (pairwise
&& q
) {
4615 /* All the pairwise insns UNDEF if Q is set */
4619 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4624 tmp
= neon_load_reg(rn
, 0);
4625 tmp2
= neon_load_reg(rn
, 1);
4627 tmp
= neon_load_reg(rm
, 0);
4628 tmp2
= neon_load_reg(rm
, 1);
4632 tmp
= neon_load_reg(rn
, pass
);
4633 tmp2
= neon_load_reg(rm
, pass
);
4637 GEN_NEON_INTEGER_OP(hadd
);
4640 GEN_NEON_INTEGER_OP_ENV(qadd
);
4642 case NEON_3R_VRHADD
:
4643 GEN_NEON_INTEGER_OP(rhadd
);
4645 case NEON_3R_LOGIC
: /* Logic ops. */
4646 switch ((u
<< 2) | size
) {
4648 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4651 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4654 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4657 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4660 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4663 tmp3
= neon_load_reg(rd
, pass
);
4664 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4665 tcg_temp_free_i32(tmp3
);
4668 tmp3
= neon_load_reg(rd
, pass
);
4669 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4670 tcg_temp_free_i32(tmp3
);
4673 tmp3
= neon_load_reg(rd
, pass
);
4674 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4675 tcg_temp_free_i32(tmp3
);
4680 GEN_NEON_INTEGER_OP(hsub
);
4683 GEN_NEON_INTEGER_OP_ENV(qsub
);
4686 GEN_NEON_INTEGER_OP(cgt
);
4689 GEN_NEON_INTEGER_OP(cge
);
4692 GEN_NEON_INTEGER_OP(shl
);
4695 GEN_NEON_INTEGER_OP_ENV(qshl
);
4698 GEN_NEON_INTEGER_OP(rshl
);
4700 case NEON_3R_VQRSHL
:
4701 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4704 GEN_NEON_INTEGER_OP(max
);
4707 GEN_NEON_INTEGER_OP(min
);
4710 GEN_NEON_INTEGER_OP(abd
);
4713 GEN_NEON_INTEGER_OP(abd
);
4714 tcg_temp_free_i32(tmp2
);
4715 tmp2
= neon_load_reg(rd
, pass
);
4716 gen_neon_add(size
, tmp
, tmp2
);
4718 case NEON_3R_VADD_VSUB
:
4719 if (!u
) { /* VADD */
4720 gen_neon_add(size
, tmp
, tmp2
);
4723 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4724 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4725 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4730 case NEON_3R_VTST_VCEQ
:
4731 if (!u
) { /* VTST */
4733 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4734 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4735 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4740 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4741 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4742 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4747 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4749 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4750 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4751 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4754 tcg_temp_free_i32(tmp2
);
4755 tmp2
= neon_load_reg(rd
, pass
);
4757 gen_neon_rsb(size
, tmp
, tmp2
);
4759 gen_neon_add(size
, tmp
, tmp2
);
4763 if (u
) { /* polynomial */
4764 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4765 } else { /* Integer */
4767 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4768 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4769 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4775 GEN_NEON_INTEGER_OP(pmax
);
4778 GEN_NEON_INTEGER_OP(pmin
);
4780 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4781 if (!u
) { /* VQDMULH */
4784 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4787 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4791 } else { /* VQRDMULH */
4794 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4797 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4805 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4806 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4807 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4811 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4813 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4814 switch ((u
<< 2) | size
) {
4817 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4820 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
4823 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
4828 tcg_temp_free_ptr(fpstatus
);
4831 case NEON_3R_FLOAT_MULTIPLY
:
4833 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4834 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
4836 tcg_temp_free_i32(tmp2
);
4837 tmp2
= neon_load_reg(rd
, pass
);
4839 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4841 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
4844 tcg_temp_free_ptr(fpstatus
);
4847 case NEON_3R_FLOAT_CMP
:
4849 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4851 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
4854 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4856 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4859 tcg_temp_free_ptr(fpstatus
);
4862 case NEON_3R_FLOAT_ACMP
:
4864 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4866 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4868 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4870 tcg_temp_free_ptr(fpstatus
);
4873 case NEON_3R_FLOAT_MINMAX
:
4875 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4877 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
4879 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
4881 tcg_temp_free_ptr(fpstatus
);
4884 case NEON_3R_VRECPS_VRSQRTS
:
4886 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4888 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4892 /* VFMA, VFMS: fused multiply-add */
4893 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4894 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
4897 gen_helper_vfp_negs(tmp
, tmp
);
4899 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
4900 tcg_temp_free_i32(tmp3
);
4901 tcg_temp_free_ptr(fpstatus
);
4907 tcg_temp_free_i32(tmp2
);
4909 /* Save the result. For elementwise operations we can put it
4910 straight into the destination register. For pairwise operations
4911 we have to be careful to avoid clobbering the source operands. */
4912 if (pairwise
&& rd
== rm
) {
4913 neon_store_scratch(pass
, tmp
);
4915 neon_store_reg(rd
, pass
, tmp
);
4919 if (pairwise
&& rd
== rm
) {
4920 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4921 tmp
= neon_load_scratch(pass
);
4922 neon_store_reg(rd
, pass
, tmp
);
4925 /* End of 3 register same size operations. */
4926 } else if (insn
& (1 << 4)) {
4927 if ((insn
& 0x00380080) != 0) {
4928 /* Two registers and shift. */
4929 op
= (insn
>> 8) & 0xf;
4930 if (insn
& (1 << 7)) {
4938 while ((insn
& (1 << (size
+ 19))) == 0)
4941 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
4942 /* To avoid excessive duplication of ops we implement shift
4943 by immediate using the variable shift operations. */
4945 /* Shift by immediate:
4946 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4947 if (q
&& ((rd
| rm
) & 1)) {
4950 if (!u
&& (op
== 4 || op
== 6)) {
4953 /* Right shifts are encoded as N - shift, where N is the
4954 element size in bits. */
4956 shift
= shift
- (1 << (size
+ 3));
4964 imm
= (uint8_t) shift
;
4969 imm
= (uint16_t) shift
;
4980 for (pass
= 0; pass
< count
; pass
++) {
4982 neon_load_reg64(cpu_V0
, rm
+ pass
);
4983 tcg_gen_movi_i64(cpu_V1
, imm
);
4988 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4990 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4995 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4997 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5000 case 5: /* VSHL, VSLI */
5001 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5003 case 6: /* VQSHLU */
5004 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5009 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5012 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5017 if (op
== 1 || op
== 3) {
5019 neon_load_reg64(cpu_V1
, rd
+ pass
);
5020 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5021 } else if (op
== 4 || (op
== 5 && u
)) {
5023 neon_load_reg64(cpu_V1
, rd
+ pass
);
5025 if (shift
< -63 || shift
> 63) {
5029 mask
= 0xffffffffffffffffull
>> -shift
;
5031 mask
= 0xffffffffffffffffull
<< shift
;
5034 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5035 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5037 neon_store_reg64(cpu_V0
, rd
+ pass
);
5038 } else { /* size < 3 */
5039 /* Operands in T0 and T1. */
5040 tmp
= neon_load_reg(rm
, pass
);
5041 tmp2
= tcg_temp_new_i32();
5042 tcg_gen_movi_i32(tmp2
, imm
);
5046 GEN_NEON_INTEGER_OP(shl
);
5050 GEN_NEON_INTEGER_OP(rshl
);
5053 case 5: /* VSHL, VSLI */
5055 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5056 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5057 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5061 case 6: /* VQSHLU */
5064 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5068 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5072 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5080 GEN_NEON_INTEGER_OP_ENV(qshl
);
5083 tcg_temp_free_i32(tmp2
);
5085 if (op
== 1 || op
== 3) {
5087 tmp2
= neon_load_reg(rd
, pass
);
5088 gen_neon_add(size
, tmp
, tmp2
);
5089 tcg_temp_free_i32(tmp2
);
5090 } else if (op
== 4 || (op
== 5 && u
)) {
5095 mask
= 0xff >> -shift
;
5097 mask
= (uint8_t)(0xff << shift
);
5103 mask
= 0xffff >> -shift
;
5105 mask
= (uint16_t)(0xffff << shift
);
5109 if (shift
< -31 || shift
> 31) {
5113 mask
= 0xffffffffu
>> -shift
;
5115 mask
= 0xffffffffu
<< shift
;
5121 tmp2
= neon_load_reg(rd
, pass
);
5122 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5123 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5124 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5125 tcg_temp_free_i32(tmp2
);
5127 neon_store_reg(rd
, pass
, tmp
);
5130 } else if (op
< 10) {
5131 /* Shift by immediate and narrow:
5132 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5133 int input_unsigned
= (op
== 8) ? !u
: u
;
5137 shift
= shift
- (1 << (size
+ 3));
5140 tmp64
= tcg_const_i64(shift
);
5141 neon_load_reg64(cpu_V0
, rm
);
5142 neon_load_reg64(cpu_V1
, rm
+ 1);
5143 for (pass
= 0; pass
< 2; pass
++) {
5151 if (input_unsigned
) {
5152 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5154 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5157 if (input_unsigned
) {
5158 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5160 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5163 tmp
= tcg_temp_new_i32();
5164 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5165 neon_store_reg(rd
, pass
, tmp
);
5167 tcg_temp_free_i64(tmp64
);
5170 imm
= (uint16_t)shift
;
5174 imm
= (uint32_t)shift
;
5176 tmp2
= tcg_const_i32(imm
);
5177 tmp4
= neon_load_reg(rm
+ 1, 0);
5178 tmp5
= neon_load_reg(rm
+ 1, 1);
5179 for (pass
= 0; pass
< 2; pass
++) {
5181 tmp
= neon_load_reg(rm
, 0);
5185 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5188 tmp3
= neon_load_reg(rm
, 1);
5192 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5194 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5195 tcg_temp_free_i32(tmp
);
5196 tcg_temp_free_i32(tmp3
);
5197 tmp
= tcg_temp_new_i32();
5198 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5199 neon_store_reg(rd
, pass
, tmp
);
5201 tcg_temp_free_i32(tmp2
);
5203 } else if (op
== 10) {
5205 if (q
|| (rd
& 1)) {
5208 tmp
= neon_load_reg(rm
, 0);
5209 tmp2
= neon_load_reg(rm
, 1);
5210 for (pass
= 0; pass
< 2; pass
++) {
5214 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5217 /* The shift is less than the width of the source
5218 type, so we can just shift the whole register. */
5219 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5220 /* Widen the result of shift: we need to clear
5221 * the potential overflow bits resulting from
5222 * left bits of the narrow input appearing as
5223 * right bits of left the neighbour narrow
5225 if (size
< 2 || !u
) {
5228 imm
= (0xffu
>> (8 - shift
));
5230 } else if (size
== 1) {
5231 imm
= 0xffff >> (16 - shift
);
5234 imm
= 0xffffffff >> (32 - shift
);
5237 imm64
= imm
| (((uint64_t)imm
) << 32);
5241 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5244 neon_store_reg64(cpu_V0
, rd
+ pass
);
5246 } else if (op
>= 14) {
5247 /* VCVT fixed-point. */
5248 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5251 /* We have already masked out the must-be-1 top bit of imm6,
5252 * hence this 32-shift where the ARM ARM has 64-imm6.
5255 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5256 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5259 gen_vfp_ulto(0, shift
, 1);
5261 gen_vfp_slto(0, shift
, 1);
5264 gen_vfp_toul(0, shift
, 1);
5266 gen_vfp_tosl(0, shift
, 1);
5268 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5273 } else { /* (insn & 0x00380080) == 0 */
5275 if (q
&& (rd
& 1)) {
5279 op
= (insn
>> 8) & 0xf;
5280 /* One register and immediate. */
5281 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5282 invert
= (insn
& (1 << 5)) != 0;
5283 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5284 * We choose to not special-case this and will behave as if a
5285 * valid constant encoding of 0 had been given.
5304 imm
= (imm
<< 8) | (imm
<< 24);
5307 imm
= (imm
<< 8) | 0xff;
5310 imm
= (imm
<< 16) | 0xffff;
5313 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5321 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5322 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5328 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5329 if (op
& 1 && op
< 12) {
5330 tmp
= neon_load_reg(rd
, pass
);
5332 /* The immediate value has already been inverted, so
5334 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5336 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5340 tmp
= tcg_temp_new_i32();
5341 if (op
== 14 && invert
) {
5345 for (n
= 0; n
< 4; n
++) {
5346 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5347 val
|= 0xff << (n
* 8);
5349 tcg_gen_movi_i32(tmp
, val
);
5351 tcg_gen_movi_i32(tmp
, imm
);
5354 neon_store_reg(rd
, pass
, tmp
);
5357 } else { /* (insn & 0x00800010 == 0x00800000) */
5359 op
= (insn
>> 8) & 0xf;
5360 if ((insn
& (1 << 6)) == 0) {
5361 /* Three registers of different lengths. */
5365 /* undefreq: bit 0 : UNDEF if size != 0
5366 * bit 1 : UNDEF if size == 0
5367 * bit 2 : UNDEF if U == 1
5368 * Note that [1:0] set implies 'always UNDEF'
5371 /* prewiden, src1_wide, src2_wide, undefreq */
5372 static const int neon_3reg_wide
[16][4] = {
5373 {1, 0, 0, 0}, /* VADDL */
5374 {1, 1, 0, 0}, /* VADDW */
5375 {1, 0, 0, 0}, /* VSUBL */
5376 {1, 1, 0, 0}, /* VSUBW */
5377 {0, 1, 1, 0}, /* VADDHN */
5378 {0, 0, 0, 0}, /* VABAL */
5379 {0, 1, 1, 0}, /* VSUBHN */
5380 {0, 0, 0, 0}, /* VABDL */
5381 {0, 0, 0, 0}, /* VMLAL */
5382 {0, 0, 0, 6}, /* VQDMLAL */
5383 {0, 0, 0, 0}, /* VMLSL */
5384 {0, 0, 0, 6}, /* VQDMLSL */
5385 {0, 0, 0, 0}, /* Integer VMULL */
5386 {0, 0, 0, 2}, /* VQDMULL */
5387 {0, 0, 0, 5}, /* Polynomial VMULL */
5388 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5391 prewiden
= neon_3reg_wide
[op
][0];
5392 src1_wide
= neon_3reg_wide
[op
][1];
5393 src2_wide
= neon_3reg_wide
[op
][2];
5394 undefreq
= neon_3reg_wide
[op
][3];
5396 if (((undefreq
& 1) && (size
!= 0)) ||
5397 ((undefreq
& 2) && (size
== 0)) ||
5398 ((undefreq
& 4) && u
)) {
5401 if ((src1_wide
&& (rn
& 1)) ||
5402 (src2_wide
&& (rm
& 1)) ||
5403 (!src2_wide
&& (rd
& 1))) {
5407 /* Avoid overlapping operands. Wide source operands are
5408 always aligned so will never overlap with wide
5409 destinations in problematic ways. */
5410 if (rd
== rm
&& !src2_wide
) {
5411 tmp
= neon_load_reg(rm
, 1);
5412 neon_store_scratch(2, tmp
);
5413 } else if (rd
== rn
&& !src1_wide
) {
5414 tmp
= neon_load_reg(rn
, 1);
5415 neon_store_scratch(2, tmp
);
5418 for (pass
= 0; pass
< 2; pass
++) {
5420 neon_load_reg64(cpu_V0
, rn
+ pass
);
5423 if (pass
== 1 && rd
== rn
) {
5424 tmp
= neon_load_scratch(2);
5426 tmp
= neon_load_reg(rn
, pass
);
5429 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5433 neon_load_reg64(cpu_V1
, rm
+ pass
);
5436 if (pass
== 1 && rd
== rm
) {
5437 tmp2
= neon_load_scratch(2);
5439 tmp2
= neon_load_reg(rm
, pass
);
5442 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5446 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5447 gen_neon_addl(size
);
5449 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5450 gen_neon_subl(size
);
5452 case 5: case 7: /* VABAL, VABDL */
5453 switch ((size
<< 1) | u
) {
5455 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5458 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5461 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5464 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5467 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5470 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5474 tcg_temp_free_i32(tmp2
);
5475 tcg_temp_free_i32(tmp
);
5477 case 8: case 9: case 10: case 11: case 12: case 13:
5478 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5479 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5481 case 14: /* Polynomial VMULL */
5482 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5483 tcg_temp_free_i32(tmp2
);
5484 tcg_temp_free_i32(tmp
);
5486 default: /* 15 is RESERVED: caught earlier */
5491 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5492 neon_store_reg64(cpu_V0
, rd
+ pass
);
5493 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5495 neon_load_reg64(cpu_V1
, rd
+ pass
);
5497 case 10: /* VMLSL */
5498 gen_neon_negl(cpu_V0
, size
);
5500 case 5: case 8: /* VABAL, VMLAL */
5501 gen_neon_addl(size
);
5503 case 9: case 11: /* VQDMLAL, VQDMLSL */
5504 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5506 gen_neon_negl(cpu_V0
, size
);
5508 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5513 neon_store_reg64(cpu_V0
, rd
+ pass
);
5514 } else if (op
== 4 || op
== 6) {
5515 /* Narrowing operation. */
5516 tmp
= tcg_temp_new_i32();
5520 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5523 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5526 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5527 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5534 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5537 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5540 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5541 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5542 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5550 neon_store_reg(rd
, 0, tmp3
);
5551 neon_store_reg(rd
, 1, tmp
);
5554 /* Write back the result. */
5555 neon_store_reg64(cpu_V0
, rd
+ pass
);
5559 /* Two registers and a scalar. NB that for ops of this form
5560 * the ARM ARM labels bit 24 as Q, but it is in our variable
5567 case 1: /* Float VMLA scalar */
5568 case 5: /* Floating point VMLS scalar */
5569 case 9: /* Floating point VMUL scalar */
5574 case 0: /* Integer VMLA scalar */
5575 case 4: /* Integer VMLS scalar */
5576 case 8: /* Integer VMUL scalar */
5577 case 12: /* VQDMULH scalar */
5578 case 13: /* VQRDMULH scalar */
5579 if (u
&& ((rd
| rn
) & 1)) {
5582 tmp
= neon_get_scalar(size
, rm
);
5583 neon_store_scratch(0, tmp
);
5584 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5585 tmp
= neon_load_scratch(0);
5586 tmp2
= neon_load_reg(rn
, pass
);
5589 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5591 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5593 } else if (op
== 13) {
5595 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5597 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5599 } else if (op
& 1) {
5600 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5601 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5602 tcg_temp_free_ptr(fpstatus
);
5605 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5606 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5607 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5611 tcg_temp_free_i32(tmp2
);
5614 tmp2
= neon_load_reg(rd
, pass
);
5617 gen_neon_add(size
, tmp
, tmp2
);
5621 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5622 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5623 tcg_temp_free_ptr(fpstatus
);
5627 gen_neon_rsb(size
, tmp
, tmp2
);
5631 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5632 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5633 tcg_temp_free_ptr(fpstatus
);
5639 tcg_temp_free_i32(tmp2
);
5641 neon_store_reg(rd
, pass
, tmp
);
5644 case 3: /* VQDMLAL scalar */
5645 case 7: /* VQDMLSL scalar */
5646 case 11: /* VQDMULL scalar */
5651 case 2: /* VMLAL sclar */
5652 case 6: /* VMLSL scalar */
5653 case 10: /* VMULL scalar */
5657 tmp2
= neon_get_scalar(size
, rm
);
5658 /* We need a copy of tmp2 because gen_neon_mull
5659 * deletes it during pass 0. */
5660 tmp4
= tcg_temp_new_i32();
5661 tcg_gen_mov_i32(tmp4
, tmp2
);
5662 tmp3
= neon_load_reg(rn
, 1);
5664 for (pass
= 0; pass
< 2; pass
++) {
5666 tmp
= neon_load_reg(rn
, 0);
5671 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5673 neon_load_reg64(cpu_V1
, rd
+ pass
);
5677 gen_neon_negl(cpu_V0
, size
);
5680 gen_neon_addl(size
);
5683 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5685 gen_neon_negl(cpu_V0
, size
);
5687 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5693 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5698 neon_store_reg64(cpu_V0
, rd
+ pass
);
5703 default: /* 14 and 15 are RESERVED */
5707 } else { /* size == 3 */
5710 imm
= (insn
>> 8) & 0xf;
5715 if (q
&& ((rd
| rn
| rm
) & 1)) {
5720 neon_load_reg64(cpu_V0
, rn
);
5722 neon_load_reg64(cpu_V1
, rn
+ 1);
5724 } else if (imm
== 8) {
5725 neon_load_reg64(cpu_V0
, rn
+ 1);
5727 neon_load_reg64(cpu_V1
, rm
);
5730 tmp64
= tcg_temp_new_i64();
5732 neon_load_reg64(cpu_V0
, rn
);
5733 neon_load_reg64(tmp64
, rn
+ 1);
5735 neon_load_reg64(cpu_V0
, rn
+ 1);
5736 neon_load_reg64(tmp64
, rm
);
5738 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5739 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5740 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5742 neon_load_reg64(cpu_V1
, rm
);
5744 neon_load_reg64(cpu_V1
, rm
+ 1);
5747 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5748 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5749 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5750 tcg_temp_free_i64(tmp64
);
5753 neon_load_reg64(cpu_V0
, rn
);
5754 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5755 neon_load_reg64(cpu_V1
, rm
);
5756 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5757 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5759 neon_store_reg64(cpu_V0
, rd
);
5761 neon_store_reg64(cpu_V1
, rd
+ 1);
5763 } else if ((insn
& (1 << 11)) == 0) {
5764 /* Two register misc. */
5765 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5766 size
= (insn
>> 18) & 3;
5767 /* UNDEF for unknown op values and bad op-size combinations */
5768 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5771 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5772 q
&& ((rm
| rd
) & 1)) {
5776 case NEON_2RM_VREV64
:
5777 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5778 tmp
= neon_load_reg(rm
, pass
* 2);
5779 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5781 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5782 case 1: gen_swap_half(tmp
); break;
5783 case 2: /* no-op */ break;
5786 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5788 neon_store_reg(rd
, pass
* 2, tmp2
);
5791 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5792 case 1: gen_swap_half(tmp2
); break;
5795 neon_store_reg(rd
, pass
* 2, tmp2
);
5799 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5800 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5801 for (pass
= 0; pass
< q
+ 1; pass
++) {
5802 tmp
= neon_load_reg(rm
, pass
* 2);
5803 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5804 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5805 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5807 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5808 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5809 case 2: tcg_gen_add_i64(CPU_V001
); break;
5812 if (op
>= NEON_2RM_VPADAL
) {
5814 neon_load_reg64(cpu_V1
, rd
+ pass
);
5815 gen_neon_addl(size
);
5817 neon_store_reg64(cpu_V0
, rd
+ pass
);
5823 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5824 tmp
= neon_load_reg(rm
, n
);
5825 tmp2
= neon_load_reg(rd
, n
+ 1);
5826 neon_store_reg(rm
, n
, tmp2
);
5827 neon_store_reg(rd
, n
+ 1, tmp
);
5834 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5839 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5843 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
5844 /* also VQMOVUN; op field and mnemonics don't line up */
5849 for (pass
= 0; pass
< 2; pass
++) {
5850 neon_load_reg64(cpu_V0
, rm
+ pass
);
5851 tmp
= tcg_temp_new_i32();
5852 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
5857 neon_store_reg(rd
, 0, tmp2
);
5858 neon_store_reg(rd
, 1, tmp
);
5862 case NEON_2RM_VSHLL
:
5863 if (q
|| (rd
& 1)) {
5866 tmp
= neon_load_reg(rm
, 0);
5867 tmp2
= neon_load_reg(rm
, 1);
5868 for (pass
= 0; pass
< 2; pass
++) {
5871 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5872 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5873 neon_store_reg64(cpu_V0
, rd
+ pass
);
5876 case NEON_2RM_VCVT_F16_F32
:
5877 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5881 tmp
= tcg_temp_new_i32();
5882 tmp2
= tcg_temp_new_i32();
5883 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5884 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5885 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5886 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5887 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5888 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5889 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5890 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5891 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5892 neon_store_reg(rd
, 0, tmp2
);
5893 tmp2
= tcg_temp_new_i32();
5894 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5895 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5896 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5897 neon_store_reg(rd
, 1, tmp2
);
5898 tcg_temp_free_i32(tmp
);
5900 case NEON_2RM_VCVT_F32_F16
:
5901 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5905 tmp3
= tcg_temp_new_i32();
5906 tmp
= neon_load_reg(rm
, 0);
5907 tmp2
= neon_load_reg(rm
, 1);
5908 tcg_gen_ext16u_i32(tmp3
, tmp
);
5909 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5910 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5911 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5912 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5913 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5914 tcg_temp_free_i32(tmp
);
5915 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5916 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5917 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5918 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5919 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5920 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5921 tcg_temp_free_i32(tmp2
);
5922 tcg_temp_free_i32(tmp3
);
5926 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5927 if (neon_2rm_is_float_op(op
)) {
5928 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5929 neon_reg_offset(rm
, pass
));
5932 tmp
= neon_load_reg(rm
, pass
);
5935 case NEON_2RM_VREV32
:
5937 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5938 case 1: gen_swap_half(tmp
); break;
5942 case NEON_2RM_VREV16
:
5947 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
5948 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
5949 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
5955 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
5956 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
5957 case 2: gen_helper_clz(tmp
, tmp
); break;
5962 gen_helper_neon_cnt_u8(tmp
, tmp
);
5965 tcg_gen_not_i32(tmp
, tmp
);
5967 case NEON_2RM_VQABS
:
5970 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
5973 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
5976 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
5981 case NEON_2RM_VQNEG
:
5984 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
5987 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
5990 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
5995 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
5996 tmp2
= tcg_const_i32(0);
5998 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
5999 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6000 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6003 tcg_temp_free(tmp2
);
6004 if (op
== NEON_2RM_VCLE0
) {
6005 tcg_gen_not_i32(tmp
, tmp
);
6008 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6009 tmp2
= tcg_const_i32(0);
6011 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6012 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6013 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6016 tcg_temp_free(tmp2
);
6017 if (op
== NEON_2RM_VCLT0
) {
6018 tcg_gen_not_i32(tmp
, tmp
);
6021 case NEON_2RM_VCEQ0
:
6022 tmp2
= tcg_const_i32(0);
6024 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6025 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6026 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6029 tcg_temp_free(tmp2
);
6033 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6034 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6035 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6040 tmp2
= tcg_const_i32(0);
6041 gen_neon_rsb(size
, tmp
, tmp2
);
6042 tcg_temp_free(tmp2
);
6044 case NEON_2RM_VCGT0_F
:
6046 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6047 tmp2
= tcg_const_i32(0);
6048 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6049 tcg_temp_free(tmp2
);
6050 tcg_temp_free_ptr(fpstatus
);
6053 case NEON_2RM_VCGE0_F
:
6055 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6056 tmp2
= tcg_const_i32(0);
6057 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6058 tcg_temp_free(tmp2
);
6059 tcg_temp_free_ptr(fpstatus
);
6062 case NEON_2RM_VCEQ0_F
:
6064 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6065 tmp2
= tcg_const_i32(0);
6066 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6067 tcg_temp_free(tmp2
);
6068 tcg_temp_free_ptr(fpstatus
);
6071 case NEON_2RM_VCLE0_F
:
6073 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6074 tmp2
= tcg_const_i32(0);
6075 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6076 tcg_temp_free(tmp2
);
6077 tcg_temp_free_ptr(fpstatus
);
6080 case NEON_2RM_VCLT0_F
:
6082 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6083 tmp2
= tcg_const_i32(0);
6084 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6085 tcg_temp_free(tmp2
);
6086 tcg_temp_free_ptr(fpstatus
);
6089 case NEON_2RM_VABS_F
:
6092 case NEON_2RM_VNEG_F
:
6096 tmp2
= neon_load_reg(rd
, pass
);
6097 neon_store_reg(rm
, pass
, tmp2
);
6100 tmp2
= neon_load_reg(rd
, pass
);
6102 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6103 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6106 neon_store_reg(rm
, pass
, tmp2
);
6108 case NEON_2RM_VRECPE
:
6109 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6111 case NEON_2RM_VRSQRTE
:
6112 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6114 case NEON_2RM_VRECPE_F
:
6115 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6117 case NEON_2RM_VRSQRTE_F
:
6118 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6120 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6123 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6126 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6127 gen_vfp_tosiz(0, 1);
6129 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6130 gen_vfp_touiz(0, 1);
6133 /* Reserved op values were caught by the
6134 * neon_2rm_sizes[] check earlier.
6138 if (neon_2rm_is_float_op(op
)) {
6139 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6140 neon_reg_offset(rd
, pass
));
6142 neon_store_reg(rd
, pass
, tmp
);
6147 } else if ((insn
& (1 << 10)) == 0) {
6149 int n
= ((insn
>> 8) & 3) + 1;
6150 if ((rn
+ n
) > 32) {
6151 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6152 * helper function running off the end of the register file.
6157 if (insn
& (1 << 6)) {
6158 tmp
= neon_load_reg(rd
, 0);
6160 tmp
= tcg_temp_new_i32();
6161 tcg_gen_movi_i32(tmp
, 0);
6163 tmp2
= neon_load_reg(rm
, 0);
6164 tmp4
= tcg_const_i32(rn
);
6165 tmp5
= tcg_const_i32(n
);
6166 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6167 tcg_temp_free_i32(tmp
);
6168 if (insn
& (1 << 6)) {
6169 tmp
= neon_load_reg(rd
, 1);
6171 tmp
= tcg_temp_new_i32();
6172 tcg_gen_movi_i32(tmp
, 0);
6174 tmp3
= neon_load_reg(rm
, 1);
6175 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6176 tcg_temp_free_i32(tmp5
);
6177 tcg_temp_free_i32(tmp4
);
6178 neon_store_reg(rd
, 0, tmp2
);
6179 neon_store_reg(rd
, 1, tmp3
);
6180 tcg_temp_free_i32(tmp
);
6181 } else if ((insn
& 0x380) == 0) {
6183 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6186 if (insn
& (1 << 19)) {
6187 tmp
= neon_load_reg(rm
, 1);
6189 tmp
= neon_load_reg(rm
, 0);
6191 if (insn
& (1 << 16)) {
6192 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6193 } else if (insn
& (1 << 17)) {
6194 if ((insn
>> 18) & 1)
6195 gen_neon_dup_high16(tmp
);
6197 gen_neon_dup_low16(tmp
);
6199 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6200 tmp2
= tcg_temp_new_i32();
6201 tcg_gen_mov_i32(tmp2
, tmp
);
6202 neon_store_reg(rd
, pass
, tmp2
);
6204 tcg_temp_free_i32(tmp
);
6213 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6215 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6216 const ARMCPRegInfo
*ri
;
6217 ARMCPU
*cpu
= arm_env_get_cpu(env
);
6219 cpnum
= (insn
>> 8) & 0xf;
6220 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6221 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6224 /* First check for coprocessor space used for actual instructions */
6228 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6229 return disas_iwmmxt_insn(env
, s
, insn
);
6230 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6231 return disas_dsp_insn(env
, s
, insn
);
6236 return disas_vfp_insn (env
, s
, insn
);
6241 /* Otherwise treat as a generic register access */
6242 is64
= (insn
& (1 << 25)) == 0;
6243 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6251 opc1
= (insn
>> 4) & 0xf;
6253 rt2
= (insn
>> 16) & 0xf;
6255 crn
= (insn
>> 16) & 0xf;
6256 opc1
= (insn
>> 21) & 7;
6257 opc2
= (insn
>> 5) & 7;
6260 isread
= (insn
>> 20) & 1;
6261 rt
= (insn
>> 12) & 0xf;
6263 ri
= get_arm_cp_reginfo(cpu
,
6264 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6266 /* Check access permissions */
6267 if (!cp_access_ok(env
, ri
, isread
)) {
6271 /* Handle special cases first */
6272 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6279 gen_set_pc_im(s
->pc
);
6280 s
->is_jmp
= DISAS_WFI
;
6291 if (ri
->type
& ARM_CP_CONST
) {
6292 tmp64
= tcg_const_i64(ri
->resetvalue
);
6293 } else if (ri
->readfn
) {
6295 gen_set_pc_im(s
->pc
);
6296 tmp64
= tcg_temp_new_i64();
6297 tmpptr
= tcg_const_ptr(ri
);
6298 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6299 tcg_temp_free_ptr(tmpptr
);
6301 tmp64
= tcg_temp_new_i64();
6302 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6304 tmp
= tcg_temp_new_i32();
6305 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6306 store_reg(s
, rt
, tmp
);
6307 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6308 tmp
= tcg_temp_new_i32();
6309 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6310 tcg_temp_free_i64(tmp64
);
6311 store_reg(s
, rt2
, tmp
);
6314 if (ri
->type
& ARM_CP_CONST
) {
6315 tmp
= tcg_const_i32(ri
->resetvalue
);
6316 } else if (ri
->readfn
) {
6318 gen_set_pc_im(s
->pc
);
6319 tmp
= tcg_temp_new_i32();
6320 tmpptr
= tcg_const_ptr(ri
);
6321 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6322 tcg_temp_free_ptr(tmpptr
);
6324 tmp
= load_cpu_offset(ri
->fieldoffset
);
6327 /* Destination register of r15 for 32 bit loads sets
6328 * the condition codes from the high 4 bits of the value
6331 tcg_temp_free_i32(tmp
);
6333 store_reg(s
, rt
, tmp
);
6338 if (ri
->type
& ARM_CP_CONST
) {
6339 /* If not forbidden by access permissions, treat as WI */
6345 TCGv_i64 tmp64
= tcg_temp_new_i64();
6346 tmplo
= load_reg(s
, rt
);
6347 tmphi
= load_reg(s
, rt2
);
6348 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6349 tcg_temp_free_i32(tmplo
);
6350 tcg_temp_free_i32(tmphi
);
6352 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6353 gen_set_pc_im(s
->pc
);
6354 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6355 tcg_temp_free_ptr(tmpptr
);
6357 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6359 tcg_temp_free_i64(tmp64
);
6364 gen_set_pc_im(s
->pc
);
6365 tmp
= load_reg(s
, rt
);
6366 tmpptr
= tcg_const_ptr(ri
);
6367 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6368 tcg_temp_free_ptr(tmpptr
);
6369 tcg_temp_free_i32(tmp
);
6371 TCGv tmp
= load_reg(s
, rt
);
6372 store_cpu_offset(tmp
, ri
->fieldoffset
);
6375 /* We default to ending the TB on a coprocessor register write,
6376 * but allow this to be suppressed by the register definition
6377 * (usually only necessary to work around guest bugs).
6379 if (!(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6390 /* Store a 64-bit value to a register pair. Clobbers val. */
6391 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6394 tmp
= tcg_temp_new_i32();
6395 tcg_gen_trunc_i64_i32(tmp
, val
);
6396 store_reg(s
, rlow
, tmp
);
6397 tmp
= tcg_temp_new_i32();
6398 tcg_gen_shri_i64(val
, val
, 32);
6399 tcg_gen_trunc_i64_i32(tmp
, val
);
6400 store_reg(s
, rhigh
, tmp
);
6403 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6404 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6409 /* Load value and extend to 64 bits. */
6410 tmp
= tcg_temp_new_i64();
6411 tmp2
= load_reg(s
, rlow
);
6412 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6413 tcg_temp_free_i32(tmp2
);
6414 tcg_gen_add_i64(val
, val
, tmp
);
6415 tcg_temp_free_i64(tmp
);
6418 /* load and add a 64-bit value from a register pair. */
6419 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6425 /* Load 64-bit value rd:rn. */
6426 tmpl
= load_reg(s
, rlow
);
6427 tmph
= load_reg(s
, rhigh
);
6428 tmp
= tcg_temp_new_i64();
6429 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6430 tcg_temp_free_i32(tmpl
);
6431 tcg_temp_free_i32(tmph
);
6432 tcg_gen_add_i64(val
, val
, tmp
);
6433 tcg_temp_free_i64(tmp
);
6436 /* Set N and Z flags from a 64-bit value. */
6437 static void gen_logicq_cc(TCGv_i64 val
)
6439 TCGv tmp
= tcg_temp_new_i32();
6440 gen_helper_logicq_cc(tmp
, val
);
6442 tcg_temp_free_i32(tmp
);
6445 /* Load/Store exclusive instructions are implemented by remembering
6446 the value/address loaded, and seeing if these are the same
6447 when the store is performed. This should be sufficient to implement
6448 the architecturally mandated semantics, and avoids having to monitor
6451 In system emulation mode only one CPU will be running at once, so
6452 this sequence is effectively atomic. In user emulation mode we
6453 throw an exception and handle the atomic operation elsewhere. */
6454 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6455 TCGv addr
, int size
)
6461 tmp
= gen_ld8u(addr
, IS_USER(s
));
6464 tmp
= gen_ld16u(addr
, IS_USER(s
));
6468 tmp
= gen_ld32(addr
, IS_USER(s
));
6473 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6474 store_reg(s
, rt
, tmp
);
6476 TCGv tmp2
= tcg_temp_new_i32();
6477 tcg_gen_addi_i32(tmp2
, addr
, 4);
6478 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6479 tcg_temp_free_i32(tmp2
);
6480 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6481 store_reg(s
, rt2
, tmp
);
6483 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6486 static void gen_clrex(DisasContext
*s
)
6488 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6491 #ifdef CONFIG_USER_ONLY
6492 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6493 TCGv addr
, int size
)
6495 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6496 tcg_gen_movi_i32(cpu_exclusive_info
,
6497 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6498 gen_exception_insn(s
, 4, EXCP_STREX
);
6501 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6502 TCGv addr
, int size
)
6508 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6514 fail_label
= gen_new_label();
6515 done_label
= gen_new_label();
6516 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6519 tmp
= gen_ld8u(addr
, IS_USER(s
));
6522 tmp
= gen_ld16u(addr
, IS_USER(s
));
6526 tmp
= gen_ld32(addr
, IS_USER(s
));
6531 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6532 tcg_temp_free_i32(tmp
);
6534 TCGv tmp2
= tcg_temp_new_i32();
6535 tcg_gen_addi_i32(tmp2
, addr
, 4);
6536 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6537 tcg_temp_free_i32(tmp2
);
6538 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6539 tcg_temp_free_i32(tmp
);
6541 tmp
= load_reg(s
, rt
);
6544 gen_st8(tmp
, addr
, IS_USER(s
));
6547 gen_st16(tmp
, addr
, IS_USER(s
));
6551 gen_st32(tmp
, addr
, IS_USER(s
));
6557 tcg_gen_addi_i32(addr
, addr
, 4);
6558 tmp
= load_reg(s
, rt2
);
6559 gen_st32(tmp
, addr
, IS_USER(s
));
6561 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6562 tcg_gen_br(done_label
);
6563 gen_set_label(fail_label
);
6564 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6565 gen_set_label(done_label
);
6566 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6570 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6572 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6579 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
6582 /* M variants do not implement ARM mode. */
6587 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6588 * choose to UNDEF. In ARMv5 and above the space is used
6589 * for miscellaneous unconditional instructions.
6593 /* Unconditional instructions. */
6594 if (((insn
>> 25) & 7) == 1) {
6595 /* NEON Data processing. */
6596 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6599 if (disas_neon_data_insn(env
, s
, insn
))
6603 if ((insn
& 0x0f100000) == 0x04000000) {
6604 /* NEON load/store. */
6605 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6608 if (disas_neon_ls_insn(env
, s
, insn
))
6612 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6613 ((insn
& 0x0f30f010) == 0x0710f000)) {
6614 if ((insn
& (1 << 22)) == 0) {
6616 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6620 /* Otherwise PLD; v5TE+ */
6624 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6625 ((insn
& 0x0f70f010) == 0x0650f000)) {
6627 return; /* PLI; V7 */
6629 if (((insn
& 0x0f700000) == 0x04100000) ||
6630 ((insn
& 0x0f700010) == 0x06100000)) {
6631 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6634 return; /* v7MP: Unallocated memory hint: must NOP */
6637 if ((insn
& 0x0ffffdff) == 0x01010000) {
6640 if (((insn
>> 9) & 1) != s
->bswap_code
) {
6641 /* Dynamic endianness switching not implemented. */
6645 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6646 switch ((insn
>> 4) & 0xf) {
6655 /* We don't emulate caches so these are a no-op. */
6660 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6666 op1
= (insn
& 0x1f);
6667 addr
= tcg_temp_new_i32();
6668 tmp
= tcg_const_i32(op1
);
6669 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6670 tcg_temp_free_i32(tmp
);
6671 i
= (insn
>> 23) & 3;
6673 case 0: offset
= -4; break; /* DA */
6674 case 1: offset
= 0; break; /* IA */
6675 case 2: offset
= -8; break; /* DB */
6676 case 3: offset
= 4; break; /* IB */
6680 tcg_gen_addi_i32(addr
, addr
, offset
);
6681 tmp
= load_reg(s
, 14);
6682 gen_st32(tmp
, addr
, 0);
6683 tmp
= load_cpu_field(spsr
);
6684 tcg_gen_addi_i32(addr
, addr
, 4);
6685 gen_st32(tmp
, addr
, 0);
6686 if (insn
& (1 << 21)) {
6687 /* Base writeback. */
6689 case 0: offset
= -8; break;
6690 case 1: offset
= 4; break;
6691 case 2: offset
= -4; break;
6692 case 3: offset
= 0; break;
6696 tcg_gen_addi_i32(addr
, addr
, offset
);
6697 tmp
= tcg_const_i32(op1
);
6698 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6699 tcg_temp_free_i32(tmp
);
6700 tcg_temp_free_i32(addr
);
6702 tcg_temp_free_i32(addr
);
6705 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6711 rn
= (insn
>> 16) & 0xf;
6712 addr
= load_reg(s
, rn
);
6713 i
= (insn
>> 23) & 3;
6715 case 0: offset
= -4; break; /* DA */
6716 case 1: offset
= 0; break; /* IA */
6717 case 2: offset
= -8; break; /* DB */
6718 case 3: offset
= 4; break; /* IB */
6722 tcg_gen_addi_i32(addr
, addr
, offset
);
6723 /* Load PC into tmp and CPSR into tmp2. */
6724 tmp
= gen_ld32(addr
, 0);
6725 tcg_gen_addi_i32(addr
, addr
, 4);
6726 tmp2
= gen_ld32(addr
, 0);
6727 if (insn
& (1 << 21)) {
6728 /* Base writeback. */
6730 case 0: offset
= -8; break;
6731 case 1: offset
= 4; break;
6732 case 2: offset
= -4; break;
6733 case 3: offset
= 0; break;
6737 tcg_gen_addi_i32(addr
, addr
, offset
);
6738 store_reg(s
, rn
, addr
);
6740 tcg_temp_free_i32(addr
);
6742 gen_rfe(s
, tmp
, tmp2
);
6744 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6745 /* branch link and change to thumb (blx <offset>) */
6748 val
= (uint32_t)s
->pc
;
6749 tmp
= tcg_temp_new_i32();
6750 tcg_gen_movi_i32(tmp
, val
);
6751 store_reg(s
, 14, tmp
);
6752 /* Sign-extend the 24-bit offset */
6753 offset
= (((int32_t)insn
) << 8) >> 8;
6754 /* offset * 4 + bit24 * 2 + (thumb bit) */
6755 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6756 /* pipeline offset */
6758 /* protected by ARCH(5); above, near the start of uncond block */
6761 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6762 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6763 /* iWMMXt register transfer. */
6764 if (env
->cp15
.c15_cpar
& (1 << 1))
6765 if (!disas_iwmmxt_insn(env
, s
, insn
))
6768 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6769 /* Coprocessor double register transfer. */
6771 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6772 /* Additional coprocessor register transfer. */
6773 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6776 /* cps (privileged) */
6780 if (insn
& (1 << 19)) {
6781 if (insn
& (1 << 8))
6783 if (insn
& (1 << 7))
6785 if (insn
& (1 << 6))
6787 if (insn
& (1 << 18))
6790 if (insn
& (1 << 17)) {
6792 val
|= (insn
& 0x1f);
6795 gen_set_psr_im(s
, mask
, 0, val
);
6802 /* if not always execute, we generate a conditional jump to
6804 s
->condlabel
= gen_new_label();
6805 gen_test_cc(cond
^ 1, s
->condlabel
);
6808 if ((insn
& 0x0f900000) == 0x03000000) {
6809 if ((insn
& (1 << 21)) == 0) {
6811 rd
= (insn
>> 12) & 0xf;
6812 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6813 if ((insn
& (1 << 22)) == 0) {
6815 tmp
= tcg_temp_new_i32();
6816 tcg_gen_movi_i32(tmp
, val
);
6819 tmp
= load_reg(s
, rd
);
6820 tcg_gen_ext16u_i32(tmp
, tmp
);
6821 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6823 store_reg(s
, rd
, tmp
);
6825 if (((insn
>> 12) & 0xf) != 0xf)
6827 if (((insn
>> 16) & 0xf) == 0) {
6828 gen_nop_hint(s
, insn
& 0xff);
6830 /* CPSR = immediate */
6832 shift
= ((insn
>> 8) & 0xf) * 2;
6834 val
= (val
>> shift
) | (val
<< (32 - shift
));
6835 i
= ((insn
& (1 << 22)) != 0);
6836 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6840 } else if ((insn
& 0x0f900000) == 0x01000000
6841 && (insn
& 0x00000090) != 0x00000090) {
6842 /* miscellaneous instructions */
6843 op1
= (insn
>> 21) & 3;
6844 sh
= (insn
>> 4) & 0xf;
6847 case 0x0: /* move program status register */
6850 tmp
= load_reg(s
, rm
);
6851 i
= ((op1
& 2) != 0);
6852 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6856 rd
= (insn
>> 12) & 0xf;
6860 tmp
= load_cpu_field(spsr
);
6862 tmp
= tcg_temp_new_i32();
6863 gen_helper_cpsr_read(tmp
, cpu_env
);
6865 store_reg(s
, rd
, tmp
);
6870 /* branch/exchange thumb (bx). */
6872 tmp
= load_reg(s
, rm
);
6874 } else if (op1
== 3) {
6877 rd
= (insn
>> 12) & 0xf;
6878 tmp
= load_reg(s
, rm
);
6879 gen_helper_clz(tmp
, tmp
);
6880 store_reg(s
, rd
, tmp
);
6888 /* Trivial implementation equivalent to bx. */
6889 tmp
= load_reg(s
, rm
);
6900 /* branch link/exchange thumb (blx) */
6901 tmp
= load_reg(s
, rm
);
6902 tmp2
= tcg_temp_new_i32();
6903 tcg_gen_movi_i32(tmp2
, s
->pc
);
6904 store_reg(s
, 14, tmp2
);
6907 case 0x5: /* saturating add/subtract */
6909 rd
= (insn
>> 12) & 0xf;
6910 rn
= (insn
>> 16) & 0xf;
6911 tmp
= load_reg(s
, rm
);
6912 tmp2
= load_reg(s
, rn
);
6914 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
6916 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6918 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6919 tcg_temp_free_i32(tmp2
);
6920 store_reg(s
, rd
, tmp
);
6923 /* SMC instruction (op1 == 3)
6924 and undefined instructions (op1 == 0 || op1 == 2)
6931 gen_exception_insn(s
, 4, EXCP_BKPT
);
6933 case 0x8: /* signed multiply */
6938 rs
= (insn
>> 8) & 0xf;
6939 rn
= (insn
>> 12) & 0xf;
6940 rd
= (insn
>> 16) & 0xf;
6942 /* (32 * 16) >> 16 */
6943 tmp
= load_reg(s
, rm
);
6944 tmp2
= load_reg(s
, rs
);
6946 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
6949 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6950 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
6951 tmp
= tcg_temp_new_i32();
6952 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6953 tcg_temp_free_i64(tmp64
);
6954 if ((sh
& 2) == 0) {
6955 tmp2
= load_reg(s
, rn
);
6956 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
6957 tcg_temp_free_i32(tmp2
);
6959 store_reg(s
, rd
, tmp
);
6962 tmp
= load_reg(s
, rm
);
6963 tmp2
= load_reg(s
, rs
);
6964 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
6965 tcg_temp_free_i32(tmp2
);
6967 tmp64
= tcg_temp_new_i64();
6968 tcg_gen_ext_i32_i64(tmp64
, tmp
);
6969 tcg_temp_free_i32(tmp
);
6970 gen_addq(s
, tmp64
, rn
, rd
);
6971 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6972 tcg_temp_free_i64(tmp64
);
6975 tmp2
= load_reg(s
, rn
);
6976 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
6977 tcg_temp_free_i32(tmp2
);
6979 store_reg(s
, rd
, tmp
);
6986 } else if (((insn
& 0x0e000000) == 0 &&
6987 (insn
& 0x00000090) != 0x90) ||
6988 ((insn
& 0x0e000000) == (1 << 25))) {
6989 int set_cc
, logic_cc
, shiftop
;
6991 op1
= (insn
>> 21) & 0xf;
6992 set_cc
= (insn
>> 20) & 1;
6993 logic_cc
= table_logic_cc
[op1
] & set_cc
;
6995 /* data processing instruction */
6996 if (insn
& (1 << 25)) {
6997 /* immediate operand */
6999 shift
= ((insn
>> 8) & 0xf) * 2;
7001 val
= (val
>> shift
) | (val
<< (32 - shift
));
7003 tmp2
= tcg_temp_new_i32();
7004 tcg_gen_movi_i32(tmp2
, val
);
7005 if (logic_cc
&& shift
) {
7006 gen_set_CF_bit31(tmp2
);
7011 tmp2
= load_reg(s
, rm
);
7012 shiftop
= (insn
>> 5) & 3;
7013 if (!(insn
& (1 << 4))) {
7014 shift
= (insn
>> 7) & 0x1f;
7015 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7017 rs
= (insn
>> 8) & 0xf;
7018 tmp
= load_reg(s
, rs
);
7019 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7022 if (op1
!= 0x0f && op1
!= 0x0d) {
7023 rn
= (insn
>> 16) & 0xf;
7024 tmp
= load_reg(s
, rn
);
7028 rd
= (insn
>> 12) & 0xf;
7031 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7035 store_reg_bx(env
, s
, rd
, tmp
);
7038 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7042 store_reg_bx(env
, s
, rd
, tmp
);
7045 if (set_cc
&& rd
== 15) {
7046 /* SUBS r15, ... is used for exception return. */
7050 gen_sub_CC(tmp
, tmp
, tmp2
);
7051 gen_exception_return(s
, tmp
);
7054 gen_sub_CC(tmp
, tmp
, tmp2
);
7056 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7058 store_reg_bx(env
, s
, rd
, tmp
);
7063 gen_sub_CC(tmp
, tmp2
, tmp
);
7065 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7067 store_reg_bx(env
, s
, rd
, tmp
);
7071 gen_add_CC(tmp
, tmp
, tmp2
);
7073 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7075 store_reg_bx(env
, s
, rd
, tmp
);
7079 gen_helper_adc_cc(tmp
, cpu_env
, tmp
, tmp2
);
7081 gen_add_carry(tmp
, tmp
, tmp2
);
7083 store_reg_bx(env
, s
, rd
, tmp
);
7087 gen_helper_sbc_cc(tmp
, cpu_env
, tmp
, tmp2
);
7089 gen_sub_carry(tmp
, tmp
, tmp2
);
7091 store_reg_bx(env
, s
, rd
, tmp
);
7095 gen_helper_sbc_cc(tmp
, cpu_env
, tmp2
, tmp
);
7097 gen_sub_carry(tmp
, tmp2
, tmp
);
7099 store_reg_bx(env
, s
, rd
, tmp
);
7103 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7106 tcg_temp_free_i32(tmp
);
7110 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7113 tcg_temp_free_i32(tmp
);
7117 gen_sub_CC(tmp
, tmp
, tmp2
);
7119 tcg_temp_free_i32(tmp
);
7123 gen_add_CC(tmp
, tmp
, tmp2
);
7125 tcg_temp_free_i32(tmp
);
7128 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7132 store_reg_bx(env
, s
, rd
, tmp
);
7135 if (logic_cc
&& rd
== 15) {
7136 /* MOVS r15, ... is used for exception return. */
7140 gen_exception_return(s
, tmp2
);
7145 store_reg_bx(env
, s
, rd
, tmp2
);
7149 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7153 store_reg_bx(env
, s
, rd
, tmp
);
7157 tcg_gen_not_i32(tmp2
, tmp2
);
7161 store_reg_bx(env
, s
, rd
, tmp2
);
7164 if (op1
!= 0x0f && op1
!= 0x0d) {
7165 tcg_temp_free_i32(tmp2
);
7168 /* other instructions */
7169 op1
= (insn
>> 24) & 0xf;
7173 /* multiplies, extra load/stores */
7174 sh
= (insn
>> 5) & 3;
7177 rd
= (insn
>> 16) & 0xf;
7178 rn
= (insn
>> 12) & 0xf;
7179 rs
= (insn
>> 8) & 0xf;
7181 op1
= (insn
>> 20) & 0xf;
7183 case 0: case 1: case 2: case 3: case 6:
7185 tmp
= load_reg(s
, rs
);
7186 tmp2
= load_reg(s
, rm
);
7187 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7188 tcg_temp_free_i32(tmp2
);
7189 if (insn
& (1 << 22)) {
7190 /* Subtract (mls) */
7192 tmp2
= load_reg(s
, rn
);
7193 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7194 tcg_temp_free_i32(tmp2
);
7195 } else if (insn
& (1 << 21)) {
7197 tmp2
= load_reg(s
, rn
);
7198 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7199 tcg_temp_free_i32(tmp2
);
7201 if (insn
& (1 << 20))
7203 store_reg(s
, rd
, tmp
);
7206 /* 64 bit mul double accumulate (UMAAL) */
7208 tmp
= load_reg(s
, rs
);
7209 tmp2
= load_reg(s
, rm
);
7210 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7211 gen_addq_lo(s
, tmp64
, rn
);
7212 gen_addq_lo(s
, tmp64
, rd
);
7213 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7214 tcg_temp_free_i64(tmp64
);
7216 case 8: case 9: case 10: case 11:
7217 case 12: case 13: case 14: case 15:
7218 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7219 tmp
= load_reg(s
, rs
);
7220 tmp2
= load_reg(s
, rm
);
7221 if (insn
& (1 << 22)) {
7222 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7224 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7226 if (insn
& (1 << 21)) { /* mult accumulate */
7227 gen_addq(s
, tmp64
, rn
, rd
);
7229 if (insn
& (1 << 20)) {
7230 gen_logicq_cc(tmp64
);
7232 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7233 tcg_temp_free_i64(tmp64
);
7239 rn
= (insn
>> 16) & 0xf;
7240 rd
= (insn
>> 12) & 0xf;
7241 if (insn
& (1 << 23)) {
7242 /* load/store exclusive */
7243 op1
= (insn
>> 21) & 0x3;
7248 addr
= tcg_temp_local_new_i32();
7249 load_reg_var(s
, addr
, rn
);
7250 if (insn
& (1 << 20)) {
7253 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7255 case 1: /* ldrexd */
7256 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7258 case 2: /* ldrexb */
7259 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7261 case 3: /* ldrexh */
7262 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7271 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7273 case 1: /* strexd */
7274 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7276 case 2: /* strexb */
7277 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7279 case 3: /* strexh */
7280 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7286 tcg_temp_free(addr
);
7288 /* SWP instruction */
7291 /* ??? This is not really atomic. However we know
7292 we never have multiple CPUs running in parallel,
7293 so it is good enough. */
7294 addr
= load_reg(s
, rn
);
7295 tmp
= load_reg(s
, rm
);
7296 if (insn
& (1 << 22)) {
7297 tmp2
= gen_ld8u(addr
, IS_USER(s
));
7298 gen_st8(tmp
, addr
, IS_USER(s
));
7300 tmp2
= gen_ld32(addr
, IS_USER(s
));
7301 gen_st32(tmp
, addr
, IS_USER(s
));
7303 tcg_temp_free_i32(addr
);
7304 store_reg(s
, rd
, tmp2
);
7310 /* Misc load/store */
7311 rn
= (insn
>> 16) & 0xf;
7312 rd
= (insn
>> 12) & 0xf;
7313 addr
= load_reg(s
, rn
);
7314 if (insn
& (1 << 24))
7315 gen_add_datah_offset(s
, insn
, 0, addr
);
7317 if (insn
& (1 << 20)) {
7321 tmp
= gen_ld16u(addr
, IS_USER(s
));
7324 tmp
= gen_ld8s(addr
, IS_USER(s
));
7328 tmp
= gen_ld16s(addr
, IS_USER(s
));
7332 } else if (sh
& 2) {
7337 tmp
= load_reg(s
, rd
);
7338 gen_st32(tmp
, addr
, IS_USER(s
));
7339 tcg_gen_addi_i32(addr
, addr
, 4);
7340 tmp
= load_reg(s
, rd
+ 1);
7341 gen_st32(tmp
, addr
, IS_USER(s
));
7345 tmp
= gen_ld32(addr
, IS_USER(s
));
7346 store_reg(s
, rd
, tmp
);
7347 tcg_gen_addi_i32(addr
, addr
, 4);
7348 tmp
= gen_ld32(addr
, IS_USER(s
));
7352 address_offset
= -4;
7355 tmp
= load_reg(s
, rd
);
7356 gen_st16(tmp
, addr
, IS_USER(s
));
7359 /* Perform base writeback before the loaded value to
7360 ensure correct behavior with overlapping index registers.
7361 ldrd with base writeback is is undefined if the
7362 destination and index registers overlap. */
7363 if (!(insn
& (1 << 24))) {
7364 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7365 store_reg(s
, rn
, addr
);
7366 } else if (insn
& (1 << 21)) {
7368 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7369 store_reg(s
, rn
, addr
);
7371 tcg_temp_free_i32(addr
);
7374 /* Complete the load. */
7375 store_reg(s
, rd
, tmp
);
7384 if (insn
& (1 << 4)) {
7386 /* Armv6 Media instructions. */
7388 rn
= (insn
>> 16) & 0xf;
7389 rd
= (insn
>> 12) & 0xf;
7390 rs
= (insn
>> 8) & 0xf;
7391 switch ((insn
>> 23) & 3) {
7392 case 0: /* Parallel add/subtract. */
7393 op1
= (insn
>> 20) & 7;
7394 tmp
= load_reg(s
, rn
);
7395 tmp2
= load_reg(s
, rm
);
7396 sh
= (insn
>> 5) & 7;
7397 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7399 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7400 tcg_temp_free_i32(tmp2
);
7401 store_reg(s
, rd
, tmp
);
7404 if ((insn
& 0x00700020) == 0) {
7405 /* Halfword pack. */
7406 tmp
= load_reg(s
, rn
);
7407 tmp2
= load_reg(s
, rm
);
7408 shift
= (insn
>> 7) & 0x1f;
7409 if (insn
& (1 << 6)) {
7413 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7414 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7415 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7419 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7420 tcg_gen_ext16u_i32(tmp
, tmp
);
7421 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7423 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7424 tcg_temp_free_i32(tmp2
);
7425 store_reg(s
, rd
, tmp
);
7426 } else if ((insn
& 0x00200020) == 0x00200000) {
7428 tmp
= load_reg(s
, rm
);
7429 shift
= (insn
>> 7) & 0x1f;
7430 if (insn
& (1 << 6)) {
7433 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7435 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7437 sh
= (insn
>> 16) & 0x1f;
7438 tmp2
= tcg_const_i32(sh
);
7439 if (insn
& (1 << 22))
7440 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
7442 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
7443 tcg_temp_free_i32(tmp2
);
7444 store_reg(s
, rd
, tmp
);
7445 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7447 tmp
= load_reg(s
, rm
);
7448 sh
= (insn
>> 16) & 0x1f;
7449 tmp2
= tcg_const_i32(sh
);
7450 if (insn
& (1 << 22))
7451 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
7453 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
7454 tcg_temp_free_i32(tmp2
);
7455 store_reg(s
, rd
, tmp
);
7456 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7458 tmp
= load_reg(s
, rn
);
7459 tmp2
= load_reg(s
, rm
);
7460 tmp3
= tcg_temp_new_i32();
7461 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7462 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7463 tcg_temp_free_i32(tmp3
);
7464 tcg_temp_free_i32(tmp2
);
7465 store_reg(s
, rd
, tmp
);
7466 } else if ((insn
& 0x000003e0) == 0x00000060) {
7467 tmp
= load_reg(s
, rm
);
7468 shift
= (insn
>> 10) & 3;
7469 /* ??? In many cases it's not necessary to do a
7470 rotate, a shift is sufficient. */
7472 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7473 op1
= (insn
>> 20) & 7;
7475 case 0: gen_sxtb16(tmp
); break;
7476 case 2: gen_sxtb(tmp
); break;
7477 case 3: gen_sxth(tmp
); break;
7478 case 4: gen_uxtb16(tmp
); break;
7479 case 6: gen_uxtb(tmp
); break;
7480 case 7: gen_uxth(tmp
); break;
7481 default: goto illegal_op
;
7484 tmp2
= load_reg(s
, rn
);
7485 if ((op1
& 3) == 0) {
7486 gen_add16(tmp
, tmp2
);
7488 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7489 tcg_temp_free_i32(tmp2
);
7492 store_reg(s
, rd
, tmp
);
7493 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7495 tmp
= load_reg(s
, rm
);
7496 if (insn
& (1 << 22)) {
7497 if (insn
& (1 << 7)) {
7501 gen_helper_rbit(tmp
, tmp
);
7504 if (insn
& (1 << 7))
7507 tcg_gen_bswap32_i32(tmp
, tmp
);
7509 store_reg(s
, rd
, tmp
);
7514 case 2: /* Multiplies (Type 3). */
7515 switch ((insn
>> 20) & 0x7) {
7517 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7518 /* op2 not 00x or 11x : UNDEF */
7521 /* Signed multiply most significant [accumulate].
7522 (SMMUL, SMMLA, SMMLS) */
7523 tmp
= load_reg(s
, rm
);
7524 tmp2
= load_reg(s
, rs
);
7525 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7528 tmp
= load_reg(s
, rd
);
7529 if (insn
& (1 << 6)) {
7530 tmp64
= gen_subq_msw(tmp64
, tmp
);
7532 tmp64
= gen_addq_msw(tmp64
, tmp
);
7535 if (insn
& (1 << 5)) {
7536 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7538 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7539 tmp
= tcg_temp_new_i32();
7540 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7541 tcg_temp_free_i64(tmp64
);
7542 store_reg(s
, rn
, tmp
);
7546 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7547 if (insn
& (1 << 7)) {
7550 tmp
= load_reg(s
, rm
);
7551 tmp2
= load_reg(s
, rs
);
7552 if (insn
& (1 << 5))
7553 gen_swap_half(tmp2
);
7554 gen_smul_dual(tmp
, tmp2
);
7555 if (insn
& (1 << 6)) {
7556 /* This subtraction cannot overflow. */
7557 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7559 /* This addition cannot overflow 32 bits;
7560 * however it may overflow considered as a signed
7561 * operation, in which case we must set the Q flag.
7563 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7565 tcg_temp_free_i32(tmp2
);
7566 if (insn
& (1 << 22)) {
7567 /* smlald, smlsld */
7568 tmp64
= tcg_temp_new_i64();
7569 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7570 tcg_temp_free_i32(tmp
);
7571 gen_addq(s
, tmp64
, rd
, rn
);
7572 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7573 tcg_temp_free_i64(tmp64
);
7575 /* smuad, smusd, smlad, smlsd */
7578 tmp2
= load_reg(s
, rd
);
7579 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7580 tcg_temp_free_i32(tmp2
);
7582 store_reg(s
, rn
, tmp
);
7588 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7591 if (((insn
>> 5) & 7) || (rd
!= 15)) {
7594 tmp
= load_reg(s
, rm
);
7595 tmp2
= load_reg(s
, rs
);
7596 if (insn
& (1 << 21)) {
7597 gen_helper_udiv(tmp
, tmp
, tmp2
);
7599 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7601 tcg_temp_free_i32(tmp2
);
7602 store_reg(s
, rn
, tmp
);
7609 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7611 case 0: /* Unsigned sum of absolute differences. */
7613 tmp
= load_reg(s
, rm
);
7614 tmp2
= load_reg(s
, rs
);
7615 gen_helper_usad8(tmp
, tmp
, tmp2
);
7616 tcg_temp_free_i32(tmp2
);
7618 tmp2
= load_reg(s
, rd
);
7619 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7620 tcg_temp_free_i32(tmp2
);
7622 store_reg(s
, rn
, tmp
);
7624 case 0x20: case 0x24: case 0x28: case 0x2c:
7625 /* Bitfield insert/clear. */
7627 shift
= (insn
>> 7) & 0x1f;
7628 i
= (insn
>> 16) & 0x1f;
7631 tmp
= tcg_temp_new_i32();
7632 tcg_gen_movi_i32(tmp
, 0);
7634 tmp
= load_reg(s
, rm
);
7637 tmp2
= load_reg(s
, rd
);
7638 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
7639 tcg_temp_free_i32(tmp2
);
7641 store_reg(s
, rd
, tmp
);
7643 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7644 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7646 tmp
= load_reg(s
, rm
);
7647 shift
= (insn
>> 7) & 0x1f;
7648 i
= ((insn
>> 16) & 0x1f) + 1;
7653 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7655 gen_sbfx(tmp
, shift
, i
);
7658 store_reg(s
, rd
, tmp
);
7668 /* Check for undefined extension instructions
7669 * per the ARM Bible IE:
7670 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7672 sh
= (0xf << 20) | (0xf << 4);
7673 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7677 /* load/store byte/word */
7678 rn
= (insn
>> 16) & 0xf;
7679 rd
= (insn
>> 12) & 0xf;
7680 tmp2
= load_reg(s
, rn
);
7681 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7682 if (insn
& (1 << 24))
7683 gen_add_data_offset(s
, insn
, tmp2
);
7684 if (insn
& (1 << 20)) {
7686 if (insn
& (1 << 22)) {
7687 tmp
= gen_ld8u(tmp2
, i
);
7689 tmp
= gen_ld32(tmp2
, i
);
7693 tmp
= load_reg(s
, rd
);
7694 if (insn
& (1 << 22))
7695 gen_st8(tmp
, tmp2
, i
);
7697 gen_st32(tmp
, tmp2
, i
);
7699 if (!(insn
& (1 << 24))) {
7700 gen_add_data_offset(s
, insn
, tmp2
);
7701 store_reg(s
, rn
, tmp2
);
7702 } else if (insn
& (1 << 21)) {
7703 store_reg(s
, rn
, tmp2
);
7705 tcg_temp_free_i32(tmp2
);
7707 if (insn
& (1 << 20)) {
7708 /* Complete the load. */
7709 store_reg_from_load(env
, s
, rd
, tmp
);
7715 int j
, n
, user
, loaded_base
;
7717 /* load/store multiple words */
7718 /* XXX: store correct base if write back */
7720 if (insn
& (1 << 22)) {
7722 goto illegal_op
; /* only usable in supervisor mode */
7724 if ((insn
& (1 << 15)) == 0)
7727 rn
= (insn
>> 16) & 0xf;
7728 addr
= load_reg(s
, rn
);
7730 /* compute total size */
7732 TCGV_UNUSED(loaded_var
);
7735 if (insn
& (1 << i
))
7738 /* XXX: test invalid n == 0 case ? */
7739 if (insn
& (1 << 23)) {
7740 if (insn
& (1 << 24)) {
7742 tcg_gen_addi_i32(addr
, addr
, 4);
7744 /* post increment */
7747 if (insn
& (1 << 24)) {
7749 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7751 /* post decrement */
7753 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7758 if (insn
& (1 << i
)) {
7759 if (insn
& (1 << 20)) {
7761 tmp
= gen_ld32(addr
, IS_USER(s
));
7763 tmp2
= tcg_const_i32(i
);
7764 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
7765 tcg_temp_free_i32(tmp2
);
7766 tcg_temp_free_i32(tmp
);
7767 } else if (i
== rn
) {
7771 store_reg_from_load(env
, s
, i
, tmp
);
7776 /* special case: r15 = PC + 8 */
7777 val
= (long)s
->pc
+ 4;
7778 tmp
= tcg_temp_new_i32();
7779 tcg_gen_movi_i32(tmp
, val
);
7781 tmp
= tcg_temp_new_i32();
7782 tmp2
= tcg_const_i32(i
);
7783 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
7784 tcg_temp_free_i32(tmp2
);
7786 tmp
= load_reg(s
, i
);
7788 gen_st32(tmp
, addr
, IS_USER(s
));
7791 /* no need to add after the last transfer */
7793 tcg_gen_addi_i32(addr
, addr
, 4);
7796 if (insn
& (1 << 21)) {
7798 if (insn
& (1 << 23)) {
7799 if (insn
& (1 << 24)) {
7802 /* post increment */
7803 tcg_gen_addi_i32(addr
, addr
, 4);
7806 if (insn
& (1 << 24)) {
7809 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7811 /* post decrement */
7812 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7815 store_reg(s
, rn
, addr
);
7817 tcg_temp_free_i32(addr
);
7820 store_reg(s
, rn
, loaded_var
);
7822 if ((insn
& (1 << 22)) && !user
) {
7823 /* Restore CPSR from SPSR. */
7824 tmp
= load_cpu_field(spsr
);
7825 gen_set_cpsr(tmp
, 0xffffffff);
7826 tcg_temp_free_i32(tmp
);
7827 s
->is_jmp
= DISAS_UPDATE
;
7836 /* branch (and link) */
7837 val
= (int32_t)s
->pc
;
7838 if (insn
& (1 << 24)) {
7839 tmp
= tcg_temp_new_i32();
7840 tcg_gen_movi_i32(tmp
, val
);
7841 store_reg(s
, 14, tmp
);
7843 offset
= (((int32_t)insn
<< 8) >> 8);
7844 val
+= (offset
<< 2) + 4;
7852 if (disas_coproc_insn(env
, s
, insn
))
7857 gen_set_pc_im(s
->pc
);
7858 s
->is_jmp
= DISAS_SWI
;
7862 gen_exception_insn(s
, 4, EXCP_UDEF
);
7868 /* Return true if this is a Thumb-2 logical op. */
7870 thumb2_logic_op(int op
)
7875 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7876 then set condition code flags based on the result of the operation.
7877 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7878 to the high bit of T1.
7879 Returns zero if the opcode is valid. */
7882 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
7889 tcg_gen_and_i32(t0
, t0
, t1
);
7893 tcg_gen_andc_i32(t0
, t0
, t1
);
7897 tcg_gen_or_i32(t0
, t0
, t1
);
7901 tcg_gen_orc_i32(t0
, t0
, t1
);
7905 tcg_gen_xor_i32(t0
, t0
, t1
);
7910 gen_add_CC(t0
, t0
, t1
);
7912 tcg_gen_add_i32(t0
, t0
, t1
);
7916 gen_helper_adc_cc(t0
, cpu_env
, t0
, t1
);
7922 gen_helper_sbc_cc(t0
, cpu_env
, t0
, t1
);
7924 gen_sub_carry(t0
, t0
, t1
);
7928 gen_sub_CC(t0
, t0
, t1
);
7930 tcg_gen_sub_i32(t0
, t0
, t1
);
7934 gen_sub_CC(t0
, t1
, t0
);
7936 tcg_gen_sub_i32(t0
, t1
, t0
);
7938 default: /* 5, 6, 7, 9, 12, 15. */
7944 gen_set_CF_bit31(t1
);
7949 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7951 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
7953 uint32_t insn
, imm
, shift
, offset
;
7954 uint32_t rd
, rn
, rm
, rs
;
7965 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
7966 || arm_feature (env
, ARM_FEATURE_M
))) {
7967 /* Thumb-1 cores may need to treat bl and blx as a pair of
7968 16-bit instructions to get correct prefetch abort behavior. */
7970 if ((insn
& (1 << 12)) == 0) {
7972 /* Second half of blx. */
7973 offset
= ((insn
& 0x7ff) << 1);
7974 tmp
= load_reg(s
, 14);
7975 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7976 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
7978 tmp2
= tcg_temp_new_i32();
7979 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7980 store_reg(s
, 14, tmp2
);
7984 if (insn
& (1 << 11)) {
7985 /* Second half of bl. */
7986 offset
= ((insn
& 0x7ff) << 1) | 1;
7987 tmp
= load_reg(s
, 14);
7988 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7990 tmp2
= tcg_temp_new_i32();
7991 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7992 store_reg(s
, 14, tmp2
);
7996 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
7997 /* Instruction spans a page boundary. Implement it as two
7998 16-bit instructions in case the second half causes an
8000 offset
= ((int32_t)insn
<< 21) >> 9;
8001 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8004 /* Fall through to 32-bit decode. */
8007 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8009 insn
|= (uint32_t)insn_hw1
<< 16;
8011 if ((insn
& 0xf800e800) != 0xf000e800) {
8015 rn
= (insn
>> 16) & 0xf;
8016 rs
= (insn
>> 12) & 0xf;
8017 rd
= (insn
>> 8) & 0xf;
8019 switch ((insn
>> 25) & 0xf) {
8020 case 0: case 1: case 2: case 3:
8021 /* 16-bit instructions. Should never happen. */
8024 if (insn
& (1 << 22)) {
8025 /* Other load/store, table branch. */
8026 if (insn
& 0x01200000) {
8027 /* Load/store doubleword. */
8029 addr
= tcg_temp_new_i32();
8030 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8032 addr
= load_reg(s
, rn
);
8034 offset
= (insn
& 0xff) * 4;
8035 if ((insn
& (1 << 23)) == 0)
8037 if (insn
& (1 << 24)) {
8038 tcg_gen_addi_i32(addr
, addr
, offset
);
8041 if (insn
& (1 << 20)) {
8043 tmp
= gen_ld32(addr
, IS_USER(s
));
8044 store_reg(s
, rs
, tmp
);
8045 tcg_gen_addi_i32(addr
, addr
, 4);
8046 tmp
= gen_ld32(addr
, IS_USER(s
));
8047 store_reg(s
, rd
, tmp
);
8050 tmp
= load_reg(s
, rs
);
8051 gen_st32(tmp
, addr
, IS_USER(s
));
8052 tcg_gen_addi_i32(addr
, addr
, 4);
8053 tmp
= load_reg(s
, rd
);
8054 gen_st32(tmp
, addr
, IS_USER(s
));
8056 if (insn
& (1 << 21)) {
8057 /* Base writeback. */
8060 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8061 store_reg(s
, rn
, addr
);
8063 tcg_temp_free_i32(addr
);
8065 } else if ((insn
& (1 << 23)) == 0) {
8066 /* Load/store exclusive word. */
8067 addr
= tcg_temp_local_new();
8068 load_reg_var(s
, addr
, rn
);
8069 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8070 if (insn
& (1 << 20)) {
8071 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8073 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8075 tcg_temp_free(addr
);
8076 } else if ((insn
& (1 << 6)) == 0) {
8079 addr
= tcg_temp_new_i32();
8080 tcg_gen_movi_i32(addr
, s
->pc
);
8082 addr
= load_reg(s
, rn
);
8084 tmp
= load_reg(s
, rm
);
8085 tcg_gen_add_i32(addr
, addr
, tmp
);
8086 if (insn
& (1 << 4)) {
8088 tcg_gen_add_i32(addr
, addr
, tmp
);
8089 tcg_temp_free_i32(tmp
);
8090 tmp
= gen_ld16u(addr
, IS_USER(s
));
8092 tcg_temp_free_i32(tmp
);
8093 tmp
= gen_ld8u(addr
, IS_USER(s
));
8095 tcg_temp_free_i32(addr
);
8096 tcg_gen_shli_i32(tmp
, tmp
, 1);
8097 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8098 store_reg(s
, 15, tmp
);
8100 /* Load/store exclusive byte/halfword/doubleword. */
8102 op
= (insn
>> 4) & 0x3;
8106 addr
= tcg_temp_local_new();
8107 load_reg_var(s
, addr
, rn
);
8108 if (insn
& (1 << 20)) {
8109 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8111 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8113 tcg_temp_free(addr
);
8116 /* Load/store multiple, RFE, SRS. */
8117 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8118 /* Not available in user mode. */
8121 if (insn
& (1 << 20)) {
8123 addr
= load_reg(s
, rn
);
8124 if ((insn
& (1 << 24)) == 0)
8125 tcg_gen_addi_i32(addr
, addr
, -8);
8126 /* Load PC into tmp and CPSR into tmp2. */
8127 tmp
= gen_ld32(addr
, 0);
8128 tcg_gen_addi_i32(addr
, addr
, 4);
8129 tmp2
= gen_ld32(addr
, 0);
8130 if (insn
& (1 << 21)) {
8131 /* Base writeback. */
8132 if (insn
& (1 << 24)) {
8133 tcg_gen_addi_i32(addr
, addr
, 4);
8135 tcg_gen_addi_i32(addr
, addr
, -4);
8137 store_reg(s
, rn
, addr
);
8139 tcg_temp_free_i32(addr
);
8141 gen_rfe(s
, tmp
, tmp2
);
8145 addr
= tcg_temp_new_i32();
8146 tmp
= tcg_const_i32(op
);
8147 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8148 tcg_temp_free_i32(tmp
);
8149 if ((insn
& (1 << 24)) == 0) {
8150 tcg_gen_addi_i32(addr
, addr
, -8);
8152 tmp
= load_reg(s
, 14);
8153 gen_st32(tmp
, addr
, 0);
8154 tcg_gen_addi_i32(addr
, addr
, 4);
8155 tmp
= tcg_temp_new_i32();
8156 gen_helper_cpsr_read(tmp
, cpu_env
);
8157 gen_st32(tmp
, addr
, 0);
8158 if (insn
& (1 << 21)) {
8159 if ((insn
& (1 << 24)) == 0) {
8160 tcg_gen_addi_i32(addr
, addr
, -4);
8162 tcg_gen_addi_i32(addr
, addr
, 4);
8164 tmp
= tcg_const_i32(op
);
8165 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8166 tcg_temp_free_i32(tmp
);
8168 tcg_temp_free_i32(addr
);
8172 int i
, loaded_base
= 0;
8174 /* Load/store multiple. */
8175 addr
= load_reg(s
, rn
);
8177 for (i
= 0; i
< 16; i
++) {
8178 if (insn
& (1 << i
))
8181 if (insn
& (1 << 24)) {
8182 tcg_gen_addi_i32(addr
, addr
, -offset
);
8185 TCGV_UNUSED(loaded_var
);
8186 for (i
= 0; i
< 16; i
++) {
8187 if ((insn
& (1 << i
)) == 0)
8189 if (insn
& (1 << 20)) {
8191 tmp
= gen_ld32(addr
, IS_USER(s
));
8194 } else if (i
== rn
) {
8198 store_reg(s
, i
, tmp
);
8202 tmp
= load_reg(s
, i
);
8203 gen_st32(tmp
, addr
, IS_USER(s
));
8205 tcg_gen_addi_i32(addr
, addr
, 4);
8208 store_reg(s
, rn
, loaded_var
);
8210 if (insn
& (1 << 21)) {
8211 /* Base register writeback. */
8212 if (insn
& (1 << 24)) {
8213 tcg_gen_addi_i32(addr
, addr
, -offset
);
8215 /* Fault if writeback register is in register list. */
8216 if (insn
& (1 << rn
))
8218 store_reg(s
, rn
, addr
);
8220 tcg_temp_free_i32(addr
);
8227 op
= (insn
>> 21) & 0xf;
8229 /* Halfword pack. */
8230 tmp
= load_reg(s
, rn
);
8231 tmp2
= load_reg(s
, rm
);
8232 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8233 if (insn
& (1 << 5)) {
8237 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8238 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8239 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8243 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8244 tcg_gen_ext16u_i32(tmp
, tmp
);
8245 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8247 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8248 tcg_temp_free_i32(tmp2
);
8249 store_reg(s
, rd
, tmp
);
8251 /* Data processing register constant shift. */
8253 tmp
= tcg_temp_new_i32();
8254 tcg_gen_movi_i32(tmp
, 0);
8256 tmp
= load_reg(s
, rn
);
8258 tmp2
= load_reg(s
, rm
);
8260 shiftop
= (insn
>> 4) & 3;
8261 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8262 conds
= (insn
& (1 << 20)) != 0;
8263 logic_cc
= (conds
&& thumb2_logic_op(op
));
8264 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8265 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8267 tcg_temp_free_i32(tmp2
);
8269 store_reg(s
, rd
, tmp
);
8271 tcg_temp_free_i32(tmp
);
8275 case 13: /* Misc data processing. */
8276 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8277 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8280 case 0: /* Register controlled shift. */
8281 tmp
= load_reg(s
, rn
);
8282 tmp2
= load_reg(s
, rm
);
8283 if ((insn
& 0x70) != 0)
8285 op
= (insn
>> 21) & 3;
8286 logic_cc
= (insn
& (1 << 20)) != 0;
8287 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8290 store_reg_bx(env
, s
, rd
, tmp
);
8292 case 1: /* Sign/zero extend. */
8293 tmp
= load_reg(s
, rm
);
8294 shift
= (insn
>> 4) & 3;
8295 /* ??? In many cases it's not necessary to do a
8296 rotate, a shift is sufficient. */
8298 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8299 op
= (insn
>> 20) & 7;
8301 case 0: gen_sxth(tmp
); break;
8302 case 1: gen_uxth(tmp
); break;
8303 case 2: gen_sxtb16(tmp
); break;
8304 case 3: gen_uxtb16(tmp
); break;
8305 case 4: gen_sxtb(tmp
); break;
8306 case 5: gen_uxtb(tmp
); break;
8307 default: goto illegal_op
;
8310 tmp2
= load_reg(s
, rn
);
8311 if ((op
>> 1) == 1) {
8312 gen_add16(tmp
, tmp2
);
8314 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8315 tcg_temp_free_i32(tmp2
);
8318 store_reg(s
, rd
, tmp
);
8320 case 2: /* SIMD add/subtract. */
8321 op
= (insn
>> 20) & 7;
8322 shift
= (insn
>> 4) & 7;
8323 if ((op
& 3) == 3 || (shift
& 3) == 3)
8325 tmp
= load_reg(s
, rn
);
8326 tmp2
= load_reg(s
, rm
);
8327 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8328 tcg_temp_free_i32(tmp2
);
8329 store_reg(s
, rd
, tmp
);
8331 case 3: /* Other data processing. */
8332 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8334 /* Saturating add/subtract. */
8335 tmp
= load_reg(s
, rn
);
8336 tmp2
= load_reg(s
, rm
);
8338 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
8340 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
8342 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8343 tcg_temp_free_i32(tmp2
);
8345 tmp
= load_reg(s
, rn
);
8347 case 0x0a: /* rbit */
8348 gen_helper_rbit(tmp
, tmp
);
8350 case 0x08: /* rev */
8351 tcg_gen_bswap32_i32(tmp
, tmp
);
8353 case 0x09: /* rev16 */
8356 case 0x0b: /* revsh */
8359 case 0x10: /* sel */
8360 tmp2
= load_reg(s
, rm
);
8361 tmp3
= tcg_temp_new_i32();
8362 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8363 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8364 tcg_temp_free_i32(tmp3
);
8365 tcg_temp_free_i32(tmp2
);
8367 case 0x18: /* clz */
8368 gen_helper_clz(tmp
, tmp
);
8374 store_reg(s
, rd
, tmp
);
8376 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8377 op
= (insn
>> 4) & 0xf;
8378 tmp
= load_reg(s
, rn
);
8379 tmp2
= load_reg(s
, rm
);
8380 switch ((insn
>> 20) & 7) {
8381 case 0: /* 32 x 32 -> 32 */
8382 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8383 tcg_temp_free_i32(tmp2
);
8385 tmp2
= load_reg(s
, rs
);
8387 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8389 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8390 tcg_temp_free_i32(tmp2
);
8393 case 1: /* 16 x 16 -> 32 */
8394 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8395 tcg_temp_free_i32(tmp2
);
8397 tmp2
= load_reg(s
, rs
);
8398 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8399 tcg_temp_free_i32(tmp2
);
8402 case 2: /* Dual multiply add. */
8403 case 4: /* Dual multiply subtract. */
8405 gen_swap_half(tmp2
);
8406 gen_smul_dual(tmp
, tmp2
);
8407 if (insn
& (1 << 22)) {
8408 /* This subtraction cannot overflow. */
8409 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8411 /* This addition cannot overflow 32 bits;
8412 * however it may overflow considered as a signed
8413 * operation, in which case we must set the Q flag.
8415 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8417 tcg_temp_free_i32(tmp2
);
8420 tmp2
= load_reg(s
, rs
);
8421 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8422 tcg_temp_free_i32(tmp2
);
8425 case 3: /* 32 * 16 -> 32msb */
8427 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8430 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8431 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8432 tmp
= tcg_temp_new_i32();
8433 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8434 tcg_temp_free_i64(tmp64
);
8437 tmp2
= load_reg(s
, rs
);
8438 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8439 tcg_temp_free_i32(tmp2
);
8442 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8443 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8445 tmp
= load_reg(s
, rs
);
8446 if (insn
& (1 << 20)) {
8447 tmp64
= gen_addq_msw(tmp64
, tmp
);
8449 tmp64
= gen_subq_msw(tmp64
, tmp
);
8452 if (insn
& (1 << 4)) {
8453 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8455 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8456 tmp
= tcg_temp_new_i32();
8457 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8458 tcg_temp_free_i64(tmp64
);
8460 case 7: /* Unsigned sum of absolute differences. */
8461 gen_helper_usad8(tmp
, tmp
, tmp2
);
8462 tcg_temp_free_i32(tmp2
);
8464 tmp2
= load_reg(s
, rs
);
8465 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8466 tcg_temp_free_i32(tmp2
);
8470 store_reg(s
, rd
, tmp
);
8472 case 6: case 7: /* 64-bit multiply, Divide. */
8473 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8474 tmp
= load_reg(s
, rn
);
8475 tmp2
= load_reg(s
, rm
);
8476 if ((op
& 0x50) == 0x10) {
8478 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8482 gen_helper_udiv(tmp
, tmp
, tmp2
);
8484 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8485 tcg_temp_free_i32(tmp2
);
8486 store_reg(s
, rd
, tmp
);
8487 } else if ((op
& 0xe) == 0xc) {
8488 /* Dual multiply accumulate long. */
8490 gen_swap_half(tmp2
);
8491 gen_smul_dual(tmp
, tmp2
);
8493 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8495 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8497 tcg_temp_free_i32(tmp2
);
8499 tmp64
= tcg_temp_new_i64();
8500 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8501 tcg_temp_free_i32(tmp
);
8502 gen_addq(s
, tmp64
, rs
, rd
);
8503 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8504 tcg_temp_free_i64(tmp64
);
8507 /* Unsigned 64-bit multiply */
8508 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8512 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8513 tcg_temp_free_i32(tmp2
);
8514 tmp64
= tcg_temp_new_i64();
8515 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8516 tcg_temp_free_i32(tmp
);
8518 /* Signed 64-bit multiply */
8519 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8524 gen_addq_lo(s
, tmp64
, rs
);
8525 gen_addq_lo(s
, tmp64
, rd
);
8526 } else if (op
& 0x40) {
8527 /* 64-bit accumulate. */
8528 gen_addq(s
, tmp64
, rs
, rd
);
8530 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8531 tcg_temp_free_i64(tmp64
);
8536 case 6: case 7: case 14: case 15:
8538 if (((insn
>> 24) & 3) == 3) {
8539 /* Translate into the equivalent ARM encoding. */
8540 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8541 if (disas_neon_data_insn(env
, s
, insn
))
8544 if (insn
& (1 << 28))
8546 if (disas_coproc_insn (env
, s
, insn
))
8550 case 8: case 9: case 10: case 11:
8551 if (insn
& (1 << 15)) {
8552 /* Branches, misc control. */
8553 if (insn
& 0x5000) {
8554 /* Unconditional branch. */
8555 /* signextend(hw1[10:0]) -> offset[:12]. */
8556 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8557 /* hw1[10:0] -> offset[11:1]. */
8558 offset
|= (insn
& 0x7ff) << 1;
8559 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8560 offset[24:22] already have the same value because of the
8561 sign extension above. */
8562 offset
^= ((~insn
) & (1 << 13)) << 10;
8563 offset
^= ((~insn
) & (1 << 11)) << 11;
8565 if (insn
& (1 << 14)) {
8566 /* Branch and link. */
8567 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8571 if (insn
& (1 << 12)) {
8576 offset
&= ~(uint32_t)2;
8577 /* thumb2 bx, no need to check */
8578 gen_bx_im(s
, offset
);
8580 } else if (((insn
>> 23) & 7) == 7) {
8582 if (insn
& (1 << 13))
8585 if (insn
& (1 << 26)) {
8586 /* Secure monitor call (v6Z) */
8587 goto illegal_op
; /* not implemented. */
8589 op
= (insn
>> 20) & 7;
8591 case 0: /* msr cpsr. */
8593 tmp
= load_reg(s
, rn
);
8594 addr
= tcg_const_i32(insn
& 0xff);
8595 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8596 tcg_temp_free_i32(addr
);
8597 tcg_temp_free_i32(tmp
);
8602 case 1: /* msr spsr. */
8605 tmp
= load_reg(s
, rn
);
8607 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8611 case 2: /* cps, nop-hint. */
8612 if (((insn
>> 8) & 7) == 0) {
8613 gen_nop_hint(s
, insn
& 0xff);
8615 /* Implemented as NOP in user mode. */
8620 if (insn
& (1 << 10)) {
8621 if (insn
& (1 << 7))
8623 if (insn
& (1 << 6))
8625 if (insn
& (1 << 5))
8627 if (insn
& (1 << 9))
8628 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8630 if (insn
& (1 << 8)) {
8632 imm
|= (insn
& 0x1f);
8635 gen_set_psr_im(s
, offset
, 0, imm
);
8638 case 3: /* Special control operations. */
8640 op
= (insn
>> 4) & 0xf;
8648 /* These execute as NOPs. */
8655 /* Trivial implementation equivalent to bx. */
8656 tmp
= load_reg(s
, rn
);
8659 case 5: /* Exception return. */
8663 if (rn
!= 14 || rd
!= 15) {
8666 tmp
= load_reg(s
, rn
);
8667 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8668 gen_exception_return(s
, tmp
);
8670 case 6: /* mrs cpsr. */
8671 tmp
= tcg_temp_new_i32();
8673 addr
= tcg_const_i32(insn
& 0xff);
8674 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8675 tcg_temp_free_i32(addr
);
8677 gen_helper_cpsr_read(tmp
, cpu_env
);
8679 store_reg(s
, rd
, tmp
);
8681 case 7: /* mrs spsr. */
8682 /* Not accessible in user mode. */
8683 if (IS_USER(s
) || IS_M(env
))
8685 tmp
= load_cpu_field(spsr
);
8686 store_reg(s
, rd
, tmp
);
8691 /* Conditional branch. */
8692 op
= (insn
>> 22) & 0xf;
8693 /* Generate a conditional jump to next instruction. */
8694 s
->condlabel
= gen_new_label();
8695 gen_test_cc(op
^ 1, s
->condlabel
);
8698 /* offset[11:1] = insn[10:0] */
8699 offset
= (insn
& 0x7ff) << 1;
8700 /* offset[17:12] = insn[21:16]. */
8701 offset
|= (insn
& 0x003f0000) >> 4;
8702 /* offset[31:20] = insn[26]. */
8703 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8704 /* offset[18] = insn[13]. */
8705 offset
|= (insn
& (1 << 13)) << 5;
8706 /* offset[19] = insn[11]. */
8707 offset
|= (insn
& (1 << 11)) << 8;
8709 /* jump to the offset */
8710 gen_jmp(s
, s
->pc
+ offset
);
8713 /* Data processing immediate. */
8714 if (insn
& (1 << 25)) {
8715 if (insn
& (1 << 24)) {
8716 if (insn
& (1 << 20))
8718 /* Bitfield/Saturate. */
8719 op
= (insn
>> 21) & 7;
8721 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8723 tmp
= tcg_temp_new_i32();
8724 tcg_gen_movi_i32(tmp
, 0);
8726 tmp
= load_reg(s
, rn
);
8729 case 2: /* Signed bitfield extract. */
8731 if (shift
+ imm
> 32)
8734 gen_sbfx(tmp
, shift
, imm
);
8736 case 6: /* Unsigned bitfield extract. */
8738 if (shift
+ imm
> 32)
8741 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8743 case 3: /* Bitfield insert/clear. */
8746 imm
= imm
+ 1 - shift
;
8748 tmp2
= load_reg(s
, rd
);
8749 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
8750 tcg_temp_free_i32(tmp2
);
8755 default: /* Saturate. */
8758 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8760 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8762 tmp2
= tcg_const_i32(imm
);
8765 if ((op
& 1) && shift
== 0)
8766 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8768 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8771 if ((op
& 1) && shift
== 0)
8772 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8774 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8776 tcg_temp_free_i32(tmp2
);
8779 store_reg(s
, rd
, tmp
);
8781 imm
= ((insn
& 0x04000000) >> 15)
8782 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8783 if (insn
& (1 << 22)) {
8784 /* 16-bit immediate. */
8785 imm
|= (insn
>> 4) & 0xf000;
8786 if (insn
& (1 << 23)) {
8788 tmp
= load_reg(s
, rd
);
8789 tcg_gen_ext16u_i32(tmp
, tmp
);
8790 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8793 tmp
= tcg_temp_new_i32();
8794 tcg_gen_movi_i32(tmp
, imm
);
8797 /* Add/sub 12-bit immediate. */
8799 offset
= s
->pc
& ~(uint32_t)3;
8800 if (insn
& (1 << 23))
8804 tmp
= tcg_temp_new_i32();
8805 tcg_gen_movi_i32(tmp
, offset
);
8807 tmp
= load_reg(s
, rn
);
8808 if (insn
& (1 << 23))
8809 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8811 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8814 store_reg(s
, rd
, tmp
);
8817 int shifter_out
= 0;
8818 /* modified 12-bit immediate. */
8819 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8820 imm
= (insn
& 0xff);
8823 /* Nothing to do. */
8825 case 1: /* 00XY00XY */
8828 case 2: /* XY00XY00 */
8832 case 3: /* XYXYXYXY */
8836 default: /* Rotated constant. */
8837 shift
= (shift
<< 1) | (imm
>> 7);
8839 imm
= imm
<< (32 - shift
);
8843 tmp2
= tcg_temp_new_i32();
8844 tcg_gen_movi_i32(tmp2
, imm
);
8845 rn
= (insn
>> 16) & 0xf;
8847 tmp
= tcg_temp_new_i32();
8848 tcg_gen_movi_i32(tmp
, 0);
8850 tmp
= load_reg(s
, rn
);
8852 op
= (insn
>> 21) & 0xf;
8853 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8854 shifter_out
, tmp
, tmp2
))
8856 tcg_temp_free_i32(tmp2
);
8857 rd
= (insn
>> 8) & 0xf;
8859 store_reg(s
, rd
, tmp
);
8861 tcg_temp_free_i32(tmp
);
8866 case 12: /* Load/store single data item. */
8871 if ((insn
& 0x01100000) == 0x01000000) {
8872 if (disas_neon_ls_insn(env
, s
, insn
))
8876 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8878 if (!(insn
& (1 << 20))) {
8882 /* Byte or halfword load space with dest == r15 : memory hints.
8883 * Catch them early so we don't emit pointless addressing code.
8884 * This space is a mix of:
8885 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8886 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8888 * unallocated hints, which must be treated as NOPs
8889 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8890 * which is easiest for the decoding logic
8891 * Some space which must UNDEF
8893 int op1
= (insn
>> 23) & 3;
8894 int op2
= (insn
>> 6) & 0x3f;
8899 /* UNPREDICTABLE, unallocated hint or
8900 * PLD/PLDW/PLI (literal)
8905 return 0; /* PLD/PLDW/PLI or unallocated hint */
8907 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
8908 return 0; /* PLD/PLDW/PLI or unallocated hint */
8910 /* UNDEF space, or an UNPREDICTABLE */
8916 addr
= tcg_temp_new_i32();
8918 /* s->pc has already been incremented by 4. */
8919 imm
= s
->pc
& 0xfffffffc;
8920 if (insn
& (1 << 23))
8921 imm
+= insn
& 0xfff;
8923 imm
-= insn
& 0xfff;
8924 tcg_gen_movi_i32(addr
, imm
);
8926 addr
= load_reg(s
, rn
);
8927 if (insn
& (1 << 23)) {
8928 /* Positive offset. */
8930 tcg_gen_addi_i32(addr
, addr
, imm
);
8933 switch ((insn
>> 8) & 0xf) {
8934 case 0x0: /* Shifted Register. */
8935 shift
= (insn
>> 4) & 0xf;
8937 tcg_temp_free_i32(addr
);
8940 tmp
= load_reg(s
, rm
);
8942 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8943 tcg_gen_add_i32(addr
, addr
, tmp
);
8944 tcg_temp_free_i32(tmp
);
8946 case 0xc: /* Negative offset. */
8947 tcg_gen_addi_i32(addr
, addr
, -imm
);
8949 case 0xe: /* User privilege. */
8950 tcg_gen_addi_i32(addr
, addr
, imm
);
8953 case 0x9: /* Post-decrement. */
8956 case 0xb: /* Post-increment. */
8960 case 0xd: /* Pre-decrement. */
8963 case 0xf: /* Pre-increment. */
8964 tcg_gen_addi_i32(addr
, addr
, imm
);
8968 tcg_temp_free_i32(addr
);
8973 if (insn
& (1 << 20)) {
8976 case 0: tmp
= gen_ld8u(addr
, user
); break;
8977 case 4: tmp
= gen_ld8s(addr
, user
); break;
8978 case 1: tmp
= gen_ld16u(addr
, user
); break;
8979 case 5: tmp
= gen_ld16s(addr
, user
); break;
8980 case 2: tmp
= gen_ld32(addr
, user
); break;
8982 tcg_temp_free_i32(addr
);
8988 store_reg(s
, rs
, tmp
);
8992 tmp
= load_reg(s
, rs
);
8994 case 0: gen_st8(tmp
, addr
, user
); break;
8995 case 1: gen_st16(tmp
, addr
, user
); break;
8996 case 2: gen_st32(tmp
, addr
, user
); break;
8998 tcg_temp_free_i32(addr
);
9003 tcg_gen_addi_i32(addr
, addr
, imm
);
9005 store_reg(s
, rn
, addr
);
9007 tcg_temp_free_i32(addr
);
9019 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9021 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9028 if (s
->condexec_mask
) {
9029 cond
= s
->condexec_cond
;
9030 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9031 s
->condlabel
= gen_new_label();
9032 gen_test_cc(cond
^ 1, s
->condlabel
);
9037 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9040 switch (insn
>> 12) {
9044 op
= (insn
>> 11) & 3;
9047 rn
= (insn
>> 3) & 7;
9048 tmp
= load_reg(s
, rn
);
9049 if (insn
& (1 << 10)) {
9051 tmp2
= tcg_temp_new_i32();
9052 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9055 rm
= (insn
>> 6) & 7;
9056 tmp2
= load_reg(s
, rm
);
9058 if (insn
& (1 << 9)) {
9059 if (s
->condexec_mask
)
9060 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9062 gen_sub_CC(tmp
, tmp
, tmp2
);
9064 if (s
->condexec_mask
)
9065 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9067 gen_add_CC(tmp
, tmp
, tmp2
);
9069 tcg_temp_free_i32(tmp2
);
9070 store_reg(s
, rd
, tmp
);
9072 /* shift immediate */
9073 rm
= (insn
>> 3) & 7;
9074 shift
= (insn
>> 6) & 0x1f;
9075 tmp
= load_reg(s
, rm
);
9076 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9077 if (!s
->condexec_mask
)
9079 store_reg(s
, rd
, tmp
);
9083 /* arithmetic large immediate */
9084 op
= (insn
>> 11) & 3;
9085 rd
= (insn
>> 8) & 0x7;
9086 if (op
== 0) { /* mov */
9087 tmp
= tcg_temp_new_i32();
9088 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9089 if (!s
->condexec_mask
)
9091 store_reg(s
, rd
, tmp
);
9093 tmp
= load_reg(s
, rd
);
9094 tmp2
= tcg_temp_new_i32();
9095 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9098 gen_sub_CC(tmp
, tmp
, tmp2
);
9099 tcg_temp_free_i32(tmp
);
9100 tcg_temp_free_i32(tmp2
);
9103 if (s
->condexec_mask
)
9104 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9106 gen_add_CC(tmp
, tmp
, tmp2
);
9107 tcg_temp_free_i32(tmp2
);
9108 store_reg(s
, rd
, tmp
);
9111 if (s
->condexec_mask
)
9112 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9114 gen_sub_CC(tmp
, tmp
, tmp2
);
9115 tcg_temp_free_i32(tmp2
);
9116 store_reg(s
, rd
, tmp
);
9122 if (insn
& (1 << 11)) {
9123 rd
= (insn
>> 8) & 7;
9124 /* load pc-relative. Bit 1 of PC is ignored. */
9125 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9126 val
&= ~(uint32_t)2;
9127 addr
= tcg_temp_new_i32();
9128 tcg_gen_movi_i32(addr
, val
);
9129 tmp
= gen_ld32(addr
, IS_USER(s
));
9130 tcg_temp_free_i32(addr
);
9131 store_reg(s
, rd
, tmp
);
9134 if (insn
& (1 << 10)) {
9135 /* data processing extended or blx */
9136 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9137 rm
= (insn
>> 3) & 0xf;
9138 op
= (insn
>> 8) & 3;
9141 tmp
= load_reg(s
, rd
);
9142 tmp2
= load_reg(s
, rm
);
9143 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9144 tcg_temp_free_i32(tmp2
);
9145 store_reg(s
, rd
, tmp
);
9148 tmp
= load_reg(s
, rd
);
9149 tmp2
= load_reg(s
, rm
);
9150 gen_sub_CC(tmp
, tmp
, tmp2
);
9151 tcg_temp_free_i32(tmp2
);
9152 tcg_temp_free_i32(tmp
);
9154 case 2: /* mov/cpy */
9155 tmp
= load_reg(s
, rm
);
9156 store_reg(s
, rd
, tmp
);
9158 case 3:/* branch [and link] exchange thumb register */
9159 tmp
= load_reg(s
, rm
);
9160 if (insn
& (1 << 7)) {
9162 val
= (uint32_t)s
->pc
| 1;
9163 tmp2
= tcg_temp_new_i32();
9164 tcg_gen_movi_i32(tmp2
, val
);
9165 store_reg(s
, 14, tmp2
);
9167 /* already thumb, no need to check */
9174 /* data processing register */
9176 rm
= (insn
>> 3) & 7;
9177 op
= (insn
>> 6) & 0xf;
9178 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9179 /* the shift/rotate ops want the operands backwards */
9188 if (op
== 9) { /* neg */
9189 tmp
= tcg_temp_new_i32();
9190 tcg_gen_movi_i32(tmp
, 0);
9191 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9192 tmp
= load_reg(s
, rd
);
9197 tmp2
= load_reg(s
, rm
);
9200 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9201 if (!s
->condexec_mask
)
9205 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9206 if (!s
->condexec_mask
)
9210 if (s
->condexec_mask
) {
9211 gen_shl(tmp2
, tmp2
, tmp
);
9213 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9218 if (s
->condexec_mask
) {
9219 gen_shr(tmp2
, tmp2
, tmp
);
9221 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9226 if (s
->condexec_mask
) {
9227 gen_sar(tmp2
, tmp2
, tmp
);
9229 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9234 if (s
->condexec_mask
)
9237 gen_helper_adc_cc(tmp
, cpu_env
, tmp
, tmp2
);
9240 if (s
->condexec_mask
)
9241 gen_sub_carry(tmp
, tmp
, tmp2
);
9243 gen_helper_sbc_cc(tmp
, cpu_env
, tmp
, tmp2
);
9246 if (s
->condexec_mask
) {
9247 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9248 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9250 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9255 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9260 if (s
->condexec_mask
)
9261 tcg_gen_neg_i32(tmp
, tmp2
);
9263 gen_sub_CC(tmp
, tmp
, tmp2
);
9266 gen_sub_CC(tmp
, tmp
, tmp2
);
9270 gen_add_CC(tmp
, tmp
, tmp2
);
9274 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9275 if (!s
->condexec_mask
)
9279 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9280 if (!s
->condexec_mask
)
9284 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9285 if (!s
->condexec_mask
)
9289 tcg_gen_not_i32(tmp2
, tmp2
);
9290 if (!s
->condexec_mask
)
9298 store_reg(s
, rm
, tmp2
);
9300 tcg_temp_free_i32(tmp
);
9302 store_reg(s
, rd
, tmp
);
9303 tcg_temp_free_i32(tmp2
);
9306 tcg_temp_free_i32(tmp
);
9307 tcg_temp_free_i32(tmp2
);
9312 /* load/store register offset. */
9314 rn
= (insn
>> 3) & 7;
9315 rm
= (insn
>> 6) & 7;
9316 op
= (insn
>> 9) & 7;
9317 addr
= load_reg(s
, rn
);
9318 tmp
= load_reg(s
, rm
);
9319 tcg_gen_add_i32(addr
, addr
, tmp
);
9320 tcg_temp_free_i32(tmp
);
9322 if (op
< 3) /* store */
9323 tmp
= load_reg(s
, rd
);
9327 gen_st32(tmp
, addr
, IS_USER(s
));
9330 gen_st16(tmp
, addr
, IS_USER(s
));
9333 gen_st8(tmp
, addr
, IS_USER(s
));
9336 tmp
= gen_ld8s(addr
, IS_USER(s
));
9339 tmp
= gen_ld32(addr
, IS_USER(s
));
9342 tmp
= gen_ld16u(addr
, IS_USER(s
));
9345 tmp
= gen_ld8u(addr
, IS_USER(s
));
9348 tmp
= gen_ld16s(addr
, IS_USER(s
));
9351 if (op
>= 3) /* load */
9352 store_reg(s
, rd
, tmp
);
9353 tcg_temp_free_i32(addr
);
9357 /* load/store word immediate offset */
9359 rn
= (insn
>> 3) & 7;
9360 addr
= load_reg(s
, rn
);
9361 val
= (insn
>> 4) & 0x7c;
9362 tcg_gen_addi_i32(addr
, addr
, val
);
9364 if (insn
& (1 << 11)) {
9366 tmp
= gen_ld32(addr
, IS_USER(s
));
9367 store_reg(s
, rd
, tmp
);
9370 tmp
= load_reg(s
, rd
);
9371 gen_st32(tmp
, addr
, IS_USER(s
));
9373 tcg_temp_free_i32(addr
);
9377 /* load/store byte immediate offset */
9379 rn
= (insn
>> 3) & 7;
9380 addr
= load_reg(s
, rn
);
9381 val
= (insn
>> 6) & 0x1f;
9382 tcg_gen_addi_i32(addr
, addr
, val
);
9384 if (insn
& (1 << 11)) {
9386 tmp
= gen_ld8u(addr
, IS_USER(s
));
9387 store_reg(s
, rd
, tmp
);
9390 tmp
= load_reg(s
, rd
);
9391 gen_st8(tmp
, addr
, IS_USER(s
));
9393 tcg_temp_free_i32(addr
);
9397 /* load/store halfword immediate offset */
9399 rn
= (insn
>> 3) & 7;
9400 addr
= load_reg(s
, rn
);
9401 val
= (insn
>> 5) & 0x3e;
9402 tcg_gen_addi_i32(addr
, addr
, val
);
9404 if (insn
& (1 << 11)) {
9406 tmp
= gen_ld16u(addr
, IS_USER(s
));
9407 store_reg(s
, rd
, tmp
);
9410 tmp
= load_reg(s
, rd
);
9411 gen_st16(tmp
, addr
, IS_USER(s
));
9413 tcg_temp_free_i32(addr
);
9417 /* load/store from stack */
9418 rd
= (insn
>> 8) & 7;
9419 addr
= load_reg(s
, 13);
9420 val
= (insn
& 0xff) * 4;
9421 tcg_gen_addi_i32(addr
, addr
, val
);
9423 if (insn
& (1 << 11)) {
9425 tmp
= gen_ld32(addr
, IS_USER(s
));
9426 store_reg(s
, rd
, tmp
);
9429 tmp
= load_reg(s
, rd
);
9430 gen_st32(tmp
, addr
, IS_USER(s
));
9432 tcg_temp_free_i32(addr
);
9436 /* add to high reg */
9437 rd
= (insn
>> 8) & 7;
9438 if (insn
& (1 << 11)) {
9440 tmp
= load_reg(s
, 13);
9442 /* PC. bit 1 is ignored. */
9443 tmp
= tcg_temp_new_i32();
9444 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9446 val
= (insn
& 0xff) * 4;
9447 tcg_gen_addi_i32(tmp
, tmp
, val
);
9448 store_reg(s
, rd
, tmp
);
9453 op
= (insn
>> 8) & 0xf;
9456 /* adjust stack pointer */
9457 tmp
= load_reg(s
, 13);
9458 val
= (insn
& 0x7f) * 4;
9459 if (insn
& (1 << 7))
9460 val
= -(int32_t)val
;
9461 tcg_gen_addi_i32(tmp
, tmp
, val
);
9462 store_reg(s
, 13, tmp
);
9465 case 2: /* sign/zero extend. */
9468 rm
= (insn
>> 3) & 7;
9469 tmp
= load_reg(s
, rm
);
9470 switch ((insn
>> 6) & 3) {
9471 case 0: gen_sxth(tmp
); break;
9472 case 1: gen_sxtb(tmp
); break;
9473 case 2: gen_uxth(tmp
); break;
9474 case 3: gen_uxtb(tmp
); break;
9476 store_reg(s
, rd
, tmp
);
9478 case 4: case 5: case 0xc: case 0xd:
9480 addr
= load_reg(s
, 13);
9481 if (insn
& (1 << 8))
9485 for (i
= 0; i
< 8; i
++) {
9486 if (insn
& (1 << i
))
9489 if ((insn
& (1 << 11)) == 0) {
9490 tcg_gen_addi_i32(addr
, addr
, -offset
);
9492 for (i
= 0; i
< 8; i
++) {
9493 if (insn
& (1 << i
)) {
9494 if (insn
& (1 << 11)) {
9496 tmp
= gen_ld32(addr
, IS_USER(s
));
9497 store_reg(s
, i
, tmp
);
9500 tmp
= load_reg(s
, i
);
9501 gen_st32(tmp
, addr
, IS_USER(s
));
9503 /* advance to the next address. */
9504 tcg_gen_addi_i32(addr
, addr
, 4);
9508 if (insn
& (1 << 8)) {
9509 if (insn
& (1 << 11)) {
9511 tmp
= gen_ld32(addr
, IS_USER(s
));
9512 /* don't set the pc until the rest of the instruction
9516 tmp
= load_reg(s
, 14);
9517 gen_st32(tmp
, addr
, IS_USER(s
));
9519 tcg_gen_addi_i32(addr
, addr
, 4);
9521 if ((insn
& (1 << 11)) == 0) {
9522 tcg_gen_addi_i32(addr
, addr
, -offset
);
9524 /* write back the new stack pointer */
9525 store_reg(s
, 13, addr
);
9526 /* set the new PC value */
9527 if ((insn
& 0x0900) == 0x0900) {
9528 store_reg_from_load(env
, s
, 15, tmp
);
9532 case 1: case 3: case 9: case 11: /* czb */
9534 tmp
= load_reg(s
, rm
);
9535 s
->condlabel
= gen_new_label();
9537 if (insn
& (1 << 11))
9538 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9540 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9541 tcg_temp_free_i32(tmp
);
9542 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9543 val
= (uint32_t)s
->pc
+ 2;
9548 case 15: /* IT, nop-hint. */
9549 if ((insn
& 0xf) == 0) {
9550 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9554 s
->condexec_cond
= (insn
>> 4) & 0xe;
9555 s
->condexec_mask
= insn
& 0x1f;
9556 /* No actual code generated for this insn, just setup state. */
9559 case 0xe: /* bkpt */
9561 gen_exception_insn(s
, 2, EXCP_BKPT
);
9566 rn
= (insn
>> 3) & 0x7;
9568 tmp
= load_reg(s
, rn
);
9569 switch ((insn
>> 6) & 3) {
9570 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9571 case 1: gen_rev16(tmp
); break;
9572 case 3: gen_revsh(tmp
); break;
9573 default: goto illegal_op
;
9575 store_reg(s
, rd
, tmp
);
9579 switch ((insn
>> 5) & 7) {
9583 if (((insn
>> 3) & 1) != s
->bswap_code
) {
9584 /* Dynamic endianness switching not implemented. */
9595 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9598 addr
= tcg_const_i32(19);
9599 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9600 tcg_temp_free_i32(addr
);
9604 addr
= tcg_const_i32(16);
9605 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9606 tcg_temp_free_i32(addr
);
9608 tcg_temp_free_i32(tmp
);
9611 if (insn
& (1 << 4)) {
9612 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9616 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9631 /* load/store multiple */
9633 TCGV_UNUSED(loaded_var
);
9634 rn
= (insn
>> 8) & 0x7;
9635 addr
= load_reg(s
, rn
);
9636 for (i
= 0; i
< 8; i
++) {
9637 if (insn
& (1 << i
)) {
9638 if (insn
& (1 << 11)) {
9640 tmp
= gen_ld32(addr
, IS_USER(s
));
9644 store_reg(s
, i
, tmp
);
9648 tmp
= load_reg(s
, i
);
9649 gen_st32(tmp
, addr
, IS_USER(s
));
9651 /* advance to the next address */
9652 tcg_gen_addi_i32(addr
, addr
, 4);
9655 if ((insn
& (1 << rn
)) == 0) {
9656 /* base reg not in list: base register writeback */
9657 store_reg(s
, rn
, addr
);
9659 /* base reg in list: if load, complete it now */
9660 if (insn
& (1 << 11)) {
9661 store_reg(s
, rn
, loaded_var
);
9663 tcg_temp_free_i32(addr
);
9668 /* conditional branch or swi */
9669 cond
= (insn
>> 8) & 0xf;
9675 gen_set_pc_im(s
->pc
);
9676 s
->is_jmp
= DISAS_SWI
;
9679 /* generate a conditional jump to next instruction */
9680 s
->condlabel
= gen_new_label();
9681 gen_test_cc(cond
^ 1, s
->condlabel
);
9684 /* jump to the offset */
9685 val
= (uint32_t)s
->pc
+ 2;
9686 offset
= ((int32_t)insn
<< 24) >> 24;
9692 if (insn
& (1 << 11)) {
9693 if (disas_thumb2_insn(env
, s
, insn
))
9697 /* unconditional branch */
9698 val
= (uint32_t)s
->pc
;
9699 offset
= ((int32_t)insn
<< 21) >> 21;
9700 val
+= (offset
<< 1) + 2;
9705 if (disas_thumb2_insn(env
, s
, insn
))
9711 gen_exception_insn(s
, 4, EXCP_UDEF
);
9715 gen_exception_insn(s
, 2, EXCP_UDEF
);
9718 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9719 basic block 'tb'. If search_pc is TRUE, also generate PC
9720 information for each intermediate instruction. */
9721 static inline void gen_intermediate_code_internal(CPUARMState
*env
,
9722 TranslationBlock
*tb
,
9725 DisasContext dc1
, *dc
= &dc1
;
9727 uint16_t *gen_opc_end
;
9729 target_ulong pc_start
;
9730 uint32_t next_page_start
;
9734 /* generate intermediate code */
9739 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
9741 dc
->is_jmp
= DISAS_NEXT
;
9743 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9745 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9746 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
9747 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9748 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9749 #if !defined(CONFIG_USER_ONLY)
9750 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9752 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9753 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9754 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9755 cpu_F0s
= tcg_temp_new_i32();
9756 cpu_F1s
= tcg_temp_new_i32();
9757 cpu_F0d
= tcg_temp_new_i64();
9758 cpu_F1d
= tcg_temp_new_i64();
9761 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9762 cpu_M0
= tcg_temp_new_i64();
9763 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9766 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9768 max_insns
= CF_COUNT_MASK
;
9772 tcg_clear_temp_count();
9774 /* A note on handling of the condexec (IT) bits:
9776 * We want to avoid the overhead of having to write the updated condexec
9777 * bits back to the CPUARMState for every instruction in an IT block. So:
9778 * (1) if the condexec bits are not already zero then we write
9779 * zero back into the CPUARMState now. This avoids complications trying
9780 * to do it at the end of the block. (For example if we don't do this
9781 * it's hard to identify whether we can safely skip writing condexec
9782 * at the end of the TB, which we definitely want to do for the case
9783 * where a TB doesn't do anything with the IT state at all.)
9784 * (2) if we are going to leave the TB then we call gen_set_condexec()
9785 * which will write the correct value into CPUARMState if zero is wrong.
9786 * This is done both for leaving the TB at the end, and for leaving
9787 * it because of an exception we know will happen, which is done in
9788 * gen_exception_insn(). The latter is necessary because we need to
9789 * leave the TB with the PC/IT state just prior to execution of the
9790 * instruction which caused the exception.
9791 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9792 * then the CPUARMState will be wrong and we need to reset it.
9793 * This is handled in the same way as restoration of the
9794 * PC in these situations: we will be called again with search_pc=1
9795 * and generate a mapping of the condexec bits for each PC in
9796 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9797 * this to restore the condexec bits.
9799 * Note that there are no instructions which can read the condexec
9800 * bits, and none which can write non-static values to them, so
9801 * we don't need to care about whether CPUARMState is correct in the
9805 /* Reset the conditional execution bits immediately. This avoids
9806 complications trying to do it at the end of the block. */
9807 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9809 TCGv tmp
= tcg_temp_new_i32();
9810 tcg_gen_movi_i32(tmp
, 0);
9811 store_cpu_field(tmp
, condexec_bits
);
9814 #ifdef CONFIG_USER_ONLY
9815 /* Intercept jump to the magic kernel page. */
9816 if (dc
->pc
>= 0xffff0000) {
9817 /* We always get here via a jump, so know we are not in a
9818 conditional execution block. */
9819 gen_exception(EXCP_KERNEL_TRAP
);
9820 dc
->is_jmp
= DISAS_UPDATE
;
9824 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9825 /* We always get here via a jump, so know we are not in a
9826 conditional execution block. */
9827 gen_exception(EXCP_EXCEPTION_EXIT
);
9828 dc
->is_jmp
= DISAS_UPDATE
;
9833 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9834 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9835 if (bp
->pc
== dc
->pc
) {
9836 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9837 /* Advance PC so that clearing the breakpoint will
9838 invalidate this TB. */
9840 goto done_generating
;
9846 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
9850 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
9852 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
9853 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9854 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
9855 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
9858 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9861 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
9862 tcg_gen_debug_insn_start(dc
->pc
);
9866 disas_thumb_insn(env
, dc
);
9867 if (dc
->condexec_mask
) {
9868 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9869 | ((dc
->condexec_mask
>> 4) & 1);
9870 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9871 if (dc
->condexec_mask
== 0) {
9872 dc
->condexec_cond
= 0;
9876 disas_arm_insn(env
, dc
);
9879 if (dc
->condjmp
&& !dc
->is_jmp
) {
9880 gen_set_label(dc
->condlabel
);
9884 if (tcg_check_temp_count()) {
9885 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
9888 /* Translation stops when a conditional branch is encountered.
9889 * Otherwise the subsequent code could get translated several times.
9890 * Also stop translation when a page boundary is reached. This
9891 * ensures prefetch aborts occur at the right place. */
9893 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
9894 !env
->singlestep_enabled
&&
9896 dc
->pc
< next_page_start
&&
9897 num_insns
< max_insns
);
9899 if (tb
->cflags
& CF_LAST_IO
) {
9901 /* FIXME: This can theoretically happen with self-modifying
9903 cpu_abort(env
, "IO on conditional branch instruction");
9908 /* At this stage dc->condjmp will only be set when the skipped
9909 instruction was a conditional branch or trap, and the PC has
9910 already been written. */
9911 if (unlikely(env
->singlestep_enabled
)) {
9912 /* Make sure the pc is updated, and raise a debug exception. */
9914 gen_set_condexec(dc
);
9915 if (dc
->is_jmp
== DISAS_SWI
) {
9916 gen_exception(EXCP_SWI
);
9918 gen_exception(EXCP_DEBUG
);
9920 gen_set_label(dc
->condlabel
);
9922 if (dc
->condjmp
|| !dc
->is_jmp
) {
9923 gen_set_pc_im(dc
->pc
);
9926 gen_set_condexec(dc
);
9927 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
9928 gen_exception(EXCP_SWI
);
9930 /* FIXME: Single stepping a WFI insn will not halt
9932 gen_exception(EXCP_DEBUG
);
9935 /* While branches must always occur at the end of an IT block,
9936 there are a few other things that can cause us to terminate
9937 the TB in the middle of an IT block:
9938 - Exception generating instructions (bkpt, swi, undefined).
9940 - Hardware watchpoints.
9941 Hardware breakpoints have already been handled and skip this code.
9943 gen_set_condexec(dc
);
9944 switch(dc
->is_jmp
) {
9946 gen_goto_tb(dc
, 1, dc
->pc
);
9951 /* indicate that the hash table must be used to find the next TB */
9955 /* nothing more to generate */
9958 gen_helper_wfi(cpu_env
);
9961 gen_exception(EXCP_SWI
);
9965 gen_set_label(dc
->condlabel
);
9966 gen_set_condexec(dc
);
9967 gen_goto_tb(dc
, 1, dc
->pc
);
9973 gen_icount_end(tb
, num_insns
);
9974 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
9977 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
9978 qemu_log("----------------\n");
9979 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
9980 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
9981 dc
->thumb
| (dc
->bswap_code
<< 1));
9986 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
9989 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
9991 tb
->size
= dc
->pc
- pc_start
;
9992 tb
->icount
= num_insns
;
9996 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
9998 gen_intermediate_code_internal(env
, tb
, 0);
10001 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10003 gen_intermediate_code_internal(env
, tb
, 1);
10006 static const char *cpu_mode_names
[16] = {
10007 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10008 "???", "???", "???", "und", "???", "???", "???", "sys"
10011 void cpu_dump_state(CPUARMState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
10017 for(i
=0;i
<16;i
++) {
10018 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10020 cpu_fprintf(f
, "\n");
10022 cpu_fprintf(f
, " ");
10024 psr
= cpsr_read(env
);
10025 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10027 psr
& (1 << 31) ? 'N' : '-',
10028 psr
& (1 << 30) ? 'Z' : '-',
10029 psr
& (1 << 29) ? 'C' : '-',
10030 psr
& (1 << 28) ? 'V' : '-',
10031 psr
& CPSR_T
? 'T' : 'A',
10032 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10034 if (flags
& CPU_DUMP_FPU
) {
10035 int numvfpregs
= 0;
10036 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10039 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10042 for (i
= 0; i
< numvfpregs
; i
++) {
10043 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10044 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10045 i
* 2, (uint32_t)v
,
10046 i
* 2 + 1, (uint32_t)(v
>> 32),
10049 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10053 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10055 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10056 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];