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 + CF. Compute C, N, V and Z flags */
425 static void gen_adc_CC(TCGv dest
, TCGv t0
, TCGv t1
)
427 TCGv tmp
= tcg_temp_new_i32();
428 if (TCG_TARGET_HAS_add2_i32
) {
429 tcg_gen_movi_i32(tmp
, 0);
430 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
431 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, cpu_CF
, t1
, tmp
);
433 TCGv_i64 q0
= tcg_temp_new_i64();
434 TCGv_i64 q1
= tcg_temp_new_i64();
435 tcg_gen_extu_i32_i64(q0
, t0
);
436 tcg_gen_extu_i32_i64(q1
, t1
);
437 tcg_gen_add_i64(q0
, q0
, q1
);
438 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
439 tcg_gen_add_i64(q0
, q0
, q1
);
440 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
441 tcg_temp_free_i64(q0
);
442 tcg_temp_free_i64(q1
);
444 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
445 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
446 tcg_gen_xor_i32(tmp
, t0
, t1
);
447 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
448 tcg_temp_free_i32(tmp
);
449 tcg_gen_mov_i32(dest
, cpu_NF
);
452 /* dest = T0 - T1. Compute C, N, V and Z flags */
453 static void gen_sub_CC(TCGv dest
, TCGv t0
, TCGv t1
)
456 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
457 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
458 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
459 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
460 tmp
= tcg_temp_new_i32();
461 tcg_gen_xor_i32(tmp
, t0
, t1
);
462 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
463 tcg_temp_free_i32(tmp
);
464 tcg_gen_mov_i32(dest
, cpu_NF
);
467 #define GEN_SHIFT(name) \
468 static void gen_##name(TCGv dest, TCGv t0, TCGv t1) \
470 TCGv tmp1, tmp2, tmp3; \
471 tmp1 = tcg_temp_new_i32(); \
472 tcg_gen_andi_i32(tmp1, t1, 0xff); \
473 tmp2 = tcg_const_i32(0); \
474 tmp3 = tcg_const_i32(0x1f); \
475 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
476 tcg_temp_free_i32(tmp3); \
477 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
478 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
479 tcg_temp_free_i32(tmp2); \
480 tcg_temp_free_i32(tmp1); \
486 static void gen_sar(TCGv dest
, TCGv t0
, TCGv t1
)
489 tmp1
= tcg_temp_new_i32();
490 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
491 tmp2
= tcg_const_i32(0x1f);
492 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
493 tcg_temp_free_i32(tmp2
);
494 tcg_gen_sar_i32(dest
, t0
, tmp1
);
495 tcg_temp_free_i32(tmp1
);
498 static void tcg_gen_abs_i32(TCGv dest
, TCGv src
)
500 TCGv c0
= tcg_const_i32(0);
501 TCGv tmp
= tcg_temp_new_i32();
502 tcg_gen_neg_i32(tmp
, src
);
503 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
504 tcg_temp_free_i32(c0
);
505 tcg_temp_free_i32(tmp
);
508 static void shifter_out_im(TCGv var
, int shift
)
511 tcg_gen_andi_i32(cpu_CF
, var
, 1);
513 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
515 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
520 /* Shift by immediate. Includes special handling for shift == 0. */
521 static inline void gen_arm_shift_im(TCGv var
, int shiftop
, int shift
, int flags
)
527 shifter_out_im(var
, 32 - shift
);
528 tcg_gen_shli_i32(var
, var
, shift
);
534 tcg_gen_shri_i32(cpu_CF
, var
, 31);
536 tcg_gen_movi_i32(var
, 0);
539 shifter_out_im(var
, shift
- 1);
540 tcg_gen_shri_i32(var
, var
, shift
);
547 shifter_out_im(var
, shift
- 1);
550 tcg_gen_sari_i32(var
, var
, shift
);
552 case 3: /* ROR/RRX */
555 shifter_out_im(var
, shift
- 1);
556 tcg_gen_rotri_i32(var
, var
, shift
); break;
558 TCGv tmp
= tcg_temp_new_i32();
559 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
561 shifter_out_im(var
, 0);
562 tcg_gen_shri_i32(var
, var
, 1);
563 tcg_gen_or_i32(var
, var
, tmp
);
564 tcg_temp_free_i32(tmp
);
569 static inline void gen_arm_shift_reg(TCGv var
, int shiftop
,
570 TCGv shift
, int flags
)
574 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
575 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
576 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
577 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
582 gen_shl(var
, var
, shift
);
585 gen_shr(var
, var
, shift
);
588 gen_sar(var
, var
, shift
);
590 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
591 tcg_gen_rotr_i32(var
, var
, shift
); break;
594 tcg_temp_free_i32(shift
);
597 #define PAS_OP(pfx) \
599 case 0: gen_pas_helper(glue(pfx,add16)); break; \
600 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
601 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
602 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
603 case 4: gen_pas_helper(glue(pfx,add8)); break; \
604 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
606 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
611 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
613 tmp
= tcg_temp_new_ptr();
614 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
616 tcg_temp_free_ptr(tmp
);
619 tmp
= tcg_temp_new_ptr();
620 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
622 tcg_temp_free_ptr(tmp
);
624 #undef gen_pas_helper
625 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
638 #undef gen_pas_helper
643 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
644 #define PAS_OP(pfx) \
646 case 0: gen_pas_helper(glue(pfx,add8)); break; \
647 case 1: gen_pas_helper(glue(pfx,add16)); break; \
648 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
649 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
650 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
651 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
653 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
658 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
660 tmp
= tcg_temp_new_ptr();
661 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
663 tcg_temp_free_ptr(tmp
);
666 tmp
= tcg_temp_new_ptr();
667 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
669 tcg_temp_free_ptr(tmp
);
671 #undef gen_pas_helper
672 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
685 #undef gen_pas_helper
690 static void gen_test_cc(int cc
, int label
)
697 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
700 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
703 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
706 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
709 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
712 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
715 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
718 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
720 case 8: /* hi: C && !Z */
721 inv
= gen_new_label();
722 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
723 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
726 case 9: /* ls: !C || Z */
727 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
728 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
730 case 10: /* ge: N == V -> N ^ V == 0 */
731 tmp
= tcg_temp_new_i32();
732 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
733 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
734 tcg_temp_free_i32(tmp
);
736 case 11: /* lt: N != V -> N ^ V != 0 */
737 tmp
= tcg_temp_new_i32();
738 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
739 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
740 tcg_temp_free_i32(tmp
);
742 case 12: /* gt: !Z && N == V */
743 inv
= gen_new_label();
744 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
745 tmp
= tcg_temp_new_i32();
746 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
747 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
748 tcg_temp_free_i32(tmp
);
751 case 13: /* le: Z || N != V */
752 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
753 tmp
= tcg_temp_new_i32();
754 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
755 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
756 tcg_temp_free_i32(tmp
);
759 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
764 static const uint8_t table_logic_cc
[16] = {
783 /* Set PC and Thumb state from an immediate address. */
784 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
788 s
->is_jmp
= DISAS_UPDATE
;
789 if (s
->thumb
!= (addr
& 1)) {
790 tmp
= tcg_temp_new_i32();
791 tcg_gen_movi_i32(tmp
, addr
& 1);
792 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
793 tcg_temp_free_i32(tmp
);
795 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
798 /* Set PC and Thumb state from var. var is marked as dead. */
799 static inline void gen_bx(DisasContext
*s
, TCGv var
)
801 s
->is_jmp
= DISAS_UPDATE
;
802 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
803 tcg_gen_andi_i32(var
, var
, 1);
804 store_cpu_field(var
, thumb
);
807 /* Variant of store_reg which uses branch&exchange logic when storing
808 to r15 in ARM architecture v7 and above. The source must be a temporary
809 and will be marked as dead. */
810 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
813 if (reg
== 15 && ENABLE_ARCH_7
) {
816 store_reg(s
, reg
, var
);
820 /* Variant of store_reg which uses branch&exchange logic when storing
821 * to r15 in ARM architecture v5T and above. This is used for storing
822 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
823 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
824 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
827 if (reg
== 15 && ENABLE_ARCH_5
) {
830 store_reg(s
, reg
, var
);
834 static inline TCGv
gen_ld8s(TCGv addr
, int index
)
836 TCGv tmp
= tcg_temp_new_i32();
837 tcg_gen_qemu_ld8s(tmp
, addr
, index
);
840 static inline TCGv
gen_ld8u(TCGv addr
, int index
)
842 TCGv tmp
= tcg_temp_new_i32();
843 tcg_gen_qemu_ld8u(tmp
, addr
, index
);
846 static inline TCGv
gen_ld16s(TCGv addr
, int index
)
848 TCGv tmp
= tcg_temp_new_i32();
849 tcg_gen_qemu_ld16s(tmp
, addr
, index
);
852 static inline TCGv
gen_ld16u(TCGv addr
, int index
)
854 TCGv tmp
= tcg_temp_new_i32();
855 tcg_gen_qemu_ld16u(tmp
, addr
, index
);
858 static inline TCGv
gen_ld32(TCGv addr
, int index
)
860 TCGv tmp
= tcg_temp_new_i32();
861 tcg_gen_qemu_ld32u(tmp
, addr
, index
);
864 static inline TCGv_i64
gen_ld64(TCGv addr
, int index
)
866 TCGv_i64 tmp
= tcg_temp_new_i64();
867 tcg_gen_qemu_ld64(tmp
, addr
, index
);
870 static inline void gen_st8(TCGv val
, TCGv addr
, int index
)
872 tcg_gen_qemu_st8(val
, addr
, index
);
873 tcg_temp_free_i32(val
);
875 static inline void gen_st16(TCGv val
, TCGv addr
, int index
)
877 tcg_gen_qemu_st16(val
, addr
, index
);
878 tcg_temp_free_i32(val
);
880 static inline void gen_st32(TCGv val
, TCGv addr
, int index
)
882 tcg_gen_qemu_st32(val
, addr
, index
);
883 tcg_temp_free_i32(val
);
885 static inline void gen_st64(TCGv_i64 val
, TCGv addr
, int index
)
887 tcg_gen_qemu_st64(val
, addr
, index
);
888 tcg_temp_free_i64(val
);
891 static inline void gen_set_pc_im(uint32_t val
)
893 tcg_gen_movi_i32(cpu_R
[15], val
);
896 /* Force a TB lookup after an instruction that changes the CPU state. */
897 static inline void gen_lookup_tb(DisasContext
*s
)
899 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
900 s
->is_jmp
= DISAS_UPDATE
;
903 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
906 int val
, rm
, shift
, shiftop
;
909 if (!(insn
& (1 << 25))) {
912 if (!(insn
& (1 << 23)))
915 tcg_gen_addi_i32(var
, var
, val
);
919 shift
= (insn
>> 7) & 0x1f;
920 shiftop
= (insn
>> 5) & 3;
921 offset
= load_reg(s
, rm
);
922 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
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 inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
937 if (insn
& (1 << 22)) {
939 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
940 if (!(insn
& (1 << 23)))
944 tcg_gen_addi_i32(var
, var
, val
);
948 tcg_gen_addi_i32(var
, var
, extra
);
950 offset
= load_reg(s
, rm
);
951 if (!(insn
& (1 << 23)))
952 tcg_gen_sub_i32(var
, var
, offset
);
954 tcg_gen_add_i32(var
, var
, offset
);
955 tcg_temp_free_i32(offset
);
959 static TCGv_ptr
get_fpstatus_ptr(int neon
)
961 TCGv_ptr statusptr
= tcg_temp_new_ptr();
964 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
966 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
968 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
972 #define VFP_OP2(name) \
973 static inline void gen_vfp_##name(int dp) \
975 TCGv_ptr fpst = get_fpstatus_ptr(0); \
977 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
979 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
981 tcg_temp_free_ptr(fpst); \
991 static inline void gen_vfp_F1_mul(int dp
)
993 /* Like gen_vfp_mul() but put result in F1 */
994 TCGv_ptr fpst
= get_fpstatus_ptr(0);
996 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
998 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1000 tcg_temp_free_ptr(fpst
);
1003 static inline void gen_vfp_F1_neg(int dp
)
1005 /* Like gen_vfp_neg() but put result in F1 */
1007 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1009 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1013 static inline void gen_vfp_abs(int dp
)
1016 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1018 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1021 static inline void gen_vfp_neg(int dp
)
1024 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1026 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1029 static inline void gen_vfp_sqrt(int dp
)
1032 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1034 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1037 static inline void gen_vfp_cmp(int dp
)
1040 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1042 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1045 static inline void gen_vfp_cmpe(int dp
)
1048 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1050 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1053 static inline void gen_vfp_F1_ld0(int dp
)
1056 tcg_gen_movi_i64(cpu_F1d
, 0);
1058 tcg_gen_movi_i32(cpu_F1s
, 0);
1061 #define VFP_GEN_ITOF(name) \
1062 static inline void gen_vfp_##name(int dp, int neon) \
1064 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1066 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1068 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1070 tcg_temp_free_ptr(statusptr); \
1077 #define VFP_GEN_FTOI(name) \
1078 static inline void gen_vfp_##name(int dp, int neon) \
1080 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1082 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1084 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1086 tcg_temp_free_ptr(statusptr); \
1095 #define VFP_GEN_FIX(name) \
1096 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1098 TCGv tmp_shift = tcg_const_i32(shift); \
1099 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1101 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1103 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1105 tcg_temp_free_i32(tmp_shift); \
1106 tcg_temp_free_ptr(statusptr); \
1118 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv addr
)
1121 tcg_gen_qemu_ld64(cpu_F0d
, addr
, IS_USER(s
));
1123 tcg_gen_qemu_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1126 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv addr
)
1129 tcg_gen_qemu_st64(cpu_F0d
, addr
, IS_USER(s
));
1131 tcg_gen_qemu_st32(cpu_F0s
, addr
, IS_USER(s
));
1135 vfp_reg_offset (int dp
, int reg
)
1138 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1140 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1141 + offsetof(CPU_DoubleU
, l
.upper
);
1143 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1144 + offsetof(CPU_DoubleU
, l
.lower
);
1148 /* Return the offset of a 32-bit piece of a NEON register.
1149 zero is the least significant end of the register. */
1151 neon_reg_offset (int reg
, int n
)
1155 return vfp_reg_offset(0, sreg
);
1158 static TCGv
neon_load_reg(int reg
, int pass
)
1160 TCGv tmp
= tcg_temp_new_i32();
1161 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1165 static void neon_store_reg(int reg
, int pass
, TCGv var
)
1167 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1168 tcg_temp_free_i32(var
);
1171 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1173 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1176 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1178 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1181 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1182 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1183 #define tcg_gen_st_f32 tcg_gen_st_i32
1184 #define tcg_gen_st_f64 tcg_gen_st_i64
1186 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1189 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1191 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1194 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1197 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1199 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1202 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1205 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1207 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1210 #define ARM_CP_RW_BIT (1 << 20)
1212 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1214 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1217 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1219 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1222 static inline TCGv
iwmmxt_load_creg(int reg
)
1224 TCGv var
= tcg_temp_new_i32();
1225 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1229 static inline void iwmmxt_store_creg(int reg
, TCGv var
)
1231 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1232 tcg_temp_free_i32(var
);
1235 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1237 iwmmxt_store_reg(cpu_M0
, rn
);
1240 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1242 iwmmxt_load_reg(cpu_M0
, rn
);
1245 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1247 iwmmxt_load_reg(cpu_V1
, rn
);
1248 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1251 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1253 iwmmxt_load_reg(cpu_V1
, rn
);
1254 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1257 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1259 iwmmxt_load_reg(cpu_V1
, rn
);
1260 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1263 #define IWMMXT_OP(name) \
1264 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1266 iwmmxt_load_reg(cpu_V1, rn); \
1267 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1270 #define IWMMXT_OP_ENV(name) \
1271 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1273 iwmmxt_load_reg(cpu_V1, rn); \
1274 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1277 #define IWMMXT_OP_ENV_SIZE(name) \
1278 IWMMXT_OP_ENV(name##b) \
1279 IWMMXT_OP_ENV(name##w) \
1280 IWMMXT_OP_ENV(name##l)
1282 #define IWMMXT_OP_ENV1(name) \
1283 static inline void gen_op_iwmmxt_##name##_M0(void) \
1285 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1299 IWMMXT_OP_ENV_SIZE(unpackl
)
1300 IWMMXT_OP_ENV_SIZE(unpackh
)
1302 IWMMXT_OP_ENV1(unpacklub
)
1303 IWMMXT_OP_ENV1(unpackluw
)
1304 IWMMXT_OP_ENV1(unpacklul
)
1305 IWMMXT_OP_ENV1(unpackhub
)
1306 IWMMXT_OP_ENV1(unpackhuw
)
1307 IWMMXT_OP_ENV1(unpackhul
)
1308 IWMMXT_OP_ENV1(unpacklsb
)
1309 IWMMXT_OP_ENV1(unpacklsw
)
1310 IWMMXT_OP_ENV1(unpacklsl
)
1311 IWMMXT_OP_ENV1(unpackhsb
)
1312 IWMMXT_OP_ENV1(unpackhsw
)
1313 IWMMXT_OP_ENV1(unpackhsl
)
1315 IWMMXT_OP_ENV_SIZE(cmpeq
)
1316 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1317 IWMMXT_OP_ENV_SIZE(cmpgts
)
1319 IWMMXT_OP_ENV_SIZE(mins
)
1320 IWMMXT_OP_ENV_SIZE(minu
)
1321 IWMMXT_OP_ENV_SIZE(maxs
)
1322 IWMMXT_OP_ENV_SIZE(maxu
)
1324 IWMMXT_OP_ENV_SIZE(subn
)
1325 IWMMXT_OP_ENV_SIZE(addn
)
1326 IWMMXT_OP_ENV_SIZE(subu
)
1327 IWMMXT_OP_ENV_SIZE(addu
)
1328 IWMMXT_OP_ENV_SIZE(subs
)
1329 IWMMXT_OP_ENV_SIZE(adds
)
1331 IWMMXT_OP_ENV(avgb0
)
1332 IWMMXT_OP_ENV(avgb1
)
1333 IWMMXT_OP_ENV(avgw0
)
1334 IWMMXT_OP_ENV(avgw1
)
1338 IWMMXT_OP_ENV(packuw
)
1339 IWMMXT_OP_ENV(packul
)
1340 IWMMXT_OP_ENV(packuq
)
1341 IWMMXT_OP_ENV(packsw
)
1342 IWMMXT_OP_ENV(packsl
)
1343 IWMMXT_OP_ENV(packsq
)
1345 static void gen_op_iwmmxt_set_mup(void)
1348 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1349 tcg_gen_ori_i32(tmp
, tmp
, 2);
1350 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1353 static void gen_op_iwmmxt_set_cup(void)
1356 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1357 tcg_gen_ori_i32(tmp
, tmp
, 1);
1358 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1361 static void gen_op_iwmmxt_setpsr_nz(void)
1363 TCGv tmp
= tcg_temp_new_i32();
1364 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1365 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1368 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1370 iwmmxt_load_reg(cpu_V1
, rn
);
1371 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1372 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1375 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1381 rd
= (insn
>> 16) & 0xf;
1382 tmp
= load_reg(s
, rd
);
1384 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1385 if (insn
& (1 << 24)) {
1387 if (insn
& (1 << 23))
1388 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1390 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1391 tcg_gen_mov_i32(dest
, tmp
);
1392 if (insn
& (1 << 21))
1393 store_reg(s
, rd
, tmp
);
1395 tcg_temp_free_i32(tmp
);
1396 } else if (insn
& (1 << 21)) {
1398 tcg_gen_mov_i32(dest
, tmp
);
1399 if (insn
& (1 << 23))
1400 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1402 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1403 store_reg(s
, rd
, tmp
);
1404 } else if (!(insn
& (1 << 23)))
1409 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1411 int rd
= (insn
>> 0) & 0xf;
1414 if (insn
& (1 << 8)) {
1415 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1418 tmp
= iwmmxt_load_creg(rd
);
1421 tmp
= tcg_temp_new_i32();
1422 iwmmxt_load_reg(cpu_V0
, rd
);
1423 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1425 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1426 tcg_gen_mov_i32(dest
, tmp
);
1427 tcg_temp_free_i32(tmp
);
1431 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1432 (ie. an undefined instruction). */
1433 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1436 int rdhi
, rdlo
, rd0
, rd1
, i
;
1438 TCGv tmp
, tmp2
, tmp3
;
1440 if ((insn
& 0x0e000e00) == 0x0c000000) {
1441 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1443 rdlo
= (insn
>> 12) & 0xf;
1444 rdhi
= (insn
>> 16) & 0xf;
1445 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1446 iwmmxt_load_reg(cpu_V0
, wrd
);
1447 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1448 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1449 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1450 } else { /* TMCRR */
1451 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1452 iwmmxt_store_reg(cpu_V0
, wrd
);
1453 gen_op_iwmmxt_set_mup();
1458 wrd
= (insn
>> 12) & 0xf;
1459 addr
= tcg_temp_new_i32();
1460 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1461 tcg_temp_free_i32(addr
);
1464 if (insn
& ARM_CP_RW_BIT
) {
1465 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1466 tmp
= tcg_temp_new_i32();
1467 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1468 iwmmxt_store_creg(wrd
, tmp
);
1471 if (insn
& (1 << 8)) {
1472 if (insn
& (1 << 22)) { /* WLDRD */
1473 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1475 } else { /* WLDRW wRd */
1476 tmp
= gen_ld32(addr
, IS_USER(s
));
1479 if (insn
& (1 << 22)) { /* WLDRH */
1480 tmp
= gen_ld16u(addr
, IS_USER(s
));
1481 } else { /* WLDRB */
1482 tmp
= gen_ld8u(addr
, IS_USER(s
));
1486 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1487 tcg_temp_free_i32(tmp
);
1489 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1492 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1493 tmp
= iwmmxt_load_creg(wrd
);
1494 gen_st32(tmp
, addr
, IS_USER(s
));
1496 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1497 tmp
= tcg_temp_new_i32();
1498 if (insn
& (1 << 8)) {
1499 if (insn
& (1 << 22)) { /* WSTRD */
1500 tcg_temp_free_i32(tmp
);
1501 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1502 } else { /* WSTRW wRd */
1503 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1504 gen_st32(tmp
, addr
, IS_USER(s
));
1507 if (insn
& (1 << 22)) { /* WSTRH */
1508 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1509 gen_st16(tmp
, addr
, IS_USER(s
));
1510 } else { /* WSTRB */
1511 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1512 gen_st8(tmp
, addr
, IS_USER(s
));
1517 tcg_temp_free_i32(addr
);
1521 if ((insn
& 0x0f000000) != 0x0e000000)
1524 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1525 case 0x000: /* WOR */
1526 wrd
= (insn
>> 12) & 0xf;
1527 rd0
= (insn
>> 0) & 0xf;
1528 rd1
= (insn
>> 16) & 0xf;
1529 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1530 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1531 gen_op_iwmmxt_setpsr_nz();
1532 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1533 gen_op_iwmmxt_set_mup();
1534 gen_op_iwmmxt_set_cup();
1536 case 0x011: /* TMCR */
1539 rd
= (insn
>> 12) & 0xf;
1540 wrd
= (insn
>> 16) & 0xf;
1542 case ARM_IWMMXT_wCID
:
1543 case ARM_IWMMXT_wCASF
:
1545 case ARM_IWMMXT_wCon
:
1546 gen_op_iwmmxt_set_cup();
1548 case ARM_IWMMXT_wCSSF
:
1549 tmp
= iwmmxt_load_creg(wrd
);
1550 tmp2
= load_reg(s
, rd
);
1551 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1552 tcg_temp_free_i32(tmp2
);
1553 iwmmxt_store_creg(wrd
, tmp
);
1555 case ARM_IWMMXT_wCGR0
:
1556 case ARM_IWMMXT_wCGR1
:
1557 case ARM_IWMMXT_wCGR2
:
1558 case ARM_IWMMXT_wCGR3
:
1559 gen_op_iwmmxt_set_cup();
1560 tmp
= load_reg(s
, rd
);
1561 iwmmxt_store_creg(wrd
, tmp
);
1567 case 0x100: /* WXOR */
1568 wrd
= (insn
>> 12) & 0xf;
1569 rd0
= (insn
>> 0) & 0xf;
1570 rd1
= (insn
>> 16) & 0xf;
1571 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1572 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1573 gen_op_iwmmxt_setpsr_nz();
1574 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1575 gen_op_iwmmxt_set_mup();
1576 gen_op_iwmmxt_set_cup();
1578 case 0x111: /* TMRC */
1581 rd
= (insn
>> 12) & 0xf;
1582 wrd
= (insn
>> 16) & 0xf;
1583 tmp
= iwmmxt_load_creg(wrd
);
1584 store_reg(s
, rd
, tmp
);
1586 case 0x300: /* WANDN */
1587 wrd
= (insn
>> 12) & 0xf;
1588 rd0
= (insn
>> 0) & 0xf;
1589 rd1
= (insn
>> 16) & 0xf;
1590 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1591 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1592 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1593 gen_op_iwmmxt_setpsr_nz();
1594 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1595 gen_op_iwmmxt_set_mup();
1596 gen_op_iwmmxt_set_cup();
1598 case 0x200: /* WAND */
1599 wrd
= (insn
>> 12) & 0xf;
1600 rd0
= (insn
>> 0) & 0xf;
1601 rd1
= (insn
>> 16) & 0xf;
1602 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1603 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1604 gen_op_iwmmxt_setpsr_nz();
1605 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1606 gen_op_iwmmxt_set_mup();
1607 gen_op_iwmmxt_set_cup();
1609 case 0x810: case 0xa10: /* WMADD */
1610 wrd
= (insn
>> 12) & 0xf;
1611 rd0
= (insn
>> 0) & 0xf;
1612 rd1
= (insn
>> 16) & 0xf;
1613 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1614 if (insn
& (1 << 21))
1615 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1617 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1618 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1619 gen_op_iwmmxt_set_mup();
1621 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1622 wrd
= (insn
>> 12) & 0xf;
1623 rd0
= (insn
>> 16) & 0xf;
1624 rd1
= (insn
>> 0) & 0xf;
1625 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1626 switch ((insn
>> 22) & 3) {
1628 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1631 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1634 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1639 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1640 gen_op_iwmmxt_set_mup();
1641 gen_op_iwmmxt_set_cup();
1643 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1644 wrd
= (insn
>> 12) & 0xf;
1645 rd0
= (insn
>> 16) & 0xf;
1646 rd1
= (insn
>> 0) & 0xf;
1647 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1648 switch ((insn
>> 22) & 3) {
1650 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1653 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1656 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1661 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1662 gen_op_iwmmxt_set_mup();
1663 gen_op_iwmmxt_set_cup();
1665 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1666 wrd
= (insn
>> 12) & 0xf;
1667 rd0
= (insn
>> 16) & 0xf;
1668 rd1
= (insn
>> 0) & 0xf;
1669 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1670 if (insn
& (1 << 22))
1671 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1673 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1674 if (!(insn
& (1 << 20)))
1675 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1676 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1677 gen_op_iwmmxt_set_mup();
1679 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1680 wrd
= (insn
>> 12) & 0xf;
1681 rd0
= (insn
>> 16) & 0xf;
1682 rd1
= (insn
>> 0) & 0xf;
1683 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1684 if (insn
& (1 << 21)) {
1685 if (insn
& (1 << 20))
1686 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1688 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1690 if (insn
& (1 << 20))
1691 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1693 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1695 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1696 gen_op_iwmmxt_set_mup();
1698 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1699 wrd
= (insn
>> 12) & 0xf;
1700 rd0
= (insn
>> 16) & 0xf;
1701 rd1
= (insn
>> 0) & 0xf;
1702 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1703 if (insn
& (1 << 21))
1704 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1706 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1707 if (!(insn
& (1 << 20))) {
1708 iwmmxt_load_reg(cpu_V1
, wrd
);
1709 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1711 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1712 gen_op_iwmmxt_set_mup();
1714 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1715 wrd
= (insn
>> 12) & 0xf;
1716 rd0
= (insn
>> 16) & 0xf;
1717 rd1
= (insn
>> 0) & 0xf;
1718 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1719 switch ((insn
>> 22) & 3) {
1721 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1724 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1727 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1732 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1733 gen_op_iwmmxt_set_mup();
1734 gen_op_iwmmxt_set_cup();
1736 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1737 wrd
= (insn
>> 12) & 0xf;
1738 rd0
= (insn
>> 16) & 0xf;
1739 rd1
= (insn
>> 0) & 0xf;
1740 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1741 if (insn
& (1 << 22)) {
1742 if (insn
& (1 << 20))
1743 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1745 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1747 if (insn
& (1 << 20))
1748 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1750 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1752 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1753 gen_op_iwmmxt_set_mup();
1754 gen_op_iwmmxt_set_cup();
1756 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1757 wrd
= (insn
>> 12) & 0xf;
1758 rd0
= (insn
>> 16) & 0xf;
1759 rd1
= (insn
>> 0) & 0xf;
1760 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1761 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1762 tcg_gen_andi_i32(tmp
, tmp
, 7);
1763 iwmmxt_load_reg(cpu_V1
, rd1
);
1764 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1765 tcg_temp_free_i32(tmp
);
1766 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1767 gen_op_iwmmxt_set_mup();
1769 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1770 if (((insn
>> 6) & 3) == 3)
1772 rd
= (insn
>> 12) & 0xf;
1773 wrd
= (insn
>> 16) & 0xf;
1774 tmp
= load_reg(s
, rd
);
1775 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1776 switch ((insn
>> 6) & 3) {
1778 tmp2
= tcg_const_i32(0xff);
1779 tmp3
= tcg_const_i32((insn
& 7) << 3);
1782 tmp2
= tcg_const_i32(0xffff);
1783 tmp3
= tcg_const_i32((insn
& 3) << 4);
1786 tmp2
= tcg_const_i32(0xffffffff);
1787 tmp3
= tcg_const_i32((insn
& 1) << 5);
1793 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1794 tcg_temp_free(tmp3
);
1795 tcg_temp_free(tmp2
);
1796 tcg_temp_free_i32(tmp
);
1797 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1798 gen_op_iwmmxt_set_mup();
1800 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1801 rd
= (insn
>> 12) & 0xf;
1802 wrd
= (insn
>> 16) & 0xf;
1803 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1805 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1806 tmp
= tcg_temp_new_i32();
1807 switch ((insn
>> 22) & 3) {
1809 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1810 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1812 tcg_gen_ext8s_i32(tmp
, tmp
);
1814 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1818 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1819 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1821 tcg_gen_ext16s_i32(tmp
, tmp
);
1823 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1827 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1828 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1831 store_reg(s
, rd
, tmp
);
1833 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1834 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1836 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1837 switch ((insn
>> 22) & 3) {
1839 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1842 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1845 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1848 tcg_gen_shli_i32(tmp
, tmp
, 28);
1850 tcg_temp_free_i32(tmp
);
1852 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1853 if (((insn
>> 6) & 3) == 3)
1855 rd
= (insn
>> 12) & 0xf;
1856 wrd
= (insn
>> 16) & 0xf;
1857 tmp
= load_reg(s
, rd
);
1858 switch ((insn
>> 6) & 3) {
1860 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1863 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1866 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1869 tcg_temp_free_i32(tmp
);
1870 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1871 gen_op_iwmmxt_set_mup();
1873 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1874 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1876 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1877 tmp2
= tcg_temp_new_i32();
1878 tcg_gen_mov_i32(tmp2
, tmp
);
1879 switch ((insn
>> 22) & 3) {
1881 for (i
= 0; i
< 7; i
++) {
1882 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1883 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1887 for (i
= 0; i
< 3; i
++) {
1888 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1889 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1893 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1894 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1898 tcg_temp_free_i32(tmp2
);
1899 tcg_temp_free_i32(tmp
);
1901 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1902 wrd
= (insn
>> 12) & 0xf;
1903 rd0
= (insn
>> 16) & 0xf;
1904 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1905 switch ((insn
>> 22) & 3) {
1907 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1910 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1913 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1918 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1919 gen_op_iwmmxt_set_mup();
1921 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1922 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1924 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1925 tmp2
= tcg_temp_new_i32();
1926 tcg_gen_mov_i32(tmp2
, tmp
);
1927 switch ((insn
>> 22) & 3) {
1929 for (i
= 0; i
< 7; i
++) {
1930 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1931 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1935 for (i
= 0; i
< 3; i
++) {
1936 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1937 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1941 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1942 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1946 tcg_temp_free_i32(tmp2
);
1947 tcg_temp_free_i32(tmp
);
1949 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1950 rd
= (insn
>> 12) & 0xf;
1951 rd0
= (insn
>> 16) & 0xf;
1952 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1954 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1955 tmp
= tcg_temp_new_i32();
1956 switch ((insn
>> 22) & 3) {
1958 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1961 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1964 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1967 store_reg(s
, rd
, tmp
);
1969 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1970 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1971 wrd
= (insn
>> 12) & 0xf;
1972 rd0
= (insn
>> 16) & 0xf;
1973 rd1
= (insn
>> 0) & 0xf;
1974 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1975 switch ((insn
>> 22) & 3) {
1977 if (insn
& (1 << 21))
1978 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1980 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1983 if (insn
& (1 << 21))
1984 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1986 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
1989 if (insn
& (1 << 21))
1990 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
1992 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
1997 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1998 gen_op_iwmmxt_set_mup();
1999 gen_op_iwmmxt_set_cup();
2001 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2002 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2003 wrd
= (insn
>> 12) & 0xf;
2004 rd0
= (insn
>> 16) & 0xf;
2005 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2006 switch ((insn
>> 22) & 3) {
2008 if (insn
& (1 << 21))
2009 gen_op_iwmmxt_unpacklsb_M0();
2011 gen_op_iwmmxt_unpacklub_M0();
2014 if (insn
& (1 << 21))
2015 gen_op_iwmmxt_unpacklsw_M0();
2017 gen_op_iwmmxt_unpackluw_M0();
2020 if (insn
& (1 << 21))
2021 gen_op_iwmmxt_unpacklsl_M0();
2023 gen_op_iwmmxt_unpacklul_M0();
2028 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2029 gen_op_iwmmxt_set_mup();
2030 gen_op_iwmmxt_set_cup();
2032 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2033 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2034 wrd
= (insn
>> 12) & 0xf;
2035 rd0
= (insn
>> 16) & 0xf;
2036 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2037 switch ((insn
>> 22) & 3) {
2039 if (insn
& (1 << 21))
2040 gen_op_iwmmxt_unpackhsb_M0();
2042 gen_op_iwmmxt_unpackhub_M0();
2045 if (insn
& (1 << 21))
2046 gen_op_iwmmxt_unpackhsw_M0();
2048 gen_op_iwmmxt_unpackhuw_M0();
2051 if (insn
& (1 << 21))
2052 gen_op_iwmmxt_unpackhsl_M0();
2054 gen_op_iwmmxt_unpackhul_M0();
2059 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2060 gen_op_iwmmxt_set_mup();
2061 gen_op_iwmmxt_set_cup();
2063 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2064 case 0x214: case 0x614: case 0xa14: case 0xe14:
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_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2080 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2083 gen_helper_iwmmxt_srlq(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 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2092 case 0x014: case 0x414: case 0x814: case 0xc14:
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_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2108 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2111 gen_helper_iwmmxt_sraq(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 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2120 case 0x114: case 0x514: case 0x914: case 0xd14:
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 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2128 tcg_temp_free_i32(tmp
);
2131 switch ((insn
>> 22) & 3) {
2133 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2136 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2139 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2142 tcg_temp_free_i32(tmp
);
2143 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2144 gen_op_iwmmxt_set_mup();
2145 gen_op_iwmmxt_set_cup();
2147 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2148 case 0x314: case 0x714: case 0xb14: case 0xf14:
2149 if (((insn
>> 22) & 3) == 0)
2151 wrd
= (insn
>> 12) & 0xf;
2152 rd0
= (insn
>> 16) & 0xf;
2153 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2154 tmp
= tcg_temp_new_i32();
2155 switch ((insn
>> 22) & 3) {
2157 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2158 tcg_temp_free_i32(tmp
);
2161 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2164 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2165 tcg_temp_free_i32(tmp
);
2168 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2171 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2172 tcg_temp_free_i32(tmp
);
2175 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2178 tcg_temp_free_i32(tmp
);
2179 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2180 gen_op_iwmmxt_set_mup();
2181 gen_op_iwmmxt_set_cup();
2183 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2184 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2185 wrd
= (insn
>> 12) & 0xf;
2186 rd0
= (insn
>> 16) & 0xf;
2187 rd1
= (insn
>> 0) & 0xf;
2188 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2189 switch ((insn
>> 22) & 3) {
2191 if (insn
& (1 << 21))
2192 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2194 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2197 if (insn
& (1 << 21))
2198 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2200 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2203 if (insn
& (1 << 21))
2204 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2206 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2211 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2212 gen_op_iwmmxt_set_mup();
2214 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2215 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2216 wrd
= (insn
>> 12) & 0xf;
2217 rd0
= (insn
>> 16) & 0xf;
2218 rd1
= (insn
>> 0) & 0xf;
2219 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2220 switch ((insn
>> 22) & 3) {
2222 if (insn
& (1 << 21))
2223 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2225 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2228 if (insn
& (1 << 21))
2229 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2231 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2234 if (insn
& (1 << 21))
2235 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2237 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2242 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2243 gen_op_iwmmxt_set_mup();
2245 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2246 case 0x402: case 0x502: case 0x602: case 0x702:
2247 wrd
= (insn
>> 12) & 0xf;
2248 rd0
= (insn
>> 16) & 0xf;
2249 rd1
= (insn
>> 0) & 0xf;
2250 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2251 tmp
= tcg_const_i32((insn
>> 20) & 3);
2252 iwmmxt_load_reg(cpu_V1
, rd1
);
2253 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2255 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2256 gen_op_iwmmxt_set_mup();
2258 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2259 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2260 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2261 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2262 wrd
= (insn
>> 12) & 0xf;
2263 rd0
= (insn
>> 16) & 0xf;
2264 rd1
= (insn
>> 0) & 0xf;
2265 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2266 switch ((insn
>> 20) & 0xf) {
2268 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2271 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2274 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2277 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2280 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2283 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2286 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2289 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2292 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2297 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2298 gen_op_iwmmxt_set_mup();
2299 gen_op_iwmmxt_set_cup();
2301 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2302 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2303 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2304 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2305 wrd
= (insn
>> 12) & 0xf;
2306 rd0
= (insn
>> 16) & 0xf;
2307 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2308 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2309 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2311 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2312 gen_op_iwmmxt_set_mup();
2313 gen_op_iwmmxt_set_cup();
2315 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2316 case 0x418: case 0x518: case 0x618: case 0x718:
2317 case 0x818: case 0x918: case 0xa18: case 0xb18:
2318 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2319 wrd
= (insn
>> 12) & 0xf;
2320 rd0
= (insn
>> 16) & 0xf;
2321 rd1
= (insn
>> 0) & 0xf;
2322 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2323 switch ((insn
>> 20) & 0xf) {
2325 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2328 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2331 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2334 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2337 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2340 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2343 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2346 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2349 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2354 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2355 gen_op_iwmmxt_set_mup();
2356 gen_op_iwmmxt_set_cup();
2358 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2359 case 0x408: case 0x508: case 0x608: case 0x708:
2360 case 0x808: case 0x908: case 0xa08: case 0xb08:
2361 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2362 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2364 wrd
= (insn
>> 12) & 0xf;
2365 rd0
= (insn
>> 16) & 0xf;
2366 rd1
= (insn
>> 0) & 0xf;
2367 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2368 switch ((insn
>> 22) & 3) {
2370 if (insn
& (1 << 21))
2371 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2373 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2376 if (insn
& (1 << 21))
2377 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2379 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2382 if (insn
& (1 << 21))
2383 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2385 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2388 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2389 gen_op_iwmmxt_set_mup();
2390 gen_op_iwmmxt_set_cup();
2392 case 0x201: case 0x203: case 0x205: case 0x207:
2393 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2394 case 0x211: case 0x213: case 0x215: case 0x217:
2395 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2396 wrd
= (insn
>> 5) & 0xf;
2397 rd0
= (insn
>> 12) & 0xf;
2398 rd1
= (insn
>> 0) & 0xf;
2399 if (rd0
== 0xf || rd1
== 0xf)
2401 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2402 tmp
= load_reg(s
, rd0
);
2403 tmp2
= load_reg(s
, rd1
);
2404 switch ((insn
>> 16) & 0xf) {
2405 case 0x0: /* TMIA */
2406 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2408 case 0x8: /* TMIAPH */
2409 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2411 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2412 if (insn
& (1 << 16))
2413 tcg_gen_shri_i32(tmp
, tmp
, 16);
2414 if (insn
& (1 << 17))
2415 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2416 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2419 tcg_temp_free_i32(tmp2
);
2420 tcg_temp_free_i32(tmp
);
2423 tcg_temp_free_i32(tmp2
);
2424 tcg_temp_free_i32(tmp
);
2425 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2426 gen_op_iwmmxt_set_mup();
2435 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2436 (ie. an undefined instruction). */
2437 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2439 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2442 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2443 /* Multiply with Internal Accumulate Format */
2444 rd0
= (insn
>> 12) & 0xf;
2446 acc
= (insn
>> 5) & 7;
2451 tmp
= load_reg(s
, rd0
);
2452 tmp2
= load_reg(s
, rd1
);
2453 switch ((insn
>> 16) & 0xf) {
2455 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2457 case 0x8: /* MIAPH */
2458 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2460 case 0xc: /* MIABB */
2461 case 0xd: /* MIABT */
2462 case 0xe: /* MIATB */
2463 case 0xf: /* MIATT */
2464 if (insn
& (1 << 16))
2465 tcg_gen_shri_i32(tmp
, tmp
, 16);
2466 if (insn
& (1 << 17))
2467 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2468 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2473 tcg_temp_free_i32(tmp2
);
2474 tcg_temp_free_i32(tmp
);
2476 gen_op_iwmmxt_movq_wRn_M0(acc
);
2480 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2481 /* Internal Accumulator Access Format */
2482 rdhi
= (insn
>> 16) & 0xf;
2483 rdlo
= (insn
>> 12) & 0xf;
2489 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2490 iwmmxt_load_reg(cpu_V0
, acc
);
2491 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2492 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2493 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2494 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2496 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2497 iwmmxt_store_reg(cpu_V0
, acc
);
2505 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2506 #define VFP_SREG(insn, bigbit, smallbit) \
2507 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2508 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2509 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2510 reg = (((insn) >> (bigbit)) & 0x0f) \
2511 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2513 if (insn & (1 << (smallbit))) \
2515 reg = ((insn) >> (bigbit)) & 0x0f; \
2518 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2519 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2520 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2521 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2522 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2523 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2525 /* Move between integer and VFP cores. */
2526 static TCGv
gen_vfp_mrs(void)
2528 TCGv tmp
= tcg_temp_new_i32();
2529 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2533 static void gen_vfp_msr(TCGv tmp
)
2535 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2536 tcg_temp_free_i32(tmp
);
2539 static void gen_neon_dup_u8(TCGv var
, int shift
)
2541 TCGv tmp
= tcg_temp_new_i32();
2543 tcg_gen_shri_i32(var
, var
, shift
);
2544 tcg_gen_ext8u_i32(var
, var
);
2545 tcg_gen_shli_i32(tmp
, var
, 8);
2546 tcg_gen_or_i32(var
, var
, tmp
);
2547 tcg_gen_shli_i32(tmp
, var
, 16);
2548 tcg_gen_or_i32(var
, var
, tmp
);
2549 tcg_temp_free_i32(tmp
);
2552 static void gen_neon_dup_low16(TCGv var
)
2554 TCGv tmp
= tcg_temp_new_i32();
2555 tcg_gen_ext16u_i32(var
, var
);
2556 tcg_gen_shli_i32(tmp
, var
, 16);
2557 tcg_gen_or_i32(var
, var
, tmp
);
2558 tcg_temp_free_i32(tmp
);
2561 static void gen_neon_dup_high16(TCGv var
)
2563 TCGv tmp
= tcg_temp_new_i32();
2564 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2565 tcg_gen_shri_i32(tmp
, var
, 16);
2566 tcg_gen_or_i32(var
, var
, tmp
);
2567 tcg_temp_free_i32(tmp
);
2570 static TCGv
gen_load_and_replicate(DisasContext
*s
, TCGv addr
, int size
)
2572 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2576 tmp
= gen_ld8u(addr
, IS_USER(s
));
2577 gen_neon_dup_u8(tmp
, 0);
2580 tmp
= gen_ld16u(addr
, IS_USER(s
));
2581 gen_neon_dup_low16(tmp
);
2584 tmp
= gen_ld32(addr
, IS_USER(s
));
2586 default: /* Avoid compiler warnings. */
2592 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2593 (ie. an undefined instruction). */
2594 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2596 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2602 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2605 if (!s
->vfp_enabled
) {
2606 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2607 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2609 rn
= (insn
>> 16) & 0xf;
2610 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2611 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2614 dp
= ((insn
& 0xf00) == 0xb00);
2615 switch ((insn
>> 24) & 0xf) {
2617 if (insn
& (1 << 4)) {
2618 /* single register transfer */
2619 rd
= (insn
>> 12) & 0xf;
2624 VFP_DREG_N(rn
, insn
);
2627 if (insn
& 0x00c00060
2628 && !arm_feature(env
, ARM_FEATURE_NEON
))
2631 pass
= (insn
>> 21) & 1;
2632 if (insn
& (1 << 22)) {
2634 offset
= ((insn
>> 5) & 3) * 8;
2635 } else if (insn
& (1 << 5)) {
2637 offset
= (insn
& (1 << 6)) ? 16 : 0;
2642 if (insn
& ARM_CP_RW_BIT
) {
2644 tmp
= neon_load_reg(rn
, pass
);
2648 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2649 if (insn
& (1 << 23))
2655 if (insn
& (1 << 23)) {
2657 tcg_gen_shri_i32(tmp
, tmp
, 16);
2663 tcg_gen_sari_i32(tmp
, tmp
, 16);
2672 store_reg(s
, rd
, tmp
);
2675 tmp
= load_reg(s
, rd
);
2676 if (insn
& (1 << 23)) {
2679 gen_neon_dup_u8(tmp
, 0);
2680 } else if (size
== 1) {
2681 gen_neon_dup_low16(tmp
);
2683 for (n
= 0; n
<= pass
* 2; n
++) {
2684 tmp2
= tcg_temp_new_i32();
2685 tcg_gen_mov_i32(tmp2
, tmp
);
2686 neon_store_reg(rn
, n
, tmp2
);
2688 neon_store_reg(rn
, n
, tmp
);
2693 tmp2
= neon_load_reg(rn
, pass
);
2694 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
2695 tcg_temp_free_i32(tmp2
);
2698 tmp2
= neon_load_reg(rn
, pass
);
2699 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
2700 tcg_temp_free_i32(tmp2
);
2705 neon_store_reg(rn
, pass
, tmp
);
2709 if ((insn
& 0x6f) != 0x00)
2711 rn
= VFP_SREG_N(insn
);
2712 if (insn
& ARM_CP_RW_BIT
) {
2714 if (insn
& (1 << 21)) {
2715 /* system register */
2720 /* VFP2 allows access to FSID from userspace.
2721 VFP3 restricts all id registers to privileged
2724 && arm_feature(env
, ARM_FEATURE_VFP3
))
2726 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2731 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2733 case ARM_VFP_FPINST
:
2734 case ARM_VFP_FPINST2
:
2735 /* Not present in VFP3. */
2737 || arm_feature(env
, ARM_FEATURE_VFP3
))
2739 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2743 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2744 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2746 tmp
= tcg_temp_new_i32();
2747 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2753 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2755 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2761 gen_mov_F0_vreg(0, rn
);
2762 tmp
= gen_vfp_mrs();
2765 /* Set the 4 flag bits in the CPSR. */
2767 tcg_temp_free_i32(tmp
);
2769 store_reg(s
, rd
, tmp
);
2773 if (insn
& (1 << 21)) {
2775 /* system register */
2780 /* Writes are ignored. */
2783 tmp
= load_reg(s
, rd
);
2784 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2785 tcg_temp_free_i32(tmp
);
2791 /* TODO: VFP subarchitecture support.
2792 * For now, keep the EN bit only */
2793 tmp
= load_reg(s
, rd
);
2794 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2795 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2798 case ARM_VFP_FPINST
:
2799 case ARM_VFP_FPINST2
:
2800 tmp
= load_reg(s
, rd
);
2801 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2807 tmp
= load_reg(s
, rd
);
2809 gen_mov_vreg_F0(0, rn
);
2814 /* data processing */
2815 /* The opcode is in bits 23, 21, 20 and 6. */
2816 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2820 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2822 /* rn is register number */
2823 VFP_DREG_N(rn
, insn
);
2826 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2827 /* Integer or single precision destination. */
2828 rd
= VFP_SREG_D(insn
);
2830 VFP_DREG_D(rd
, insn
);
2833 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2834 /* VCVT from int is always from S reg regardless of dp bit.
2835 * VCVT with immediate frac_bits has same format as SREG_M
2837 rm
= VFP_SREG_M(insn
);
2839 VFP_DREG_M(rm
, insn
);
2842 rn
= VFP_SREG_N(insn
);
2843 if (op
== 15 && rn
== 15) {
2844 /* Double precision destination. */
2845 VFP_DREG_D(rd
, insn
);
2847 rd
= VFP_SREG_D(insn
);
2849 /* NB that we implicitly rely on the encoding for the frac_bits
2850 * in VCVT of fixed to float being the same as that of an SREG_M
2852 rm
= VFP_SREG_M(insn
);
2855 veclen
= s
->vec_len
;
2856 if (op
== 15 && rn
> 3)
2859 /* Shut up compiler warnings. */
2870 /* Figure out what type of vector operation this is. */
2871 if ((rd
& bank_mask
) == 0) {
2876 delta_d
= (s
->vec_stride
>> 1) + 1;
2878 delta_d
= s
->vec_stride
+ 1;
2880 if ((rm
& bank_mask
) == 0) {
2881 /* mixed scalar/vector */
2890 /* Load the initial operands. */
2895 /* Integer source */
2896 gen_mov_F0_vreg(0, rm
);
2901 gen_mov_F0_vreg(dp
, rd
);
2902 gen_mov_F1_vreg(dp
, rm
);
2906 /* Compare with zero */
2907 gen_mov_F0_vreg(dp
, rd
);
2918 /* Source and destination the same. */
2919 gen_mov_F0_vreg(dp
, rd
);
2925 /* VCVTB, VCVTT: only present with the halfprec extension,
2926 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2928 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
2931 /* Otherwise fall through */
2933 /* One source operand. */
2934 gen_mov_F0_vreg(dp
, rm
);
2938 /* Two source operands. */
2939 gen_mov_F0_vreg(dp
, rn
);
2940 gen_mov_F1_vreg(dp
, rm
);
2944 /* Perform the calculation. */
2946 case 0: /* VMLA: fd + (fn * fm) */
2947 /* Note that order of inputs to the add matters for NaNs */
2949 gen_mov_F0_vreg(dp
, rd
);
2952 case 1: /* VMLS: fd + -(fn * fm) */
2955 gen_mov_F0_vreg(dp
, rd
);
2958 case 2: /* VNMLS: -fd + (fn * fm) */
2959 /* Note that it isn't valid to replace (-A + B) with (B - A)
2960 * or similar plausible looking simplifications
2961 * because this will give wrong results for NaNs.
2964 gen_mov_F0_vreg(dp
, rd
);
2968 case 3: /* VNMLA: -fd + -(fn * fm) */
2971 gen_mov_F0_vreg(dp
, rd
);
2975 case 4: /* mul: fn * fm */
2978 case 5: /* nmul: -(fn * fm) */
2982 case 6: /* add: fn + fm */
2985 case 7: /* sub: fn - fm */
2988 case 8: /* div: fn / fm */
2991 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
2992 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
2993 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
2994 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
2995 /* These are fused multiply-add, and must be done as one
2996 * floating point operation with no rounding between the
2997 * multiplication and addition steps.
2998 * NB that doing the negations here as separate steps is
2999 * correct : an input NaN should come out with its sign bit
3000 * flipped if it is a negated-input.
3002 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3010 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3012 frd
= tcg_temp_new_i64();
3013 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3016 gen_helper_vfp_negd(frd
, frd
);
3018 fpst
= get_fpstatus_ptr(0);
3019 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3020 cpu_F1d
, frd
, fpst
);
3021 tcg_temp_free_ptr(fpst
);
3022 tcg_temp_free_i64(frd
);
3028 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3030 frd
= tcg_temp_new_i32();
3031 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3033 gen_helper_vfp_negs(frd
, frd
);
3035 fpst
= get_fpstatus_ptr(0);
3036 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3037 cpu_F1s
, frd
, fpst
);
3038 tcg_temp_free_ptr(fpst
);
3039 tcg_temp_free_i32(frd
);
3042 case 14: /* fconst */
3043 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3046 n
= (insn
<< 12) & 0x80000000;
3047 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3054 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3061 tcg_gen_movi_i32(cpu_F0s
, n
);
3064 case 15: /* extension space */
3078 case 4: /* vcvtb.f32.f16 */
3079 tmp
= gen_vfp_mrs();
3080 tcg_gen_ext16u_i32(tmp
, tmp
);
3081 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3082 tcg_temp_free_i32(tmp
);
3084 case 5: /* vcvtt.f32.f16 */
3085 tmp
= gen_vfp_mrs();
3086 tcg_gen_shri_i32(tmp
, tmp
, 16);
3087 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3088 tcg_temp_free_i32(tmp
);
3090 case 6: /* vcvtb.f16.f32 */
3091 tmp
= tcg_temp_new_i32();
3092 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3093 gen_mov_F0_vreg(0, rd
);
3094 tmp2
= gen_vfp_mrs();
3095 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3096 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3097 tcg_temp_free_i32(tmp2
);
3100 case 7: /* vcvtt.f16.f32 */
3101 tmp
= tcg_temp_new_i32();
3102 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3103 tcg_gen_shli_i32(tmp
, tmp
, 16);
3104 gen_mov_F0_vreg(0, rd
);
3105 tmp2
= gen_vfp_mrs();
3106 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3107 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3108 tcg_temp_free_i32(tmp2
);
3120 case 11: /* cmpez */
3124 case 15: /* single<->double conversion */
3126 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3128 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3130 case 16: /* fuito */
3131 gen_vfp_uito(dp
, 0);
3133 case 17: /* fsito */
3134 gen_vfp_sito(dp
, 0);
3136 case 20: /* fshto */
3137 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3139 gen_vfp_shto(dp
, 16 - rm
, 0);
3141 case 21: /* fslto */
3142 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3144 gen_vfp_slto(dp
, 32 - rm
, 0);
3146 case 22: /* fuhto */
3147 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3149 gen_vfp_uhto(dp
, 16 - rm
, 0);
3151 case 23: /* fulto */
3152 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3154 gen_vfp_ulto(dp
, 32 - rm
, 0);
3156 case 24: /* ftoui */
3157 gen_vfp_toui(dp
, 0);
3159 case 25: /* ftouiz */
3160 gen_vfp_touiz(dp
, 0);
3162 case 26: /* ftosi */
3163 gen_vfp_tosi(dp
, 0);
3165 case 27: /* ftosiz */
3166 gen_vfp_tosiz(dp
, 0);
3168 case 28: /* ftosh */
3169 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3171 gen_vfp_tosh(dp
, 16 - rm
, 0);
3173 case 29: /* ftosl */
3174 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3176 gen_vfp_tosl(dp
, 32 - rm
, 0);
3178 case 30: /* ftouh */
3179 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3181 gen_vfp_touh(dp
, 16 - rm
, 0);
3183 case 31: /* ftoul */
3184 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3186 gen_vfp_toul(dp
, 32 - rm
, 0);
3188 default: /* undefined */
3192 default: /* undefined */
3196 /* Write back the result. */
3197 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3198 ; /* Comparison, do nothing. */
3199 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3200 /* VCVT double to int: always integer result. */
3201 gen_mov_vreg_F0(0, rd
);
3202 else if (op
== 15 && rn
== 15)
3204 gen_mov_vreg_F0(!dp
, rd
);
3206 gen_mov_vreg_F0(dp
, rd
);
3208 /* break out of the loop if we have finished */
3212 if (op
== 15 && delta_m
== 0) {
3213 /* single source one-many */
3215 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3217 gen_mov_vreg_F0(dp
, rd
);
3221 /* Setup the next operands. */
3223 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3227 /* One source operand. */
3228 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3230 gen_mov_F0_vreg(dp
, rm
);
3232 /* Two source operands. */
3233 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3235 gen_mov_F0_vreg(dp
, rn
);
3237 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3239 gen_mov_F1_vreg(dp
, rm
);
3247 if ((insn
& 0x03e00000) == 0x00400000) {
3248 /* two-register transfer */
3249 rn
= (insn
>> 16) & 0xf;
3250 rd
= (insn
>> 12) & 0xf;
3252 VFP_DREG_M(rm
, insn
);
3254 rm
= VFP_SREG_M(insn
);
3257 if (insn
& ARM_CP_RW_BIT
) {
3260 gen_mov_F0_vreg(0, rm
* 2);
3261 tmp
= gen_vfp_mrs();
3262 store_reg(s
, rd
, tmp
);
3263 gen_mov_F0_vreg(0, rm
* 2 + 1);
3264 tmp
= gen_vfp_mrs();
3265 store_reg(s
, rn
, tmp
);
3267 gen_mov_F0_vreg(0, rm
);
3268 tmp
= gen_vfp_mrs();
3269 store_reg(s
, rd
, tmp
);
3270 gen_mov_F0_vreg(0, rm
+ 1);
3271 tmp
= gen_vfp_mrs();
3272 store_reg(s
, rn
, tmp
);
3277 tmp
= load_reg(s
, rd
);
3279 gen_mov_vreg_F0(0, rm
* 2);
3280 tmp
= load_reg(s
, rn
);
3282 gen_mov_vreg_F0(0, rm
* 2 + 1);
3284 tmp
= load_reg(s
, rd
);
3286 gen_mov_vreg_F0(0, rm
);
3287 tmp
= load_reg(s
, rn
);
3289 gen_mov_vreg_F0(0, rm
+ 1);
3294 rn
= (insn
>> 16) & 0xf;
3296 VFP_DREG_D(rd
, insn
);
3298 rd
= VFP_SREG_D(insn
);
3299 if ((insn
& 0x01200000) == 0x01000000) {
3300 /* Single load/store */
3301 offset
= (insn
& 0xff) << 2;
3302 if ((insn
& (1 << 23)) == 0)
3304 if (s
->thumb
&& rn
== 15) {
3305 /* This is actually UNPREDICTABLE */
3306 addr
= tcg_temp_new_i32();
3307 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3309 addr
= load_reg(s
, rn
);
3311 tcg_gen_addi_i32(addr
, addr
, offset
);
3312 if (insn
& (1 << 20)) {
3313 gen_vfp_ld(s
, dp
, addr
);
3314 gen_mov_vreg_F0(dp
, rd
);
3316 gen_mov_F0_vreg(dp
, rd
);
3317 gen_vfp_st(s
, dp
, addr
);
3319 tcg_temp_free_i32(addr
);
3321 /* load/store multiple */
3322 int w
= insn
& (1 << 21);
3324 n
= (insn
>> 1) & 0x7f;
3328 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3329 /* P == U , W == 1 => UNDEF */
3332 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3333 /* UNPREDICTABLE cases for bad immediates: we choose to
3334 * UNDEF to avoid generating huge numbers of TCG ops
3338 if (rn
== 15 && w
) {
3339 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3343 if (s
->thumb
&& rn
== 15) {
3344 /* This is actually UNPREDICTABLE */
3345 addr
= tcg_temp_new_i32();
3346 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3348 addr
= load_reg(s
, rn
);
3350 if (insn
& (1 << 24)) /* pre-decrement */
3351 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3357 for (i
= 0; i
< n
; i
++) {
3358 if (insn
& ARM_CP_RW_BIT
) {
3360 gen_vfp_ld(s
, dp
, addr
);
3361 gen_mov_vreg_F0(dp
, rd
+ i
);
3364 gen_mov_F0_vreg(dp
, rd
+ i
);
3365 gen_vfp_st(s
, dp
, addr
);
3367 tcg_gen_addi_i32(addr
, addr
, offset
);
3371 if (insn
& (1 << 24))
3372 offset
= -offset
* n
;
3373 else if (dp
&& (insn
& 1))
3379 tcg_gen_addi_i32(addr
, addr
, offset
);
3380 store_reg(s
, rn
, addr
);
3382 tcg_temp_free_i32(addr
);
3388 /* Should never happen. */
3394 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3396 TranslationBlock
*tb
;
3399 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3401 gen_set_pc_im(dest
);
3402 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3404 gen_set_pc_im(dest
);
3409 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3411 if (unlikely(s
->singlestep_enabled
)) {
3412 /* An indirect jump so that we still trigger the debug exception. */
3417 gen_goto_tb(s
, 0, dest
);
3418 s
->is_jmp
= DISAS_TB_JUMP
;
3422 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3425 tcg_gen_sari_i32(t0
, t0
, 16);
3429 tcg_gen_sari_i32(t1
, t1
, 16);
3432 tcg_gen_mul_i32(t0
, t0
, t1
);
3435 /* Return the mask of PSR bits set by a MSR instruction. */
3436 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3440 if (flags
& (1 << 0))
3442 if (flags
& (1 << 1))
3444 if (flags
& (1 << 2))
3446 if (flags
& (1 << 3))
3449 /* Mask out undefined bits. */
3450 mask
&= ~CPSR_RESERVED
;
3451 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3453 if (!arm_feature(env
, ARM_FEATURE_V5
))
3454 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3455 if (!arm_feature(env
, ARM_FEATURE_V6
))
3456 mask
&= ~(CPSR_E
| CPSR_GE
);
3457 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3459 /* Mask out execution state bits. */
3462 /* Mask out privileged bits. */
3468 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3469 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3473 /* ??? This is also undefined in system mode. */
3477 tmp
= load_cpu_field(spsr
);
3478 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3479 tcg_gen_andi_i32(t0
, t0
, mask
);
3480 tcg_gen_or_i32(tmp
, tmp
, t0
);
3481 store_cpu_field(tmp
, spsr
);
3483 gen_set_cpsr(t0
, mask
);
3485 tcg_temp_free_i32(t0
);
3490 /* Returns nonzero if access to the PSR is not permitted. */
3491 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3494 tmp
= tcg_temp_new_i32();
3495 tcg_gen_movi_i32(tmp
, val
);
3496 return gen_set_psr(s
, mask
, spsr
, tmp
);
3499 /* Generate an old-style exception return. Marks pc as dead. */
3500 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3503 store_reg(s
, 15, pc
);
3504 tmp
= load_cpu_field(spsr
);
3505 gen_set_cpsr(tmp
, 0xffffffff);
3506 tcg_temp_free_i32(tmp
);
3507 s
->is_jmp
= DISAS_UPDATE
;
3510 /* Generate a v6 exception return. Marks both values as dead. */
3511 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3513 gen_set_cpsr(cpsr
, 0xffffffff);
3514 tcg_temp_free_i32(cpsr
);
3515 store_reg(s
, 15, pc
);
3516 s
->is_jmp
= DISAS_UPDATE
;
3520 gen_set_condexec (DisasContext
*s
)
3522 if (s
->condexec_mask
) {
3523 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3524 TCGv tmp
= tcg_temp_new_i32();
3525 tcg_gen_movi_i32(tmp
, val
);
3526 store_cpu_field(tmp
, condexec_bits
);
3530 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3532 gen_set_condexec(s
);
3533 gen_set_pc_im(s
->pc
- offset
);
3534 gen_exception(excp
);
3535 s
->is_jmp
= DISAS_JUMP
;
3538 static void gen_nop_hint(DisasContext
*s
, int val
)
3542 gen_set_pc_im(s
->pc
);
3543 s
->is_jmp
= DISAS_WFI
;
3547 /* TODO: Implement SEV and WFE. May help SMP performance. */
3553 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3555 static inline void gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3558 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3559 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3560 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3565 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3568 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3569 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3570 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3575 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3576 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3577 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3578 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3579 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3581 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3582 switch ((size << 1) | u) { \
3584 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3587 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3590 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3593 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3596 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3599 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3601 default: return 1; \
3604 #define GEN_NEON_INTEGER_OP(name) do { \
3605 switch ((size << 1) | u) { \
3607 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3610 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3613 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3616 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3619 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3622 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3624 default: return 1; \
3627 static TCGv
neon_load_scratch(int scratch
)
3629 TCGv tmp
= tcg_temp_new_i32();
3630 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3634 static void neon_store_scratch(int scratch
, TCGv var
)
3636 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3637 tcg_temp_free_i32(var
);
3640 static inline TCGv
neon_get_scalar(int size
, int reg
)
3644 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3646 gen_neon_dup_high16(tmp
);
3648 gen_neon_dup_low16(tmp
);
3651 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3656 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3659 if (!q
&& size
== 2) {
3662 tmp
= tcg_const_i32(rd
);
3663 tmp2
= tcg_const_i32(rm
);
3667 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3670 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3673 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3681 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3684 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3690 tcg_temp_free_i32(tmp
);
3691 tcg_temp_free_i32(tmp2
);
3695 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3698 if (!q
&& size
== 2) {
3701 tmp
= tcg_const_i32(rd
);
3702 tmp2
= tcg_const_i32(rm
);
3706 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3709 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3712 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3720 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3723 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3729 tcg_temp_free_i32(tmp
);
3730 tcg_temp_free_i32(tmp2
);
3734 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3738 rd
= tcg_temp_new_i32();
3739 tmp
= tcg_temp_new_i32();
3741 tcg_gen_shli_i32(rd
, t0
, 8);
3742 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3743 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3744 tcg_gen_or_i32(rd
, rd
, tmp
);
3746 tcg_gen_shri_i32(t1
, t1
, 8);
3747 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3748 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3749 tcg_gen_or_i32(t1
, t1
, tmp
);
3750 tcg_gen_mov_i32(t0
, rd
);
3752 tcg_temp_free_i32(tmp
);
3753 tcg_temp_free_i32(rd
);
3756 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3760 rd
= tcg_temp_new_i32();
3761 tmp
= tcg_temp_new_i32();
3763 tcg_gen_shli_i32(rd
, t0
, 16);
3764 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3765 tcg_gen_or_i32(rd
, rd
, tmp
);
3766 tcg_gen_shri_i32(t1
, t1
, 16);
3767 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3768 tcg_gen_or_i32(t1
, t1
, tmp
);
3769 tcg_gen_mov_i32(t0
, rd
);
3771 tcg_temp_free_i32(tmp
);
3772 tcg_temp_free_i32(rd
);
3780 } neon_ls_element_type
[11] = {
3794 /* Translate a NEON load/store element instruction. Return nonzero if the
3795 instruction is invalid. */
3796 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3815 if (!s
->vfp_enabled
)
3817 VFP_DREG_D(rd
, insn
);
3818 rn
= (insn
>> 16) & 0xf;
3820 load
= (insn
& (1 << 21)) != 0;
3821 if ((insn
& (1 << 23)) == 0) {
3822 /* Load store all elements. */
3823 op
= (insn
>> 8) & 0xf;
3824 size
= (insn
>> 6) & 3;
3827 /* Catch UNDEF cases for bad values of align field */
3830 if (((insn
>> 5) & 1) == 1) {
3835 if (((insn
>> 4) & 3) == 3) {
3842 nregs
= neon_ls_element_type
[op
].nregs
;
3843 interleave
= neon_ls_element_type
[op
].interleave
;
3844 spacing
= neon_ls_element_type
[op
].spacing
;
3845 if (size
== 3 && (interleave
| spacing
) != 1)
3847 addr
= tcg_temp_new_i32();
3848 load_reg_var(s
, addr
, rn
);
3849 stride
= (1 << size
) * interleave
;
3850 for (reg
= 0; reg
< nregs
; reg
++) {
3851 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3852 load_reg_var(s
, addr
, rn
);
3853 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3854 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3855 load_reg_var(s
, addr
, rn
);
3856 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3860 tmp64
= gen_ld64(addr
, IS_USER(s
));
3861 neon_store_reg64(tmp64
, rd
);
3862 tcg_temp_free_i64(tmp64
);
3864 tmp64
= tcg_temp_new_i64();
3865 neon_load_reg64(tmp64
, rd
);
3866 gen_st64(tmp64
, addr
, IS_USER(s
));
3868 tcg_gen_addi_i32(addr
, addr
, stride
);
3870 for (pass
= 0; pass
< 2; pass
++) {
3873 tmp
= gen_ld32(addr
, IS_USER(s
));
3874 neon_store_reg(rd
, pass
, tmp
);
3876 tmp
= neon_load_reg(rd
, pass
);
3877 gen_st32(tmp
, addr
, IS_USER(s
));
3879 tcg_gen_addi_i32(addr
, addr
, stride
);
3880 } else if (size
== 1) {
3882 tmp
= gen_ld16u(addr
, IS_USER(s
));
3883 tcg_gen_addi_i32(addr
, addr
, stride
);
3884 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3885 tcg_gen_addi_i32(addr
, addr
, stride
);
3886 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3887 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3888 tcg_temp_free_i32(tmp2
);
3889 neon_store_reg(rd
, pass
, tmp
);
3891 tmp
= neon_load_reg(rd
, pass
);
3892 tmp2
= tcg_temp_new_i32();
3893 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3894 gen_st16(tmp
, addr
, IS_USER(s
));
3895 tcg_gen_addi_i32(addr
, addr
, stride
);
3896 gen_st16(tmp2
, addr
, IS_USER(s
));
3897 tcg_gen_addi_i32(addr
, addr
, stride
);
3899 } else /* size == 0 */ {
3902 for (n
= 0; n
< 4; n
++) {
3903 tmp
= gen_ld8u(addr
, IS_USER(s
));
3904 tcg_gen_addi_i32(addr
, addr
, stride
);
3908 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3909 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3910 tcg_temp_free_i32(tmp
);
3913 neon_store_reg(rd
, pass
, tmp2
);
3915 tmp2
= neon_load_reg(rd
, pass
);
3916 for (n
= 0; n
< 4; n
++) {
3917 tmp
= tcg_temp_new_i32();
3919 tcg_gen_mov_i32(tmp
, tmp2
);
3921 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3923 gen_st8(tmp
, addr
, IS_USER(s
));
3924 tcg_gen_addi_i32(addr
, addr
, stride
);
3926 tcg_temp_free_i32(tmp2
);
3933 tcg_temp_free_i32(addr
);
3936 size
= (insn
>> 10) & 3;
3938 /* Load single element to all lanes. */
3939 int a
= (insn
>> 4) & 1;
3943 size
= (insn
>> 6) & 3;
3944 nregs
= ((insn
>> 8) & 3) + 1;
3947 if (nregs
!= 4 || a
== 0) {
3950 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3953 if (nregs
== 1 && a
== 1 && size
== 0) {
3956 if (nregs
== 3 && a
== 1) {
3959 addr
= tcg_temp_new_i32();
3960 load_reg_var(s
, addr
, rn
);
3962 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3963 tmp
= gen_load_and_replicate(s
, addr
, size
);
3964 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3965 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3966 if (insn
& (1 << 5)) {
3967 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
3968 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
3970 tcg_temp_free_i32(tmp
);
3972 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
3973 stride
= (insn
& (1 << 5)) ? 2 : 1;
3974 for (reg
= 0; reg
< nregs
; reg
++) {
3975 tmp
= gen_load_and_replicate(s
, addr
, size
);
3976 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3977 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3978 tcg_temp_free_i32(tmp
);
3979 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3983 tcg_temp_free_i32(addr
);
3984 stride
= (1 << size
) * nregs
;
3986 /* Single element. */
3987 int idx
= (insn
>> 4) & 0xf;
3988 pass
= (insn
>> 7) & 1;
3991 shift
= ((insn
>> 5) & 3) * 8;
3995 shift
= ((insn
>> 6) & 1) * 16;
3996 stride
= (insn
& (1 << 5)) ? 2 : 1;
4000 stride
= (insn
& (1 << 6)) ? 2 : 1;
4005 nregs
= ((insn
>> 8) & 3) + 1;
4006 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4009 if (((idx
& (1 << size
)) != 0) ||
4010 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4015 if ((idx
& 1) != 0) {
4020 if (size
== 2 && (idx
& 2) != 0) {
4025 if ((size
== 2) && ((idx
& 3) == 3)) {
4032 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4033 /* Attempts to write off the end of the register file
4034 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4035 * the neon_load_reg() would write off the end of the array.
4039 addr
= tcg_temp_new_i32();
4040 load_reg_var(s
, addr
, rn
);
4041 for (reg
= 0; reg
< nregs
; reg
++) {
4045 tmp
= gen_ld8u(addr
, IS_USER(s
));
4048 tmp
= gen_ld16u(addr
, IS_USER(s
));
4051 tmp
= gen_ld32(addr
, IS_USER(s
));
4053 default: /* Avoid compiler warnings. */
4057 tmp2
= neon_load_reg(rd
, pass
);
4058 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4059 shift
, size
? 16 : 8);
4060 tcg_temp_free_i32(tmp2
);
4062 neon_store_reg(rd
, pass
, tmp
);
4063 } else { /* Store */
4064 tmp
= neon_load_reg(rd
, pass
);
4066 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4069 gen_st8(tmp
, addr
, IS_USER(s
));
4072 gen_st16(tmp
, addr
, IS_USER(s
));
4075 gen_st32(tmp
, addr
, IS_USER(s
));
4080 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4082 tcg_temp_free_i32(addr
);
4083 stride
= nregs
* (1 << size
);
4089 base
= load_reg(s
, rn
);
4091 tcg_gen_addi_i32(base
, base
, stride
);
4094 index
= load_reg(s
, rm
);
4095 tcg_gen_add_i32(base
, base
, index
);
4096 tcg_temp_free_i32(index
);
4098 store_reg(s
, rn
, base
);
4103 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4104 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4106 tcg_gen_and_i32(t
, t
, c
);
4107 tcg_gen_andc_i32(f
, f
, c
);
4108 tcg_gen_or_i32(dest
, t
, f
);
4111 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4114 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4115 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4116 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4121 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4124 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4125 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4126 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4131 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4134 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4135 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4136 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4141 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4144 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4145 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4146 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4151 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4157 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4158 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4163 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4164 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4171 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4172 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4177 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4178 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4185 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4189 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4190 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4191 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4196 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4197 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4198 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4202 tcg_temp_free_i32(src
);
4205 static inline void gen_neon_addl(int size
)
4208 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4209 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4210 case 2: tcg_gen_add_i64(CPU_V001
); break;
4215 static inline void gen_neon_subl(int size
)
4218 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4219 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4220 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4225 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4228 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4229 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4231 tcg_gen_neg_i64(var
, var
);
4237 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4240 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4241 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4246 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4250 switch ((size
<< 1) | u
) {
4251 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4252 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4253 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4254 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4256 tmp
= gen_muls_i64_i32(a
, b
);
4257 tcg_gen_mov_i64(dest
, tmp
);
4258 tcg_temp_free_i64(tmp
);
4261 tmp
= gen_mulu_i64_i32(a
, b
);
4262 tcg_gen_mov_i64(dest
, tmp
);
4263 tcg_temp_free_i64(tmp
);
4268 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4269 Don't forget to clean them now. */
4271 tcg_temp_free_i32(a
);
4272 tcg_temp_free_i32(b
);
4276 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4280 gen_neon_unarrow_sats(size
, dest
, src
);
4282 gen_neon_narrow(size
, dest
, src
);
4286 gen_neon_narrow_satu(size
, dest
, src
);
4288 gen_neon_narrow_sats(size
, dest
, src
);
4293 /* Symbolic constants for op fields for Neon 3-register same-length.
4294 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4297 #define NEON_3R_VHADD 0
4298 #define NEON_3R_VQADD 1
4299 #define NEON_3R_VRHADD 2
4300 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4301 #define NEON_3R_VHSUB 4
4302 #define NEON_3R_VQSUB 5
4303 #define NEON_3R_VCGT 6
4304 #define NEON_3R_VCGE 7
4305 #define NEON_3R_VSHL 8
4306 #define NEON_3R_VQSHL 9
4307 #define NEON_3R_VRSHL 10
4308 #define NEON_3R_VQRSHL 11
4309 #define NEON_3R_VMAX 12
4310 #define NEON_3R_VMIN 13
4311 #define NEON_3R_VABD 14
4312 #define NEON_3R_VABA 15
4313 #define NEON_3R_VADD_VSUB 16
4314 #define NEON_3R_VTST_VCEQ 17
4315 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4316 #define NEON_3R_VMUL 19
4317 #define NEON_3R_VPMAX 20
4318 #define NEON_3R_VPMIN 21
4319 #define NEON_3R_VQDMULH_VQRDMULH 22
4320 #define NEON_3R_VPADD 23
4321 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4322 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4323 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4324 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4325 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4326 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4327 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4329 static const uint8_t neon_3r_sizes
[] = {
4330 [NEON_3R_VHADD
] = 0x7,
4331 [NEON_3R_VQADD
] = 0xf,
4332 [NEON_3R_VRHADD
] = 0x7,
4333 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4334 [NEON_3R_VHSUB
] = 0x7,
4335 [NEON_3R_VQSUB
] = 0xf,
4336 [NEON_3R_VCGT
] = 0x7,
4337 [NEON_3R_VCGE
] = 0x7,
4338 [NEON_3R_VSHL
] = 0xf,
4339 [NEON_3R_VQSHL
] = 0xf,
4340 [NEON_3R_VRSHL
] = 0xf,
4341 [NEON_3R_VQRSHL
] = 0xf,
4342 [NEON_3R_VMAX
] = 0x7,
4343 [NEON_3R_VMIN
] = 0x7,
4344 [NEON_3R_VABD
] = 0x7,
4345 [NEON_3R_VABA
] = 0x7,
4346 [NEON_3R_VADD_VSUB
] = 0xf,
4347 [NEON_3R_VTST_VCEQ
] = 0x7,
4348 [NEON_3R_VML
] = 0x7,
4349 [NEON_3R_VMUL
] = 0x7,
4350 [NEON_3R_VPMAX
] = 0x7,
4351 [NEON_3R_VPMIN
] = 0x7,
4352 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4353 [NEON_3R_VPADD
] = 0x7,
4354 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4355 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4356 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4357 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4358 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4359 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4360 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4363 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4364 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4367 #define NEON_2RM_VREV64 0
4368 #define NEON_2RM_VREV32 1
4369 #define NEON_2RM_VREV16 2
4370 #define NEON_2RM_VPADDL 4
4371 #define NEON_2RM_VPADDL_U 5
4372 #define NEON_2RM_VCLS 8
4373 #define NEON_2RM_VCLZ 9
4374 #define NEON_2RM_VCNT 10
4375 #define NEON_2RM_VMVN 11
4376 #define NEON_2RM_VPADAL 12
4377 #define NEON_2RM_VPADAL_U 13
4378 #define NEON_2RM_VQABS 14
4379 #define NEON_2RM_VQNEG 15
4380 #define NEON_2RM_VCGT0 16
4381 #define NEON_2RM_VCGE0 17
4382 #define NEON_2RM_VCEQ0 18
4383 #define NEON_2RM_VCLE0 19
4384 #define NEON_2RM_VCLT0 20
4385 #define NEON_2RM_VABS 22
4386 #define NEON_2RM_VNEG 23
4387 #define NEON_2RM_VCGT0_F 24
4388 #define NEON_2RM_VCGE0_F 25
4389 #define NEON_2RM_VCEQ0_F 26
4390 #define NEON_2RM_VCLE0_F 27
4391 #define NEON_2RM_VCLT0_F 28
4392 #define NEON_2RM_VABS_F 30
4393 #define NEON_2RM_VNEG_F 31
4394 #define NEON_2RM_VSWP 32
4395 #define NEON_2RM_VTRN 33
4396 #define NEON_2RM_VUZP 34
4397 #define NEON_2RM_VZIP 35
4398 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4399 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4400 #define NEON_2RM_VSHLL 38
4401 #define NEON_2RM_VCVT_F16_F32 44
4402 #define NEON_2RM_VCVT_F32_F16 46
4403 #define NEON_2RM_VRECPE 56
4404 #define NEON_2RM_VRSQRTE 57
4405 #define NEON_2RM_VRECPE_F 58
4406 #define NEON_2RM_VRSQRTE_F 59
4407 #define NEON_2RM_VCVT_FS 60
4408 #define NEON_2RM_VCVT_FU 61
4409 #define NEON_2RM_VCVT_SF 62
4410 #define NEON_2RM_VCVT_UF 63
4412 static int neon_2rm_is_float_op(int op
)
4414 /* Return true if this neon 2reg-misc op is float-to-float */
4415 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4416 op
>= NEON_2RM_VRECPE_F
);
4419 /* Each entry in this array has bit n set if the insn allows
4420 * size value n (otherwise it will UNDEF). Since unallocated
4421 * op values will have no bits set they always UNDEF.
4423 static const uint8_t neon_2rm_sizes
[] = {
4424 [NEON_2RM_VREV64
] = 0x7,
4425 [NEON_2RM_VREV32
] = 0x3,
4426 [NEON_2RM_VREV16
] = 0x1,
4427 [NEON_2RM_VPADDL
] = 0x7,
4428 [NEON_2RM_VPADDL_U
] = 0x7,
4429 [NEON_2RM_VCLS
] = 0x7,
4430 [NEON_2RM_VCLZ
] = 0x7,
4431 [NEON_2RM_VCNT
] = 0x1,
4432 [NEON_2RM_VMVN
] = 0x1,
4433 [NEON_2RM_VPADAL
] = 0x7,
4434 [NEON_2RM_VPADAL_U
] = 0x7,
4435 [NEON_2RM_VQABS
] = 0x7,
4436 [NEON_2RM_VQNEG
] = 0x7,
4437 [NEON_2RM_VCGT0
] = 0x7,
4438 [NEON_2RM_VCGE0
] = 0x7,
4439 [NEON_2RM_VCEQ0
] = 0x7,
4440 [NEON_2RM_VCLE0
] = 0x7,
4441 [NEON_2RM_VCLT0
] = 0x7,
4442 [NEON_2RM_VABS
] = 0x7,
4443 [NEON_2RM_VNEG
] = 0x7,
4444 [NEON_2RM_VCGT0_F
] = 0x4,
4445 [NEON_2RM_VCGE0_F
] = 0x4,
4446 [NEON_2RM_VCEQ0_F
] = 0x4,
4447 [NEON_2RM_VCLE0_F
] = 0x4,
4448 [NEON_2RM_VCLT0_F
] = 0x4,
4449 [NEON_2RM_VABS_F
] = 0x4,
4450 [NEON_2RM_VNEG_F
] = 0x4,
4451 [NEON_2RM_VSWP
] = 0x1,
4452 [NEON_2RM_VTRN
] = 0x7,
4453 [NEON_2RM_VUZP
] = 0x7,
4454 [NEON_2RM_VZIP
] = 0x7,
4455 [NEON_2RM_VMOVN
] = 0x7,
4456 [NEON_2RM_VQMOVN
] = 0x7,
4457 [NEON_2RM_VSHLL
] = 0x7,
4458 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4459 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4460 [NEON_2RM_VRECPE
] = 0x4,
4461 [NEON_2RM_VRSQRTE
] = 0x4,
4462 [NEON_2RM_VRECPE_F
] = 0x4,
4463 [NEON_2RM_VRSQRTE_F
] = 0x4,
4464 [NEON_2RM_VCVT_FS
] = 0x4,
4465 [NEON_2RM_VCVT_FU
] = 0x4,
4466 [NEON_2RM_VCVT_SF
] = 0x4,
4467 [NEON_2RM_VCVT_UF
] = 0x4,
4470 /* Translate a NEON data processing instruction. Return nonzero if the
4471 instruction is invalid.
4472 We process data in a mixture of 32-bit and 64-bit chunks.
4473 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4475 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4487 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4490 if (!s
->vfp_enabled
)
4492 q
= (insn
& (1 << 6)) != 0;
4493 u
= (insn
>> 24) & 1;
4494 VFP_DREG_D(rd
, insn
);
4495 VFP_DREG_N(rn
, insn
);
4496 VFP_DREG_M(rm
, insn
);
4497 size
= (insn
>> 20) & 3;
4498 if ((insn
& (1 << 23)) == 0) {
4499 /* Three register same length. */
4500 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4501 /* Catch invalid op and bad size combinations: UNDEF */
4502 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4505 /* All insns of this form UNDEF for either this condition or the
4506 * superset of cases "Q==1"; we catch the latter later.
4508 if (q
&& ((rd
| rn
| rm
) & 1)) {
4511 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4512 /* 64-bit element instructions. */
4513 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4514 neon_load_reg64(cpu_V0
, rn
+ pass
);
4515 neon_load_reg64(cpu_V1
, rm
+ pass
);
4519 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4522 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4528 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4531 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4537 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4539 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4544 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4547 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4553 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4555 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4558 case NEON_3R_VQRSHL
:
4560 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4563 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4567 case NEON_3R_VADD_VSUB
:
4569 tcg_gen_sub_i64(CPU_V001
);
4571 tcg_gen_add_i64(CPU_V001
);
4577 neon_store_reg64(cpu_V0
, rd
+ pass
);
4586 case NEON_3R_VQRSHL
:
4589 /* Shift instruction operands are reversed. */
4604 case NEON_3R_FLOAT_ARITH
:
4605 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4607 case NEON_3R_FLOAT_MINMAX
:
4608 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4610 case NEON_3R_FLOAT_CMP
:
4612 /* no encoding for U=0 C=1x */
4616 case NEON_3R_FLOAT_ACMP
:
4621 case NEON_3R_VRECPS_VRSQRTS
:
4627 if (u
&& (size
!= 0)) {
4628 /* UNDEF on invalid size for polynomial subcase */
4633 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4641 if (pairwise
&& q
) {
4642 /* All the pairwise insns UNDEF if Q is set */
4646 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4651 tmp
= neon_load_reg(rn
, 0);
4652 tmp2
= neon_load_reg(rn
, 1);
4654 tmp
= neon_load_reg(rm
, 0);
4655 tmp2
= neon_load_reg(rm
, 1);
4659 tmp
= neon_load_reg(rn
, pass
);
4660 tmp2
= neon_load_reg(rm
, pass
);
4664 GEN_NEON_INTEGER_OP(hadd
);
4667 GEN_NEON_INTEGER_OP_ENV(qadd
);
4669 case NEON_3R_VRHADD
:
4670 GEN_NEON_INTEGER_OP(rhadd
);
4672 case NEON_3R_LOGIC
: /* Logic ops. */
4673 switch ((u
<< 2) | size
) {
4675 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4678 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4681 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4684 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4687 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4690 tmp3
= neon_load_reg(rd
, pass
);
4691 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4692 tcg_temp_free_i32(tmp3
);
4695 tmp3
= neon_load_reg(rd
, pass
);
4696 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4697 tcg_temp_free_i32(tmp3
);
4700 tmp3
= neon_load_reg(rd
, pass
);
4701 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4702 tcg_temp_free_i32(tmp3
);
4707 GEN_NEON_INTEGER_OP(hsub
);
4710 GEN_NEON_INTEGER_OP_ENV(qsub
);
4713 GEN_NEON_INTEGER_OP(cgt
);
4716 GEN_NEON_INTEGER_OP(cge
);
4719 GEN_NEON_INTEGER_OP(shl
);
4722 GEN_NEON_INTEGER_OP_ENV(qshl
);
4725 GEN_NEON_INTEGER_OP(rshl
);
4727 case NEON_3R_VQRSHL
:
4728 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4731 GEN_NEON_INTEGER_OP(max
);
4734 GEN_NEON_INTEGER_OP(min
);
4737 GEN_NEON_INTEGER_OP(abd
);
4740 GEN_NEON_INTEGER_OP(abd
);
4741 tcg_temp_free_i32(tmp2
);
4742 tmp2
= neon_load_reg(rd
, pass
);
4743 gen_neon_add(size
, tmp
, tmp2
);
4745 case NEON_3R_VADD_VSUB
:
4746 if (!u
) { /* VADD */
4747 gen_neon_add(size
, tmp
, tmp2
);
4750 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4751 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4752 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4757 case NEON_3R_VTST_VCEQ
:
4758 if (!u
) { /* VTST */
4760 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4761 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4762 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4767 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4768 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4769 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4774 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4776 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4777 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4778 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4781 tcg_temp_free_i32(tmp2
);
4782 tmp2
= neon_load_reg(rd
, pass
);
4784 gen_neon_rsb(size
, tmp
, tmp2
);
4786 gen_neon_add(size
, tmp
, tmp2
);
4790 if (u
) { /* polynomial */
4791 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4792 } else { /* Integer */
4794 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4795 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4796 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4802 GEN_NEON_INTEGER_OP(pmax
);
4805 GEN_NEON_INTEGER_OP(pmin
);
4807 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4808 if (!u
) { /* VQDMULH */
4811 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4814 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4818 } else { /* VQRDMULH */
4821 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4824 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4832 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4833 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4834 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4838 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4840 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4841 switch ((u
<< 2) | size
) {
4844 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4847 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
4850 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
4855 tcg_temp_free_ptr(fpstatus
);
4858 case NEON_3R_FLOAT_MULTIPLY
:
4860 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4861 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
4863 tcg_temp_free_i32(tmp2
);
4864 tmp2
= neon_load_reg(rd
, pass
);
4866 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4868 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
4871 tcg_temp_free_ptr(fpstatus
);
4874 case NEON_3R_FLOAT_CMP
:
4876 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4878 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
4881 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4883 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4886 tcg_temp_free_ptr(fpstatus
);
4889 case NEON_3R_FLOAT_ACMP
:
4891 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4893 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4895 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4897 tcg_temp_free_ptr(fpstatus
);
4900 case NEON_3R_FLOAT_MINMAX
:
4902 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4904 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
4906 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
4908 tcg_temp_free_ptr(fpstatus
);
4911 case NEON_3R_VRECPS_VRSQRTS
:
4913 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4915 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4919 /* VFMA, VFMS: fused multiply-add */
4920 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4921 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
4924 gen_helper_vfp_negs(tmp
, tmp
);
4926 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
4927 tcg_temp_free_i32(tmp3
);
4928 tcg_temp_free_ptr(fpstatus
);
4934 tcg_temp_free_i32(tmp2
);
4936 /* Save the result. For elementwise operations we can put it
4937 straight into the destination register. For pairwise operations
4938 we have to be careful to avoid clobbering the source operands. */
4939 if (pairwise
&& rd
== rm
) {
4940 neon_store_scratch(pass
, tmp
);
4942 neon_store_reg(rd
, pass
, tmp
);
4946 if (pairwise
&& rd
== rm
) {
4947 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4948 tmp
= neon_load_scratch(pass
);
4949 neon_store_reg(rd
, pass
, tmp
);
4952 /* End of 3 register same size operations. */
4953 } else if (insn
& (1 << 4)) {
4954 if ((insn
& 0x00380080) != 0) {
4955 /* Two registers and shift. */
4956 op
= (insn
>> 8) & 0xf;
4957 if (insn
& (1 << 7)) {
4965 while ((insn
& (1 << (size
+ 19))) == 0)
4968 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
4969 /* To avoid excessive duplication of ops we implement shift
4970 by immediate using the variable shift operations. */
4972 /* Shift by immediate:
4973 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4974 if (q
&& ((rd
| rm
) & 1)) {
4977 if (!u
&& (op
== 4 || op
== 6)) {
4980 /* Right shifts are encoded as N - shift, where N is the
4981 element size in bits. */
4983 shift
= shift
- (1 << (size
+ 3));
4991 imm
= (uint8_t) shift
;
4996 imm
= (uint16_t) shift
;
5007 for (pass
= 0; pass
< count
; pass
++) {
5009 neon_load_reg64(cpu_V0
, rm
+ pass
);
5010 tcg_gen_movi_i64(cpu_V1
, imm
);
5015 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5017 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5022 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5024 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5027 case 5: /* VSHL, VSLI */
5028 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5030 case 6: /* VQSHLU */
5031 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5036 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5039 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5044 if (op
== 1 || op
== 3) {
5046 neon_load_reg64(cpu_V1
, rd
+ pass
);
5047 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5048 } else if (op
== 4 || (op
== 5 && u
)) {
5050 neon_load_reg64(cpu_V1
, rd
+ pass
);
5052 if (shift
< -63 || shift
> 63) {
5056 mask
= 0xffffffffffffffffull
>> -shift
;
5058 mask
= 0xffffffffffffffffull
<< shift
;
5061 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5062 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5064 neon_store_reg64(cpu_V0
, rd
+ pass
);
5065 } else { /* size < 3 */
5066 /* Operands in T0 and T1. */
5067 tmp
= neon_load_reg(rm
, pass
);
5068 tmp2
= tcg_temp_new_i32();
5069 tcg_gen_movi_i32(tmp2
, imm
);
5073 GEN_NEON_INTEGER_OP(shl
);
5077 GEN_NEON_INTEGER_OP(rshl
);
5080 case 5: /* VSHL, VSLI */
5082 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5083 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5084 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5088 case 6: /* VQSHLU */
5091 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5095 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5099 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5107 GEN_NEON_INTEGER_OP_ENV(qshl
);
5110 tcg_temp_free_i32(tmp2
);
5112 if (op
== 1 || op
== 3) {
5114 tmp2
= neon_load_reg(rd
, pass
);
5115 gen_neon_add(size
, tmp
, tmp2
);
5116 tcg_temp_free_i32(tmp2
);
5117 } else if (op
== 4 || (op
== 5 && u
)) {
5122 mask
= 0xff >> -shift
;
5124 mask
= (uint8_t)(0xff << shift
);
5130 mask
= 0xffff >> -shift
;
5132 mask
= (uint16_t)(0xffff << shift
);
5136 if (shift
< -31 || shift
> 31) {
5140 mask
= 0xffffffffu
>> -shift
;
5142 mask
= 0xffffffffu
<< shift
;
5148 tmp2
= neon_load_reg(rd
, pass
);
5149 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5150 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5151 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5152 tcg_temp_free_i32(tmp2
);
5154 neon_store_reg(rd
, pass
, tmp
);
5157 } else if (op
< 10) {
5158 /* Shift by immediate and narrow:
5159 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5160 int input_unsigned
= (op
== 8) ? !u
: u
;
5164 shift
= shift
- (1 << (size
+ 3));
5167 tmp64
= tcg_const_i64(shift
);
5168 neon_load_reg64(cpu_V0
, rm
);
5169 neon_load_reg64(cpu_V1
, rm
+ 1);
5170 for (pass
= 0; pass
< 2; pass
++) {
5178 if (input_unsigned
) {
5179 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5181 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5184 if (input_unsigned
) {
5185 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5187 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5190 tmp
= tcg_temp_new_i32();
5191 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5192 neon_store_reg(rd
, pass
, tmp
);
5194 tcg_temp_free_i64(tmp64
);
5197 imm
= (uint16_t)shift
;
5201 imm
= (uint32_t)shift
;
5203 tmp2
= tcg_const_i32(imm
);
5204 tmp4
= neon_load_reg(rm
+ 1, 0);
5205 tmp5
= neon_load_reg(rm
+ 1, 1);
5206 for (pass
= 0; pass
< 2; pass
++) {
5208 tmp
= neon_load_reg(rm
, 0);
5212 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5215 tmp3
= neon_load_reg(rm
, 1);
5219 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5221 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5222 tcg_temp_free_i32(tmp
);
5223 tcg_temp_free_i32(tmp3
);
5224 tmp
= tcg_temp_new_i32();
5225 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5226 neon_store_reg(rd
, pass
, tmp
);
5228 tcg_temp_free_i32(tmp2
);
5230 } else if (op
== 10) {
5232 if (q
|| (rd
& 1)) {
5235 tmp
= neon_load_reg(rm
, 0);
5236 tmp2
= neon_load_reg(rm
, 1);
5237 for (pass
= 0; pass
< 2; pass
++) {
5241 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5244 /* The shift is less than the width of the source
5245 type, so we can just shift the whole register. */
5246 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5247 /* Widen the result of shift: we need to clear
5248 * the potential overflow bits resulting from
5249 * left bits of the narrow input appearing as
5250 * right bits of left the neighbour narrow
5252 if (size
< 2 || !u
) {
5255 imm
= (0xffu
>> (8 - shift
));
5257 } else if (size
== 1) {
5258 imm
= 0xffff >> (16 - shift
);
5261 imm
= 0xffffffff >> (32 - shift
);
5264 imm64
= imm
| (((uint64_t)imm
) << 32);
5268 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5271 neon_store_reg64(cpu_V0
, rd
+ pass
);
5273 } else if (op
>= 14) {
5274 /* VCVT fixed-point. */
5275 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5278 /* We have already masked out the must-be-1 top bit of imm6,
5279 * hence this 32-shift where the ARM ARM has 64-imm6.
5282 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5283 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5286 gen_vfp_ulto(0, shift
, 1);
5288 gen_vfp_slto(0, shift
, 1);
5291 gen_vfp_toul(0, shift
, 1);
5293 gen_vfp_tosl(0, shift
, 1);
5295 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5300 } else { /* (insn & 0x00380080) == 0 */
5302 if (q
&& (rd
& 1)) {
5306 op
= (insn
>> 8) & 0xf;
5307 /* One register and immediate. */
5308 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5309 invert
= (insn
& (1 << 5)) != 0;
5310 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5311 * We choose to not special-case this and will behave as if a
5312 * valid constant encoding of 0 had been given.
5331 imm
= (imm
<< 8) | (imm
<< 24);
5334 imm
= (imm
<< 8) | 0xff;
5337 imm
= (imm
<< 16) | 0xffff;
5340 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5348 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5349 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5355 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5356 if (op
& 1 && op
< 12) {
5357 tmp
= neon_load_reg(rd
, pass
);
5359 /* The immediate value has already been inverted, so
5361 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5363 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5367 tmp
= tcg_temp_new_i32();
5368 if (op
== 14 && invert
) {
5372 for (n
= 0; n
< 4; n
++) {
5373 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5374 val
|= 0xff << (n
* 8);
5376 tcg_gen_movi_i32(tmp
, val
);
5378 tcg_gen_movi_i32(tmp
, imm
);
5381 neon_store_reg(rd
, pass
, tmp
);
5384 } else { /* (insn & 0x00800010 == 0x00800000) */
5386 op
= (insn
>> 8) & 0xf;
5387 if ((insn
& (1 << 6)) == 0) {
5388 /* Three registers of different lengths. */
5392 /* undefreq: bit 0 : UNDEF if size != 0
5393 * bit 1 : UNDEF if size == 0
5394 * bit 2 : UNDEF if U == 1
5395 * Note that [1:0] set implies 'always UNDEF'
5398 /* prewiden, src1_wide, src2_wide, undefreq */
5399 static const int neon_3reg_wide
[16][4] = {
5400 {1, 0, 0, 0}, /* VADDL */
5401 {1, 1, 0, 0}, /* VADDW */
5402 {1, 0, 0, 0}, /* VSUBL */
5403 {1, 1, 0, 0}, /* VSUBW */
5404 {0, 1, 1, 0}, /* VADDHN */
5405 {0, 0, 0, 0}, /* VABAL */
5406 {0, 1, 1, 0}, /* VSUBHN */
5407 {0, 0, 0, 0}, /* VABDL */
5408 {0, 0, 0, 0}, /* VMLAL */
5409 {0, 0, 0, 6}, /* VQDMLAL */
5410 {0, 0, 0, 0}, /* VMLSL */
5411 {0, 0, 0, 6}, /* VQDMLSL */
5412 {0, 0, 0, 0}, /* Integer VMULL */
5413 {0, 0, 0, 2}, /* VQDMULL */
5414 {0, 0, 0, 5}, /* Polynomial VMULL */
5415 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5418 prewiden
= neon_3reg_wide
[op
][0];
5419 src1_wide
= neon_3reg_wide
[op
][1];
5420 src2_wide
= neon_3reg_wide
[op
][2];
5421 undefreq
= neon_3reg_wide
[op
][3];
5423 if (((undefreq
& 1) && (size
!= 0)) ||
5424 ((undefreq
& 2) && (size
== 0)) ||
5425 ((undefreq
& 4) && u
)) {
5428 if ((src1_wide
&& (rn
& 1)) ||
5429 (src2_wide
&& (rm
& 1)) ||
5430 (!src2_wide
&& (rd
& 1))) {
5434 /* Avoid overlapping operands. Wide source operands are
5435 always aligned so will never overlap with wide
5436 destinations in problematic ways. */
5437 if (rd
== rm
&& !src2_wide
) {
5438 tmp
= neon_load_reg(rm
, 1);
5439 neon_store_scratch(2, tmp
);
5440 } else if (rd
== rn
&& !src1_wide
) {
5441 tmp
= neon_load_reg(rn
, 1);
5442 neon_store_scratch(2, tmp
);
5445 for (pass
= 0; pass
< 2; pass
++) {
5447 neon_load_reg64(cpu_V0
, rn
+ pass
);
5450 if (pass
== 1 && rd
== rn
) {
5451 tmp
= neon_load_scratch(2);
5453 tmp
= neon_load_reg(rn
, pass
);
5456 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5460 neon_load_reg64(cpu_V1
, rm
+ pass
);
5463 if (pass
== 1 && rd
== rm
) {
5464 tmp2
= neon_load_scratch(2);
5466 tmp2
= neon_load_reg(rm
, pass
);
5469 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5473 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5474 gen_neon_addl(size
);
5476 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5477 gen_neon_subl(size
);
5479 case 5: case 7: /* VABAL, VABDL */
5480 switch ((size
<< 1) | u
) {
5482 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5485 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5488 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5491 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5494 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5497 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5501 tcg_temp_free_i32(tmp2
);
5502 tcg_temp_free_i32(tmp
);
5504 case 8: case 9: case 10: case 11: case 12: case 13:
5505 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5506 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5508 case 14: /* Polynomial VMULL */
5509 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5510 tcg_temp_free_i32(tmp2
);
5511 tcg_temp_free_i32(tmp
);
5513 default: /* 15 is RESERVED: caught earlier */
5518 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5519 neon_store_reg64(cpu_V0
, rd
+ pass
);
5520 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5522 neon_load_reg64(cpu_V1
, rd
+ pass
);
5524 case 10: /* VMLSL */
5525 gen_neon_negl(cpu_V0
, size
);
5527 case 5: case 8: /* VABAL, VMLAL */
5528 gen_neon_addl(size
);
5530 case 9: case 11: /* VQDMLAL, VQDMLSL */
5531 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5533 gen_neon_negl(cpu_V0
, size
);
5535 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5540 neon_store_reg64(cpu_V0
, rd
+ pass
);
5541 } else if (op
== 4 || op
== 6) {
5542 /* Narrowing operation. */
5543 tmp
= tcg_temp_new_i32();
5547 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5550 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5553 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5554 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5561 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5564 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5567 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5568 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5569 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5577 neon_store_reg(rd
, 0, tmp3
);
5578 neon_store_reg(rd
, 1, tmp
);
5581 /* Write back the result. */
5582 neon_store_reg64(cpu_V0
, rd
+ pass
);
5586 /* Two registers and a scalar. NB that for ops of this form
5587 * the ARM ARM labels bit 24 as Q, but it is in our variable
5594 case 1: /* Float VMLA scalar */
5595 case 5: /* Floating point VMLS scalar */
5596 case 9: /* Floating point VMUL scalar */
5601 case 0: /* Integer VMLA scalar */
5602 case 4: /* Integer VMLS scalar */
5603 case 8: /* Integer VMUL scalar */
5604 case 12: /* VQDMULH scalar */
5605 case 13: /* VQRDMULH scalar */
5606 if (u
&& ((rd
| rn
) & 1)) {
5609 tmp
= neon_get_scalar(size
, rm
);
5610 neon_store_scratch(0, tmp
);
5611 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5612 tmp
= neon_load_scratch(0);
5613 tmp2
= neon_load_reg(rn
, pass
);
5616 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5618 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5620 } else if (op
== 13) {
5622 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5624 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5626 } else if (op
& 1) {
5627 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5628 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5629 tcg_temp_free_ptr(fpstatus
);
5632 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5633 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5634 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5638 tcg_temp_free_i32(tmp2
);
5641 tmp2
= neon_load_reg(rd
, pass
);
5644 gen_neon_add(size
, tmp
, tmp2
);
5648 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5649 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5650 tcg_temp_free_ptr(fpstatus
);
5654 gen_neon_rsb(size
, tmp
, tmp2
);
5658 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5659 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5660 tcg_temp_free_ptr(fpstatus
);
5666 tcg_temp_free_i32(tmp2
);
5668 neon_store_reg(rd
, pass
, tmp
);
5671 case 3: /* VQDMLAL scalar */
5672 case 7: /* VQDMLSL scalar */
5673 case 11: /* VQDMULL scalar */
5678 case 2: /* VMLAL sclar */
5679 case 6: /* VMLSL scalar */
5680 case 10: /* VMULL scalar */
5684 tmp2
= neon_get_scalar(size
, rm
);
5685 /* We need a copy of tmp2 because gen_neon_mull
5686 * deletes it during pass 0. */
5687 tmp4
= tcg_temp_new_i32();
5688 tcg_gen_mov_i32(tmp4
, tmp2
);
5689 tmp3
= neon_load_reg(rn
, 1);
5691 for (pass
= 0; pass
< 2; pass
++) {
5693 tmp
= neon_load_reg(rn
, 0);
5698 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5700 neon_load_reg64(cpu_V1
, rd
+ pass
);
5704 gen_neon_negl(cpu_V0
, size
);
5707 gen_neon_addl(size
);
5710 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5712 gen_neon_negl(cpu_V0
, size
);
5714 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5720 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5725 neon_store_reg64(cpu_V0
, rd
+ pass
);
5730 default: /* 14 and 15 are RESERVED */
5734 } else { /* size == 3 */
5737 imm
= (insn
>> 8) & 0xf;
5742 if (q
&& ((rd
| rn
| rm
) & 1)) {
5747 neon_load_reg64(cpu_V0
, rn
);
5749 neon_load_reg64(cpu_V1
, rn
+ 1);
5751 } else if (imm
== 8) {
5752 neon_load_reg64(cpu_V0
, rn
+ 1);
5754 neon_load_reg64(cpu_V1
, rm
);
5757 tmp64
= tcg_temp_new_i64();
5759 neon_load_reg64(cpu_V0
, rn
);
5760 neon_load_reg64(tmp64
, rn
+ 1);
5762 neon_load_reg64(cpu_V0
, rn
+ 1);
5763 neon_load_reg64(tmp64
, rm
);
5765 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5766 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5767 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5769 neon_load_reg64(cpu_V1
, rm
);
5771 neon_load_reg64(cpu_V1
, rm
+ 1);
5774 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5775 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5776 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5777 tcg_temp_free_i64(tmp64
);
5780 neon_load_reg64(cpu_V0
, rn
);
5781 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5782 neon_load_reg64(cpu_V1
, rm
);
5783 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5784 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5786 neon_store_reg64(cpu_V0
, rd
);
5788 neon_store_reg64(cpu_V1
, rd
+ 1);
5790 } else if ((insn
& (1 << 11)) == 0) {
5791 /* Two register misc. */
5792 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5793 size
= (insn
>> 18) & 3;
5794 /* UNDEF for unknown op values and bad op-size combinations */
5795 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5798 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5799 q
&& ((rm
| rd
) & 1)) {
5803 case NEON_2RM_VREV64
:
5804 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5805 tmp
= neon_load_reg(rm
, pass
* 2);
5806 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5808 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5809 case 1: gen_swap_half(tmp
); break;
5810 case 2: /* no-op */ break;
5813 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5815 neon_store_reg(rd
, pass
* 2, tmp2
);
5818 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5819 case 1: gen_swap_half(tmp2
); break;
5822 neon_store_reg(rd
, pass
* 2, tmp2
);
5826 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5827 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5828 for (pass
= 0; pass
< q
+ 1; pass
++) {
5829 tmp
= neon_load_reg(rm
, pass
* 2);
5830 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5831 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5832 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5834 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5835 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5836 case 2: tcg_gen_add_i64(CPU_V001
); break;
5839 if (op
>= NEON_2RM_VPADAL
) {
5841 neon_load_reg64(cpu_V1
, rd
+ pass
);
5842 gen_neon_addl(size
);
5844 neon_store_reg64(cpu_V0
, rd
+ pass
);
5850 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5851 tmp
= neon_load_reg(rm
, n
);
5852 tmp2
= neon_load_reg(rd
, n
+ 1);
5853 neon_store_reg(rm
, n
, tmp2
);
5854 neon_store_reg(rd
, n
+ 1, tmp
);
5861 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5866 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5870 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
5871 /* also VQMOVUN; op field and mnemonics don't line up */
5876 for (pass
= 0; pass
< 2; pass
++) {
5877 neon_load_reg64(cpu_V0
, rm
+ pass
);
5878 tmp
= tcg_temp_new_i32();
5879 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
5884 neon_store_reg(rd
, 0, tmp2
);
5885 neon_store_reg(rd
, 1, tmp
);
5889 case NEON_2RM_VSHLL
:
5890 if (q
|| (rd
& 1)) {
5893 tmp
= neon_load_reg(rm
, 0);
5894 tmp2
= neon_load_reg(rm
, 1);
5895 for (pass
= 0; pass
< 2; pass
++) {
5898 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5899 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5900 neon_store_reg64(cpu_V0
, rd
+ pass
);
5903 case NEON_2RM_VCVT_F16_F32
:
5904 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5908 tmp
= tcg_temp_new_i32();
5909 tmp2
= tcg_temp_new_i32();
5910 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5911 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5912 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5913 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5914 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5915 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5916 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5917 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5918 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5919 neon_store_reg(rd
, 0, tmp2
);
5920 tmp2
= tcg_temp_new_i32();
5921 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5922 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5923 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5924 neon_store_reg(rd
, 1, tmp2
);
5925 tcg_temp_free_i32(tmp
);
5927 case NEON_2RM_VCVT_F32_F16
:
5928 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5932 tmp3
= tcg_temp_new_i32();
5933 tmp
= neon_load_reg(rm
, 0);
5934 tmp2
= neon_load_reg(rm
, 1);
5935 tcg_gen_ext16u_i32(tmp3
, tmp
);
5936 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5937 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5938 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5939 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5940 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5941 tcg_temp_free_i32(tmp
);
5942 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5943 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5944 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5945 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5946 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5947 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5948 tcg_temp_free_i32(tmp2
);
5949 tcg_temp_free_i32(tmp3
);
5953 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5954 if (neon_2rm_is_float_op(op
)) {
5955 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5956 neon_reg_offset(rm
, pass
));
5959 tmp
= neon_load_reg(rm
, pass
);
5962 case NEON_2RM_VREV32
:
5964 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5965 case 1: gen_swap_half(tmp
); break;
5969 case NEON_2RM_VREV16
:
5974 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
5975 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
5976 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
5982 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
5983 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
5984 case 2: gen_helper_clz(tmp
, tmp
); break;
5989 gen_helper_neon_cnt_u8(tmp
, tmp
);
5992 tcg_gen_not_i32(tmp
, tmp
);
5994 case NEON_2RM_VQABS
:
5997 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6000 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6003 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6008 case NEON_2RM_VQNEG
:
6011 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6014 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6017 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6022 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6023 tmp2
= tcg_const_i32(0);
6025 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6026 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6027 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6030 tcg_temp_free(tmp2
);
6031 if (op
== NEON_2RM_VCLE0
) {
6032 tcg_gen_not_i32(tmp
, tmp
);
6035 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6036 tmp2
= tcg_const_i32(0);
6038 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6039 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6040 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6043 tcg_temp_free(tmp2
);
6044 if (op
== NEON_2RM_VCLT0
) {
6045 tcg_gen_not_i32(tmp
, tmp
);
6048 case NEON_2RM_VCEQ0
:
6049 tmp2
= tcg_const_i32(0);
6051 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6052 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6053 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6056 tcg_temp_free(tmp2
);
6060 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6061 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6062 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6067 tmp2
= tcg_const_i32(0);
6068 gen_neon_rsb(size
, tmp
, tmp2
);
6069 tcg_temp_free(tmp2
);
6071 case NEON_2RM_VCGT0_F
:
6073 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6074 tmp2
= tcg_const_i32(0);
6075 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6076 tcg_temp_free(tmp2
);
6077 tcg_temp_free_ptr(fpstatus
);
6080 case NEON_2RM_VCGE0_F
:
6082 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6083 tmp2
= tcg_const_i32(0);
6084 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6085 tcg_temp_free(tmp2
);
6086 tcg_temp_free_ptr(fpstatus
);
6089 case NEON_2RM_VCEQ0_F
:
6091 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6092 tmp2
= tcg_const_i32(0);
6093 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6094 tcg_temp_free(tmp2
);
6095 tcg_temp_free_ptr(fpstatus
);
6098 case NEON_2RM_VCLE0_F
:
6100 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6101 tmp2
= tcg_const_i32(0);
6102 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6103 tcg_temp_free(tmp2
);
6104 tcg_temp_free_ptr(fpstatus
);
6107 case NEON_2RM_VCLT0_F
:
6109 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6110 tmp2
= tcg_const_i32(0);
6111 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6112 tcg_temp_free(tmp2
);
6113 tcg_temp_free_ptr(fpstatus
);
6116 case NEON_2RM_VABS_F
:
6119 case NEON_2RM_VNEG_F
:
6123 tmp2
= neon_load_reg(rd
, pass
);
6124 neon_store_reg(rm
, pass
, tmp2
);
6127 tmp2
= neon_load_reg(rd
, pass
);
6129 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6130 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6133 neon_store_reg(rm
, pass
, tmp2
);
6135 case NEON_2RM_VRECPE
:
6136 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6138 case NEON_2RM_VRSQRTE
:
6139 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6141 case NEON_2RM_VRECPE_F
:
6142 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6144 case NEON_2RM_VRSQRTE_F
:
6145 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6147 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6150 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6153 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6154 gen_vfp_tosiz(0, 1);
6156 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6157 gen_vfp_touiz(0, 1);
6160 /* Reserved op values were caught by the
6161 * neon_2rm_sizes[] check earlier.
6165 if (neon_2rm_is_float_op(op
)) {
6166 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6167 neon_reg_offset(rd
, pass
));
6169 neon_store_reg(rd
, pass
, tmp
);
6174 } else if ((insn
& (1 << 10)) == 0) {
6176 int n
= ((insn
>> 8) & 3) + 1;
6177 if ((rn
+ n
) > 32) {
6178 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6179 * helper function running off the end of the register file.
6184 if (insn
& (1 << 6)) {
6185 tmp
= neon_load_reg(rd
, 0);
6187 tmp
= tcg_temp_new_i32();
6188 tcg_gen_movi_i32(tmp
, 0);
6190 tmp2
= neon_load_reg(rm
, 0);
6191 tmp4
= tcg_const_i32(rn
);
6192 tmp5
= tcg_const_i32(n
);
6193 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6194 tcg_temp_free_i32(tmp
);
6195 if (insn
& (1 << 6)) {
6196 tmp
= neon_load_reg(rd
, 1);
6198 tmp
= tcg_temp_new_i32();
6199 tcg_gen_movi_i32(tmp
, 0);
6201 tmp3
= neon_load_reg(rm
, 1);
6202 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6203 tcg_temp_free_i32(tmp5
);
6204 tcg_temp_free_i32(tmp4
);
6205 neon_store_reg(rd
, 0, tmp2
);
6206 neon_store_reg(rd
, 1, tmp3
);
6207 tcg_temp_free_i32(tmp
);
6208 } else if ((insn
& 0x380) == 0) {
6210 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6213 if (insn
& (1 << 19)) {
6214 tmp
= neon_load_reg(rm
, 1);
6216 tmp
= neon_load_reg(rm
, 0);
6218 if (insn
& (1 << 16)) {
6219 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6220 } else if (insn
& (1 << 17)) {
6221 if ((insn
>> 18) & 1)
6222 gen_neon_dup_high16(tmp
);
6224 gen_neon_dup_low16(tmp
);
6226 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6227 tmp2
= tcg_temp_new_i32();
6228 tcg_gen_mov_i32(tmp2
, tmp
);
6229 neon_store_reg(rd
, pass
, tmp2
);
6231 tcg_temp_free_i32(tmp
);
6240 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6242 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6243 const ARMCPRegInfo
*ri
;
6244 ARMCPU
*cpu
= arm_env_get_cpu(env
);
6246 cpnum
= (insn
>> 8) & 0xf;
6247 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6248 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6251 /* First check for coprocessor space used for actual instructions */
6255 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6256 return disas_iwmmxt_insn(env
, s
, insn
);
6257 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6258 return disas_dsp_insn(env
, s
, insn
);
6263 return disas_vfp_insn (env
, s
, insn
);
6268 /* Otherwise treat as a generic register access */
6269 is64
= (insn
& (1 << 25)) == 0;
6270 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6278 opc1
= (insn
>> 4) & 0xf;
6280 rt2
= (insn
>> 16) & 0xf;
6282 crn
= (insn
>> 16) & 0xf;
6283 opc1
= (insn
>> 21) & 7;
6284 opc2
= (insn
>> 5) & 7;
6287 isread
= (insn
>> 20) & 1;
6288 rt
= (insn
>> 12) & 0xf;
6290 ri
= get_arm_cp_reginfo(cpu
,
6291 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6293 /* Check access permissions */
6294 if (!cp_access_ok(env
, ri
, isread
)) {
6298 /* Handle special cases first */
6299 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6306 gen_set_pc_im(s
->pc
);
6307 s
->is_jmp
= DISAS_WFI
;
6318 if (ri
->type
& ARM_CP_CONST
) {
6319 tmp64
= tcg_const_i64(ri
->resetvalue
);
6320 } else if (ri
->readfn
) {
6322 gen_set_pc_im(s
->pc
);
6323 tmp64
= tcg_temp_new_i64();
6324 tmpptr
= tcg_const_ptr(ri
);
6325 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6326 tcg_temp_free_ptr(tmpptr
);
6328 tmp64
= tcg_temp_new_i64();
6329 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6331 tmp
= tcg_temp_new_i32();
6332 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6333 store_reg(s
, rt
, tmp
);
6334 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6335 tmp
= tcg_temp_new_i32();
6336 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6337 tcg_temp_free_i64(tmp64
);
6338 store_reg(s
, rt2
, tmp
);
6341 if (ri
->type
& ARM_CP_CONST
) {
6342 tmp
= tcg_const_i32(ri
->resetvalue
);
6343 } else if (ri
->readfn
) {
6345 gen_set_pc_im(s
->pc
);
6346 tmp
= tcg_temp_new_i32();
6347 tmpptr
= tcg_const_ptr(ri
);
6348 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6349 tcg_temp_free_ptr(tmpptr
);
6351 tmp
= load_cpu_offset(ri
->fieldoffset
);
6354 /* Destination register of r15 for 32 bit loads sets
6355 * the condition codes from the high 4 bits of the value
6358 tcg_temp_free_i32(tmp
);
6360 store_reg(s
, rt
, tmp
);
6365 if (ri
->type
& ARM_CP_CONST
) {
6366 /* If not forbidden by access permissions, treat as WI */
6372 TCGv_i64 tmp64
= tcg_temp_new_i64();
6373 tmplo
= load_reg(s
, rt
);
6374 tmphi
= load_reg(s
, rt2
);
6375 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6376 tcg_temp_free_i32(tmplo
);
6377 tcg_temp_free_i32(tmphi
);
6379 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6380 gen_set_pc_im(s
->pc
);
6381 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6382 tcg_temp_free_ptr(tmpptr
);
6384 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6386 tcg_temp_free_i64(tmp64
);
6391 gen_set_pc_im(s
->pc
);
6392 tmp
= load_reg(s
, rt
);
6393 tmpptr
= tcg_const_ptr(ri
);
6394 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6395 tcg_temp_free_ptr(tmpptr
);
6396 tcg_temp_free_i32(tmp
);
6398 TCGv tmp
= load_reg(s
, rt
);
6399 store_cpu_offset(tmp
, ri
->fieldoffset
);
6402 /* We default to ending the TB on a coprocessor register write,
6403 * but allow this to be suppressed by the register definition
6404 * (usually only necessary to work around guest bugs).
6406 if (!(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6417 /* Store a 64-bit value to a register pair. Clobbers val. */
6418 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6421 tmp
= tcg_temp_new_i32();
6422 tcg_gen_trunc_i64_i32(tmp
, val
);
6423 store_reg(s
, rlow
, tmp
);
6424 tmp
= tcg_temp_new_i32();
6425 tcg_gen_shri_i64(val
, val
, 32);
6426 tcg_gen_trunc_i64_i32(tmp
, val
);
6427 store_reg(s
, rhigh
, tmp
);
6430 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6431 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6436 /* Load value and extend to 64 bits. */
6437 tmp
= tcg_temp_new_i64();
6438 tmp2
= load_reg(s
, rlow
);
6439 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6440 tcg_temp_free_i32(tmp2
);
6441 tcg_gen_add_i64(val
, val
, tmp
);
6442 tcg_temp_free_i64(tmp
);
6445 /* load and add a 64-bit value from a register pair. */
6446 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6452 /* Load 64-bit value rd:rn. */
6453 tmpl
= load_reg(s
, rlow
);
6454 tmph
= load_reg(s
, rhigh
);
6455 tmp
= tcg_temp_new_i64();
6456 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6457 tcg_temp_free_i32(tmpl
);
6458 tcg_temp_free_i32(tmph
);
6459 tcg_gen_add_i64(val
, val
, tmp
);
6460 tcg_temp_free_i64(tmp
);
6463 /* Set N and Z flags from hi|lo. */
6464 static void gen_logicq_cc(TCGv lo
, TCGv hi
)
6466 tcg_gen_mov_i32(cpu_NF
, hi
);
6467 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
6470 /* Load/Store exclusive instructions are implemented by remembering
6471 the value/address loaded, and seeing if these are the same
6472 when the store is performed. This should be sufficient to implement
6473 the architecturally mandated semantics, and avoids having to monitor
6476 In system emulation mode only one CPU will be running at once, so
6477 this sequence is effectively atomic. In user emulation mode we
6478 throw an exception and handle the atomic operation elsewhere. */
6479 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6480 TCGv addr
, int size
)
6486 tmp
= gen_ld8u(addr
, IS_USER(s
));
6489 tmp
= gen_ld16u(addr
, IS_USER(s
));
6493 tmp
= gen_ld32(addr
, IS_USER(s
));
6498 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6499 store_reg(s
, rt
, tmp
);
6501 TCGv tmp2
= tcg_temp_new_i32();
6502 tcg_gen_addi_i32(tmp2
, addr
, 4);
6503 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6504 tcg_temp_free_i32(tmp2
);
6505 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6506 store_reg(s
, rt2
, tmp
);
6508 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6511 static void gen_clrex(DisasContext
*s
)
6513 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6516 #ifdef CONFIG_USER_ONLY
6517 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6518 TCGv addr
, int size
)
6520 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6521 tcg_gen_movi_i32(cpu_exclusive_info
,
6522 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6523 gen_exception_insn(s
, 4, EXCP_STREX
);
6526 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6527 TCGv addr
, int size
)
6533 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6539 fail_label
= gen_new_label();
6540 done_label
= gen_new_label();
6541 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6544 tmp
= gen_ld8u(addr
, IS_USER(s
));
6547 tmp
= gen_ld16u(addr
, IS_USER(s
));
6551 tmp
= gen_ld32(addr
, IS_USER(s
));
6556 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6557 tcg_temp_free_i32(tmp
);
6559 TCGv tmp2
= tcg_temp_new_i32();
6560 tcg_gen_addi_i32(tmp2
, addr
, 4);
6561 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6562 tcg_temp_free_i32(tmp2
);
6563 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6564 tcg_temp_free_i32(tmp
);
6566 tmp
= load_reg(s
, rt
);
6569 gen_st8(tmp
, addr
, IS_USER(s
));
6572 gen_st16(tmp
, addr
, IS_USER(s
));
6576 gen_st32(tmp
, addr
, IS_USER(s
));
6582 tcg_gen_addi_i32(addr
, addr
, 4);
6583 tmp
= load_reg(s
, rt2
);
6584 gen_st32(tmp
, addr
, IS_USER(s
));
6586 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6587 tcg_gen_br(done_label
);
6588 gen_set_label(fail_label
);
6589 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6590 gen_set_label(done_label
);
6591 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6595 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6597 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6604 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
6607 /* M variants do not implement ARM mode. */
6612 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6613 * choose to UNDEF. In ARMv5 and above the space is used
6614 * for miscellaneous unconditional instructions.
6618 /* Unconditional instructions. */
6619 if (((insn
>> 25) & 7) == 1) {
6620 /* NEON Data processing. */
6621 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6624 if (disas_neon_data_insn(env
, s
, insn
))
6628 if ((insn
& 0x0f100000) == 0x04000000) {
6629 /* NEON load/store. */
6630 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6633 if (disas_neon_ls_insn(env
, s
, insn
))
6637 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6638 ((insn
& 0x0f30f010) == 0x0710f000)) {
6639 if ((insn
& (1 << 22)) == 0) {
6641 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6645 /* Otherwise PLD; v5TE+ */
6649 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6650 ((insn
& 0x0f70f010) == 0x0650f000)) {
6652 return; /* PLI; V7 */
6654 if (((insn
& 0x0f700000) == 0x04100000) ||
6655 ((insn
& 0x0f700010) == 0x06100000)) {
6656 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6659 return; /* v7MP: Unallocated memory hint: must NOP */
6662 if ((insn
& 0x0ffffdff) == 0x01010000) {
6665 if (((insn
>> 9) & 1) != s
->bswap_code
) {
6666 /* Dynamic endianness switching not implemented. */
6670 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6671 switch ((insn
>> 4) & 0xf) {
6680 /* We don't emulate caches so these are a no-op. */
6685 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6691 op1
= (insn
& 0x1f);
6692 addr
= tcg_temp_new_i32();
6693 tmp
= tcg_const_i32(op1
);
6694 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6695 tcg_temp_free_i32(tmp
);
6696 i
= (insn
>> 23) & 3;
6698 case 0: offset
= -4; break; /* DA */
6699 case 1: offset
= 0; break; /* IA */
6700 case 2: offset
= -8; break; /* DB */
6701 case 3: offset
= 4; break; /* IB */
6705 tcg_gen_addi_i32(addr
, addr
, offset
);
6706 tmp
= load_reg(s
, 14);
6707 gen_st32(tmp
, addr
, 0);
6708 tmp
= load_cpu_field(spsr
);
6709 tcg_gen_addi_i32(addr
, addr
, 4);
6710 gen_st32(tmp
, addr
, 0);
6711 if (insn
& (1 << 21)) {
6712 /* Base writeback. */
6714 case 0: offset
= -8; break;
6715 case 1: offset
= 4; break;
6716 case 2: offset
= -4; break;
6717 case 3: offset
= 0; break;
6721 tcg_gen_addi_i32(addr
, addr
, offset
);
6722 tmp
= tcg_const_i32(op1
);
6723 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6724 tcg_temp_free_i32(tmp
);
6725 tcg_temp_free_i32(addr
);
6727 tcg_temp_free_i32(addr
);
6730 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6736 rn
= (insn
>> 16) & 0xf;
6737 addr
= load_reg(s
, rn
);
6738 i
= (insn
>> 23) & 3;
6740 case 0: offset
= -4; break; /* DA */
6741 case 1: offset
= 0; break; /* IA */
6742 case 2: offset
= -8; break; /* DB */
6743 case 3: offset
= 4; break; /* IB */
6747 tcg_gen_addi_i32(addr
, addr
, offset
);
6748 /* Load PC into tmp and CPSR into tmp2. */
6749 tmp
= gen_ld32(addr
, 0);
6750 tcg_gen_addi_i32(addr
, addr
, 4);
6751 tmp2
= gen_ld32(addr
, 0);
6752 if (insn
& (1 << 21)) {
6753 /* Base writeback. */
6755 case 0: offset
= -8; break;
6756 case 1: offset
= 4; break;
6757 case 2: offset
= -4; break;
6758 case 3: offset
= 0; break;
6762 tcg_gen_addi_i32(addr
, addr
, offset
);
6763 store_reg(s
, rn
, addr
);
6765 tcg_temp_free_i32(addr
);
6767 gen_rfe(s
, tmp
, tmp2
);
6769 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6770 /* branch link and change to thumb (blx <offset>) */
6773 val
= (uint32_t)s
->pc
;
6774 tmp
= tcg_temp_new_i32();
6775 tcg_gen_movi_i32(tmp
, val
);
6776 store_reg(s
, 14, tmp
);
6777 /* Sign-extend the 24-bit offset */
6778 offset
= (((int32_t)insn
) << 8) >> 8;
6779 /* offset * 4 + bit24 * 2 + (thumb bit) */
6780 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6781 /* pipeline offset */
6783 /* protected by ARCH(5); above, near the start of uncond block */
6786 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6787 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6788 /* iWMMXt register transfer. */
6789 if (env
->cp15
.c15_cpar
& (1 << 1))
6790 if (!disas_iwmmxt_insn(env
, s
, insn
))
6793 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6794 /* Coprocessor double register transfer. */
6796 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6797 /* Additional coprocessor register transfer. */
6798 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6801 /* cps (privileged) */
6805 if (insn
& (1 << 19)) {
6806 if (insn
& (1 << 8))
6808 if (insn
& (1 << 7))
6810 if (insn
& (1 << 6))
6812 if (insn
& (1 << 18))
6815 if (insn
& (1 << 17)) {
6817 val
|= (insn
& 0x1f);
6820 gen_set_psr_im(s
, mask
, 0, val
);
6827 /* if not always execute, we generate a conditional jump to
6829 s
->condlabel
= gen_new_label();
6830 gen_test_cc(cond
^ 1, s
->condlabel
);
6833 if ((insn
& 0x0f900000) == 0x03000000) {
6834 if ((insn
& (1 << 21)) == 0) {
6836 rd
= (insn
>> 12) & 0xf;
6837 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6838 if ((insn
& (1 << 22)) == 0) {
6840 tmp
= tcg_temp_new_i32();
6841 tcg_gen_movi_i32(tmp
, val
);
6844 tmp
= load_reg(s
, rd
);
6845 tcg_gen_ext16u_i32(tmp
, tmp
);
6846 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6848 store_reg(s
, rd
, tmp
);
6850 if (((insn
>> 12) & 0xf) != 0xf)
6852 if (((insn
>> 16) & 0xf) == 0) {
6853 gen_nop_hint(s
, insn
& 0xff);
6855 /* CPSR = immediate */
6857 shift
= ((insn
>> 8) & 0xf) * 2;
6859 val
= (val
>> shift
) | (val
<< (32 - shift
));
6860 i
= ((insn
& (1 << 22)) != 0);
6861 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6865 } else if ((insn
& 0x0f900000) == 0x01000000
6866 && (insn
& 0x00000090) != 0x00000090) {
6867 /* miscellaneous instructions */
6868 op1
= (insn
>> 21) & 3;
6869 sh
= (insn
>> 4) & 0xf;
6872 case 0x0: /* move program status register */
6875 tmp
= load_reg(s
, rm
);
6876 i
= ((op1
& 2) != 0);
6877 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6881 rd
= (insn
>> 12) & 0xf;
6885 tmp
= load_cpu_field(spsr
);
6887 tmp
= tcg_temp_new_i32();
6888 gen_helper_cpsr_read(tmp
, cpu_env
);
6890 store_reg(s
, rd
, tmp
);
6895 /* branch/exchange thumb (bx). */
6897 tmp
= load_reg(s
, rm
);
6899 } else if (op1
== 3) {
6902 rd
= (insn
>> 12) & 0xf;
6903 tmp
= load_reg(s
, rm
);
6904 gen_helper_clz(tmp
, tmp
);
6905 store_reg(s
, rd
, tmp
);
6913 /* Trivial implementation equivalent to bx. */
6914 tmp
= load_reg(s
, rm
);
6925 /* branch link/exchange thumb (blx) */
6926 tmp
= load_reg(s
, rm
);
6927 tmp2
= tcg_temp_new_i32();
6928 tcg_gen_movi_i32(tmp2
, s
->pc
);
6929 store_reg(s
, 14, tmp2
);
6932 case 0x5: /* saturating add/subtract */
6934 rd
= (insn
>> 12) & 0xf;
6935 rn
= (insn
>> 16) & 0xf;
6936 tmp
= load_reg(s
, rm
);
6937 tmp2
= load_reg(s
, rn
);
6939 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
6941 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6943 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6944 tcg_temp_free_i32(tmp2
);
6945 store_reg(s
, rd
, tmp
);
6948 /* SMC instruction (op1 == 3)
6949 and undefined instructions (op1 == 0 || op1 == 2)
6956 gen_exception_insn(s
, 4, EXCP_BKPT
);
6958 case 0x8: /* signed multiply */
6963 rs
= (insn
>> 8) & 0xf;
6964 rn
= (insn
>> 12) & 0xf;
6965 rd
= (insn
>> 16) & 0xf;
6967 /* (32 * 16) >> 16 */
6968 tmp
= load_reg(s
, rm
);
6969 tmp2
= load_reg(s
, rs
);
6971 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
6974 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
6975 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
6976 tmp
= tcg_temp_new_i32();
6977 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6978 tcg_temp_free_i64(tmp64
);
6979 if ((sh
& 2) == 0) {
6980 tmp2
= load_reg(s
, rn
);
6981 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
6982 tcg_temp_free_i32(tmp2
);
6984 store_reg(s
, rd
, tmp
);
6987 tmp
= load_reg(s
, rm
);
6988 tmp2
= load_reg(s
, rs
);
6989 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
6990 tcg_temp_free_i32(tmp2
);
6992 tmp64
= tcg_temp_new_i64();
6993 tcg_gen_ext_i32_i64(tmp64
, tmp
);
6994 tcg_temp_free_i32(tmp
);
6995 gen_addq(s
, tmp64
, rn
, rd
);
6996 gen_storeq_reg(s
, rn
, rd
, tmp64
);
6997 tcg_temp_free_i64(tmp64
);
7000 tmp2
= load_reg(s
, rn
);
7001 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7002 tcg_temp_free_i32(tmp2
);
7004 store_reg(s
, rd
, tmp
);
7011 } else if (((insn
& 0x0e000000) == 0 &&
7012 (insn
& 0x00000090) != 0x90) ||
7013 ((insn
& 0x0e000000) == (1 << 25))) {
7014 int set_cc
, logic_cc
, shiftop
;
7016 op1
= (insn
>> 21) & 0xf;
7017 set_cc
= (insn
>> 20) & 1;
7018 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7020 /* data processing instruction */
7021 if (insn
& (1 << 25)) {
7022 /* immediate operand */
7024 shift
= ((insn
>> 8) & 0xf) * 2;
7026 val
= (val
>> shift
) | (val
<< (32 - shift
));
7028 tmp2
= tcg_temp_new_i32();
7029 tcg_gen_movi_i32(tmp2
, val
);
7030 if (logic_cc
&& shift
) {
7031 gen_set_CF_bit31(tmp2
);
7036 tmp2
= load_reg(s
, rm
);
7037 shiftop
= (insn
>> 5) & 3;
7038 if (!(insn
& (1 << 4))) {
7039 shift
= (insn
>> 7) & 0x1f;
7040 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7042 rs
= (insn
>> 8) & 0xf;
7043 tmp
= load_reg(s
, rs
);
7044 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7047 if (op1
!= 0x0f && op1
!= 0x0d) {
7048 rn
= (insn
>> 16) & 0xf;
7049 tmp
= load_reg(s
, rn
);
7053 rd
= (insn
>> 12) & 0xf;
7056 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7060 store_reg_bx(env
, s
, rd
, tmp
);
7063 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7067 store_reg_bx(env
, s
, rd
, tmp
);
7070 if (set_cc
&& rd
== 15) {
7071 /* SUBS r15, ... is used for exception return. */
7075 gen_sub_CC(tmp
, tmp
, tmp2
);
7076 gen_exception_return(s
, tmp
);
7079 gen_sub_CC(tmp
, tmp
, tmp2
);
7081 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7083 store_reg_bx(env
, s
, rd
, tmp
);
7088 gen_sub_CC(tmp
, tmp2
, tmp
);
7090 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7092 store_reg_bx(env
, s
, rd
, tmp
);
7096 gen_add_CC(tmp
, tmp
, tmp2
);
7098 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7100 store_reg_bx(env
, s
, rd
, tmp
);
7104 gen_adc_CC(tmp
, tmp
, tmp2
);
7106 gen_add_carry(tmp
, tmp
, tmp2
);
7108 store_reg_bx(env
, s
, rd
, tmp
);
7112 gen_helper_sbc_cc(tmp
, cpu_env
, tmp
, tmp2
);
7114 gen_sub_carry(tmp
, tmp
, tmp2
);
7116 store_reg_bx(env
, s
, rd
, tmp
);
7120 gen_helper_sbc_cc(tmp
, cpu_env
, tmp2
, tmp
);
7122 gen_sub_carry(tmp
, tmp2
, tmp
);
7124 store_reg_bx(env
, s
, rd
, tmp
);
7128 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7131 tcg_temp_free_i32(tmp
);
7135 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7138 tcg_temp_free_i32(tmp
);
7142 gen_sub_CC(tmp
, tmp
, tmp2
);
7144 tcg_temp_free_i32(tmp
);
7148 gen_add_CC(tmp
, tmp
, tmp2
);
7150 tcg_temp_free_i32(tmp
);
7153 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7157 store_reg_bx(env
, s
, rd
, tmp
);
7160 if (logic_cc
&& rd
== 15) {
7161 /* MOVS r15, ... is used for exception return. */
7165 gen_exception_return(s
, tmp2
);
7170 store_reg_bx(env
, s
, rd
, tmp2
);
7174 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7178 store_reg_bx(env
, s
, rd
, tmp
);
7182 tcg_gen_not_i32(tmp2
, tmp2
);
7186 store_reg_bx(env
, s
, rd
, tmp2
);
7189 if (op1
!= 0x0f && op1
!= 0x0d) {
7190 tcg_temp_free_i32(tmp2
);
7193 /* other instructions */
7194 op1
= (insn
>> 24) & 0xf;
7198 /* multiplies, extra load/stores */
7199 sh
= (insn
>> 5) & 3;
7202 rd
= (insn
>> 16) & 0xf;
7203 rn
= (insn
>> 12) & 0xf;
7204 rs
= (insn
>> 8) & 0xf;
7206 op1
= (insn
>> 20) & 0xf;
7208 case 0: case 1: case 2: case 3: case 6:
7210 tmp
= load_reg(s
, rs
);
7211 tmp2
= load_reg(s
, rm
);
7212 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7213 tcg_temp_free_i32(tmp2
);
7214 if (insn
& (1 << 22)) {
7215 /* Subtract (mls) */
7217 tmp2
= load_reg(s
, rn
);
7218 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7219 tcg_temp_free_i32(tmp2
);
7220 } else if (insn
& (1 << 21)) {
7222 tmp2
= load_reg(s
, rn
);
7223 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7224 tcg_temp_free_i32(tmp2
);
7226 if (insn
& (1 << 20))
7228 store_reg(s
, rd
, tmp
);
7231 /* 64 bit mul double accumulate (UMAAL) */
7233 tmp
= load_reg(s
, rs
);
7234 tmp2
= load_reg(s
, rm
);
7235 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7236 gen_addq_lo(s
, tmp64
, rn
);
7237 gen_addq_lo(s
, tmp64
, rd
);
7238 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7239 tcg_temp_free_i64(tmp64
);
7241 case 8: case 9: case 10: case 11:
7242 case 12: case 13: case 14: case 15:
7243 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7244 tmp
= load_reg(s
, rs
);
7245 tmp2
= load_reg(s
, rm
);
7246 if (insn
& (1 << 22)) {
7247 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
7249 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
7251 if (insn
& (1 << 21)) { /* mult accumulate */
7252 TCGv al
= load_reg(s
, rn
);
7253 TCGv ah
= load_reg(s
, rd
);
7254 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
7258 if (insn
& (1 << 20)) {
7259 gen_logicq_cc(tmp
, tmp2
);
7261 store_reg(s
, rn
, tmp
);
7262 store_reg(s
, rd
, tmp2
);
7268 rn
= (insn
>> 16) & 0xf;
7269 rd
= (insn
>> 12) & 0xf;
7270 if (insn
& (1 << 23)) {
7271 /* load/store exclusive */
7272 op1
= (insn
>> 21) & 0x3;
7277 addr
= tcg_temp_local_new_i32();
7278 load_reg_var(s
, addr
, rn
);
7279 if (insn
& (1 << 20)) {
7282 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7284 case 1: /* ldrexd */
7285 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7287 case 2: /* ldrexb */
7288 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7290 case 3: /* ldrexh */
7291 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7300 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7302 case 1: /* strexd */
7303 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7305 case 2: /* strexb */
7306 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7308 case 3: /* strexh */
7309 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7315 tcg_temp_free(addr
);
7317 /* SWP instruction */
7320 /* ??? This is not really atomic. However we know
7321 we never have multiple CPUs running in parallel,
7322 so it is good enough. */
7323 addr
= load_reg(s
, rn
);
7324 tmp
= load_reg(s
, rm
);
7325 if (insn
& (1 << 22)) {
7326 tmp2
= gen_ld8u(addr
, IS_USER(s
));
7327 gen_st8(tmp
, addr
, IS_USER(s
));
7329 tmp2
= gen_ld32(addr
, IS_USER(s
));
7330 gen_st32(tmp
, addr
, IS_USER(s
));
7332 tcg_temp_free_i32(addr
);
7333 store_reg(s
, rd
, tmp2
);
7339 /* Misc load/store */
7340 rn
= (insn
>> 16) & 0xf;
7341 rd
= (insn
>> 12) & 0xf;
7342 addr
= load_reg(s
, rn
);
7343 if (insn
& (1 << 24))
7344 gen_add_datah_offset(s
, insn
, 0, addr
);
7346 if (insn
& (1 << 20)) {
7350 tmp
= gen_ld16u(addr
, IS_USER(s
));
7353 tmp
= gen_ld8s(addr
, IS_USER(s
));
7357 tmp
= gen_ld16s(addr
, IS_USER(s
));
7361 } else if (sh
& 2) {
7366 tmp
= load_reg(s
, rd
);
7367 gen_st32(tmp
, addr
, IS_USER(s
));
7368 tcg_gen_addi_i32(addr
, addr
, 4);
7369 tmp
= load_reg(s
, rd
+ 1);
7370 gen_st32(tmp
, addr
, IS_USER(s
));
7374 tmp
= gen_ld32(addr
, IS_USER(s
));
7375 store_reg(s
, rd
, tmp
);
7376 tcg_gen_addi_i32(addr
, addr
, 4);
7377 tmp
= gen_ld32(addr
, IS_USER(s
));
7381 address_offset
= -4;
7384 tmp
= load_reg(s
, rd
);
7385 gen_st16(tmp
, addr
, IS_USER(s
));
7388 /* Perform base writeback before the loaded value to
7389 ensure correct behavior with overlapping index registers.
7390 ldrd with base writeback is is undefined if the
7391 destination and index registers overlap. */
7392 if (!(insn
& (1 << 24))) {
7393 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7394 store_reg(s
, rn
, addr
);
7395 } else if (insn
& (1 << 21)) {
7397 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7398 store_reg(s
, rn
, addr
);
7400 tcg_temp_free_i32(addr
);
7403 /* Complete the load. */
7404 store_reg(s
, rd
, tmp
);
7413 if (insn
& (1 << 4)) {
7415 /* Armv6 Media instructions. */
7417 rn
= (insn
>> 16) & 0xf;
7418 rd
= (insn
>> 12) & 0xf;
7419 rs
= (insn
>> 8) & 0xf;
7420 switch ((insn
>> 23) & 3) {
7421 case 0: /* Parallel add/subtract. */
7422 op1
= (insn
>> 20) & 7;
7423 tmp
= load_reg(s
, rn
);
7424 tmp2
= load_reg(s
, rm
);
7425 sh
= (insn
>> 5) & 7;
7426 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7428 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7429 tcg_temp_free_i32(tmp2
);
7430 store_reg(s
, rd
, tmp
);
7433 if ((insn
& 0x00700020) == 0) {
7434 /* Halfword pack. */
7435 tmp
= load_reg(s
, rn
);
7436 tmp2
= load_reg(s
, rm
);
7437 shift
= (insn
>> 7) & 0x1f;
7438 if (insn
& (1 << 6)) {
7442 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7443 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7444 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7448 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7449 tcg_gen_ext16u_i32(tmp
, tmp
);
7450 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7452 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7453 tcg_temp_free_i32(tmp2
);
7454 store_reg(s
, rd
, tmp
);
7455 } else if ((insn
& 0x00200020) == 0x00200000) {
7457 tmp
= load_reg(s
, rm
);
7458 shift
= (insn
>> 7) & 0x1f;
7459 if (insn
& (1 << 6)) {
7462 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7464 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7466 sh
= (insn
>> 16) & 0x1f;
7467 tmp2
= tcg_const_i32(sh
);
7468 if (insn
& (1 << 22))
7469 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
7471 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
7472 tcg_temp_free_i32(tmp2
);
7473 store_reg(s
, rd
, tmp
);
7474 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7476 tmp
= load_reg(s
, rm
);
7477 sh
= (insn
>> 16) & 0x1f;
7478 tmp2
= tcg_const_i32(sh
);
7479 if (insn
& (1 << 22))
7480 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
7482 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
7483 tcg_temp_free_i32(tmp2
);
7484 store_reg(s
, rd
, tmp
);
7485 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7487 tmp
= load_reg(s
, rn
);
7488 tmp2
= load_reg(s
, rm
);
7489 tmp3
= tcg_temp_new_i32();
7490 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7491 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7492 tcg_temp_free_i32(tmp3
);
7493 tcg_temp_free_i32(tmp2
);
7494 store_reg(s
, rd
, tmp
);
7495 } else if ((insn
& 0x000003e0) == 0x00000060) {
7496 tmp
= load_reg(s
, rm
);
7497 shift
= (insn
>> 10) & 3;
7498 /* ??? In many cases it's not necessary to do a
7499 rotate, a shift is sufficient. */
7501 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7502 op1
= (insn
>> 20) & 7;
7504 case 0: gen_sxtb16(tmp
); break;
7505 case 2: gen_sxtb(tmp
); break;
7506 case 3: gen_sxth(tmp
); break;
7507 case 4: gen_uxtb16(tmp
); break;
7508 case 6: gen_uxtb(tmp
); break;
7509 case 7: gen_uxth(tmp
); break;
7510 default: goto illegal_op
;
7513 tmp2
= load_reg(s
, rn
);
7514 if ((op1
& 3) == 0) {
7515 gen_add16(tmp
, tmp2
);
7517 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7518 tcg_temp_free_i32(tmp2
);
7521 store_reg(s
, rd
, tmp
);
7522 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7524 tmp
= load_reg(s
, rm
);
7525 if (insn
& (1 << 22)) {
7526 if (insn
& (1 << 7)) {
7530 gen_helper_rbit(tmp
, tmp
);
7533 if (insn
& (1 << 7))
7536 tcg_gen_bswap32_i32(tmp
, tmp
);
7538 store_reg(s
, rd
, tmp
);
7543 case 2: /* Multiplies (Type 3). */
7544 switch ((insn
>> 20) & 0x7) {
7546 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7547 /* op2 not 00x or 11x : UNDEF */
7550 /* Signed multiply most significant [accumulate].
7551 (SMMUL, SMMLA, SMMLS) */
7552 tmp
= load_reg(s
, rm
);
7553 tmp2
= load_reg(s
, rs
);
7554 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7557 tmp
= load_reg(s
, rd
);
7558 if (insn
& (1 << 6)) {
7559 tmp64
= gen_subq_msw(tmp64
, tmp
);
7561 tmp64
= gen_addq_msw(tmp64
, tmp
);
7564 if (insn
& (1 << 5)) {
7565 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7567 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7568 tmp
= tcg_temp_new_i32();
7569 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7570 tcg_temp_free_i64(tmp64
);
7571 store_reg(s
, rn
, tmp
);
7575 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7576 if (insn
& (1 << 7)) {
7579 tmp
= load_reg(s
, rm
);
7580 tmp2
= load_reg(s
, rs
);
7581 if (insn
& (1 << 5))
7582 gen_swap_half(tmp2
);
7583 gen_smul_dual(tmp
, tmp2
);
7584 if (insn
& (1 << 6)) {
7585 /* This subtraction cannot overflow. */
7586 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7588 /* This addition cannot overflow 32 bits;
7589 * however it may overflow considered as a signed
7590 * operation, in which case we must set the Q flag.
7592 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7594 tcg_temp_free_i32(tmp2
);
7595 if (insn
& (1 << 22)) {
7596 /* smlald, smlsld */
7597 tmp64
= tcg_temp_new_i64();
7598 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7599 tcg_temp_free_i32(tmp
);
7600 gen_addq(s
, tmp64
, rd
, rn
);
7601 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7602 tcg_temp_free_i64(tmp64
);
7604 /* smuad, smusd, smlad, smlsd */
7607 tmp2
= load_reg(s
, rd
);
7608 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7609 tcg_temp_free_i32(tmp2
);
7611 store_reg(s
, rn
, tmp
);
7617 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7620 if (((insn
>> 5) & 7) || (rd
!= 15)) {
7623 tmp
= load_reg(s
, rm
);
7624 tmp2
= load_reg(s
, rs
);
7625 if (insn
& (1 << 21)) {
7626 gen_helper_udiv(tmp
, tmp
, tmp2
);
7628 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7630 tcg_temp_free_i32(tmp2
);
7631 store_reg(s
, rn
, tmp
);
7638 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7640 case 0: /* Unsigned sum of absolute differences. */
7642 tmp
= load_reg(s
, rm
);
7643 tmp2
= load_reg(s
, rs
);
7644 gen_helper_usad8(tmp
, tmp
, tmp2
);
7645 tcg_temp_free_i32(tmp2
);
7647 tmp2
= load_reg(s
, rd
);
7648 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7649 tcg_temp_free_i32(tmp2
);
7651 store_reg(s
, rn
, tmp
);
7653 case 0x20: case 0x24: case 0x28: case 0x2c:
7654 /* Bitfield insert/clear. */
7656 shift
= (insn
>> 7) & 0x1f;
7657 i
= (insn
>> 16) & 0x1f;
7660 tmp
= tcg_temp_new_i32();
7661 tcg_gen_movi_i32(tmp
, 0);
7663 tmp
= load_reg(s
, rm
);
7666 tmp2
= load_reg(s
, rd
);
7667 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
7668 tcg_temp_free_i32(tmp2
);
7670 store_reg(s
, rd
, tmp
);
7672 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7673 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7675 tmp
= load_reg(s
, rm
);
7676 shift
= (insn
>> 7) & 0x1f;
7677 i
= ((insn
>> 16) & 0x1f) + 1;
7682 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7684 gen_sbfx(tmp
, shift
, i
);
7687 store_reg(s
, rd
, tmp
);
7697 /* Check for undefined extension instructions
7698 * per the ARM Bible IE:
7699 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7701 sh
= (0xf << 20) | (0xf << 4);
7702 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7706 /* load/store byte/word */
7707 rn
= (insn
>> 16) & 0xf;
7708 rd
= (insn
>> 12) & 0xf;
7709 tmp2
= load_reg(s
, rn
);
7710 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7711 if (insn
& (1 << 24))
7712 gen_add_data_offset(s
, insn
, tmp2
);
7713 if (insn
& (1 << 20)) {
7715 if (insn
& (1 << 22)) {
7716 tmp
= gen_ld8u(tmp2
, i
);
7718 tmp
= gen_ld32(tmp2
, i
);
7722 tmp
= load_reg(s
, rd
);
7723 if (insn
& (1 << 22))
7724 gen_st8(tmp
, tmp2
, i
);
7726 gen_st32(tmp
, tmp2
, i
);
7728 if (!(insn
& (1 << 24))) {
7729 gen_add_data_offset(s
, insn
, tmp2
);
7730 store_reg(s
, rn
, tmp2
);
7731 } else if (insn
& (1 << 21)) {
7732 store_reg(s
, rn
, tmp2
);
7734 tcg_temp_free_i32(tmp2
);
7736 if (insn
& (1 << 20)) {
7737 /* Complete the load. */
7738 store_reg_from_load(env
, s
, rd
, tmp
);
7744 int j
, n
, user
, loaded_base
;
7746 /* load/store multiple words */
7747 /* XXX: store correct base if write back */
7749 if (insn
& (1 << 22)) {
7751 goto illegal_op
; /* only usable in supervisor mode */
7753 if ((insn
& (1 << 15)) == 0)
7756 rn
= (insn
>> 16) & 0xf;
7757 addr
= load_reg(s
, rn
);
7759 /* compute total size */
7761 TCGV_UNUSED(loaded_var
);
7764 if (insn
& (1 << i
))
7767 /* XXX: test invalid n == 0 case ? */
7768 if (insn
& (1 << 23)) {
7769 if (insn
& (1 << 24)) {
7771 tcg_gen_addi_i32(addr
, addr
, 4);
7773 /* post increment */
7776 if (insn
& (1 << 24)) {
7778 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7780 /* post decrement */
7782 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7787 if (insn
& (1 << i
)) {
7788 if (insn
& (1 << 20)) {
7790 tmp
= gen_ld32(addr
, IS_USER(s
));
7792 tmp2
= tcg_const_i32(i
);
7793 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
7794 tcg_temp_free_i32(tmp2
);
7795 tcg_temp_free_i32(tmp
);
7796 } else if (i
== rn
) {
7800 store_reg_from_load(env
, s
, i
, tmp
);
7805 /* special case: r15 = PC + 8 */
7806 val
= (long)s
->pc
+ 4;
7807 tmp
= tcg_temp_new_i32();
7808 tcg_gen_movi_i32(tmp
, val
);
7810 tmp
= tcg_temp_new_i32();
7811 tmp2
= tcg_const_i32(i
);
7812 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
7813 tcg_temp_free_i32(tmp2
);
7815 tmp
= load_reg(s
, i
);
7817 gen_st32(tmp
, addr
, IS_USER(s
));
7820 /* no need to add after the last transfer */
7822 tcg_gen_addi_i32(addr
, addr
, 4);
7825 if (insn
& (1 << 21)) {
7827 if (insn
& (1 << 23)) {
7828 if (insn
& (1 << 24)) {
7831 /* post increment */
7832 tcg_gen_addi_i32(addr
, addr
, 4);
7835 if (insn
& (1 << 24)) {
7838 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7840 /* post decrement */
7841 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7844 store_reg(s
, rn
, addr
);
7846 tcg_temp_free_i32(addr
);
7849 store_reg(s
, rn
, loaded_var
);
7851 if ((insn
& (1 << 22)) && !user
) {
7852 /* Restore CPSR from SPSR. */
7853 tmp
= load_cpu_field(spsr
);
7854 gen_set_cpsr(tmp
, 0xffffffff);
7855 tcg_temp_free_i32(tmp
);
7856 s
->is_jmp
= DISAS_UPDATE
;
7865 /* branch (and link) */
7866 val
= (int32_t)s
->pc
;
7867 if (insn
& (1 << 24)) {
7868 tmp
= tcg_temp_new_i32();
7869 tcg_gen_movi_i32(tmp
, val
);
7870 store_reg(s
, 14, tmp
);
7872 offset
= (((int32_t)insn
<< 8) >> 8);
7873 val
+= (offset
<< 2) + 4;
7881 if (disas_coproc_insn(env
, s
, insn
))
7886 gen_set_pc_im(s
->pc
);
7887 s
->is_jmp
= DISAS_SWI
;
7891 gen_exception_insn(s
, 4, EXCP_UDEF
);
7897 /* Return true if this is a Thumb-2 logical op. */
7899 thumb2_logic_op(int op
)
7904 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7905 then set condition code flags based on the result of the operation.
7906 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7907 to the high bit of T1.
7908 Returns zero if the opcode is valid. */
7911 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
7918 tcg_gen_and_i32(t0
, t0
, t1
);
7922 tcg_gen_andc_i32(t0
, t0
, t1
);
7926 tcg_gen_or_i32(t0
, t0
, t1
);
7930 tcg_gen_orc_i32(t0
, t0
, t1
);
7934 tcg_gen_xor_i32(t0
, t0
, t1
);
7939 gen_add_CC(t0
, t0
, t1
);
7941 tcg_gen_add_i32(t0
, t0
, t1
);
7945 gen_adc_CC(t0
, t0
, t1
);
7951 gen_helper_sbc_cc(t0
, cpu_env
, t0
, t1
);
7953 gen_sub_carry(t0
, t0
, t1
);
7957 gen_sub_CC(t0
, t0
, t1
);
7959 tcg_gen_sub_i32(t0
, t0
, t1
);
7963 gen_sub_CC(t0
, t1
, t0
);
7965 tcg_gen_sub_i32(t0
, t1
, t0
);
7967 default: /* 5, 6, 7, 9, 12, 15. */
7973 gen_set_CF_bit31(t1
);
7978 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7980 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
7982 uint32_t insn
, imm
, shift
, offset
;
7983 uint32_t rd
, rn
, rm
, rs
;
7994 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
7995 || arm_feature (env
, ARM_FEATURE_M
))) {
7996 /* Thumb-1 cores may need to treat bl and blx as a pair of
7997 16-bit instructions to get correct prefetch abort behavior. */
7999 if ((insn
& (1 << 12)) == 0) {
8001 /* Second half of blx. */
8002 offset
= ((insn
& 0x7ff) << 1);
8003 tmp
= load_reg(s
, 14);
8004 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8005 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8007 tmp2
= tcg_temp_new_i32();
8008 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8009 store_reg(s
, 14, tmp2
);
8013 if (insn
& (1 << 11)) {
8014 /* Second half of bl. */
8015 offset
= ((insn
& 0x7ff) << 1) | 1;
8016 tmp
= load_reg(s
, 14);
8017 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8019 tmp2
= tcg_temp_new_i32();
8020 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8021 store_reg(s
, 14, tmp2
);
8025 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
8026 /* Instruction spans a page boundary. Implement it as two
8027 16-bit instructions in case the second half causes an
8029 offset
= ((int32_t)insn
<< 21) >> 9;
8030 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8033 /* Fall through to 32-bit decode. */
8036 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8038 insn
|= (uint32_t)insn_hw1
<< 16;
8040 if ((insn
& 0xf800e800) != 0xf000e800) {
8044 rn
= (insn
>> 16) & 0xf;
8045 rs
= (insn
>> 12) & 0xf;
8046 rd
= (insn
>> 8) & 0xf;
8048 switch ((insn
>> 25) & 0xf) {
8049 case 0: case 1: case 2: case 3:
8050 /* 16-bit instructions. Should never happen. */
8053 if (insn
& (1 << 22)) {
8054 /* Other load/store, table branch. */
8055 if (insn
& 0x01200000) {
8056 /* Load/store doubleword. */
8058 addr
= tcg_temp_new_i32();
8059 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8061 addr
= load_reg(s
, rn
);
8063 offset
= (insn
& 0xff) * 4;
8064 if ((insn
& (1 << 23)) == 0)
8066 if (insn
& (1 << 24)) {
8067 tcg_gen_addi_i32(addr
, addr
, offset
);
8070 if (insn
& (1 << 20)) {
8072 tmp
= gen_ld32(addr
, IS_USER(s
));
8073 store_reg(s
, rs
, tmp
);
8074 tcg_gen_addi_i32(addr
, addr
, 4);
8075 tmp
= gen_ld32(addr
, IS_USER(s
));
8076 store_reg(s
, rd
, tmp
);
8079 tmp
= load_reg(s
, rs
);
8080 gen_st32(tmp
, addr
, IS_USER(s
));
8081 tcg_gen_addi_i32(addr
, addr
, 4);
8082 tmp
= load_reg(s
, rd
);
8083 gen_st32(tmp
, addr
, IS_USER(s
));
8085 if (insn
& (1 << 21)) {
8086 /* Base writeback. */
8089 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8090 store_reg(s
, rn
, addr
);
8092 tcg_temp_free_i32(addr
);
8094 } else if ((insn
& (1 << 23)) == 0) {
8095 /* Load/store exclusive word. */
8096 addr
= tcg_temp_local_new();
8097 load_reg_var(s
, addr
, rn
);
8098 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8099 if (insn
& (1 << 20)) {
8100 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8102 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8104 tcg_temp_free(addr
);
8105 } else if ((insn
& (1 << 6)) == 0) {
8108 addr
= tcg_temp_new_i32();
8109 tcg_gen_movi_i32(addr
, s
->pc
);
8111 addr
= load_reg(s
, rn
);
8113 tmp
= load_reg(s
, rm
);
8114 tcg_gen_add_i32(addr
, addr
, tmp
);
8115 if (insn
& (1 << 4)) {
8117 tcg_gen_add_i32(addr
, addr
, tmp
);
8118 tcg_temp_free_i32(tmp
);
8119 tmp
= gen_ld16u(addr
, IS_USER(s
));
8121 tcg_temp_free_i32(tmp
);
8122 tmp
= gen_ld8u(addr
, IS_USER(s
));
8124 tcg_temp_free_i32(addr
);
8125 tcg_gen_shli_i32(tmp
, tmp
, 1);
8126 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8127 store_reg(s
, 15, tmp
);
8129 /* Load/store exclusive byte/halfword/doubleword. */
8131 op
= (insn
>> 4) & 0x3;
8135 addr
= tcg_temp_local_new();
8136 load_reg_var(s
, addr
, rn
);
8137 if (insn
& (1 << 20)) {
8138 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8140 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8142 tcg_temp_free(addr
);
8145 /* Load/store multiple, RFE, SRS. */
8146 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8147 /* Not available in user mode. */
8150 if (insn
& (1 << 20)) {
8152 addr
= load_reg(s
, rn
);
8153 if ((insn
& (1 << 24)) == 0)
8154 tcg_gen_addi_i32(addr
, addr
, -8);
8155 /* Load PC into tmp and CPSR into tmp2. */
8156 tmp
= gen_ld32(addr
, 0);
8157 tcg_gen_addi_i32(addr
, addr
, 4);
8158 tmp2
= gen_ld32(addr
, 0);
8159 if (insn
& (1 << 21)) {
8160 /* Base writeback. */
8161 if (insn
& (1 << 24)) {
8162 tcg_gen_addi_i32(addr
, addr
, 4);
8164 tcg_gen_addi_i32(addr
, addr
, -4);
8166 store_reg(s
, rn
, addr
);
8168 tcg_temp_free_i32(addr
);
8170 gen_rfe(s
, tmp
, tmp2
);
8174 addr
= tcg_temp_new_i32();
8175 tmp
= tcg_const_i32(op
);
8176 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8177 tcg_temp_free_i32(tmp
);
8178 if ((insn
& (1 << 24)) == 0) {
8179 tcg_gen_addi_i32(addr
, addr
, -8);
8181 tmp
= load_reg(s
, 14);
8182 gen_st32(tmp
, addr
, 0);
8183 tcg_gen_addi_i32(addr
, addr
, 4);
8184 tmp
= tcg_temp_new_i32();
8185 gen_helper_cpsr_read(tmp
, cpu_env
);
8186 gen_st32(tmp
, addr
, 0);
8187 if (insn
& (1 << 21)) {
8188 if ((insn
& (1 << 24)) == 0) {
8189 tcg_gen_addi_i32(addr
, addr
, -4);
8191 tcg_gen_addi_i32(addr
, addr
, 4);
8193 tmp
= tcg_const_i32(op
);
8194 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8195 tcg_temp_free_i32(tmp
);
8197 tcg_temp_free_i32(addr
);
8201 int i
, loaded_base
= 0;
8203 /* Load/store multiple. */
8204 addr
= load_reg(s
, rn
);
8206 for (i
= 0; i
< 16; i
++) {
8207 if (insn
& (1 << i
))
8210 if (insn
& (1 << 24)) {
8211 tcg_gen_addi_i32(addr
, addr
, -offset
);
8214 TCGV_UNUSED(loaded_var
);
8215 for (i
= 0; i
< 16; i
++) {
8216 if ((insn
& (1 << i
)) == 0)
8218 if (insn
& (1 << 20)) {
8220 tmp
= gen_ld32(addr
, IS_USER(s
));
8223 } else if (i
== rn
) {
8227 store_reg(s
, i
, tmp
);
8231 tmp
= load_reg(s
, i
);
8232 gen_st32(tmp
, addr
, IS_USER(s
));
8234 tcg_gen_addi_i32(addr
, addr
, 4);
8237 store_reg(s
, rn
, loaded_var
);
8239 if (insn
& (1 << 21)) {
8240 /* Base register writeback. */
8241 if (insn
& (1 << 24)) {
8242 tcg_gen_addi_i32(addr
, addr
, -offset
);
8244 /* Fault if writeback register is in register list. */
8245 if (insn
& (1 << rn
))
8247 store_reg(s
, rn
, addr
);
8249 tcg_temp_free_i32(addr
);
8256 op
= (insn
>> 21) & 0xf;
8258 /* Halfword pack. */
8259 tmp
= load_reg(s
, rn
);
8260 tmp2
= load_reg(s
, rm
);
8261 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8262 if (insn
& (1 << 5)) {
8266 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8267 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8268 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8272 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8273 tcg_gen_ext16u_i32(tmp
, tmp
);
8274 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8276 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8277 tcg_temp_free_i32(tmp2
);
8278 store_reg(s
, rd
, tmp
);
8280 /* Data processing register constant shift. */
8282 tmp
= tcg_temp_new_i32();
8283 tcg_gen_movi_i32(tmp
, 0);
8285 tmp
= load_reg(s
, rn
);
8287 tmp2
= load_reg(s
, rm
);
8289 shiftop
= (insn
>> 4) & 3;
8290 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8291 conds
= (insn
& (1 << 20)) != 0;
8292 logic_cc
= (conds
&& thumb2_logic_op(op
));
8293 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8294 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8296 tcg_temp_free_i32(tmp2
);
8298 store_reg(s
, rd
, tmp
);
8300 tcg_temp_free_i32(tmp
);
8304 case 13: /* Misc data processing. */
8305 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8306 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8309 case 0: /* Register controlled shift. */
8310 tmp
= load_reg(s
, rn
);
8311 tmp2
= load_reg(s
, rm
);
8312 if ((insn
& 0x70) != 0)
8314 op
= (insn
>> 21) & 3;
8315 logic_cc
= (insn
& (1 << 20)) != 0;
8316 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8319 store_reg_bx(env
, s
, rd
, tmp
);
8321 case 1: /* Sign/zero extend. */
8322 tmp
= load_reg(s
, rm
);
8323 shift
= (insn
>> 4) & 3;
8324 /* ??? In many cases it's not necessary to do a
8325 rotate, a shift is sufficient. */
8327 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8328 op
= (insn
>> 20) & 7;
8330 case 0: gen_sxth(tmp
); break;
8331 case 1: gen_uxth(tmp
); break;
8332 case 2: gen_sxtb16(tmp
); break;
8333 case 3: gen_uxtb16(tmp
); break;
8334 case 4: gen_sxtb(tmp
); break;
8335 case 5: gen_uxtb(tmp
); break;
8336 default: goto illegal_op
;
8339 tmp2
= load_reg(s
, rn
);
8340 if ((op
>> 1) == 1) {
8341 gen_add16(tmp
, tmp2
);
8343 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8344 tcg_temp_free_i32(tmp2
);
8347 store_reg(s
, rd
, tmp
);
8349 case 2: /* SIMD add/subtract. */
8350 op
= (insn
>> 20) & 7;
8351 shift
= (insn
>> 4) & 7;
8352 if ((op
& 3) == 3 || (shift
& 3) == 3)
8354 tmp
= load_reg(s
, rn
);
8355 tmp2
= load_reg(s
, rm
);
8356 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8357 tcg_temp_free_i32(tmp2
);
8358 store_reg(s
, rd
, tmp
);
8360 case 3: /* Other data processing. */
8361 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8363 /* Saturating add/subtract. */
8364 tmp
= load_reg(s
, rn
);
8365 tmp2
= load_reg(s
, rm
);
8367 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
8369 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
8371 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8372 tcg_temp_free_i32(tmp2
);
8374 tmp
= load_reg(s
, rn
);
8376 case 0x0a: /* rbit */
8377 gen_helper_rbit(tmp
, tmp
);
8379 case 0x08: /* rev */
8380 tcg_gen_bswap32_i32(tmp
, tmp
);
8382 case 0x09: /* rev16 */
8385 case 0x0b: /* revsh */
8388 case 0x10: /* sel */
8389 tmp2
= load_reg(s
, rm
);
8390 tmp3
= tcg_temp_new_i32();
8391 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8392 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8393 tcg_temp_free_i32(tmp3
);
8394 tcg_temp_free_i32(tmp2
);
8396 case 0x18: /* clz */
8397 gen_helper_clz(tmp
, tmp
);
8403 store_reg(s
, rd
, tmp
);
8405 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8406 op
= (insn
>> 4) & 0xf;
8407 tmp
= load_reg(s
, rn
);
8408 tmp2
= load_reg(s
, rm
);
8409 switch ((insn
>> 20) & 7) {
8410 case 0: /* 32 x 32 -> 32 */
8411 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8412 tcg_temp_free_i32(tmp2
);
8414 tmp2
= load_reg(s
, rs
);
8416 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8418 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8419 tcg_temp_free_i32(tmp2
);
8422 case 1: /* 16 x 16 -> 32 */
8423 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8424 tcg_temp_free_i32(tmp2
);
8426 tmp2
= load_reg(s
, rs
);
8427 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8428 tcg_temp_free_i32(tmp2
);
8431 case 2: /* Dual multiply add. */
8432 case 4: /* Dual multiply subtract. */
8434 gen_swap_half(tmp2
);
8435 gen_smul_dual(tmp
, tmp2
);
8436 if (insn
& (1 << 22)) {
8437 /* This subtraction cannot overflow. */
8438 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8440 /* This addition cannot overflow 32 bits;
8441 * however it may overflow considered as a signed
8442 * operation, in which case we must set the Q flag.
8444 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8446 tcg_temp_free_i32(tmp2
);
8449 tmp2
= load_reg(s
, rs
);
8450 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8451 tcg_temp_free_i32(tmp2
);
8454 case 3: /* 32 * 16 -> 32msb */
8456 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8459 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8460 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8461 tmp
= tcg_temp_new_i32();
8462 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8463 tcg_temp_free_i64(tmp64
);
8466 tmp2
= load_reg(s
, rs
);
8467 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8468 tcg_temp_free_i32(tmp2
);
8471 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8472 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8474 tmp
= load_reg(s
, rs
);
8475 if (insn
& (1 << 20)) {
8476 tmp64
= gen_addq_msw(tmp64
, tmp
);
8478 tmp64
= gen_subq_msw(tmp64
, tmp
);
8481 if (insn
& (1 << 4)) {
8482 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8484 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8485 tmp
= tcg_temp_new_i32();
8486 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8487 tcg_temp_free_i64(tmp64
);
8489 case 7: /* Unsigned sum of absolute differences. */
8490 gen_helper_usad8(tmp
, tmp
, tmp2
);
8491 tcg_temp_free_i32(tmp2
);
8493 tmp2
= load_reg(s
, rs
);
8494 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8495 tcg_temp_free_i32(tmp2
);
8499 store_reg(s
, rd
, tmp
);
8501 case 6: case 7: /* 64-bit multiply, Divide. */
8502 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8503 tmp
= load_reg(s
, rn
);
8504 tmp2
= load_reg(s
, rm
);
8505 if ((op
& 0x50) == 0x10) {
8507 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8511 gen_helper_udiv(tmp
, tmp
, tmp2
);
8513 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8514 tcg_temp_free_i32(tmp2
);
8515 store_reg(s
, rd
, tmp
);
8516 } else if ((op
& 0xe) == 0xc) {
8517 /* Dual multiply accumulate long. */
8519 gen_swap_half(tmp2
);
8520 gen_smul_dual(tmp
, tmp2
);
8522 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8524 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8526 tcg_temp_free_i32(tmp2
);
8528 tmp64
= tcg_temp_new_i64();
8529 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8530 tcg_temp_free_i32(tmp
);
8531 gen_addq(s
, tmp64
, rs
, rd
);
8532 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8533 tcg_temp_free_i64(tmp64
);
8536 /* Unsigned 64-bit multiply */
8537 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8541 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8542 tcg_temp_free_i32(tmp2
);
8543 tmp64
= tcg_temp_new_i64();
8544 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8545 tcg_temp_free_i32(tmp
);
8547 /* Signed 64-bit multiply */
8548 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8553 gen_addq_lo(s
, tmp64
, rs
);
8554 gen_addq_lo(s
, tmp64
, rd
);
8555 } else if (op
& 0x40) {
8556 /* 64-bit accumulate. */
8557 gen_addq(s
, tmp64
, rs
, rd
);
8559 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8560 tcg_temp_free_i64(tmp64
);
8565 case 6: case 7: case 14: case 15:
8567 if (((insn
>> 24) & 3) == 3) {
8568 /* Translate into the equivalent ARM encoding. */
8569 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8570 if (disas_neon_data_insn(env
, s
, insn
))
8573 if (insn
& (1 << 28))
8575 if (disas_coproc_insn (env
, s
, insn
))
8579 case 8: case 9: case 10: case 11:
8580 if (insn
& (1 << 15)) {
8581 /* Branches, misc control. */
8582 if (insn
& 0x5000) {
8583 /* Unconditional branch. */
8584 /* signextend(hw1[10:0]) -> offset[:12]. */
8585 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8586 /* hw1[10:0] -> offset[11:1]. */
8587 offset
|= (insn
& 0x7ff) << 1;
8588 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8589 offset[24:22] already have the same value because of the
8590 sign extension above. */
8591 offset
^= ((~insn
) & (1 << 13)) << 10;
8592 offset
^= ((~insn
) & (1 << 11)) << 11;
8594 if (insn
& (1 << 14)) {
8595 /* Branch and link. */
8596 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8600 if (insn
& (1 << 12)) {
8605 offset
&= ~(uint32_t)2;
8606 /* thumb2 bx, no need to check */
8607 gen_bx_im(s
, offset
);
8609 } else if (((insn
>> 23) & 7) == 7) {
8611 if (insn
& (1 << 13))
8614 if (insn
& (1 << 26)) {
8615 /* Secure monitor call (v6Z) */
8616 goto illegal_op
; /* not implemented. */
8618 op
= (insn
>> 20) & 7;
8620 case 0: /* msr cpsr. */
8622 tmp
= load_reg(s
, rn
);
8623 addr
= tcg_const_i32(insn
& 0xff);
8624 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8625 tcg_temp_free_i32(addr
);
8626 tcg_temp_free_i32(tmp
);
8631 case 1: /* msr spsr. */
8634 tmp
= load_reg(s
, rn
);
8636 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8640 case 2: /* cps, nop-hint. */
8641 if (((insn
>> 8) & 7) == 0) {
8642 gen_nop_hint(s
, insn
& 0xff);
8644 /* Implemented as NOP in user mode. */
8649 if (insn
& (1 << 10)) {
8650 if (insn
& (1 << 7))
8652 if (insn
& (1 << 6))
8654 if (insn
& (1 << 5))
8656 if (insn
& (1 << 9))
8657 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8659 if (insn
& (1 << 8)) {
8661 imm
|= (insn
& 0x1f);
8664 gen_set_psr_im(s
, offset
, 0, imm
);
8667 case 3: /* Special control operations. */
8669 op
= (insn
>> 4) & 0xf;
8677 /* These execute as NOPs. */
8684 /* Trivial implementation equivalent to bx. */
8685 tmp
= load_reg(s
, rn
);
8688 case 5: /* Exception return. */
8692 if (rn
!= 14 || rd
!= 15) {
8695 tmp
= load_reg(s
, rn
);
8696 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8697 gen_exception_return(s
, tmp
);
8699 case 6: /* mrs cpsr. */
8700 tmp
= tcg_temp_new_i32();
8702 addr
= tcg_const_i32(insn
& 0xff);
8703 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8704 tcg_temp_free_i32(addr
);
8706 gen_helper_cpsr_read(tmp
, cpu_env
);
8708 store_reg(s
, rd
, tmp
);
8710 case 7: /* mrs spsr. */
8711 /* Not accessible in user mode. */
8712 if (IS_USER(s
) || IS_M(env
))
8714 tmp
= load_cpu_field(spsr
);
8715 store_reg(s
, rd
, tmp
);
8720 /* Conditional branch. */
8721 op
= (insn
>> 22) & 0xf;
8722 /* Generate a conditional jump to next instruction. */
8723 s
->condlabel
= gen_new_label();
8724 gen_test_cc(op
^ 1, s
->condlabel
);
8727 /* offset[11:1] = insn[10:0] */
8728 offset
= (insn
& 0x7ff) << 1;
8729 /* offset[17:12] = insn[21:16]. */
8730 offset
|= (insn
& 0x003f0000) >> 4;
8731 /* offset[31:20] = insn[26]. */
8732 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8733 /* offset[18] = insn[13]. */
8734 offset
|= (insn
& (1 << 13)) << 5;
8735 /* offset[19] = insn[11]. */
8736 offset
|= (insn
& (1 << 11)) << 8;
8738 /* jump to the offset */
8739 gen_jmp(s
, s
->pc
+ offset
);
8742 /* Data processing immediate. */
8743 if (insn
& (1 << 25)) {
8744 if (insn
& (1 << 24)) {
8745 if (insn
& (1 << 20))
8747 /* Bitfield/Saturate. */
8748 op
= (insn
>> 21) & 7;
8750 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8752 tmp
= tcg_temp_new_i32();
8753 tcg_gen_movi_i32(tmp
, 0);
8755 tmp
= load_reg(s
, rn
);
8758 case 2: /* Signed bitfield extract. */
8760 if (shift
+ imm
> 32)
8763 gen_sbfx(tmp
, shift
, imm
);
8765 case 6: /* Unsigned bitfield extract. */
8767 if (shift
+ imm
> 32)
8770 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8772 case 3: /* Bitfield insert/clear. */
8775 imm
= imm
+ 1 - shift
;
8777 tmp2
= load_reg(s
, rd
);
8778 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
8779 tcg_temp_free_i32(tmp2
);
8784 default: /* Saturate. */
8787 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8789 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8791 tmp2
= tcg_const_i32(imm
);
8794 if ((op
& 1) && shift
== 0)
8795 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8797 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8800 if ((op
& 1) && shift
== 0)
8801 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8803 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8805 tcg_temp_free_i32(tmp2
);
8808 store_reg(s
, rd
, tmp
);
8810 imm
= ((insn
& 0x04000000) >> 15)
8811 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8812 if (insn
& (1 << 22)) {
8813 /* 16-bit immediate. */
8814 imm
|= (insn
>> 4) & 0xf000;
8815 if (insn
& (1 << 23)) {
8817 tmp
= load_reg(s
, rd
);
8818 tcg_gen_ext16u_i32(tmp
, tmp
);
8819 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8822 tmp
= tcg_temp_new_i32();
8823 tcg_gen_movi_i32(tmp
, imm
);
8826 /* Add/sub 12-bit immediate. */
8828 offset
= s
->pc
& ~(uint32_t)3;
8829 if (insn
& (1 << 23))
8833 tmp
= tcg_temp_new_i32();
8834 tcg_gen_movi_i32(tmp
, offset
);
8836 tmp
= load_reg(s
, rn
);
8837 if (insn
& (1 << 23))
8838 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8840 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8843 store_reg(s
, rd
, tmp
);
8846 int shifter_out
= 0;
8847 /* modified 12-bit immediate. */
8848 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8849 imm
= (insn
& 0xff);
8852 /* Nothing to do. */
8854 case 1: /* 00XY00XY */
8857 case 2: /* XY00XY00 */
8861 case 3: /* XYXYXYXY */
8865 default: /* Rotated constant. */
8866 shift
= (shift
<< 1) | (imm
>> 7);
8868 imm
= imm
<< (32 - shift
);
8872 tmp2
= tcg_temp_new_i32();
8873 tcg_gen_movi_i32(tmp2
, imm
);
8874 rn
= (insn
>> 16) & 0xf;
8876 tmp
= tcg_temp_new_i32();
8877 tcg_gen_movi_i32(tmp
, 0);
8879 tmp
= load_reg(s
, rn
);
8881 op
= (insn
>> 21) & 0xf;
8882 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8883 shifter_out
, tmp
, tmp2
))
8885 tcg_temp_free_i32(tmp2
);
8886 rd
= (insn
>> 8) & 0xf;
8888 store_reg(s
, rd
, tmp
);
8890 tcg_temp_free_i32(tmp
);
8895 case 12: /* Load/store single data item. */
8900 if ((insn
& 0x01100000) == 0x01000000) {
8901 if (disas_neon_ls_insn(env
, s
, insn
))
8905 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8907 if (!(insn
& (1 << 20))) {
8911 /* Byte or halfword load space with dest == r15 : memory hints.
8912 * Catch them early so we don't emit pointless addressing code.
8913 * This space is a mix of:
8914 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8915 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8917 * unallocated hints, which must be treated as NOPs
8918 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8919 * which is easiest for the decoding logic
8920 * Some space which must UNDEF
8922 int op1
= (insn
>> 23) & 3;
8923 int op2
= (insn
>> 6) & 0x3f;
8928 /* UNPREDICTABLE, unallocated hint or
8929 * PLD/PLDW/PLI (literal)
8934 return 0; /* PLD/PLDW/PLI or unallocated hint */
8936 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
8937 return 0; /* PLD/PLDW/PLI or unallocated hint */
8939 /* UNDEF space, or an UNPREDICTABLE */
8945 addr
= tcg_temp_new_i32();
8947 /* s->pc has already been incremented by 4. */
8948 imm
= s
->pc
& 0xfffffffc;
8949 if (insn
& (1 << 23))
8950 imm
+= insn
& 0xfff;
8952 imm
-= insn
& 0xfff;
8953 tcg_gen_movi_i32(addr
, imm
);
8955 addr
= load_reg(s
, rn
);
8956 if (insn
& (1 << 23)) {
8957 /* Positive offset. */
8959 tcg_gen_addi_i32(addr
, addr
, imm
);
8962 switch ((insn
>> 8) & 0xf) {
8963 case 0x0: /* Shifted Register. */
8964 shift
= (insn
>> 4) & 0xf;
8966 tcg_temp_free_i32(addr
);
8969 tmp
= load_reg(s
, rm
);
8971 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8972 tcg_gen_add_i32(addr
, addr
, tmp
);
8973 tcg_temp_free_i32(tmp
);
8975 case 0xc: /* Negative offset. */
8976 tcg_gen_addi_i32(addr
, addr
, -imm
);
8978 case 0xe: /* User privilege. */
8979 tcg_gen_addi_i32(addr
, addr
, imm
);
8982 case 0x9: /* Post-decrement. */
8985 case 0xb: /* Post-increment. */
8989 case 0xd: /* Pre-decrement. */
8992 case 0xf: /* Pre-increment. */
8993 tcg_gen_addi_i32(addr
, addr
, imm
);
8997 tcg_temp_free_i32(addr
);
9002 if (insn
& (1 << 20)) {
9005 case 0: tmp
= gen_ld8u(addr
, user
); break;
9006 case 4: tmp
= gen_ld8s(addr
, user
); break;
9007 case 1: tmp
= gen_ld16u(addr
, user
); break;
9008 case 5: tmp
= gen_ld16s(addr
, user
); break;
9009 case 2: tmp
= gen_ld32(addr
, user
); break;
9011 tcg_temp_free_i32(addr
);
9017 store_reg(s
, rs
, tmp
);
9021 tmp
= load_reg(s
, rs
);
9023 case 0: gen_st8(tmp
, addr
, user
); break;
9024 case 1: gen_st16(tmp
, addr
, user
); break;
9025 case 2: gen_st32(tmp
, addr
, user
); break;
9027 tcg_temp_free_i32(addr
);
9032 tcg_gen_addi_i32(addr
, addr
, imm
);
9034 store_reg(s
, rn
, addr
);
9036 tcg_temp_free_i32(addr
);
9048 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9050 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9057 if (s
->condexec_mask
) {
9058 cond
= s
->condexec_cond
;
9059 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9060 s
->condlabel
= gen_new_label();
9061 gen_test_cc(cond
^ 1, s
->condlabel
);
9066 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9069 switch (insn
>> 12) {
9073 op
= (insn
>> 11) & 3;
9076 rn
= (insn
>> 3) & 7;
9077 tmp
= load_reg(s
, rn
);
9078 if (insn
& (1 << 10)) {
9080 tmp2
= tcg_temp_new_i32();
9081 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9084 rm
= (insn
>> 6) & 7;
9085 tmp2
= load_reg(s
, rm
);
9087 if (insn
& (1 << 9)) {
9088 if (s
->condexec_mask
)
9089 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9091 gen_sub_CC(tmp
, tmp
, tmp2
);
9093 if (s
->condexec_mask
)
9094 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9096 gen_add_CC(tmp
, tmp
, tmp2
);
9098 tcg_temp_free_i32(tmp2
);
9099 store_reg(s
, rd
, tmp
);
9101 /* shift immediate */
9102 rm
= (insn
>> 3) & 7;
9103 shift
= (insn
>> 6) & 0x1f;
9104 tmp
= load_reg(s
, rm
);
9105 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9106 if (!s
->condexec_mask
)
9108 store_reg(s
, rd
, tmp
);
9112 /* arithmetic large immediate */
9113 op
= (insn
>> 11) & 3;
9114 rd
= (insn
>> 8) & 0x7;
9115 if (op
== 0) { /* mov */
9116 tmp
= tcg_temp_new_i32();
9117 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9118 if (!s
->condexec_mask
)
9120 store_reg(s
, rd
, tmp
);
9122 tmp
= load_reg(s
, rd
);
9123 tmp2
= tcg_temp_new_i32();
9124 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9127 gen_sub_CC(tmp
, tmp
, tmp2
);
9128 tcg_temp_free_i32(tmp
);
9129 tcg_temp_free_i32(tmp2
);
9132 if (s
->condexec_mask
)
9133 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9135 gen_add_CC(tmp
, tmp
, tmp2
);
9136 tcg_temp_free_i32(tmp2
);
9137 store_reg(s
, rd
, tmp
);
9140 if (s
->condexec_mask
)
9141 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9143 gen_sub_CC(tmp
, tmp
, tmp2
);
9144 tcg_temp_free_i32(tmp2
);
9145 store_reg(s
, rd
, tmp
);
9151 if (insn
& (1 << 11)) {
9152 rd
= (insn
>> 8) & 7;
9153 /* load pc-relative. Bit 1 of PC is ignored. */
9154 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9155 val
&= ~(uint32_t)2;
9156 addr
= tcg_temp_new_i32();
9157 tcg_gen_movi_i32(addr
, val
);
9158 tmp
= gen_ld32(addr
, IS_USER(s
));
9159 tcg_temp_free_i32(addr
);
9160 store_reg(s
, rd
, tmp
);
9163 if (insn
& (1 << 10)) {
9164 /* data processing extended or blx */
9165 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9166 rm
= (insn
>> 3) & 0xf;
9167 op
= (insn
>> 8) & 3;
9170 tmp
= load_reg(s
, rd
);
9171 tmp2
= load_reg(s
, rm
);
9172 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9173 tcg_temp_free_i32(tmp2
);
9174 store_reg(s
, rd
, tmp
);
9177 tmp
= load_reg(s
, rd
);
9178 tmp2
= load_reg(s
, rm
);
9179 gen_sub_CC(tmp
, tmp
, tmp2
);
9180 tcg_temp_free_i32(tmp2
);
9181 tcg_temp_free_i32(tmp
);
9183 case 2: /* mov/cpy */
9184 tmp
= load_reg(s
, rm
);
9185 store_reg(s
, rd
, tmp
);
9187 case 3:/* branch [and link] exchange thumb register */
9188 tmp
= load_reg(s
, rm
);
9189 if (insn
& (1 << 7)) {
9191 val
= (uint32_t)s
->pc
| 1;
9192 tmp2
= tcg_temp_new_i32();
9193 tcg_gen_movi_i32(tmp2
, val
);
9194 store_reg(s
, 14, tmp2
);
9196 /* already thumb, no need to check */
9203 /* data processing register */
9205 rm
= (insn
>> 3) & 7;
9206 op
= (insn
>> 6) & 0xf;
9207 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9208 /* the shift/rotate ops want the operands backwards */
9217 if (op
== 9) { /* neg */
9218 tmp
= tcg_temp_new_i32();
9219 tcg_gen_movi_i32(tmp
, 0);
9220 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9221 tmp
= load_reg(s
, rd
);
9226 tmp2
= load_reg(s
, rm
);
9229 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9230 if (!s
->condexec_mask
)
9234 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9235 if (!s
->condexec_mask
)
9239 if (s
->condexec_mask
) {
9240 gen_shl(tmp2
, tmp2
, tmp
);
9242 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9247 if (s
->condexec_mask
) {
9248 gen_shr(tmp2
, tmp2
, tmp
);
9250 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9255 if (s
->condexec_mask
) {
9256 gen_sar(tmp2
, tmp2
, tmp
);
9258 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9263 if (s
->condexec_mask
) {
9266 gen_adc_CC(tmp
, tmp
, tmp2
);
9270 if (s
->condexec_mask
)
9271 gen_sub_carry(tmp
, tmp
, tmp2
);
9273 gen_helper_sbc_cc(tmp
, cpu_env
, tmp
, tmp2
);
9276 if (s
->condexec_mask
) {
9277 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9278 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9280 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9285 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9290 if (s
->condexec_mask
)
9291 tcg_gen_neg_i32(tmp
, tmp2
);
9293 gen_sub_CC(tmp
, tmp
, tmp2
);
9296 gen_sub_CC(tmp
, tmp
, tmp2
);
9300 gen_add_CC(tmp
, tmp
, tmp2
);
9304 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9305 if (!s
->condexec_mask
)
9309 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9310 if (!s
->condexec_mask
)
9314 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9315 if (!s
->condexec_mask
)
9319 tcg_gen_not_i32(tmp2
, tmp2
);
9320 if (!s
->condexec_mask
)
9328 store_reg(s
, rm
, tmp2
);
9330 tcg_temp_free_i32(tmp
);
9332 store_reg(s
, rd
, tmp
);
9333 tcg_temp_free_i32(tmp2
);
9336 tcg_temp_free_i32(tmp
);
9337 tcg_temp_free_i32(tmp2
);
9342 /* load/store register offset. */
9344 rn
= (insn
>> 3) & 7;
9345 rm
= (insn
>> 6) & 7;
9346 op
= (insn
>> 9) & 7;
9347 addr
= load_reg(s
, rn
);
9348 tmp
= load_reg(s
, rm
);
9349 tcg_gen_add_i32(addr
, addr
, tmp
);
9350 tcg_temp_free_i32(tmp
);
9352 if (op
< 3) /* store */
9353 tmp
= load_reg(s
, rd
);
9357 gen_st32(tmp
, addr
, IS_USER(s
));
9360 gen_st16(tmp
, addr
, IS_USER(s
));
9363 gen_st8(tmp
, addr
, IS_USER(s
));
9366 tmp
= gen_ld8s(addr
, IS_USER(s
));
9369 tmp
= gen_ld32(addr
, IS_USER(s
));
9372 tmp
= gen_ld16u(addr
, IS_USER(s
));
9375 tmp
= gen_ld8u(addr
, IS_USER(s
));
9378 tmp
= gen_ld16s(addr
, IS_USER(s
));
9381 if (op
>= 3) /* load */
9382 store_reg(s
, rd
, tmp
);
9383 tcg_temp_free_i32(addr
);
9387 /* load/store word immediate offset */
9389 rn
= (insn
>> 3) & 7;
9390 addr
= load_reg(s
, rn
);
9391 val
= (insn
>> 4) & 0x7c;
9392 tcg_gen_addi_i32(addr
, addr
, val
);
9394 if (insn
& (1 << 11)) {
9396 tmp
= gen_ld32(addr
, IS_USER(s
));
9397 store_reg(s
, rd
, tmp
);
9400 tmp
= load_reg(s
, rd
);
9401 gen_st32(tmp
, addr
, IS_USER(s
));
9403 tcg_temp_free_i32(addr
);
9407 /* load/store byte immediate offset */
9409 rn
= (insn
>> 3) & 7;
9410 addr
= load_reg(s
, rn
);
9411 val
= (insn
>> 6) & 0x1f;
9412 tcg_gen_addi_i32(addr
, addr
, val
);
9414 if (insn
& (1 << 11)) {
9416 tmp
= gen_ld8u(addr
, IS_USER(s
));
9417 store_reg(s
, rd
, tmp
);
9420 tmp
= load_reg(s
, rd
);
9421 gen_st8(tmp
, addr
, IS_USER(s
));
9423 tcg_temp_free_i32(addr
);
9427 /* load/store halfword immediate offset */
9429 rn
= (insn
>> 3) & 7;
9430 addr
= load_reg(s
, rn
);
9431 val
= (insn
>> 5) & 0x3e;
9432 tcg_gen_addi_i32(addr
, addr
, val
);
9434 if (insn
& (1 << 11)) {
9436 tmp
= gen_ld16u(addr
, IS_USER(s
));
9437 store_reg(s
, rd
, tmp
);
9440 tmp
= load_reg(s
, rd
);
9441 gen_st16(tmp
, addr
, IS_USER(s
));
9443 tcg_temp_free_i32(addr
);
9447 /* load/store from stack */
9448 rd
= (insn
>> 8) & 7;
9449 addr
= load_reg(s
, 13);
9450 val
= (insn
& 0xff) * 4;
9451 tcg_gen_addi_i32(addr
, addr
, val
);
9453 if (insn
& (1 << 11)) {
9455 tmp
= gen_ld32(addr
, IS_USER(s
));
9456 store_reg(s
, rd
, tmp
);
9459 tmp
= load_reg(s
, rd
);
9460 gen_st32(tmp
, addr
, IS_USER(s
));
9462 tcg_temp_free_i32(addr
);
9466 /* add to high reg */
9467 rd
= (insn
>> 8) & 7;
9468 if (insn
& (1 << 11)) {
9470 tmp
= load_reg(s
, 13);
9472 /* PC. bit 1 is ignored. */
9473 tmp
= tcg_temp_new_i32();
9474 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9476 val
= (insn
& 0xff) * 4;
9477 tcg_gen_addi_i32(tmp
, tmp
, val
);
9478 store_reg(s
, rd
, tmp
);
9483 op
= (insn
>> 8) & 0xf;
9486 /* adjust stack pointer */
9487 tmp
= load_reg(s
, 13);
9488 val
= (insn
& 0x7f) * 4;
9489 if (insn
& (1 << 7))
9490 val
= -(int32_t)val
;
9491 tcg_gen_addi_i32(tmp
, tmp
, val
);
9492 store_reg(s
, 13, tmp
);
9495 case 2: /* sign/zero extend. */
9498 rm
= (insn
>> 3) & 7;
9499 tmp
= load_reg(s
, rm
);
9500 switch ((insn
>> 6) & 3) {
9501 case 0: gen_sxth(tmp
); break;
9502 case 1: gen_sxtb(tmp
); break;
9503 case 2: gen_uxth(tmp
); break;
9504 case 3: gen_uxtb(tmp
); break;
9506 store_reg(s
, rd
, tmp
);
9508 case 4: case 5: case 0xc: case 0xd:
9510 addr
= load_reg(s
, 13);
9511 if (insn
& (1 << 8))
9515 for (i
= 0; i
< 8; i
++) {
9516 if (insn
& (1 << i
))
9519 if ((insn
& (1 << 11)) == 0) {
9520 tcg_gen_addi_i32(addr
, addr
, -offset
);
9522 for (i
= 0; i
< 8; i
++) {
9523 if (insn
& (1 << i
)) {
9524 if (insn
& (1 << 11)) {
9526 tmp
= gen_ld32(addr
, IS_USER(s
));
9527 store_reg(s
, i
, tmp
);
9530 tmp
= load_reg(s
, i
);
9531 gen_st32(tmp
, addr
, IS_USER(s
));
9533 /* advance to the next address. */
9534 tcg_gen_addi_i32(addr
, addr
, 4);
9538 if (insn
& (1 << 8)) {
9539 if (insn
& (1 << 11)) {
9541 tmp
= gen_ld32(addr
, IS_USER(s
));
9542 /* don't set the pc until the rest of the instruction
9546 tmp
= load_reg(s
, 14);
9547 gen_st32(tmp
, addr
, IS_USER(s
));
9549 tcg_gen_addi_i32(addr
, addr
, 4);
9551 if ((insn
& (1 << 11)) == 0) {
9552 tcg_gen_addi_i32(addr
, addr
, -offset
);
9554 /* write back the new stack pointer */
9555 store_reg(s
, 13, addr
);
9556 /* set the new PC value */
9557 if ((insn
& 0x0900) == 0x0900) {
9558 store_reg_from_load(env
, s
, 15, tmp
);
9562 case 1: case 3: case 9: case 11: /* czb */
9564 tmp
= load_reg(s
, rm
);
9565 s
->condlabel
= gen_new_label();
9567 if (insn
& (1 << 11))
9568 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9570 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9571 tcg_temp_free_i32(tmp
);
9572 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9573 val
= (uint32_t)s
->pc
+ 2;
9578 case 15: /* IT, nop-hint. */
9579 if ((insn
& 0xf) == 0) {
9580 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9584 s
->condexec_cond
= (insn
>> 4) & 0xe;
9585 s
->condexec_mask
= insn
& 0x1f;
9586 /* No actual code generated for this insn, just setup state. */
9589 case 0xe: /* bkpt */
9591 gen_exception_insn(s
, 2, EXCP_BKPT
);
9596 rn
= (insn
>> 3) & 0x7;
9598 tmp
= load_reg(s
, rn
);
9599 switch ((insn
>> 6) & 3) {
9600 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9601 case 1: gen_rev16(tmp
); break;
9602 case 3: gen_revsh(tmp
); break;
9603 default: goto illegal_op
;
9605 store_reg(s
, rd
, tmp
);
9609 switch ((insn
>> 5) & 7) {
9613 if (((insn
>> 3) & 1) != s
->bswap_code
) {
9614 /* Dynamic endianness switching not implemented. */
9625 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9628 addr
= tcg_const_i32(19);
9629 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9630 tcg_temp_free_i32(addr
);
9634 addr
= tcg_const_i32(16);
9635 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9636 tcg_temp_free_i32(addr
);
9638 tcg_temp_free_i32(tmp
);
9641 if (insn
& (1 << 4)) {
9642 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9646 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9661 /* load/store multiple */
9663 TCGV_UNUSED(loaded_var
);
9664 rn
= (insn
>> 8) & 0x7;
9665 addr
= load_reg(s
, rn
);
9666 for (i
= 0; i
< 8; i
++) {
9667 if (insn
& (1 << i
)) {
9668 if (insn
& (1 << 11)) {
9670 tmp
= gen_ld32(addr
, IS_USER(s
));
9674 store_reg(s
, i
, tmp
);
9678 tmp
= load_reg(s
, i
);
9679 gen_st32(tmp
, addr
, IS_USER(s
));
9681 /* advance to the next address */
9682 tcg_gen_addi_i32(addr
, addr
, 4);
9685 if ((insn
& (1 << rn
)) == 0) {
9686 /* base reg not in list: base register writeback */
9687 store_reg(s
, rn
, addr
);
9689 /* base reg in list: if load, complete it now */
9690 if (insn
& (1 << 11)) {
9691 store_reg(s
, rn
, loaded_var
);
9693 tcg_temp_free_i32(addr
);
9698 /* conditional branch or swi */
9699 cond
= (insn
>> 8) & 0xf;
9705 gen_set_pc_im(s
->pc
);
9706 s
->is_jmp
= DISAS_SWI
;
9709 /* generate a conditional jump to next instruction */
9710 s
->condlabel
= gen_new_label();
9711 gen_test_cc(cond
^ 1, s
->condlabel
);
9714 /* jump to the offset */
9715 val
= (uint32_t)s
->pc
+ 2;
9716 offset
= ((int32_t)insn
<< 24) >> 24;
9722 if (insn
& (1 << 11)) {
9723 if (disas_thumb2_insn(env
, s
, insn
))
9727 /* unconditional branch */
9728 val
= (uint32_t)s
->pc
;
9729 offset
= ((int32_t)insn
<< 21) >> 21;
9730 val
+= (offset
<< 1) + 2;
9735 if (disas_thumb2_insn(env
, s
, insn
))
9741 gen_exception_insn(s
, 4, EXCP_UDEF
);
9745 gen_exception_insn(s
, 2, EXCP_UDEF
);
9748 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9749 basic block 'tb'. If search_pc is TRUE, also generate PC
9750 information for each intermediate instruction. */
9751 static inline void gen_intermediate_code_internal(CPUARMState
*env
,
9752 TranslationBlock
*tb
,
9755 DisasContext dc1
, *dc
= &dc1
;
9757 uint16_t *gen_opc_end
;
9759 target_ulong pc_start
;
9760 uint32_t next_page_start
;
9764 /* generate intermediate code */
9769 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
9771 dc
->is_jmp
= DISAS_NEXT
;
9773 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9775 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9776 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
9777 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9778 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9779 #if !defined(CONFIG_USER_ONLY)
9780 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9782 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9783 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9784 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9785 cpu_F0s
= tcg_temp_new_i32();
9786 cpu_F1s
= tcg_temp_new_i32();
9787 cpu_F0d
= tcg_temp_new_i64();
9788 cpu_F1d
= tcg_temp_new_i64();
9791 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9792 cpu_M0
= tcg_temp_new_i64();
9793 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9796 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9798 max_insns
= CF_COUNT_MASK
;
9802 tcg_clear_temp_count();
9804 /* A note on handling of the condexec (IT) bits:
9806 * We want to avoid the overhead of having to write the updated condexec
9807 * bits back to the CPUARMState for every instruction in an IT block. So:
9808 * (1) if the condexec bits are not already zero then we write
9809 * zero back into the CPUARMState now. This avoids complications trying
9810 * to do it at the end of the block. (For example if we don't do this
9811 * it's hard to identify whether we can safely skip writing condexec
9812 * at the end of the TB, which we definitely want to do for the case
9813 * where a TB doesn't do anything with the IT state at all.)
9814 * (2) if we are going to leave the TB then we call gen_set_condexec()
9815 * which will write the correct value into CPUARMState if zero is wrong.
9816 * This is done both for leaving the TB at the end, and for leaving
9817 * it because of an exception we know will happen, which is done in
9818 * gen_exception_insn(). The latter is necessary because we need to
9819 * leave the TB with the PC/IT state just prior to execution of the
9820 * instruction which caused the exception.
9821 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9822 * then the CPUARMState will be wrong and we need to reset it.
9823 * This is handled in the same way as restoration of the
9824 * PC in these situations: we will be called again with search_pc=1
9825 * and generate a mapping of the condexec bits for each PC in
9826 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9827 * this to restore the condexec bits.
9829 * Note that there are no instructions which can read the condexec
9830 * bits, and none which can write non-static values to them, so
9831 * we don't need to care about whether CPUARMState is correct in the
9835 /* Reset the conditional execution bits immediately. This avoids
9836 complications trying to do it at the end of the block. */
9837 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9839 TCGv tmp
= tcg_temp_new_i32();
9840 tcg_gen_movi_i32(tmp
, 0);
9841 store_cpu_field(tmp
, condexec_bits
);
9844 #ifdef CONFIG_USER_ONLY
9845 /* Intercept jump to the magic kernel page. */
9846 if (dc
->pc
>= 0xffff0000) {
9847 /* We always get here via a jump, so know we are not in a
9848 conditional execution block. */
9849 gen_exception(EXCP_KERNEL_TRAP
);
9850 dc
->is_jmp
= DISAS_UPDATE
;
9854 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9855 /* We always get here via a jump, so know we are not in a
9856 conditional execution block. */
9857 gen_exception(EXCP_EXCEPTION_EXIT
);
9858 dc
->is_jmp
= DISAS_UPDATE
;
9863 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9864 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9865 if (bp
->pc
== dc
->pc
) {
9866 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9867 /* Advance PC so that clearing the breakpoint will
9868 invalidate this TB. */
9870 goto done_generating
;
9876 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
9880 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
9882 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
9883 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9884 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
9885 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
9888 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9891 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
9892 tcg_gen_debug_insn_start(dc
->pc
);
9896 disas_thumb_insn(env
, dc
);
9897 if (dc
->condexec_mask
) {
9898 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9899 | ((dc
->condexec_mask
>> 4) & 1);
9900 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9901 if (dc
->condexec_mask
== 0) {
9902 dc
->condexec_cond
= 0;
9906 disas_arm_insn(env
, dc
);
9909 if (dc
->condjmp
&& !dc
->is_jmp
) {
9910 gen_set_label(dc
->condlabel
);
9914 if (tcg_check_temp_count()) {
9915 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
9918 /* Translation stops when a conditional branch is encountered.
9919 * Otherwise the subsequent code could get translated several times.
9920 * Also stop translation when a page boundary is reached. This
9921 * ensures prefetch aborts occur at the right place. */
9923 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
9924 !env
->singlestep_enabled
&&
9926 dc
->pc
< next_page_start
&&
9927 num_insns
< max_insns
);
9929 if (tb
->cflags
& CF_LAST_IO
) {
9931 /* FIXME: This can theoretically happen with self-modifying
9933 cpu_abort(env
, "IO on conditional branch instruction");
9938 /* At this stage dc->condjmp will only be set when the skipped
9939 instruction was a conditional branch or trap, and the PC has
9940 already been written. */
9941 if (unlikely(env
->singlestep_enabled
)) {
9942 /* Make sure the pc is updated, and raise a debug exception. */
9944 gen_set_condexec(dc
);
9945 if (dc
->is_jmp
== DISAS_SWI
) {
9946 gen_exception(EXCP_SWI
);
9948 gen_exception(EXCP_DEBUG
);
9950 gen_set_label(dc
->condlabel
);
9952 if (dc
->condjmp
|| !dc
->is_jmp
) {
9953 gen_set_pc_im(dc
->pc
);
9956 gen_set_condexec(dc
);
9957 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
9958 gen_exception(EXCP_SWI
);
9960 /* FIXME: Single stepping a WFI insn will not halt
9962 gen_exception(EXCP_DEBUG
);
9965 /* While branches must always occur at the end of an IT block,
9966 there are a few other things that can cause us to terminate
9967 the TB in the middle of an IT block:
9968 - Exception generating instructions (bkpt, swi, undefined).
9970 - Hardware watchpoints.
9971 Hardware breakpoints have already been handled and skip this code.
9973 gen_set_condexec(dc
);
9974 switch(dc
->is_jmp
) {
9976 gen_goto_tb(dc
, 1, dc
->pc
);
9981 /* indicate that the hash table must be used to find the next TB */
9985 /* nothing more to generate */
9988 gen_helper_wfi(cpu_env
);
9991 gen_exception(EXCP_SWI
);
9995 gen_set_label(dc
->condlabel
);
9996 gen_set_condexec(dc
);
9997 gen_goto_tb(dc
, 1, dc
->pc
);
10003 gen_icount_end(tb
, num_insns
);
10004 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
10007 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
10008 qemu_log("----------------\n");
10009 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
10010 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
10011 dc
->thumb
| (dc
->bswap_code
<< 1));
10016 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10019 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10021 tb
->size
= dc
->pc
- pc_start
;
10022 tb
->icount
= num_insns
;
10026 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
10028 gen_intermediate_code_internal(env
, tb
, 0);
10031 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10033 gen_intermediate_code_internal(env
, tb
, 1);
10036 static const char *cpu_mode_names
[16] = {
10037 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10038 "???", "???", "???", "und", "???", "???", "???", "sys"
10041 void cpu_dump_state(CPUARMState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
10047 for(i
=0;i
<16;i
++) {
10048 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10050 cpu_fprintf(f
, "\n");
10052 cpu_fprintf(f
, " ");
10054 psr
= cpsr_read(env
);
10055 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10057 psr
& (1 << 31) ? 'N' : '-',
10058 psr
& (1 << 30) ? 'Z' : '-',
10059 psr
& (1 << 29) ? 'C' : '-',
10060 psr
& (1 << 28) ? 'V' : '-',
10061 psr
& CPSR_T
? 'T' : 'A',
10062 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10064 if (flags
& CPU_DUMP_FPU
) {
10065 int numvfpregs
= 0;
10066 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10069 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10072 for (i
= 0; i
< numvfpregs
; i
++) {
10073 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10074 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10075 i
* 2, (uint32_t)v
,
10076 i
* 2 + 1, (uint32_t)(v
>> 32),
10079 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10083 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10085 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10086 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];