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
, cpu_NF
, 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 /* dest = T0 + ~T1 + CF = T0 - T1 + CF - 1. Compute C, N, V and Z flags */
468 static void gen_sbc_CC(TCGv dest
, TCGv t0
, TCGv t1
)
470 TCGv tmp
= tcg_temp_new_i32();
471 tcg_gen_subi_i32(cpu_CF
, cpu_CF
, 1);
472 if (TCG_TARGET_HAS_add2_i32
) {
473 tcg_gen_movi_i32(tmp
, 0);
474 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
475 tcg_gen_sub2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
477 TCGv_i64 q0
= tcg_temp_new_i64();
478 TCGv_i64 q1
= tcg_temp_new_i64();
479 tcg_gen_extu_i32_i64(q0
, t0
);
480 tcg_gen_extu_i32_i64(q1
, t1
);
481 tcg_gen_sub_i64(q0
, q0
, q1
);
482 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
483 tcg_gen_add_i64(q0
, q0
, q1
);
484 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
485 tcg_temp_free_i64(q0
);
486 tcg_temp_free_i64(q1
);
488 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
489 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
490 tcg_gen_xor_i32(tmp
, t0
, t1
);
491 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
492 tcg_temp_free_i32(tmp
);
493 tcg_gen_mov_i32(dest
, cpu_NF
);
496 #define GEN_SHIFT(name) \
497 static void gen_##name(TCGv dest, TCGv t0, TCGv t1) \
499 TCGv tmp1, tmp2, tmp3; \
500 tmp1 = tcg_temp_new_i32(); \
501 tcg_gen_andi_i32(tmp1, t1, 0xff); \
502 tmp2 = tcg_const_i32(0); \
503 tmp3 = tcg_const_i32(0x1f); \
504 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
505 tcg_temp_free_i32(tmp3); \
506 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
507 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
508 tcg_temp_free_i32(tmp2); \
509 tcg_temp_free_i32(tmp1); \
515 static void gen_sar(TCGv dest
, TCGv t0
, TCGv t1
)
518 tmp1
= tcg_temp_new_i32();
519 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
520 tmp2
= tcg_const_i32(0x1f);
521 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
522 tcg_temp_free_i32(tmp2
);
523 tcg_gen_sar_i32(dest
, t0
, tmp1
);
524 tcg_temp_free_i32(tmp1
);
527 static void tcg_gen_abs_i32(TCGv dest
, TCGv src
)
529 TCGv c0
= tcg_const_i32(0);
530 TCGv tmp
= tcg_temp_new_i32();
531 tcg_gen_neg_i32(tmp
, src
);
532 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
533 tcg_temp_free_i32(c0
);
534 tcg_temp_free_i32(tmp
);
537 static void shifter_out_im(TCGv var
, int shift
)
540 tcg_gen_andi_i32(cpu_CF
, var
, 1);
542 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
544 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
549 /* Shift by immediate. Includes special handling for shift == 0. */
550 static inline void gen_arm_shift_im(TCGv var
, int shiftop
, int shift
, int flags
)
556 shifter_out_im(var
, 32 - shift
);
557 tcg_gen_shli_i32(var
, var
, shift
);
563 tcg_gen_shri_i32(cpu_CF
, var
, 31);
565 tcg_gen_movi_i32(var
, 0);
568 shifter_out_im(var
, shift
- 1);
569 tcg_gen_shri_i32(var
, var
, shift
);
576 shifter_out_im(var
, shift
- 1);
579 tcg_gen_sari_i32(var
, var
, shift
);
581 case 3: /* ROR/RRX */
584 shifter_out_im(var
, shift
- 1);
585 tcg_gen_rotri_i32(var
, var
, shift
); break;
587 TCGv tmp
= tcg_temp_new_i32();
588 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
590 shifter_out_im(var
, 0);
591 tcg_gen_shri_i32(var
, var
, 1);
592 tcg_gen_or_i32(var
, var
, tmp
);
593 tcg_temp_free_i32(tmp
);
598 static inline void gen_arm_shift_reg(TCGv var
, int shiftop
,
599 TCGv shift
, int flags
)
603 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
604 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
605 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
606 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
611 gen_shl(var
, var
, shift
);
614 gen_shr(var
, var
, shift
);
617 gen_sar(var
, var
, shift
);
619 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
620 tcg_gen_rotr_i32(var
, var
, shift
); break;
623 tcg_temp_free_i32(shift
);
626 #define PAS_OP(pfx) \
628 case 0: gen_pas_helper(glue(pfx,add16)); break; \
629 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
630 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
631 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
632 case 4: gen_pas_helper(glue(pfx,add8)); break; \
633 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
635 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
640 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
642 tmp
= tcg_temp_new_ptr();
643 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
645 tcg_temp_free_ptr(tmp
);
648 tmp
= tcg_temp_new_ptr();
649 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
651 tcg_temp_free_ptr(tmp
);
653 #undef gen_pas_helper
654 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
667 #undef gen_pas_helper
672 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
673 #define PAS_OP(pfx) \
675 case 0: gen_pas_helper(glue(pfx,add8)); break; \
676 case 1: gen_pas_helper(glue(pfx,add16)); break; \
677 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
678 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
679 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
680 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
682 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv a
, TCGv b
)
687 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
689 tmp
= tcg_temp_new_ptr();
690 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
692 tcg_temp_free_ptr(tmp
);
695 tmp
= tcg_temp_new_ptr();
696 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
698 tcg_temp_free_ptr(tmp
);
700 #undef gen_pas_helper
701 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
714 #undef gen_pas_helper
719 static void gen_test_cc(int cc
, int label
)
726 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
729 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
732 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
735 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
738 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
741 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
744 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
747 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
749 case 8: /* hi: C && !Z */
750 inv
= gen_new_label();
751 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
752 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
755 case 9: /* ls: !C || Z */
756 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
757 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
759 case 10: /* ge: N == V -> N ^ V == 0 */
760 tmp
= tcg_temp_new_i32();
761 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
762 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
763 tcg_temp_free_i32(tmp
);
765 case 11: /* lt: N != V -> N ^ V != 0 */
766 tmp
= tcg_temp_new_i32();
767 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
768 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
769 tcg_temp_free_i32(tmp
);
771 case 12: /* gt: !Z && N == V */
772 inv
= gen_new_label();
773 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
774 tmp
= tcg_temp_new_i32();
775 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
776 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
777 tcg_temp_free_i32(tmp
);
780 case 13: /* le: Z || N != V */
781 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
782 tmp
= tcg_temp_new_i32();
783 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
784 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
785 tcg_temp_free_i32(tmp
);
788 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
793 static const uint8_t table_logic_cc
[16] = {
812 /* Set PC and Thumb state from an immediate address. */
813 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
817 s
->is_jmp
= DISAS_UPDATE
;
818 if (s
->thumb
!= (addr
& 1)) {
819 tmp
= tcg_temp_new_i32();
820 tcg_gen_movi_i32(tmp
, addr
& 1);
821 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
822 tcg_temp_free_i32(tmp
);
824 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
827 /* Set PC and Thumb state from var. var is marked as dead. */
828 static inline void gen_bx(DisasContext
*s
, TCGv var
)
830 s
->is_jmp
= DISAS_UPDATE
;
831 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
832 tcg_gen_andi_i32(var
, var
, 1);
833 store_cpu_field(var
, thumb
);
836 /* Variant of store_reg which uses branch&exchange logic when storing
837 to r15 in ARM architecture v7 and above. The source must be a temporary
838 and will be marked as dead. */
839 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
842 if (reg
== 15 && ENABLE_ARCH_7
) {
845 store_reg(s
, reg
, var
);
849 /* Variant of store_reg which uses branch&exchange logic when storing
850 * to r15 in ARM architecture v5T and above. This is used for storing
851 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
852 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
853 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
856 if (reg
== 15 && ENABLE_ARCH_5
) {
859 store_reg(s
, reg
, var
);
863 static inline TCGv
gen_ld8s(TCGv addr
, int index
)
865 TCGv tmp
= tcg_temp_new_i32();
866 tcg_gen_qemu_ld8s(tmp
, addr
, index
);
869 static inline TCGv
gen_ld8u(TCGv addr
, int index
)
871 TCGv tmp
= tcg_temp_new_i32();
872 tcg_gen_qemu_ld8u(tmp
, addr
, index
);
875 static inline TCGv
gen_ld16s(TCGv addr
, int index
)
877 TCGv tmp
= tcg_temp_new_i32();
878 tcg_gen_qemu_ld16s(tmp
, addr
, index
);
881 static inline TCGv
gen_ld16u(TCGv addr
, int index
)
883 TCGv tmp
= tcg_temp_new_i32();
884 tcg_gen_qemu_ld16u(tmp
, addr
, index
);
887 static inline TCGv
gen_ld32(TCGv addr
, int index
)
889 TCGv tmp
= tcg_temp_new_i32();
890 tcg_gen_qemu_ld32u(tmp
, addr
, index
);
893 static inline TCGv_i64
gen_ld64(TCGv addr
, int index
)
895 TCGv_i64 tmp
= tcg_temp_new_i64();
896 tcg_gen_qemu_ld64(tmp
, addr
, index
);
899 static inline void gen_st8(TCGv val
, TCGv addr
, int index
)
901 tcg_gen_qemu_st8(val
, addr
, index
);
902 tcg_temp_free_i32(val
);
904 static inline void gen_st16(TCGv val
, TCGv addr
, int index
)
906 tcg_gen_qemu_st16(val
, addr
, index
);
907 tcg_temp_free_i32(val
);
909 static inline void gen_st32(TCGv val
, TCGv addr
, int index
)
911 tcg_gen_qemu_st32(val
, addr
, index
);
912 tcg_temp_free_i32(val
);
914 static inline void gen_st64(TCGv_i64 val
, TCGv addr
, int index
)
916 tcg_gen_qemu_st64(val
, addr
, index
);
917 tcg_temp_free_i64(val
);
920 static inline void gen_set_pc_im(uint32_t val
)
922 tcg_gen_movi_i32(cpu_R
[15], val
);
925 /* Force a TB lookup after an instruction that changes the CPU state. */
926 static inline void gen_lookup_tb(DisasContext
*s
)
928 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
929 s
->is_jmp
= DISAS_UPDATE
;
932 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
935 int val
, rm
, shift
, shiftop
;
938 if (!(insn
& (1 << 25))) {
941 if (!(insn
& (1 << 23)))
944 tcg_gen_addi_i32(var
, var
, val
);
948 shift
= (insn
>> 7) & 0x1f;
949 shiftop
= (insn
>> 5) & 3;
950 offset
= load_reg(s
, rm
);
951 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
952 if (!(insn
& (1 << 23)))
953 tcg_gen_sub_i32(var
, var
, offset
);
955 tcg_gen_add_i32(var
, var
, offset
);
956 tcg_temp_free_i32(offset
);
960 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
966 if (insn
& (1 << 22)) {
968 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
969 if (!(insn
& (1 << 23)))
973 tcg_gen_addi_i32(var
, var
, val
);
977 tcg_gen_addi_i32(var
, var
, extra
);
979 offset
= load_reg(s
, rm
);
980 if (!(insn
& (1 << 23)))
981 tcg_gen_sub_i32(var
, var
, offset
);
983 tcg_gen_add_i32(var
, var
, offset
);
984 tcg_temp_free_i32(offset
);
988 static TCGv_ptr
get_fpstatus_ptr(int neon
)
990 TCGv_ptr statusptr
= tcg_temp_new_ptr();
993 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
995 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
997 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1001 #define VFP_OP2(name) \
1002 static inline void gen_vfp_##name(int dp) \
1004 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1006 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1008 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1010 tcg_temp_free_ptr(fpst); \
1020 static inline void gen_vfp_F1_mul(int dp
)
1022 /* Like gen_vfp_mul() but put result in F1 */
1023 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1025 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1027 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1029 tcg_temp_free_ptr(fpst
);
1032 static inline void gen_vfp_F1_neg(int dp
)
1034 /* Like gen_vfp_neg() but put result in F1 */
1036 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1038 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1042 static inline void gen_vfp_abs(int dp
)
1045 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1047 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1050 static inline void gen_vfp_neg(int dp
)
1053 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1055 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1058 static inline void gen_vfp_sqrt(int dp
)
1061 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1063 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1066 static inline void gen_vfp_cmp(int dp
)
1069 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1071 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1074 static inline void gen_vfp_cmpe(int dp
)
1077 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1079 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1082 static inline void gen_vfp_F1_ld0(int dp
)
1085 tcg_gen_movi_i64(cpu_F1d
, 0);
1087 tcg_gen_movi_i32(cpu_F1s
, 0);
1090 #define VFP_GEN_ITOF(name) \
1091 static inline void gen_vfp_##name(int dp, int neon) \
1093 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1095 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1097 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1099 tcg_temp_free_ptr(statusptr); \
1106 #define VFP_GEN_FTOI(name) \
1107 static inline void gen_vfp_##name(int dp, int neon) \
1109 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1111 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1113 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1115 tcg_temp_free_ptr(statusptr); \
1124 #define VFP_GEN_FIX(name) \
1125 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1127 TCGv tmp_shift = tcg_const_i32(shift); \
1128 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1130 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1132 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1134 tcg_temp_free_i32(tmp_shift); \
1135 tcg_temp_free_ptr(statusptr); \
1147 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv addr
)
1150 tcg_gen_qemu_ld64(cpu_F0d
, addr
, IS_USER(s
));
1152 tcg_gen_qemu_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1155 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv addr
)
1158 tcg_gen_qemu_st64(cpu_F0d
, addr
, IS_USER(s
));
1160 tcg_gen_qemu_st32(cpu_F0s
, addr
, IS_USER(s
));
1164 vfp_reg_offset (int dp
, int reg
)
1167 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1169 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1170 + offsetof(CPU_DoubleU
, l
.upper
);
1172 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1173 + offsetof(CPU_DoubleU
, l
.lower
);
1177 /* Return the offset of a 32-bit piece of a NEON register.
1178 zero is the least significant end of the register. */
1180 neon_reg_offset (int reg
, int n
)
1184 return vfp_reg_offset(0, sreg
);
1187 static TCGv
neon_load_reg(int reg
, int pass
)
1189 TCGv tmp
= tcg_temp_new_i32();
1190 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1194 static void neon_store_reg(int reg
, int pass
, TCGv var
)
1196 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1197 tcg_temp_free_i32(var
);
1200 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1202 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1205 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1207 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1210 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1211 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1212 #define tcg_gen_st_f32 tcg_gen_st_i32
1213 #define tcg_gen_st_f64 tcg_gen_st_i64
1215 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1218 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1220 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1223 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1226 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1228 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1231 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1234 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1236 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1239 #define ARM_CP_RW_BIT (1 << 20)
1241 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1243 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1246 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1248 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1251 static inline TCGv
iwmmxt_load_creg(int reg
)
1253 TCGv var
= tcg_temp_new_i32();
1254 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1258 static inline void iwmmxt_store_creg(int reg
, TCGv var
)
1260 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1261 tcg_temp_free_i32(var
);
1264 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1266 iwmmxt_store_reg(cpu_M0
, rn
);
1269 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1271 iwmmxt_load_reg(cpu_M0
, rn
);
1274 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1276 iwmmxt_load_reg(cpu_V1
, rn
);
1277 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1280 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1282 iwmmxt_load_reg(cpu_V1
, rn
);
1283 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1286 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1288 iwmmxt_load_reg(cpu_V1
, rn
);
1289 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1292 #define IWMMXT_OP(name) \
1293 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1295 iwmmxt_load_reg(cpu_V1, rn); \
1296 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1299 #define IWMMXT_OP_ENV(name) \
1300 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1302 iwmmxt_load_reg(cpu_V1, rn); \
1303 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1306 #define IWMMXT_OP_ENV_SIZE(name) \
1307 IWMMXT_OP_ENV(name##b) \
1308 IWMMXT_OP_ENV(name##w) \
1309 IWMMXT_OP_ENV(name##l)
1311 #define IWMMXT_OP_ENV1(name) \
1312 static inline void gen_op_iwmmxt_##name##_M0(void) \
1314 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1328 IWMMXT_OP_ENV_SIZE(unpackl
)
1329 IWMMXT_OP_ENV_SIZE(unpackh
)
1331 IWMMXT_OP_ENV1(unpacklub
)
1332 IWMMXT_OP_ENV1(unpackluw
)
1333 IWMMXT_OP_ENV1(unpacklul
)
1334 IWMMXT_OP_ENV1(unpackhub
)
1335 IWMMXT_OP_ENV1(unpackhuw
)
1336 IWMMXT_OP_ENV1(unpackhul
)
1337 IWMMXT_OP_ENV1(unpacklsb
)
1338 IWMMXT_OP_ENV1(unpacklsw
)
1339 IWMMXT_OP_ENV1(unpacklsl
)
1340 IWMMXT_OP_ENV1(unpackhsb
)
1341 IWMMXT_OP_ENV1(unpackhsw
)
1342 IWMMXT_OP_ENV1(unpackhsl
)
1344 IWMMXT_OP_ENV_SIZE(cmpeq
)
1345 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1346 IWMMXT_OP_ENV_SIZE(cmpgts
)
1348 IWMMXT_OP_ENV_SIZE(mins
)
1349 IWMMXT_OP_ENV_SIZE(minu
)
1350 IWMMXT_OP_ENV_SIZE(maxs
)
1351 IWMMXT_OP_ENV_SIZE(maxu
)
1353 IWMMXT_OP_ENV_SIZE(subn
)
1354 IWMMXT_OP_ENV_SIZE(addn
)
1355 IWMMXT_OP_ENV_SIZE(subu
)
1356 IWMMXT_OP_ENV_SIZE(addu
)
1357 IWMMXT_OP_ENV_SIZE(subs
)
1358 IWMMXT_OP_ENV_SIZE(adds
)
1360 IWMMXT_OP_ENV(avgb0
)
1361 IWMMXT_OP_ENV(avgb1
)
1362 IWMMXT_OP_ENV(avgw0
)
1363 IWMMXT_OP_ENV(avgw1
)
1367 IWMMXT_OP_ENV(packuw
)
1368 IWMMXT_OP_ENV(packul
)
1369 IWMMXT_OP_ENV(packuq
)
1370 IWMMXT_OP_ENV(packsw
)
1371 IWMMXT_OP_ENV(packsl
)
1372 IWMMXT_OP_ENV(packsq
)
1374 static void gen_op_iwmmxt_set_mup(void)
1377 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1378 tcg_gen_ori_i32(tmp
, tmp
, 2);
1379 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1382 static void gen_op_iwmmxt_set_cup(void)
1385 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1386 tcg_gen_ori_i32(tmp
, tmp
, 1);
1387 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1390 static void gen_op_iwmmxt_setpsr_nz(void)
1392 TCGv tmp
= tcg_temp_new_i32();
1393 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1394 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1397 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1399 iwmmxt_load_reg(cpu_V1
, rn
);
1400 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1401 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1404 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
, TCGv dest
)
1410 rd
= (insn
>> 16) & 0xf;
1411 tmp
= load_reg(s
, rd
);
1413 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1414 if (insn
& (1 << 24)) {
1416 if (insn
& (1 << 23))
1417 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1419 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1420 tcg_gen_mov_i32(dest
, tmp
);
1421 if (insn
& (1 << 21))
1422 store_reg(s
, rd
, tmp
);
1424 tcg_temp_free_i32(tmp
);
1425 } else if (insn
& (1 << 21)) {
1427 tcg_gen_mov_i32(dest
, tmp
);
1428 if (insn
& (1 << 23))
1429 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1431 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1432 store_reg(s
, rd
, tmp
);
1433 } else if (!(insn
& (1 << 23)))
1438 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv dest
)
1440 int rd
= (insn
>> 0) & 0xf;
1443 if (insn
& (1 << 8)) {
1444 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1447 tmp
= iwmmxt_load_creg(rd
);
1450 tmp
= tcg_temp_new_i32();
1451 iwmmxt_load_reg(cpu_V0
, rd
);
1452 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1454 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1455 tcg_gen_mov_i32(dest
, tmp
);
1456 tcg_temp_free_i32(tmp
);
1460 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1461 (ie. an undefined instruction). */
1462 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1465 int rdhi
, rdlo
, rd0
, rd1
, i
;
1467 TCGv tmp
, tmp2
, tmp3
;
1469 if ((insn
& 0x0e000e00) == 0x0c000000) {
1470 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1472 rdlo
= (insn
>> 12) & 0xf;
1473 rdhi
= (insn
>> 16) & 0xf;
1474 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1475 iwmmxt_load_reg(cpu_V0
, wrd
);
1476 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1477 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1478 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1479 } else { /* TMCRR */
1480 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1481 iwmmxt_store_reg(cpu_V0
, wrd
);
1482 gen_op_iwmmxt_set_mup();
1487 wrd
= (insn
>> 12) & 0xf;
1488 addr
= tcg_temp_new_i32();
1489 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1490 tcg_temp_free_i32(addr
);
1493 if (insn
& ARM_CP_RW_BIT
) {
1494 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1495 tmp
= tcg_temp_new_i32();
1496 tcg_gen_qemu_ld32u(tmp
, addr
, IS_USER(s
));
1497 iwmmxt_store_creg(wrd
, tmp
);
1500 if (insn
& (1 << 8)) {
1501 if (insn
& (1 << 22)) { /* WLDRD */
1502 tcg_gen_qemu_ld64(cpu_M0
, addr
, IS_USER(s
));
1504 } else { /* WLDRW wRd */
1505 tmp
= gen_ld32(addr
, IS_USER(s
));
1508 if (insn
& (1 << 22)) { /* WLDRH */
1509 tmp
= gen_ld16u(addr
, IS_USER(s
));
1510 } else { /* WLDRB */
1511 tmp
= gen_ld8u(addr
, IS_USER(s
));
1515 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1516 tcg_temp_free_i32(tmp
);
1518 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1521 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1522 tmp
= iwmmxt_load_creg(wrd
);
1523 gen_st32(tmp
, addr
, IS_USER(s
));
1525 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1526 tmp
= tcg_temp_new_i32();
1527 if (insn
& (1 << 8)) {
1528 if (insn
& (1 << 22)) { /* WSTRD */
1529 tcg_temp_free_i32(tmp
);
1530 tcg_gen_qemu_st64(cpu_M0
, addr
, IS_USER(s
));
1531 } else { /* WSTRW wRd */
1532 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1533 gen_st32(tmp
, addr
, IS_USER(s
));
1536 if (insn
& (1 << 22)) { /* WSTRH */
1537 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1538 gen_st16(tmp
, addr
, IS_USER(s
));
1539 } else { /* WSTRB */
1540 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1541 gen_st8(tmp
, addr
, IS_USER(s
));
1546 tcg_temp_free_i32(addr
);
1550 if ((insn
& 0x0f000000) != 0x0e000000)
1553 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1554 case 0x000: /* WOR */
1555 wrd
= (insn
>> 12) & 0xf;
1556 rd0
= (insn
>> 0) & 0xf;
1557 rd1
= (insn
>> 16) & 0xf;
1558 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1559 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1560 gen_op_iwmmxt_setpsr_nz();
1561 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1562 gen_op_iwmmxt_set_mup();
1563 gen_op_iwmmxt_set_cup();
1565 case 0x011: /* TMCR */
1568 rd
= (insn
>> 12) & 0xf;
1569 wrd
= (insn
>> 16) & 0xf;
1571 case ARM_IWMMXT_wCID
:
1572 case ARM_IWMMXT_wCASF
:
1574 case ARM_IWMMXT_wCon
:
1575 gen_op_iwmmxt_set_cup();
1577 case ARM_IWMMXT_wCSSF
:
1578 tmp
= iwmmxt_load_creg(wrd
);
1579 tmp2
= load_reg(s
, rd
);
1580 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1581 tcg_temp_free_i32(tmp2
);
1582 iwmmxt_store_creg(wrd
, tmp
);
1584 case ARM_IWMMXT_wCGR0
:
1585 case ARM_IWMMXT_wCGR1
:
1586 case ARM_IWMMXT_wCGR2
:
1587 case ARM_IWMMXT_wCGR3
:
1588 gen_op_iwmmxt_set_cup();
1589 tmp
= load_reg(s
, rd
);
1590 iwmmxt_store_creg(wrd
, tmp
);
1596 case 0x100: /* WXOR */
1597 wrd
= (insn
>> 12) & 0xf;
1598 rd0
= (insn
>> 0) & 0xf;
1599 rd1
= (insn
>> 16) & 0xf;
1600 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1601 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1602 gen_op_iwmmxt_setpsr_nz();
1603 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1604 gen_op_iwmmxt_set_mup();
1605 gen_op_iwmmxt_set_cup();
1607 case 0x111: /* TMRC */
1610 rd
= (insn
>> 12) & 0xf;
1611 wrd
= (insn
>> 16) & 0xf;
1612 tmp
= iwmmxt_load_creg(wrd
);
1613 store_reg(s
, rd
, tmp
);
1615 case 0x300: /* WANDN */
1616 wrd
= (insn
>> 12) & 0xf;
1617 rd0
= (insn
>> 0) & 0xf;
1618 rd1
= (insn
>> 16) & 0xf;
1619 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1620 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1621 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1622 gen_op_iwmmxt_setpsr_nz();
1623 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1624 gen_op_iwmmxt_set_mup();
1625 gen_op_iwmmxt_set_cup();
1627 case 0x200: /* WAND */
1628 wrd
= (insn
>> 12) & 0xf;
1629 rd0
= (insn
>> 0) & 0xf;
1630 rd1
= (insn
>> 16) & 0xf;
1631 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1632 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1633 gen_op_iwmmxt_setpsr_nz();
1634 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1635 gen_op_iwmmxt_set_mup();
1636 gen_op_iwmmxt_set_cup();
1638 case 0x810: case 0xa10: /* WMADD */
1639 wrd
= (insn
>> 12) & 0xf;
1640 rd0
= (insn
>> 0) & 0xf;
1641 rd1
= (insn
>> 16) & 0xf;
1642 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1643 if (insn
& (1 << 21))
1644 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1646 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1647 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1648 gen_op_iwmmxt_set_mup();
1650 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1651 wrd
= (insn
>> 12) & 0xf;
1652 rd0
= (insn
>> 16) & 0xf;
1653 rd1
= (insn
>> 0) & 0xf;
1654 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1655 switch ((insn
>> 22) & 3) {
1657 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1660 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1663 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1668 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1669 gen_op_iwmmxt_set_mup();
1670 gen_op_iwmmxt_set_cup();
1672 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1673 wrd
= (insn
>> 12) & 0xf;
1674 rd0
= (insn
>> 16) & 0xf;
1675 rd1
= (insn
>> 0) & 0xf;
1676 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1677 switch ((insn
>> 22) & 3) {
1679 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1682 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1685 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1690 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1691 gen_op_iwmmxt_set_mup();
1692 gen_op_iwmmxt_set_cup();
1694 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1695 wrd
= (insn
>> 12) & 0xf;
1696 rd0
= (insn
>> 16) & 0xf;
1697 rd1
= (insn
>> 0) & 0xf;
1698 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1699 if (insn
& (1 << 22))
1700 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1702 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1703 if (!(insn
& (1 << 20)))
1704 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1705 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1706 gen_op_iwmmxt_set_mup();
1708 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1709 wrd
= (insn
>> 12) & 0xf;
1710 rd0
= (insn
>> 16) & 0xf;
1711 rd1
= (insn
>> 0) & 0xf;
1712 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1713 if (insn
& (1 << 21)) {
1714 if (insn
& (1 << 20))
1715 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1717 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1719 if (insn
& (1 << 20))
1720 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1722 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1724 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1725 gen_op_iwmmxt_set_mup();
1727 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1728 wrd
= (insn
>> 12) & 0xf;
1729 rd0
= (insn
>> 16) & 0xf;
1730 rd1
= (insn
>> 0) & 0xf;
1731 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1732 if (insn
& (1 << 21))
1733 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1735 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1736 if (!(insn
& (1 << 20))) {
1737 iwmmxt_load_reg(cpu_V1
, wrd
);
1738 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1740 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1741 gen_op_iwmmxt_set_mup();
1743 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1744 wrd
= (insn
>> 12) & 0xf;
1745 rd0
= (insn
>> 16) & 0xf;
1746 rd1
= (insn
>> 0) & 0xf;
1747 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1748 switch ((insn
>> 22) & 3) {
1750 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1753 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1756 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1761 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1762 gen_op_iwmmxt_set_mup();
1763 gen_op_iwmmxt_set_cup();
1765 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1766 wrd
= (insn
>> 12) & 0xf;
1767 rd0
= (insn
>> 16) & 0xf;
1768 rd1
= (insn
>> 0) & 0xf;
1769 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1770 if (insn
& (1 << 22)) {
1771 if (insn
& (1 << 20))
1772 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1774 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1776 if (insn
& (1 << 20))
1777 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1779 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1781 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1782 gen_op_iwmmxt_set_mup();
1783 gen_op_iwmmxt_set_cup();
1785 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1786 wrd
= (insn
>> 12) & 0xf;
1787 rd0
= (insn
>> 16) & 0xf;
1788 rd1
= (insn
>> 0) & 0xf;
1789 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1790 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1791 tcg_gen_andi_i32(tmp
, tmp
, 7);
1792 iwmmxt_load_reg(cpu_V1
, rd1
);
1793 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1794 tcg_temp_free_i32(tmp
);
1795 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1796 gen_op_iwmmxt_set_mup();
1798 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1799 if (((insn
>> 6) & 3) == 3)
1801 rd
= (insn
>> 12) & 0xf;
1802 wrd
= (insn
>> 16) & 0xf;
1803 tmp
= load_reg(s
, rd
);
1804 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1805 switch ((insn
>> 6) & 3) {
1807 tmp2
= tcg_const_i32(0xff);
1808 tmp3
= tcg_const_i32((insn
& 7) << 3);
1811 tmp2
= tcg_const_i32(0xffff);
1812 tmp3
= tcg_const_i32((insn
& 3) << 4);
1815 tmp2
= tcg_const_i32(0xffffffff);
1816 tmp3
= tcg_const_i32((insn
& 1) << 5);
1822 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1823 tcg_temp_free(tmp3
);
1824 tcg_temp_free(tmp2
);
1825 tcg_temp_free_i32(tmp
);
1826 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1827 gen_op_iwmmxt_set_mup();
1829 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1830 rd
= (insn
>> 12) & 0xf;
1831 wrd
= (insn
>> 16) & 0xf;
1832 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1834 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1835 tmp
= tcg_temp_new_i32();
1836 switch ((insn
>> 22) & 3) {
1838 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1839 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1841 tcg_gen_ext8s_i32(tmp
, tmp
);
1843 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1847 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1848 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1850 tcg_gen_ext16s_i32(tmp
, tmp
);
1852 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1856 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1857 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1860 store_reg(s
, rd
, tmp
);
1862 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1863 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1865 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1866 switch ((insn
>> 22) & 3) {
1868 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1871 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1874 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1877 tcg_gen_shli_i32(tmp
, tmp
, 28);
1879 tcg_temp_free_i32(tmp
);
1881 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1882 if (((insn
>> 6) & 3) == 3)
1884 rd
= (insn
>> 12) & 0xf;
1885 wrd
= (insn
>> 16) & 0xf;
1886 tmp
= load_reg(s
, rd
);
1887 switch ((insn
>> 6) & 3) {
1889 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1892 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1895 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1898 tcg_temp_free_i32(tmp
);
1899 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1900 gen_op_iwmmxt_set_mup();
1902 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1903 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1905 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1906 tmp2
= tcg_temp_new_i32();
1907 tcg_gen_mov_i32(tmp2
, tmp
);
1908 switch ((insn
>> 22) & 3) {
1910 for (i
= 0; i
< 7; i
++) {
1911 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1912 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1916 for (i
= 0; i
< 3; i
++) {
1917 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1918 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1922 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1923 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1927 tcg_temp_free_i32(tmp2
);
1928 tcg_temp_free_i32(tmp
);
1930 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1931 wrd
= (insn
>> 12) & 0xf;
1932 rd0
= (insn
>> 16) & 0xf;
1933 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1934 switch ((insn
>> 22) & 3) {
1936 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1939 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1942 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1947 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1948 gen_op_iwmmxt_set_mup();
1950 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1951 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1953 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1954 tmp2
= tcg_temp_new_i32();
1955 tcg_gen_mov_i32(tmp2
, tmp
);
1956 switch ((insn
>> 22) & 3) {
1958 for (i
= 0; i
< 7; i
++) {
1959 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1960 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1964 for (i
= 0; i
< 3; i
++) {
1965 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1966 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1970 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1971 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1975 tcg_temp_free_i32(tmp2
);
1976 tcg_temp_free_i32(tmp
);
1978 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1979 rd
= (insn
>> 12) & 0xf;
1980 rd0
= (insn
>> 16) & 0xf;
1981 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1983 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1984 tmp
= tcg_temp_new_i32();
1985 switch ((insn
>> 22) & 3) {
1987 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1990 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1993 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1996 store_reg(s
, rd
, tmp
);
1998 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1999 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2000 wrd
= (insn
>> 12) & 0xf;
2001 rd0
= (insn
>> 16) & 0xf;
2002 rd1
= (insn
>> 0) & 0xf;
2003 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2004 switch ((insn
>> 22) & 3) {
2006 if (insn
& (1 << 21))
2007 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2009 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2012 if (insn
& (1 << 21))
2013 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2015 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2018 if (insn
& (1 << 21))
2019 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2021 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2026 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2027 gen_op_iwmmxt_set_mup();
2028 gen_op_iwmmxt_set_cup();
2030 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2031 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2032 wrd
= (insn
>> 12) & 0xf;
2033 rd0
= (insn
>> 16) & 0xf;
2034 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2035 switch ((insn
>> 22) & 3) {
2037 if (insn
& (1 << 21))
2038 gen_op_iwmmxt_unpacklsb_M0();
2040 gen_op_iwmmxt_unpacklub_M0();
2043 if (insn
& (1 << 21))
2044 gen_op_iwmmxt_unpacklsw_M0();
2046 gen_op_iwmmxt_unpackluw_M0();
2049 if (insn
& (1 << 21))
2050 gen_op_iwmmxt_unpacklsl_M0();
2052 gen_op_iwmmxt_unpacklul_M0();
2057 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2058 gen_op_iwmmxt_set_mup();
2059 gen_op_iwmmxt_set_cup();
2061 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2062 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2063 wrd
= (insn
>> 12) & 0xf;
2064 rd0
= (insn
>> 16) & 0xf;
2065 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2066 switch ((insn
>> 22) & 3) {
2068 if (insn
& (1 << 21))
2069 gen_op_iwmmxt_unpackhsb_M0();
2071 gen_op_iwmmxt_unpackhub_M0();
2074 if (insn
& (1 << 21))
2075 gen_op_iwmmxt_unpackhsw_M0();
2077 gen_op_iwmmxt_unpackhuw_M0();
2080 if (insn
& (1 << 21))
2081 gen_op_iwmmxt_unpackhsl_M0();
2083 gen_op_iwmmxt_unpackhul_M0();
2088 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2089 gen_op_iwmmxt_set_mup();
2090 gen_op_iwmmxt_set_cup();
2092 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2093 case 0x214: case 0x614: case 0xa14: case 0xe14:
2094 if (((insn
>> 22) & 3) == 0)
2096 wrd
= (insn
>> 12) & 0xf;
2097 rd0
= (insn
>> 16) & 0xf;
2098 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2099 tmp
= tcg_temp_new_i32();
2100 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2101 tcg_temp_free_i32(tmp
);
2104 switch ((insn
>> 22) & 3) {
2106 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2109 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2112 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2115 tcg_temp_free_i32(tmp
);
2116 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2117 gen_op_iwmmxt_set_mup();
2118 gen_op_iwmmxt_set_cup();
2120 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2121 case 0x014: case 0x414: case 0x814: case 0xc14:
2122 if (((insn
>> 22) & 3) == 0)
2124 wrd
= (insn
>> 12) & 0xf;
2125 rd0
= (insn
>> 16) & 0xf;
2126 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2127 tmp
= tcg_temp_new_i32();
2128 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2129 tcg_temp_free_i32(tmp
);
2132 switch ((insn
>> 22) & 3) {
2134 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2137 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2140 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2143 tcg_temp_free_i32(tmp
);
2144 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2145 gen_op_iwmmxt_set_mup();
2146 gen_op_iwmmxt_set_cup();
2148 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2149 case 0x114: case 0x514: case 0x914: case 0xd14:
2150 if (((insn
>> 22) & 3) == 0)
2152 wrd
= (insn
>> 12) & 0xf;
2153 rd0
= (insn
>> 16) & 0xf;
2154 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2155 tmp
= tcg_temp_new_i32();
2156 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2157 tcg_temp_free_i32(tmp
);
2160 switch ((insn
>> 22) & 3) {
2162 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2165 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2168 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2171 tcg_temp_free_i32(tmp
);
2172 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2173 gen_op_iwmmxt_set_mup();
2174 gen_op_iwmmxt_set_cup();
2176 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2177 case 0x314: case 0x714: case 0xb14: case 0xf14:
2178 if (((insn
>> 22) & 3) == 0)
2180 wrd
= (insn
>> 12) & 0xf;
2181 rd0
= (insn
>> 16) & 0xf;
2182 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2183 tmp
= tcg_temp_new_i32();
2184 switch ((insn
>> 22) & 3) {
2186 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2187 tcg_temp_free_i32(tmp
);
2190 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2193 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2194 tcg_temp_free_i32(tmp
);
2197 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2200 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2201 tcg_temp_free_i32(tmp
);
2204 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2207 tcg_temp_free_i32(tmp
);
2208 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2209 gen_op_iwmmxt_set_mup();
2210 gen_op_iwmmxt_set_cup();
2212 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2213 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2214 wrd
= (insn
>> 12) & 0xf;
2215 rd0
= (insn
>> 16) & 0xf;
2216 rd1
= (insn
>> 0) & 0xf;
2217 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2218 switch ((insn
>> 22) & 3) {
2220 if (insn
& (1 << 21))
2221 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2223 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2226 if (insn
& (1 << 21))
2227 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2229 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2232 if (insn
& (1 << 21))
2233 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2235 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2240 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2241 gen_op_iwmmxt_set_mup();
2243 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2244 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2245 wrd
= (insn
>> 12) & 0xf;
2246 rd0
= (insn
>> 16) & 0xf;
2247 rd1
= (insn
>> 0) & 0xf;
2248 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2249 switch ((insn
>> 22) & 3) {
2251 if (insn
& (1 << 21))
2252 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2254 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2257 if (insn
& (1 << 21))
2258 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2260 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2263 if (insn
& (1 << 21))
2264 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2266 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2271 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2272 gen_op_iwmmxt_set_mup();
2274 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2275 case 0x402: case 0x502: case 0x602: case 0x702:
2276 wrd
= (insn
>> 12) & 0xf;
2277 rd0
= (insn
>> 16) & 0xf;
2278 rd1
= (insn
>> 0) & 0xf;
2279 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2280 tmp
= tcg_const_i32((insn
>> 20) & 3);
2281 iwmmxt_load_reg(cpu_V1
, rd1
);
2282 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2284 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2285 gen_op_iwmmxt_set_mup();
2287 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2288 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2289 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2290 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2291 wrd
= (insn
>> 12) & 0xf;
2292 rd0
= (insn
>> 16) & 0xf;
2293 rd1
= (insn
>> 0) & 0xf;
2294 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2295 switch ((insn
>> 20) & 0xf) {
2297 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2300 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2303 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2306 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2309 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2312 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2315 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2318 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2321 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2326 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2327 gen_op_iwmmxt_set_mup();
2328 gen_op_iwmmxt_set_cup();
2330 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2331 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2332 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2333 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2334 wrd
= (insn
>> 12) & 0xf;
2335 rd0
= (insn
>> 16) & 0xf;
2336 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2337 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2338 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2340 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2341 gen_op_iwmmxt_set_mup();
2342 gen_op_iwmmxt_set_cup();
2344 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2345 case 0x418: case 0x518: case 0x618: case 0x718:
2346 case 0x818: case 0x918: case 0xa18: case 0xb18:
2347 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2348 wrd
= (insn
>> 12) & 0xf;
2349 rd0
= (insn
>> 16) & 0xf;
2350 rd1
= (insn
>> 0) & 0xf;
2351 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2352 switch ((insn
>> 20) & 0xf) {
2354 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2357 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2360 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2363 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2366 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2369 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2372 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2375 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2378 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2383 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2384 gen_op_iwmmxt_set_mup();
2385 gen_op_iwmmxt_set_cup();
2387 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2388 case 0x408: case 0x508: case 0x608: case 0x708:
2389 case 0x808: case 0x908: case 0xa08: case 0xb08:
2390 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2391 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2393 wrd
= (insn
>> 12) & 0xf;
2394 rd0
= (insn
>> 16) & 0xf;
2395 rd1
= (insn
>> 0) & 0xf;
2396 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2397 switch ((insn
>> 22) & 3) {
2399 if (insn
& (1 << 21))
2400 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2402 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2405 if (insn
& (1 << 21))
2406 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2408 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2411 if (insn
& (1 << 21))
2412 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2414 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2417 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2418 gen_op_iwmmxt_set_mup();
2419 gen_op_iwmmxt_set_cup();
2421 case 0x201: case 0x203: case 0x205: case 0x207:
2422 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2423 case 0x211: case 0x213: case 0x215: case 0x217:
2424 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2425 wrd
= (insn
>> 5) & 0xf;
2426 rd0
= (insn
>> 12) & 0xf;
2427 rd1
= (insn
>> 0) & 0xf;
2428 if (rd0
== 0xf || rd1
== 0xf)
2430 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2431 tmp
= load_reg(s
, rd0
);
2432 tmp2
= load_reg(s
, rd1
);
2433 switch ((insn
>> 16) & 0xf) {
2434 case 0x0: /* TMIA */
2435 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2437 case 0x8: /* TMIAPH */
2438 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2440 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2441 if (insn
& (1 << 16))
2442 tcg_gen_shri_i32(tmp
, tmp
, 16);
2443 if (insn
& (1 << 17))
2444 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2445 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2448 tcg_temp_free_i32(tmp2
);
2449 tcg_temp_free_i32(tmp
);
2452 tcg_temp_free_i32(tmp2
);
2453 tcg_temp_free_i32(tmp
);
2454 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2455 gen_op_iwmmxt_set_mup();
2464 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2465 (ie. an undefined instruction). */
2466 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2468 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2471 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2472 /* Multiply with Internal Accumulate Format */
2473 rd0
= (insn
>> 12) & 0xf;
2475 acc
= (insn
>> 5) & 7;
2480 tmp
= load_reg(s
, rd0
);
2481 tmp2
= load_reg(s
, rd1
);
2482 switch ((insn
>> 16) & 0xf) {
2484 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2486 case 0x8: /* MIAPH */
2487 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2489 case 0xc: /* MIABB */
2490 case 0xd: /* MIABT */
2491 case 0xe: /* MIATB */
2492 case 0xf: /* MIATT */
2493 if (insn
& (1 << 16))
2494 tcg_gen_shri_i32(tmp
, tmp
, 16);
2495 if (insn
& (1 << 17))
2496 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2497 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2502 tcg_temp_free_i32(tmp2
);
2503 tcg_temp_free_i32(tmp
);
2505 gen_op_iwmmxt_movq_wRn_M0(acc
);
2509 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2510 /* Internal Accumulator Access Format */
2511 rdhi
= (insn
>> 16) & 0xf;
2512 rdlo
= (insn
>> 12) & 0xf;
2518 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2519 iwmmxt_load_reg(cpu_V0
, acc
);
2520 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2521 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2522 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2523 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2525 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2526 iwmmxt_store_reg(cpu_V0
, acc
);
2534 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2535 #define VFP_SREG(insn, bigbit, smallbit) \
2536 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2537 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2538 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2539 reg = (((insn) >> (bigbit)) & 0x0f) \
2540 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2542 if (insn & (1 << (smallbit))) \
2544 reg = ((insn) >> (bigbit)) & 0x0f; \
2547 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2548 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2549 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2550 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2551 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2552 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2554 /* Move between integer and VFP cores. */
2555 static TCGv
gen_vfp_mrs(void)
2557 TCGv tmp
= tcg_temp_new_i32();
2558 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2562 static void gen_vfp_msr(TCGv tmp
)
2564 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2565 tcg_temp_free_i32(tmp
);
2568 static void gen_neon_dup_u8(TCGv var
, int shift
)
2570 TCGv tmp
= tcg_temp_new_i32();
2572 tcg_gen_shri_i32(var
, var
, shift
);
2573 tcg_gen_ext8u_i32(var
, var
);
2574 tcg_gen_shli_i32(tmp
, var
, 8);
2575 tcg_gen_or_i32(var
, var
, tmp
);
2576 tcg_gen_shli_i32(tmp
, var
, 16);
2577 tcg_gen_or_i32(var
, var
, tmp
);
2578 tcg_temp_free_i32(tmp
);
2581 static void gen_neon_dup_low16(TCGv var
)
2583 TCGv tmp
= tcg_temp_new_i32();
2584 tcg_gen_ext16u_i32(var
, var
);
2585 tcg_gen_shli_i32(tmp
, var
, 16);
2586 tcg_gen_or_i32(var
, var
, tmp
);
2587 tcg_temp_free_i32(tmp
);
2590 static void gen_neon_dup_high16(TCGv var
)
2592 TCGv tmp
= tcg_temp_new_i32();
2593 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2594 tcg_gen_shri_i32(tmp
, var
, 16);
2595 tcg_gen_or_i32(var
, var
, tmp
);
2596 tcg_temp_free_i32(tmp
);
2599 static TCGv
gen_load_and_replicate(DisasContext
*s
, TCGv addr
, int size
)
2601 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2605 tmp
= gen_ld8u(addr
, IS_USER(s
));
2606 gen_neon_dup_u8(tmp
, 0);
2609 tmp
= gen_ld16u(addr
, IS_USER(s
));
2610 gen_neon_dup_low16(tmp
);
2613 tmp
= gen_ld32(addr
, IS_USER(s
));
2615 default: /* Avoid compiler warnings. */
2621 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2622 (ie. an undefined instruction). */
2623 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2625 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2631 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2634 if (!s
->vfp_enabled
) {
2635 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2636 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2638 rn
= (insn
>> 16) & 0xf;
2639 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2640 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2643 dp
= ((insn
& 0xf00) == 0xb00);
2644 switch ((insn
>> 24) & 0xf) {
2646 if (insn
& (1 << 4)) {
2647 /* single register transfer */
2648 rd
= (insn
>> 12) & 0xf;
2653 VFP_DREG_N(rn
, insn
);
2656 if (insn
& 0x00c00060
2657 && !arm_feature(env
, ARM_FEATURE_NEON
))
2660 pass
= (insn
>> 21) & 1;
2661 if (insn
& (1 << 22)) {
2663 offset
= ((insn
>> 5) & 3) * 8;
2664 } else if (insn
& (1 << 5)) {
2666 offset
= (insn
& (1 << 6)) ? 16 : 0;
2671 if (insn
& ARM_CP_RW_BIT
) {
2673 tmp
= neon_load_reg(rn
, pass
);
2677 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2678 if (insn
& (1 << 23))
2684 if (insn
& (1 << 23)) {
2686 tcg_gen_shri_i32(tmp
, tmp
, 16);
2692 tcg_gen_sari_i32(tmp
, tmp
, 16);
2701 store_reg(s
, rd
, tmp
);
2704 tmp
= load_reg(s
, rd
);
2705 if (insn
& (1 << 23)) {
2708 gen_neon_dup_u8(tmp
, 0);
2709 } else if (size
== 1) {
2710 gen_neon_dup_low16(tmp
);
2712 for (n
= 0; n
<= pass
* 2; n
++) {
2713 tmp2
= tcg_temp_new_i32();
2714 tcg_gen_mov_i32(tmp2
, tmp
);
2715 neon_store_reg(rn
, n
, tmp2
);
2717 neon_store_reg(rn
, n
, tmp
);
2722 tmp2
= neon_load_reg(rn
, pass
);
2723 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
2724 tcg_temp_free_i32(tmp2
);
2727 tmp2
= neon_load_reg(rn
, pass
);
2728 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
2729 tcg_temp_free_i32(tmp2
);
2734 neon_store_reg(rn
, pass
, tmp
);
2738 if ((insn
& 0x6f) != 0x00)
2740 rn
= VFP_SREG_N(insn
);
2741 if (insn
& ARM_CP_RW_BIT
) {
2743 if (insn
& (1 << 21)) {
2744 /* system register */
2749 /* VFP2 allows access to FSID from userspace.
2750 VFP3 restricts all id registers to privileged
2753 && arm_feature(env
, ARM_FEATURE_VFP3
))
2755 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2760 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2762 case ARM_VFP_FPINST
:
2763 case ARM_VFP_FPINST2
:
2764 /* Not present in VFP3. */
2766 || arm_feature(env
, ARM_FEATURE_VFP3
))
2768 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2772 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
2773 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
2775 tmp
= tcg_temp_new_i32();
2776 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
2782 || !arm_feature(env
, ARM_FEATURE_MVFR
))
2784 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
2790 gen_mov_F0_vreg(0, rn
);
2791 tmp
= gen_vfp_mrs();
2794 /* Set the 4 flag bits in the CPSR. */
2796 tcg_temp_free_i32(tmp
);
2798 store_reg(s
, rd
, tmp
);
2802 if (insn
& (1 << 21)) {
2804 /* system register */
2809 /* Writes are ignored. */
2812 tmp
= load_reg(s
, rd
);
2813 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
2814 tcg_temp_free_i32(tmp
);
2820 /* TODO: VFP subarchitecture support.
2821 * For now, keep the EN bit only */
2822 tmp
= load_reg(s
, rd
);
2823 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
2824 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2827 case ARM_VFP_FPINST
:
2828 case ARM_VFP_FPINST2
:
2829 tmp
= load_reg(s
, rd
);
2830 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
2836 tmp
= load_reg(s
, rd
);
2838 gen_mov_vreg_F0(0, rn
);
2843 /* data processing */
2844 /* The opcode is in bits 23, 21, 20 and 6. */
2845 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
2849 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
2851 /* rn is register number */
2852 VFP_DREG_N(rn
, insn
);
2855 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
2856 /* Integer or single precision destination. */
2857 rd
= VFP_SREG_D(insn
);
2859 VFP_DREG_D(rd
, insn
);
2862 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
2863 /* VCVT from int is always from S reg regardless of dp bit.
2864 * VCVT with immediate frac_bits has same format as SREG_M
2866 rm
= VFP_SREG_M(insn
);
2868 VFP_DREG_M(rm
, insn
);
2871 rn
= VFP_SREG_N(insn
);
2872 if (op
== 15 && rn
== 15) {
2873 /* Double precision destination. */
2874 VFP_DREG_D(rd
, insn
);
2876 rd
= VFP_SREG_D(insn
);
2878 /* NB that we implicitly rely on the encoding for the frac_bits
2879 * in VCVT of fixed to float being the same as that of an SREG_M
2881 rm
= VFP_SREG_M(insn
);
2884 veclen
= s
->vec_len
;
2885 if (op
== 15 && rn
> 3)
2888 /* Shut up compiler warnings. */
2899 /* Figure out what type of vector operation this is. */
2900 if ((rd
& bank_mask
) == 0) {
2905 delta_d
= (s
->vec_stride
>> 1) + 1;
2907 delta_d
= s
->vec_stride
+ 1;
2909 if ((rm
& bank_mask
) == 0) {
2910 /* mixed scalar/vector */
2919 /* Load the initial operands. */
2924 /* Integer source */
2925 gen_mov_F0_vreg(0, rm
);
2930 gen_mov_F0_vreg(dp
, rd
);
2931 gen_mov_F1_vreg(dp
, rm
);
2935 /* Compare with zero */
2936 gen_mov_F0_vreg(dp
, rd
);
2947 /* Source and destination the same. */
2948 gen_mov_F0_vreg(dp
, rd
);
2954 /* VCVTB, VCVTT: only present with the halfprec extension,
2955 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2957 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
2960 /* Otherwise fall through */
2962 /* One source operand. */
2963 gen_mov_F0_vreg(dp
, rm
);
2967 /* Two source operands. */
2968 gen_mov_F0_vreg(dp
, rn
);
2969 gen_mov_F1_vreg(dp
, rm
);
2973 /* Perform the calculation. */
2975 case 0: /* VMLA: fd + (fn * fm) */
2976 /* Note that order of inputs to the add matters for NaNs */
2978 gen_mov_F0_vreg(dp
, rd
);
2981 case 1: /* VMLS: fd + -(fn * fm) */
2984 gen_mov_F0_vreg(dp
, rd
);
2987 case 2: /* VNMLS: -fd + (fn * fm) */
2988 /* Note that it isn't valid to replace (-A + B) with (B - A)
2989 * or similar plausible looking simplifications
2990 * because this will give wrong results for NaNs.
2993 gen_mov_F0_vreg(dp
, rd
);
2997 case 3: /* VNMLA: -fd + -(fn * fm) */
3000 gen_mov_F0_vreg(dp
, rd
);
3004 case 4: /* mul: fn * fm */
3007 case 5: /* nmul: -(fn * fm) */
3011 case 6: /* add: fn + fm */
3014 case 7: /* sub: fn - fm */
3017 case 8: /* div: fn / fm */
3020 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3021 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3022 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3023 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3024 /* These are fused multiply-add, and must be done as one
3025 * floating point operation with no rounding between the
3026 * multiplication and addition steps.
3027 * NB that doing the negations here as separate steps is
3028 * correct : an input NaN should come out with its sign bit
3029 * flipped if it is a negated-input.
3031 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3039 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3041 frd
= tcg_temp_new_i64();
3042 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3045 gen_helper_vfp_negd(frd
, frd
);
3047 fpst
= get_fpstatus_ptr(0);
3048 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3049 cpu_F1d
, frd
, fpst
);
3050 tcg_temp_free_ptr(fpst
);
3051 tcg_temp_free_i64(frd
);
3057 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3059 frd
= tcg_temp_new_i32();
3060 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3062 gen_helper_vfp_negs(frd
, frd
);
3064 fpst
= get_fpstatus_ptr(0);
3065 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3066 cpu_F1s
, frd
, fpst
);
3067 tcg_temp_free_ptr(fpst
);
3068 tcg_temp_free_i32(frd
);
3071 case 14: /* fconst */
3072 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3075 n
= (insn
<< 12) & 0x80000000;
3076 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3083 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3090 tcg_gen_movi_i32(cpu_F0s
, n
);
3093 case 15: /* extension space */
3107 case 4: /* vcvtb.f32.f16 */
3108 tmp
= gen_vfp_mrs();
3109 tcg_gen_ext16u_i32(tmp
, tmp
);
3110 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3111 tcg_temp_free_i32(tmp
);
3113 case 5: /* vcvtt.f32.f16 */
3114 tmp
= gen_vfp_mrs();
3115 tcg_gen_shri_i32(tmp
, tmp
, 16);
3116 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3117 tcg_temp_free_i32(tmp
);
3119 case 6: /* vcvtb.f16.f32 */
3120 tmp
= tcg_temp_new_i32();
3121 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3122 gen_mov_F0_vreg(0, rd
);
3123 tmp2
= gen_vfp_mrs();
3124 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3125 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3126 tcg_temp_free_i32(tmp2
);
3129 case 7: /* vcvtt.f16.f32 */
3130 tmp
= tcg_temp_new_i32();
3131 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3132 tcg_gen_shli_i32(tmp
, tmp
, 16);
3133 gen_mov_F0_vreg(0, rd
);
3134 tmp2
= gen_vfp_mrs();
3135 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3136 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3137 tcg_temp_free_i32(tmp2
);
3149 case 11: /* cmpez */
3153 case 15: /* single<->double conversion */
3155 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3157 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3159 case 16: /* fuito */
3160 gen_vfp_uito(dp
, 0);
3162 case 17: /* fsito */
3163 gen_vfp_sito(dp
, 0);
3165 case 20: /* fshto */
3166 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3168 gen_vfp_shto(dp
, 16 - rm
, 0);
3170 case 21: /* fslto */
3171 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3173 gen_vfp_slto(dp
, 32 - rm
, 0);
3175 case 22: /* fuhto */
3176 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3178 gen_vfp_uhto(dp
, 16 - rm
, 0);
3180 case 23: /* fulto */
3181 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3183 gen_vfp_ulto(dp
, 32 - rm
, 0);
3185 case 24: /* ftoui */
3186 gen_vfp_toui(dp
, 0);
3188 case 25: /* ftouiz */
3189 gen_vfp_touiz(dp
, 0);
3191 case 26: /* ftosi */
3192 gen_vfp_tosi(dp
, 0);
3194 case 27: /* ftosiz */
3195 gen_vfp_tosiz(dp
, 0);
3197 case 28: /* ftosh */
3198 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3200 gen_vfp_tosh(dp
, 16 - rm
, 0);
3202 case 29: /* ftosl */
3203 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3205 gen_vfp_tosl(dp
, 32 - rm
, 0);
3207 case 30: /* ftouh */
3208 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3210 gen_vfp_touh(dp
, 16 - rm
, 0);
3212 case 31: /* ftoul */
3213 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3215 gen_vfp_toul(dp
, 32 - rm
, 0);
3217 default: /* undefined */
3221 default: /* undefined */
3225 /* Write back the result. */
3226 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3227 ; /* Comparison, do nothing. */
3228 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3229 /* VCVT double to int: always integer result. */
3230 gen_mov_vreg_F0(0, rd
);
3231 else if (op
== 15 && rn
== 15)
3233 gen_mov_vreg_F0(!dp
, rd
);
3235 gen_mov_vreg_F0(dp
, rd
);
3237 /* break out of the loop if we have finished */
3241 if (op
== 15 && delta_m
== 0) {
3242 /* single source one-many */
3244 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3246 gen_mov_vreg_F0(dp
, rd
);
3250 /* Setup the next operands. */
3252 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3256 /* One source operand. */
3257 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3259 gen_mov_F0_vreg(dp
, rm
);
3261 /* Two source operands. */
3262 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3264 gen_mov_F0_vreg(dp
, rn
);
3266 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3268 gen_mov_F1_vreg(dp
, rm
);
3276 if ((insn
& 0x03e00000) == 0x00400000) {
3277 /* two-register transfer */
3278 rn
= (insn
>> 16) & 0xf;
3279 rd
= (insn
>> 12) & 0xf;
3281 VFP_DREG_M(rm
, insn
);
3283 rm
= VFP_SREG_M(insn
);
3286 if (insn
& ARM_CP_RW_BIT
) {
3289 gen_mov_F0_vreg(0, rm
* 2);
3290 tmp
= gen_vfp_mrs();
3291 store_reg(s
, rd
, tmp
);
3292 gen_mov_F0_vreg(0, rm
* 2 + 1);
3293 tmp
= gen_vfp_mrs();
3294 store_reg(s
, rn
, tmp
);
3296 gen_mov_F0_vreg(0, rm
);
3297 tmp
= gen_vfp_mrs();
3298 store_reg(s
, rd
, tmp
);
3299 gen_mov_F0_vreg(0, rm
+ 1);
3300 tmp
= gen_vfp_mrs();
3301 store_reg(s
, rn
, tmp
);
3306 tmp
= load_reg(s
, rd
);
3308 gen_mov_vreg_F0(0, rm
* 2);
3309 tmp
= load_reg(s
, rn
);
3311 gen_mov_vreg_F0(0, rm
* 2 + 1);
3313 tmp
= load_reg(s
, rd
);
3315 gen_mov_vreg_F0(0, rm
);
3316 tmp
= load_reg(s
, rn
);
3318 gen_mov_vreg_F0(0, rm
+ 1);
3323 rn
= (insn
>> 16) & 0xf;
3325 VFP_DREG_D(rd
, insn
);
3327 rd
= VFP_SREG_D(insn
);
3328 if ((insn
& 0x01200000) == 0x01000000) {
3329 /* Single load/store */
3330 offset
= (insn
& 0xff) << 2;
3331 if ((insn
& (1 << 23)) == 0)
3333 if (s
->thumb
&& rn
== 15) {
3334 /* This is actually UNPREDICTABLE */
3335 addr
= tcg_temp_new_i32();
3336 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3338 addr
= load_reg(s
, rn
);
3340 tcg_gen_addi_i32(addr
, addr
, offset
);
3341 if (insn
& (1 << 20)) {
3342 gen_vfp_ld(s
, dp
, addr
);
3343 gen_mov_vreg_F0(dp
, rd
);
3345 gen_mov_F0_vreg(dp
, rd
);
3346 gen_vfp_st(s
, dp
, addr
);
3348 tcg_temp_free_i32(addr
);
3350 /* load/store multiple */
3351 int w
= insn
& (1 << 21);
3353 n
= (insn
>> 1) & 0x7f;
3357 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3358 /* P == U , W == 1 => UNDEF */
3361 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3362 /* UNPREDICTABLE cases for bad immediates: we choose to
3363 * UNDEF to avoid generating huge numbers of TCG ops
3367 if (rn
== 15 && w
) {
3368 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3372 if (s
->thumb
&& rn
== 15) {
3373 /* This is actually UNPREDICTABLE */
3374 addr
= tcg_temp_new_i32();
3375 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3377 addr
= load_reg(s
, rn
);
3379 if (insn
& (1 << 24)) /* pre-decrement */
3380 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3386 for (i
= 0; i
< n
; i
++) {
3387 if (insn
& ARM_CP_RW_BIT
) {
3389 gen_vfp_ld(s
, dp
, addr
);
3390 gen_mov_vreg_F0(dp
, rd
+ i
);
3393 gen_mov_F0_vreg(dp
, rd
+ i
);
3394 gen_vfp_st(s
, dp
, addr
);
3396 tcg_gen_addi_i32(addr
, addr
, offset
);
3400 if (insn
& (1 << 24))
3401 offset
= -offset
* n
;
3402 else if (dp
&& (insn
& 1))
3408 tcg_gen_addi_i32(addr
, addr
, offset
);
3409 store_reg(s
, rn
, addr
);
3411 tcg_temp_free_i32(addr
);
3417 /* Should never happen. */
3423 static inline void gen_goto_tb(DisasContext
*s
, int n
, uint32_t dest
)
3425 TranslationBlock
*tb
;
3428 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3430 gen_set_pc_im(dest
);
3431 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3433 gen_set_pc_im(dest
);
3438 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3440 if (unlikely(s
->singlestep_enabled
)) {
3441 /* An indirect jump so that we still trigger the debug exception. */
3446 gen_goto_tb(s
, 0, dest
);
3447 s
->is_jmp
= DISAS_TB_JUMP
;
3451 static inline void gen_mulxy(TCGv t0
, TCGv t1
, int x
, int y
)
3454 tcg_gen_sari_i32(t0
, t0
, 16);
3458 tcg_gen_sari_i32(t1
, t1
, 16);
3461 tcg_gen_mul_i32(t0
, t0
, t1
);
3464 /* Return the mask of PSR bits set by a MSR instruction. */
3465 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3469 if (flags
& (1 << 0))
3471 if (flags
& (1 << 1))
3473 if (flags
& (1 << 2))
3475 if (flags
& (1 << 3))
3478 /* Mask out undefined bits. */
3479 mask
&= ~CPSR_RESERVED
;
3480 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3482 if (!arm_feature(env
, ARM_FEATURE_V5
))
3483 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3484 if (!arm_feature(env
, ARM_FEATURE_V6
))
3485 mask
&= ~(CPSR_E
| CPSR_GE
);
3486 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3488 /* Mask out execution state bits. */
3491 /* Mask out privileged bits. */
3497 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3498 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv t0
)
3502 /* ??? This is also undefined in system mode. */
3506 tmp
= load_cpu_field(spsr
);
3507 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3508 tcg_gen_andi_i32(t0
, t0
, mask
);
3509 tcg_gen_or_i32(tmp
, tmp
, t0
);
3510 store_cpu_field(tmp
, spsr
);
3512 gen_set_cpsr(t0
, mask
);
3514 tcg_temp_free_i32(t0
);
3519 /* Returns nonzero if access to the PSR is not permitted. */
3520 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3523 tmp
= tcg_temp_new_i32();
3524 tcg_gen_movi_i32(tmp
, val
);
3525 return gen_set_psr(s
, mask
, spsr
, tmp
);
3528 /* Generate an old-style exception return. Marks pc as dead. */
3529 static void gen_exception_return(DisasContext
*s
, TCGv pc
)
3532 store_reg(s
, 15, pc
);
3533 tmp
= load_cpu_field(spsr
);
3534 gen_set_cpsr(tmp
, 0xffffffff);
3535 tcg_temp_free_i32(tmp
);
3536 s
->is_jmp
= DISAS_UPDATE
;
3539 /* Generate a v6 exception return. Marks both values as dead. */
3540 static void gen_rfe(DisasContext
*s
, TCGv pc
, TCGv cpsr
)
3542 gen_set_cpsr(cpsr
, 0xffffffff);
3543 tcg_temp_free_i32(cpsr
);
3544 store_reg(s
, 15, pc
);
3545 s
->is_jmp
= DISAS_UPDATE
;
3549 gen_set_condexec (DisasContext
*s
)
3551 if (s
->condexec_mask
) {
3552 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3553 TCGv tmp
= tcg_temp_new_i32();
3554 tcg_gen_movi_i32(tmp
, val
);
3555 store_cpu_field(tmp
, condexec_bits
);
3559 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3561 gen_set_condexec(s
);
3562 gen_set_pc_im(s
->pc
- offset
);
3563 gen_exception(excp
);
3564 s
->is_jmp
= DISAS_JUMP
;
3567 static void gen_nop_hint(DisasContext
*s
, int val
)
3571 gen_set_pc_im(s
->pc
);
3572 s
->is_jmp
= DISAS_WFI
;
3576 /* TODO: Implement SEV and WFE. May help SMP performance. */
3582 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3584 static inline void gen_neon_add(int size
, TCGv t0
, TCGv t1
)
3587 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3588 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3589 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3594 static inline void gen_neon_rsb(int size
, TCGv t0
, TCGv t1
)
3597 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3598 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3599 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3604 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3605 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3606 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3607 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3608 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3610 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3611 switch ((size << 1) | u) { \
3613 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3616 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3619 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3622 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3625 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3628 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3630 default: return 1; \
3633 #define GEN_NEON_INTEGER_OP(name) do { \
3634 switch ((size << 1) | u) { \
3636 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3639 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3642 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3645 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3648 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3651 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3653 default: return 1; \
3656 static TCGv
neon_load_scratch(int scratch
)
3658 TCGv tmp
= tcg_temp_new_i32();
3659 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3663 static void neon_store_scratch(int scratch
, TCGv var
)
3665 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3666 tcg_temp_free_i32(var
);
3669 static inline TCGv
neon_get_scalar(int size
, int reg
)
3673 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3675 gen_neon_dup_high16(tmp
);
3677 gen_neon_dup_low16(tmp
);
3680 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3685 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3688 if (!q
&& size
== 2) {
3691 tmp
= tcg_const_i32(rd
);
3692 tmp2
= tcg_const_i32(rm
);
3696 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
3699 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
3702 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
3710 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
3713 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
3719 tcg_temp_free_i32(tmp
);
3720 tcg_temp_free_i32(tmp2
);
3724 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3727 if (!q
&& size
== 2) {
3730 tmp
= tcg_const_i32(rd
);
3731 tmp2
= tcg_const_i32(rm
);
3735 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
3738 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
3741 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
3749 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
3752 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
3758 tcg_temp_free_i32(tmp
);
3759 tcg_temp_free_i32(tmp2
);
3763 static void gen_neon_trn_u8(TCGv t0
, TCGv t1
)
3767 rd
= tcg_temp_new_i32();
3768 tmp
= tcg_temp_new_i32();
3770 tcg_gen_shli_i32(rd
, t0
, 8);
3771 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3772 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3773 tcg_gen_or_i32(rd
, rd
, tmp
);
3775 tcg_gen_shri_i32(t1
, t1
, 8);
3776 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3777 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3778 tcg_gen_or_i32(t1
, t1
, tmp
);
3779 tcg_gen_mov_i32(t0
, rd
);
3781 tcg_temp_free_i32(tmp
);
3782 tcg_temp_free_i32(rd
);
3785 static void gen_neon_trn_u16(TCGv t0
, TCGv t1
)
3789 rd
= tcg_temp_new_i32();
3790 tmp
= tcg_temp_new_i32();
3792 tcg_gen_shli_i32(rd
, t0
, 16);
3793 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3794 tcg_gen_or_i32(rd
, rd
, tmp
);
3795 tcg_gen_shri_i32(t1
, t1
, 16);
3796 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3797 tcg_gen_or_i32(t1
, t1
, tmp
);
3798 tcg_gen_mov_i32(t0
, rd
);
3800 tcg_temp_free_i32(tmp
);
3801 tcg_temp_free_i32(rd
);
3809 } neon_ls_element_type
[11] = {
3823 /* Translate a NEON load/store element instruction. Return nonzero if the
3824 instruction is invalid. */
3825 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
3844 if (!s
->vfp_enabled
)
3846 VFP_DREG_D(rd
, insn
);
3847 rn
= (insn
>> 16) & 0xf;
3849 load
= (insn
& (1 << 21)) != 0;
3850 if ((insn
& (1 << 23)) == 0) {
3851 /* Load store all elements. */
3852 op
= (insn
>> 8) & 0xf;
3853 size
= (insn
>> 6) & 3;
3856 /* Catch UNDEF cases for bad values of align field */
3859 if (((insn
>> 5) & 1) == 1) {
3864 if (((insn
>> 4) & 3) == 3) {
3871 nregs
= neon_ls_element_type
[op
].nregs
;
3872 interleave
= neon_ls_element_type
[op
].interleave
;
3873 spacing
= neon_ls_element_type
[op
].spacing
;
3874 if (size
== 3 && (interleave
| spacing
) != 1)
3876 addr
= tcg_temp_new_i32();
3877 load_reg_var(s
, addr
, rn
);
3878 stride
= (1 << size
) * interleave
;
3879 for (reg
= 0; reg
< nregs
; reg
++) {
3880 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
3881 load_reg_var(s
, addr
, rn
);
3882 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
3883 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
3884 load_reg_var(s
, addr
, rn
);
3885 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3889 tmp64
= gen_ld64(addr
, IS_USER(s
));
3890 neon_store_reg64(tmp64
, rd
);
3891 tcg_temp_free_i64(tmp64
);
3893 tmp64
= tcg_temp_new_i64();
3894 neon_load_reg64(tmp64
, rd
);
3895 gen_st64(tmp64
, addr
, IS_USER(s
));
3897 tcg_gen_addi_i32(addr
, addr
, stride
);
3899 for (pass
= 0; pass
< 2; pass
++) {
3902 tmp
= gen_ld32(addr
, IS_USER(s
));
3903 neon_store_reg(rd
, pass
, tmp
);
3905 tmp
= neon_load_reg(rd
, pass
);
3906 gen_st32(tmp
, addr
, IS_USER(s
));
3908 tcg_gen_addi_i32(addr
, addr
, stride
);
3909 } else if (size
== 1) {
3911 tmp
= gen_ld16u(addr
, IS_USER(s
));
3912 tcg_gen_addi_i32(addr
, addr
, stride
);
3913 tmp2
= gen_ld16u(addr
, IS_USER(s
));
3914 tcg_gen_addi_i32(addr
, addr
, stride
);
3915 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
3916 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3917 tcg_temp_free_i32(tmp2
);
3918 neon_store_reg(rd
, pass
, tmp
);
3920 tmp
= neon_load_reg(rd
, pass
);
3921 tmp2
= tcg_temp_new_i32();
3922 tcg_gen_shri_i32(tmp2
, tmp
, 16);
3923 gen_st16(tmp
, addr
, IS_USER(s
));
3924 tcg_gen_addi_i32(addr
, addr
, stride
);
3925 gen_st16(tmp2
, addr
, IS_USER(s
));
3926 tcg_gen_addi_i32(addr
, addr
, stride
);
3928 } else /* size == 0 */ {
3931 for (n
= 0; n
< 4; n
++) {
3932 tmp
= gen_ld8u(addr
, IS_USER(s
));
3933 tcg_gen_addi_i32(addr
, addr
, stride
);
3937 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
3938 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
3939 tcg_temp_free_i32(tmp
);
3942 neon_store_reg(rd
, pass
, tmp2
);
3944 tmp2
= neon_load_reg(rd
, pass
);
3945 for (n
= 0; n
< 4; n
++) {
3946 tmp
= tcg_temp_new_i32();
3948 tcg_gen_mov_i32(tmp
, tmp2
);
3950 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
3952 gen_st8(tmp
, addr
, IS_USER(s
));
3953 tcg_gen_addi_i32(addr
, addr
, stride
);
3955 tcg_temp_free_i32(tmp2
);
3962 tcg_temp_free_i32(addr
);
3965 size
= (insn
>> 10) & 3;
3967 /* Load single element to all lanes. */
3968 int a
= (insn
>> 4) & 1;
3972 size
= (insn
>> 6) & 3;
3973 nregs
= ((insn
>> 8) & 3) + 1;
3976 if (nregs
!= 4 || a
== 0) {
3979 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3982 if (nregs
== 1 && a
== 1 && size
== 0) {
3985 if (nregs
== 3 && a
== 1) {
3988 addr
= tcg_temp_new_i32();
3989 load_reg_var(s
, addr
, rn
);
3991 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3992 tmp
= gen_load_and_replicate(s
, addr
, size
);
3993 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
3994 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
3995 if (insn
& (1 << 5)) {
3996 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
3997 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
3999 tcg_temp_free_i32(tmp
);
4001 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4002 stride
= (insn
& (1 << 5)) ? 2 : 1;
4003 for (reg
= 0; reg
< nregs
; reg
++) {
4004 tmp
= gen_load_and_replicate(s
, addr
, size
);
4005 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4006 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4007 tcg_temp_free_i32(tmp
);
4008 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4012 tcg_temp_free_i32(addr
);
4013 stride
= (1 << size
) * nregs
;
4015 /* Single element. */
4016 int idx
= (insn
>> 4) & 0xf;
4017 pass
= (insn
>> 7) & 1;
4020 shift
= ((insn
>> 5) & 3) * 8;
4024 shift
= ((insn
>> 6) & 1) * 16;
4025 stride
= (insn
& (1 << 5)) ? 2 : 1;
4029 stride
= (insn
& (1 << 6)) ? 2 : 1;
4034 nregs
= ((insn
>> 8) & 3) + 1;
4035 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4038 if (((idx
& (1 << size
)) != 0) ||
4039 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4044 if ((idx
& 1) != 0) {
4049 if (size
== 2 && (idx
& 2) != 0) {
4054 if ((size
== 2) && ((idx
& 3) == 3)) {
4061 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4062 /* Attempts to write off the end of the register file
4063 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4064 * the neon_load_reg() would write off the end of the array.
4068 addr
= tcg_temp_new_i32();
4069 load_reg_var(s
, addr
, rn
);
4070 for (reg
= 0; reg
< nregs
; reg
++) {
4074 tmp
= gen_ld8u(addr
, IS_USER(s
));
4077 tmp
= gen_ld16u(addr
, IS_USER(s
));
4080 tmp
= gen_ld32(addr
, IS_USER(s
));
4082 default: /* Avoid compiler warnings. */
4086 tmp2
= neon_load_reg(rd
, pass
);
4087 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4088 shift
, size
? 16 : 8);
4089 tcg_temp_free_i32(tmp2
);
4091 neon_store_reg(rd
, pass
, tmp
);
4092 } else { /* Store */
4093 tmp
= neon_load_reg(rd
, pass
);
4095 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4098 gen_st8(tmp
, addr
, IS_USER(s
));
4101 gen_st16(tmp
, addr
, IS_USER(s
));
4104 gen_st32(tmp
, addr
, IS_USER(s
));
4109 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4111 tcg_temp_free_i32(addr
);
4112 stride
= nregs
* (1 << size
);
4118 base
= load_reg(s
, rn
);
4120 tcg_gen_addi_i32(base
, base
, stride
);
4123 index
= load_reg(s
, rm
);
4124 tcg_gen_add_i32(base
, base
, index
);
4125 tcg_temp_free_i32(index
);
4127 store_reg(s
, rn
, base
);
4132 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4133 static void gen_neon_bsl(TCGv dest
, TCGv t
, TCGv f
, TCGv c
)
4135 tcg_gen_and_i32(t
, t
, c
);
4136 tcg_gen_andc_i32(f
, f
, c
);
4137 tcg_gen_or_i32(dest
, t
, f
);
4140 static inline void gen_neon_narrow(int size
, TCGv dest
, TCGv_i64 src
)
4143 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4144 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4145 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4150 static inline void gen_neon_narrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4153 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4154 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4155 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4160 static inline void gen_neon_narrow_satu(int size
, TCGv dest
, TCGv_i64 src
)
4163 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4164 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4165 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4170 static inline void gen_neon_unarrow_sats(int size
, TCGv dest
, TCGv_i64 src
)
4173 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4174 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4175 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4180 static inline void gen_neon_shift_narrow(int size
, TCGv var
, TCGv shift
,
4186 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4187 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4192 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4193 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4200 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4201 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4206 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4207 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4214 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv src
, int size
, int u
)
4218 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4219 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4220 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4225 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4226 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4227 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4231 tcg_temp_free_i32(src
);
4234 static inline void gen_neon_addl(int size
)
4237 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4238 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4239 case 2: tcg_gen_add_i64(CPU_V001
); break;
4244 static inline void gen_neon_subl(int size
)
4247 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4248 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4249 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4254 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4257 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4258 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4260 tcg_gen_neg_i64(var
, var
);
4266 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4269 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4270 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4275 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv a
, TCGv b
, int size
, int u
)
4279 switch ((size
<< 1) | u
) {
4280 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4281 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4282 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4283 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4285 tmp
= gen_muls_i64_i32(a
, b
);
4286 tcg_gen_mov_i64(dest
, tmp
);
4287 tcg_temp_free_i64(tmp
);
4290 tmp
= gen_mulu_i64_i32(a
, b
);
4291 tcg_gen_mov_i64(dest
, tmp
);
4292 tcg_temp_free_i64(tmp
);
4297 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4298 Don't forget to clean them now. */
4300 tcg_temp_free_i32(a
);
4301 tcg_temp_free_i32(b
);
4305 static void gen_neon_narrow_op(int op
, int u
, int size
, TCGv dest
, TCGv_i64 src
)
4309 gen_neon_unarrow_sats(size
, dest
, src
);
4311 gen_neon_narrow(size
, dest
, src
);
4315 gen_neon_narrow_satu(size
, dest
, src
);
4317 gen_neon_narrow_sats(size
, dest
, src
);
4322 /* Symbolic constants for op fields for Neon 3-register same-length.
4323 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4326 #define NEON_3R_VHADD 0
4327 #define NEON_3R_VQADD 1
4328 #define NEON_3R_VRHADD 2
4329 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4330 #define NEON_3R_VHSUB 4
4331 #define NEON_3R_VQSUB 5
4332 #define NEON_3R_VCGT 6
4333 #define NEON_3R_VCGE 7
4334 #define NEON_3R_VSHL 8
4335 #define NEON_3R_VQSHL 9
4336 #define NEON_3R_VRSHL 10
4337 #define NEON_3R_VQRSHL 11
4338 #define NEON_3R_VMAX 12
4339 #define NEON_3R_VMIN 13
4340 #define NEON_3R_VABD 14
4341 #define NEON_3R_VABA 15
4342 #define NEON_3R_VADD_VSUB 16
4343 #define NEON_3R_VTST_VCEQ 17
4344 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4345 #define NEON_3R_VMUL 19
4346 #define NEON_3R_VPMAX 20
4347 #define NEON_3R_VPMIN 21
4348 #define NEON_3R_VQDMULH_VQRDMULH 22
4349 #define NEON_3R_VPADD 23
4350 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4351 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4352 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4353 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4354 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4355 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4356 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4358 static const uint8_t neon_3r_sizes
[] = {
4359 [NEON_3R_VHADD
] = 0x7,
4360 [NEON_3R_VQADD
] = 0xf,
4361 [NEON_3R_VRHADD
] = 0x7,
4362 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4363 [NEON_3R_VHSUB
] = 0x7,
4364 [NEON_3R_VQSUB
] = 0xf,
4365 [NEON_3R_VCGT
] = 0x7,
4366 [NEON_3R_VCGE
] = 0x7,
4367 [NEON_3R_VSHL
] = 0xf,
4368 [NEON_3R_VQSHL
] = 0xf,
4369 [NEON_3R_VRSHL
] = 0xf,
4370 [NEON_3R_VQRSHL
] = 0xf,
4371 [NEON_3R_VMAX
] = 0x7,
4372 [NEON_3R_VMIN
] = 0x7,
4373 [NEON_3R_VABD
] = 0x7,
4374 [NEON_3R_VABA
] = 0x7,
4375 [NEON_3R_VADD_VSUB
] = 0xf,
4376 [NEON_3R_VTST_VCEQ
] = 0x7,
4377 [NEON_3R_VML
] = 0x7,
4378 [NEON_3R_VMUL
] = 0x7,
4379 [NEON_3R_VPMAX
] = 0x7,
4380 [NEON_3R_VPMIN
] = 0x7,
4381 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4382 [NEON_3R_VPADD
] = 0x7,
4383 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4384 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4385 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4386 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4387 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4388 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4389 [NEON_3R_VRECPS_VRSQRTS
] = 0x5, /* size bit 1 encodes op */
4392 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4393 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4396 #define NEON_2RM_VREV64 0
4397 #define NEON_2RM_VREV32 1
4398 #define NEON_2RM_VREV16 2
4399 #define NEON_2RM_VPADDL 4
4400 #define NEON_2RM_VPADDL_U 5
4401 #define NEON_2RM_VCLS 8
4402 #define NEON_2RM_VCLZ 9
4403 #define NEON_2RM_VCNT 10
4404 #define NEON_2RM_VMVN 11
4405 #define NEON_2RM_VPADAL 12
4406 #define NEON_2RM_VPADAL_U 13
4407 #define NEON_2RM_VQABS 14
4408 #define NEON_2RM_VQNEG 15
4409 #define NEON_2RM_VCGT0 16
4410 #define NEON_2RM_VCGE0 17
4411 #define NEON_2RM_VCEQ0 18
4412 #define NEON_2RM_VCLE0 19
4413 #define NEON_2RM_VCLT0 20
4414 #define NEON_2RM_VABS 22
4415 #define NEON_2RM_VNEG 23
4416 #define NEON_2RM_VCGT0_F 24
4417 #define NEON_2RM_VCGE0_F 25
4418 #define NEON_2RM_VCEQ0_F 26
4419 #define NEON_2RM_VCLE0_F 27
4420 #define NEON_2RM_VCLT0_F 28
4421 #define NEON_2RM_VABS_F 30
4422 #define NEON_2RM_VNEG_F 31
4423 #define NEON_2RM_VSWP 32
4424 #define NEON_2RM_VTRN 33
4425 #define NEON_2RM_VUZP 34
4426 #define NEON_2RM_VZIP 35
4427 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4428 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4429 #define NEON_2RM_VSHLL 38
4430 #define NEON_2RM_VCVT_F16_F32 44
4431 #define NEON_2RM_VCVT_F32_F16 46
4432 #define NEON_2RM_VRECPE 56
4433 #define NEON_2RM_VRSQRTE 57
4434 #define NEON_2RM_VRECPE_F 58
4435 #define NEON_2RM_VRSQRTE_F 59
4436 #define NEON_2RM_VCVT_FS 60
4437 #define NEON_2RM_VCVT_FU 61
4438 #define NEON_2RM_VCVT_SF 62
4439 #define NEON_2RM_VCVT_UF 63
4441 static int neon_2rm_is_float_op(int op
)
4443 /* Return true if this neon 2reg-misc op is float-to-float */
4444 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4445 op
>= NEON_2RM_VRECPE_F
);
4448 /* Each entry in this array has bit n set if the insn allows
4449 * size value n (otherwise it will UNDEF). Since unallocated
4450 * op values will have no bits set they always UNDEF.
4452 static const uint8_t neon_2rm_sizes
[] = {
4453 [NEON_2RM_VREV64
] = 0x7,
4454 [NEON_2RM_VREV32
] = 0x3,
4455 [NEON_2RM_VREV16
] = 0x1,
4456 [NEON_2RM_VPADDL
] = 0x7,
4457 [NEON_2RM_VPADDL_U
] = 0x7,
4458 [NEON_2RM_VCLS
] = 0x7,
4459 [NEON_2RM_VCLZ
] = 0x7,
4460 [NEON_2RM_VCNT
] = 0x1,
4461 [NEON_2RM_VMVN
] = 0x1,
4462 [NEON_2RM_VPADAL
] = 0x7,
4463 [NEON_2RM_VPADAL_U
] = 0x7,
4464 [NEON_2RM_VQABS
] = 0x7,
4465 [NEON_2RM_VQNEG
] = 0x7,
4466 [NEON_2RM_VCGT0
] = 0x7,
4467 [NEON_2RM_VCGE0
] = 0x7,
4468 [NEON_2RM_VCEQ0
] = 0x7,
4469 [NEON_2RM_VCLE0
] = 0x7,
4470 [NEON_2RM_VCLT0
] = 0x7,
4471 [NEON_2RM_VABS
] = 0x7,
4472 [NEON_2RM_VNEG
] = 0x7,
4473 [NEON_2RM_VCGT0_F
] = 0x4,
4474 [NEON_2RM_VCGE0_F
] = 0x4,
4475 [NEON_2RM_VCEQ0_F
] = 0x4,
4476 [NEON_2RM_VCLE0_F
] = 0x4,
4477 [NEON_2RM_VCLT0_F
] = 0x4,
4478 [NEON_2RM_VABS_F
] = 0x4,
4479 [NEON_2RM_VNEG_F
] = 0x4,
4480 [NEON_2RM_VSWP
] = 0x1,
4481 [NEON_2RM_VTRN
] = 0x7,
4482 [NEON_2RM_VUZP
] = 0x7,
4483 [NEON_2RM_VZIP
] = 0x7,
4484 [NEON_2RM_VMOVN
] = 0x7,
4485 [NEON_2RM_VQMOVN
] = 0x7,
4486 [NEON_2RM_VSHLL
] = 0x7,
4487 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4488 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4489 [NEON_2RM_VRECPE
] = 0x4,
4490 [NEON_2RM_VRSQRTE
] = 0x4,
4491 [NEON_2RM_VRECPE_F
] = 0x4,
4492 [NEON_2RM_VRSQRTE_F
] = 0x4,
4493 [NEON_2RM_VCVT_FS
] = 0x4,
4494 [NEON_2RM_VCVT_FU
] = 0x4,
4495 [NEON_2RM_VCVT_SF
] = 0x4,
4496 [NEON_2RM_VCVT_UF
] = 0x4,
4499 /* Translate a NEON data processing instruction. Return nonzero if the
4500 instruction is invalid.
4501 We process data in a mixture of 32-bit and 64-bit chunks.
4502 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4504 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4516 TCGv tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4519 if (!s
->vfp_enabled
)
4521 q
= (insn
& (1 << 6)) != 0;
4522 u
= (insn
>> 24) & 1;
4523 VFP_DREG_D(rd
, insn
);
4524 VFP_DREG_N(rn
, insn
);
4525 VFP_DREG_M(rm
, insn
);
4526 size
= (insn
>> 20) & 3;
4527 if ((insn
& (1 << 23)) == 0) {
4528 /* Three register same length. */
4529 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4530 /* Catch invalid op and bad size combinations: UNDEF */
4531 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4534 /* All insns of this form UNDEF for either this condition or the
4535 * superset of cases "Q==1"; we catch the latter later.
4537 if (q
&& ((rd
| rn
| rm
) & 1)) {
4540 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4541 /* 64-bit element instructions. */
4542 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4543 neon_load_reg64(cpu_V0
, rn
+ pass
);
4544 neon_load_reg64(cpu_V1
, rm
+ pass
);
4548 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4551 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4557 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4560 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4566 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4568 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4573 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4576 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4582 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4584 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4587 case NEON_3R_VQRSHL
:
4589 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4592 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4596 case NEON_3R_VADD_VSUB
:
4598 tcg_gen_sub_i64(CPU_V001
);
4600 tcg_gen_add_i64(CPU_V001
);
4606 neon_store_reg64(cpu_V0
, rd
+ pass
);
4615 case NEON_3R_VQRSHL
:
4618 /* Shift instruction operands are reversed. */
4633 case NEON_3R_FLOAT_ARITH
:
4634 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4636 case NEON_3R_FLOAT_MINMAX
:
4637 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4639 case NEON_3R_FLOAT_CMP
:
4641 /* no encoding for U=0 C=1x */
4645 case NEON_3R_FLOAT_ACMP
:
4650 case NEON_3R_VRECPS_VRSQRTS
:
4656 if (u
&& (size
!= 0)) {
4657 /* UNDEF on invalid size for polynomial subcase */
4662 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
4670 if (pairwise
&& q
) {
4671 /* All the pairwise insns UNDEF if Q is set */
4675 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4680 tmp
= neon_load_reg(rn
, 0);
4681 tmp2
= neon_load_reg(rn
, 1);
4683 tmp
= neon_load_reg(rm
, 0);
4684 tmp2
= neon_load_reg(rm
, 1);
4688 tmp
= neon_load_reg(rn
, pass
);
4689 tmp2
= neon_load_reg(rm
, pass
);
4693 GEN_NEON_INTEGER_OP(hadd
);
4696 GEN_NEON_INTEGER_OP_ENV(qadd
);
4698 case NEON_3R_VRHADD
:
4699 GEN_NEON_INTEGER_OP(rhadd
);
4701 case NEON_3R_LOGIC
: /* Logic ops. */
4702 switch ((u
<< 2) | size
) {
4704 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
4707 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
4710 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4713 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
4716 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
4719 tmp3
= neon_load_reg(rd
, pass
);
4720 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
4721 tcg_temp_free_i32(tmp3
);
4724 tmp3
= neon_load_reg(rd
, pass
);
4725 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
4726 tcg_temp_free_i32(tmp3
);
4729 tmp3
= neon_load_reg(rd
, pass
);
4730 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
4731 tcg_temp_free_i32(tmp3
);
4736 GEN_NEON_INTEGER_OP(hsub
);
4739 GEN_NEON_INTEGER_OP_ENV(qsub
);
4742 GEN_NEON_INTEGER_OP(cgt
);
4745 GEN_NEON_INTEGER_OP(cge
);
4748 GEN_NEON_INTEGER_OP(shl
);
4751 GEN_NEON_INTEGER_OP_ENV(qshl
);
4754 GEN_NEON_INTEGER_OP(rshl
);
4756 case NEON_3R_VQRSHL
:
4757 GEN_NEON_INTEGER_OP_ENV(qrshl
);
4760 GEN_NEON_INTEGER_OP(max
);
4763 GEN_NEON_INTEGER_OP(min
);
4766 GEN_NEON_INTEGER_OP(abd
);
4769 GEN_NEON_INTEGER_OP(abd
);
4770 tcg_temp_free_i32(tmp2
);
4771 tmp2
= neon_load_reg(rd
, pass
);
4772 gen_neon_add(size
, tmp
, tmp2
);
4774 case NEON_3R_VADD_VSUB
:
4775 if (!u
) { /* VADD */
4776 gen_neon_add(size
, tmp
, tmp2
);
4779 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
4780 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
4781 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
4786 case NEON_3R_VTST_VCEQ
:
4787 if (!u
) { /* VTST */
4789 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
4790 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
4791 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
4796 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
4797 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
4798 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
4803 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
4805 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4806 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4807 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4810 tcg_temp_free_i32(tmp2
);
4811 tmp2
= neon_load_reg(rd
, pass
);
4813 gen_neon_rsb(size
, tmp
, tmp2
);
4815 gen_neon_add(size
, tmp
, tmp2
);
4819 if (u
) { /* polynomial */
4820 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
4821 } else { /* Integer */
4823 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
4824 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
4825 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
4831 GEN_NEON_INTEGER_OP(pmax
);
4834 GEN_NEON_INTEGER_OP(pmin
);
4836 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
4837 if (!u
) { /* VQDMULH */
4840 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4843 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4847 } else { /* VQRDMULH */
4850 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
4853 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
4861 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
4862 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
4863 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
4867 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
4869 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4870 switch ((u
<< 2) | size
) {
4873 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4876 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
4879 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
4884 tcg_temp_free_ptr(fpstatus
);
4887 case NEON_3R_FLOAT_MULTIPLY
:
4889 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4890 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
4892 tcg_temp_free_i32(tmp2
);
4893 tmp2
= neon_load_reg(rd
, pass
);
4895 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
4897 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
4900 tcg_temp_free_ptr(fpstatus
);
4903 case NEON_3R_FLOAT_CMP
:
4905 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4907 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
4910 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4912 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4915 tcg_temp_free_ptr(fpstatus
);
4918 case NEON_3R_FLOAT_ACMP
:
4920 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4922 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
4924 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
4926 tcg_temp_free_ptr(fpstatus
);
4929 case NEON_3R_FLOAT_MINMAX
:
4931 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4933 gen_helper_neon_max_f32(tmp
, tmp
, tmp2
, fpstatus
);
4935 gen_helper_neon_min_f32(tmp
, tmp
, tmp2
, fpstatus
);
4937 tcg_temp_free_ptr(fpstatus
);
4940 case NEON_3R_VRECPS_VRSQRTS
:
4942 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
4944 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
4948 /* VFMA, VFMS: fused multiply-add */
4949 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
4950 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
4953 gen_helper_vfp_negs(tmp
, tmp
);
4955 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
4956 tcg_temp_free_i32(tmp3
);
4957 tcg_temp_free_ptr(fpstatus
);
4963 tcg_temp_free_i32(tmp2
);
4965 /* Save the result. For elementwise operations we can put it
4966 straight into the destination register. For pairwise operations
4967 we have to be careful to avoid clobbering the source operands. */
4968 if (pairwise
&& rd
== rm
) {
4969 neon_store_scratch(pass
, tmp
);
4971 neon_store_reg(rd
, pass
, tmp
);
4975 if (pairwise
&& rd
== rm
) {
4976 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4977 tmp
= neon_load_scratch(pass
);
4978 neon_store_reg(rd
, pass
, tmp
);
4981 /* End of 3 register same size operations. */
4982 } else if (insn
& (1 << 4)) {
4983 if ((insn
& 0x00380080) != 0) {
4984 /* Two registers and shift. */
4985 op
= (insn
>> 8) & 0xf;
4986 if (insn
& (1 << 7)) {
4994 while ((insn
& (1 << (size
+ 19))) == 0)
4997 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
4998 /* To avoid excessive duplication of ops we implement shift
4999 by immediate using the variable shift operations. */
5001 /* Shift by immediate:
5002 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5003 if (q
&& ((rd
| rm
) & 1)) {
5006 if (!u
&& (op
== 4 || op
== 6)) {
5009 /* Right shifts are encoded as N - shift, where N is the
5010 element size in bits. */
5012 shift
= shift
- (1 << (size
+ 3));
5020 imm
= (uint8_t) shift
;
5025 imm
= (uint16_t) shift
;
5036 for (pass
= 0; pass
< count
; pass
++) {
5038 neon_load_reg64(cpu_V0
, rm
+ pass
);
5039 tcg_gen_movi_i64(cpu_V1
, imm
);
5044 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5046 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5051 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5053 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5056 case 5: /* VSHL, VSLI */
5057 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5059 case 6: /* VQSHLU */
5060 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5065 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5068 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5073 if (op
== 1 || op
== 3) {
5075 neon_load_reg64(cpu_V1
, rd
+ pass
);
5076 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5077 } else if (op
== 4 || (op
== 5 && u
)) {
5079 neon_load_reg64(cpu_V1
, rd
+ pass
);
5081 if (shift
< -63 || shift
> 63) {
5085 mask
= 0xffffffffffffffffull
>> -shift
;
5087 mask
= 0xffffffffffffffffull
<< shift
;
5090 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5091 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5093 neon_store_reg64(cpu_V0
, rd
+ pass
);
5094 } else { /* size < 3 */
5095 /* Operands in T0 and T1. */
5096 tmp
= neon_load_reg(rm
, pass
);
5097 tmp2
= tcg_temp_new_i32();
5098 tcg_gen_movi_i32(tmp2
, imm
);
5102 GEN_NEON_INTEGER_OP(shl
);
5106 GEN_NEON_INTEGER_OP(rshl
);
5109 case 5: /* VSHL, VSLI */
5111 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5112 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5113 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5117 case 6: /* VQSHLU */
5120 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5124 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5128 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5136 GEN_NEON_INTEGER_OP_ENV(qshl
);
5139 tcg_temp_free_i32(tmp2
);
5141 if (op
== 1 || op
== 3) {
5143 tmp2
= neon_load_reg(rd
, pass
);
5144 gen_neon_add(size
, tmp
, tmp2
);
5145 tcg_temp_free_i32(tmp2
);
5146 } else if (op
== 4 || (op
== 5 && u
)) {
5151 mask
= 0xff >> -shift
;
5153 mask
= (uint8_t)(0xff << shift
);
5159 mask
= 0xffff >> -shift
;
5161 mask
= (uint16_t)(0xffff << shift
);
5165 if (shift
< -31 || shift
> 31) {
5169 mask
= 0xffffffffu
>> -shift
;
5171 mask
= 0xffffffffu
<< shift
;
5177 tmp2
= neon_load_reg(rd
, pass
);
5178 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5179 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5180 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5181 tcg_temp_free_i32(tmp2
);
5183 neon_store_reg(rd
, pass
, tmp
);
5186 } else if (op
< 10) {
5187 /* Shift by immediate and narrow:
5188 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5189 int input_unsigned
= (op
== 8) ? !u
: u
;
5193 shift
= shift
- (1 << (size
+ 3));
5196 tmp64
= tcg_const_i64(shift
);
5197 neon_load_reg64(cpu_V0
, rm
);
5198 neon_load_reg64(cpu_V1
, rm
+ 1);
5199 for (pass
= 0; pass
< 2; pass
++) {
5207 if (input_unsigned
) {
5208 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5210 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5213 if (input_unsigned
) {
5214 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5216 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5219 tmp
= tcg_temp_new_i32();
5220 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5221 neon_store_reg(rd
, pass
, tmp
);
5223 tcg_temp_free_i64(tmp64
);
5226 imm
= (uint16_t)shift
;
5230 imm
= (uint32_t)shift
;
5232 tmp2
= tcg_const_i32(imm
);
5233 tmp4
= neon_load_reg(rm
+ 1, 0);
5234 tmp5
= neon_load_reg(rm
+ 1, 1);
5235 for (pass
= 0; pass
< 2; pass
++) {
5237 tmp
= neon_load_reg(rm
, 0);
5241 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5244 tmp3
= neon_load_reg(rm
, 1);
5248 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5250 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5251 tcg_temp_free_i32(tmp
);
5252 tcg_temp_free_i32(tmp3
);
5253 tmp
= tcg_temp_new_i32();
5254 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5255 neon_store_reg(rd
, pass
, tmp
);
5257 tcg_temp_free_i32(tmp2
);
5259 } else if (op
== 10) {
5261 if (q
|| (rd
& 1)) {
5264 tmp
= neon_load_reg(rm
, 0);
5265 tmp2
= neon_load_reg(rm
, 1);
5266 for (pass
= 0; pass
< 2; pass
++) {
5270 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5273 /* The shift is less than the width of the source
5274 type, so we can just shift the whole register. */
5275 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5276 /* Widen the result of shift: we need to clear
5277 * the potential overflow bits resulting from
5278 * left bits of the narrow input appearing as
5279 * right bits of left the neighbour narrow
5281 if (size
< 2 || !u
) {
5284 imm
= (0xffu
>> (8 - shift
));
5286 } else if (size
== 1) {
5287 imm
= 0xffff >> (16 - shift
);
5290 imm
= 0xffffffff >> (32 - shift
);
5293 imm64
= imm
| (((uint64_t)imm
) << 32);
5297 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5300 neon_store_reg64(cpu_V0
, rd
+ pass
);
5302 } else if (op
>= 14) {
5303 /* VCVT fixed-point. */
5304 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5307 /* We have already masked out the must-be-1 top bit of imm6,
5308 * hence this 32-shift where the ARM ARM has 64-imm6.
5311 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5312 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5315 gen_vfp_ulto(0, shift
, 1);
5317 gen_vfp_slto(0, shift
, 1);
5320 gen_vfp_toul(0, shift
, 1);
5322 gen_vfp_tosl(0, shift
, 1);
5324 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5329 } else { /* (insn & 0x00380080) == 0 */
5331 if (q
&& (rd
& 1)) {
5335 op
= (insn
>> 8) & 0xf;
5336 /* One register and immediate. */
5337 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5338 invert
= (insn
& (1 << 5)) != 0;
5339 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5340 * We choose to not special-case this and will behave as if a
5341 * valid constant encoding of 0 had been given.
5360 imm
= (imm
<< 8) | (imm
<< 24);
5363 imm
= (imm
<< 8) | 0xff;
5366 imm
= (imm
<< 16) | 0xffff;
5369 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5377 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5378 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5384 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5385 if (op
& 1 && op
< 12) {
5386 tmp
= neon_load_reg(rd
, pass
);
5388 /* The immediate value has already been inverted, so
5390 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5392 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5396 tmp
= tcg_temp_new_i32();
5397 if (op
== 14 && invert
) {
5401 for (n
= 0; n
< 4; n
++) {
5402 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5403 val
|= 0xff << (n
* 8);
5405 tcg_gen_movi_i32(tmp
, val
);
5407 tcg_gen_movi_i32(tmp
, imm
);
5410 neon_store_reg(rd
, pass
, tmp
);
5413 } else { /* (insn & 0x00800010 == 0x00800000) */
5415 op
= (insn
>> 8) & 0xf;
5416 if ((insn
& (1 << 6)) == 0) {
5417 /* Three registers of different lengths. */
5421 /* undefreq: bit 0 : UNDEF if size != 0
5422 * bit 1 : UNDEF if size == 0
5423 * bit 2 : UNDEF if U == 1
5424 * Note that [1:0] set implies 'always UNDEF'
5427 /* prewiden, src1_wide, src2_wide, undefreq */
5428 static const int neon_3reg_wide
[16][4] = {
5429 {1, 0, 0, 0}, /* VADDL */
5430 {1, 1, 0, 0}, /* VADDW */
5431 {1, 0, 0, 0}, /* VSUBL */
5432 {1, 1, 0, 0}, /* VSUBW */
5433 {0, 1, 1, 0}, /* VADDHN */
5434 {0, 0, 0, 0}, /* VABAL */
5435 {0, 1, 1, 0}, /* VSUBHN */
5436 {0, 0, 0, 0}, /* VABDL */
5437 {0, 0, 0, 0}, /* VMLAL */
5438 {0, 0, 0, 6}, /* VQDMLAL */
5439 {0, 0, 0, 0}, /* VMLSL */
5440 {0, 0, 0, 6}, /* VQDMLSL */
5441 {0, 0, 0, 0}, /* Integer VMULL */
5442 {0, 0, 0, 2}, /* VQDMULL */
5443 {0, 0, 0, 5}, /* Polynomial VMULL */
5444 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5447 prewiden
= neon_3reg_wide
[op
][0];
5448 src1_wide
= neon_3reg_wide
[op
][1];
5449 src2_wide
= neon_3reg_wide
[op
][2];
5450 undefreq
= neon_3reg_wide
[op
][3];
5452 if (((undefreq
& 1) && (size
!= 0)) ||
5453 ((undefreq
& 2) && (size
== 0)) ||
5454 ((undefreq
& 4) && u
)) {
5457 if ((src1_wide
&& (rn
& 1)) ||
5458 (src2_wide
&& (rm
& 1)) ||
5459 (!src2_wide
&& (rd
& 1))) {
5463 /* Avoid overlapping operands. Wide source operands are
5464 always aligned so will never overlap with wide
5465 destinations in problematic ways. */
5466 if (rd
== rm
&& !src2_wide
) {
5467 tmp
= neon_load_reg(rm
, 1);
5468 neon_store_scratch(2, tmp
);
5469 } else if (rd
== rn
&& !src1_wide
) {
5470 tmp
= neon_load_reg(rn
, 1);
5471 neon_store_scratch(2, tmp
);
5474 for (pass
= 0; pass
< 2; pass
++) {
5476 neon_load_reg64(cpu_V0
, rn
+ pass
);
5479 if (pass
== 1 && rd
== rn
) {
5480 tmp
= neon_load_scratch(2);
5482 tmp
= neon_load_reg(rn
, pass
);
5485 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5489 neon_load_reg64(cpu_V1
, rm
+ pass
);
5492 if (pass
== 1 && rd
== rm
) {
5493 tmp2
= neon_load_scratch(2);
5495 tmp2
= neon_load_reg(rm
, pass
);
5498 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5502 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5503 gen_neon_addl(size
);
5505 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5506 gen_neon_subl(size
);
5508 case 5: case 7: /* VABAL, VABDL */
5509 switch ((size
<< 1) | u
) {
5511 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5514 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5517 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5520 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5523 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5526 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5530 tcg_temp_free_i32(tmp2
);
5531 tcg_temp_free_i32(tmp
);
5533 case 8: case 9: case 10: case 11: case 12: case 13:
5534 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5535 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5537 case 14: /* Polynomial VMULL */
5538 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5539 tcg_temp_free_i32(tmp2
);
5540 tcg_temp_free_i32(tmp
);
5542 default: /* 15 is RESERVED: caught earlier */
5547 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5548 neon_store_reg64(cpu_V0
, rd
+ pass
);
5549 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5551 neon_load_reg64(cpu_V1
, rd
+ pass
);
5553 case 10: /* VMLSL */
5554 gen_neon_negl(cpu_V0
, size
);
5556 case 5: case 8: /* VABAL, VMLAL */
5557 gen_neon_addl(size
);
5559 case 9: case 11: /* VQDMLAL, VQDMLSL */
5560 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5562 gen_neon_negl(cpu_V0
, size
);
5564 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5569 neon_store_reg64(cpu_V0
, rd
+ pass
);
5570 } else if (op
== 4 || op
== 6) {
5571 /* Narrowing operation. */
5572 tmp
= tcg_temp_new_i32();
5576 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5579 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5582 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5583 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5590 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5593 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5596 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5597 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5598 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5606 neon_store_reg(rd
, 0, tmp3
);
5607 neon_store_reg(rd
, 1, tmp
);
5610 /* Write back the result. */
5611 neon_store_reg64(cpu_V0
, rd
+ pass
);
5615 /* Two registers and a scalar. NB that for ops of this form
5616 * the ARM ARM labels bit 24 as Q, but it is in our variable
5623 case 1: /* Float VMLA scalar */
5624 case 5: /* Floating point VMLS scalar */
5625 case 9: /* Floating point VMUL scalar */
5630 case 0: /* Integer VMLA scalar */
5631 case 4: /* Integer VMLS scalar */
5632 case 8: /* Integer VMUL scalar */
5633 case 12: /* VQDMULH scalar */
5634 case 13: /* VQRDMULH scalar */
5635 if (u
&& ((rd
| rn
) & 1)) {
5638 tmp
= neon_get_scalar(size
, rm
);
5639 neon_store_scratch(0, tmp
);
5640 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5641 tmp
= neon_load_scratch(0);
5642 tmp2
= neon_load_reg(rn
, pass
);
5645 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5647 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5649 } else if (op
== 13) {
5651 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5653 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5655 } else if (op
& 1) {
5656 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5657 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5658 tcg_temp_free_ptr(fpstatus
);
5661 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5662 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5663 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5667 tcg_temp_free_i32(tmp2
);
5670 tmp2
= neon_load_reg(rd
, pass
);
5673 gen_neon_add(size
, tmp
, tmp2
);
5677 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5678 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5679 tcg_temp_free_ptr(fpstatus
);
5683 gen_neon_rsb(size
, tmp
, tmp2
);
5687 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5688 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5689 tcg_temp_free_ptr(fpstatus
);
5695 tcg_temp_free_i32(tmp2
);
5697 neon_store_reg(rd
, pass
, tmp
);
5700 case 3: /* VQDMLAL scalar */
5701 case 7: /* VQDMLSL scalar */
5702 case 11: /* VQDMULL scalar */
5707 case 2: /* VMLAL sclar */
5708 case 6: /* VMLSL scalar */
5709 case 10: /* VMULL scalar */
5713 tmp2
= neon_get_scalar(size
, rm
);
5714 /* We need a copy of tmp2 because gen_neon_mull
5715 * deletes it during pass 0. */
5716 tmp4
= tcg_temp_new_i32();
5717 tcg_gen_mov_i32(tmp4
, tmp2
);
5718 tmp3
= neon_load_reg(rn
, 1);
5720 for (pass
= 0; pass
< 2; pass
++) {
5722 tmp
= neon_load_reg(rn
, 0);
5727 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5729 neon_load_reg64(cpu_V1
, rd
+ pass
);
5733 gen_neon_negl(cpu_V0
, size
);
5736 gen_neon_addl(size
);
5739 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5741 gen_neon_negl(cpu_V0
, size
);
5743 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5749 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5754 neon_store_reg64(cpu_V0
, rd
+ pass
);
5759 default: /* 14 and 15 are RESERVED */
5763 } else { /* size == 3 */
5766 imm
= (insn
>> 8) & 0xf;
5771 if (q
&& ((rd
| rn
| rm
) & 1)) {
5776 neon_load_reg64(cpu_V0
, rn
);
5778 neon_load_reg64(cpu_V1
, rn
+ 1);
5780 } else if (imm
== 8) {
5781 neon_load_reg64(cpu_V0
, rn
+ 1);
5783 neon_load_reg64(cpu_V1
, rm
);
5786 tmp64
= tcg_temp_new_i64();
5788 neon_load_reg64(cpu_V0
, rn
);
5789 neon_load_reg64(tmp64
, rn
+ 1);
5791 neon_load_reg64(cpu_V0
, rn
+ 1);
5792 neon_load_reg64(tmp64
, rm
);
5794 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
5795 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
5796 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5798 neon_load_reg64(cpu_V1
, rm
);
5800 neon_load_reg64(cpu_V1
, rm
+ 1);
5803 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5804 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
5805 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
5806 tcg_temp_free_i64(tmp64
);
5809 neon_load_reg64(cpu_V0
, rn
);
5810 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
5811 neon_load_reg64(cpu_V1
, rm
);
5812 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
5813 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5815 neon_store_reg64(cpu_V0
, rd
);
5817 neon_store_reg64(cpu_V1
, rd
+ 1);
5819 } else if ((insn
& (1 << 11)) == 0) {
5820 /* Two register misc. */
5821 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
5822 size
= (insn
>> 18) & 3;
5823 /* UNDEF for unknown op values and bad op-size combinations */
5824 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
5827 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
5828 q
&& ((rm
| rd
) & 1)) {
5832 case NEON_2RM_VREV64
:
5833 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5834 tmp
= neon_load_reg(rm
, pass
* 2);
5835 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
5837 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5838 case 1: gen_swap_half(tmp
); break;
5839 case 2: /* no-op */ break;
5842 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
5844 neon_store_reg(rd
, pass
* 2, tmp2
);
5847 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
5848 case 1: gen_swap_half(tmp2
); break;
5851 neon_store_reg(rd
, pass
* 2, tmp2
);
5855 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
5856 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
5857 for (pass
= 0; pass
< q
+ 1; pass
++) {
5858 tmp
= neon_load_reg(rm
, pass
* 2);
5859 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
5860 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
5861 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
5863 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
5864 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
5865 case 2: tcg_gen_add_i64(CPU_V001
); break;
5868 if (op
>= NEON_2RM_VPADAL
) {
5870 neon_load_reg64(cpu_V1
, rd
+ pass
);
5871 gen_neon_addl(size
);
5873 neon_store_reg64(cpu_V0
, rd
+ pass
);
5879 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
5880 tmp
= neon_load_reg(rm
, n
);
5881 tmp2
= neon_load_reg(rd
, n
+ 1);
5882 neon_store_reg(rm
, n
, tmp2
);
5883 neon_store_reg(rd
, n
+ 1, tmp
);
5890 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
5895 if (gen_neon_zip(rd
, rm
, size
, q
)) {
5899 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
5900 /* also VQMOVUN; op field and mnemonics don't line up */
5905 for (pass
= 0; pass
< 2; pass
++) {
5906 neon_load_reg64(cpu_V0
, rm
+ pass
);
5907 tmp
= tcg_temp_new_i32();
5908 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
5913 neon_store_reg(rd
, 0, tmp2
);
5914 neon_store_reg(rd
, 1, tmp
);
5918 case NEON_2RM_VSHLL
:
5919 if (q
|| (rd
& 1)) {
5922 tmp
= neon_load_reg(rm
, 0);
5923 tmp2
= neon_load_reg(rm
, 1);
5924 for (pass
= 0; pass
< 2; pass
++) {
5927 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
5928 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
5929 neon_store_reg64(cpu_V0
, rd
+ pass
);
5932 case NEON_2RM_VCVT_F16_F32
:
5933 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5937 tmp
= tcg_temp_new_i32();
5938 tmp2
= tcg_temp_new_i32();
5939 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
5940 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5941 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
5942 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5943 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5944 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5945 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
5946 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
5947 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
5948 neon_store_reg(rd
, 0, tmp2
);
5949 tmp2
= tcg_temp_new_i32();
5950 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
5951 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
5952 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
5953 neon_store_reg(rd
, 1, tmp2
);
5954 tcg_temp_free_i32(tmp
);
5956 case NEON_2RM_VCVT_F32_F16
:
5957 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
5961 tmp3
= tcg_temp_new_i32();
5962 tmp
= neon_load_reg(rm
, 0);
5963 tmp2
= neon_load_reg(rm
, 1);
5964 tcg_gen_ext16u_i32(tmp3
, tmp
);
5965 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5966 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
5967 tcg_gen_shri_i32(tmp3
, tmp
, 16);
5968 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5969 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
5970 tcg_temp_free_i32(tmp
);
5971 tcg_gen_ext16u_i32(tmp3
, tmp2
);
5972 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5973 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
5974 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
5975 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
5976 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
5977 tcg_temp_free_i32(tmp2
);
5978 tcg_temp_free_i32(tmp3
);
5982 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5983 if (neon_2rm_is_float_op(op
)) {
5984 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
5985 neon_reg_offset(rm
, pass
));
5988 tmp
= neon_load_reg(rm
, pass
);
5991 case NEON_2RM_VREV32
:
5993 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
5994 case 1: gen_swap_half(tmp
); break;
5998 case NEON_2RM_VREV16
:
6003 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6004 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6005 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6011 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6012 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6013 case 2: gen_helper_clz(tmp
, tmp
); break;
6018 gen_helper_neon_cnt_u8(tmp
, tmp
);
6021 tcg_gen_not_i32(tmp
, tmp
);
6023 case NEON_2RM_VQABS
:
6026 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6029 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6032 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6037 case NEON_2RM_VQNEG
:
6040 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6043 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6046 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6051 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6052 tmp2
= tcg_const_i32(0);
6054 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6055 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6056 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6059 tcg_temp_free(tmp2
);
6060 if (op
== NEON_2RM_VCLE0
) {
6061 tcg_gen_not_i32(tmp
, tmp
);
6064 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6065 tmp2
= tcg_const_i32(0);
6067 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6068 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6069 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6072 tcg_temp_free(tmp2
);
6073 if (op
== NEON_2RM_VCLT0
) {
6074 tcg_gen_not_i32(tmp
, tmp
);
6077 case NEON_2RM_VCEQ0
:
6078 tmp2
= tcg_const_i32(0);
6080 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6081 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6082 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6085 tcg_temp_free(tmp2
);
6089 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6090 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6091 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6096 tmp2
= tcg_const_i32(0);
6097 gen_neon_rsb(size
, tmp
, tmp2
);
6098 tcg_temp_free(tmp2
);
6100 case NEON_2RM_VCGT0_F
:
6102 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6103 tmp2
= tcg_const_i32(0);
6104 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6105 tcg_temp_free(tmp2
);
6106 tcg_temp_free_ptr(fpstatus
);
6109 case NEON_2RM_VCGE0_F
:
6111 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6112 tmp2
= tcg_const_i32(0);
6113 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6114 tcg_temp_free(tmp2
);
6115 tcg_temp_free_ptr(fpstatus
);
6118 case NEON_2RM_VCEQ0_F
:
6120 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6121 tmp2
= tcg_const_i32(0);
6122 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6123 tcg_temp_free(tmp2
);
6124 tcg_temp_free_ptr(fpstatus
);
6127 case NEON_2RM_VCLE0_F
:
6129 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6130 tmp2
= tcg_const_i32(0);
6131 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6132 tcg_temp_free(tmp2
);
6133 tcg_temp_free_ptr(fpstatus
);
6136 case NEON_2RM_VCLT0_F
:
6138 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6139 tmp2
= tcg_const_i32(0);
6140 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6141 tcg_temp_free(tmp2
);
6142 tcg_temp_free_ptr(fpstatus
);
6145 case NEON_2RM_VABS_F
:
6148 case NEON_2RM_VNEG_F
:
6152 tmp2
= neon_load_reg(rd
, pass
);
6153 neon_store_reg(rm
, pass
, tmp2
);
6156 tmp2
= neon_load_reg(rd
, pass
);
6158 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6159 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6162 neon_store_reg(rm
, pass
, tmp2
);
6164 case NEON_2RM_VRECPE
:
6165 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6167 case NEON_2RM_VRSQRTE
:
6168 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6170 case NEON_2RM_VRECPE_F
:
6171 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6173 case NEON_2RM_VRSQRTE_F
:
6174 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6176 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6179 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6182 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6183 gen_vfp_tosiz(0, 1);
6185 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6186 gen_vfp_touiz(0, 1);
6189 /* Reserved op values were caught by the
6190 * neon_2rm_sizes[] check earlier.
6194 if (neon_2rm_is_float_op(op
)) {
6195 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6196 neon_reg_offset(rd
, pass
));
6198 neon_store_reg(rd
, pass
, tmp
);
6203 } else if ((insn
& (1 << 10)) == 0) {
6205 int n
= ((insn
>> 8) & 3) + 1;
6206 if ((rn
+ n
) > 32) {
6207 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6208 * helper function running off the end of the register file.
6213 if (insn
& (1 << 6)) {
6214 tmp
= neon_load_reg(rd
, 0);
6216 tmp
= tcg_temp_new_i32();
6217 tcg_gen_movi_i32(tmp
, 0);
6219 tmp2
= neon_load_reg(rm
, 0);
6220 tmp4
= tcg_const_i32(rn
);
6221 tmp5
= tcg_const_i32(n
);
6222 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6223 tcg_temp_free_i32(tmp
);
6224 if (insn
& (1 << 6)) {
6225 tmp
= neon_load_reg(rd
, 1);
6227 tmp
= tcg_temp_new_i32();
6228 tcg_gen_movi_i32(tmp
, 0);
6230 tmp3
= neon_load_reg(rm
, 1);
6231 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6232 tcg_temp_free_i32(tmp5
);
6233 tcg_temp_free_i32(tmp4
);
6234 neon_store_reg(rd
, 0, tmp2
);
6235 neon_store_reg(rd
, 1, tmp3
);
6236 tcg_temp_free_i32(tmp
);
6237 } else if ((insn
& 0x380) == 0) {
6239 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6242 if (insn
& (1 << 19)) {
6243 tmp
= neon_load_reg(rm
, 1);
6245 tmp
= neon_load_reg(rm
, 0);
6247 if (insn
& (1 << 16)) {
6248 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6249 } else if (insn
& (1 << 17)) {
6250 if ((insn
>> 18) & 1)
6251 gen_neon_dup_high16(tmp
);
6253 gen_neon_dup_low16(tmp
);
6255 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6256 tmp2
= tcg_temp_new_i32();
6257 tcg_gen_mov_i32(tmp2
, tmp
);
6258 neon_store_reg(rd
, pass
, tmp2
);
6260 tcg_temp_free_i32(tmp
);
6269 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6271 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6272 const ARMCPRegInfo
*ri
;
6273 ARMCPU
*cpu
= arm_env_get_cpu(env
);
6275 cpnum
= (insn
>> 8) & 0xf;
6276 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6277 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6280 /* First check for coprocessor space used for actual instructions */
6284 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6285 return disas_iwmmxt_insn(env
, s
, insn
);
6286 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6287 return disas_dsp_insn(env
, s
, insn
);
6292 return disas_vfp_insn (env
, s
, insn
);
6297 /* Otherwise treat as a generic register access */
6298 is64
= (insn
& (1 << 25)) == 0;
6299 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6307 opc1
= (insn
>> 4) & 0xf;
6309 rt2
= (insn
>> 16) & 0xf;
6311 crn
= (insn
>> 16) & 0xf;
6312 opc1
= (insn
>> 21) & 7;
6313 opc2
= (insn
>> 5) & 7;
6316 isread
= (insn
>> 20) & 1;
6317 rt
= (insn
>> 12) & 0xf;
6319 ri
= get_arm_cp_reginfo(cpu
,
6320 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6322 /* Check access permissions */
6323 if (!cp_access_ok(env
, ri
, isread
)) {
6327 /* Handle special cases first */
6328 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6335 gen_set_pc_im(s
->pc
);
6336 s
->is_jmp
= DISAS_WFI
;
6347 if (ri
->type
& ARM_CP_CONST
) {
6348 tmp64
= tcg_const_i64(ri
->resetvalue
);
6349 } else if (ri
->readfn
) {
6351 gen_set_pc_im(s
->pc
);
6352 tmp64
= tcg_temp_new_i64();
6353 tmpptr
= tcg_const_ptr(ri
);
6354 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6355 tcg_temp_free_ptr(tmpptr
);
6357 tmp64
= tcg_temp_new_i64();
6358 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6360 tmp
= tcg_temp_new_i32();
6361 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6362 store_reg(s
, rt
, tmp
);
6363 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6364 tmp
= tcg_temp_new_i32();
6365 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6366 tcg_temp_free_i64(tmp64
);
6367 store_reg(s
, rt2
, tmp
);
6370 if (ri
->type
& ARM_CP_CONST
) {
6371 tmp
= tcg_const_i32(ri
->resetvalue
);
6372 } else if (ri
->readfn
) {
6374 gen_set_pc_im(s
->pc
);
6375 tmp
= tcg_temp_new_i32();
6376 tmpptr
= tcg_const_ptr(ri
);
6377 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6378 tcg_temp_free_ptr(tmpptr
);
6380 tmp
= load_cpu_offset(ri
->fieldoffset
);
6383 /* Destination register of r15 for 32 bit loads sets
6384 * the condition codes from the high 4 bits of the value
6387 tcg_temp_free_i32(tmp
);
6389 store_reg(s
, rt
, tmp
);
6394 if (ri
->type
& ARM_CP_CONST
) {
6395 /* If not forbidden by access permissions, treat as WI */
6401 TCGv_i64 tmp64
= tcg_temp_new_i64();
6402 tmplo
= load_reg(s
, rt
);
6403 tmphi
= load_reg(s
, rt2
);
6404 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6405 tcg_temp_free_i32(tmplo
);
6406 tcg_temp_free_i32(tmphi
);
6408 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6409 gen_set_pc_im(s
->pc
);
6410 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6411 tcg_temp_free_ptr(tmpptr
);
6413 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6415 tcg_temp_free_i64(tmp64
);
6420 gen_set_pc_im(s
->pc
);
6421 tmp
= load_reg(s
, rt
);
6422 tmpptr
= tcg_const_ptr(ri
);
6423 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6424 tcg_temp_free_ptr(tmpptr
);
6425 tcg_temp_free_i32(tmp
);
6427 TCGv tmp
= load_reg(s
, rt
);
6428 store_cpu_offset(tmp
, ri
->fieldoffset
);
6431 /* We default to ending the TB on a coprocessor register write,
6432 * but allow this to be suppressed by the register definition
6433 * (usually only necessary to work around guest bugs).
6435 if (!(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6446 /* Store a 64-bit value to a register pair. Clobbers val. */
6447 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6450 tmp
= tcg_temp_new_i32();
6451 tcg_gen_trunc_i64_i32(tmp
, val
);
6452 store_reg(s
, rlow
, tmp
);
6453 tmp
= tcg_temp_new_i32();
6454 tcg_gen_shri_i64(val
, val
, 32);
6455 tcg_gen_trunc_i64_i32(tmp
, val
);
6456 store_reg(s
, rhigh
, tmp
);
6459 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6460 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6465 /* Load value and extend to 64 bits. */
6466 tmp
= tcg_temp_new_i64();
6467 tmp2
= load_reg(s
, rlow
);
6468 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6469 tcg_temp_free_i32(tmp2
);
6470 tcg_gen_add_i64(val
, val
, tmp
);
6471 tcg_temp_free_i64(tmp
);
6474 /* load and add a 64-bit value from a register pair. */
6475 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6481 /* Load 64-bit value rd:rn. */
6482 tmpl
= load_reg(s
, rlow
);
6483 tmph
= load_reg(s
, rhigh
);
6484 tmp
= tcg_temp_new_i64();
6485 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6486 tcg_temp_free_i32(tmpl
);
6487 tcg_temp_free_i32(tmph
);
6488 tcg_gen_add_i64(val
, val
, tmp
);
6489 tcg_temp_free_i64(tmp
);
6492 /* Set N and Z flags from hi|lo. */
6493 static void gen_logicq_cc(TCGv lo
, TCGv hi
)
6495 tcg_gen_mov_i32(cpu_NF
, hi
);
6496 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
6499 /* Load/Store exclusive instructions are implemented by remembering
6500 the value/address loaded, and seeing if these are the same
6501 when the store is performed. This should be sufficient to implement
6502 the architecturally mandated semantics, and avoids having to monitor
6505 In system emulation mode only one CPU will be running at once, so
6506 this sequence is effectively atomic. In user emulation mode we
6507 throw an exception and handle the atomic operation elsewhere. */
6508 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6509 TCGv addr
, int size
)
6515 tmp
= gen_ld8u(addr
, IS_USER(s
));
6518 tmp
= gen_ld16u(addr
, IS_USER(s
));
6522 tmp
= gen_ld32(addr
, IS_USER(s
));
6527 tcg_gen_mov_i32(cpu_exclusive_val
, tmp
);
6528 store_reg(s
, rt
, tmp
);
6530 TCGv tmp2
= tcg_temp_new_i32();
6531 tcg_gen_addi_i32(tmp2
, addr
, 4);
6532 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6533 tcg_temp_free_i32(tmp2
);
6534 tcg_gen_mov_i32(cpu_exclusive_high
, tmp
);
6535 store_reg(s
, rt2
, tmp
);
6537 tcg_gen_mov_i32(cpu_exclusive_addr
, addr
);
6540 static void gen_clrex(DisasContext
*s
)
6542 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6545 #ifdef CONFIG_USER_ONLY
6546 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6547 TCGv addr
, int size
)
6549 tcg_gen_mov_i32(cpu_exclusive_test
, addr
);
6550 tcg_gen_movi_i32(cpu_exclusive_info
,
6551 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
6552 gen_exception_insn(s
, 4, EXCP_STREX
);
6555 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
6556 TCGv addr
, int size
)
6562 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6568 fail_label
= gen_new_label();
6569 done_label
= gen_new_label();
6570 tcg_gen_brcond_i32(TCG_COND_NE
, addr
, cpu_exclusive_addr
, fail_label
);
6573 tmp
= gen_ld8u(addr
, IS_USER(s
));
6576 tmp
= gen_ld16u(addr
, IS_USER(s
));
6580 tmp
= gen_ld32(addr
, IS_USER(s
));
6585 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_val
, fail_label
);
6586 tcg_temp_free_i32(tmp
);
6588 TCGv tmp2
= tcg_temp_new_i32();
6589 tcg_gen_addi_i32(tmp2
, addr
, 4);
6590 tmp
= gen_ld32(tmp2
, IS_USER(s
));
6591 tcg_temp_free_i32(tmp2
);
6592 tcg_gen_brcond_i32(TCG_COND_NE
, tmp
, cpu_exclusive_high
, fail_label
);
6593 tcg_temp_free_i32(tmp
);
6595 tmp
= load_reg(s
, rt
);
6598 gen_st8(tmp
, addr
, IS_USER(s
));
6601 gen_st16(tmp
, addr
, IS_USER(s
));
6605 gen_st32(tmp
, addr
, IS_USER(s
));
6611 tcg_gen_addi_i32(addr
, addr
, 4);
6612 tmp
= load_reg(s
, rt2
);
6613 gen_st32(tmp
, addr
, IS_USER(s
));
6615 tcg_gen_movi_i32(cpu_R
[rd
], 0);
6616 tcg_gen_br(done_label
);
6617 gen_set_label(fail_label
);
6618 tcg_gen_movi_i32(cpu_R
[rd
], 1);
6619 gen_set_label(done_label
);
6620 tcg_gen_movi_i32(cpu_exclusive_addr
, -1);
6624 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
6626 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
6633 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
6636 /* M variants do not implement ARM mode. */
6641 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6642 * choose to UNDEF. In ARMv5 and above the space is used
6643 * for miscellaneous unconditional instructions.
6647 /* Unconditional instructions. */
6648 if (((insn
>> 25) & 7) == 1) {
6649 /* NEON Data processing. */
6650 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6653 if (disas_neon_data_insn(env
, s
, insn
))
6657 if ((insn
& 0x0f100000) == 0x04000000) {
6658 /* NEON load/store. */
6659 if (!arm_feature(env
, ARM_FEATURE_NEON
))
6662 if (disas_neon_ls_insn(env
, s
, insn
))
6666 if (((insn
& 0x0f30f000) == 0x0510f000) ||
6667 ((insn
& 0x0f30f010) == 0x0710f000)) {
6668 if ((insn
& (1 << 22)) == 0) {
6670 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6674 /* Otherwise PLD; v5TE+ */
6678 if (((insn
& 0x0f70f000) == 0x0450f000) ||
6679 ((insn
& 0x0f70f010) == 0x0650f000)) {
6681 return; /* PLI; V7 */
6683 if (((insn
& 0x0f700000) == 0x04100000) ||
6684 ((insn
& 0x0f700010) == 0x06100000)) {
6685 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
6688 return; /* v7MP: Unallocated memory hint: must NOP */
6691 if ((insn
& 0x0ffffdff) == 0x01010000) {
6694 if (((insn
>> 9) & 1) != s
->bswap_code
) {
6695 /* Dynamic endianness switching not implemented. */
6699 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
6700 switch ((insn
>> 4) & 0xf) {
6709 /* We don't emulate caches so these are a no-op. */
6714 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
6720 op1
= (insn
& 0x1f);
6721 addr
= tcg_temp_new_i32();
6722 tmp
= tcg_const_i32(op1
);
6723 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
6724 tcg_temp_free_i32(tmp
);
6725 i
= (insn
>> 23) & 3;
6727 case 0: offset
= -4; break; /* DA */
6728 case 1: offset
= 0; break; /* IA */
6729 case 2: offset
= -8; break; /* DB */
6730 case 3: offset
= 4; break; /* IB */
6734 tcg_gen_addi_i32(addr
, addr
, offset
);
6735 tmp
= load_reg(s
, 14);
6736 gen_st32(tmp
, addr
, 0);
6737 tmp
= load_cpu_field(spsr
);
6738 tcg_gen_addi_i32(addr
, addr
, 4);
6739 gen_st32(tmp
, addr
, 0);
6740 if (insn
& (1 << 21)) {
6741 /* Base writeback. */
6743 case 0: offset
= -8; break;
6744 case 1: offset
= 4; break;
6745 case 2: offset
= -4; break;
6746 case 3: offset
= 0; break;
6750 tcg_gen_addi_i32(addr
, addr
, offset
);
6751 tmp
= tcg_const_i32(op1
);
6752 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
6753 tcg_temp_free_i32(tmp
);
6754 tcg_temp_free_i32(addr
);
6756 tcg_temp_free_i32(addr
);
6759 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
6765 rn
= (insn
>> 16) & 0xf;
6766 addr
= load_reg(s
, rn
);
6767 i
= (insn
>> 23) & 3;
6769 case 0: offset
= -4; break; /* DA */
6770 case 1: offset
= 0; break; /* IA */
6771 case 2: offset
= -8; break; /* DB */
6772 case 3: offset
= 4; break; /* IB */
6776 tcg_gen_addi_i32(addr
, addr
, offset
);
6777 /* Load PC into tmp and CPSR into tmp2. */
6778 tmp
= gen_ld32(addr
, 0);
6779 tcg_gen_addi_i32(addr
, addr
, 4);
6780 tmp2
= gen_ld32(addr
, 0);
6781 if (insn
& (1 << 21)) {
6782 /* Base writeback. */
6784 case 0: offset
= -8; break;
6785 case 1: offset
= 4; break;
6786 case 2: offset
= -4; break;
6787 case 3: offset
= 0; break;
6791 tcg_gen_addi_i32(addr
, addr
, offset
);
6792 store_reg(s
, rn
, addr
);
6794 tcg_temp_free_i32(addr
);
6796 gen_rfe(s
, tmp
, tmp2
);
6798 } else if ((insn
& 0x0e000000) == 0x0a000000) {
6799 /* branch link and change to thumb (blx <offset>) */
6802 val
= (uint32_t)s
->pc
;
6803 tmp
= tcg_temp_new_i32();
6804 tcg_gen_movi_i32(tmp
, val
);
6805 store_reg(s
, 14, tmp
);
6806 /* Sign-extend the 24-bit offset */
6807 offset
= (((int32_t)insn
) << 8) >> 8;
6808 /* offset * 4 + bit24 * 2 + (thumb bit) */
6809 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
6810 /* pipeline offset */
6812 /* protected by ARCH(5); above, near the start of uncond block */
6815 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
6816 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6817 /* iWMMXt register transfer. */
6818 if (env
->cp15
.c15_cpar
& (1 << 1))
6819 if (!disas_iwmmxt_insn(env
, s
, insn
))
6822 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
6823 /* Coprocessor double register transfer. */
6825 } else if ((insn
& 0x0f000010) == 0x0e000010) {
6826 /* Additional coprocessor register transfer. */
6827 } else if ((insn
& 0x0ff10020) == 0x01000000) {
6830 /* cps (privileged) */
6834 if (insn
& (1 << 19)) {
6835 if (insn
& (1 << 8))
6837 if (insn
& (1 << 7))
6839 if (insn
& (1 << 6))
6841 if (insn
& (1 << 18))
6844 if (insn
& (1 << 17)) {
6846 val
|= (insn
& 0x1f);
6849 gen_set_psr_im(s
, mask
, 0, val
);
6856 /* if not always execute, we generate a conditional jump to
6858 s
->condlabel
= gen_new_label();
6859 gen_test_cc(cond
^ 1, s
->condlabel
);
6862 if ((insn
& 0x0f900000) == 0x03000000) {
6863 if ((insn
& (1 << 21)) == 0) {
6865 rd
= (insn
>> 12) & 0xf;
6866 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
6867 if ((insn
& (1 << 22)) == 0) {
6869 tmp
= tcg_temp_new_i32();
6870 tcg_gen_movi_i32(tmp
, val
);
6873 tmp
= load_reg(s
, rd
);
6874 tcg_gen_ext16u_i32(tmp
, tmp
);
6875 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
6877 store_reg(s
, rd
, tmp
);
6879 if (((insn
>> 12) & 0xf) != 0xf)
6881 if (((insn
>> 16) & 0xf) == 0) {
6882 gen_nop_hint(s
, insn
& 0xff);
6884 /* CPSR = immediate */
6886 shift
= ((insn
>> 8) & 0xf) * 2;
6888 val
= (val
>> shift
) | (val
<< (32 - shift
));
6889 i
= ((insn
& (1 << 22)) != 0);
6890 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
6894 } else if ((insn
& 0x0f900000) == 0x01000000
6895 && (insn
& 0x00000090) != 0x00000090) {
6896 /* miscellaneous instructions */
6897 op1
= (insn
>> 21) & 3;
6898 sh
= (insn
>> 4) & 0xf;
6901 case 0x0: /* move program status register */
6904 tmp
= load_reg(s
, rm
);
6905 i
= ((op1
& 2) != 0);
6906 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
6910 rd
= (insn
>> 12) & 0xf;
6914 tmp
= load_cpu_field(spsr
);
6916 tmp
= tcg_temp_new_i32();
6917 gen_helper_cpsr_read(tmp
, cpu_env
);
6919 store_reg(s
, rd
, tmp
);
6924 /* branch/exchange thumb (bx). */
6926 tmp
= load_reg(s
, rm
);
6928 } else if (op1
== 3) {
6931 rd
= (insn
>> 12) & 0xf;
6932 tmp
= load_reg(s
, rm
);
6933 gen_helper_clz(tmp
, tmp
);
6934 store_reg(s
, rd
, tmp
);
6942 /* Trivial implementation equivalent to bx. */
6943 tmp
= load_reg(s
, rm
);
6954 /* branch link/exchange thumb (blx) */
6955 tmp
= load_reg(s
, rm
);
6956 tmp2
= tcg_temp_new_i32();
6957 tcg_gen_movi_i32(tmp2
, s
->pc
);
6958 store_reg(s
, 14, tmp2
);
6961 case 0x5: /* saturating add/subtract */
6963 rd
= (insn
>> 12) & 0xf;
6964 rn
= (insn
>> 16) & 0xf;
6965 tmp
= load_reg(s
, rm
);
6966 tmp2
= load_reg(s
, rn
);
6968 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
6970 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6972 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
6973 tcg_temp_free_i32(tmp2
);
6974 store_reg(s
, rd
, tmp
);
6977 /* SMC instruction (op1 == 3)
6978 and undefined instructions (op1 == 0 || op1 == 2)
6985 gen_exception_insn(s
, 4, EXCP_BKPT
);
6987 case 0x8: /* signed multiply */
6992 rs
= (insn
>> 8) & 0xf;
6993 rn
= (insn
>> 12) & 0xf;
6994 rd
= (insn
>> 16) & 0xf;
6996 /* (32 * 16) >> 16 */
6997 tmp
= load_reg(s
, rm
);
6998 tmp2
= load_reg(s
, rs
);
7000 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7003 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7004 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7005 tmp
= tcg_temp_new_i32();
7006 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7007 tcg_temp_free_i64(tmp64
);
7008 if ((sh
& 2) == 0) {
7009 tmp2
= load_reg(s
, rn
);
7010 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7011 tcg_temp_free_i32(tmp2
);
7013 store_reg(s
, rd
, tmp
);
7016 tmp
= load_reg(s
, rm
);
7017 tmp2
= load_reg(s
, rs
);
7018 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7019 tcg_temp_free_i32(tmp2
);
7021 tmp64
= tcg_temp_new_i64();
7022 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7023 tcg_temp_free_i32(tmp
);
7024 gen_addq(s
, tmp64
, rn
, rd
);
7025 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7026 tcg_temp_free_i64(tmp64
);
7029 tmp2
= load_reg(s
, rn
);
7030 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7031 tcg_temp_free_i32(tmp2
);
7033 store_reg(s
, rd
, tmp
);
7040 } else if (((insn
& 0x0e000000) == 0 &&
7041 (insn
& 0x00000090) != 0x90) ||
7042 ((insn
& 0x0e000000) == (1 << 25))) {
7043 int set_cc
, logic_cc
, shiftop
;
7045 op1
= (insn
>> 21) & 0xf;
7046 set_cc
= (insn
>> 20) & 1;
7047 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7049 /* data processing instruction */
7050 if (insn
& (1 << 25)) {
7051 /* immediate operand */
7053 shift
= ((insn
>> 8) & 0xf) * 2;
7055 val
= (val
>> shift
) | (val
<< (32 - shift
));
7057 tmp2
= tcg_temp_new_i32();
7058 tcg_gen_movi_i32(tmp2
, val
);
7059 if (logic_cc
&& shift
) {
7060 gen_set_CF_bit31(tmp2
);
7065 tmp2
= load_reg(s
, rm
);
7066 shiftop
= (insn
>> 5) & 3;
7067 if (!(insn
& (1 << 4))) {
7068 shift
= (insn
>> 7) & 0x1f;
7069 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7071 rs
= (insn
>> 8) & 0xf;
7072 tmp
= load_reg(s
, rs
);
7073 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7076 if (op1
!= 0x0f && op1
!= 0x0d) {
7077 rn
= (insn
>> 16) & 0xf;
7078 tmp
= load_reg(s
, rn
);
7082 rd
= (insn
>> 12) & 0xf;
7085 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7089 store_reg_bx(env
, s
, rd
, tmp
);
7092 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7096 store_reg_bx(env
, s
, rd
, tmp
);
7099 if (set_cc
&& rd
== 15) {
7100 /* SUBS r15, ... is used for exception return. */
7104 gen_sub_CC(tmp
, tmp
, tmp2
);
7105 gen_exception_return(s
, tmp
);
7108 gen_sub_CC(tmp
, tmp
, tmp2
);
7110 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7112 store_reg_bx(env
, s
, rd
, tmp
);
7117 gen_sub_CC(tmp
, tmp2
, tmp
);
7119 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7121 store_reg_bx(env
, s
, rd
, tmp
);
7125 gen_add_CC(tmp
, tmp
, tmp2
);
7127 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7129 store_reg_bx(env
, s
, rd
, tmp
);
7133 gen_adc_CC(tmp
, tmp
, tmp2
);
7135 gen_add_carry(tmp
, tmp
, tmp2
);
7137 store_reg_bx(env
, s
, rd
, tmp
);
7141 gen_sbc_CC(tmp
, tmp
, tmp2
);
7143 gen_sub_carry(tmp
, tmp
, tmp2
);
7145 store_reg_bx(env
, s
, rd
, tmp
);
7149 gen_sbc_CC(tmp
, tmp2
, tmp
);
7151 gen_sub_carry(tmp
, tmp2
, tmp
);
7153 store_reg_bx(env
, s
, rd
, tmp
);
7157 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7160 tcg_temp_free_i32(tmp
);
7164 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7167 tcg_temp_free_i32(tmp
);
7171 gen_sub_CC(tmp
, tmp
, tmp2
);
7173 tcg_temp_free_i32(tmp
);
7177 gen_add_CC(tmp
, tmp
, tmp2
);
7179 tcg_temp_free_i32(tmp
);
7182 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7186 store_reg_bx(env
, s
, rd
, tmp
);
7189 if (logic_cc
&& rd
== 15) {
7190 /* MOVS r15, ... is used for exception return. */
7194 gen_exception_return(s
, tmp2
);
7199 store_reg_bx(env
, s
, rd
, tmp2
);
7203 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7207 store_reg_bx(env
, s
, rd
, tmp
);
7211 tcg_gen_not_i32(tmp2
, tmp2
);
7215 store_reg_bx(env
, s
, rd
, tmp2
);
7218 if (op1
!= 0x0f && op1
!= 0x0d) {
7219 tcg_temp_free_i32(tmp2
);
7222 /* other instructions */
7223 op1
= (insn
>> 24) & 0xf;
7227 /* multiplies, extra load/stores */
7228 sh
= (insn
>> 5) & 3;
7231 rd
= (insn
>> 16) & 0xf;
7232 rn
= (insn
>> 12) & 0xf;
7233 rs
= (insn
>> 8) & 0xf;
7235 op1
= (insn
>> 20) & 0xf;
7237 case 0: case 1: case 2: case 3: case 6:
7239 tmp
= load_reg(s
, rs
);
7240 tmp2
= load_reg(s
, rm
);
7241 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7242 tcg_temp_free_i32(tmp2
);
7243 if (insn
& (1 << 22)) {
7244 /* Subtract (mls) */
7246 tmp2
= load_reg(s
, rn
);
7247 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7248 tcg_temp_free_i32(tmp2
);
7249 } else if (insn
& (1 << 21)) {
7251 tmp2
= load_reg(s
, rn
);
7252 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7253 tcg_temp_free_i32(tmp2
);
7255 if (insn
& (1 << 20))
7257 store_reg(s
, rd
, tmp
);
7260 /* 64 bit mul double accumulate (UMAAL) */
7262 tmp
= load_reg(s
, rs
);
7263 tmp2
= load_reg(s
, rm
);
7264 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7265 gen_addq_lo(s
, tmp64
, rn
);
7266 gen_addq_lo(s
, tmp64
, rd
);
7267 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7268 tcg_temp_free_i64(tmp64
);
7270 case 8: case 9: case 10: case 11:
7271 case 12: case 13: case 14: case 15:
7272 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7273 tmp
= load_reg(s
, rs
);
7274 tmp2
= load_reg(s
, rm
);
7275 if (insn
& (1 << 22)) {
7276 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
7278 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
7280 if (insn
& (1 << 21)) { /* mult accumulate */
7281 TCGv al
= load_reg(s
, rn
);
7282 TCGv ah
= load_reg(s
, rd
);
7283 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
7287 if (insn
& (1 << 20)) {
7288 gen_logicq_cc(tmp
, tmp2
);
7290 store_reg(s
, rn
, tmp
);
7291 store_reg(s
, rd
, tmp2
);
7297 rn
= (insn
>> 16) & 0xf;
7298 rd
= (insn
>> 12) & 0xf;
7299 if (insn
& (1 << 23)) {
7300 /* load/store exclusive */
7301 op1
= (insn
>> 21) & 0x3;
7306 addr
= tcg_temp_local_new_i32();
7307 load_reg_var(s
, addr
, rn
);
7308 if (insn
& (1 << 20)) {
7311 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7313 case 1: /* ldrexd */
7314 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7316 case 2: /* ldrexb */
7317 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7319 case 3: /* ldrexh */
7320 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7329 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7331 case 1: /* strexd */
7332 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7334 case 2: /* strexb */
7335 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7337 case 3: /* strexh */
7338 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7344 tcg_temp_free(addr
);
7346 /* SWP instruction */
7349 /* ??? This is not really atomic. However we know
7350 we never have multiple CPUs running in parallel,
7351 so it is good enough. */
7352 addr
= load_reg(s
, rn
);
7353 tmp
= load_reg(s
, rm
);
7354 if (insn
& (1 << 22)) {
7355 tmp2
= gen_ld8u(addr
, IS_USER(s
));
7356 gen_st8(tmp
, addr
, IS_USER(s
));
7358 tmp2
= gen_ld32(addr
, IS_USER(s
));
7359 gen_st32(tmp
, addr
, IS_USER(s
));
7361 tcg_temp_free_i32(addr
);
7362 store_reg(s
, rd
, tmp2
);
7368 /* Misc load/store */
7369 rn
= (insn
>> 16) & 0xf;
7370 rd
= (insn
>> 12) & 0xf;
7371 addr
= load_reg(s
, rn
);
7372 if (insn
& (1 << 24))
7373 gen_add_datah_offset(s
, insn
, 0, addr
);
7375 if (insn
& (1 << 20)) {
7379 tmp
= gen_ld16u(addr
, IS_USER(s
));
7382 tmp
= gen_ld8s(addr
, IS_USER(s
));
7386 tmp
= gen_ld16s(addr
, IS_USER(s
));
7390 } else if (sh
& 2) {
7395 tmp
= load_reg(s
, rd
);
7396 gen_st32(tmp
, addr
, IS_USER(s
));
7397 tcg_gen_addi_i32(addr
, addr
, 4);
7398 tmp
= load_reg(s
, rd
+ 1);
7399 gen_st32(tmp
, addr
, IS_USER(s
));
7403 tmp
= gen_ld32(addr
, IS_USER(s
));
7404 store_reg(s
, rd
, tmp
);
7405 tcg_gen_addi_i32(addr
, addr
, 4);
7406 tmp
= gen_ld32(addr
, IS_USER(s
));
7410 address_offset
= -4;
7413 tmp
= load_reg(s
, rd
);
7414 gen_st16(tmp
, addr
, IS_USER(s
));
7417 /* Perform base writeback before the loaded value to
7418 ensure correct behavior with overlapping index registers.
7419 ldrd with base writeback is is undefined if the
7420 destination and index registers overlap. */
7421 if (!(insn
& (1 << 24))) {
7422 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
7423 store_reg(s
, rn
, addr
);
7424 } else if (insn
& (1 << 21)) {
7426 tcg_gen_addi_i32(addr
, addr
, address_offset
);
7427 store_reg(s
, rn
, addr
);
7429 tcg_temp_free_i32(addr
);
7432 /* Complete the load. */
7433 store_reg(s
, rd
, tmp
);
7442 if (insn
& (1 << 4)) {
7444 /* Armv6 Media instructions. */
7446 rn
= (insn
>> 16) & 0xf;
7447 rd
= (insn
>> 12) & 0xf;
7448 rs
= (insn
>> 8) & 0xf;
7449 switch ((insn
>> 23) & 3) {
7450 case 0: /* Parallel add/subtract. */
7451 op1
= (insn
>> 20) & 7;
7452 tmp
= load_reg(s
, rn
);
7453 tmp2
= load_reg(s
, rm
);
7454 sh
= (insn
>> 5) & 7;
7455 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
7457 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
7458 tcg_temp_free_i32(tmp2
);
7459 store_reg(s
, rd
, tmp
);
7462 if ((insn
& 0x00700020) == 0) {
7463 /* Halfword pack. */
7464 tmp
= load_reg(s
, rn
);
7465 tmp2
= load_reg(s
, rm
);
7466 shift
= (insn
>> 7) & 0x1f;
7467 if (insn
& (1 << 6)) {
7471 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
7472 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
7473 tcg_gen_ext16u_i32(tmp2
, tmp2
);
7477 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
7478 tcg_gen_ext16u_i32(tmp
, tmp
);
7479 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
7481 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7482 tcg_temp_free_i32(tmp2
);
7483 store_reg(s
, rd
, tmp
);
7484 } else if ((insn
& 0x00200020) == 0x00200000) {
7486 tmp
= load_reg(s
, rm
);
7487 shift
= (insn
>> 7) & 0x1f;
7488 if (insn
& (1 << 6)) {
7491 tcg_gen_sari_i32(tmp
, tmp
, shift
);
7493 tcg_gen_shli_i32(tmp
, tmp
, shift
);
7495 sh
= (insn
>> 16) & 0x1f;
7496 tmp2
= tcg_const_i32(sh
);
7497 if (insn
& (1 << 22))
7498 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
7500 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
7501 tcg_temp_free_i32(tmp2
);
7502 store_reg(s
, rd
, tmp
);
7503 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
7505 tmp
= load_reg(s
, rm
);
7506 sh
= (insn
>> 16) & 0x1f;
7507 tmp2
= tcg_const_i32(sh
);
7508 if (insn
& (1 << 22))
7509 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
7511 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
7512 tcg_temp_free_i32(tmp2
);
7513 store_reg(s
, rd
, tmp
);
7514 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
7516 tmp
= load_reg(s
, rn
);
7517 tmp2
= load_reg(s
, rm
);
7518 tmp3
= tcg_temp_new_i32();
7519 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
7520 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
7521 tcg_temp_free_i32(tmp3
);
7522 tcg_temp_free_i32(tmp2
);
7523 store_reg(s
, rd
, tmp
);
7524 } else if ((insn
& 0x000003e0) == 0x00000060) {
7525 tmp
= load_reg(s
, rm
);
7526 shift
= (insn
>> 10) & 3;
7527 /* ??? In many cases it's not necessary to do a
7528 rotate, a shift is sufficient. */
7530 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
7531 op1
= (insn
>> 20) & 7;
7533 case 0: gen_sxtb16(tmp
); break;
7534 case 2: gen_sxtb(tmp
); break;
7535 case 3: gen_sxth(tmp
); break;
7536 case 4: gen_uxtb16(tmp
); break;
7537 case 6: gen_uxtb(tmp
); break;
7538 case 7: gen_uxth(tmp
); break;
7539 default: goto illegal_op
;
7542 tmp2
= load_reg(s
, rn
);
7543 if ((op1
& 3) == 0) {
7544 gen_add16(tmp
, tmp2
);
7546 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7547 tcg_temp_free_i32(tmp2
);
7550 store_reg(s
, rd
, tmp
);
7551 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
7553 tmp
= load_reg(s
, rm
);
7554 if (insn
& (1 << 22)) {
7555 if (insn
& (1 << 7)) {
7559 gen_helper_rbit(tmp
, tmp
);
7562 if (insn
& (1 << 7))
7565 tcg_gen_bswap32_i32(tmp
, tmp
);
7567 store_reg(s
, rd
, tmp
);
7572 case 2: /* Multiplies (Type 3). */
7573 switch ((insn
>> 20) & 0x7) {
7575 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
7576 /* op2 not 00x or 11x : UNDEF */
7579 /* Signed multiply most significant [accumulate].
7580 (SMMUL, SMMLA, SMMLS) */
7581 tmp
= load_reg(s
, rm
);
7582 tmp2
= load_reg(s
, rs
);
7583 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7586 tmp
= load_reg(s
, rd
);
7587 if (insn
& (1 << 6)) {
7588 tmp64
= gen_subq_msw(tmp64
, tmp
);
7590 tmp64
= gen_addq_msw(tmp64
, tmp
);
7593 if (insn
& (1 << 5)) {
7594 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
7596 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7597 tmp
= tcg_temp_new_i32();
7598 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7599 tcg_temp_free_i64(tmp64
);
7600 store_reg(s
, rn
, tmp
);
7604 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7605 if (insn
& (1 << 7)) {
7608 tmp
= load_reg(s
, rm
);
7609 tmp2
= load_reg(s
, rs
);
7610 if (insn
& (1 << 5))
7611 gen_swap_half(tmp2
);
7612 gen_smul_dual(tmp
, tmp2
);
7613 if (insn
& (1 << 6)) {
7614 /* This subtraction cannot overflow. */
7615 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7617 /* This addition cannot overflow 32 bits;
7618 * however it may overflow considered as a signed
7619 * operation, in which case we must set the Q flag.
7621 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7623 tcg_temp_free_i32(tmp2
);
7624 if (insn
& (1 << 22)) {
7625 /* smlald, smlsld */
7626 tmp64
= tcg_temp_new_i64();
7627 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7628 tcg_temp_free_i32(tmp
);
7629 gen_addq(s
, tmp64
, rd
, rn
);
7630 gen_storeq_reg(s
, rd
, rn
, tmp64
);
7631 tcg_temp_free_i64(tmp64
);
7633 /* smuad, smusd, smlad, smlsd */
7636 tmp2
= load_reg(s
, rd
);
7637 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7638 tcg_temp_free_i32(tmp2
);
7640 store_reg(s
, rn
, tmp
);
7646 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
7649 if (((insn
>> 5) & 7) || (rd
!= 15)) {
7652 tmp
= load_reg(s
, rm
);
7653 tmp2
= load_reg(s
, rs
);
7654 if (insn
& (1 << 21)) {
7655 gen_helper_udiv(tmp
, tmp
, tmp2
);
7657 gen_helper_sdiv(tmp
, tmp
, tmp2
);
7659 tcg_temp_free_i32(tmp2
);
7660 store_reg(s
, rn
, tmp
);
7667 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
7669 case 0: /* Unsigned sum of absolute differences. */
7671 tmp
= load_reg(s
, rm
);
7672 tmp2
= load_reg(s
, rs
);
7673 gen_helper_usad8(tmp
, tmp
, tmp2
);
7674 tcg_temp_free_i32(tmp2
);
7676 tmp2
= load_reg(s
, rd
);
7677 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7678 tcg_temp_free_i32(tmp2
);
7680 store_reg(s
, rn
, tmp
);
7682 case 0x20: case 0x24: case 0x28: case 0x2c:
7683 /* Bitfield insert/clear. */
7685 shift
= (insn
>> 7) & 0x1f;
7686 i
= (insn
>> 16) & 0x1f;
7689 tmp
= tcg_temp_new_i32();
7690 tcg_gen_movi_i32(tmp
, 0);
7692 tmp
= load_reg(s
, rm
);
7695 tmp2
= load_reg(s
, rd
);
7696 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
7697 tcg_temp_free_i32(tmp2
);
7699 store_reg(s
, rd
, tmp
);
7701 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7702 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7704 tmp
= load_reg(s
, rm
);
7705 shift
= (insn
>> 7) & 0x1f;
7706 i
= ((insn
>> 16) & 0x1f) + 1;
7711 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
7713 gen_sbfx(tmp
, shift
, i
);
7716 store_reg(s
, rd
, tmp
);
7726 /* Check for undefined extension instructions
7727 * per the ARM Bible IE:
7728 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7730 sh
= (0xf << 20) | (0xf << 4);
7731 if (op1
== 0x7 && ((insn
& sh
) == sh
))
7735 /* load/store byte/word */
7736 rn
= (insn
>> 16) & 0xf;
7737 rd
= (insn
>> 12) & 0xf;
7738 tmp2
= load_reg(s
, rn
);
7739 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
7740 if (insn
& (1 << 24))
7741 gen_add_data_offset(s
, insn
, tmp2
);
7742 if (insn
& (1 << 20)) {
7744 if (insn
& (1 << 22)) {
7745 tmp
= gen_ld8u(tmp2
, i
);
7747 tmp
= gen_ld32(tmp2
, i
);
7751 tmp
= load_reg(s
, rd
);
7752 if (insn
& (1 << 22))
7753 gen_st8(tmp
, tmp2
, i
);
7755 gen_st32(tmp
, tmp2
, i
);
7757 if (!(insn
& (1 << 24))) {
7758 gen_add_data_offset(s
, insn
, tmp2
);
7759 store_reg(s
, rn
, tmp2
);
7760 } else if (insn
& (1 << 21)) {
7761 store_reg(s
, rn
, tmp2
);
7763 tcg_temp_free_i32(tmp2
);
7765 if (insn
& (1 << 20)) {
7766 /* Complete the load. */
7767 store_reg_from_load(env
, s
, rd
, tmp
);
7773 int j
, n
, user
, loaded_base
;
7775 /* load/store multiple words */
7776 /* XXX: store correct base if write back */
7778 if (insn
& (1 << 22)) {
7780 goto illegal_op
; /* only usable in supervisor mode */
7782 if ((insn
& (1 << 15)) == 0)
7785 rn
= (insn
>> 16) & 0xf;
7786 addr
= load_reg(s
, rn
);
7788 /* compute total size */
7790 TCGV_UNUSED(loaded_var
);
7793 if (insn
& (1 << i
))
7796 /* XXX: test invalid n == 0 case ? */
7797 if (insn
& (1 << 23)) {
7798 if (insn
& (1 << 24)) {
7800 tcg_gen_addi_i32(addr
, addr
, 4);
7802 /* post increment */
7805 if (insn
& (1 << 24)) {
7807 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7809 /* post decrement */
7811 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7816 if (insn
& (1 << i
)) {
7817 if (insn
& (1 << 20)) {
7819 tmp
= gen_ld32(addr
, IS_USER(s
));
7821 tmp2
= tcg_const_i32(i
);
7822 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
7823 tcg_temp_free_i32(tmp2
);
7824 tcg_temp_free_i32(tmp
);
7825 } else if (i
== rn
) {
7829 store_reg_from_load(env
, s
, i
, tmp
);
7834 /* special case: r15 = PC + 8 */
7835 val
= (long)s
->pc
+ 4;
7836 tmp
= tcg_temp_new_i32();
7837 tcg_gen_movi_i32(tmp
, val
);
7839 tmp
= tcg_temp_new_i32();
7840 tmp2
= tcg_const_i32(i
);
7841 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
7842 tcg_temp_free_i32(tmp2
);
7844 tmp
= load_reg(s
, i
);
7846 gen_st32(tmp
, addr
, IS_USER(s
));
7849 /* no need to add after the last transfer */
7851 tcg_gen_addi_i32(addr
, addr
, 4);
7854 if (insn
& (1 << 21)) {
7856 if (insn
& (1 << 23)) {
7857 if (insn
& (1 << 24)) {
7860 /* post increment */
7861 tcg_gen_addi_i32(addr
, addr
, 4);
7864 if (insn
& (1 << 24)) {
7867 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
7869 /* post decrement */
7870 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
7873 store_reg(s
, rn
, addr
);
7875 tcg_temp_free_i32(addr
);
7878 store_reg(s
, rn
, loaded_var
);
7880 if ((insn
& (1 << 22)) && !user
) {
7881 /* Restore CPSR from SPSR. */
7882 tmp
= load_cpu_field(spsr
);
7883 gen_set_cpsr(tmp
, 0xffffffff);
7884 tcg_temp_free_i32(tmp
);
7885 s
->is_jmp
= DISAS_UPDATE
;
7894 /* branch (and link) */
7895 val
= (int32_t)s
->pc
;
7896 if (insn
& (1 << 24)) {
7897 tmp
= tcg_temp_new_i32();
7898 tcg_gen_movi_i32(tmp
, val
);
7899 store_reg(s
, 14, tmp
);
7901 offset
= (((int32_t)insn
<< 8) >> 8);
7902 val
+= (offset
<< 2) + 4;
7910 if (disas_coproc_insn(env
, s
, insn
))
7915 gen_set_pc_im(s
->pc
);
7916 s
->is_jmp
= DISAS_SWI
;
7920 gen_exception_insn(s
, 4, EXCP_UDEF
);
7926 /* Return true if this is a Thumb-2 logical op. */
7928 thumb2_logic_op(int op
)
7933 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7934 then set condition code flags based on the result of the operation.
7935 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7936 to the high bit of T1.
7937 Returns zero if the opcode is valid. */
7940 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
, TCGv t0
, TCGv t1
)
7947 tcg_gen_and_i32(t0
, t0
, t1
);
7951 tcg_gen_andc_i32(t0
, t0
, t1
);
7955 tcg_gen_or_i32(t0
, t0
, t1
);
7959 tcg_gen_orc_i32(t0
, t0
, t1
);
7963 tcg_gen_xor_i32(t0
, t0
, t1
);
7968 gen_add_CC(t0
, t0
, t1
);
7970 tcg_gen_add_i32(t0
, t0
, t1
);
7974 gen_adc_CC(t0
, t0
, t1
);
7980 gen_sbc_CC(t0
, t0
, t1
);
7982 gen_sub_carry(t0
, t0
, t1
);
7987 gen_sub_CC(t0
, t0
, t1
);
7989 tcg_gen_sub_i32(t0
, t0
, t1
);
7993 gen_sub_CC(t0
, t1
, t0
);
7995 tcg_gen_sub_i32(t0
, t1
, t0
);
7997 default: /* 5, 6, 7, 9, 12, 15. */
8003 gen_set_CF_bit31(t1
);
8008 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8010 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8012 uint32_t insn
, imm
, shift
, offset
;
8013 uint32_t rd
, rn
, rm
, rs
;
8024 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8025 || arm_feature (env
, ARM_FEATURE_M
))) {
8026 /* Thumb-1 cores may need to treat bl and blx as a pair of
8027 16-bit instructions to get correct prefetch abort behavior. */
8029 if ((insn
& (1 << 12)) == 0) {
8031 /* Second half of blx. */
8032 offset
= ((insn
& 0x7ff) << 1);
8033 tmp
= load_reg(s
, 14);
8034 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8035 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8037 tmp2
= tcg_temp_new_i32();
8038 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8039 store_reg(s
, 14, tmp2
);
8043 if (insn
& (1 << 11)) {
8044 /* Second half of bl. */
8045 offset
= ((insn
& 0x7ff) << 1) | 1;
8046 tmp
= load_reg(s
, 14);
8047 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8049 tmp2
= tcg_temp_new_i32();
8050 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8051 store_reg(s
, 14, tmp2
);
8055 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
8056 /* Instruction spans a page boundary. Implement it as two
8057 16-bit instructions in case the second half causes an
8059 offset
= ((int32_t)insn
<< 21) >> 9;
8060 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8063 /* Fall through to 32-bit decode. */
8066 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8068 insn
|= (uint32_t)insn_hw1
<< 16;
8070 if ((insn
& 0xf800e800) != 0xf000e800) {
8074 rn
= (insn
>> 16) & 0xf;
8075 rs
= (insn
>> 12) & 0xf;
8076 rd
= (insn
>> 8) & 0xf;
8078 switch ((insn
>> 25) & 0xf) {
8079 case 0: case 1: case 2: case 3:
8080 /* 16-bit instructions. Should never happen. */
8083 if (insn
& (1 << 22)) {
8084 /* Other load/store, table branch. */
8085 if (insn
& 0x01200000) {
8086 /* Load/store doubleword. */
8088 addr
= tcg_temp_new_i32();
8089 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8091 addr
= load_reg(s
, rn
);
8093 offset
= (insn
& 0xff) * 4;
8094 if ((insn
& (1 << 23)) == 0)
8096 if (insn
& (1 << 24)) {
8097 tcg_gen_addi_i32(addr
, addr
, offset
);
8100 if (insn
& (1 << 20)) {
8102 tmp
= gen_ld32(addr
, IS_USER(s
));
8103 store_reg(s
, rs
, tmp
);
8104 tcg_gen_addi_i32(addr
, addr
, 4);
8105 tmp
= gen_ld32(addr
, IS_USER(s
));
8106 store_reg(s
, rd
, tmp
);
8109 tmp
= load_reg(s
, rs
);
8110 gen_st32(tmp
, addr
, IS_USER(s
));
8111 tcg_gen_addi_i32(addr
, addr
, 4);
8112 tmp
= load_reg(s
, rd
);
8113 gen_st32(tmp
, addr
, IS_USER(s
));
8115 if (insn
& (1 << 21)) {
8116 /* Base writeback. */
8119 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8120 store_reg(s
, rn
, addr
);
8122 tcg_temp_free_i32(addr
);
8124 } else if ((insn
& (1 << 23)) == 0) {
8125 /* Load/store exclusive word. */
8126 addr
= tcg_temp_local_new();
8127 load_reg_var(s
, addr
, rn
);
8128 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8129 if (insn
& (1 << 20)) {
8130 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8132 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8134 tcg_temp_free(addr
);
8135 } else if ((insn
& (1 << 6)) == 0) {
8138 addr
= tcg_temp_new_i32();
8139 tcg_gen_movi_i32(addr
, s
->pc
);
8141 addr
= load_reg(s
, rn
);
8143 tmp
= load_reg(s
, rm
);
8144 tcg_gen_add_i32(addr
, addr
, tmp
);
8145 if (insn
& (1 << 4)) {
8147 tcg_gen_add_i32(addr
, addr
, tmp
);
8148 tcg_temp_free_i32(tmp
);
8149 tmp
= gen_ld16u(addr
, IS_USER(s
));
8151 tcg_temp_free_i32(tmp
);
8152 tmp
= gen_ld8u(addr
, IS_USER(s
));
8154 tcg_temp_free_i32(addr
);
8155 tcg_gen_shli_i32(tmp
, tmp
, 1);
8156 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8157 store_reg(s
, 15, tmp
);
8159 /* Load/store exclusive byte/halfword/doubleword. */
8161 op
= (insn
>> 4) & 0x3;
8165 addr
= tcg_temp_local_new();
8166 load_reg_var(s
, addr
, rn
);
8167 if (insn
& (1 << 20)) {
8168 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8170 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8172 tcg_temp_free(addr
);
8175 /* Load/store multiple, RFE, SRS. */
8176 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8177 /* Not available in user mode. */
8180 if (insn
& (1 << 20)) {
8182 addr
= load_reg(s
, rn
);
8183 if ((insn
& (1 << 24)) == 0)
8184 tcg_gen_addi_i32(addr
, addr
, -8);
8185 /* Load PC into tmp and CPSR into tmp2. */
8186 tmp
= gen_ld32(addr
, 0);
8187 tcg_gen_addi_i32(addr
, addr
, 4);
8188 tmp2
= gen_ld32(addr
, 0);
8189 if (insn
& (1 << 21)) {
8190 /* Base writeback. */
8191 if (insn
& (1 << 24)) {
8192 tcg_gen_addi_i32(addr
, addr
, 4);
8194 tcg_gen_addi_i32(addr
, addr
, -4);
8196 store_reg(s
, rn
, addr
);
8198 tcg_temp_free_i32(addr
);
8200 gen_rfe(s
, tmp
, tmp2
);
8204 addr
= tcg_temp_new_i32();
8205 tmp
= tcg_const_i32(op
);
8206 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
8207 tcg_temp_free_i32(tmp
);
8208 if ((insn
& (1 << 24)) == 0) {
8209 tcg_gen_addi_i32(addr
, addr
, -8);
8211 tmp
= load_reg(s
, 14);
8212 gen_st32(tmp
, addr
, 0);
8213 tcg_gen_addi_i32(addr
, addr
, 4);
8214 tmp
= tcg_temp_new_i32();
8215 gen_helper_cpsr_read(tmp
, cpu_env
);
8216 gen_st32(tmp
, addr
, 0);
8217 if (insn
& (1 << 21)) {
8218 if ((insn
& (1 << 24)) == 0) {
8219 tcg_gen_addi_i32(addr
, addr
, -4);
8221 tcg_gen_addi_i32(addr
, addr
, 4);
8223 tmp
= tcg_const_i32(op
);
8224 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
8225 tcg_temp_free_i32(tmp
);
8227 tcg_temp_free_i32(addr
);
8231 int i
, loaded_base
= 0;
8233 /* Load/store multiple. */
8234 addr
= load_reg(s
, rn
);
8236 for (i
= 0; i
< 16; i
++) {
8237 if (insn
& (1 << i
))
8240 if (insn
& (1 << 24)) {
8241 tcg_gen_addi_i32(addr
, addr
, -offset
);
8244 TCGV_UNUSED(loaded_var
);
8245 for (i
= 0; i
< 16; i
++) {
8246 if ((insn
& (1 << i
)) == 0)
8248 if (insn
& (1 << 20)) {
8250 tmp
= gen_ld32(addr
, IS_USER(s
));
8253 } else if (i
== rn
) {
8257 store_reg(s
, i
, tmp
);
8261 tmp
= load_reg(s
, i
);
8262 gen_st32(tmp
, addr
, IS_USER(s
));
8264 tcg_gen_addi_i32(addr
, addr
, 4);
8267 store_reg(s
, rn
, loaded_var
);
8269 if (insn
& (1 << 21)) {
8270 /* Base register writeback. */
8271 if (insn
& (1 << 24)) {
8272 tcg_gen_addi_i32(addr
, addr
, -offset
);
8274 /* Fault if writeback register is in register list. */
8275 if (insn
& (1 << rn
))
8277 store_reg(s
, rn
, addr
);
8279 tcg_temp_free_i32(addr
);
8286 op
= (insn
>> 21) & 0xf;
8288 /* Halfword pack. */
8289 tmp
= load_reg(s
, rn
);
8290 tmp2
= load_reg(s
, rm
);
8291 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8292 if (insn
& (1 << 5)) {
8296 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8297 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8298 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8302 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8303 tcg_gen_ext16u_i32(tmp
, tmp
);
8304 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8306 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8307 tcg_temp_free_i32(tmp2
);
8308 store_reg(s
, rd
, tmp
);
8310 /* Data processing register constant shift. */
8312 tmp
= tcg_temp_new_i32();
8313 tcg_gen_movi_i32(tmp
, 0);
8315 tmp
= load_reg(s
, rn
);
8317 tmp2
= load_reg(s
, rm
);
8319 shiftop
= (insn
>> 4) & 3;
8320 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8321 conds
= (insn
& (1 << 20)) != 0;
8322 logic_cc
= (conds
&& thumb2_logic_op(op
));
8323 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8324 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8326 tcg_temp_free_i32(tmp2
);
8328 store_reg(s
, rd
, tmp
);
8330 tcg_temp_free_i32(tmp
);
8334 case 13: /* Misc data processing. */
8335 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8336 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8339 case 0: /* Register controlled shift. */
8340 tmp
= load_reg(s
, rn
);
8341 tmp2
= load_reg(s
, rm
);
8342 if ((insn
& 0x70) != 0)
8344 op
= (insn
>> 21) & 3;
8345 logic_cc
= (insn
& (1 << 20)) != 0;
8346 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
8349 store_reg_bx(env
, s
, rd
, tmp
);
8351 case 1: /* Sign/zero extend. */
8352 tmp
= load_reg(s
, rm
);
8353 shift
= (insn
>> 4) & 3;
8354 /* ??? In many cases it's not necessary to do a
8355 rotate, a shift is sufficient. */
8357 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8358 op
= (insn
>> 20) & 7;
8360 case 0: gen_sxth(tmp
); break;
8361 case 1: gen_uxth(tmp
); break;
8362 case 2: gen_sxtb16(tmp
); break;
8363 case 3: gen_uxtb16(tmp
); break;
8364 case 4: gen_sxtb(tmp
); break;
8365 case 5: gen_uxtb(tmp
); break;
8366 default: goto illegal_op
;
8369 tmp2
= load_reg(s
, rn
);
8370 if ((op
>> 1) == 1) {
8371 gen_add16(tmp
, tmp2
);
8373 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8374 tcg_temp_free_i32(tmp2
);
8377 store_reg(s
, rd
, tmp
);
8379 case 2: /* SIMD add/subtract. */
8380 op
= (insn
>> 20) & 7;
8381 shift
= (insn
>> 4) & 7;
8382 if ((op
& 3) == 3 || (shift
& 3) == 3)
8384 tmp
= load_reg(s
, rn
);
8385 tmp2
= load_reg(s
, rm
);
8386 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
8387 tcg_temp_free_i32(tmp2
);
8388 store_reg(s
, rd
, tmp
);
8390 case 3: /* Other data processing. */
8391 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
8393 /* Saturating add/subtract. */
8394 tmp
= load_reg(s
, rn
);
8395 tmp2
= load_reg(s
, rm
);
8397 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
8399 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
8401 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8402 tcg_temp_free_i32(tmp2
);
8404 tmp
= load_reg(s
, rn
);
8406 case 0x0a: /* rbit */
8407 gen_helper_rbit(tmp
, tmp
);
8409 case 0x08: /* rev */
8410 tcg_gen_bswap32_i32(tmp
, tmp
);
8412 case 0x09: /* rev16 */
8415 case 0x0b: /* revsh */
8418 case 0x10: /* sel */
8419 tmp2
= load_reg(s
, rm
);
8420 tmp3
= tcg_temp_new_i32();
8421 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8422 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8423 tcg_temp_free_i32(tmp3
);
8424 tcg_temp_free_i32(tmp2
);
8426 case 0x18: /* clz */
8427 gen_helper_clz(tmp
, tmp
);
8433 store_reg(s
, rd
, tmp
);
8435 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8436 op
= (insn
>> 4) & 0xf;
8437 tmp
= load_reg(s
, rn
);
8438 tmp2
= load_reg(s
, rm
);
8439 switch ((insn
>> 20) & 7) {
8440 case 0: /* 32 x 32 -> 32 */
8441 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8442 tcg_temp_free_i32(tmp2
);
8444 tmp2
= load_reg(s
, rs
);
8446 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8448 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8449 tcg_temp_free_i32(tmp2
);
8452 case 1: /* 16 x 16 -> 32 */
8453 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8454 tcg_temp_free_i32(tmp2
);
8456 tmp2
= load_reg(s
, rs
);
8457 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8458 tcg_temp_free_i32(tmp2
);
8461 case 2: /* Dual multiply add. */
8462 case 4: /* Dual multiply subtract. */
8464 gen_swap_half(tmp2
);
8465 gen_smul_dual(tmp
, tmp2
);
8466 if (insn
& (1 << 22)) {
8467 /* This subtraction cannot overflow. */
8468 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8470 /* This addition cannot overflow 32 bits;
8471 * however it may overflow considered as a signed
8472 * operation, in which case we must set the Q flag.
8474 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8476 tcg_temp_free_i32(tmp2
);
8479 tmp2
= load_reg(s
, rs
);
8480 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8481 tcg_temp_free_i32(tmp2
);
8484 case 3: /* 32 * 16 -> 32msb */
8486 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8489 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8490 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8491 tmp
= tcg_temp_new_i32();
8492 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8493 tcg_temp_free_i64(tmp64
);
8496 tmp2
= load_reg(s
, rs
);
8497 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8498 tcg_temp_free_i32(tmp2
);
8501 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8502 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8504 tmp
= load_reg(s
, rs
);
8505 if (insn
& (1 << 20)) {
8506 tmp64
= gen_addq_msw(tmp64
, tmp
);
8508 tmp64
= gen_subq_msw(tmp64
, tmp
);
8511 if (insn
& (1 << 4)) {
8512 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8514 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8515 tmp
= tcg_temp_new_i32();
8516 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8517 tcg_temp_free_i64(tmp64
);
8519 case 7: /* Unsigned sum of absolute differences. */
8520 gen_helper_usad8(tmp
, tmp
, tmp2
);
8521 tcg_temp_free_i32(tmp2
);
8523 tmp2
= load_reg(s
, rs
);
8524 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8525 tcg_temp_free_i32(tmp2
);
8529 store_reg(s
, rd
, tmp
);
8531 case 6: case 7: /* 64-bit multiply, Divide. */
8532 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
8533 tmp
= load_reg(s
, rn
);
8534 tmp2
= load_reg(s
, rm
);
8535 if ((op
& 0x50) == 0x10) {
8537 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
8541 gen_helper_udiv(tmp
, tmp
, tmp2
);
8543 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8544 tcg_temp_free_i32(tmp2
);
8545 store_reg(s
, rd
, tmp
);
8546 } else if ((op
& 0xe) == 0xc) {
8547 /* Dual multiply accumulate long. */
8549 gen_swap_half(tmp2
);
8550 gen_smul_dual(tmp
, tmp2
);
8552 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8554 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8556 tcg_temp_free_i32(tmp2
);
8558 tmp64
= tcg_temp_new_i64();
8559 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8560 tcg_temp_free_i32(tmp
);
8561 gen_addq(s
, tmp64
, rs
, rd
);
8562 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8563 tcg_temp_free_i64(tmp64
);
8566 /* Unsigned 64-bit multiply */
8567 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8571 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
8572 tcg_temp_free_i32(tmp2
);
8573 tmp64
= tcg_temp_new_i64();
8574 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8575 tcg_temp_free_i32(tmp
);
8577 /* Signed 64-bit multiply */
8578 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8583 gen_addq_lo(s
, tmp64
, rs
);
8584 gen_addq_lo(s
, tmp64
, rd
);
8585 } else if (op
& 0x40) {
8586 /* 64-bit accumulate. */
8587 gen_addq(s
, tmp64
, rs
, rd
);
8589 gen_storeq_reg(s
, rs
, rd
, tmp64
);
8590 tcg_temp_free_i64(tmp64
);
8595 case 6: case 7: case 14: case 15:
8597 if (((insn
>> 24) & 3) == 3) {
8598 /* Translate into the equivalent ARM encoding. */
8599 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
8600 if (disas_neon_data_insn(env
, s
, insn
))
8603 if (insn
& (1 << 28))
8605 if (disas_coproc_insn (env
, s
, insn
))
8609 case 8: case 9: case 10: case 11:
8610 if (insn
& (1 << 15)) {
8611 /* Branches, misc control. */
8612 if (insn
& 0x5000) {
8613 /* Unconditional branch. */
8614 /* signextend(hw1[10:0]) -> offset[:12]. */
8615 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
8616 /* hw1[10:0] -> offset[11:1]. */
8617 offset
|= (insn
& 0x7ff) << 1;
8618 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8619 offset[24:22] already have the same value because of the
8620 sign extension above. */
8621 offset
^= ((~insn
) & (1 << 13)) << 10;
8622 offset
^= ((~insn
) & (1 << 11)) << 11;
8624 if (insn
& (1 << 14)) {
8625 /* Branch and link. */
8626 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
8630 if (insn
& (1 << 12)) {
8635 offset
&= ~(uint32_t)2;
8636 /* thumb2 bx, no need to check */
8637 gen_bx_im(s
, offset
);
8639 } else if (((insn
>> 23) & 7) == 7) {
8641 if (insn
& (1 << 13))
8644 if (insn
& (1 << 26)) {
8645 /* Secure monitor call (v6Z) */
8646 goto illegal_op
; /* not implemented. */
8648 op
= (insn
>> 20) & 7;
8650 case 0: /* msr cpsr. */
8652 tmp
= load_reg(s
, rn
);
8653 addr
= tcg_const_i32(insn
& 0xff);
8654 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
8655 tcg_temp_free_i32(addr
);
8656 tcg_temp_free_i32(tmp
);
8661 case 1: /* msr spsr. */
8664 tmp
= load_reg(s
, rn
);
8666 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
8670 case 2: /* cps, nop-hint. */
8671 if (((insn
>> 8) & 7) == 0) {
8672 gen_nop_hint(s
, insn
& 0xff);
8674 /* Implemented as NOP in user mode. */
8679 if (insn
& (1 << 10)) {
8680 if (insn
& (1 << 7))
8682 if (insn
& (1 << 6))
8684 if (insn
& (1 << 5))
8686 if (insn
& (1 << 9))
8687 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
8689 if (insn
& (1 << 8)) {
8691 imm
|= (insn
& 0x1f);
8694 gen_set_psr_im(s
, offset
, 0, imm
);
8697 case 3: /* Special control operations. */
8699 op
= (insn
>> 4) & 0xf;
8707 /* These execute as NOPs. */
8714 /* Trivial implementation equivalent to bx. */
8715 tmp
= load_reg(s
, rn
);
8718 case 5: /* Exception return. */
8722 if (rn
!= 14 || rd
!= 15) {
8725 tmp
= load_reg(s
, rn
);
8726 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
8727 gen_exception_return(s
, tmp
);
8729 case 6: /* mrs cpsr. */
8730 tmp
= tcg_temp_new_i32();
8732 addr
= tcg_const_i32(insn
& 0xff);
8733 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
8734 tcg_temp_free_i32(addr
);
8736 gen_helper_cpsr_read(tmp
, cpu_env
);
8738 store_reg(s
, rd
, tmp
);
8740 case 7: /* mrs spsr. */
8741 /* Not accessible in user mode. */
8742 if (IS_USER(s
) || IS_M(env
))
8744 tmp
= load_cpu_field(spsr
);
8745 store_reg(s
, rd
, tmp
);
8750 /* Conditional branch. */
8751 op
= (insn
>> 22) & 0xf;
8752 /* Generate a conditional jump to next instruction. */
8753 s
->condlabel
= gen_new_label();
8754 gen_test_cc(op
^ 1, s
->condlabel
);
8757 /* offset[11:1] = insn[10:0] */
8758 offset
= (insn
& 0x7ff) << 1;
8759 /* offset[17:12] = insn[21:16]. */
8760 offset
|= (insn
& 0x003f0000) >> 4;
8761 /* offset[31:20] = insn[26]. */
8762 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
8763 /* offset[18] = insn[13]. */
8764 offset
|= (insn
& (1 << 13)) << 5;
8765 /* offset[19] = insn[11]. */
8766 offset
|= (insn
& (1 << 11)) << 8;
8768 /* jump to the offset */
8769 gen_jmp(s
, s
->pc
+ offset
);
8772 /* Data processing immediate. */
8773 if (insn
& (1 << 25)) {
8774 if (insn
& (1 << 24)) {
8775 if (insn
& (1 << 20))
8777 /* Bitfield/Saturate. */
8778 op
= (insn
>> 21) & 7;
8780 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8782 tmp
= tcg_temp_new_i32();
8783 tcg_gen_movi_i32(tmp
, 0);
8785 tmp
= load_reg(s
, rn
);
8788 case 2: /* Signed bitfield extract. */
8790 if (shift
+ imm
> 32)
8793 gen_sbfx(tmp
, shift
, imm
);
8795 case 6: /* Unsigned bitfield extract. */
8797 if (shift
+ imm
> 32)
8800 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
8802 case 3: /* Bitfield insert/clear. */
8805 imm
= imm
+ 1 - shift
;
8807 tmp2
= load_reg(s
, rd
);
8808 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
8809 tcg_temp_free_i32(tmp2
);
8814 default: /* Saturate. */
8817 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8819 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8821 tmp2
= tcg_const_i32(imm
);
8824 if ((op
& 1) && shift
== 0)
8825 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8827 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8830 if ((op
& 1) && shift
== 0)
8831 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8833 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8835 tcg_temp_free_i32(tmp2
);
8838 store_reg(s
, rd
, tmp
);
8840 imm
= ((insn
& 0x04000000) >> 15)
8841 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
8842 if (insn
& (1 << 22)) {
8843 /* 16-bit immediate. */
8844 imm
|= (insn
>> 4) & 0xf000;
8845 if (insn
& (1 << 23)) {
8847 tmp
= load_reg(s
, rd
);
8848 tcg_gen_ext16u_i32(tmp
, tmp
);
8849 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
8852 tmp
= tcg_temp_new_i32();
8853 tcg_gen_movi_i32(tmp
, imm
);
8856 /* Add/sub 12-bit immediate. */
8858 offset
= s
->pc
& ~(uint32_t)3;
8859 if (insn
& (1 << 23))
8863 tmp
= tcg_temp_new_i32();
8864 tcg_gen_movi_i32(tmp
, offset
);
8866 tmp
= load_reg(s
, rn
);
8867 if (insn
& (1 << 23))
8868 tcg_gen_subi_i32(tmp
, tmp
, imm
);
8870 tcg_gen_addi_i32(tmp
, tmp
, imm
);
8873 store_reg(s
, rd
, tmp
);
8876 int shifter_out
= 0;
8877 /* modified 12-bit immediate. */
8878 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
8879 imm
= (insn
& 0xff);
8882 /* Nothing to do. */
8884 case 1: /* 00XY00XY */
8887 case 2: /* XY00XY00 */
8891 case 3: /* XYXYXYXY */
8895 default: /* Rotated constant. */
8896 shift
= (shift
<< 1) | (imm
>> 7);
8898 imm
= imm
<< (32 - shift
);
8902 tmp2
= tcg_temp_new_i32();
8903 tcg_gen_movi_i32(tmp2
, imm
);
8904 rn
= (insn
>> 16) & 0xf;
8906 tmp
= tcg_temp_new_i32();
8907 tcg_gen_movi_i32(tmp
, 0);
8909 tmp
= load_reg(s
, rn
);
8911 op
= (insn
>> 21) & 0xf;
8912 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
8913 shifter_out
, tmp
, tmp2
))
8915 tcg_temp_free_i32(tmp2
);
8916 rd
= (insn
>> 8) & 0xf;
8918 store_reg(s
, rd
, tmp
);
8920 tcg_temp_free_i32(tmp
);
8925 case 12: /* Load/store single data item. */
8930 if ((insn
& 0x01100000) == 0x01000000) {
8931 if (disas_neon_ls_insn(env
, s
, insn
))
8935 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
8937 if (!(insn
& (1 << 20))) {
8941 /* Byte or halfword load space with dest == r15 : memory hints.
8942 * Catch them early so we don't emit pointless addressing code.
8943 * This space is a mix of:
8944 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8945 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8947 * unallocated hints, which must be treated as NOPs
8948 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8949 * which is easiest for the decoding logic
8950 * Some space which must UNDEF
8952 int op1
= (insn
>> 23) & 3;
8953 int op2
= (insn
>> 6) & 0x3f;
8958 /* UNPREDICTABLE, unallocated hint or
8959 * PLD/PLDW/PLI (literal)
8964 return 0; /* PLD/PLDW/PLI or unallocated hint */
8966 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
8967 return 0; /* PLD/PLDW/PLI or unallocated hint */
8969 /* UNDEF space, or an UNPREDICTABLE */
8975 addr
= tcg_temp_new_i32();
8977 /* s->pc has already been incremented by 4. */
8978 imm
= s
->pc
& 0xfffffffc;
8979 if (insn
& (1 << 23))
8980 imm
+= insn
& 0xfff;
8982 imm
-= insn
& 0xfff;
8983 tcg_gen_movi_i32(addr
, imm
);
8985 addr
= load_reg(s
, rn
);
8986 if (insn
& (1 << 23)) {
8987 /* Positive offset. */
8989 tcg_gen_addi_i32(addr
, addr
, imm
);
8992 switch ((insn
>> 8) & 0xf) {
8993 case 0x0: /* Shifted Register. */
8994 shift
= (insn
>> 4) & 0xf;
8996 tcg_temp_free_i32(addr
);
8999 tmp
= load_reg(s
, rm
);
9001 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9002 tcg_gen_add_i32(addr
, addr
, tmp
);
9003 tcg_temp_free_i32(tmp
);
9005 case 0xc: /* Negative offset. */
9006 tcg_gen_addi_i32(addr
, addr
, -imm
);
9008 case 0xe: /* User privilege. */
9009 tcg_gen_addi_i32(addr
, addr
, imm
);
9012 case 0x9: /* Post-decrement. */
9015 case 0xb: /* Post-increment. */
9019 case 0xd: /* Pre-decrement. */
9022 case 0xf: /* Pre-increment. */
9023 tcg_gen_addi_i32(addr
, addr
, imm
);
9027 tcg_temp_free_i32(addr
);
9032 if (insn
& (1 << 20)) {
9035 case 0: tmp
= gen_ld8u(addr
, user
); break;
9036 case 4: tmp
= gen_ld8s(addr
, user
); break;
9037 case 1: tmp
= gen_ld16u(addr
, user
); break;
9038 case 5: tmp
= gen_ld16s(addr
, user
); break;
9039 case 2: tmp
= gen_ld32(addr
, user
); break;
9041 tcg_temp_free_i32(addr
);
9047 store_reg(s
, rs
, tmp
);
9051 tmp
= load_reg(s
, rs
);
9053 case 0: gen_st8(tmp
, addr
, user
); break;
9054 case 1: gen_st16(tmp
, addr
, user
); break;
9055 case 2: gen_st32(tmp
, addr
, user
); break;
9057 tcg_temp_free_i32(addr
);
9062 tcg_gen_addi_i32(addr
, addr
, imm
);
9064 store_reg(s
, rn
, addr
);
9066 tcg_temp_free_i32(addr
);
9078 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9080 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9087 if (s
->condexec_mask
) {
9088 cond
= s
->condexec_cond
;
9089 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9090 s
->condlabel
= gen_new_label();
9091 gen_test_cc(cond
^ 1, s
->condlabel
);
9096 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9099 switch (insn
>> 12) {
9103 op
= (insn
>> 11) & 3;
9106 rn
= (insn
>> 3) & 7;
9107 tmp
= load_reg(s
, rn
);
9108 if (insn
& (1 << 10)) {
9110 tmp2
= tcg_temp_new_i32();
9111 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9114 rm
= (insn
>> 6) & 7;
9115 tmp2
= load_reg(s
, rm
);
9117 if (insn
& (1 << 9)) {
9118 if (s
->condexec_mask
)
9119 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9121 gen_sub_CC(tmp
, tmp
, tmp2
);
9123 if (s
->condexec_mask
)
9124 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9126 gen_add_CC(tmp
, tmp
, tmp2
);
9128 tcg_temp_free_i32(tmp2
);
9129 store_reg(s
, rd
, tmp
);
9131 /* shift immediate */
9132 rm
= (insn
>> 3) & 7;
9133 shift
= (insn
>> 6) & 0x1f;
9134 tmp
= load_reg(s
, rm
);
9135 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9136 if (!s
->condexec_mask
)
9138 store_reg(s
, rd
, tmp
);
9142 /* arithmetic large immediate */
9143 op
= (insn
>> 11) & 3;
9144 rd
= (insn
>> 8) & 0x7;
9145 if (op
== 0) { /* mov */
9146 tmp
= tcg_temp_new_i32();
9147 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9148 if (!s
->condexec_mask
)
9150 store_reg(s
, rd
, tmp
);
9152 tmp
= load_reg(s
, rd
);
9153 tmp2
= tcg_temp_new_i32();
9154 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9157 gen_sub_CC(tmp
, tmp
, tmp2
);
9158 tcg_temp_free_i32(tmp
);
9159 tcg_temp_free_i32(tmp2
);
9162 if (s
->condexec_mask
)
9163 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9165 gen_add_CC(tmp
, tmp
, tmp2
);
9166 tcg_temp_free_i32(tmp2
);
9167 store_reg(s
, rd
, tmp
);
9170 if (s
->condexec_mask
)
9171 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9173 gen_sub_CC(tmp
, tmp
, tmp2
);
9174 tcg_temp_free_i32(tmp2
);
9175 store_reg(s
, rd
, tmp
);
9181 if (insn
& (1 << 11)) {
9182 rd
= (insn
>> 8) & 7;
9183 /* load pc-relative. Bit 1 of PC is ignored. */
9184 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9185 val
&= ~(uint32_t)2;
9186 addr
= tcg_temp_new_i32();
9187 tcg_gen_movi_i32(addr
, val
);
9188 tmp
= gen_ld32(addr
, IS_USER(s
));
9189 tcg_temp_free_i32(addr
);
9190 store_reg(s
, rd
, tmp
);
9193 if (insn
& (1 << 10)) {
9194 /* data processing extended or blx */
9195 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9196 rm
= (insn
>> 3) & 0xf;
9197 op
= (insn
>> 8) & 3;
9200 tmp
= load_reg(s
, rd
);
9201 tmp2
= load_reg(s
, rm
);
9202 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9203 tcg_temp_free_i32(tmp2
);
9204 store_reg(s
, rd
, tmp
);
9207 tmp
= load_reg(s
, rd
);
9208 tmp2
= load_reg(s
, rm
);
9209 gen_sub_CC(tmp
, tmp
, tmp2
);
9210 tcg_temp_free_i32(tmp2
);
9211 tcg_temp_free_i32(tmp
);
9213 case 2: /* mov/cpy */
9214 tmp
= load_reg(s
, rm
);
9215 store_reg(s
, rd
, tmp
);
9217 case 3:/* branch [and link] exchange thumb register */
9218 tmp
= load_reg(s
, rm
);
9219 if (insn
& (1 << 7)) {
9221 val
= (uint32_t)s
->pc
| 1;
9222 tmp2
= tcg_temp_new_i32();
9223 tcg_gen_movi_i32(tmp2
, val
);
9224 store_reg(s
, 14, tmp2
);
9226 /* already thumb, no need to check */
9233 /* data processing register */
9235 rm
= (insn
>> 3) & 7;
9236 op
= (insn
>> 6) & 0xf;
9237 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9238 /* the shift/rotate ops want the operands backwards */
9247 if (op
== 9) { /* neg */
9248 tmp
= tcg_temp_new_i32();
9249 tcg_gen_movi_i32(tmp
, 0);
9250 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9251 tmp
= load_reg(s
, rd
);
9256 tmp2
= load_reg(s
, rm
);
9259 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9260 if (!s
->condexec_mask
)
9264 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9265 if (!s
->condexec_mask
)
9269 if (s
->condexec_mask
) {
9270 gen_shl(tmp2
, tmp2
, tmp
);
9272 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9277 if (s
->condexec_mask
) {
9278 gen_shr(tmp2
, tmp2
, tmp
);
9280 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9285 if (s
->condexec_mask
) {
9286 gen_sar(tmp2
, tmp2
, tmp
);
9288 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9293 if (s
->condexec_mask
) {
9296 gen_adc_CC(tmp
, tmp
, tmp2
);
9300 if (s
->condexec_mask
) {
9301 gen_sub_carry(tmp
, tmp
, tmp2
);
9303 gen_sbc_CC(tmp
, tmp
, tmp2
);
9307 if (s
->condexec_mask
) {
9308 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9309 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9311 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9316 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9321 if (s
->condexec_mask
)
9322 tcg_gen_neg_i32(tmp
, tmp2
);
9324 gen_sub_CC(tmp
, tmp
, tmp2
);
9327 gen_sub_CC(tmp
, tmp
, tmp2
);
9331 gen_add_CC(tmp
, tmp
, tmp2
);
9335 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9336 if (!s
->condexec_mask
)
9340 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9341 if (!s
->condexec_mask
)
9345 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
9346 if (!s
->condexec_mask
)
9350 tcg_gen_not_i32(tmp2
, tmp2
);
9351 if (!s
->condexec_mask
)
9359 store_reg(s
, rm
, tmp2
);
9361 tcg_temp_free_i32(tmp
);
9363 store_reg(s
, rd
, tmp
);
9364 tcg_temp_free_i32(tmp2
);
9367 tcg_temp_free_i32(tmp
);
9368 tcg_temp_free_i32(tmp2
);
9373 /* load/store register offset. */
9375 rn
= (insn
>> 3) & 7;
9376 rm
= (insn
>> 6) & 7;
9377 op
= (insn
>> 9) & 7;
9378 addr
= load_reg(s
, rn
);
9379 tmp
= load_reg(s
, rm
);
9380 tcg_gen_add_i32(addr
, addr
, tmp
);
9381 tcg_temp_free_i32(tmp
);
9383 if (op
< 3) /* store */
9384 tmp
= load_reg(s
, rd
);
9388 gen_st32(tmp
, addr
, IS_USER(s
));
9391 gen_st16(tmp
, addr
, IS_USER(s
));
9394 gen_st8(tmp
, addr
, IS_USER(s
));
9397 tmp
= gen_ld8s(addr
, IS_USER(s
));
9400 tmp
= gen_ld32(addr
, IS_USER(s
));
9403 tmp
= gen_ld16u(addr
, IS_USER(s
));
9406 tmp
= gen_ld8u(addr
, IS_USER(s
));
9409 tmp
= gen_ld16s(addr
, IS_USER(s
));
9412 if (op
>= 3) /* load */
9413 store_reg(s
, rd
, tmp
);
9414 tcg_temp_free_i32(addr
);
9418 /* load/store word immediate offset */
9420 rn
= (insn
>> 3) & 7;
9421 addr
= load_reg(s
, rn
);
9422 val
= (insn
>> 4) & 0x7c;
9423 tcg_gen_addi_i32(addr
, addr
, val
);
9425 if (insn
& (1 << 11)) {
9427 tmp
= gen_ld32(addr
, IS_USER(s
));
9428 store_reg(s
, rd
, tmp
);
9431 tmp
= load_reg(s
, rd
);
9432 gen_st32(tmp
, addr
, IS_USER(s
));
9434 tcg_temp_free_i32(addr
);
9438 /* load/store byte immediate offset */
9440 rn
= (insn
>> 3) & 7;
9441 addr
= load_reg(s
, rn
);
9442 val
= (insn
>> 6) & 0x1f;
9443 tcg_gen_addi_i32(addr
, addr
, val
);
9445 if (insn
& (1 << 11)) {
9447 tmp
= gen_ld8u(addr
, IS_USER(s
));
9448 store_reg(s
, rd
, tmp
);
9451 tmp
= load_reg(s
, rd
);
9452 gen_st8(tmp
, addr
, IS_USER(s
));
9454 tcg_temp_free_i32(addr
);
9458 /* load/store halfword immediate offset */
9460 rn
= (insn
>> 3) & 7;
9461 addr
= load_reg(s
, rn
);
9462 val
= (insn
>> 5) & 0x3e;
9463 tcg_gen_addi_i32(addr
, addr
, val
);
9465 if (insn
& (1 << 11)) {
9467 tmp
= gen_ld16u(addr
, IS_USER(s
));
9468 store_reg(s
, rd
, tmp
);
9471 tmp
= load_reg(s
, rd
);
9472 gen_st16(tmp
, addr
, IS_USER(s
));
9474 tcg_temp_free_i32(addr
);
9478 /* load/store from stack */
9479 rd
= (insn
>> 8) & 7;
9480 addr
= load_reg(s
, 13);
9481 val
= (insn
& 0xff) * 4;
9482 tcg_gen_addi_i32(addr
, addr
, val
);
9484 if (insn
& (1 << 11)) {
9486 tmp
= gen_ld32(addr
, IS_USER(s
));
9487 store_reg(s
, rd
, tmp
);
9490 tmp
= load_reg(s
, rd
);
9491 gen_st32(tmp
, addr
, IS_USER(s
));
9493 tcg_temp_free_i32(addr
);
9497 /* add to high reg */
9498 rd
= (insn
>> 8) & 7;
9499 if (insn
& (1 << 11)) {
9501 tmp
= load_reg(s
, 13);
9503 /* PC. bit 1 is ignored. */
9504 tmp
= tcg_temp_new_i32();
9505 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
9507 val
= (insn
& 0xff) * 4;
9508 tcg_gen_addi_i32(tmp
, tmp
, val
);
9509 store_reg(s
, rd
, tmp
);
9514 op
= (insn
>> 8) & 0xf;
9517 /* adjust stack pointer */
9518 tmp
= load_reg(s
, 13);
9519 val
= (insn
& 0x7f) * 4;
9520 if (insn
& (1 << 7))
9521 val
= -(int32_t)val
;
9522 tcg_gen_addi_i32(tmp
, tmp
, val
);
9523 store_reg(s
, 13, tmp
);
9526 case 2: /* sign/zero extend. */
9529 rm
= (insn
>> 3) & 7;
9530 tmp
= load_reg(s
, rm
);
9531 switch ((insn
>> 6) & 3) {
9532 case 0: gen_sxth(tmp
); break;
9533 case 1: gen_sxtb(tmp
); break;
9534 case 2: gen_uxth(tmp
); break;
9535 case 3: gen_uxtb(tmp
); break;
9537 store_reg(s
, rd
, tmp
);
9539 case 4: case 5: case 0xc: case 0xd:
9541 addr
= load_reg(s
, 13);
9542 if (insn
& (1 << 8))
9546 for (i
= 0; i
< 8; i
++) {
9547 if (insn
& (1 << i
))
9550 if ((insn
& (1 << 11)) == 0) {
9551 tcg_gen_addi_i32(addr
, addr
, -offset
);
9553 for (i
= 0; i
< 8; i
++) {
9554 if (insn
& (1 << i
)) {
9555 if (insn
& (1 << 11)) {
9557 tmp
= gen_ld32(addr
, IS_USER(s
));
9558 store_reg(s
, i
, tmp
);
9561 tmp
= load_reg(s
, i
);
9562 gen_st32(tmp
, addr
, IS_USER(s
));
9564 /* advance to the next address. */
9565 tcg_gen_addi_i32(addr
, addr
, 4);
9569 if (insn
& (1 << 8)) {
9570 if (insn
& (1 << 11)) {
9572 tmp
= gen_ld32(addr
, IS_USER(s
));
9573 /* don't set the pc until the rest of the instruction
9577 tmp
= load_reg(s
, 14);
9578 gen_st32(tmp
, addr
, IS_USER(s
));
9580 tcg_gen_addi_i32(addr
, addr
, 4);
9582 if ((insn
& (1 << 11)) == 0) {
9583 tcg_gen_addi_i32(addr
, addr
, -offset
);
9585 /* write back the new stack pointer */
9586 store_reg(s
, 13, addr
);
9587 /* set the new PC value */
9588 if ((insn
& 0x0900) == 0x0900) {
9589 store_reg_from_load(env
, s
, 15, tmp
);
9593 case 1: case 3: case 9: case 11: /* czb */
9595 tmp
= load_reg(s
, rm
);
9596 s
->condlabel
= gen_new_label();
9598 if (insn
& (1 << 11))
9599 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
9601 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
9602 tcg_temp_free_i32(tmp
);
9603 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
9604 val
= (uint32_t)s
->pc
+ 2;
9609 case 15: /* IT, nop-hint. */
9610 if ((insn
& 0xf) == 0) {
9611 gen_nop_hint(s
, (insn
>> 4) & 0xf);
9615 s
->condexec_cond
= (insn
>> 4) & 0xe;
9616 s
->condexec_mask
= insn
& 0x1f;
9617 /* No actual code generated for this insn, just setup state. */
9620 case 0xe: /* bkpt */
9622 gen_exception_insn(s
, 2, EXCP_BKPT
);
9627 rn
= (insn
>> 3) & 0x7;
9629 tmp
= load_reg(s
, rn
);
9630 switch ((insn
>> 6) & 3) {
9631 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
9632 case 1: gen_rev16(tmp
); break;
9633 case 3: gen_revsh(tmp
); break;
9634 default: goto illegal_op
;
9636 store_reg(s
, rd
, tmp
);
9640 switch ((insn
>> 5) & 7) {
9644 if (((insn
>> 3) & 1) != s
->bswap_code
) {
9645 /* Dynamic endianness switching not implemented. */
9656 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
9659 addr
= tcg_const_i32(19);
9660 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9661 tcg_temp_free_i32(addr
);
9665 addr
= tcg_const_i32(16);
9666 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9667 tcg_temp_free_i32(addr
);
9669 tcg_temp_free_i32(tmp
);
9672 if (insn
& (1 << 4)) {
9673 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
9677 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
9692 /* load/store multiple */
9694 TCGV_UNUSED(loaded_var
);
9695 rn
= (insn
>> 8) & 0x7;
9696 addr
= load_reg(s
, rn
);
9697 for (i
= 0; i
< 8; i
++) {
9698 if (insn
& (1 << i
)) {
9699 if (insn
& (1 << 11)) {
9701 tmp
= gen_ld32(addr
, IS_USER(s
));
9705 store_reg(s
, i
, tmp
);
9709 tmp
= load_reg(s
, i
);
9710 gen_st32(tmp
, addr
, IS_USER(s
));
9712 /* advance to the next address */
9713 tcg_gen_addi_i32(addr
, addr
, 4);
9716 if ((insn
& (1 << rn
)) == 0) {
9717 /* base reg not in list: base register writeback */
9718 store_reg(s
, rn
, addr
);
9720 /* base reg in list: if load, complete it now */
9721 if (insn
& (1 << 11)) {
9722 store_reg(s
, rn
, loaded_var
);
9724 tcg_temp_free_i32(addr
);
9729 /* conditional branch or swi */
9730 cond
= (insn
>> 8) & 0xf;
9736 gen_set_pc_im(s
->pc
);
9737 s
->is_jmp
= DISAS_SWI
;
9740 /* generate a conditional jump to next instruction */
9741 s
->condlabel
= gen_new_label();
9742 gen_test_cc(cond
^ 1, s
->condlabel
);
9745 /* jump to the offset */
9746 val
= (uint32_t)s
->pc
+ 2;
9747 offset
= ((int32_t)insn
<< 24) >> 24;
9753 if (insn
& (1 << 11)) {
9754 if (disas_thumb2_insn(env
, s
, insn
))
9758 /* unconditional branch */
9759 val
= (uint32_t)s
->pc
;
9760 offset
= ((int32_t)insn
<< 21) >> 21;
9761 val
+= (offset
<< 1) + 2;
9766 if (disas_thumb2_insn(env
, s
, insn
))
9772 gen_exception_insn(s
, 4, EXCP_UDEF
);
9776 gen_exception_insn(s
, 2, EXCP_UDEF
);
9779 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9780 basic block 'tb'. If search_pc is TRUE, also generate PC
9781 information for each intermediate instruction. */
9782 static inline void gen_intermediate_code_internal(CPUARMState
*env
,
9783 TranslationBlock
*tb
,
9786 DisasContext dc1
, *dc
= &dc1
;
9788 uint16_t *gen_opc_end
;
9790 target_ulong pc_start
;
9791 uint32_t next_page_start
;
9795 /* generate intermediate code */
9800 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
9802 dc
->is_jmp
= DISAS_NEXT
;
9804 dc
->singlestep_enabled
= env
->singlestep_enabled
;
9806 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
9807 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
9808 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
9809 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
9810 #if !defined(CONFIG_USER_ONLY)
9811 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
9813 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
9814 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
9815 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
9816 cpu_F0s
= tcg_temp_new_i32();
9817 cpu_F1s
= tcg_temp_new_i32();
9818 cpu_F0d
= tcg_temp_new_i64();
9819 cpu_F1d
= tcg_temp_new_i64();
9822 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9823 cpu_M0
= tcg_temp_new_i64();
9824 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
9827 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
9829 max_insns
= CF_COUNT_MASK
;
9833 tcg_clear_temp_count();
9835 /* A note on handling of the condexec (IT) bits:
9837 * We want to avoid the overhead of having to write the updated condexec
9838 * bits back to the CPUARMState for every instruction in an IT block. So:
9839 * (1) if the condexec bits are not already zero then we write
9840 * zero back into the CPUARMState now. This avoids complications trying
9841 * to do it at the end of the block. (For example if we don't do this
9842 * it's hard to identify whether we can safely skip writing condexec
9843 * at the end of the TB, which we definitely want to do for the case
9844 * where a TB doesn't do anything with the IT state at all.)
9845 * (2) if we are going to leave the TB then we call gen_set_condexec()
9846 * which will write the correct value into CPUARMState if zero is wrong.
9847 * This is done both for leaving the TB at the end, and for leaving
9848 * it because of an exception we know will happen, which is done in
9849 * gen_exception_insn(). The latter is necessary because we need to
9850 * leave the TB with the PC/IT state just prior to execution of the
9851 * instruction which caused the exception.
9852 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9853 * then the CPUARMState will be wrong and we need to reset it.
9854 * This is handled in the same way as restoration of the
9855 * PC in these situations: we will be called again with search_pc=1
9856 * and generate a mapping of the condexec bits for each PC in
9857 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9858 * this to restore the condexec bits.
9860 * Note that there are no instructions which can read the condexec
9861 * bits, and none which can write non-static values to them, so
9862 * we don't need to care about whether CPUARMState is correct in the
9866 /* Reset the conditional execution bits immediately. This avoids
9867 complications trying to do it at the end of the block. */
9868 if (dc
->condexec_mask
|| dc
->condexec_cond
)
9870 TCGv tmp
= tcg_temp_new_i32();
9871 tcg_gen_movi_i32(tmp
, 0);
9872 store_cpu_field(tmp
, condexec_bits
);
9875 #ifdef CONFIG_USER_ONLY
9876 /* Intercept jump to the magic kernel page. */
9877 if (dc
->pc
>= 0xffff0000) {
9878 /* We always get here via a jump, so know we are not in a
9879 conditional execution block. */
9880 gen_exception(EXCP_KERNEL_TRAP
);
9881 dc
->is_jmp
= DISAS_UPDATE
;
9885 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
9886 /* We always get here via a jump, so know we are not in a
9887 conditional execution block. */
9888 gen_exception(EXCP_EXCEPTION_EXIT
);
9889 dc
->is_jmp
= DISAS_UPDATE
;
9894 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
9895 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
9896 if (bp
->pc
== dc
->pc
) {
9897 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
9898 /* Advance PC so that clearing the breakpoint will
9899 invalidate this TB. */
9901 goto done_generating
;
9907 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
9911 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
9913 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
9914 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
9915 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
9916 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
9919 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
9922 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
9923 tcg_gen_debug_insn_start(dc
->pc
);
9927 disas_thumb_insn(env
, dc
);
9928 if (dc
->condexec_mask
) {
9929 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
9930 | ((dc
->condexec_mask
>> 4) & 1);
9931 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
9932 if (dc
->condexec_mask
== 0) {
9933 dc
->condexec_cond
= 0;
9937 disas_arm_insn(env
, dc
);
9940 if (dc
->condjmp
&& !dc
->is_jmp
) {
9941 gen_set_label(dc
->condlabel
);
9945 if (tcg_check_temp_count()) {
9946 fprintf(stderr
, "TCG temporary leak before %08x\n", dc
->pc
);
9949 /* Translation stops when a conditional branch is encountered.
9950 * Otherwise the subsequent code could get translated several times.
9951 * Also stop translation when a page boundary is reached. This
9952 * ensures prefetch aborts occur at the right place. */
9954 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
9955 !env
->singlestep_enabled
&&
9957 dc
->pc
< next_page_start
&&
9958 num_insns
< max_insns
);
9960 if (tb
->cflags
& CF_LAST_IO
) {
9962 /* FIXME: This can theoretically happen with self-modifying
9964 cpu_abort(env
, "IO on conditional branch instruction");
9969 /* At this stage dc->condjmp will only be set when the skipped
9970 instruction was a conditional branch or trap, and the PC has
9971 already been written. */
9972 if (unlikely(env
->singlestep_enabled
)) {
9973 /* Make sure the pc is updated, and raise a debug exception. */
9975 gen_set_condexec(dc
);
9976 if (dc
->is_jmp
== DISAS_SWI
) {
9977 gen_exception(EXCP_SWI
);
9979 gen_exception(EXCP_DEBUG
);
9981 gen_set_label(dc
->condlabel
);
9983 if (dc
->condjmp
|| !dc
->is_jmp
) {
9984 gen_set_pc_im(dc
->pc
);
9987 gen_set_condexec(dc
);
9988 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
9989 gen_exception(EXCP_SWI
);
9991 /* FIXME: Single stepping a WFI insn will not halt
9993 gen_exception(EXCP_DEBUG
);
9996 /* While branches must always occur at the end of an IT block,
9997 there are a few other things that can cause us to terminate
9998 the TB in the middle of an IT block:
9999 - Exception generating instructions (bkpt, swi, undefined).
10001 - Hardware watchpoints.
10002 Hardware breakpoints have already been handled and skip this code.
10004 gen_set_condexec(dc
);
10005 switch(dc
->is_jmp
) {
10007 gen_goto_tb(dc
, 1, dc
->pc
);
10012 /* indicate that the hash table must be used to find the next TB */
10013 tcg_gen_exit_tb(0);
10015 case DISAS_TB_JUMP
:
10016 /* nothing more to generate */
10019 gen_helper_wfi(cpu_env
);
10022 gen_exception(EXCP_SWI
);
10026 gen_set_label(dc
->condlabel
);
10027 gen_set_condexec(dc
);
10028 gen_goto_tb(dc
, 1, dc
->pc
);
10034 gen_icount_end(tb
, num_insns
);
10035 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
10038 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
10039 qemu_log("----------------\n");
10040 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
10041 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
10042 dc
->thumb
| (dc
->bswap_code
<< 1));
10047 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10050 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10052 tb
->size
= dc
->pc
- pc_start
;
10053 tb
->icount
= num_insns
;
10057 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
10059 gen_intermediate_code_internal(env
, tb
, 0);
10062 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10064 gen_intermediate_code_internal(env
, tb
, 1);
10067 static const char *cpu_mode_names
[16] = {
10068 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10069 "???", "???", "???", "und", "???", "???", "???", "sys"
10072 void cpu_dump_state(CPUARMState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
10078 for(i
=0;i
<16;i
++) {
10079 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10081 cpu_fprintf(f
, "\n");
10083 cpu_fprintf(f
, " ");
10085 psr
= cpsr_read(env
);
10086 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10088 psr
& (1 << 31) ? 'N' : '-',
10089 psr
& (1 << 30) ? 'Z' : '-',
10090 psr
& (1 << 29) ? 'C' : '-',
10091 psr
& (1 << 28) ? 'V' : '-',
10092 psr
& CPSR_T
? 'T' : 'A',
10093 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10095 if (flags
& CPU_DUMP_FPU
) {
10096 int numvfpregs
= 0;
10097 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10100 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10103 for (i
= 0; i
< numvfpregs
; i
++) {
10104 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10105 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10106 i
* 2, (uint32_t)v
,
10107 i
* 2 + 1, (uint32_t)(v
>> 32),
10110 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10114 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10116 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10117 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];