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
)
413 TCGv tmp
= tcg_temp_new_i32();
414 tcg_gen_movi_i32(tmp
, 0);
415 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
416 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
417 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
418 tcg_gen_xor_i32(tmp
, t0
, t1
);
419 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
420 tcg_temp_free_i32(tmp
);
421 tcg_gen_mov_i32(dest
, cpu_NF
);
424 /* dest = T0 - T1. Compute C, N, V and Z flags */
425 static void gen_sub_CC(TCGv dest
, TCGv t0
, TCGv t1
)
428 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
429 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
430 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
431 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
432 tmp
= tcg_temp_new_i32();
433 tcg_gen_xor_i32(tmp
, t0
, t1
);
434 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
435 tcg_temp_free_i32(tmp
);
436 tcg_gen_mov_i32(dest
, cpu_NF
);
439 #define GEN_SHIFT(name) \
440 static void gen_##name(TCGv dest, TCGv t0, TCGv t1) \
442 TCGv tmp1, tmp2, tmp3; \
443 tmp1 = tcg_temp_new_i32(); \
444 tcg_gen_andi_i32(tmp1, t1, 0xff); \
445 tmp2 = tcg_const_i32(0); \
446 tmp3 = tcg_const_i32(0x1f); \
447 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
448 tcg_temp_free_i32(tmp3); \
449 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
450 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
451 tcg_temp_free_i32(tmp2); \
452 tcg_temp_free_i32(tmp1); \
458 static void gen_sar(TCGv dest
, TCGv t0
, TCGv t1
)
461 tmp1
= tcg_temp_new_i32();
462 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
463 tmp2
= tcg_const_i32(0x1f);
464 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
465 tcg_temp_free_i32(tmp2
);
466 tcg_gen_sar_i32(dest
, t0
, tmp1
);
467 tcg_temp_free_i32(tmp1
);
470 static void tcg_gen_abs_i32(TCGv dest
, TCGv src
)
472 TCGv c0
= tcg_const_i32(0);
473 TCGv tmp
= tcg_temp_new_i32();
474 tcg_gen_neg_i32(tmp
, src
);
475 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
476 tcg_temp_free_i32(c0
);
477 tcg_temp_free_i32(tmp
);
480 static void shifter_out_im(TCGv var
, int shift
)
483 tcg_gen_andi_i32(cpu_CF
, var
, 1);
485 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
487 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
492 /* Shift by immediate. Includes special handling for shift == 0. */
493 static inline void gen_arm_shift_im(TCGv var
, int shiftop
, int shift
, int flags
)
499 shifter_out_im(var
, 32 - shift
);
500 tcg_gen_shli_i32(var
, var
, shift
);
506 tcg_gen_shri_i32(cpu_CF
, var
, 31);
508 tcg_gen_movi_i32(var
, 0);
511 shifter_out_im(var
, shift
- 1);
512 tcg_gen_shri_i32(var
, var
, shift
);
519 shifter_out_im(var
, shift
- 1);
522 tcg_gen_sari_i32(var
, var
, shift
);
524 case 3: /* ROR/RRX */
527 shifter_out_im(var
, shift
- 1);
528 tcg_gen_rotri_i32(var
, var
, shift
); break;
530 TCGv tmp
= tcg_temp_new_i32();
531 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
533 shifter_out_im(var
, 0);
534 tcg_gen_shri_i32(var
, var
, 1);
535 tcg_gen_or_i32(var
, var
, tmp
);
536 tcg_temp_free_i32(tmp
);
541 static inline void gen_arm_shift_reg(TCGv var
, int shiftop
,
542 TCGv shift
, int flags
)
546 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
547 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
548 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
549 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
554 gen_shl(var
, var
, shift
);
557 gen_shr(var
, var
, shift
);
560 gen_sar(var
, var
, shift
);
562 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
563 tcg_gen_rotr_i32(var
, var
, shift
); break;
566 tcg_temp_free_i32(shift
);
569 #define PAS_OP(pfx) \
571 case 0: gen_pas_helper(glue(pfx,add16)); break; \
572 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
573 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
574 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
575 case 4: gen_pas_helper(glue(pfx,add8)); break; \
576 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
578 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
583 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
585 tmp
= tcg_temp_new_ptr();
586 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
588 tcg_temp_free_ptr(tmp
);
591 tmp
= tcg_temp_new_ptr();
592 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
594 tcg_temp_free_ptr(tmp
);
596 #undef gen_pas_helper
597 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
610 #undef gen_pas_helper
615 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
616 #define PAS_OP(pfx) \
618 case 0: gen_pas_helper(glue(pfx,add8)); break; \
619 case 1: gen_pas_helper(glue(pfx,add16)); break; \
620 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
621 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
622 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
623 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
625 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
630 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
632 tmp
= tcg_temp_new_ptr();
633 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
635 tcg_temp_free_ptr(tmp
);
638 tmp
= tcg_temp_new_ptr();
639 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
641 tcg_temp_free_ptr(tmp
);
643 #undef gen_pas_helper
644 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
657 #undef gen_pas_helper
662 static void gen_test_cc(int cc
, int label
)
669 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
672 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
675 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
678 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
681 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
684 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
687 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
690 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
692 case 8: /* hi: C && !Z */
693 inv
= gen_new_label();
694 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
695 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
698 case 9: /* ls: !C || Z */
699 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
700 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
702 case 10: /* ge: N == V -> N ^ V == 0 */
703 tmp
= tcg_temp_new_i32();
704 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
705 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
706 tcg_temp_free_i32(tmp
);
708 case 11: /* lt: N != V -> N ^ V != 0 */
709 tmp
= tcg_temp_new_i32();
710 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
711 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
712 tcg_temp_free_i32(tmp
);
714 case 12: /* gt: !Z && N == V */
715 inv
= gen_new_label();
716 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
717 tmp
= tcg_temp_new_i32();
718 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
719 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
720 tcg_temp_free_i32(tmp
);
723 case 13: /* le: Z || N != V */
724 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
725 tmp
= tcg_temp_new_i32();
726 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
727 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
728 tcg_temp_free_i32(tmp
);
731 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
736 static const uint8_t table_logic_cc
[16] = {
755 /* Set PC and Thumb state from an immediate address. */
756 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
760 s
->is_jmp
= DISAS_UPDATE
;
761 if (s
->thumb
!= (addr
& 1)) {
762 tmp
= tcg_temp_new_i32();
763 tcg_gen_movi_i32(tmp
, addr
& 1);
764 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
765 tcg_temp_free_i32(tmp
);
767 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
770 /* Set PC and Thumb state from var. var is marked as dead. */
771 static inline void gen_bx(DisasContext
*s
, TCGv var
)
773 s
->is_jmp
= DISAS_UPDATE
;
774 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
775 tcg_gen_andi_i32(var
, var
, 1);
776 store_cpu_field(var
, thumb
);
779 /* Variant of store_reg which uses branch&exchange logic when storing
780 to r15 in ARM architecture v7 and above. The source must be a temporary
781 and will be marked as dead. */
782 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
785 if (reg
== 15 && ENABLE_ARCH_7
) {
788 store_reg(s
, reg
, var
);
792 /* Variant of store_reg which uses branch&exchange logic when storing
793 * to r15 in ARM architecture v5T and above. This is used for storing
794 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
795 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
796 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
799 if (reg
== 15 && ENABLE_ARCH_5
) {
802 store_reg(s
, reg
, var
);
806 static inline TCGv
gen_ld8s(TCGv addr
, int index
)
808 TCGv tmp
= tcg_temp_new_i32();
809 tcg_gen_qemu_ld8s(tmp
, addr
, index
);
812 static inline TCGv
gen_ld8u(TCGv addr
, int index
)
814 TCGv tmp
= tcg_temp_new_i32();
815 tcg_gen_qemu_ld8u(tmp
, addr
, index
);
818 static inline TCGv
gen_ld16s(TCGv addr
, int index
)
820 TCGv tmp
= tcg_temp_new_i32();
821 tcg_gen_qemu_ld16s(tmp
, addr
, index
);
824 static inline TCGv
gen_ld16u(TCGv addr
, int index
)
826 TCGv tmp
= tcg_temp_new_i32();
827 tcg_gen_qemu_ld16u(tmp
, addr
, index
);
830 static inline TCGv
gen_ld32(TCGv addr
, int index
)
832 TCGv tmp
= tcg_temp_new_i32();
833 tcg_gen_qemu_ld32u(tmp
, addr
, index
);
836 static inline TCGv_i64
gen_ld64(TCGv addr
, int index
)
838 TCGv_i64 tmp
= tcg_temp_new_i64();
839 tcg_gen_qemu_ld64(tmp
, addr
, index
);
842 static inline void gen_st8(TCGv val
, TCGv addr
, int index
)
844 tcg_gen_qemu_st8(val
, addr
, index
);
845 tcg_temp_free_i32(val
);
847 static inline void gen_st16(TCGv val
, TCGv addr
, int index
)
849 tcg_gen_qemu_st16(val
, addr
, index
);
850 tcg_temp_free_i32(val
);
852 static inline void gen_st32(TCGv val
, TCGv addr
, int index
)
854 tcg_gen_qemu_st32(val
, addr
, index
);
855 tcg_temp_free_i32(val
);
857 static inline void gen_st64(TCGv_i64 val
, TCGv addr
, int index
)
859 tcg_gen_qemu_st64(val
, addr
, index
);
860 tcg_temp_free_i64(val
);
863 static inline void gen_set_pc_im(uint32_t val
)
865 tcg_gen_movi_i32(cpu_R
[15], val
);
868 /* Force a TB lookup after an instruction that changes the CPU state. */
869 static inline void gen_lookup_tb(DisasContext
*s
)
871 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
872 s
->is_jmp
= DISAS_UPDATE
;
875 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
878 int val
, rm
, shift
, shiftop
;
881 if (!(insn
& (1 << 25))) {
884 if (!(insn
& (1 << 23)))
887 tcg_gen_addi_i32(var
, var
, val
);
891 shift
= (insn
>> 7) & 0x1f;
892 shiftop
= (insn
>> 5) & 3;
893 offset
= load_reg(s
, rm
);
894 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
895 if (!(insn
& (1 << 23)))
896 tcg_gen_sub_i32(var
, var
, offset
);
898 tcg_gen_add_i32(var
, var
, offset
);
899 tcg_temp_free_i32(offset
);
903 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
909 if (insn
& (1 << 22)) {
911 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
912 if (!(insn
& (1 << 23)))
916 tcg_gen_addi_i32(var
, var
, val
);
920 tcg_gen_addi_i32(var
, var
, extra
);
922 offset
= load_reg(s
, rm
);
923 if (!(insn
& (1 << 23)))
924 tcg_gen_sub_i32(var
, var
, offset
);
926 tcg_gen_add_i32(var
, var
, offset
);
927 tcg_temp_free_i32(offset
);
931 static TCGv_ptr
get_fpstatus_ptr(int neon
)
933 TCGv_ptr statusptr
= tcg_temp_new_ptr();
936 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
938 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
940 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
944 #define VFP_OP2(name) \
945 static inline void gen_vfp_##name(int dp) \
947 TCGv_ptr fpst = get_fpstatus_ptr(0); \
949 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
951 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
953 tcg_temp_free_ptr(fpst); \
963 static inline void gen_vfp_F1_mul(int dp
)
965 /* Like gen_vfp_mul() but put result in F1 */
966 TCGv_ptr fpst
= get_fpstatus_ptr(0);
968 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
970 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
972 tcg_temp_free_ptr(fpst
);
975 static inline void gen_vfp_F1_neg(int dp
)
977 /* Like gen_vfp_neg() but put result in F1 */
979 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
981 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
985 static inline void gen_vfp_abs(int dp
)
988 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
990 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
993 static inline void gen_vfp_neg(int dp
)
996 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
998 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1001 static inline void gen_vfp_sqrt(int dp
)
1004 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1006 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1009 static inline void gen_vfp_cmp(int dp
)
1012 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1014 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1017 static inline void gen_vfp_cmpe(int dp
)
1020 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1022 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1025 static inline void gen_vfp_F1_ld0(int dp
)
1028 tcg_gen_movi_i64(cpu_F1d
, 0);
1030 tcg_gen_movi_i32(cpu_F1s
, 0);
1033 #define VFP_GEN_ITOF(name) \
1034 static inline void gen_vfp_##name(int dp, int neon) \
1036 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1038 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1040 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1042 tcg_temp_free_ptr(statusptr); \
1049 #define VFP_GEN_FTOI(name) \
1050 static inline void gen_vfp_##name(int dp, int neon) \
1052 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1054 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1056 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1058 tcg_temp_free_ptr(statusptr); \
1067 #define VFP_GEN_FIX(name) \
1068 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1070 TCGv tmp_shift = tcg_const_i32(shift); \
1071 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1073 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1075 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1077 tcg_temp_free_i32(tmp_shift); \
1078 tcg_temp_free_ptr(statusptr); \
1090 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv addr
)
1093 tcg_gen_qemu_ld64(cpu_F0d
, addr
, IS_USER(s
));
1095 tcg_gen_qemu_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1098 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv addr
)
1101 tcg_gen_qemu_st64(cpu_F0d
, addr
, IS_USER(s
));
1103 tcg_gen_qemu_st32(cpu_F0s
, addr
, IS_USER(s
));
1107 vfp_reg_offset (int dp
, int reg
)
1110 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1112 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1113 + offsetof(CPU_DoubleU
, l
.upper
);
1115 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1116 + offsetof(CPU_DoubleU
, l
.lower
);
1120 /* Return the offset of a 32-bit piece of a NEON register.
1121 zero is the least significant end of the register. */
1123 neon_reg_offset (int reg
, int n
)
1127 return vfp_reg_offset(0, sreg
);
1130 static TCGv
neon_load_reg(int reg
, int pass
)
1132 TCGv tmp
= tcg_temp_new_i32();
1133 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1137 static void neon_store_reg(int reg
, int pass
, TCGv var
)
1139 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1140 tcg_temp_free_i32(var
);
1143 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1145 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1148 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1150 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1153 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1154 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1155 #define tcg_gen_st_f32 tcg_gen_st_i32
1156 #define tcg_gen_st_f64 tcg_gen_st_i64
1158 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1161 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1163 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1166 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1169 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1171 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1174 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1177 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1179 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1182 #define ARM_CP_RW_BIT (1 << 20)
1184 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1186 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1189 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1191 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1194 static inline TCGv
iwmmxt_load_creg(int reg
)
1196 TCGv var
= tcg_temp_new_i32();
1197 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1201 static inline void iwmmxt_store_creg(int reg
, TCGv var
)
1203 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1204 tcg_temp_free_i32(var
);
1207 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1209 iwmmxt_store_reg(cpu_M0
, rn
);
1212 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1214 iwmmxt_load_reg(cpu_M0
, rn
);
1217 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1219 iwmmxt_load_reg(cpu_V1
, rn
);
1220 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1223 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1225 iwmmxt_load_reg(cpu_V1
, rn
);
1226 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1229 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1231 iwmmxt_load_reg(cpu_V1
, rn
);
1232 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1235 #define IWMMXT_OP(name) \
1236 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1238 iwmmxt_load_reg(cpu_V1, rn); \
1239 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1242 #define IWMMXT_OP_ENV(name) \
1243 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1245 iwmmxt_load_reg(cpu_V1, rn); \
1246 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1249 #define IWMMXT_OP_ENV_SIZE(name) \
1250 IWMMXT_OP_ENV(name##b) \
1251 IWMMXT_OP_ENV(name##w) \
1252 IWMMXT_OP_ENV(name##l)
1254 #define IWMMXT_OP_ENV1(name) \
1255 static inline void gen_op_iwmmxt_##name##_M0(void) \
1257 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1271 IWMMXT_OP_ENV_SIZE(unpackl
)
1272 IWMMXT_OP_ENV_SIZE(unpackh
)
1274 IWMMXT_OP_ENV1(unpacklub
)
1275 IWMMXT_OP_ENV1(unpackluw
)
1276 IWMMXT_OP_ENV1(unpacklul
)
1277 IWMMXT_OP_ENV1(unpackhub
)
1278 IWMMXT_OP_ENV1(unpackhuw
)
1279 IWMMXT_OP_ENV1(unpackhul
)
1280 IWMMXT_OP_ENV1(unpacklsb
)
1281 IWMMXT_OP_ENV1(unpacklsw
)
1282 IWMMXT_OP_ENV1(unpacklsl
)
1283 IWMMXT_OP_ENV1(unpackhsb
)
1284 IWMMXT_OP_ENV1(unpackhsw
)
1285 IWMMXT_OP_ENV1(unpackhsl
)
1287 IWMMXT_OP_ENV_SIZE(cmpeq
)
1288 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1289 IWMMXT_OP_ENV_SIZE(cmpgts
)
1291 IWMMXT_OP_ENV_SIZE(mins
)
1292 IWMMXT_OP_ENV_SIZE(minu
)
1293 IWMMXT_OP_ENV_SIZE(maxs
)
1294 IWMMXT_OP_ENV_SIZE(maxu
)
1296 IWMMXT_OP_ENV_SIZE(subn
)
1297 IWMMXT_OP_ENV_SIZE(addn
)
1298 IWMMXT_OP_ENV_SIZE(subu
)
1299 IWMMXT_OP_ENV_SIZE(addu
)
1300 IWMMXT_OP_ENV_SIZE(subs
)
1301 IWMMXT_OP_ENV_SIZE(adds
)
1303 IWMMXT_OP_ENV(avgb0
)
1304 IWMMXT_OP_ENV(avgb1
)
1305 IWMMXT_OP_ENV(avgw0
)
1306 IWMMXT_OP_ENV(avgw1
)
1310 IWMMXT_OP_ENV(packuw
)
1311 IWMMXT_OP_ENV(packul
)
1312 IWMMXT_OP_ENV(packuq
)
1313 IWMMXT_OP_ENV(packsw
)
1314 IWMMXT_OP_ENV(packsl
)
1315 IWMMXT_OP_ENV(packsq
)
1317 static void gen_op_iwmmxt_set_mup(void)
1320 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1321 tcg_gen_ori_i32(tmp
, tmp
, 2);
1322 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1325 static void gen_op_iwmmxt_set_cup(void)
1328 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1329 tcg_gen_ori_i32(tmp
, tmp
, 1);
1330 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1333 static void gen_op_iwmmxt_setpsr_nz(void)
1335 TCGv tmp
= tcg_temp_new_i32();
1336 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1337 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1340 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1342 iwmmxt_load_reg(cpu_V1
, rn
);
1343 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1344 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1347 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1353 rd
= (insn
>> 16) & 0xf;
1354 tmp
= load_reg(s
, rd
);
1356 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1357 if (insn
& (1 << 24)) {
1359 if (insn
& (1 << 23))
1360 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1362 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1363 tcg_gen_mov_i32(dest
, tmp
);
1364 if (insn
& (1 << 21))
1365 store_reg(s
, rd
, tmp
);
1367 tcg_temp_free_i32(tmp
);
1368 } else if (insn
& (1 << 21)) {
1370 tcg_gen_mov_i32(dest
, tmp
);
1371 if (insn
& (1 << 23))
1372 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1374 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1375 store_reg(s
, rd
, tmp
);
1376 } else if (!(insn
& (1 << 23)))
1381 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1383 int rd
= (insn
>> 0) & 0xf;
1386 if (insn
& (1 << 8)) {
1387 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1390 tmp
= iwmmxt_load_creg(rd
);
1393 tmp
= tcg_temp_new_i32();
1394 iwmmxt_load_reg(cpu_V0
, rd
);
1395 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1397 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1398 tcg_gen_mov_i32(dest
, tmp
);
1399 tcg_temp_free_i32(tmp
);
1403 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1404 (ie. an undefined instruction). */
1405 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1408 int rdhi
, rdlo
, rd0
, rd1
, i
;
1410 TCGv tmp
, tmp2
, tmp3
;
1412 if ((insn
& 0x0e000e00) == 0x0c000000) {
1413 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1415 rdlo
= (insn
>> 12) & 0xf;
1416 rdhi
= (insn
>> 16) & 0xf;
1417 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1418 iwmmxt_load_reg(cpu_V0
, wrd
);
1419 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1420 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1421 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1422 } else { /* TMCRR */
1423 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1424 iwmmxt_store_reg(cpu_V0
, wrd
);
1425 gen_op_iwmmxt_set_mup();
1430 wrd
= (insn
>> 12) & 0xf;
1431 addr
= tcg_temp_new_i32();
1432 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1433 tcg_temp_free_i32(addr
);
1436 if (insn
& ARM_CP_RW_BIT
) {
1437 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1438 tmp
= tcg_temp_new_i32();
1439 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1440 iwmmxt_store_creg(wrd
, tmp
);
1443 if (insn
& (1 << 8)) {
1444 if (insn
& (1 << 22)) { /* WLDRD */
1445 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1447 } else { /* WLDRW wRd */
1448 tmp
= gen_ld32(addr
, IS_USER(s
));
1451 if (insn
& (1 << 22)) { /* WLDRH */
1452 tmp
= gen_ld16u(addr
, IS_USER(s
));
1453 } else { /* WLDRB */
1454 tmp
= gen_ld8u(addr
, IS_USER(s
));
1458 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1459 tcg_temp_free_i32(tmp
);
1461 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1464 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1465 tmp
= iwmmxt_load_creg(wrd
);
1466 gen_st32(tmp
, addr
, IS_USER(s
));
1468 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1469 tmp
= tcg_temp_new_i32();
1470 if (insn
& (1 << 8)) {
1471 if (insn
& (1 << 22)) { /* WSTRD */
1472 tcg_temp_free_i32(tmp
);
1473 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1474 } else { /* WSTRW wRd */
1475 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1476 gen_st32(tmp
, addr
, IS_USER(s
));
1479 if (insn
& (1 << 22)) { /* WSTRH */
1480 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1481 gen_st16(tmp
, addr
, IS_USER(s
));
1482 } else { /* WSTRB */
1483 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1484 gen_st8(tmp
, addr
, IS_USER(s
));
1489 tcg_temp_free_i32(addr
);
1493 if ((insn
& 0x0f000000) != 0x0e000000)
1496 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1497 case 0x000: /* WOR */
1498 wrd
= (insn
>> 12) & 0xf;
1499 rd0
= (insn
>> 0) & 0xf;
1500 rd1
= (insn
>> 16) & 0xf;
1501 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1502 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1503 gen_op_iwmmxt_setpsr_nz();
1504 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1505 gen_op_iwmmxt_set_mup();
1506 gen_op_iwmmxt_set_cup();
1508 case 0x011: /* TMCR */
1511 rd
= (insn
>> 12) & 0xf;
1512 wrd
= (insn
>> 16) & 0xf;
1514 case ARM_IWMMXT_wCID
:
1515 case ARM_IWMMXT_wCASF
:
1517 case ARM_IWMMXT_wCon
:
1518 gen_op_iwmmxt_set_cup();
1520 case ARM_IWMMXT_wCSSF
:
1521 tmp
= iwmmxt_load_creg(wrd
);
1522 tmp2
= load_reg(s
, rd
);
1523 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1524 tcg_temp_free_i32(tmp2
);
1525 iwmmxt_store_creg(wrd
, tmp
);
1527 case ARM_IWMMXT_wCGR0
:
1528 case ARM_IWMMXT_wCGR1
:
1529 case ARM_IWMMXT_wCGR2
:
1530 case ARM_IWMMXT_wCGR3
:
1531 gen_op_iwmmxt_set_cup();
1532 tmp
= load_reg(s
, rd
);
1533 iwmmxt_store_creg(wrd
, tmp
);
1539 case 0x100: /* WXOR */
1540 wrd
= (insn
>> 12) & 0xf;
1541 rd0
= (insn
>> 0) & 0xf;
1542 rd1
= (insn
>> 16) & 0xf;
1543 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1544 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1545 gen_op_iwmmxt_setpsr_nz();
1546 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1547 gen_op_iwmmxt_set_mup();
1548 gen_op_iwmmxt_set_cup();
1550 case 0x111: /* TMRC */
1553 rd
= (insn
>> 12) & 0xf;
1554 wrd
= (insn
>> 16) & 0xf;
1555 tmp
= iwmmxt_load_creg(wrd
);
1556 store_reg(s
, rd
, tmp
);
1558 case 0x300: /* WANDN */
1559 wrd
= (insn
>> 12) & 0xf;
1560 rd0
= (insn
>> 0) & 0xf;
1561 rd1
= (insn
>> 16) & 0xf;
1562 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1563 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1564 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1565 gen_op_iwmmxt_setpsr_nz();
1566 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1567 gen_op_iwmmxt_set_mup();
1568 gen_op_iwmmxt_set_cup();
1570 case 0x200: /* WAND */
1571 wrd
= (insn
>> 12) & 0xf;
1572 rd0
= (insn
>> 0) & 0xf;
1573 rd1
= (insn
>> 16) & 0xf;
1574 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1575 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1576 gen_op_iwmmxt_setpsr_nz();
1577 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1578 gen_op_iwmmxt_set_mup();
1579 gen_op_iwmmxt_set_cup();
1581 case 0x810: case 0xa10: /* WMADD */
1582 wrd
= (insn
>> 12) & 0xf;
1583 rd0
= (insn
>> 0) & 0xf;
1584 rd1
= (insn
>> 16) & 0xf;
1585 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1586 if (insn
& (1 << 21))
1587 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1589 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1590 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1591 gen_op_iwmmxt_set_mup();
1593 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1594 wrd
= (insn
>> 12) & 0xf;
1595 rd0
= (insn
>> 16) & 0xf;
1596 rd1
= (insn
>> 0) & 0xf;
1597 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1598 switch ((insn
>> 22) & 3) {
1600 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1603 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1606 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1611 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1612 gen_op_iwmmxt_set_mup();
1613 gen_op_iwmmxt_set_cup();
1615 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1616 wrd
= (insn
>> 12) & 0xf;
1617 rd0
= (insn
>> 16) & 0xf;
1618 rd1
= (insn
>> 0) & 0xf;
1619 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1620 switch ((insn
>> 22) & 3) {
1622 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1625 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1628 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1633 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1634 gen_op_iwmmxt_set_mup();
1635 gen_op_iwmmxt_set_cup();
1637 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1638 wrd
= (insn
>> 12) & 0xf;
1639 rd0
= (insn
>> 16) & 0xf;
1640 rd1
= (insn
>> 0) & 0xf;
1641 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1642 if (insn
& (1 << 22))
1643 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1645 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1646 if (!(insn
& (1 << 20)))
1647 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1648 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1649 gen_op_iwmmxt_set_mup();
1651 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1652 wrd
= (insn
>> 12) & 0xf;
1653 rd0
= (insn
>> 16) & 0xf;
1654 rd1
= (insn
>> 0) & 0xf;
1655 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1656 if (insn
& (1 << 21)) {
1657 if (insn
& (1 << 20))
1658 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1660 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1662 if (insn
& (1 << 20))
1663 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1665 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1667 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1668 gen_op_iwmmxt_set_mup();
1670 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1671 wrd
= (insn
>> 12) & 0xf;
1672 rd0
= (insn
>> 16) & 0xf;
1673 rd1
= (insn
>> 0) & 0xf;
1674 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1675 if (insn
& (1 << 21))
1676 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1678 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1679 if (!(insn
& (1 << 20))) {
1680 iwmmxt_load_reg(cpu_V1
, wrd
);
1681 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1683 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1684 gen_op_iwmmxt_set_mup();
1686 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1687 wrd
= (insn
>> 12) & 0xf;
1688 rd0
= (insn
>> 16) & 0xf;
1689 rd1
= (insn
>> 0) & 0xf;
1690 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1691 switch ((insn
>> 22) & 3) {
1693 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1696 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1699 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1704 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1705 gen_op_iwmmxt_set_mup();
1706 gen_op_iwmmxt_set_cup();
1708 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1709 wrd
= (insn
>> 12) & 0xf;
1710 rd0
= (insn
>> 16) & 0xf;
1711 rd1
= (insn
>> 0) & 0xf;
1712 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1713 if (insn
& (1 << 22)) {
1714 if (insn
& (1 << 20))
1715 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1717 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1719 if (insn
& (1 << 20))
1720 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1722 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1724 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1725 gen_op_iwmmxt_set_mup();
1726 gen_op_iwmmxt_set_cup();
1728 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1729 wrd
= (insn
>> 12) & 0xf;
1730 rd0
= (insn
>> 16) & 0xf;
1731 rd1
= (insn
>> 0) & 0xf;
1732 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1733 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1734 tcg_gen_andi_i32(tmp
, tmp
, 7);
1735 iwmmxt_load_reg(cpu_V1
, rd1
);
1736 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1737 tcg_temp_free_i32(tmp
);
1738 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1739 gen_op_iwmmxt_set_mup();
1741 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1742 if (((insn
>> 6) & 3) == 3)
1744 rd
= (insn
>> 12) & 0xf;
1745 wrd
= (insn
>> 16) & 0xf;
1746 tmp
= load_reg(s
, rd
);
1747 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1748 switch ((insn
>> 6) & 3) {
1750 tmp2
= tcg_const_i32(0xff);
1751 tmp3
= tcg_const_i32((insn
& 7) << 3);
1754 tmp2
= tcg_const_i32(0xffff);
1755 tmp3
= tcg_const_i32((insn
& 3) << 4);
1758 tmp2
= tcg_const_i32(0xffffffff);
1759 tmp3
= tcg_const_i32((insn
& 1) << 5);
1765 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1766 tcg_temp_free(tmp3
);
1767 tcg_temp_free(tmp2
);
1768 tcg_temp_free_i32(tmp
);
1769 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1770 gen_op_iwmmxt_set_mup();
1772 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1773 rd
= (insn
>> 12) & 0xf;
1774 wrd
= (insn
>> 16) & 0xf;
1775 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1777 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1778 tmp
= tcg_temp_new_i32();
1779 switch ((insn
>> 22) & 3) {
1781 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1782 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1784 tcg_gen_ext8s_i32(tmp
, tmp
);
1786 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1790 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1791 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1793 tcg_gen_ext16s_i32(tmp
, tmp
);
1795 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1799 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1800 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1803 store_reg(s
, rd
, tmp
);
1805 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1806 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1808 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1809 switch ((insn
>> 22) & 3) {
1811 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1814 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1817 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1820 tcg_gen_shli_i32(tmp
, tmp
, 28);
1822 tcg_temp_free_i32(tmp
);
1824 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1825 if (((insn
>> 6) & 3) == 3)
1827 rd
= (insn
>> 12) & 0xf;
1828 wrd
= (insn
>> 16) & 0xf;
1829 tmp
= load_reg(s
, rd
);
1830 switch ((insn
>> 6) & 3) {
1832 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1835 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1838 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1841 tcg_temp_free_i32(tmp
);
1842 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1843 gen_op_iwmmxt_set_mup();
1845 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1846 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1848 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1849 tmp2
= tcg_temp_new_i32();
1850 tcg_gen_mov_i32(tmp2
, tmp
);
1851 switch ((insn
>> 22) & 3) {
1853 for (i
= 0; i
< 7; i
++) {
1854 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1855 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1859 for (i
= 0; i
< 3; i
++) {
1860 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1861 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1865 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1866 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1870 tcg_temp_free_i32(tmp2
);
1871 tcg_temp_free_i32(tmp
);
1873 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1874 wrd
= (insn
>> 12) & 0xf;
1875 rd0
= (insn
>> 16) & 0xf;
1876 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1877 switch ((insn
>> 22) & 3) {
1879 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1882 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1885 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1890 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1891 gen_op_iwmmxt_set_mup();
1893 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1894 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1896 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1897 tmp2
= tcg_temp_new_i32();
1898 tcg_gen_mov_i32(tmp2
, tmp
);
1899 switch ((insn
>> 22) & 3) {
1901 for (i
= 0; i
< 7; i
++) {
1902 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1903 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1907 for (i
= 0; i
< 3; i
++) {
1908 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1909 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1913 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1914 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1918 tcg_temp_free_i32(tmp2
);
1919 tcg_temp_free_i32(tmp
);
1921 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1922 rd
= (insn
>> 12) & 0xf;
1923 rd0
= (insn
>> 16) & 0xf;
1924 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1926 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1927 tmp
= tcg_temp_new_i32();
1928 switch ((insn
>> 22) & 3) {
1930 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1933 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1936 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1939 store_reg(s
, rd
, tmp
);
1941 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1942 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1943 wrd
= (insn
>> 12) & 0xf;
1944 rd0
= (insn
>> 16) & 0xf;
1945 rd1
= (insn
>> 0) & 0xf;
1946 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1947 switch ((insn
>> 22) & 3) {
1949 if (insn
& (1 << 21))
1950 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1952 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1955 if (insn
& (1 << 21))
1956 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1958 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1961 if (insn
& (1 << 21))
1962 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1964 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1969 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1970 gen_op_iwmmxt_set_mup();
1971 gen_op_iwmmxt_set_cup();
1973 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1974 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1975 wrd
= (insn
>> 12) & 0xf;
1976 rd0
= (insn
>> 16) & 0xf;
1977 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1978 switch ((insn
>> 22) & 3) {
1980 if (insn
& (1 << 21))
1981 gen_op_iwmmxt_unpacklsb_M0();
1983 gen_op_iwmmxt_unpacklub_M0();
1986 if (insn
& (1 << 21))
1987 gen_op_iwmmxt_unpacklsw_M0();
1989 gen_op_iwmmxt_unpackluw_M0();
1992 if (insn
& (1 << 21))
1993 gen_op_iwmmxt_unpacklsl_M0();
1995 gen_op_iwmmxt_unpacklul_M0();
2000 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2001 gen_op_iwmmxt_set_mup();
2002 gen_op_iwmmxt_set_cup();
2004 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2005 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2006 wrd
= (insn
>> 12) & 0xf;
2007 rd0
= (insn
>> 16) & 0xf;
2008 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2009 switch ((insn
>> 22) & 3) {
2011 if (insn
& (1 << 21))
2012 gen_op_iwmmxt_unpackhsb_M0();
2014 gen_op_iwmmxt_unpackhub_M0();
2017 if (insn
& (1 << 21))
2018 gen_op_iwmmxt_unpackhsw_M0();
2020 gen_op_iwmmxt_unpackhuw_M0();
2023 if (insn
& (1 << 21))
2024 gen_op_iwmmxt_unpackhsl_M0();
2026 gen_op_iwmmxt_unpackhul_M0();
2031 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2032 gen_op_iwmmxt_set_mup();
2033 gen_op_iwmmxt_set_cup();
2035 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2036 case 0x214: case 0x614: case 0xa14: case 0xe14:
2037 if (((insn
>> 22) & 3) == 0)
2039 wrd
= (insn
>> 12) & 0xf;
2040 rd0
= (insn
>> 16) & 0xf;
2041 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2042 tmp
= tcg_temp_new_i32();
2043 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2044 tcg_temp_free_i32(tmp
);
2047 switch ((insn
>> 22) & 3) {
2049 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2052 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2055 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2058 tcg_temp_free_i32(tmp
);
2059 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2060 gen_op_iwmmxt_set_mup();
2061 gen_op_iwmmxt_set_cup();
2063 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2064 case 0x014: case 0x414: case 0x814: case 0xc14:
2065 if (((insn
>> 22) & 3) == 0)
2067 wrd
= (insn
>> 12) & 0xf;
2068 rd0
= (insn
>> 16) & 0xf;
2069 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2070 tmp
= tcg_temp_new_i32();
2071 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2072 tcg_temp_free_i32(tmp
);
2075 switch ((insn
>> 22) & 3) {
2077 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2080 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2083 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2086 tcg_temp_free_i32(tmp
);
2087 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2088 gen_op_iwmmxt_set_mup();
2089 gen_op_iwmmxt_set_cup();
2091 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2092 case 0x114: case 0x514: case 0x914: case 0xd14:
2093 if (((insn
>> 22) & 3) == 0)
2095 wrd
= (insn
>> 12) & 0xf;
2096 rd0
= (insn
>> 16) & 0xf;
2097 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2098 tmp
= tcg_temp_new_i32();
2099 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2100 tcg_temp_free_i32(tmp
);
2103 switch ((insn
>> 22) & 3) {
2105 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2108 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2111 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2114 tcg_temp_free_i32(tmp
);
2115 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2116 gen_op_iwmmxt_set_mup();
2117 gen_op_iwmmxt_set_cup();
2119 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2120 case 0x314: case 0x714: case 0xb14: case 0xf14:
2121 if (((insn
>> 22) & 3) == 0)
2123 wrd
= (insn
>> 12) & 0xf;
2124 rd0
= (insn
>> 16) & 0xf;
2125 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2126 tmp
= tcg_temp_new_i32();
2127 switch ((insn
>> 22) & 3) {
2129 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2130 tcg_temp_free_i32(tmp
);
2133 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2136 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2137 tcg_temp_free_i32(tmp
);
2140 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2143 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2144 tcg_temp_free_i32(tmp
);
2147 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2150 tcg_temp_free_i32(tmp
);
2151 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2152 gen_op_iwmmxt_set_mup();
2153 gen_op_iwmmxt_set_cup();
2155 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2156 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2157 wrd
= (insn
>> 12) & 0xf;
2158 rd0
= (insn
>> 16) & 0xf;
2159 rd1
= (insn
>> 0) & 0xf;
2160 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2161 switch ((insn
>> 22) & 3) {
2163 if (insn
& (1 << 21))
2164 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2166 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2169 if (insn
& (1 << 21))
2170 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2172 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2175 if (insn
& (1 << 21))
2176 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2178 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2183 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2184 gen_op_iwmmxt_set_mup();
2186 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2187 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2188 wrd
= (insn
>> 12) & 0xf;
2189 rd0
= (insn
>> 16) & 0xf;
2190 rd1
= (insn
>> 0) & 0xf;
2191 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2192 switch ((insn
>> 22) & 3) {
2194 if (insn
& (1 << 21))
2195 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2197 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2200 if (insn
& (1 << 21))
2201 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2203 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2206 if (insn
& (1 << 21))
2207 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2209 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2214 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2215 gen_op_iwmmxt_set_mup();
2217 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2218 case 0x402: case 0x502: case 0x602: case 0x702:
2219 wrd
= (insn
>> 12) & 0xf;
2220 rd0
= (insn
>> 16) & 0xf;
2221 rd1
= (insn
>> 0) & 0xf;
2222 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2223 tmp
= tcg_const_i32((insn
>> 20) & 3);
2224 iwmmxt_load_reg(cpu_V1
, rd1
);
2225 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2227 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2228 gen_op_iwmmxt_set_mup();
2230 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2231 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2232 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2233 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2234 wrd
= (insn
>> 12) & 0xf;
2235 rd0
= (insn
>> 16) & 0xf;
2236 rd1
= (insn
>> 0) & 0xf;
2237 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2238 switch ((insn
>> 20) & 0xf) {
2240 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2243 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2246 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2249 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2252 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2255 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2258 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2261 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2264 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2269 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2270 gen_op_iwmmxt_set_mup();
2271 gen_op_iwmmxt_set_cup();
2273 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2274 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2275 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2276 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2277 wrd
= (insn
>> 12) & 0xf;
2278 rd0
= (insn
>> 16) & 0xf;
2279 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2280 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2281 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2283 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2284 gen_op_iwmmxt_set_mup();
2285 gen_op_iwmmxt_set_cup();
2287 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2288 case 0x418: case 0x518: case 0x618: case 0x718:
2289 case 0x818: case 0x918: case 0xa18: case 0xb18:
2290 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2291 wrd
= (insn
>> 12) & 0xf;
2292 rd0
= (insn
>> 16) & 0xf;
2293 rd1
= (insn
>> 0) & 0xf;
2294 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2295 switch ((insn
>> 20) & 0xf) {
2297 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2300 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2303 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2306 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2309 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2312 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2315 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2318 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2321 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2326 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2327 gen_op_iwmmxt_set_mup();
2328 gen_op_iwmmxt_set_cup();
2330 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2331 case 0x408: case 0x508: case 0x608: case 0x708:
2332 case 0x808: case 0x908: case 0xa08: case 0xb08:
2333 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2334 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2336 wrd
= (insn
>> 12) & 0xf;
2337 rd0
= (insn
>> 16) & 0xf;
2338 rd1
= (insn
>> 0) & 0xf;
2339 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2340 switch ((insn
>> 22) & 3) {
2342 if (insn
& (1 << 21))
2343 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2345 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2348 if (insn
& (1 << 21))
2349 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2351 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2354 if (insn
& (1 << 21))
2355 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2357 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2360 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2361 gen_op_iwmmxt_set_mup();
2362 gen_op_iwmmxt_set_cup();
2364 case 0x201: case 0x203: case 0x205: case 0x207:
2365 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2366 case 0x211: case 0x213: case 0x215: case 0x217:
2367 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2368 wrd
= (insn
>> 5) & 0xf;
2369 rd0
= (insn
>> 12) & 0xf;
2370 rd1
= (insn
>> 0) & 0xf;
2371 if (rd0
== 0xf || rd1
== 0xf)
2373 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2374 tmp
= load_reg(s
, rd0
);
2375 tmp2
= load_reg(s
, rd1
);
2376 switch ((insn
>> 16) & 0xf) {
2377 case 0x0: /* TMIA */
2378 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2380 case 0x8: /* TMIAPH */
2381 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2383 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2384 if (insn
& (1 << 16))
2385 tcg_gen_shri_i32(tmp
, tmp
, 16);
2386 if (insn
& (1 << 17))
2387 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2388 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2391 tcg_temp_free_i32(tmp2
);
2392 tcg_temp_free_i32(tmp
);
2395 tcg_temp_free_i32(tmp2
);
2396 tcg_temp_free_i32(tmp
);
2397 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2398 gen_op_iwmmxt_set_mup();
2407 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2408 (ie. an undefined instruction). */
2409 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2411 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2414 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2415 /* Multiply with Internal Accumulate Format */
2416 rd0
= (insn
>> 12) & 0xf;
2418 acc
= (insn
>> 5) & 7;
2423 tmp
= load_reg(s
, rd0
);
2424 tmp2
= load_reg(s
, rd1
);
2425 switch ((insn
>> 16) & 0xf) {
2427 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2429 case 0x8: /* MIAPH */
2430 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2432 case 0xc: /* MIABB */
2433 case 0xd: /* MIABT */
2434 case 0xe: /* MIATB */
2435 case 0xf: /* MIATT */
2436 if (insn
& (1 << 16))
2437 tcg_gen_shri_i32(tmp
, tmp
, 16);
2438 if (insn
& (1 << 17))
2439 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2440 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2445 tcg_temp_free_i32(tmp2
);
2446 tcg_temp_free_i32(tmp
);
2448 gen_op_iwmmxt_movq_wRn_M0(acc
);
2452 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2453 /* Internal Accumulator Access Format */
2454 rdhi
= (insn
>> 16) & 0xf;
2455 rdlo
= (insn
>> 12) & 0xf;
2461 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2462 iwmmxt_load_reg(cpu_V0
, acc
);
2463 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2464 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2465 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2466 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2468 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2469 iwmmxt_store_reg(cpu_V0
, acc
);
2477 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2478 #define VFP_SREG(insn, bigbit, smallbit) \
2479 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2480 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2481 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2482 reg = (((insn) >> (bigbit)) & 0x0f) \
2483 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2485 if (insn & (1 << (smallbit))) \
2487 reg = ((insn) >> (bigbit)) & 0x0f; \
2490 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2491 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2492 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2493 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2494 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2495 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2497 /* Move between integer and VFP cores. */
2498 static TCGv
gen_vfp_mrs(void)
2500 TCGv tmp
= tcg_temp_new_i32();
2501 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2505 static void gen_vfp_msr(TCGv tmp
)
2507 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2508 tcg_temp_free_i32(tmp
);
2511 static void gen_neon_dup_u8(TCGv var
, int shift
)
2513 TCGv tmp
= tcg_temp_new_i32();
2515 tcg_gen_shri_i32(var
, var
, shift
);
2516 tcg_gen_ext8u_i32(var
, var
);
2517 tcg_gen_shli_i32(tmp
, var
, 8);
2518 tcg_gen_or_i32(var
, var
, tmp
);
2519 tcg_gen_shli_i32(tmp
, var
, 16);
2520 tcg_gen_or_i32(var
, var
, tmp
);
2521 tcg_temp_free_i32(tmp
);
2524 static void gen_neon_dup_low16(TCGv var
)
2526 TCGv tmp
= tcg_temp_new_i32();
2527 tcg_gen_ext16u_i32(var
, var
);
2528 tcg_gen_shli_i32(tmp
, var
, 16);
2529 tcg_gen_or_i32(var
, var
, tmp
);
2530 tcg_temp_free_i32(tmp
);
2533 static void gen_neon_dup_high16(TCGv var
)
2535 TCGv tmp
= tcg_temp_new_i32();
2536 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2537 tcg_gen_shri_i32(tmp
, var
, 16);
2538 tcg_gen_or_i32(var
, var
, tmp
);
2539 tcg_temp_free_i32(tmp
);
2542 static TCGv
gen_load_and_replicate(DisasContext
*s
, TCGv addr
, int size
)
2544 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2548 tmp
= gen_ld8u(addr
, IS_USER(s
));
2549 gen_neon_dup_u8(tmp
, 0);
2552 tmp
= gen_ld16u(addr
, IS_USER(s
));
2553 gen_neon_dup_low16(tmp
);
2556 tmp
= gen_ld32(addr
, IS_USER(s
));
2558 default: /* Avoid compiler warnings. */
2564 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2565 (ie. an undefined instruction). */
2566 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2568 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2574 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2577 if (!s
->vfp_enabled
) {
2578 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2579 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2581 rn
= (insn
>> 16) & 0xf;
2582 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2583 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2586 dp
= ((insn
& 0xf00) == 0xb00);
2587 switch ((insn
>> 24) & 0xf) {
2589 if (insn
& (1 << 4)) {
2590 /* single register transfer */
2591 rd
= (insn
>> 12) & 0xf;
2596 VFP_DREG_N(rn
, insn
);
2599 if (insn
& 0x00c00060
2600 && !arm_feature(env
, ARM_FEATURE_NEON
))
2603 pass
= (insn
>> 21) & 1;
2604 if (insn
& (1 << 22)) {
2606 offset
= ((insn
>> 5) & 3) * 8;
2607 } else if (insn
& (1 << 5)) {
2609 offset
= (insn
& (1 << 6)) ? 16 : 0;
2614 if (insn
& ARM_CP_RW_BIT
) {
2616 tmp
= neon_load_reg(rn
, pass
);
2620 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2621 if (insn
& (1 << 23))
2627 if (insn
& (1 << 23)) {
2629 tcg_gen_shri_i32(tmp
, tmp
, 16);
2635 tcg_gen_sari_i32(tmp
, tmp
, 16);
2644 store_reg(s
, rd
, tmp
);
2647 tmp
= load_reg(s
, rd
);
2648 if (insn
& (1 << 23)) {
2651 gen_neon_dup_u8(tmp
, 0);
2652 } else if (size
== 1) {
2653 gen_neon_dup_low16(tmp
);
2655 for (n
= 0; n
<= pass
* 2; n
++) {
2656 tmp2
= tcg_temp_new_i32();
2657 tcg_gen_mov_i32(tmp2
, tmp
);
2658 neon_store_reg(rn
, n
, tmp2
);
2660 neon_store_reg(rn
, n
, tmp
);
2665 tmp2
= neon_load_reg(rn
, pass
);
2666 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
2667 tcg_temp_free_i32(tmp2
);
2670 tmp2
= neon_load_reg(rn
, pass
);
2671 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
2672 tcg_temp_free_i32(tmp2
);
2677 neon_store_reg(rn
, pass
, tmp
);
2681 if ((insn
& 0x6f) != 0x00)
2683 rn
= VFP_SREG_N(insn
);
2684 if (insn
& ARM_CP_RW_BIT
) {
2686 if (insn
& (1 << 21)) {
2687 /* system register */
2692 /* VFP2 allows access to FSID from userspace.
2693 VFP3 restricts all id registers to privileged
2696 && arm_feature(env
, ARM_FEATURE_VFP3
))
2698 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2703 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2705 case ARM_VFP_FPINST
:
2706 case ARM_VFP_FPINST2
:
2707 /* Not present in VFP3. */
2709 || arm_feature(env
, ARM_FEATURE_VFP3
))
2711 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2715 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2716 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2718 tmp
= tcg_temp_new_i32();
2719 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2725 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2727 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2733 gen_mov_F0_vreg(0, rn
);
2734 tmp
= gen_vfp_mrs();
2737 /* Set the 4 flag bits in the CPSR. */
2739 tcg_temp_free_i32(tmp
);
2741 store_reg(s
, rd
, tmp
);
2745 if (insn
& (1 << 21)) {
2747 /* system register */
2752 /* Writes are ignored. */
2755 tmp
= load_reg(s
, rd
);
2756 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2757 tcg_temp_free_i32(tmp
);
2763 /* TODO: VFP subarchitecture support.
2764 * For now, keep the EN bit only */
2765 tmp
= load_reg(s
, rd
);
2766 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2767 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2770 case ARM_VFP_FPINST
:
2771 case ARM_VFP_FPINST2
:
2772 tmp
= load_reg(s
, rd
);
2773 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2779 tmp
= load_reg(s
, rd
);
2781 gen_mov_vreg_F0(0, rn
);
2786 /* data processing */
2787 /* The opcode is in bits 23, 21, 20 and 6. */
2788 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2792 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2794 /* rn is register number */
2795 VFP_DREG_N(rn
, insn
);
2798 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2799 /* Integer or single precision destination. */
2800 rd
= VFP_SREG_D(insn
);
2802 VFP_DREG_D(rd
, insn
);
2805 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2806 /* VCVT from int is always from S reg regardless of dp bit.
2807 * VCVT with immediate frac_bits has same format as SREG_M
2809 rm
= VFP_SREG_M(insn
);
2811 VFP_DREG_M(rm
, insn
);
2814 rn
= VFP_SREG_N(insn
);
2815 if (op
== 15 && rn
== 15) {
2816 /* Double precision destination. */
2817 VFP_DREG_D(rd
, insn
);
2819 rd
= VFP_SREG_D(insn
);
2821 /* NB that we implicitly rely on the encoding for the frac_bits
2822 * in VCVT of fixed to float being the same as that of an SREG_M
2824 rm
= VFP_SREG_M(insn
);
2827 veclen
= s
->vec_len
;
2828 if (op
== 15 && rn
> 3)
2831 /* Shut up compiler warnings. */
2842 /* Figure out what type of vector operation this is. */
2843 if ((rd
& bank_mask
) == 0) {
2848 delta_d
= (s
->vec_stride
>> 1) + 1;
2850 delta_d
= s
->vec_stride
+ 1;
2852 if ((rm
& bank_mask
) == 0) {
2853 /* mixed scalar/vector */
2862 /* Load the initial operands. */
2867 /* Integer source */
2868 gen_mov_F0_vreg(0, rm
);
2873 gen_mov_F0_vreg(dp
, rd
);
2874 gen_mov_F1_vreg(dp
, rm
);
2878 /* Compare with zero */
2879 gen_mov_F0_vreg(dp
, rd
);
2890 /* Source and destination the same. */
2891 gen_mov_F0_vreg(dp
, rd
);
2897 /* VCVTB, VCVTT: only present with the halfprec extension,
2898 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2900 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
2903 /* Otherwise fall through */
2905 /* One source operand. */
2906 gen_mov_F0_vreg(dp
, rm
);
2910 /* Two source operands. */
2911 gen_mov_F0_vreg(dp
, rn
);
2912 gen_mov_F1_vreg(dp
, rm
);
2916 /* Perform the calculation. */
2918 case 0: /* VMLA: fd + (fn * fm) */
2919 /* Note that order of inputs to the add matters for NaNs */
2921 gen_mov_F0_vreg(dp
, rd
);
2924 case 1: /* VMLS: fd + -(fn * fm) */
2927 gen_mov_F0_vreg(dp
, rd
);
2930 case 2: /* VNMLS: -fd + (fn * fm) */
2931 /* Note that it isn't valid to replace (-A + B) with (B - A)
2932 * or similar plausible looking simplifications
2933 * because this will give wrong results for NaNs.
2936 gen_mov_F0_vreg(dp
, rd
);
2940 case 3: /* VNMLA: -fd + -(fn * fm) */
2943 gen_mov_F0_vreg(dp
, rd
);
2947 case 4: /* mul: fn * fm */
2950 case 5: /* nmul: -(fn * fm) */
2954 case 6: /* add: fn + fm */
2957 case 7: /* sub: fn - fm */
2960 case 8: /* div: fn / fm */
2963 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
2964 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
2965 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
2966 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
2967 /* These are fused multiply-add, and must be done as one
2968 * floating point operation with no rounding between the
2969 * multiplication and addition steps.
2970 * NB that doing the negations here as separate steps is
2971 * correct : an input NaN should come out with its sign bit
2972 * flipped if it is a negated-input.
2974 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
2982 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
2984 frd
= tcg_temp_new_i64();
2985 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
2988 gen_helper_vfp_negd(frd
, frd
);
2990 fpst
= get_fpstatus_ptr(0);
2991 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
2992 cpu_F1d
, frd
, fpst
);
2993 tcg_temp_free_ptr(fpst
);
2994 tcg_temp_free_i64(frd
);
3000 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3002 frd
= tcg_temp_new_i32();
3003 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3005 gen_helper_vfp_negs(frd
, frd
);
3007 fpst
= get_fpstatus_ptr(0);
3008 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3009 cpu_F1s
, frd
, fpst
);
3010 tcg_temp_free_ptr(fpst
);
3011 tcg_temp_free_i32(frd
);
3014 case 14: /* fconst */
3015 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3018 n
= (insn
<< 12) & 0x80000000;
3019 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3026 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3033 tcg_gen_movi_i32(cpu_F0s
, n
);
3036 case 15: /* extension space */
3050 case 4: /* vcvtb.f32.f16 */
3051 tmp
= gen_vfp_mrs();
3052 tcg_gen_ext16u_i32(tmp
, tmp
);
3053 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3054 tcg_temp_free_i32(tmp
);
3056 case 5: /* vcvtt.f32.f16 */
3057 tmp
= gen_vfp_mrs();
3058 tcg_gen_shri_i32(tmp
, tmp
, 16);
3059 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3060 tcg_temp_free_i32(tmp
);
3062 case 6: /* vcvtb.f16.f32 */
3063 tmp
= tcg_temp_new_i32();
3064 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3065 gen_mov_F0_vreg(0, rd
);
3066 tmp2
= gen_vfp_mrs();
3067 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3068 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3069 tcg_temp_free_i32(tmp2
);
3072 case 7: /* vcvtt.f16.f32 */
3073 tmp
= tcg_temp_new_i32();
3074 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3075 tcg_gen_shli_i32(tmp
, tmp
, 16);
3076 gen_mov_F0_vreg(0, rd
);
3077 tmp2
= gen_vfp_mrs();
3078 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3079 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3080 tcg_temp_free_i32(tmp2
);
3092 case 11: /* cmpez */
3096 case 15: /* single<->double conversion */
3098 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3100 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3102 case 16: /* fuito */
3103 gen_vfp_uito(dp
, 0);
3105 case 17: /* fsito */
3106 gen_vfp_sito(dp
, 0);
3108 case 20: /* fshto */
3109 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3111 gen_vfp_shto(dp
, 16 - rm
, 0);
3113 case 21: /* fslto */
3114 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3116 gen_vfp_slto(dp
, 32 - rm
, 0);
3118 case 22: /* fuhto */
3119 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3121 gen_vfp_uhto(dp
, 16 - rm
, 0);
3123 case 23: /* fulto */
3124 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3126 gen_vfp_ulto(dp
, 32 - rm
, 0);
3128 case 24: /* ftoui */
3129 gen_vfp_toui(dp
, 0);
3131 case 25: /* ftouiz */
3132 gen_vfp_touiz(dp
, 0);
3134 case 26: /* ftosi */
3135 gen_vfp_tosi(dp
, 0);
3137 case 27: /* ftosiz */
3138 gen_vfp_tosiz(dp
, 0);
3140 case 28: /* ftosh */
3141 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3143 gen_vfp_tosh(dp
, 16 - rm
, 0);
3145 case 29: /* ftosl */
3146 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3148 gen_vfp_tosl(dp
, 32 - rm
, 0);
3150 case 30: /* ftouh */
3151 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3153 gen_vfp_touh(dp
, 16 - rm
, 0);
3155 case 31: /* ftoul */
3156 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3158 gen_vfp_toul(dp
, 32 - rm
, 0);
3160 default: /* undefined */
3164 default: /* undefined */
3168 /* Write back the result. */
3169 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3170 ; /* Comparison, do nothing. */
3171 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3172 /* VCVT double to int: always integer result. */
3173 gen_mov_vreg_F0(0, rd
);
3174 else if (op
== 15 && rn
== 15)
3176 gen_mov_vreg_F0(!dp
, rd
);
3178 gen_mov_vreg_F0(dp
, rd
);
3180 /* break out of the loop if we have finished */
3184 if (op
== 15 && delta_m
== 0) {
3185 /* single source one-many */
3187 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3189 gen_mov_vreg_F0(dp
, rd
);
3193 /* Setup the next operands. */
3195 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3199 /* One source operand. */
3200 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3202 gen_mov_F0_vreg(dp
, rm
);
3204 /* Two source operands. */
3205 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3207 gen_mov_F0_vreg(dp
, rn
);
3209 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3211 gen_mov_F1_vreg(dp
, rm
);
3219 if ((insn
& 0x03e00000) == 0x00400000) {
3220 /* two-register transfer */
3221 rn
= (insn
>> 16) & 0xf;
3222 rd
= (insn
>> 12) & 0xf;
3224 VFP_DREG_M(rm
, insn
);
3226 rm
= VFP_SREG_M(insn
);
3229 if (insn
& ARM_CP_RW_BIT
) {
3232 gen_mov_F0_vreg(0, rm
* 2);
3233 tmp
= gen_vfp_mrs();
3234 store_reg(s
, rd
, tmp
);
3235 gen_mov_F0_vreg(0, rm
* 2 + 1);
3236 tmp
= gen_vfp_mrs();
3237 store_reg(s
, rn
, tmp
);
3239 gen_mov_F0_vreg(0, rm
);
3240 tmp
= gen_vfp_mrs();
3241 store_reg(s
, rd
, tmp
);
3242 gen_mov_F0_vreg(0, rm
+ 1);
3243 tmp
= gen_vfp_mrs();
3244 store_reg(s
, rn
, tmp
);
3249 tmp
= load_reg(s
, rd
);
3251 gen_mov_vreg_F0(0, rm
* 2);
3252 tmp
= load_reg(s
, rn
);
3254 gen_mov_vreg_F0(0, rm
* 2 + 1);
3256 tmp
= load_reg(s
, rd
);
3258 gen_mov_vreg_F0(0, rm
);
3259 tmp
= load_reg(s
, rn
);
3261 gen_mov_vreg_F0(0, rm
+ 1);
3266 rn
= (insn
>> 16) & 0xf;
3268 VFP_DREG_D(rd
, insn
);
3270 rd
= VFP_SREG_D(insn
);
3271 if ((insn
& 0x01200000) == 0x01000000) {
3272 /* Single load/store */
3273 offset
= (insn
& 0xff) << 2;
3274 if ((insn
& (1 << 23)) == 0)
3276 if (s
->thumb
&& rn
== 15) {
3277 /* This is actually UNPREDICTABLE */
3278 addr
= tcg_temp_new_i32();
3279 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3281 addr
= load_reg(s
, rn
);
3283 tcg_gen_addi_i32(addr
, addr
, offset
);
3284 if (insn
& (1 << 20)) {
3285 gen_vfp_ld(s
, dp
, addr
);
3286 gen_mov_vreg_F0(dp
, rd
);
3288 gen_mov_F0_vreg(dp
, rd
);
3289 gen_vfp_st(s
, dp
, addr
);
3291 tcg_temp_free_i32(addr
);
3293 /* load/store multiple */
3294 int w
= insn
& (1 << 21);
3296 n
= (insn
>> 1) & 0x7f;
3300 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3301 /* P == U , W == 1 => UNDEF */
3304 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3305 /* UNPREDICTABLE cases for bad immediates: we choose to
3306 * UNDEF to avoid generating huge numbers of TCG ops
3310 if (rn
== 15 && w
) {
3311 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3315 if (s
->thumb
&& rn
== 15) {
3316 /* This is actually UNPREDICTABLE */
3317 addr
= tcg_temp_new_i32();
3318 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3320 addr
= load_reg(s
, rn
);
3322 if (insn
& (1 << 24)) /* pre-decrement */
3323 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3329 for (i
= 0; i
< n
; i
++) {
3330 if (insn
& ARM_CP_RW_BIT
) {
3332 gen_vfp_ld(s
, dp
, addr
);
3333 gen_mov_vreg_F0(dp
, rd
+ i
);
3336 gen_mov_F0_vreg(dp
, rd
+ i
);
3337 gen_vfp_st(s
, dp
, addr
);
3339 tcg_gen_addi_i32(addr
, addr
, offset
);
3343 if (insn
& (1 << 24))
3344 offset
= -offset
* n
;
3345 else if (dp
&& (insn
& 1))
3351 tcg_gen_addi_i32(addr
, addr
, offset
);
3352 store_reg(s
, rn
, addr
);
3354 tcg_temp_free_i32(addr
);
3360 /* Should never happen. */
3366 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3368 TranslationBlock
*tb
;
3371 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3373 gen_set_pc_im(dest
);
3374 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3376 gen_set_pc_im(dest
);
3381 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3383 if (unlikely(s
->singlestep_enabled
)) {
3384 /* An indirect jump so that we still trigger the debug exception. */
3389 gen_goto_tb(s
, 0, dest
);
3390 s
->is_jmp
= DISAS_TB_JUMP
;
3394 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3397 tcg_gen_sari_i32(t0
, t0
, 16);
3401 tcg_gen_sari_i32(t1
, t1
, 16);
3404 tcg_gen_mul_i32(t0
, t0
, t1
);
3407 /* Return the mask of PSR bits set by a MSR instruction. */
3408 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3412 if (flags
& (1 << 0))
3414 if (flags
& (1 << 1))
3416 if (flags
& (1 << 2))
3418 if (flags
& (1 << 3))
3421 /* Mask out undefined bits. */
3422 mask
&= ~CPSR_RESERVED
;
3423 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3425 if (!arm_feature(env
, ARM_FEATURE_V5
))
3426 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3427 if (!arm_feature(env
, ARM_FEATURE_V6
))
3428 mask
&= ~(CPSR_E
| CPSR_GE
);
3429 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3431 /* Mask out execution state bits. */
3434 /* Mask out privileged bits. */
3440 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3441 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3445 /* ??? This is also undefined in system mode. */
3449 tmp
= load_cpu_field(spsr
);
3450 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3451 tcg_gen_andi_i32(t0
, t0
, mask
);
3452 tcg_gen_or_i32(tmp
, tmp
, t0
);
3453 store_cpu_field(tmp
, spsr
);
3455 gen_set_cpsr(t0
, mask
);
3457 tcg_temp_free_i32(t0
);
3462 /* Returns nonzero if access to the PSR is not permitted. */
3463 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3466 tmp
= tcg_temp_new_i32();
3467 tcg_gen_movi_i32(tmp
, val
);
3468 return gen_set_psr(s
, mask
, spsr
, tmp
);
3471 /* Generate an old-style exception return. Marks pc as dead. */
3472 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3475 store_reg(s
, 15, pc
);
3476 tmp
= load_cpu_field(spsr
);
3477 gen_set_cpsr(tmp
, 0xffffffff);
3478 tcg_temp_free_i32(tmp
);
3479 s
->is_jmp
= DISAS_UPDATE
;
3482 /* Generate a v6 exception return. Marks both values as dead. */
3483 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3485 gen_set_cpsr(cpsr
, 0xffffffff);
3486 tcg_temp_free_i32(cpsr
);
3487 store_reg(s
, 15, pc
);
3488 s
->is_jmp
= DISAS_UPDATE
;
3492 gen_set_condexec (DisasContext
*s
)
3494 if (s
->condexec_mask
) {
3495 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3496 TCGv tmp
= tcg_temp_new_i32();
3497 tcg_gen_movi_i32(tmp
, val
);
3498 store_cpu_field(tmp
, condexec_bits
);
3502 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3504 gen_set_condexec(s
);
3505 gen_set_pc_im(s
->pc
- offset
);
3506 gen_exception(excp
);
3507 s
->is_jmp
= DISAS_JUMP
;
3510 static void gen_nop_hint(DisasContext
*s
, int val
)
3514 gen_set_pc_im(s
->pc
);
3515 s
->is_jmp
= DISAS_WFI
;
3519 /* TODO: Implement SEV and WFE. May help SMP performance. */
3525 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3527 static inline void gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3530 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3531 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3532 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3537 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3540 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3541 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3542 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3547 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3548 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3549 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3550 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3551 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3553 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3554 switch ((size << 1) | u) { \
3556 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3559 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3562 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3565 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3568 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3571 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3573 default: return 1; \
3576 #define GEN_NEON_INTEGER_OP(name) do { \
3577 switch ((size << 1) | u) { \
3579 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3582 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3585 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3588 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3591 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3594 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3596 default: return 1; \
3599 static TCGv
neon_load_scratch(int scratch
)
3601 TCGv tmp
= tcg_temp_new_i32();
3602 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3606 static void neon_store_scratch(int scratch
, TCGv var
)
3608 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3609 tcg_temp_free_i32(var
);
3612 static inline TCGv
neon_get_scalar(int size
, int reg
)
3616 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3618 gen_neon_dup_high16(tmp
);
3620 gen_neon_dup_low16(tmp
);
3623 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3628 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3631 if (!q
&& size
== 2) {
3634 tmp
= tcg_const_i32(rd
);
3635 tmp2
= tcg_const_i32(rm
);
3639 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3642 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3645 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3653 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3656 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3662 tcg_temp_free_i32(tmp
);
3663 tcg_temp_free_i32(tmp2
);
3667 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3670 if (!q
&& size
== 2) {
3673 tmp
= tcg_const_i32(rd
);
3674 tmp2
= tcg_const_i32(rm
);
3678 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3681 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3684 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3692 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3695 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3701 tcg_temp_free_i32(tmp
);
3702 tcg_temp_free_i32(tmp2
);
3706 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3710 rd
= tcg_temp_new_i32();
3711 tmp
= tcg_temp_new_i32();
3713 tcg_gen_shli_i32(rd
, t0
, 8);
3714 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3715 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3716 tcg_gen_or_i32(rd
, rd
, tmp
);
3718 tcg_gen_shri_i32(t1
, t1
, 8);
3719 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3720 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3721 tcg_gen_or_i32(t1
, t1
, tmp
);
3722 tcg_gen_mov_i32(t0
, rd
);
3724 tcg_temp_free_i32(tmp
);
3725 tcg_temp_free_i32(rd
);
3728 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3732 rd
= tcg_temp_new_i32();
3733 tmp
= tcg_temp_new_i32();
3735 tcg_gen_shli_i32(rd
, t0
, 16);
3736 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3737 tcg_gen_or_i32(rd
, rd
, tmp
);
3738 tcg_gen_shri_i32(t1
, t1
, 16);
3739 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3740 tcg_gen_or_i32(t1
, t1
, tmp
);
3741 tcg_gen_mov_i32(t0
, rd
);
3743 tcg_temp_free_i32(tmp
);
3744 tcg_temp_free_i32(rd
);
3752 } neon_ls_element_type
[11] = {
3766 /* Translate a NEON load/store element instruction. Return nonzero if the
3767 instruction is invalid. */
3768 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3787 if (!s
->vfp_enabled
)
3789 VFP_DREG_D(rd
, insn
);
3790 rn
= (insn
>> 16) & 0xf;
3792 load
= (insn
& (1 << 21)) != 0;
3793 if ((insn
& (1 << 23)) == 0) {
3794 /* Load store all elements. */
3795 op
= (insn
>> 8) & 0xf;
3796 size
= (insn
>> 6) & 3;
3799 /* Catch UNDEF cases for bad values of align field */
3802 if (((insn
>> 5) & 1) == 1) {
3807 if (((insn
>> 4) & 3) == 3) {
3814 nregs
= neon_ls_element_type
[op
].nregs
;
3815 interleave
= neon_ls_element_type
[op
].interleave
;
3816 spacing
= neon_ls_element_type
[op
].spacing
;
3817 if (size
== 3 && (interleave
| spacing
) != 1)
3819 addr
= tcg_temp_new_i32();
3820 load_reg_var(s
, addr
, rn
);
3821 stride
= (1 << size
) * interleave
;
3822 for (reg
= 0; reg
< nregs
; reg
++) {
3823 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3824 load_reg_var(s
, addr
, rn
);
3825 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3826 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3827 load_reg_var(s
, addr
, rn
);
3828 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3832 tmp64
= gen_ld64(addr
, IS_USER(s
));
3833 neon_store_reg64(tmp64
, rd
);
3834 tcg_temp_free_i64(tmp64
);
3836 tmp64
= tcg_temp_new_i64();
3837 neon_load_reg64(tmp64
, rd
);
3838 gen_st64(tmp64
, addr
, IS_USER(s
));
3840 tcg_gen_addi_i32(addr
, addr
, stride
);
3842 for (pass
= 0; pass
< 2; pass
++) {
3845 tmp
= gen_ld32(addr
, IS_USER(s
));
3846 neon_store_reg(rd
, pass
, tmp
);
3848 tmp
= neon_load_reg(rd
, pass
);
3849 gen_st32(tmp
, addr
, IS_USER(s
));
3851 tcg_gen_addi_i32(addr
, addr
, stride
);
3852 } else if (size
== 1) {
3854 tmp
= gen_ld16u(addr
, IS_USER(s
));
3855 tcg_gen_addi_i32(addr
, addr
, stride
);
3856 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3857 tcg_gen_addi_i32(addr
, addr
, stride
);
3858 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3859 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3860 tcg_temp_free_i32(tmp2
);
3861 neon_store_reg(rd
, pass
, tmp
);
3863 tmp
= neon_load_reg(rd
, pass
);
3864 tmp2
= tcg_temp_new_i32();
3865 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3866 gen_st16(tmp
, addr
, IS_USER(s
));
3867 tcg_gen_addi_i32(addr
, addr
, stride
);
3868 gen_st16(tmp2
, addr
, IS_USER(s
));
3869 tcg_gen_addi_i32(addr
, addr
, stride
);
3871 } else /* size == 0 */ {
3874 for (n
= 0; n
< 4; n
++) {
3875 tmp
= gen_ld8u(addr
, IS_USER(s
));
3876 tcg_gen_addi_i32(addr
, addr
, stride
);
3880 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3881 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3882 tcg_temp_free_i32(tmp
);
3885 neon_store_reg(rd
, pass
, tmp2
);
3887 tmp2
= neon_load_reg(rd
, pass
);
3888 for (n
= 0; n
< 4; n
++) {
3889 tmp
= tcg_temp_new_i32();
3891 tcg_gen_mov_i32(tmp
, tmp2
);
3893 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3895 gen_st8(tmp
, addr
, IS_USER(s
));
3896 tcg_gen_addi_i32(addr
, addr
, stride
);
3898 tcg_temp_free_i32(tmp2
);
3905 tcg_temp_free_i32(addr
);
3908 size
= (insn
>> 10) & 3;
3910 /* Load single element to all lanes. */
3911 int a
= (insn
>> 4) & 1;
3915 size
= (insn
>> 6) & 3;
3916 nregs
= ((insn
>> 8) & 3) + 1;
3919 if (nregs
!= 4 || a
== 0) {
3922 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3925 if (nregs
== 1 && a
== 1 && size
== 0) {
3928 if (nregs
== 3 && a
== 1) {
3931 addr
= tcg_temp_new_i32();
3932 load_reg_var(s
, addr
, rn
);
3934 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3935 tmp
= gen_load_and_replicate(s
, addr
, size
);
3936 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3937 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3938 if (insn
& (1 << 5)) {
3939 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
3940 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
3942 tcg_temp_free_i32(tmp
);
3944 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
3945 stride
= (insn
& (1 << 5)) ? 2 : 1;
3946 for (reg
= 0; reg
< nregs
; reg
++) {
3947 tmp
= gen_load_and_replicate(s
, addr
, size
);
3948 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3949 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3950 tcg_temp_free_i32(tmp
);
3951 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3955 tcg_temp_free_i32(addr
);
3956 stride
= (1 << size
) * nregs
;
3958 /* Single element. */
3959 int idx
= (insn
>> 4) & 0xf;
3960 pass
= (insn
>> 7) & 1;
3963 shift
= ((insn
>> 5) & 3) * 8;
3967 shift
= ((insn
>> 6) & 1) * 16;
3968 stride
= (insn
& (1 << 5)) ? 2 : 1;
3972 stride
= (insn
& (1 << 6)) ? 2 : 1;
3977 nregs
= ((insn
>> 8) & 3) + 1;
3978 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3981 if (((idx
& (1 << size
)) != 0) ||
3982 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
3987 if ((idx
& 1) != 0) {
3992 if (size
== 2 && (idx
& 2) != 0) {
3997 if ((size
== 2) && ((idx
& 3) == 3)) {
4004 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4005 /* Attempts to write off the end of the register file
4006 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4007 * the neon_load_reg() would write off the end of the array.
4011 addr
= tcg_temp_new_i32();
4012 load_reg_var(s
, addr
, rn
);
4013 for (reg
= 0; reg
< nregs
; reg
++) {
4017 tmp
= gen_ld8u(addr
, IS_USER(s
));
4020 tmp
= gen_ld16u(addr
, IS_USER(s
));
4023 tmp
= gen_ld32(addr
, IS_USER(s
));
4025 default: /* Avoid compiler warnings. */
4029 tmp2
= neon_load_reg(rd
, pass
);
4030 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4031 shift
, size
? 16 : 8);
4032 tcg_temp_free_i32(tmp2
);
4034 neon_store_reg(rd
, pass
, tmp
);
4035 } else { /* Store */
4036 tmp
= neon_load_reg(rd
, pass
);
4038 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4041 gen_st8(tmp
, addr
, IS_USER(s
));
4044 gen_st16(tmp
, addr
, IS_USER(s
));
4047 gen_st32(tmp
, addr
, IS_USER(s
));
4052 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4054 tcg_temp_free_i32(addr
);
4055 stride
= nregs
* (1 << size
);
4061 base
= load_reg(s
, rn
);
4063 tcg_gen_addi_i32(base
, base
, stride
);
4066 index
= load_reg(s
, rm
);
4067 tcg_gen_add_i32(base
, base
, index
);
4068 tcg_temp_free_i32(index
);
4070 store_reg(s
, rn
, base
);
4075 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4076 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4078 tcg_gen_and_i32(t
, t
, c
);
4079 tcg_gen_andc_i32(f
, f
, c
);
4080 tcg_gen_or_i32(dest
, t
, f
);
4083 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4086 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4087 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4088 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4093 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4096 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4097 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4098 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4103 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4106 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4107 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4108 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4113 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4116 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4117 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4118 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4123 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4129 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4130 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4135 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4136 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4143 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4144 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4149 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4150 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4157 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4161 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4162 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4163 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4168 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4169 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4170 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4174 tcg_temp_free_i32(src
);
4177 static inline void gen_neon_addl(int size
)
4180 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4181 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4182 case 2: tcg_gen_add_i64(CPU_V001
); break;
4187 static inline void gen_neon_subl(int size
)
4190 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4191 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4192 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4197 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4200 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4201 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4203 tcg_gen_neg_i64(var
, var
);
4209 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4212 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4213 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4218 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4222 switch ((size
<< 1) | u
) {
4223 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4224 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4225 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4226 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4228 tmp
= gen_muls_i64_i32(a
, b
);
4229 tcg_gen_mov_i64(dest
, tmp
);
4230 tcg_temp_free_i64(tmp
);
4233 tmp
= gen_mulu_i64_i32(a
, b
);
4234 tcg_gen_mov_i64(dest
, tmp
);
4235 tcg_temp_free_i64(tmp
);
4240 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4241 Don't forget to clean them now. */
4243 tcg_temp_free_i32(a
);
4244 tcg_temp_free_i32(b
);
4248 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4252 gen_neon_unarrow_sats(size
, dest
, src
);
4254 gen_neon_narrow(size
, dest
, src
);
4258 gen_neon_narrow_satu(size
, dest
, src
);
4260 gen_neon_narrow_sats(size
, dest
, src
);
4265 /* Symbolic constants for op fields for Neon 3-register same-length.
4266 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4269 #define NEON_3R_VHADD 0
4270 #define NEON_3R_VQADD 1
4271 #define NEON_3R_VRHADD 2
4272 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4273 #define NEON_3R_VHSUB 4
4274 #define NEON_3R_VQSUB 5
4275 #define NEON_3R_VCGT 6
4276 #define NEON_3R_VCGE 7
4277 #define NEON_3R_VSHL 8
4278 #define NEON_3R_VQSHL 9
4279 #define NEON_3R_VRSHL 10
4280 #define NEON_3R_VQRSHL 11
4281 #define NEON_3R_VMAX 12
4282 #define NEON_3R_VMIN 13
4283 #define NEON_3R_VABD 14
4284 #define NEON_3R_VABA 15
4285 #define NEON_3R_VADD_VSUB 16
4286 #define NEON_3R_VTST_VCEQ 17
4287 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4288 #define NEON_3R_VMUL 19
4289 #define NEON_3R_VPMAX 20
4290 #define NEON_3R_VPMIN 21
4291 #define NEON_3R_VQDMULH_VQRDMULH 22
4292 #define NEON_3R_VPADD 23
4293 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4294 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4295 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4296 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4297 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4298 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4299 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4301 static const uint8_t neon_3r_sizes
[] = {
4302 [NEON_3R_VHADD
] = 0x7,
4303 [NEON_3R_VQADD
] = 0xf,
4304 [NEON_3R_VRHADD
] = 0x7,
4305 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4306 [NEON_3R_VHSUB
] = 0x7,
4307 [NEON_3R_VQSUB
] = 0xf,
4308 [NEON_3R_VCGT
] = 0x7,
4309 [NEON_3R_VCGE
] = 0x7,
4310 [NEON_3R_VSHL
] = 0xf,
4311 [NEON_3R_VQSHL
] = 0xf,
4312 [NEON_3R_VRSHL
] = 0xf,
4313 [NEON_3R_VQRSHL
] = 0xf,
4314 [NEON_3R_VMAX
] = 0x7,
4315 [NEON_3R_VMIN
] = 0x7,
4316 [NEON_3R_VABD
] = 0x7,
4317 [NEON_3R_VABA
] = 0x7,
4318 [NEON_3R_VADD_VSUB
] = 0xf,
4319 [NEON_3R_VTST_VCEQ
] = 0x7,
4320 [NEON_3R_VML
] = 0x7,
4321 [NEON_3R_VMUL
] = 0x7,
4322 [NEON_3R_VPMAX
] = 0x7,
4323 [NEON_3R_VPMIN
] = 0x7,
4324 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4325 [NEON_3R_VPADD
] = 0x7,
4326 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4327 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4328 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4329 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4330 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4331 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4332 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4335 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4336 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4339 #define NEON_2RM_VREV64 0
4340 #define NEON_2RM_VREV32 1
4341 #define NEON_2RM_VREV16 2
4342 #define NEON_2RM_VPADDL 4
4343 #define NEON_2RM_VPADDL_U 5
4344 #define NEON_2RM_VCLS 8
4345 #define NEON_2RM_VCLZ 9
4346 #define NEON_2RM_VCNT 10
4347 #define NEON_2RM_VMVN 11
4348 #define NEON_2RM_VPADAL 12
4349 #define NEON_2RM_VPADAL_U 13
4350 #define NEON_2RM_VQABS 14
4351 #define NEON_2RM_VQNEG 15
4352 #define NEON_2RM_VCGT0 16
4353 #define NEON_2RM_VCGE0 17
4354 #define NEON_2RM_VCEQ0 18
4355 #define NEON_2RM_VCLE0 19
4356 #define NEON_2RM_VCLT0 20
4357 #define NEON_2RM_VABS 22
4358 #define NEON_2RM_VNEG 23
4359 #define NEON_2RM_VCGT0_F 24
4360 #define NEON_2RM_VCGE0_F 25
4361 #define NEON_2RM_VCEQ0_F 26
4362 #define NEON_2RM_VCLE0_F 27
4363 #define NEON_2RM_VCLT0_F 28
4364 #define NEON_2RM_VABS_F 30
4365 #define NEON_2RM_VNEG_F 31
4366 #define NEON_2RM_VSWP 32
4367 #define NEON_2RM_VTRN 33
4368 #define NEON_2RM_VUZP 34
4369 #define NEON_2RM_VZIP 35
4370 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4371 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4372 #define NEON_2RM_VSHLL 38
4373 #define NEON_2RM_VCVT_F16_F32 44
4374 #define NEON_2RM_VCVT_F32_F16 46
4375 #define NEON_2RM_VRECPE 56
4376 #define NEON_2RM_VRSQRTE 57
4377 #define NEON_2RM_VRECPE_F 58
4378 #define NEON_2RM_VRSQRTE_F 59
4379 #define NEON_2RM_VCVT_FS 60
4380 #define NEON_2RM_VCVT_FU 61
4381 #define NEON_2RM_VCVT_SF 62
4382 #define NEON_2RM_VCVT_UF 63
4384 static int neon_2rm_is_float_op(int op
)
4386 /* Return true if this neon 2reg-misc op is float-to-float */
4387 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4388 op
>= NEON_2RM_VRECPE_F
);
4391 /* Each entry in this array has bit n set if the insn allows
4392 * size value n (otherwise it will UNDEF). Since unallocated
4393 * op values will have no bits set they always UNDEF.
4395 static const uint8_t neon_2rm_sizes
[] = {
4396 [NEON_2RM_VREV64
] = 0x7,
4397 [NEON_2RM_VREV32
] = 0x3,
4398 [NEON_2RM_VREV16
] = 0x1,
4399 [NEON_2RM_VPADDL
] = 0x7,
4400 [NEON_2RM_VPADDL_U
] = 0x7,
4401 [NEON_2RM_VCLS
] = 0x7,
4402 [NEON_2RM_VCLZ
] = 0x7,
4403 [NEON_2RM_VCNT
] = 0x1,
4404 [NEON_2RM_VMVN
] = 0x1,
4405 [NEON_2RM_VPADAL
] = 0x7,
4406 [NEON_2RM_VPADAL_U
] = 0x7,
4407 [NEON_2RM_VQABS
] = 0x7,
4408 [NEON_2RM_VQNEG
] = 0x7,
4409 [NEON_2RM_VCGT0
] = 0x7,
4410 [NEON_2RM_VCGE0
] = 0x7,
4411 [NEON_2RM_VCEQ0
] = 0x7,
4412 [NEON_2RM_VCLE0
] = 0x7,
4413 [NEON_2RM_VCLT0
] = 0x7,
4414 [NEON_2RM_VABS
] = 0x7,
4415 [NEON_2RM_VNEG
] = 0x7,
4416 [NEON_2RM_VCGT0_F
] = 0x4,
4417 [NEON_2RM_VCGE0_F
] = 0x4,
4418 [NEON_2RM_VCEQ0_F
] = 0x4,
4419 [NEON_2RM_VCLE0_F
] = 0x4,
4420 [NEON_2RM_VCLT0_F
] = 0x4,
4421 [NEON_2RM_VABS_F
] = 0x4,
4422 [NEON_2RM_VNEG_F
] = 0x4,
4423 [NEON_2RM_VSWP
] = 0x1,
4424 [NEON_2RM_VTRN
] = 0x7,
4425 [NEON_2RM_VUZP
] = 0x7,
4426 [NEON_2RM_VZIP
] = 0x7,
4427 [NEON_2RM_VMOVN
] = 0x7,
4428 [NEON_2RM_VQMOVN
] = 0x7,
4429 [NEON_2RM_VSHLL
] = 0x7,
4430 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4431 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4432 [NEON_2RM_VRECPE
] = 0x4,
4433 [NEON_2RM_VRSQRTE
] = 0x4,
4434 [NEON_2RM_VRECPE_F
] = 0x4,
4435 [NEON_2RM_VRSQRTE_F
] = 0x4,
4436 [NEON_2RM_VCVT_FS
] = 0x4,
4437 [NEON_2RM_VCVT_FU
] = 0x4,
4438 [NEON_2RM_VCVT_SF
] = 0x4,
4439 [NEON_2RM_VCVT_UF
] = 0x4,
4442 /* Translate a NEON data processing instruction. Return nonzero if the
4443 instruction is invalid.
4444 We process data in a mixture of 32-bit and 64-bit chunks.
4445 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4447 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4459 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4462 if (!s
->vfp_enabled
)
4464 q
= (insn
& (1 << 6)) != 0;
4465 u
= (insn
>> 24) & 1;
4466 VFP_DREG_D(rd
, insn
);
4467 VFP_DREG_N(rn
, insn
);
4468 VFP_DREG_M(rm
, insn
);
4469 size
= (insn
>> 20) & 3;
4470 if ((insn
& (1 << 23)) == 0) {
4471 /* Three register same length. */
4472 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4473 /* Catch invalid op and bad size combinations: UNDEF */
4474 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4477 /* All insns of this form UNDEF for either this condition or the
4478 * superset of cases "Q==1"; we catch the latter later.
4480 if (q
&& ((rd
| rn
| rm
) & 1)) {
4483 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4484 /* 64-bit element instructions. */
4485 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4486 neon_load_reg64(cpu_V0
, rn
+ pass
);
4487 neon_load_reg64(cpu_V1
, rm
+ pass
);
4491 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4494 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4500 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4503 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4509 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4511 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4516 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4519 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4525 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4527 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4530 case NEON_3R_VQRSHL
:
4532 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4535 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4539 case NEON_3R_VADD_VSUB
:
4541 tcg_gen_sub_i64(CPU_V001
);
4543 tcg_gen_add_i64(CPU_V001
);
4549 neon_store_reg64(cpu_V0
, rd
+ pass
);
4558 case NEON_3R_VQRSHL
:
4561 /* Shift instruction operands are reversed. */
4576 case NEON_3R_FLOAT_ARITH
:
4577 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4579 case NEON_3R_FLOAT_MINMAX
:
4580 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4582 case NEON_3R_FLOAT_CMP
:
4584 /* no encoding for U=0 C=1x */
4588 case NEON_3R_FLOAT_ACMP
:
4593 case NEON_3R_VRECPS_VRSQRTS
:
4599 if (u
&& (size
!= 0)) {
4600 /* UNDEF on invalid size for polynomial subcase */
4605 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4613 if (pairwise
&& q
) {
4614 /* All the pairwise insns UNDEF if Q is set */
4618 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4623 tmp
= neon_load_reg(rn
, 0);
4624 tmp2
= neon_load_reg(rn
, 1);
4626 tmp
= neon_load_reg(rm
, 0);
4627 tmp2
= neon_load_reg(rm
, 1);
4631 tmp
= neon_load_reg(rn
, pass
);
4632 tmp2
= neon_load_reg(rm
, pass
);
4636 GEN_NEON_INTEGER_OP(hadd
);
4639 GEN_NEON_INTEGER_OP_ENV(qadd
);
4641 case NEON_3R_VRHADD
:
4642 GEN_NEON_INTEGER_OP(rhadd
);
4644 case NEON_3R_LOGIC
: /* Logic ops. */
4645 switch ((u
<< 2) | size
) {
4647 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4650 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4653 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4656 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4659 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4662 tmp3
= neon_load_reg(rd
, pass
);
4663 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4664 tcg_temp_free_i32(tmp3
);
4667 tmp3
= neon_load_reg(rd
, pass
);
4668 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4669 tcg_temp_free_i32(tmp3
);
4672 tmp3
= neon_load_reg(rd
, pass
);
4673 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4674 tcg_temp_free_i32(tmp3
);
4679 GEN_NEON_INTEGER_OP(hsub
);
4682 GEN_NEON_INTEGER_OP_ENV(qsub
);
4685 GEN_NEON_INTEGER_OP(cgt
);
4688 GEN_NEON_INTEGER_OP(cge
);
4691 GEN_NEON_INTEGER_OP(shl
);
4694 GEN_NEON_INTEGER_OP_ENV(qshl
);
4697 GEN_NEON_INTEGER_OP(rshl
);
4699 case NEON_3R_VQRSHL
:
4700 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4703 GEN_NEON_INTEGER_OP(max
);
4706 GEN_NEON_INTEGER_OP(min
);
4709 GEN_NEON_INTEGER_OP(abd
);
4712 GEN_NEON_INTEGER_OP(abd
);
4713 tcg_temp_free_i32(tmp2
);
4714 tmp2
= neon_load_reg(rd
, pass
);
4715 gen_neon_add(size
, tmp
, tmp2
);
4717 case NEON_3R_VADD_VSUB
:
4718 if (!u
) { /* VADD */
4719 gen_neon_add(size
, tmp
, tmp2
);
4722 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4723 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4724 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4729 case NEON_3R_VTST_VCEQ
:
4730 if (!u
) { /* VTST */
4732 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4733 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4734 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4739 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4740 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4741 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4746 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4748 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4749 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4750 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4753 tcg_temp_free_i32(tmp2
);
4754 tmp2
= neon_load_reg(rd
, pass
);
4756 gen_neon_rsb(size
, tmp
, tmp2
);
4758 gen_neon_add(size
, tmp
, tmp2
);
4762 if (u
) { /* polynomial */
4763 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4764 } else { /* Integer */
4766 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4767 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4768 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4774 GEN_NEON_INTEGER_OP(pmax
);
4777 GEN_NEON_INTEGER_OP(pmin
);
4779 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4780 if (!u
) { /* VQDMULH */
4783 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4786 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4790 } else { /* VQRDMULH */
4793 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4796 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4804 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4805 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4806 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4810 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4812 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4813 switch ((u
<< 2) | size
) {
4816 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4819 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
4822 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
4827 tcg_temp_free_ptr(fpstatus
);
4830 case NEON_3R_FLOAT_MULTIPLY
:
4832 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4833 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
4835 tcg_temp_free_i32(tmp2
);
4836 tmp2
= neon_load_reg(rd
, pass
);
4838 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4840 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
4843 tcg_temp_free_ptr(fpstatus
);
4846 case NEON_3R_FLOAT_CMP
:
4848 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4850 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
4853 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4855 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4858 tcg_temp_free_ptr(fpstatus
);
4861 case NEON_3R_FLOAT_ACMP
:
4863 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4865 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4867 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4869 tcg_temp_free_ptr(fpstatus
);
4872 case NEON_3R_FLOAT_MINMAX
:
4874 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4876 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
4878 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
4880 tcg_temp_free_ptr(fpstatus
);
4883 case NEON_3R_VRECPS_VRSQRTS
:
4885 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4887 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4891 /* VFMA, VFMS: fused multiply-add */
4892 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4893 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
4896 gen_helper_vfp_negs(tmp
, tmp
);
4898 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
4899 tcg_temp_free_i32(tmp3
);
4900 tcg_temp_free_ptr(fpstatus
);
4906 tcg_temp_free_i32(tmp2
);
4908 /* Save the result. For elementwise operations we can put it
4909 straight into the destination register. For pairwise operations
4910 we have to be careful to avoid clobbering the source operands. */
4911 if (pairwise
&& rd
== rm
) {
4912 neon_store_scratch(pass
, tmp
);
4914 neon_store_reg(rd
, pass
, tmp
);
4918 if (pairwise
&& rd
== rm
) {
4919 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4920 tmp
= neon_load_scratch(pass
);
4921 neon_store_reg(rd
, pass
, tmp
);
4924 /* End of 3 register same size operations. */
4925 } else if (insn
& (1 << 4)) {
4926 if ((insn
& 0x00380080) != 0) {
4927 /* Two registers and shift. */
4928 op
= (insn
>> 8) & 0xf;
4929 if (insn
& (1 << 7)) {
4937 while ((insn
& (1 << (size
+ 19))) == 0)
4940 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
4941 /* To avoid excessive duplication of ops we implement shift
4942 by immediate using the variable shift operations. */
4944 /* Shift by immediate:
4945 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4946 if (q
&& ((rd
| rm
) & 1)) {
4949 if (!u
&& (op
== 4 || op
== 6)) {
4952 /* Right shifts are encoded as N - shift, where N is the
4953 element size in bits. */
4955 shift
= shift
- (1 << (size
+ 3));
4963 imm
= (uint8_t) shift
;
4968 imm
= (uint16_t) shift
;
4979 for (pass
= 0; pass
< count
; pass
++) {
4981 neon_load_reg64(cpu_V0
, rm
+ pass
);
4982 tcg_gen_movi_i64(cpu_V1
, imm
);
4987 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4989 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4994 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
4996 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
4999 case 5: /* VSHL, VSLI */
5000 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5002 case 6: /* VQSHLU */
5003 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5008 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5011 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5016 if (op
== 1 || op
== 3) {
5018 neon_load_reg64(cpu_V1
, rd
+ pass
);
5019 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5020 } else if (op
== 4 || (op
== 5 && u
)) {
5022 neon_load_reg64(cpu_V1
, rd
+ pass
);
5024 if (shift
< -63 || shift
> 63) {
5028 mask
= 0xffffffffffffffffull
>> -shift
;
5030 mask
= 0xffffffffffffffffull
<< shift
;
5033 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5034 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5036 neon_store_reg64(cpu_V0
, rd
+ pass
);
5037 } else { /* size < 3 */
5038 /* Operands in T0 and T1. */
5039 tmp
= neon_load_reg(rm
, pass
);
5040 tmp2
= tcg_temp_new_i32();
5041 tcg_gen_movi_i32(tmp2
, imm
);
5045 GEN_NEON_INTEGER_OP(shl
);
5049 GEN_NEON_INTEGER_OP(rshl
);
5052 case 5: /* VSHL, VSLI */
5054 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5055 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5056 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5060 case 6: /* VQSHLU */
5063 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5067 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5071 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5079 GEN_NEON_INTEGER_OP_ENV(qshl
);
5082 tcg_temp_free_i32(tmp2
);
5084 if (op
== 1 || op
== 3) {
5086 tmp2
= neon_load_reg(rd
, pass
);
5087 gen_neon_add(size
, tmp
, tmp2
);
5088 tcg_temp_free_i32(tmp2
);
5089 } else if (op
== 4 || (op
== 5 && u
)) {
5094 mask
= 0xff >> -shift
;
5096 mask
= (uint8_t)(0xff << shift
);
5102 mask
= 0xffff >> -shift
;
5104 mask
= (uint16_t)(0xffff << shift
);
5108 if (shift
< -31 || shift
> 31) {
5112 mask
= 0xffffffffu
>> -shift
;
5114 mask
= 0xffffffffu
<< shift
;
5120 tmp2
= neon_load_reg(rd
, pass
);
5121 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5122 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5123 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5124 tcg_temp_free_i32(tmp2
);
5126 neon_store_reg(rd
, pass
, tmp
);
5129 } else if (op
< 10) {
5130 /* Shift by immediate and narrow:
5131 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5132 int input_unsigned
= (op
== 8) ? !u
: u
;
5136 shift
= shift
- (1 << (size
+ 3));
5139 tmp64
= tcg_const_i64(shift
);
5140 neon_load_reg64(cpu_V0
, rm
);
5141 neon_load_reg64(cpu_V1
, rm
+ 1);
5142 for (pass
= 0; pass
< 2; pass
++) {
5150 if (input_unsigned
) {
5151 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5153 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5156 if (input_unsigned
) {
5157 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5159 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5162 tmp
= tcg_temp_new_i32();
5163 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5164 neon_store_reg(rd
, pass
, tmp
);
5166 tcg_temp_free_i64(tmp64
);
5169 imm
= (uint16_t)shift
;
5173 imm
= (uint32_t)shift
;
5175 tmp2
= tcg_const_i32(imm
);
5176 tmp4
= neon_load_reg(rm
+ 1, 0);
5177 tmp5
= neon_load_reg(rm
+ 1, 1);
5178 for (pass
= 0; pass
< 2; pass
++) {
5180 tmp
= neon_load_reg(rm
, 0);
5184 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5187 tmp3
= neon_load_reg(rm
, 1);
5191 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5193 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5194 tcg_temp_free_i32(tmp
);
5195 tcg_temp_free_i32(tmp3
);
5196 tmp
= tcg_temp_new_i32();
5197 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5198 neon_store_reg(rd
, pass
, tmp
);
5200 tcg_temp_free_i32(tmp2
);
5202 } else if (op
== 10) {
5204 if (q
|| (rd
& 1)) {
5207 tmp
= neon_load_reg(rm
, 0);
5208 tmp2
= neon_load_reg(rm
, 1);
5209 for (pass
= 0; pass
< 2; pass
++) {
5213 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5216 /* The shift is less than the width of the source
5217 type, so we can just shift the whole register. */
5218 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5219 /* Widen the result of shift: we need to clear
5220 * the potential overflow bits resulting from
5221 * left bits of the narrow input appearing as
5222 * right bits of left the neighbour narrow
5224 if (size
< 2 || !u
) {
5227 imm
= (0xffu
>> (8 - shift
));
5229 } else if (size
== 1) {
5230 imm
= 0xffff >> (16 - shift
);
5233 imm
= 0xffffffff >> (32 - shift
);
5236 imm64
= imm
| (((uint64_t)imm
) << 32);
5240 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5243 neon_store_reg64(cpu_V0
, rd
+ pass
);
5245 } else if (op
>= 14) {
5246 /* VCVT fixed-point. */
5247 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5250 /* We have already masked out the must-be-1 top bit of imm6,
5251 * hence this 32-shift where the ARM ARM has 64-imm6.
5254 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5255 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5258 gen_vfp_ulto(0, shift
, 1);
5260 gen_vfp_slto(0, shift
, 1);
5263 gen_vfp_toul(0, shift
, 1);
5265 gen_vfp_tosl(0, shift
, 1);
5267 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5272 } else { /* (insn & 0x00380080) == 0 */
5274 if (q
&& (rd
& 1)) {
5278 op
= (insn
>> 8) & 0xf;
5279 /* One register and immediate. */
5280 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5281 invert
= (insn
& (1 << 5)) != 0;
5282 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5283 * We choose to not special-case this and will behave as if a
5284 * valid constant encoding of 0 had been given.
5303 imm
= (imm
<< 8) | (imm
<< 24);
5306 imm
= (imm
<< 8) | 0xff;
5309 imm
= (imm
<< 16) | 0xffff;
5312 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5320 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5321 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5327 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5328 if (op
& 1 && op
< 12) {
5329 tmp
= neon_load_reg(rd
, pass
);
5331 /* The immediate value has already been inverted, so
5333 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5335 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5339 tmp
= tcg_temp_new_i32();
5340 if (op
== 14 && invert
) {
5344 for (n
= 0; n
< 4; n
++) {
5345 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5346 val
|= 0xff << (n
* 8);
5348 tcg_gen_movi_i32(tmp
, val
);
5350 tcg_gen_movi_i32(tmp
, imm
);
5353 neon_store_reg(rd
, pass
, tmp
);
5356 } else { /* (insn & 0x00800010 == 0x00800000) */
5358 op
= (insn
>> 8) & 0xf;
5359 if ((insn
& (1 << 6)) == 0) {
5360 /* Three registers of different lengths. */
5364 /* undefreq: bit 0 : UNDEF if size != 0
5365 * bit 1 : UNDEF if size == 0
5366 * bit 2 : UNDEF if U == 1
5367 * Note that [1:0] set implies 'always UNDEF'
5370 /* prewiden, src1_wide, src2_wide, undefreq */
5371 static const int neon_3reg_wide
[16][4] = {
5372 {1, 0, 0, 0}, /* VADDL */
5373 {1, 1, 0, 0}, /* VADDW */
5374 {1, 0, 0, 0}, /* VSUBL */
5375 {1, 1, 0, 0}, /* VSUBW */
5376 {0, 1, 1, 0}, /* VADDHN */
5377 {0, 0, 0, 0}, /* VABAL */
5378 {0, 1, 1, 0}, /* VSUBHN */
5379 {0, 0, 0, 0}, /* VABDL */
5380 {0, 0, 0, 0}, /* VMLAL */
5381 {0, 0, 0, 6}, /* VQDMLAL */
5382 {0, 0, 0, 0}, /* VMLSL */
5383 {0, 0, 0, 6}, /* VQDMLSL */
5384 {0, 0, 0, 0}, /* Integer VMULL */
5385 {0, 0, 0, 2}, /* VQDMULL */
5386 {0, 0, 0, 5}, /* Polynomial VMULL */
5387 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5390 prewiden
= neon_3reg_wide
[op
][0];
5391 src1_wide
= neon_3reg_wide
[op
][1];
5392 src2_wide
= neon_3reg_wide
[op
][2];
5393 undefreq
= neon_3reg_wide
[op
][3];
5395 if (((undefreq
& 1) && (size
!= 0)) ||
5396 ((undefreq
& 2) && (size
== 0)) ||
5397 ((undefreq
& 4) && u
)) {
5400 if ((src1_wide
&& (rn
& 1)) ||
5401 (src2_wide
&& (rm
& 1)) ||
5402 (!src2_wide
&& (rd
& 1))) {
5406 /* Avoid overlapping operands. Wide source operands are
5407 always aligned so will never overlap with wide
5408 destinations in problematic ways. */
5409 if (rd
== rm
&& !src2_wide
) {
5410 tmp
= neon_load_reg(rm
, 1);
5411 neon_store_scratch(2, tmp
);
5412 } else if (rd
== rn
&& !src1_wide
) {
5413 tmp
= neon_load_reg(rn
, 1);
5414 neon_store_scratch(2, tmp
);
5417 for (pass
= 0; pass
< 2; pass
++) {
5419 neon_load_reg64(cpu_V0
, rn
+ pass
);
5422 if (pass
== 1 && rd
== rn
) {
5423 tmp
= neon_load_scratch(2);
5425 tmp
= neon_load_reg(rn
, pass
);
5428 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5432 neon_load_reg64(cpu_V1
, rm
+ pass
);
5435 if (pass
== 1 && rd
== rm
) {
5436 tmp2
= neon_load_scratch(2);
5438 tmp2
= neon_load_reg(rm
, pass
);
5441 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5445 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5446 gen_neon_addl(size
);
5448 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5449 gen_neon_subl(size
);
5451 case 5: case 7: /* VABAL, VABDL */
5452 switch ((size
<< 1) | u
) {
5454 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5457 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5460 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5463 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5466 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5469 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5473 tcg_temp_free_i32(tmp2
);
5474 tcg_temp_free_i32(tmp
);
5476 case 8: case 9: case 10: case 11: case 12: case 13:
5477 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5478 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5480 case 14: /* Polynomial VMULL */
5481 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5482 tcg_temp_free_i32(tmp2
);
5483 tcg_temp_free_i32(tmp
);
5485 default: /* 15 is RESERVED: caught earlier */
5490 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5491 neon_store_reg64(cpu_V0
, rd
+ pass
);
5492 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5494 neon_load_reg64(cpu_V1
, rd
+ pass
);
5496 case 10: /* VMLSL */
5497 gen_neon_negl(cpu_V0
, size
);
5499 case 5: case 8: /* VABAL, VMLAL */
5500 gen_neon_addl(size
);
5502 case 9: case 11: /* VQDMLAL, VQDMLSL */
5503 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5505 gen_neon_negl(cpu_V0
, size
);
5507 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5512 neon_store_reg64(cpu_V0
, rd
+ pass
);
5513 } else if (op
== 4 || op
== 6) {
5514 /* Narrowing operation. */
5515 tmp
= tcg_temp_new_i32();
5519 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5522 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5525 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5526 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5533 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5536 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5539 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5540 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5541 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5549 neon_store_reg(rd
, 0, tmp3
);
5550 neon_store_reg(rd
, 1, tmp
);
5553 /* Write back the result. */
5554 neon_store_reg64(cpu_V0
, rd
+ pass
);
5558 /* Two registers and a scalar. NB that for ops of this form
5559 * the ARM ARM labels bit 24 as Q, but it is in our variable
5566 case 1: /* Float VMLA scalar */
5567 case 5: /* Floating point VMLS scalar */
5568 case 9: /* Floating point VMUL scalar */
5573 case 0: /* Integer VMLA scalar */
5574 case 4: /* Integer VMLS scalar */
5575 case 8: /* Integer VMUL scalar */
5576 case 12: /* VQDMULH scalar */
5577 case 13: /* VQRDMULH scalar */
5578 if (u
&& ((rd
| rn
) & 1)) {
5581 tmp
= neon_get_scalar(size
, rm
);
5582 neon_store_scratch(0, tmp
);
5583 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5584 tmp
= neon_load_scratch(0);
5585 tmp2
= neon_load_reg(rn
, pass
);
5588 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5590 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5592 } else if (op
== 13) {
5594 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5596 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5598 } else if (op
& 1) {
5599 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5600 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5601 tcg_temp_free_ptr(fpstatus
);
5604 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5605 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5606 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5610 tcg_temp_free_i32(tmp2
);
5613 tmp2
= neon_load_reg(rd
, pass
);
5616 gen_neon_add(size
, tmp
, tmp2
);
5620 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5621 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5622 tcg_temp_free_ptr(fpstatus
);
5626 gen_neon_rsb(size
, tmp
, tmp2
);
5630 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5631 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5632 tcg_temp_free_ptr(fpstatus
);
5638 tcg_temp_free_i32(tmp2
);
5640 neon_store_reg(rd
, pass
, tmp
);
5643 case 3: /* VQDMLAL scalar */
5644 case 7: /* VQDMLSL scalar */
5645 case 11: /* VQDMULL scalar */
5650 case 2: /* VMLAL sclar */
5651 case 6: /* VMLSL scalar */
5652 case 10: /* VMULL scalar */
5656 tmp2
= neon_get_scalar(size
, rm
);
5657 /* We need a copy of tmp2 because gen_neon_mull
5658 * deletes it during pass 0. */
5659 tmp4
= tcg_temp_new_i32();
5660 tcg_gen_mov_i32(tmp4
, tmp2
);
5661 tmp3
= neon_load_reg(rn
, 1);
5663 for (pass
= 0; pass
< 2; pass
++) {
5665 tmp
= neon_load_reg(rn
, 0);
5670 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5672 neon_load_reg64(cpu_V1
, rd
+ pass
);
5676 gen_neon_negl(cpu_V0
, size
);
5679 gen_neon_addl(size
);
5682 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5684 gen_neon_negl(cpu_V0
, size
);
5686 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5692 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5697 neon_store_reg64(cpu_V0
, rd
+ pass
);
5702 default: /* 14 and 15 are RESERVED */
5706 } else { /* size == 3 */
5709 imm
= (insn
>> 8) & 0xf;
5714 if (q
&& ((rd
| rn
| rm
) & 1)) {
5719 neon_load_reg64(cpu_V0
, rn
);
5721 neon_load_reg64(cpu_V1
, rn
+ 1);
5723 } else if (imm
== 8) {
5724 neon_load_reg64(cpu_V0
, rn
+ 1);
5726 neon_load_reg64(cpu_V1
, rm
);
5729 tmp64
= tcg_temp_new_i64();
5731 neon_load_reg64(cpu_V0
, rn
);
5732 neon_load_reg64(tmp64
, rn
+ 1);
5734 neon_load_reg64(cpu_V0
, rn
+ 1);
5735 neon_load_reg64(tmp64
, rm
);
5737 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5738 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5739 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5741 neon_load_reg64(cpu_V1
, rm
);
5743 neon_load_reg64(cpu_V1
, rm
+ 1);
5746 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5747 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5748 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5749 tcg_temp_free_i64(tmp64
);
5752 neon_load_reg64(cpu_V0
, rn
);
5753 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5754 neon_load_reg64(cpu_V1
, rm
);
5755 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5756 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5758 neon_store_reg64(cpu_V0
, rd
);
5760 neon_store_reg64(cpu_V1
, rd
+ 1);
5762 } else if ((insn
& (1 << 11)) == 0) {
5763 /* Two register misc. */
5764 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5765 size
= (insn
>> 18) & 3;
5766 /* UNDEF for unknown op values and bad op-size combinations */
5767 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5770 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5771 q
&& ((rm
| rd
) & 1)) {
5775 case NEON_2RM_VREV64
:
5776 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5777 tmp
= neon_load_reg(rm
, pass
* 2);
5778 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5780 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5781 case 1: gen_swap_half(tmp
); break;
5782 case 2: /* no-op */ break;
5785 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5787 neon_store_reg(rd
, pass
* 2, tmp2
);
5790 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5791 case 1: gen_swap_half(tmp2
); break;
5794 neon_store_reg(rd
, pass
* 2, tmp2
);
5798 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5799 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5800 for (pass
= 0; pass
< q
+ 1; pass
++) {
5801 tmp
= neon_load_reg(rm
, pass
* 2);
5802 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5803 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5804 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5806 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5807 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5808 case 2: tcg_gen_add_i64(CPU_V001
); break;
5811 if (op
>= NEON_2RM_VPADAL
) {
5813 neon_load_reg64(cpu_V1
, rd
+ pass
);
5814 gen_neon_addl(size
);
5816 neon_store_reg64(cpu_V0
, rd
+ pass
);
5822 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5823 tmp
= neon_load_reg(rm
, n
);
5824 tmp2
= neon_load_reg(rd
, n
+ 1);
5825 neon_store_reg(rm
, n
, tmp2
);
5826 neon_store_reg(rd
, n
+ 1, tmp
);
5833 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5838 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5842 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
5843 /* also VQMOVUN; op field and mnemonics don't line up */
5848 for (pass
= 0; pass
< 2; pass
++) {
5849 neon_load_reg64(cpu_V0
, rm
+ pass
);
5850 tmp
= tcg_temp_new_i32();
5851 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
5856 neon_store_reg(rd
, 0, tmp2
);
5857 neon_store_reg(rd
, 1, tmp
);
5861 case NEON_2RM_VSHLL
:
5862 if (q
|| (rd
& 1)) {
5865 tmp
= neon_load_reg(rm
, 0);
5866 tmp2
= neon_load_reg(rm
, 1);
5867 for (pass
= 0; pass
< 2; pass
++) {
5870 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5871 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5872 neon_store_reg64(cpu_V0
, rd
+ pass
);
5875 case NEON_2RM_VCVT_F16_F32
:
5876 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5880 tmp
= tcg_temp_new_i32();
5881 tmp2
= tcg_temp_new_i32();
5882 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5883 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5884 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5885 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5886 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5887 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5888 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5889 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5890 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5891 neon_store_reg(rd
, 0, tmp2
);
5892 tmp2
= tcg_temp_new_i32();
5893 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5894 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5895 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5896 neon_store_reg(rd
, 1, tmp2
);
5897 tcg_temp_free_i32(tmp
);
5899 case NEON_2RM_VCVT_F32_F16
:
5900 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5904 tmp3
= tcg_temp_new_i32();
5905 tmp
= neon_load_reg(rm
, 0);
5906 tmp2
= neon_load_reg(rm
, 1);
5907 tcg_gen_ext16u_i32(tmp3
, tmp
);
5908 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5909 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5910 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5911 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5912 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5913 tcg_temp_free_i32(tmp
);
5914 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5915 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5916 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5917 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5918 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5919 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5920 tcg_temp_free_i32(tmp2
);
5921 tcg_temp_free_i32(tmp3
);
5925 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5926 if (neon_2rm_is_float_op(op
)) {
5927 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5928 neon_reg_offset(rm
, pass
));
5931 tmp
= neon_load_reg(rm
, pass
);
5934 case NEON_2RM_VREV32
:
5936 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5937 case 1: gen_swap_half(tmp
); break;
5941 case NEON_2RM_VREV16
:
5946 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
5947 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
5948 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
5954 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
5955 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
5956 case 2: gen_helper_clz(tmp
, tmp
); break;
5961 gen_helper_neon_cnt_u8(tmp
, tmp
);
5964 tcg_gen_not_i32(tmp
, tmp
);
5966 case NEON_2RM_VQABS
:
5969 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
5972 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
5975 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
5980 case NEON_2RM_VQNEG
:
5983 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
5986 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
5989 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
5994 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
5995 tmp2
= tcg_const_i32(0);
5997 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
5998 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
5999 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6002 tcg_temp_free(tmp2
);
6003 if (op
== NEON_2RM_VCLE0
) {
6004 tcg_gen_not_i32(tmp
, tmp
);
6007 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6008 tmp2
= tcg_const_i32(0);
6010 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6011 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6012 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6015 tcg_temp_free(tmp2
);
6016 if (op
== NEON_2RM_VCLT0
) {
6017 tcg_gen_not_i32(tmp
, tmp
);
6020 case NEON_2RM_VCEQ0
:
6021 tmp2
= tcg_const_i32(0);
6023 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6024 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6025 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6028 tcg_temp_free(tmp2
);
6032 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6033 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6034 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6039 tmp2
= tcg_const_i32(0);
6040 gen_neon_rsb(size
, tmp
, tmp2
);
6041 tcg_temp_free(tmp2
);
6043 case NEON_2RM_VCGT0_F
:
6045 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6046 tmp2
= tcg_const_i32(0);
6047 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6048 tcg_temp_free(tmp2
);
6049 tcg_temp_free_ptr(fpstatus
);
6052 case NEON_2RM_VCGE0_F
:
6054 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6055 tmp2
= tcg_const_i32(0);
6056 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6057 tcg_temp_free(tmp2
);
6058 tcg_temp_free_ptr(fpstatus
);
6061 case NEON_2RM_VCEQ0_F
:
6063 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6064 tmp2
= tcg_const_i32(0);
6065 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6066 tcg_temp_free(tmp2
);
6067 tcg_temp_free_ptr(fpstatus
);
6070 case NEON_2RM_VCLE0_F
:
6072 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6073 tmp2
= tcg_const_i32(0);
6074 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6075 tcg_temp_free(tmp2
);
6076 tcg_temp_free_ptr(fpstatus
);
6079 case NEON_2RM_VCLT0_F
:
6081 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6082 tmp2
= tcg_const_i32(0);
6083 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6084 tcg_temp_free(tmp2
);
6085 tcg_temp_free_ptr(fpstatus
);
6088 case NEON_2RM_VABS_F
:
6091 case NEON_2RM_VNEG_F
:
6095 tmp2
= neon_load_reg(rd
, pass
);
6096 neon_store_reg(rm
, pass
, tmp2
);
6099 tmp2
= neon_load_reg(rd
, pass
);
6101 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6102 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6105 neon_store_reg(rm
, pass
, tmp2
);
6107 case NEON_2RM_VRECPE
:
6108 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6110 case NEON_2RM_VRSQRTE
:
6111 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6113 case NEON_2RM_VRECPE_F
:
6114 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6116 case NEON_2RM_VRSQRTE_F
:
6117 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6119 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6122 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6125 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6126 gen_vfp_tosiz(0, 1);
6128 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6129 gen_vfp_touiz(0, 1);
6132 /* Reserved op values were caught by the
6133 * neon_2rm_sizes[] check earlier.
6137 if (neon_2rm_is_float_op(op
)) {
6138 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6139 neon_reg_offset(rd
, pass
));
6141 neon_store_reg(rd
, pass
, tmp
);
6146 } else if ((insn
& (1 << 10)) == 0) {
6148 int n
= ((insn
>> 8) & 3) + 1;
6149 if ((rn
+ n
) > 32) {
6150 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6151 * helper function running off the end of the register file.
6156 if (insn
& (1 << 6)) {
6157 tmp
= neon_load_reg(rd
, 0);
6159 tmp
= tcg_temp_new_i32();
6160 tcg_gen_movi_i32(tmp
, 0);
6162 tmp2
= neon_load_reg(rm
, 0);
6163 tmp4
= tcg_const_i32(rn
);
6164 tmp5
= tcg_const_i32(n
);
6165 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6166 tcg_temp_free_i32(tmp
);
6167 if (insn
& (1 << 6)) {
6168 tmp
= neon_load_reg(rd
, 1);
6170 tmp
= tcg_temp_new_i32();
6171 tcg_gen_movi_i32(tmp
, 0);
6173 tmp3
= neon_load_reg(rm
, 1);
6174 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6175 tcg_temp_free_i32(tmp5
);
6176 tcg_temp_free_i32(tmp4
);
6177 neon_store_reg(rd
, 0, tmp2
);
6178 neon_store_reg(rd
, 1, tmp3
);
6179 tcg_temp_free_i32(tmp
);
6180 } else if ((insn
& 0x380) == 0) {
6182 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6185 if (insn
& (1 << 19)) {
6186 tmp
= neon_load_reg(rm
, 1);
6188 tmp
= neon_load_reg(rm
, 0);
6190 if (insn
& (1 << 16)) {
6191 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6192 } else if (insn
& (1 << 17)) {
6193 if ((insn
>> 18) & 1)
6194 gen_neon_dup_high16(tmp
);
6196 gen_neon_dup_low16(tmp
);
6198 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6199 tmp2
= tcg_temp_new_i32();
6200 tcg_gen_mov_i32(tmp2
, tmp
);
6201 neon_store_reg(rd
, pass
, tmp2
);
6203 tcg_temp_free_i32(tmp
);
6212 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6214 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6215 const ARMCPRegInfo
*ri
;
6216 ARMCPU
*cpu
= arm_env_get_cpu(env
);
6218 cpnum
= (insn
>> 8) & 0xf;
6219 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6220 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6223 /* First check for coprocessor space used for actual instructions */
6227 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6228 return disas_iwmmxt_insn(env
, s
, insn
);
6229 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6230 return disas_dsp_insn(env
, s
, insn
);
6235 return disas_vfp_insn (env
, s
, insn
);
6240 /* Otherwise treat as a generic register access */
6241 is64
= (insn
& (1 << 25)) == 0;
6242 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6250 opc1
= (insn
>> 4) & 0xf;
6252 rt2
= (insn
>> 16) & 0xf;
6254 crn
= (insn
>> 16) & 0xf;
6255 opc1
= (insn
>> 21) & 7;
6256 opc2
= (insn
>> 5) & 7;
6259 isread
= (insn
>> 20) & 1;
6260 rt
= (insn
>> 12) & 0xf;
6262 ri
= get_arm_cp_reginfo(cpu
,
6263 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6265 /* Check access permissions */
6266 if (!cp_access_ok(env
, ri
, isread
)) {
6270 /* Handle special cases first */
6271 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6278 gen_set_pc_im(s
->pc
);
6279 s
->is_jmp
= DISAS_WFI
;
6290 if (ri
->type
& ARM_CP_CONST
) {
6291 tmp64
= tcg_const_i64(ri
->resetvalue
);
6292 } else if (ri
->readfn
) {
6294 gen_set_pc_im(s
->pc
);
6295 tmp64
= tcg_temp_new_i64();
6296 tmpptr
= tcg_const_ptr(ri
);
6297 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6298 tcg_temp_free_ptr(tmpptr
);
6300 tmp64
= tcg_temp_new_i64();
6301 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6303 tmp
= tcg_temp_new_i32();
6304 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6305 store_reg(s
, rt
, tmp
);
6306 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6307 tmp
= tcg_temp_new_i32();
6308 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6309 tcg_temp_free_i64(tmp64
);
6310 store_reg(s
, rt2
, tmp
);
6313 if (ri
->type
& ARM_CP_CONST
) {
6314 tmp
= tcg_const_i32(ri
->resetvalue
);
6315 } else if (ri
->readfn
) {
6317 gen_set_pc_im(s
->pc
);
6318 tmp
= tcg_temp_new_i32();
6319 tmpptr
= tcg_const_ptr(ri
);
6320 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6321 tcg_temp_free_ptr(tmpptr
);
6323 tmp
= load_cpu_offset(ri
->fieldoffset
);
6326 /* Destination register of r15 for 32 bit loads sets
6327 * the condition codes from the high 4 bits of the value
6330 tcg_temp_free_i32(tmp
);
6332 store_reg(s
, rt
, tmp
);
6337 if (ri
->type
& ARM_CP_CONST
) {
6338 /* If not forbidden by access permissions, treat as WI */
6344 TCGv_i64 tmp64
= tcg_temp_new_i64();
6345 tmplo
= load_reg(s
, rt
);
6346 tmphi
= load_reg(s
, rt2
);
6347 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6348 tcg_temp_free_i32(tmplo
);
6349 tcg_temp_free_i32(tmphi
);
6351 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6352 gen_set_pc_im(s
->pc
);
6353 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6354 tcg_temp_free_ptr(tmpptr
);
6356 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6358 tcg_temp_free_i64(tmp64
);
6363 gen_set_pc_im(s
->pc
);
6364 tmp
= load_reg(s
, rt
);
6365 tmpptr
= tcg_const_ptr(ri
);
6366 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6367 tcg_temp_free_ptr(tmpptr
);
6368 tcg_temp_free_i32(tmp
);
6370 TCGv tmp
= load_reg(s
, rt
);
6371 store_cpu_offset(tmp
, ri
->fieldoffset
);
6374 /* We default to ending the TB on a coprocessor register write,
6375 * but allow this to be suppressed by the register definition
6376 * (usually only necessary to work around guest bugs).
6378 if (!(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6389 /* Store a 64-bit value to a register pair. Clobbers val. */
6390 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6393 tmp
= tcg_temp_new_i32();
6394 tcg_gen_trunc_i64_i32(tmp
, val
);
6395 store_reg(s
, rlow
, tmp
);
6396 tmp
= tcg_temp_new_i32();
6397 tcg_gen_shri_i64(val
, val
, 32);
6398 tcg_gen_trunc_i64_i32(tmp
, val
);
6399 store_reg(s
, rhigh
, tmp
);
6402 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6403 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6408 /* Load value and extend to 64 bits. */
6409 tmp
= tcg_temp_new_i64();
6410 tmp2
= load_reg(s
, rlow
);
6411 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6412 tcg_temp_free_i32(tmp2
);
6413 tcg_gen_add_i64(val
, val
, tmp
);
6414 tcg_temp_free_i64(tmp
);
6417 /* load and add a 64-bit value from a register pair. */
6418 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6424 /* Load 64-bit value rd:rn. */
6425 tmpl
= load_reg(s
, rlow
);
6426 tmph
= load_reg(s
, rhigh
);
6427 tmp
= tcg_temp_new_i64();
6428 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6429 tcg_temp_free_i32(tmpl
);
6430 tcg_temp_free_i32(tmph
);
6431 tcg_gen_add_i64(val
, val
, tmp
);
6432 tcg_temp_free_i64(tmp
);
6435 /* Set N and Z flags from hi|lo. */
6436 static void gen_logicq_cc(TCGv lo
, TCGv hi
)
6438 tcg_gen_mov_i32(cpu_NF
, hi
);
6439 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
6442 /* Load/Store exclusive instructions are implemented by remembering
6443 the value/address loaded, and seeing if these are the same
6444 when the store is performed. This should be sufficient to implement
6445 the architecturally mandated semantics, and avoids having to monitor
6448 In system emulation mode only one CPU will be running at once, so
6449 this sequence is effectively atomic. In user emulation mode we
6450 throw an exception and handle the atomic operation elsewhere. */
6451 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6452 TCGv addr
, int size
)
6458 tmp
= gen_ld8u(addr
, IS_USER(s
));
6461 tmp
= gen_ld16u(addr
, IS_USER(s
));
6465 tmp
= gen_ld32(addr
, IS_USER(s
));
6470 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6471 store_reg(s
, rt
, tmp
);
6473 TCGv tmp2
= tcg_temp_new_i32();
6474 tcg_gen_addi_i32(tmp2
, addr
, 4);
6475 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6476 tcg_temp_free_i32(tmp2
);
6477 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6478 store_reg(s
, rt2
, tmp
);
6480 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6483 static void gen_clrex(DisasContext
*s
)
6485 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6488 #ifdef CONFIG_USER_ONLY
6489 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6490 TCGv addr
, int size
)
6492 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6493 tcg_gen_movi_i32(cpu_exclusive_info
,
6494 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6495 gen_exception_insn(s
, 4, EXCP_STREX
);
6498 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6499 TCGv addr
, int size
)
6505 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6511 fail_label
= gen_new_label();
6512 done_label
= gen_new_label();
6513 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6516 tmp
= gen_ld8u(addr
, IS_USER(s
));
6519 tmp
= gen_ld16u(addr
, IS_USER(s
));
6523 tmp
= gen_ld32(addr
, IS_USER(s
));
6528 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6529 tcg_temp_free_i32(tmp
);
6531 TCGv tmp2
= tcg_temp_new_i32();
6532 tcg_gen_addi_i32(tmp2
, addr
, 4);
6533 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6534 tcg_temp_free_i32(tmp2
);
6535 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6536 tcg_temp_free_i32(tmp
);
6538 tmp
= load_reg(s
, rt
);
6541 gen_st8(tmp
, addr
, IS_USER(s
));
6544 gen_st16(tmp
, addr
, IS_USER(s
));
6548 gen_st32(tmp
, addr
, IS_USER(s
));
6554 tcg_gen_addi_i32(addr
, addr
, 4);
6555 tmp
= load_reg(s
, rt2
);
6556 gen_st32(tmp
, addr
, IS_USER(s
));
6558 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6559 tcg_gen_br(done_label
);
6560 gen_set_label(fail_label
);
6561 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6562 gen_set_label(done_label
);
6563 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6567 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6569 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6576 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
6579 /* M variants do not implement ARM mode. */
6584 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6585 * choose to UNDEF. In ARMv5 and above the space is used
6586 * for miscellaneous unconditional instructions.
6590 /* Unconditional instructions. */
6591 if (((insn
>> 25) & 7) == 1) {
6592 /* NEON Data processing. */
6593 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6596 if (disas_neon_data_insn(env
, s
, insn
))
6600 if ((insn
& 0x0f100000) == 0x04000000) {
6601 /* NEON load/store. */
6602 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6605 if (disas_neon_ls_insn(env
, s
, insn
))
6609 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6610 ((insn
& 0x0f30f010) == 0x0710f000)) {
6611 if ((insn
& (1 << 22)) == 0) {
6613 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6617 /* Otherwise PLD; v5TE+ */
6621 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6622 ((insn
& 0x0f70f010) == 0x0650f000)) {
6624 return; /* PLI; V7 */
6626 if (((insn
& 0x0f700000) == 0x04100000) ||
6627 ((insn
& 0x0f700010) == 0x06100000)) {
6628 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6631 return; /* v7MP: Unallocated memory hint: must NOP */
6634 if ((insn
& 0x0ffffdff) == 0x01010000) {
6637 if (((insn
>> 9) & 1) != s
->bswap_code
) {
6638 /* Dynamic endianness switching not implemented. */
6642 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6643 switch ((insn
>> 4) & 0xf) {
6652 /* We don't emulate caches so these are a no-op. */
6657 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6663 op1
= (insn
& 0x1f);
6664 addr
= tcg_temp_new_i32();
6665 tmp
= tcg_const_i32(op1
);
6666 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6667 tcg_temp_free_i32(tmp
);
6668 i
= (insn
>> 23) & 3;
6670 case 0: offset
= -4; break; /* DA */
6671 case 1: offset
= 0; break; /* IA */
6672 case 2: offset
= -8; break; /* DB */
6673 case 3: offset
= 4; break; /* IB */
6677 tcg_gen_addi_i32(addr
, addr
, offset
);
6678 tmp
= load_reg(s
, 14);
6679 gen_st32(tmp
, addr
, 0);
6680 tmp
= load_cpu_field(spsr
);
6681 tcg_gen_addi_i32(addr
, addr
, 4);
6682 gen_st32(tmp
, addr
, 0);
6683 if (insn
& (1 << 21)) {
6684 /* Base writeback. */
6686 case 0: offset
= -8; break;
6687 case 1: offset
= 4; break;
6688 case 2: offset
= -4; break;
6689 case 3: offset
= 0; break;
6693 tcg_gen_addi_i32(addr
, addr
, offset
);
6694 tmp
= tcg_const_i32(op1
);
6695 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6696 tcg_temp_free_i32(tmp
);
6697 tcg_temp_free_i32(addr
);
6699 tcg_temp_free_i32(addr
);
6702 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6708 rn
= (insn
>> 16) & 0xf;
6709 addr
= load_reg(s
, rn
);
6710 i
= (insn
>> 23) & 3;
6712 case 0: offset
= -4; break; /* DA */
6713 case 1: offset
= 0; break; /* IA */
6714 case 2: offset
= -8; break; /* DB */
6715 case 3: offset
= 4; break; /* IB */
6719 tcg_gen_addi_i32(addr
, addr
, offset
);
6720 /* Load PC into tmp and CPSR into tmp2. */
6721 tmp
= gen_ld32(addr
, 0);
6722 tcg_gen_addi_i32(addr
, addr
, 4);
6723 tmp2
= gen_ld32(addr
, 0);
6724 if (insn
& (1 << 21)) {
6725 /* Base writeback. */
6727 case 0: offset
= -8; break;
6728 case 1: offset
= 4; break;
6729 case 2: offset
= -4; break;
6730 case 3: offset
= 0; break;
6734 tcg_gen_addi_i32(addr
, addr
, offset
);
6735 store_reg(s
, rn
, addr
);
6737 tcg_temp_free_i32(addr
);
6739 gen_rfe(s
, tmp
, tmp2
);
6741 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6742 /* branch link and change to thumb (blx <offset>) */
6745 val
= (uint32_t)s
->pc
;
6746 tmp
= tcg_temp_new_i32();
6747 tcg_gen_movi_i32(tmp
, val
);
6748 store_reg(s
, 14, tmp
);
6749 /* Sign-extend the 24-bit offset */
6750 offset
= (((int32_t)insn
) << 8) >> 8;
6751 /* offset * 4 + bit24 * 2 + (thumb bit) */
6752 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6753 /* pipeline offset */
6755 /* protected by ARCH(5); above, near the start of uncond block */
6758 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6759 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6760 /* iWMMXt register transfer. */
6761 if (env
->cp15
.c15_cpar
& (1 << 1))
6762 if (!disas_iwmmxt_insn(env
, s
, insn
))
6765 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6766 /* Coprocessor double register transfer. */
6768 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6769 /* Additional coprocessor register transfer. */
6770 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6773 /* cps (privileged) */
6777 if (insn
& (1 << 19)) {
6778 if (insn
& (1 << 8))
6780 if (insn
& (1 << 7))
6782 if (insn
& (1 << 6))
6784 if (insn
& (1 << 18))
6787 if (insn
& (1 << 17)) {
6789 val
|= (insn
& 0x1f);
6792 gen_set_psr_im(s
, mask
, 0, val
);
6799 /* if not always execute, we generate a conditional jump to
6801 s
->condlabel
= gen_new_label();
6802 gen_test_cc(cond
^ 1, s
->condlabel
);
6805 if ((insn
& 0x0f900000) == 0x03000000) {
6806 if ((insn
& (1 << 21)) == 0) {
6808 rd
= (insn
>> 12) & 0xf;
6809 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6810 if ((insn
& (1 << 22)) == 0) {
6812 tmp
= tcg_temp_new_i32();
6813 tcg_gen_movi_i32(tmp
, val
);
6816 tmp
= load_reg(s
, rd
);
6817 tcg_gen_ext16u_i32(tmp
, tmp
);
6818 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6820 store_reg(s
, rd
, tmp
);
6822 if (((insn
>> 12) & 0xf) != 0xf)
6824 if (((insn
>> 16) & 0xf) == 0) {
6825 gen_nop_hint(s
, insn
& 0xff);
6827 /* CPSR = immediate */
6829 shift
= ((insn
>> 8) & 0xf) * 2;
6831 val
= (val
>> shift
) | (val
<< (32 - shift
));
6832 i
= ((insn
& (1 << 22)) != 0);
6833 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6837 } else if ((insn
& 0x0f900000) == 0x01000000
6838 && (insn
& 0x00000090) != 0x00000090) {
6839 /* miscellaneous instructions */
6840 op1
= (insn
>> 21) & 3;
6841 sh
= (insn
>> 4) & 0xf;
6844 case 0x0: /* move program status register */
6847 tmp
= load_reg(s
, rm
);
6848 i
= ((op1
& 2) != 0);
6849 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6853 rd
= (insn
>> 12) & 0xf;
6857 tmp
= load_cpu_field(spsr
);
6859 tmp
= tcg_temp_new_i32();
6860 gen_helper_cpsr_read(tmp
, cpu_env
);
6862 store_reg(s
, rd
, tmp
);
6867 /* branch/exchange thumb (bx). */
6869 tmp
= load_reg(s
, rm
);
6871 } else if (op1
== 3) {
6874 rd
= (insn
>> 12) & 0xf;
6875 tmp
= load_reg(s
, rm
);
6876 gen_helper_clz(tmp
, tmp
);
6877 store_reg(s
, rd
, tmp
);
6885 /* Trivial implementation equivalent to bx. */
6886 tmp
= load_reg(s
, rm
);
6897 /* branch link/exchange thumb (blx) */
6898 tmp
= load_reg(s
, rm
);
6899 tmp2
= tcg_temp_new_i32();
6900 tcg_gen_movi_i32(tmp2
, s
->pc
);
6901 store_reg(s
, 14, tmp2
);
6904 case 0x5: /* saturating add/subtract */
6906 rd
= (insn
>> 12) & 0xf;
6907 rn
= (insn
>> 16) & 0xf;
6908 tmp
= load_reg(s
, rm
);
6909 tmp2
= load_reg(s
, rn
);
6911 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
6913 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6915 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6916 tcg_temp_free_i32(tmp2
);
6917 store_reg(s
, rd
, tmp
);
6920 /* SMC instruction (op1 == 3)
6921 and undefined instructions (op1 == 0 || op1 == 2)
6928 gen_exception_insn(s
, 4, EXCP_BKPT
);
6930 case 0x8: /* signed multiply */
6935 rs
= (insn
>> 8) & 0xf;
6936 rn
= (insn
>> 12) & 0xf;
6937 rd
= (insn
>> 16) & 0xf;
6939 /* (32 * 16) >> 16 */
6940 tmp
= load_reg(s
, rm
);
6941 tmp2
= load_reg(s
, rs
);
6943 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
6946 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6947 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
6948 tmp
= tcg_temp_new_i32();
6949 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6950 tcg_temp_free_i64(tmp64
);
6951 if ((sh
& 2) == 0) {
6952 tmp2
= load_reg(s
, rn
);
6953 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
6954 tcg_temp_free_i32(tmp2
);
6956 store_reg(s
, rd
, tmp
);
6959 tmp
= load_reg(s
, rm
);
6960 tmp2
= load_reg(s
, rs
);
6961 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
6962 tcg_temp_free_i32(tmp2
);
6964 tmp64
= tcg_temp_new_i64();
6965 tcg_gen_ext_i32_i64(tmp64
, tmp
);
6966 tcg_temp_free_i32(tmp
);
6967 gen_addq(s
, tmp64
, rn
, rd
);
6968 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6969 tcg_temp_free_i64(tmp64
);
6972 tmp2
= load_reg(s
, rn
);
6973 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
6974 tcg_temp_free_i32(tmp2
);
6976 store_reg(s
, rd
, tmp
);
6983 } else if (((insn
& 0x0e000000) == 0 &&
6984 (insn
& 0x00000090) != 0x90) ||
6985 ((insn
& 0x0e000000) == (1 << 25))) {
6986 int set_cc
, logic_cc
, shiftop
;
6988 op1
= (insn
>> 21) & 0xf;
6989 set_cc
= (insn
>> 20) & 1;
6990 logic_cc
= table_logic_cc
[op1
] & set_cc
;
6992 /* data processing instruction */
6993 if (insn
& (1 << 25)) {
6994 /* immediate operand */
6996 shift
= ((insn
>> 8) & 0xf) * 2;
6998 val
= (val
>> shift
) | (val
<< (32 - shift
));
7000 tmp2
= tcg_temp_new_i32();
7001 tcg_gen_movi_i32(tmp2
, val
);
7002 if (logic_cc
&& shift
) {
7003 gen_set_CF_bit31(tmp2
);
7008 tmp2
= load_reg(s
, rm
);
7009 shiftop
= (insn
>> 5) & 3;
7010 if (!(insn
& (1 << 4))) {
7011 shift
= (insn
>> 7) & 0x1f;
7012 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7014 rs
= (insn
>> 8) & 0xf;
7015 tmp
= load_reg(s
, rs
);
7016 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7019 if (op1
!= 0x0f && op1
!= 0x0d) {
7020 rn
= (insn
>> 16) & 0xf;
7021 tmp
= load_reg(s
, rn
);
7025 rd
= (insn
>> 12) & 0xf;
7028 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7032 store_reg_bx(env
, s
, rd
, tmp
);
7035 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7039 store_reg_bx(env
, s
, rd
, tmp
);
7042 if (set_cc
&& rd
== 15) {
7043 /* SUBS r15, ... is used for exception return. */
7047 gen_sub_CC(tmp
, tmp
, tmp2
);
7048 gen_exception_return(s
, tmp
);
7051 gen_sub_CC(tmp
, tmp
, tmp2
);
7053 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7055 store_reg_bx(env
, s
, rd
, tmp
);
7060 gen_sub_CC(tmp
, tmp2
, tmp
);
7062 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7064 store_reg_bx(env
, s
, rd
, tmp
);
7068 gen_add_CC(tmp
, tmp
, tmp2
);
7070 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7072 store_reg_bx(env
, s
, rd
, tmp
);
7076 gen_helper_adc_cc(tmp
, cpu_env
, tmp
, tmp2
);
7078 gen_add_carry(tmp
, tmp
, tmp2
);
7080 store_reg_bx(env
, s
, rd
, tmp
);
7084 gen_helper_sbc_cc(tmp
, cpu_env
, tmp
, tmp2
);
7086 gen_sub_carry(tmp
, tmp
, tmp2
);
7088 store_reg_bx(env
, s
, rd
, tmp
);
7092 gen_helper_sbc_cc(tmp
, cpu_env
, tmp2
, tmp
);
7094 gen_sub_carry(tmp
, tmp2
, tmp
);
7096 store_reg_bx(env
, s
, rd
, tmp
);
7100 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7103 tcg_temp_free_i32(tmp
);
7107 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7110 tcg_temp_free_i32(tmp
);
7114 gen_sub_CC(tmp
, tmp
, tmp2
);
7116 tcg_temp_free_i32(tmp
);
7120 gen_add_CC(tmp
, tmp
, tmp2
);
7122 tcg_temp_free_i32(tmp
);
7125 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7129 store_reg_bx(env
, s
, rd
, tmp
);
7132 if (logic_cc
&& rd
== 15) {
7133 /* MOVS r15, ... is used for exception return. */
7137 gen_exception_return(s
, tmp2
);
7142 store_reg_bx(env
, s
, rd
, tmp2
);
7146 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7150 store_reg_bx(env
, s
, rd
, tmp
);
7154 tcg_gen_not_i32(tmp2
, tmp2
);
7158 store_reg_bx(env
, s
, rd
, tmp2
);
7161 if (op1
!= 0x0f && op1
!= 0x0d) {
7162 tcg_temp_free_i32(tmp2
);
7165 /* other instructions */
7166 op1
= (insn
>> 24) & 0xf;
7170 /* multiplies, extra load/stores */
7171 sh
= (insn
>> 5) & 3;
7174 rd
= (insn
>> 16) & 0xf;
7175 rn
= (insn
>> 12) & 0xf;
7176 rs
= (insn
>> 8) & 0xf;
7178 op1
= (insn
>> 20) & 0xf;
7180 case 0: case 1: case 2: case 3: case 6:
7182 tmp
= load_reg(s
, rs
);
7183 tmp2
= load_reg(s
, rm
);
7184 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7185 tcg_temp_free_i32(tmp2
);
7186 if (insn
& (1 << 22)) {
7187 /* Subtract (mls) */
7189 tmp2
= load_reg(s
, rn
);
7190 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7191 tcg_temp_free_i32(tmp2
);
7192 } else if (insn
& (1 << 21)) {
7194 tmp2
= load_reg(s
, rn
);
7195 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7196 tcg_temp_free_i32(tmp2
);
7198 if (insn
& (1 << 20))
7200 store_reg(s
, rd
, tmp
);
7203 /* 64 bit mul double accumulate (UMAAL) */
7205 tmp
= load_reg(s
, rs
);
7206 tmp2
= load_reg(s
, rm
);
7207 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7208 gen_addq_lo(s
, tmp64
, rn
);
7209 gen_addq_lo(s
, tmp64
, rd
);
7210 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7211 tcg_temp_free_i64(tmp64
);
7213 case 8: case 9: case 10: case 11:
7214 case 12: case 13: case 14: case 15:
7215 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7216 tmp
= load_reg(s
, rs
);
7217 tmp2
= load_reg(s
, rm
);
7218 if (insn
& (1 << 22)) {
7219 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
7221 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
7223 if (insn
& (1 << 21)) { /* mult accumulate */
7224 TCGv al
= load_reg(s
, rn
);
7225 TCGv ah
= load_reg(s
, rd
);
7226 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
7230 if (insn
& (1 << 20)) {
7231 gen_logicq_cc(tmp
, tmp2
);
7233 store_reg(s
, rn
, tmp
);
7234 store_reg(s
, rd
, tmp2
);
7240 rn
= (insn
>> 16) & 0xf;
7241 rd
= (insn
>> 12) & 0xf;
7242 if (insn
& (1 << 23)) {
7243 /* load/store exclusive */
7244 op1
= (insn
>> 21) & 0x3;
7249 addr
= tcg_temp_local_new_i32();
7250 load_reg_var(s
, addr
, rn
);
7251 if (insn
& (1 << 20)) {
7254 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7256 case 1: /* ldrexd */
7257 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7259 case 2: /* ldrexb */
7260 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7262 case 3: /* ldrexh */
7263 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7272 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7274 case 1: /* strexd */
7275 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7277 case 2: /* strexb */
7278 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7280 case 3: /* strexh */
7281 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7287 tcg_temp_free(addr
);
7289 /* SWP instruction */
7292 /* ??? This is not really atomic. However we know
7293 we never have multiple CPUs running in parallel,
7294 so it is good enough. */
7295 addr
= load_reg(s
, rn
);
7296 tmp
= load_reg(s
, rm
);
7297 if (insn
& (1 << 22)) {
7298 tmp2
= gen_ld8u(addr
, IS_USER(s
));
7299 gen_st8(tmp
, addr
, IS_USER(s
));
7301 tmp2
= gen_ld32(addr
, IS_USER(s
));
7302 gen_st32(tmp
, addr
, IS_USER(s
));
7304 tcg_temp_free_i32(addr
);
7305 store_reg(s
, rd
, tmp2
);
7311 /* Misc load/store */
7312 rn
= (insn
>> 16) & 0xf;
7313 rd
= (insn
>> 12) & 0xf;
7314 addr
= load_reg(s
, rn
);
7315 if (insn
& (1 << 24))
7316 gen_add_datah_offset(s
, insn
, 0, addr
);
7318 if (insn
& (1 << 20)) {
7322 tmp
= gen_ld16u(addr
, IS_USER(s
));
7325 tmp
= gen_ld8s(addr
, IS_USER(s
));
7329 tmp
= gen_ld16s(addr
, IS_USER(s
));
7333 } else if (sh
& 2) {
7338 tmp
= load_reg(s
, rd
);
7339 gen_st32(tmp
, addr
, IS_USER(s
));
7340 tcg_gen_addi_i32(addr
, addr
, 4);
7341 tmp
= load_reg(s
, rd
+ 1);
7342 gen_st32(tmp
, addr
, IS_USER(s
));
7346 tmp
= gen_ld32(addr
, IS_USER(s
));
7347 store_reg(s
, rd
, tmp
);
7348 tcg_gen_addi_i32(addr
, addr
, 4);
7349 tmp
= gen_ld32(addr
, IS_USER(s
));
7353 address_offset
= -4;
7356 tmp
= load_reg(s
, rd
);
7357 gen_st16(tmp
, addr
, IS_USER(s
));
7360 /* Perform base writeback before the loaded value to
7361 ensure correct behavior with overlapping index registers.
7362 ldrd with base writeback is is undefined if the
7363 destination and index registers overlap. */
7364 if (!(insn
& (1 << 24))) {
7365 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7366 store_reg(s
, rn
, addr
);
7367 } else if (insn
& (1 << 21)) {
7369 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7370 store_reg(s
, rn
, addr
);
7372 tcg_temp_free_i32(addr
);
7375 /* Complete the load. */
7376 store_reg(s
, rd
, tmp
);
7385 if (insn
& (1 << 4)) {
7387 /* Armv6 Media instructions. */
7389 rn
= (insn
>> 16) & 0xf;
7390 rd
= (insn
>> 12) & 0xf;
7391 rs
= (insn
>> 8) & 0xf;
7392 switch ((insn
>> 23) & 3) {
7393 case 0: /* Parallel add/subtract. */
7394 op1
= (insn
>> 20) & 7;
7395 tmp
= load_reg(s
, rn
);
7396 tmp2
= load_reg(s
, rm
);
7397 sh
= (insn
>> 5) & 7;
7398 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7400 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7401 tcg_temp_free_i32(tmp2
);
7402 store_reg(s
, rd
, tmp
);
7405 if ((insn
& 0x00700020) == 0) {
7406 /* Halfword pack. */
7407 tmp
= load_reg(s
, rn
);
7408 tmp2
= load_reg(s
, rm
);
7409 shift
= (insn
>> 7) & 0x1f;
7410 if (insn
& (1 << 6)) {
7414 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7415 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7416 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7420 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7421 tcg_gen_ext16u_i32(tmp
, tmp
);
7422 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7424 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7425 tcg_temp_free_i32(tmp2
);
7426 store_reg(s
, rd
, tmp
);
7427 } else if ((insn
& 0x00200020) == 0x00200000) {
7429 tmp
= load_reg(s
, rm
);
7430 shift
= (insn
>> 7) & 0x1f;
7431 if (insn
& (1 << 6)) {
7434 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7436 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7438 sh
= (insn
>> 16) & 0x1f;
7439 tmp2
= tcg_const_i32(sh
);
7440 if (insn
& (1 << 22))
7441 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
7443 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
7444 tcg_temp_free_i32(tmp2
);
7445 store_reg(s
, rd
, tmp
);
7446 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7448 tmp
= load_reg(s
, rm
);
7449 sh
= (insn
>> 16) & 0x1f;
7450 tmp2
= tcg_const_i32(sh
);
7451 if (insn
& (1 << 22))
7452 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
7454 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
7455 tcg_temp_free_i32(tmp2
);
7456 store_reg(s
, rd
, tmp
);
7457 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7459 tmp
= load_reg(s
, rn
);
7460 tmp2
= load_reg(s
, rm
);
7461 tmp3
= tcg_temp_new_i32();
7462 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7463 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7464 tcg_temp_free_i32(tmp3
);
7465 tcg_temp_free_i32(tmp2
);
7466 store_reg(s
, rd
, tmp
);
7467 } else if ((insn
& 0x000003e0) == 0x00000060) {
7468 tmp
= load_reg(s
, rm
);
7469 shift
= (insn
>> 10) & 3;
7470 /* ??? In many cases it's not necessary to do a
7471 rotate, a shift is sufficient. */
7473 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7474 op1
= (insn
>> 20) & 7;
7476 case 0: gen_sxtb16(tmp
); break;
7477 case 2: gen_sxtb(tmp
); break;
7478 case 3: gen_sxth(tmp
); break;
7479 case 4: gen_uxtb16(tmp
); break;
7480 case 6: gen_uxtb(tmp
); break;
7481 case 7: gen_uxth(tmp
); break;
7482 default: goto illegal_op
;
7485 tmp2
= load_reg(s
, rn
);
7486 if ((op1
& 3) == 0) {
7487 gen_add16(tmp
, tmp2
);
7489 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7490 tcg_temp_free_i32(tmp2
);
7493 store_reg(s
, rd
, tmp
);
7494 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7496 tmp
= load_reg(s
, rm
);
7497 if (insn
& (1 << 22)) {
7498 if (insn
& (1 << 7)) {
7502 gen_helper_rbit(tmp
, tmp
);
7505 if (insn
& (1 << 7))
7508 tcg_gen_bswap32_i32(tmp
, tmp
);
7510 store_reg(s
, rd
, tmp
);
7515 case 2: /* Multiplies (Type 3). */
7516 switch ((insn
>> 20) & 0x7) {
7518 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7519 /* op2 not 00x or 11x : UNDEF */
7522 /* Signed multiply most significant [accumulate].
7523 (SMMUL, SMMLA, SMMLS) */
7524 tmp
= load_reg(s
, rm
);
7525 tmp2
= load_reg(s
, rs
);
7526 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7529 tmp
= load_reg(s
, rd
);
7530 if (insn
& (1 << 6)) {
7531 tmp64
= gen_subq_msw(tmp64
, tmp
);
7533 tmp64
= gen_addq_msw(tmp64
, tmp
);
7536 if (insn
& (1 << 5)) {
7537 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7539 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7540 tmp
= tcg_temp_new_i32();
7541 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7542 tcg_temp_free_i64(tmp64
);
7543 store_reg(s
, rn
, tmp
);
7547 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7548 if (insn
& (1 << 7)) {
7551 tmp
= load_reg(s
, rm
);
7552 tmp2
= load_reg(s
, rs
);
7553 if (insn
& (1 << 5))
7554 gen_swap_half(tmp2
);
7555 gen_smul_dual(tmp
, tmp2
);
7556 if (insn
& (1 << 6)) {
7557 /* This subtraction cannot overflow. */
7558 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7560 /* This addition cannot overflow 32 bits;
7561 * however it may overflow considered as a signed
7562 * operation, in which case we must set the Q flag.
7564 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7566 tcg_temp_free_i32(tmp2
);
7567 if (insn
& (1 << 22)) {
7568 /* smlald, smlsld */
7569 tmp64
= tcg_temp_new_i64();
7570 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7571 tcg_temp_free_i32(tmp
);
7572 gen_addq(s
, tmp64
, rd
, rn
);
7573 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7574 tcg_temp_free_i64(tmp64
);
7576 /* smuad, smusd, smlad, smlsd */
7579 tmp2
= load_reg(s
, rd
);
7580 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7581 tcg_temp_free_i32(tmp2
);
7583 store_reg(s
, rn
, tmp
);
7589 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7592 if (((insn
>> 5) & 7) || (rd
!= 15)) {
7595 tmp
= load_reg(s
, rm
);
7596 tmp2
= load_reg(s
, rs
);
7597 if (insn
& (1 << 21)) {
7598 gen_helper_udiv(tmp
, tmp
, tmp2
);
7600 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7602 tcg_temp_free_i32(tmp2
);
7603 store_reg(s
, rn
, tmp
);
7610 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7612 case 0: /* Unsigned sum of absolute differences. */
7614 tmp
= load_reg(s
, rm
);
7615 tmp2
= load_reg(s
, rs
);
7616 gen_helper_usad8(tmp
, tmp
, tmp2
);
7617 tcg_temp_free_i32(tmp2
);
7619 tmp2
= load_reg(s
, rd
);
7620 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7621 tcg_temp_free_i32(tmp2
);
7623 store_reg(s
, rn
, tmp
);
7625 case 0x20: case 0x24: case 0x28: case 0x2c:
7626 /* Bitfield insert/clear. */
7628 shift
= (insn
>> 7) & 0x1f;
7629 i
= (insn
>> 16) & 0x1f;
7632 tmp
= tcg_temp_new_i32();
7633 tcg_gen_movi_i32(tmp
, 0);
7635 tmp
= load_reg(s
, rm
);
7638 tmp2
= load_reg(s
, rd
);
7639 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
7640 tcg_temp_free_i32(tmp2
);
7642 store_reg(s
, rd
, tmp
);
7644 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7645 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7647 tmp
= load_reg(s
, rm
);
7648 shift
= (insn
>> 7) & 0x1f;
7649 i
= ((insn
>> 16) & 0x1f) + 1;
7654 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7656 gen_sbfx(tmp
, shift
, i
);
7659 store_reg(s
, rd
, tmp
);
7669 /* Check for undefined extension instructions
7670 * per the ARM Bible IE:
7671 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7673 sh
= (0xf << 20) | (0xf << 4);
7674 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7678 /* load/store byte/word */
7679 rn
= (insn
>> 16) & 0xf;
7680 rd
= (insn
>> 12) & 0xf;
7681 tmp2
= load_reg(s
, rn
);
7682 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7683 if (insn
& (1 << 24))
7684 gen_add_data_offset(s
, insn
, tmp2
);
7685 if (insn
& (1 << 20)) {
7687 if (insn
& (1 << 22)) {
7688 tmp
= gen_ld8u(tmp2
, i
);
7690 tmp
= gen_ld32(tmp2
, i
);
7694 tmp
= load_reg(s
, rd
);
7695 if (insn
& (1 << 22))
7696 gen_st8(tmp
, tmp2
, i
);
7698 gen_st32(tmp
, tmp2
, i
);
7700 if (!(insn
& (1 << 24))) {
7701 gen_add_data_offset(s
, insn
, tmp2
);
7702 store_reg(s
, rn
, tmp2
);
7703 } else if (insn
& (1 << 21)) {
7704 store_reg(s
, rn
, tmp2
);
7706 tcg_temp_free_i32(tmp2
);
7708 if (insn
& (1 << 20)) {
7709 /* Complete the load. */
7710 store_reg_from_load(env
, s
, rd
, tmp
);
7716 int j
, n
, user
, loaded_base
;
7718 /* load/store multiple words */
7719 /* XXX: store correct base if write back */
7721 if (insn
& (1 << 22)) {
7723 goto illegal_op
; /* only usable in supervisor mode */
7725 if ((insn
& (1 << 15)) == 0)
7728 rn
= (insn
>> 16) & 0xf;
7729 addr
= load_reg(s
, rn
);
7731 /* compute total size */
7733 TCGV_UNUSED(loaded_var
);
7736 if (insn
& (1 << i
))
7739 /* XXX: test invalid n == 0 case ? */
7740 if (insn
& (1 << 23)) {
7741 if (insn
& (1 << 24)) {
7743 tcg_gen_addi_i32(addr
, addr
, 4);
7745 /* post increment */
7748 if (insn
& (1 << 24)) {
7750 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7752 /* post decrement */
7754 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7759 if (insn
& (1 << i
)) {
7760 if (insn
& (1 << 20)) {
7762 tmp
= gen_ld32(addr
, IS_USER(s
));
7764 tmp2
= tcg_const_i32(i
);
7765 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
7766 tcg_temp_free_i32(tmp2
);
7767 tcg_temp_free_i32(tmp
);
7768 } else if (i
== rn
) {
7772 store_reg_from_load(env
, s
, i
, tmp
);
7777 /* special case: r15 = PC + 8 */
7778 val
= (long)s
->pc
+ 4;
7779 tmp
= tcg_temp_new_i32();
7780 tcg_gen_movi_i32(tmp
, val
);
7782 tmp
= tcg_temp_new_i32();
7783 tmp2
= tcg_const_i32(i
);
7784 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
7785 tcg_temp_free_i32(tmp2
);
7787 tmp
= load_reg(s
, i
);
7789 gen_st32(tmp
, addr
, IS_USER(s
));
7792 /* no need to add after the last transfer */
7794 tcg_gen_addi_i32(addr
, addr
, 4);
7797 if (insn
& (1 << 21)) {
7799 if (insn
& (1 << 23)) {
7800 if (insn
& (1 << 24)) {
7803 /* post increment */
7804 tcg_gen_addi_i32(addr
, addr
, 4);
7807 if (insn
& (1 << 24)) {
7810 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7812 /* post decrement */
7813 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7816 store_reg(s
, rn
, addr
);
7818 tcg_temp_free_i32(addr
);
7821 store_reg(s
, rn
, loaded_var
);
7823 if ((insn
& (1 << 22)) && !user
) {
7824 /* Restore CPSR from SPSR. */
7825 tmp
= load_cpu_field(spsr
);
7826 gen_set_cpsr(tmp
, 0xffffffff);
7827 tcg_temp_free_i32(tmp
);
7828 s
->is_jmp
= DISAS_UPDATE
;
7837 /* branch (and link) */
7838 val
= (int32_t)s
->pc
;
7839 if (insn
& (1 << 24)) {
7840 tmp
= tcg_temp_new_i32();
7841 tcg_gen_movi_i32(tmp
, val
);
7842 store_reg(s
, 14, tmp
);
7844 offset
= (((int32_t)insn
<< 8) >> 8);
7845 val
+= (offset
<< 2) + 4;
7853 if (disas_coproc_insn(env
, s
, insn
))
7858 gen_set_pc_im(s
->pc
);
7859 s
->is_jmp
= DISAS_SWI
;
7863 gen_exception_insn(s
, 4, EXCP_UDEF
);
7869 /* Return true if this is a Thumb-2 logical op. */
7871 thumb2_logic_op(int op
)
7876 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7877 then set condition code flags based on the result of the operation.
7878 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7879 to the high bit of T1.
7880 Returns zero if the opcode is valid. */
7883 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
7890 tcg_gen_and_i32(t0
, t0
, t1
);
7894 tcg_gen_andc_i32(t0
, t0
, t1
);
7898 tcg_gen_or_i32(t0
, t0
, t1
);
7902 tcg_gen_orc_i32(t0
, t0
, t1
);
7906 tcg_gen_xor_i32(t0
, t0
, t1
);
7911 gen_add_CC(t0
, t0
, t1
);
7913 tcg_gen_add_i32(t0
, t0
, t1
);
7917 gen_helper_adc_cc(t0
, cpu_env
, t0
, t1
);
7923 gen_helper_sbc_cc(t0
, cpu_env
, t0
, t1
);
7925 gen_sub_carry(t0
, t0
, t1
);
7929 gen_sub_CC(t0
, t0
, t1
);
7931 tcg_gen_sub_i32(t0
, t0
, t1
);
7935 gen_sub_CC(t0
, t1
, t0
);
7937 tcg_gen_sub_i32(t0
, t1
, t0
);
7939 default: /* 5, 6, 7, 9, 12, 15. */
7945 gen_set_CF_bit31(t1
);
7950 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7952 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
7954 uint32_t insn
, imm
, shift
, offset
;
7955 uint32_t rd
, rn
, rm
, rs
;
7966 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
7967 || arm_feature (env
, ARM_FEATURE_M
))) {
7968 /* Thumb-1 cores may need to treat bl and blx as a pair of
7969 16-bit instructions to get correct prefetch abort behavior. */
7971 if ((insn
& (1 << 12)) == 0) {
7973 /* Second half of blx. */
7974 offset
= ((insn
& 0x7ff) << 1);
7975 tmp
= load_reg(s
, 14);
7976 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7977 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
7979 tmp2
= tcg_temp_new_i32();
7980 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7981 store_reg(s
, 14, tmp2
);
7985 if (insn
& (1 << 11)) {
7986 /* Second half of bl. */
7987 offset
= ((insn
& 0x7ff) << 1) | 1;
7988 tmp
= load_reg(s
, 14);
7989 tcg_gen_addi_i32(tmp
, tmp
, offset
);
7991 tmp2
= tcg_temp_new_i32();
7992 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
7993 store_reg(s
, 14, tmp2
);
7997 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
7998 /* Instruction spans a page boundary. Implement it as two
7999 16-bit instructions in case the second half causes an
8001 offset
= ((int32_t)insn
<< 21) >> 9;
8002 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8005 /* Fall through to 32-bit decode. */
8008 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8010 insn
|= (uint32_t)insn_hw1
<< 16;
8012 if ((insn
& 0xf800e800) != 0xf000e800) {
8016 rn
= (insn
>> 16) & 0xf;
8017 rs
= (insn
>> 12) & 0xf;
8018 rd
= (insn
>> 8) & 0xf;
8020 switch ((insn
>> 25) & 0xf) {
8021 case 0: case 1: case 2: case 3:
8022 /* 16-bit instructions. Should never happen. */
8025 if (insn
& (1 << 22)) {
8026 /* Other load/store, table branch. */
8027 if (insn
& 0x01200000) {
8028 /* Load/store doubleword. */
8030 addr
= tcg_temp_new_i32();
8031 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8033 addr
= load_reg(s
, rn
);
8035 offset
= (insn
& 0xff) * 4;
8036 if ((insn
& (1 << 23)) == 0)
8038 if (insn
& (1 << 24)) {
8039 tcg_gen_addi_i32(addr
, addr
, offset
);
8042 if (insn
& (1 << 20)) {
8044 tmp
= gen_ld32(addr
, IS_USER(s
));
8045 store_reg(s
, rs
, tmp
);
8046 tcg_gen_addi_i32(addr
, addr
, 4);
8047 tmp
= gen_ld32(addr
, IS_USER(s
));
8048 store_reg(s
, rd
, tmp
);
8051 tmp
= load_reg(s
, rs
);
8052 gen_st32(tmp
, addr
, IS_USER(s
));
8053 tcg_gen_addi_i32(addr
, addr
, 4);
8054 tmp
= load_reg(s
, rd
);
8055 gen_st32(tmp
, addr
, IS_USER(s
));
8057 if (insn
& (1 << 21)) {
8058 /* Base writeback. */
8061 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8062 store_reg(s
, rn
, addr
);
8064 tcg_temp_free_i32(addr
);
8066 } else if ((insn
& (1 << 23)) == 0) {
8067 /* Load/store exclusive word. */
8068 addr
= tcg_temp_local_new();
8069 load_reg_var(s
, addr
, rn
);
8070 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8071 if (insn
& (1 << 20)) {
8072 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8074 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8076 tcg_temp_free(addr
);
8077 } else if ((insn
& (1 << 6)) == 0) {
8080 addr
= tcg_temp_new_i32();
8081 tcg_gen_movi_i32(addr
, s
->pc
);
8083 addr
= load_reg(s
, rn
);
8085 tmp
= load_reg(s
, rm
);
8086 tcg_gen_add_i32(addr
, addr
, tmp
);
8087 if (insn
& (1 << 4)) {
8089 tcg_gen_add_i32(addr
, addr
, tmp
);
8090 tcg_temp_free_i32(tmp
);
8091 tmp
= gen_ld16u(addr
, IS_USER(s
));
8093 tcg_temp_free_i32(tmp
);
8094 tmp
= gen_ld8u(addr
, IS_USER(s
));
8096 tcg_temp_free_i32(addr
);
8097 tcg_gen_shli_i32(tmp
, tmp
, 1);
8098 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8099 store_reg(s
, 15, tmp
);
8101 /* Load/store exclusive byte/halfword/doubleword. */
8103 op
= (insn
>> 4) & 0x3;
8107 addr
= tcg_temp_local_new();
8108 load_reg_var(s
, addr
, rn
);
8109 if (insn
& (1 << 20)) {
8110 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8112 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8114 tcg_temp_free(addr
);
8117 /* Load/store multiple, RFE, SRS. */
8118 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8119 /* Not available in user mode. */
8122 if (insn
& (1 << 20)) {
8124 addr
= load_reg(s
, rn
);
8125 if ((insn
& (1 << 24)) == 0)
8126 tcg_gen_addi_i32(addr
, addr
, -8);
8127 /* Load PC into tmp and CPSR into tmp2. */
8128 tmp
= gen_ld32(addr
, 0);
8129 tcg_gen_addi_i32(addr
, addr
, 4);
8130 tmp2
= gen_ld32(addr
, 0);
8131 if (insn
& (1 << 21)) {
8132 /* Base writeback. */
8133 if (insn
& (1 << 24)) {
8134 tcg_gen_addi_i32(addr
, addr
, 4);
8136 tcg_gen_addi_i32(addr
, addr
, -4);
8138 store_reg(s
, rn
, addr
);
8140 tcg_temp_free_i32(addr
);
8142 gen_rfe(s
, tmp
, tmp2
);
8146 addr
= tcg_temp_new_i32();
8147 tmp
= tcg_const_i32(op
);
8148 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8149 tcg_temp_free_i32(tmp
);
8150 if ((insn
& (1 << 24)) == 0) {
8151 tcg_gen_addi_i32(addr
, addr
, -8);
8153 tmp
= load_reg(s
, 14);
8154 gen_st32(tmp
, addr
, 0);
8155 tcg_gen_addi_i32(addr
, addr
, 4);
8156 tmp
= tcg_temp_new_i32();
8157 gen_helper_cpsr_read(tmp
, cpu_env
);
8158 gen_st32(tmp
, addr
, 0);
8159 if (insn
& (1 << 21)) {
8160 if ((insn
& (1 << 24)) == 0) {
8161 tcg_gen_addi_i32(addr
, addr
, -4);
8163 tcg_gen_addi_i32(addr
, addr
, 4);
8165 tmp
= tcg_const_i32(op
);
8166 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8167 tcg_temp_free_i32(tmp
);
8169 tcg_temp_free_i32(addr
);
8173 int i
, loaded_base
= 0;
8175 /* Load/store multiple. */
8176 addr
= load_reg(s
, rn
);
8178 for (i
= 0; i
< 16; i
++) {
8179 if (insn
& (1 << i
))
8182 if (insn
& (1 << 24)) {
8183 tcg_gen_addi_i32(addr
, addr
, -offset
);
8186 TCGV_UNUSED(loaded_var
);
8187 for (i
= 0; i
< 16; i
++) {
8188 if ((insn
& (1 << i
)) == 0)
8190 if (insn
& (1 << 20)) {
8192 tmp
= gen_ld32(addr
, IS_USER(s
));
8195 } else if (i
== rn
) {
8199 store_reg(s
, i
, tmp
);
8203 tmp
= load_reg(s
, i
);
8204 gen_st32(tmp
, addr
, IS_USER(s
));
8206 tcg_gen_addi_i32(addr
, addr
, 4);
8209 store_reg(s
, rn
, loaded_var
);
8211 if (insn
& (1 << 21)) {
8212 /* Base register writeback. */
8213 if (insn
& (1 << 24)) {
8214 tcg_gen_addi_i32(addr
, addr
, -offset
);
8216 /* Fault if writeback register is in register list. */
8217 if (insn
& (1 << rn
))
8219 store_reg(s
, rn
, addr
);
8221 tcg_temp_free_i32(addr
);
8228 op
= (insn
>> 21) & 0xf;
8230 /* Halfword pack. */
8231 tmp
= load_reg(s
, rn
);
8232 tmp2
= load_reg(s
, rm
);
8233 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8234 if (insn
& (1 << 5)) {
8238 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8239 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8240 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8244 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8245 tcg_gen_ext16u_i32(tmp
, tmp
);
8246 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8248 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8249 tcg_temp_free_i32(tmp2
);
8250 store_reg(s
, rd
, tmp
);
8252 /* Data processing register constant shift. */
8254 tmp
= tcg_temp_new_i32();
8255 tcg_gen_movi_i32(tmp
, 0);
8257 tmp
= load_reg(s
, rn
);
8259 tmp2
= load_reg(s
, rm
);
8261 shiftop
= (insn
>> 4) & 3;
8262 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8263 conds
= (insn
& (1 << 20)) != 0;
8264 logic_cc
= (conds
&& thumb2_logic_op(op
));
8265 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8266 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8268 tcg_temp_free_i32(tmp2
);
8270 store_reg(s
, rd
, tmp
);
8272 tcg_temp_free_i32(tmp
);
8276 case 13: /* Misc data processing. */
8277 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8278 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8281 case 0: /* Register controlled shift. */
8282 tmp
= load_reg(s
, rn
);
8283 tmp2
= load_reg(s
, rm
);
8284 if ((insn
& 0x70) != 0)
8286 op
= (insn
>> 21) & 3;
8287 logic_cc
= (insn
& (1 << 20)) != 0;
8288 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8291 store_reg_bx(env
, s
, rd
, tmp
);
8293 case 1: /* Sign/zero extend. */
8294 tmp
= load_reg(s
, rm
);
8295 shift
= (insn
>> 4) & 3;
8296 /* ??? In many cases it's not necessary to do a
8297 rotate, a shift is sufficient. */
8299 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8300 op
= (insn
>> 20) & 7;
8302 case 0: gen_sxth(tmp
); break;
8303 case 1: gen_uxth(tmp
); break;
8304 case 2: gen_sxtb16(tmp
); break;
8305 case 3: gen_uxtb16(tmp
); break;
8306 case 4: gen_sxtb(tmp
); break;
8307 case 5: gen_uxtb(tmp
); break;
8308 default: goto illegal_op
;
8311 tmp2
= load_reg(s
, rn
);
8312 if ((op
>> 1) == 1) {
8313 gen_add16(tmp
, tmp2
);
8315 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8316 tcg_temp_free_i32(tmp2
);
8319 store_reg(s
, rd
, tmp
);
8321 case 2: /* SIMD add/subtract. */
8322 op
= (insn
>> 20) & 7;
8323 shift
= (insn
>> 4) & 7;
8324 if ((op
& 3) == 3 || (shift
& 3) == 3)
8326 tmp
= load_reg(s
, rn
);
8327 tmp2
= load_reg(s
, rm
);
8328 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8329 tcg_temp_free_i32(tmp2
);
8330 store_reg(s
, rd
, tmp
);
8332 case 3: /* Other data processing. */
8333 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8335 /* Saturating add/subtract. */
8336 tmp
= load_reg(s
, rn
);
8337 tmp2
= load_reg(s
, rm
);
8339 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
8341 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
8343 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8344 tcg_temp_free_i32(tmp2
);
8346 tmp
= load_reg(s
, rn
);
8348 case 0x0a: /* rbit */
8349 gen_helper_rbit(tmp
, tmp
);
8351 case 0x08: /* rev */
8352 tcg_gen_bswap32_i32(tmp
, tmp
);
8354 case 0x09: /* rev16 */
8357 case 0x0b: /* revsh */
8360 case 0x10: /* sel */
8361 tmp2
= load_reg(s
, rm
);
8362 tmp3
= tcg_temp_new_i32();
8363 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8364 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8365 tcg_temp_free_i32(tmp3
);
8366 tcg_temp_free_i32(tmp2
);
8368 case 0x18: /* clz */
8369 gen_helper_clz(tmp
, tmp
);
8375 store_reg(s
, rd
, tmp
);
8377 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8378 op
= (insn
>> 4) & 0xf;
8379 tmp
= load_reg(s
, rn
);
8380 tmp2
= load_reg(s
, rm
);
8381 switch ((insn
>> 20) & 7) {
8382 case 0: /* 32 x 32 -> 32 */
8383 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8384 tcg_temp_free_i32(tmp2
);
8386 tmp2
= load_reg(s
, rs
);
8388 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8390 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8391 tcg_temp_free_i32(tmp2
);
8394 case 1: /* 16 x 16 -> 32 */
8395 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8396 tcg_temp_free_i32(tmp2
);
8398 tmp2
= load_reg(s
, rs
);
8399 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8400 tcg_temp_free_i32(tmp2
);
8403 case 2: /* Dual multiply add. */
8404 case 4: /* Dual multiply subtract. */
8406 gen_swap_half(tmp2
);
8407 gen_smul_dual(tmp
, tmp2
);
8408 if (insn
& (1 << 22)) {
8409 /* This subtraction cannot overflow. */
8410 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8412 /* This addition cannot overflow 32 bits;
8413 * however it may overflow considered as a signed
8414 * operation, in which case we must set the Q flag.
8416 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8418 tcg_temp_free_i32(tmp2
);
8421 tmp2
= load_reg(s
, rs
);
8422 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8423 tcg_temp_free_i32(tmp2
);
8426 case 3: /* 32 * 16 -> 32msb */
8428 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8431 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8432 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8433 tmp
= tcg_temp_new_i32();
8434 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8435 tcg_temp_free_i64(tmp64
);
8438 tmp2
= load_reg(s
, rs
);
8439 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8440 tcg_temp_free_i32(tmp2
);
8443 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8444 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8446 tmp
= load_reg(s
, rs
);
8447 if (insn
& (1 << 20)) {
8448 tmp64
= gen_addq_msw(tmp64
, tmp
);
8450 tmp64
= gen_subq_msw(tmp64
, tmp
);
8453 if (insn
& (1 << 4)) {
8454 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8456 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8457 tmp
= tcg_temp_new_i32();
8458 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8459 tcg_temp_free_i64(tmp64
);
8461 case 7: /* Unsigned sum of absolute differences. */
8462 gen_helper_usad8(tmp
, tmp
, tmp2
);
8463 tcg_temp_free_i32(tmp2
);
8465 tmp2
= load_reg(s
, rs
);
8466 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8467 tcg_temp_free_i32(tmp2
);
8471 store_reg(s
, rd
, tmp
);
8473 case 6: case 7: /* 64-bit multiply, Divide. */
8474 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8475 tmp
= load_reg(s
, rn
);
8476 tmp2
= load_reg(s
, rm
);
8477 if ((op
& 0x50) == 0x10) {
8479 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8483 gen_helper_udiv(tmp
, tmp
, tmp2
);
8485 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8486 tcg_temp_free_i32(tmp2
);
8487 store_reg(s
, rd
, tmp
);
8488 } else if ((op
& 0xe) == 0xc) {
8489 /* Dual multiply accumulate long. */
8491 gen_swap_half(tmp2
);
8492 gen_smul_dual(tmp
, tmp2
);
8494 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8496 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8498 tcg_temp_free_i32(tmp2
);
8500 tmp64
= tcg_temp_new_i64();
8501 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8502 tcg_temp_free_i32(tmp
);
8503 gen_addq(s
, tmp64
, rs
, rd
);
8504 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8505 tcg_temp_free_i64(tmp64
);
8508 /* Unsigned 64-bit multiply */
8509 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8513 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8514 tcg_temp_free_i32(tmp2
);
8515 tmp64
= tcg_temp_new_i64();
8516 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8517 tcg_temp_free_i32(tmp
);
8519 /* Signed 64-bit multiply */
8520 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8525 gen_addq_lo(s
, tmp64
, rs
);
8526 gen_addq_lo(s
, tmp64
, rd
);
8527 } else if (op
& 0x40) {
8528 /* 64-bit accumulate. */
8529 gen_addq(s
, tmp64
, rs
, rd
);
8531 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8532 tcg_temp_free_i64(tmp64
);
8537 case 6: case 7: case 14: case 15:
8539 if (((insn
>> 24) & 3) == 3) {
8540 /* Translate into the equivalent ARM encoding. */
8541 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8542 if (disas_neon_data_insn(env
, s
, insn
))
8545 if (insn
& (1 << 28))
8547 if (disas_coproc_insn (env
, s
, insn
))
8551 case 8: case 9: case 10: case 11:
8552 if (insn
& (1 << 15)) {
8553 /* Branches, misc control. */
8554 if (insn
& 0x5000) {
8555 /* Unconditional branch. */
8556 /* signextend(hw1[10:0]) -> offset[:12]. */
8557 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8558 /* hw1[10:0] -> offset[11:1]. */
8559 offset
|= (insn
& 0x7ff) << 1;
8560 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8561 offset[24:22] already have the same value because of the
8562 sign extension above. */
8563 offset
^= ((~insn
) & (1 << 13)) << 10;
8564 offset
^= ((~insn
) & (1 << 11)) << 11;
8566 if (insn
& (1 << 14)) {
8567 /* Branch and link. */
8568 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8572 if (insn
& (1 << 12)) {
8577 offset
&= ~(uint32_t)2;
8578 /* thumb2 bx, no need to check */
8579 gen_bx_im(s
, offset
);
8581 } else if (((insn
>> 23) & 7) == 7) {
8583 if (insn
& (1 << 13))
8586 if (insn
& (1 << 26)) {
8587 /* Secure monitor call (v6Z) */
8588 goto illegal_op
; /* not implemented. */
8590 op
= (insn
>> 20) & 7;
8592 case 0: /* msr cpsr. */
8594 tmp
= load_reg(s
, rn
);
8595 addr
= tcg_const_i32(insn
& 0xff);
8596 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8597 tcg_temp_free_i32(addr
);
8598 tcg_temp_free_i32(tmp
);
8603 case 1: /* msr spsr. */
8606 tmp
= load_reg(s
, rn
);
8608 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8612 case 2: /* cps, nop-hint. */
8613 if (((insn
>> 8) & 7) == 0) {
8614 gen_nop_hint(s
, insn
& 0xff);
8616 /* Implemented as NOP in user mode. */
8621 if (insn
& (1 << 10)) {
8622 if (insn
& (1 << 7))
8624 if (insn
& (1 << 6))
8626 if (insn
& (1 << 5))
8628 if (insn
& (1 << 9))
8629 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8631 if (insn
& (1 << 8)) {
8633 imm
|= (insn
& 0x1f);
8636 gen_set_psr_im(s
, offset
, 0, imm
);
8639 case 3: /* Special control operations. */
8641 op
= (insn
>> 4) & 0xf;
8649 /* These execute as NOPs. */
8656 /* Trivial implementation equivalent to bx. */
8657 tmp
= load_reg(s
, rn
);
8660 case 5: /* Exception return. */
8664 if (rn
!= 14 || rd
!= 15) {
8667 tmp
= load_reg(s
, rn
);
8668 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8669 gen_exception_return(s
, tmp
);
8671 case 6: /* mrs cpsr. */
8672 tmp
= tcg_temp_new_i32();
8674 addr
= tcg_const_i32(insn
& 0xff);
8675 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8676 tcg_temp_free_i32(addr
);
8678 gen_helper_cpsr_read(tmp
, cpu_env
);
8680 store_reg(s
, rd
, tmp
);
8682 case 7: /* mrs spsr. */
8683 /* Not accessible in user mode. */
8684 if (IS_USER(s
) || IS_M(env
))
8686 tmp
= load_cpu_field(spsr
);
8687 store_reg(s
, rd
, tmp
);
8692 /* Conditional branch. */
8693 op
= (insn
>> 22) & 0xf;
8694 /* Generate a conditional jump to next instruction. */
8695 s
->condlabel
= gen_new_label();
8696 gen_test_cc(op
^ 1, s
->condlabel
);
8699 /* offset[11:1] = insn[10:0] */
8700 offset
= (insn
& 0x7ff) << 1;
8701 /* offset[17:12] = insn[21:16]. */
8702 offset
|= (insn
& 0x003f0000) >> 4;
8703 /* offset[31:20] = insn[26]. */
8704 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8705 /* offset[18] = insn[13]. */
8706 offset
|= (insn
& (1 << 13)) << 5;
8707 /* offset[19] = insn[11]. */
8708 offset
|= (insn
& (1 << 11)) << 8;
8710 /* jump to the offset */
8711 gen_jmp(s
, s
->pc
+ offset
);
8714 /* Data processing immediate. */
8715 if (insn
& (1 << 25)) {
8716 if (insn
& (1 << 24)) {
8717 if (insn
& (1 << 20))
8719 /* Bitfield/Saturate. */
8720 op
= (insn
>> 21) & 7;
8722 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8724 tmp
= tcg_temp_new_i32();
8725 tcg_gen_movi_i32(tmp
, 0);
8727 tmp
= load_reg(s
, rn
);
8730 case 2: /* Signed bitfield extract. */
8732 if (shift
+ imm
> 32)
8735 gen_sbfx(tmp
, shift
, imm
);
8737 case 6: /* Unsigned bitfield extract. */
8739 if (shift
+ imm
> 32)
8742 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8744 case 3: /* Bitfield insert/clear. */
8747 imm
= imm
+ 1 - shift
;
8749 tmp2
= load_reg(s
, rd
);
8750 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
8751 tcg_temp_free_i32(tmp2
);
8756 default: /* Saturate. */
8759 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8761 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8763 tmp2
= tcg_const_i32(imm
);
8766 if ((op
& 1) && shift
== 0)
8767 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8769 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8772 if ((op
& 1) && shift
== 0)
8773 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8775 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8777 tcg_temp_free_i32(tmp2
);
8780 store_reg(s
, rd
, tmp
);
8782 imm
= ((insn
& 0x04000000) >> 15)
8783 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8784 if (insn
& (1 << 22)) {
8785 /* 16-bit immediate. */
8786 imm
|= (insn
>> 4) & 0xf000;
8787 if (insn
& (1 << 23)) {
8789 tmp
= load_reg(s
, rd
);
8790 tcg_gen_ext16u_i32(tmp
, tmp
);
8791 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8794 tmp
= tcg_temp_new_i32();
8795 tcg_gen_movi_i32(tmp
, imm
);
8798 /* Add/sub 12-bit immediate. */
8800 offset
= s
->pc
& ~(uint32_t)3;
8801 if (insn
& (1 << 23))
8805 tmp
= tcg_temp_new_i32();
8806 tcg_gen_movi_i32(tmp
, offset
);
8808 tmp
= load_reg(s
, rn
);
8809 if (insn
& (1 << 23))
8810 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8812 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8815 store_reg(s
, rd
, tmp
);
8818 int shifter_out
= 0;
8819 /* modified 12-bit immediate. */
8820 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8821 imm
= (insn
& 0xff);
8824 /* Nothing to do. */
8826 case 1: /* 00XY00XY */
8829 case 2: /* XY00XY00 */
8833 case 3: /* XYXYXYXY */
8837 default: /* Rotated constant. */
8838 shift
= (shift
<< 1) | (imm
>> 7);
8840 imm
= imm
<< (32 - shift
);
8844 tmp2
= tcg_temp_new_i32();
8845 tcg_gen_movi_i32(tmp2
, imm
);
8846 rn
= (insn
>> 16) & 0xf;
8848 tmp
= tcg_temp_new_i32();
8849 tcg_gen_movi_i32(tmp
, 0);
8851 tmp
= load_reg(s
, rn
);
8853 op
= (insn
>> 21) & 0xf;
8854 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8855 shifter_out
, tmp
, tmp2
))
8857 tcg_temp_free_i32(tmp2
);
8858 rd
= (insn
>> 8) & 0xf;
8860 store_reg(s
, rd
, tmp
);
8862 tcg_temp_free_i32(tmp
);
8867 case 12: /* Load/store single data item. */
8872 if ((insn
& 0x01100000) == 0x01000000) {
8873 if (disas_neon_ls_insn(env
, s
, insn
))
8877 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8879 if (!(insn
& (1 << 20))) {
8883 /* Byte or halfword load space with dest == r15 : memory hints.
8884 * Catch them early so we don't emit pointless addressing code.
8885 * This space is a mix of:
8886 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8887 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8889 * unallocated hints, which must be treated as NOPs
8890 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8891 * which is easiest for the decoding logic
8892 * Some space which must UNDEF
8894 int op1
= (insn
>> 23) & 3;
8895 int op2
= (insn
>> 6) & 0x3f;
8900 /* UNPREDICTABLE, unallocated hint or
8901 * PLD/PLDW/PLI (literal)
8906 return 0; /* PLD/PLDW/PLI or unallocated hint */
8908 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
8909 return 0; /* PLD/PLDW/PLI or unallocated hint */
8911 /* UNDEF space, or an UNPREDICTABLE */
8917 addr
= tcg_temp_new_i32();
8919 /* s->pc has already been incremented by 4. */
8920 imm
= s
->pc
& 0xfffffffc;
8921 if (insn
& (1 << 23))
8922 imm
+= insn
& 0xfff;
8924 imm
-= insn
& 0xfff;
8925 tcg_gen_movi_i32(addr
, imm
);
8927 addr
= load_reg(s
, rn
);
8928 if (insn
& (1 << 23)) {
8929 /* Positive offset. */
8931 tcg_gen_addi_i32(addr
, addr
, imm
);
8934 switch ((insn
>> 8) & 0xf) {
8935 case 0x0: /* Shifted Register. */
8936 shift
= (insn
>> 4) & 0xf;
8938 tcg_temp_free_i32(addr
);
8941 tmp
= load_reg(s
, rm
);
8943 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8944 tcg_gen_add_i32(addr
, addr
, tmp
);
8945 tcg_temp_free_i32(tmp
);
8947 case 0xc: /* Negative offset. */
8948 tcg_gen_addi_i32(addr
, addr
, -imm
);
8950 case 0xe: /* User privilege. */
8951 tcg_gen_addi_i32(addr
, addr
, imm
);
8954 case 0x9: /* Post-decrement. */
8957 case 0xb: /* Post-increment. */
8961 case 0xd: /* Pre-decrement. */
8964 case 0xf: /* Pre-increment. */
8965 tcg_gen_addi_i32(addr
, addr
, imm
);
8969 tcg_temp_free_i32(addr
);
8974 if (insn
& (1 << 20)) {
8977 case 0: tmp
= gen_ld8u(addr
, user
); break;
8978 case 4: tmp
= gen_ld8s(addr
, user
); break;
8979 case 1: tmp
= gen_ld16u(addr
, user
); break;
8980 case 5: tmp
= gen_ld16s(addr
, user
); break;
8981 case 2: tmp
= gen_ld32(addr
, user
); break;
8983 tcg_temp_free_i32(addr
);
8989 store_reg(s
, rs
, tmp
);
8993 tmp
= load_reg(s
, rs
);
8995 case 0: gen_st8(tmp
, addr
, user
); break;
8996 case 1: gen_st16(tmp
, addr
, user
); break;
8997 case 2: gen_st32(tmp
, addr
, user
); break;
8999 tcg_temp_free_i32(addr
);
9004 tcg_gen_addi_i32(addr
, addr
, imm
);
9006 store_reg(s
, rn
, addr
);
9008 tcg_temp_free_i32(addr
);
9020 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9022 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9029 if (s
->condexec_mask
) {
9030 cond
= s
->condexec_cond
;
9031 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9032 s
->condlabel
= gen_new_label();
9033 gen_test_cc(cond
^ 1, s
->condlabel
);
9038 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9041 switch (insn
>> 12) {
9045 op
= (insn
>> 11) & 3;
9048 rn
= (insn
>> 3) & 7;
9049 tmp
= load_reg(s
, rn
);
9050 if (insn
& (1 << 10)) {
9052 tmp2
= tcg_temp_new_i32();
9053 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9056 rm
= (insn
>> 6) & 7;
9057 tmp2
= load_reg(s
, rm
);
9059 if (insn
& (1 << 9)) {
9060 if (s
->condexec_mask
)
9061 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9063 gen_sub_CC(tmp
, tmp
, tmp2
);
9065 if (s
->condexec_mask
)
9066 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9068 gen_add_CC(tmp
, tmp
, tmp2
);
9070 tcg_temp_free_i32(tmp2
);
9071 store_reg(s
, rd
, tmp
);
9073 /* shift immediate */
9074 rm
= (insn
>> 3) & 7;
9075 shift
= (insn
>> 6) & 0x1f;
9076 tmp
= load_reg(s
, rm
);
9077 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9078 if (!s
->condexec_mask
)
9080 store_reg(s
, rd
, tmp
);
9084 /* arithmetic large immediate */
9085 op
= (insn
>> 11) & 3;
9086 rd
= (insn
>> 8) & 0x7;
9087 if (op
== 0) { /* mov */
9088 tmp
= tcg_temp_new_i32();
9089 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9090 if (!s
->condexec_mask
)
9092 store_reg(s
, rd
, tmp
);
9094 tmp
= load_reg(s
, rd
);
9095 tmp2
= tcg_temp_new_i32();
9096 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9099 gen_sub_CC(tmp
, tmp
, tmp2
);
9100 tcg_temp_free_i32(tmp
);
9101 tcg_temp_free_i32(tmp2
);
9104 if (s
->condexec_mask
)
9105 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9107 gen_add_CC(tmp
, tmp
, tmp2
);
9108 tcg_temp_free_i32(tmp2
);
9109 store_reg(s
, rd
, tmp
);
9112 if (s
->condexec_mask
)
9113 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9115 gen_sub_CC(tmp
, tmp
, tmp2
);
9116 tcg_temp_free_i32(tmp2
);
9117 store_reg(s
, rd
, tmp
);
9123 if (insn
& (1 << 11)) {
9124 rd
= (insn
>> 8) & 7;
9125 /* load pc-relative. Bit 1 of PC is ignored. */
9126 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9127 val
&= ~(uint32_t)2;
9128 addr
= tcg_temp_new_i32();
9129 tcg_gen_movi_i32(addr
, val
);
9130 tmp
= gen_ld32(addr
, IS_USER(s
));
9131 tcg_temp_free_i32(addr
);
9132 store_reg(s
, rd
, tmp
);
9135 if (insn
& (1 << 10)) {
9136 /* data processing extended or blx */
9137 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9138 rm
= (insn
>> 3) & 0xf;
9139 op
= (insn
>> 8) & 3;
9142 tmp
= load_reg(s
, rd
);
9143 tmp2
= load_reg(s
, rm
);
9144 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9145 tcg_temp_free_i32(tmp2
);
9146 store_reg(s
, rd
, tmp
);
9149 tmp
= load_reg(s
, rd
);
9150 tmp2
= load_reg(s
, rm
);
9151 gen_sub_CC(tmp
, tmp
, tmp2
);
9152 tcg_temp_free_i32(tmp2
);
9153 tcg_temp_free_i32(tmp
);
9155 case 2: /* mov/cpy */
9156 tmp
= load_reg(s
, rm
);
9157 store_reg(s
, rd
, tmp
);
9159 case 3:/* branch [and link] exchange thumb register */
9160 tmp
= load_reg(s
, rm
);
9161 if (insn
& (1 << 7)) {
9163 val
= (uint32_t)s
->pc
| 1;
9164 tmp2
= tcg_temp_new_i32();
9165 tcg_gen_movi_i32(tmp2
, val
);
9166 store_reg(s
, 14, tmp2
);
9168 /* already thumb, no need to check */
9175 /* data processing register */
9177 rm
= (insn
>> 3) & 7;
9178 op
= (insn
>> 6) & 0xf;
9179 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9180 /* the shift/rotate ops want the operands backwards */
9189 if (op
== 9) { /* neg */
9190 tmp
= tcg_temp_new_i32();
9191 tcg_gen_movi_i32(tmp
, 0);
9192 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9193 tmp
= load_reg(s
, rd
);
9198 tmp2
= load_reg(s
, rm
);
9201 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9202 if (!s
->condexec_mask
)
9206 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9207 if (!s
->condexec_mask
)
9211 if (s
->condexec_mask
) {
9212 gen_shl(tmp2
, tmp2
, tmp
);
9214 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9219 if (s
->condexec_mask
) {
9220 gen_shr(tmp2
, tmp2
, tmp
);
9222 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9227 if (s
->condexec_mask
) {
9228 gen_sar(tmp2
, tmp2
, tmp
);
9230 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9235 if (s
->condexec_mask
)
9238 gen_helper_adc_cc(tmp
, cpu_env
, tmp
, tmp2
);
9241 if (s
->condexec_mask
)
9242 gen_sub_carry(tmp
, tmp
, tmp2
);
9244 gen_helper_sbc_cc(tmp
, cpu_env
, tmp
, tmp2
);
9247 if (s
->condexec_mask
) {
9248 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9249 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9251 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9256 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9261 if (s
->condexec_mask
)
9262 tcg_gen_neg_i32(tmp
, tmp2
);
9264 gen_sub_CC(tmp
, tmp
, tmp2
);
9267 gen_sub_CC(tmp
, tmp
, tmp2
);
9271 gen_add_CC(tmp
, tmp
, tmp2
);
9275 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9276 if (!s
->condexec_mask
)
9280 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9281 if (!s
->condexec_mask
)
9285 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9286 if (!s
->condexec_mask
)
9290 tcg_gen_not_i32(tmp2
, tmp2
);
9291 if (!s
->condexec_mask
)
9299 store_reg(s
, rm
, tmp2
);
9301 tcg_temp_free_i32(tmp
);
9303 store_reg(s
, rd
, tmp
);
9304 tcg_temp_free_i32(tmp2
);
9307 tcg_temp_free_i32(tmp
);
9308 tcg_temp_free_i32(tmp2
);
9313 /* load/store register offset. */
9315 rn
= (insn
>> 3) & 7;
9316 rm
= (insn
>> 6) & 7;
9317 op
= (insn
>> 9) & 7;
9318 addr
= load_reg(s
, rn
);
9319 tmp
= load_reg(s
, rm
);
9320 tcg_gen_add_i32(addr
, addr
, tmp
);
9321 tcg_temp_free_i32(tmp
);
9323 if (op
< 3) /* store */
9324 tmp
= load_reg(s
, rd
);
9328 gen_st32(tmp
, addr
, IS_USER(s
));
9331 gen_st16(tmp
, addr
, IS_USER(s
));
9334 gen_st8(tmp
, addr
, IS_USER(s
));
9337 tmp
= gen_ld8s(addr
, IS_USER(s
));
9340 tmp
= gen_ld32(addr
, IS_USER(s
));
9343 tmp
= gen_ld16u(addr
, IS_USER(s
));
9346 tmp
= gen_ld8u(addr
, IS_USER(s
));
9349 tmp
= gen_ld16s(addr
, IS_USER(s
));
9352 if (op
>= 3) /* load */
9353 store_reg(s
, rd
, tmp
);
9354 tcg_temp_free_i32(addr
);
9358 /* load/store word immediate offset */
9360 rn
= (insn
>> 3) & 7;
9361 addr
= load_reg(s
, rn
);
9362 val
= (insn
>> 4) & 0x7c;
9363 tcg_gen_addi_i32(addr
, addr
, val
);
9365 if (insn
& (1 << 11)) {
9367 tmp
= gen_ld32(addr
, IS_USER(s
));
9368 store_reg(s
, rd
, tmp
);
9371 tmp
= load_reg(s
, rd
);
9372 gen_st32(tmp
, addr
, IS_USER(s
));
9374 tcg_temp_free_i32(addr
);
9378 /* load/store byte immediate offset */
9380 rn
= (insn
>> 3) & 7;
9381 addr
= load_reg(s
, rn
);
9382 val
= (insn
>> 6) & 0x1f;
9383 tcg_gen_addi_i32(addr
, addr
, val
);
9385 if (insn
& (1 << 11)) {
9387 tmp
= gen_ld8u(addr
, IS_USER(s
));
9388 store_reg(s
, rd
, tmp
);
9391 tmp
= load_reg(s
, rd
);
9392 gen_st8(tmp
, addr
, IS_USER(s
));
9394 tcg_temp_free_i32(addr
);
9398 /* load/store halfword immediate offset */
9400 rn
= (insn
>> 3) & 7;
9401 addr
= load_reg(s
, rn
);
9402 val
= (insn
>> 5) & 0x3e;
9403 tcg_gen_addi_i32(addr
, addr
, val
);
9405 if (insn
& (1 << 11)) {
9407 tmp
= gen_ld16u(addr
, IS_USER(s
));
9408 store_reg(s
, rd
, tmp
);
9411 tmp
= load_reg(s
, rd
);
9412 gen_st16(tmp
, addr
, IS_USER(s
));
9414 tcg_temp_free_i32(addr
);
9418 /* load/store from stack */
9419 rd
= (insn
>> 8) & 7;
9420 addr
= load_reg(s
, 13);
9421 val
= (insn
& 0xff) * 4;
9422 tcg_gen_addi_i32(addr
, addr
, val
);
9424 if (insn
& (1 << 11)) {
9426 tmp
= gen_ld32(addr
, IS_USER(s
));
9427 store_reg(s
, rd
, tmp
);
9430 tmp
= load_reg(s
, rd
);
9431 gen_st32(tmp
, addr
, IS_USER(s
));
9433 tcg_temp_free_i32(addr
);
9437 /* add to high reg */
9438 rd
= (insn
>> 8) & 7;
9439 if (insn
& (1 << 11)) {
9441 tmp
= load_reg(s
, 13);
9443 /* PC. bit 1 is ignored. */
9444 tmp
= tcg_temp_new_i32();
9445 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9447 val
= (insn
& 0xff) * 4;
9448 tcg_gen_addi_i32(tmp
, tmp
, val
);
9449 store_reg(s
, rd
, tmp
);
9454 op
= (insn
>> 8) & 0xf;
9457 /* adjust stack pointer */
9458 tmp
= load_reg(s
, 13);
9459 val
= (insn
& 0x7f) * 4;
9460 if (insn
& (1 << 7))
9461 val
= -(int32_t)val
;
9462 tcg_gen_addi_i32(tmp
, tmp
, val
);
9463 store_reg(s
, 13, tmp
);
9466 case 2: /* sign/zero extend. */
9469 rm
= (insn
>> 3) & 7;
9470 tmp
= load_reg(s
, rm
);
9471 switch ((insn
>> 6) & 3) {
9472 case 0: gen_sxth(tmp
); break;
9473 case 1: gen_sxtb(tmp
); break;
9474 case 2: gen_uxth(tmp
); break;
9475 case 3: gen_uxtb(tmp
); break;
9477 store_reg(s
, rd
, tmp
);
9479 case 4: case 5: case 0xc: case 0xd:
9481 addr
= load_reg(s
, 13);
9482 if (insn
& (1 << 8))
9486 for (i
= 0; i
< 8; i
++) {
9487 if (insn
& (1 << i
))
9490 if ((insn
& (1 << 11)) == 0) {
9491 tcg_gen_addi_i32(addr
, addr
, -offset
);
9493 for (i
= 0; i
< 8; i
++) {
9494 if (insn
& (1 << i
)) {
9495 if (insn
& (1 << 11)) {
9497 tmp
= gen_ld32(addr
, IS_USER(s
));
9498 store_reg(s
, i
, tmp
);
9501 tmp
= load_reg(s
, i
);
9502 gen_st32(tmp
, addr
, IS_USER(s
));
9504 /* advance to the next address. */
9505 tcg_gen_addi_i32(addr
, addr
, 4);
9509 if (insn
& (1 << 8)) {
9510 if (insn
& (1 << 11)) {
9512 tmp
= gen_ld32(addr
, IS_USER(s
));
9513 /* don't set the pc until the rest of the instruction
9517 tmp
= load_reg(s
, 14);
9518 gen_st32(tmp
, addr
, IS_USER(s
));
9520 tcg_gen_addi_i32(addr
, addr
, 4);
9522 if ((insn
& (1 << 11)) == 0) {
9523 tcg_gen_addi_i32(addr
, addr
, -offset
);
9525 /* write back the new stack pointer */
9526 store_reg(s
, 13, addr
);
9527 /* set the new PC value */
9528 if ((insn
& 0x0900) == 0x0900) {
9529 store_reg_from_load(env
, s
, 15, tmp
);
9533 case 1: case 3: case 9: case 11: /* czb */
9535 tmp
= load_reg(s
, rm
);
9536 s
->condlabel
= gen_new_label();
9538 if (insn
& (1 << 11))
9539 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9541 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9542 tcg_temp_free_i32(tmp
);
9543 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9544 val
= (uint32_t)s
->pc
+ 2;
9549 case 15: /* IT, nop-hint. */
9550 if ((insn
& 0xf) == 0) {
9551 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9555 s
->condexec_cond
= (insn
>> 4) & 0xe;
9556 s
->condexec_mask
= insn
& 0x1f;
9557 /* No actual code generated for this insn, just setup state. */
9560 case 0xe: /* bkpt */
9562 gen_exception_insn(s
, 2, EXCP_BKPT
);
9567 rn
= (insn
>> 3) & 0x7;
9569 tmp
= load_reg(s
, rn
);
9570 switch ((insn
>> 6) & 3) {
9571 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9572 case 1: gen_rev16(tmp
); break;
9573 case 3: gen_revsh(tmp
); break;
9574 default: goto illegal_op
;
9576 store_reg(s
, rd
, tmp
);
9580 switch ((insn
>> 5) & 7) {
9584 if (((insn
>> 3) & 1) != s
->bswap_code
) {
9585 /* Dynamic endianness switching not implemented. */
9596 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9599 addr
= tcg_const_i32(19);
9600 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9601 tcg_temp_free_i32(addr
);
9605 addr
= tcg_const_i32(16);
9606 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9607 tcg_temp_free_i32(addr
);
9609 tcg_temp_free_i32(tmp
);
9612 if (insn
& (1 << 4)) {
9613 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9617 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9632 /* load/store multiple */
9634 TCGV_UNUSED(loaded_var
);
9635 rn
= (insn
>> 8) & 0x7;
9636 addr
= load_reg(s
, rn
);
9637 for (i
= 0; i
< 8; i
++) {
9638 if (insn
& (1 << i
)) {
9639 if (insn
& (1 << 11)) {
9641 tmp
= gen_ld32(addr
, IS_USER(s
));
9645 store_reg(s
, i
, tmp
);
9649 tmp
= load_reg(s
, i
);
9650 gen_st32(tmp
, addr
, IS_USER(s
));
9652 /* advance to the next address */
9653 tcg_gen_addi_i32(addr
, addr
, 4);
9656 if ((insn
& (1 << rn
)) == 0) {
9657 /* base reg not in list: base register writeback */
9658 store_reg(s
, rn
, addr
);
9660 /* base reg in list: if load, complete it now */
9661 if (insn
& (1 << 11)) {
9662 store_reg(s
, rn
, loaded_var
);
9664 tcg_temp_free_i32(addr
);
9669 /* conditional branch or swi */
9670 cond
= (insn
>> 8) & 0xf;
9676 gen_set_pc_im(s
->pc
);
9677 s
->is_jmp
= DISAS_SWI
;
9680 /* generate a conditional jump to next instruction */
9681 s
->condlabel
= gen_new_label();
9682 gen_test_cc(cond
^ 1, s
->condlabel
);
9685 /* jump to the offset */
9686 val
= (uint32_t)s
->pc
+ 2;
9687 offset
= ((int32_t)insn
<< 24) >> 24;
9693 if (insn
& (1 << 11)) {
9694 if (disas_thumb2_insn(env
, s
, insn
))
9698 /* unconditional branch */
9699 val
= (uint32_t)s
->pc
;
9700 offset
= ((int32_t)insn
<< 21) >> 21;
9701 val
+= (offset
<< 1) + 2;
9706 if (disas_thumb2_insn(env
, s
, insn
))
9712 gen_exception_insn(s
, 4, EXCP_UDEF
);
9716 gen_exception_insn(s
, 2, EXCP_UDEF
);
9719 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9720 basic block 'tb'. If search_pc is TRUE, also generate PC
9721 information for each intermediate instruction. */
9722 static inline void gen_intermediate_code_internal(CPUARMState
*env
,
9723 TranslationBlock
*tb
,
9726 DisasContext dc1
, *dc
= &dc1
;
9728 uint16_t *gen_opc_end
;
9730 target_ulong pc_start
;
9731 uint32_t next_page_start
;
9735 /* generate intermediate code */
9740 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
9742 dc
->is_jmp
= DISAS_NEXT
;
9744 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9746 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9747 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
9748 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9749 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9750 #if !defined(CONFIG_USER_ONLY)
9751 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9753 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9754 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9755 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9756 cpu_F0s
= tcg_temp_new_i32();
9757 cpu_F1s
= tcg_temp_new_i32();
9758 cpu_F0d
= tcg_temp_new_i64();
9759 cpu_F1d
= tcg_temp_new_i64();
9762 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9763 cpu_M0
= tcg_temp_new_i64();
9764 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9767 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9769 max_insns
= CF_COUNT_MASK
;
9773 tcg_clear_temp_count();
9775 /* A note on handling of the condexec (IT) bits:
9777 * We want to avoid the overhead of having to write the updated condexec
9778 * bits back to the CPUARMState for every instruction in an IT block. So:
9779 * (1) if the condexec bits are not already zero then we write
9780 * zero back into the CPUARMState now. This avoids complications trying
9781 * to do it at the end of the block. (For example if we don't do this
9782 * it's hard to identify whether we can safely skip writing condexec
9783 * at the end of the TB, which we definitely want to do for the case
9784 * where a TB doesn't do anything with the IT state at all.)
9785 * (2) if we are going to leave the TB then we call gen_set_condexec()
9786 * which will write the correct value into CPUARMState if zero is wrong.
9787 * This is done both for leaving the TB at the end, and for leaving
9788 * it because of an exception we know will happen, which is done in
9789 * gen_exception_insn(). The latter is necessary because we need to
9790 * leave the TB with the PC/IT state just prior to execution of the
9791 * instruction which caused the exception.
9792 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9793 * then the CPUARMState will be wrong and we need to reset it.
9794 * This is handled in the same way as restoration of the
9795 * PC in these situations: we will be called again with search_pc=1
9796 * and generate a mapping of the condexec bits for each PC in
9797 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9798 * this to restore the condexec bits.
9800 * Note that there are no instructions which can read the condexec
9801 * bits, and none which can write non-static values to them, so
9802 * we don't need to care about whether CPUARMState is correct in the
9806 /* Reset the conditional execution bits immediately. This avoids
9807 complications trying to do it at the end of the block. */
9808 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9810 TCGv tmp
= tcg_temp_new_i32();
9811 tcg_gen_movi_i32(tmp
, 0);
9812 store_cpu_field(tmp
, condexec_bits
);
9815 #ifdef CONFIG_USER_ONLY
9816 /* Intercept jump to the magic kernel page. */
9817 if (dc
->pc
>= 0xffff0000) {
9818 /* We always get here via a jump, so know we are not in a
9819 conditional execution block. */
9820 gen_exception(EXCP_KERNEL_TRAP
);
9821 dc
->is_jmp
= DISAS_UPDATE
;
9825 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9826 /* We always get here via a jump, so know we are not in a
9827 conditional execution block. */
9828 gen_exception(EXCP_EXCEPTION_EXIT
);
9829 dc
->is_jmp
= DISAS_UPDATE
;
9834 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9835 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9836 if (bp
->pc
== dc
->pc
) {
9837 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9838 /* Advance PC so that clearing the breakpoint will
9839 invalidate this TB. */
9841 goto done_generating
;
9847 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
9851 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
9853 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
9854 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9855 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
9856 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
9859 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9862 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
9863 tcg_gen_debug_insn_start(dc
->pc
);
9867 disas_thumb_insn(env
, dc
);
9868 if (dc
->condexec_mask
) {
9869 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9870 | ((dc
->condexec_mask
>> 4) & 1);
9871 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9872 if (dc
->condexec_mask
== 0) {
9873 dc
->condexec_cond
= 0;
9877 disas_arm_insn(env
, dc
);
9880 if (dc
->condjmp
&& !dc
->is_jmp
) {
9881 gen_set_label(dc
->condlabel
);
9885 if (tcg_check_temp_count()) {
9886 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
9889 /* Translation stops when a conditional branch is encountered.
9890 * Otherwise the subsequent code could get translated several times.
9891 * Also stop translation when a page boundary is reached. This
9892 * ensures prefetch aborts occur at the right place. */
9894 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
9895 !env
->singlestep_enabled
&&
9897 dc
->pc
< next_page_start
&&
9898 num_insns
< max_insns
);
9900 if (tb
->cflags
& CF_LAST_IO
) {
9902 /* FIXME: This can theoretically happen with self-modifying
9904 cpu_abort(env
, "IO on conditional branch instruction");
9909 /* At this stage dc->condjmp will only be set when the skipped
9910 instruction was a conditional branch or trap, and the PC has
9911 already been written. */
9912 if (unlikely(env
->singlestep_enabled
)) {
9913 /* Make sure the pc is updated, and raise a debug exception. */
9915 gen_set_condexec(dc
);
9916 if (dc
->is_jmp
== DISAS_SWI
) {
9917 gen_exception(EXCP_SWI
);
9919 gen_exception(EXCP_DEBUG
);
9921 gen_set_label(dc
->condlabel
);
9923 if (dc
->condjmp
|| !dc
->is_jmp
) {
9924 gen_set_pc_im(dc
->pc
);
9927 gen_set_condexec(dc
);
9928 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
9929 gen_exception(EXCP_SWI
);
9931 /* FIXME: Single stepping a WFI insn will not halt
9933 gen_exception(EXCP_DEBUG
);
9936 /* While branches must always occur at the end of an IT block,
9937 there are a few other things that can cause us to terminate
9938 the TB in the middle of an IT block:
9939 - Exception generating instructions (bkpt, swi, undefined).
9941 - Hardware watchpoints.
9942 Hardware breakpoints have already been handled and skip this code.
9944 gen_set_condexec(dc
);
9945 switch(dc
->is_jmp
) {
9947 gen_goto_tb(dc
, 1, dc
->pc
);
9952 /* indicate that the hash table must be used to find the next TB */
9956 /* nothing more to generate */
9959 gen_helper_wfi(cpu_env
);
9962 gen_exception(EXCP_SWI
);
9966 gen_set_label(dc
->condlabel
);
9967 gen_set_condexec(dc
);
9968 gen_goto_tb(dc
, 1, dc
->pc
);
9974 gen_icount_end(tb
, num_insns
);
9975 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
9978 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
9979 qemu_log("----------------\n");
9980 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
9981 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
9982 dc
->thumb
| (dc
->bswap_code
<< 1));
9987 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
9990 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
9992 tb
->size
= dc
->pc
- pc_start
;
9993 tb
->icount
= num_insns
;
9997 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
9999 gen_intermediate_code_internal(env
, tb
, 0);
10002 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10004 gen_intermediate_code_internal(env
, tb
, 1);
10007 static const char *cpu_mode_names
[16] = {
10008 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10009 "???", "???", "???", "und", "???", "???", "???", "sys"
10012 void cpu_dump_state(CPUARMState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
10018 for(i
=0;i
<16;i
++) {
10019 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10021 cpu_fprintf(f
, "\n");
10023 cpu_fprintf(f
, " ");
10025 psr
= cpsr_read(env
);
10026 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10028 psr
& (1 << 31) ? 'N' : '-',
10029 psr
& (1 << 30) ? 'Z' : '-',
10030 psr
& (1 << 29) ? 'C' : '-',
10031 psr
& (1 << 28) ? 'V' : '-',
10032 psr
& CPSR_T
? 'T' : 'A',
10033 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10035 if (flags
& CPU_DUMP_FPU
) {
10036 int numvfpregs
= 0;
10037 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10040 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10043 for (i
= 0; i
< numvfpregs
; i
++) {
10044 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10045 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10046 i
* 2, (uint32_t)v
,
10047 i
* 2 + 1, (uint32_t)(v
>> 32),
10050 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10054 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10056 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10057 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];