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"
31 #include "qemu/bitops.h"
37 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
38 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
39 /* currently all emulated v5 cores are also v5TE, so don't bother */
40 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
41 #define ENABLE_ARCH_5J 0
42 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
43 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
44 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
45 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
48 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50 #include "translate.h"
51 static uint32_t gen_opc_condexec_bits
[OPC_BUF_SIZE
];
53 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) (s->user)
60 /* We reuse the same 64-bit temporaries for efficiency. */
61 static TCGv_i64 cpu_V0
, cpu_V1
, cpu_M0
;
62 static TCGv_i32 cpu_R
[16];
63 static TCGv_i32 cpu_CF
, cpu_NF
, cpu_VF
, cpu_ZF
;
64 static TCGv_i64 cpu_exclusive_addr
;
65 static TCGv_i64 cpu_exclusive_val
;
66 #ifdef CONFIG_USER_ONLY
67 static TCGv_i64 cpu_exclusive_test
;
68 static TCGv_i32 cpu_exclusive_info
;
71 /* FIXME: These should be removed. */
72 static TCGv_i32 cpu_F0s
, cpu_F1s
;
73 static TCGv_i64 cpu_F0d
, cpu_F1d
;
75 #include "exec/gen-icount.h"
77 static const char *regnames
[] =
78 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
79 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
86 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
88 for (i
= 0; i
< 16; i
++) {
89 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
90 offsetof(CPUARMState
, regs
[i
]),
93 cpu_CF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, CF
), "CF");
94 cpu_NF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, NF
), "NF");
95 cpu_VF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, VF
), "VF");
96 cpu_ZF
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUARMState
, ZF
), "ZF");
98 cpu_exclusive_addr
= tcg_global_mem_new_i64(TCG_AREG0
,
99 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
100 cpu_exclusive_val
= tcg_global_mem_new_i64(TCG_AREG0
,
101 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
102 #ifdef CONFIG_USER_ONLY
103 cpu_exclusive_test
= tcg_global_mem_new_i64(TCG_AREG0
,
104 offsetof(CPUARMState
, exclusive_test
), "exclusive_test");
105 cpu_exclusive_info
= tcg_global_mem_new_i32(TCG_AREG0
,
106 offsetof(CPUARMState
, exclusive_info
), "exclusive_info");
109 a64_translate_init();
112 static inline TCGv_i32
load_cpu_offset(int offset
)
114 TCGv_i32 tmp
= tcg_temp_new_i32();
115 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
119 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
121 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
123 tcg_gen_st_i32(var
, cpu_env
, offset
);
124 tcg_temp_free_i32(var
);
127 #define store_cpu_field(var, name) \
128 store_cpu_offset(var, offsetof(CPUARMState, name))
130 /* Set a variable to the value of a CPU register. */
131 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
135 /* normally, since we updated PC, we need only to add one insn */
137 addr
= (long)s
->pc
+ 2;
139 addr
= (long)s
->pc
+ 4;
140 tcg_gen_movi_i32(var
, addr
);
142 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
146 /* Create a new temporary and set it to the value of a CPU register. */
147 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
149 TCGv_i32 tmp
= tcg_temp_new_i32();
150 load_reg_var(s
, tmp
, reg
);
154 /* Set a CPU register. The source must be a temporary and will be
156 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
159 tcg_gen_andi_i32(var
, var
, ~1);
160 s
->is_jmp
= DISAS_JUMP
;
162 tcg_gen_mov_i32(cpu_R
[reg
], var
);
163 tcg_temp_free_i32(var
);
166 /* Value extensions. */
167 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
168 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
169 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
170 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
172 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
173 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
176 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
178 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
179 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
180 tcg_temp_free_i32(tmp_mask
);
182 /* Set NZCV flags from the high 4 bits of var. */
183 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
185 static void gen_exception(int excp
)
187 TCGv_i32 tmp
= tcg_temp_new_i32();
188 tcg_gen_movi_i32(tmp
, excp
);
189 gen_helper_exception(cpu_env
, tmp
);
190 tcg_temp_free_i32(tmp
);
193 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
195 TCGv_i32 tmp1
= tcg_temp_new_i32();
196 TCGv_i32 tmp2
= tcg_temp_new_i32();
197 tcg_gen_ext16s_i32(tmp1
, a
);
198 tcg_gen_ext16s_i32(tmp2
, b
);
199 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
200 tcg_temp_free_i32(tmp2
);
201 tcg_gen_sari_i32(a
, a
, 16);
202 tcg_gen_sari_i32(b
, b
, 16);
203 tcg_gen_mul_i32(b
, b
, a
);
204 tcg_gen_mov_i32(a
, tmp1
);
205 tcg_temp_free_i32(tmp1
);
208 /* Byteswap each halfword. */
209 static void gen_rev16(TCGv_i32 var
)
211 TCGv_i32 tmp
= tcg_temp_new_i32();
212 tcg_gen_shri_i32(tmp
, var
, 8);
213 tcg_gen_andi_i32(tmp
, tmp
, 0x00ff00ff);
214 tcg_gen_shli_i32(var
, var
, 8);
215 tcg_gen_andi_i32(var
, var
, 0xff00ff00);
216 tcg_gen_or_i32(var
, var
, tmp
);
217 tcg_temp_free_i32(tmp
);
220 /* Byteswap low halfword and sign extend. */
221 static void gen_revsh(TCGv_i32 var
)
223 tcg_gen_ext16u_i32(var
, var
);
224 tcg_gen_bswap16_i32(var
, var
);
225 tcg_gen_ext16s_i32(var
, var
);
228 /* Unsigned bitfield extract. */
229 static void gen_ubfx(TCGv_i32 var
, int shift
, uint32_t mask
)
232 tcg_gen_shri_i32(var
, var
, shift
);
233 tcg_gen_andi_i32(var
, var
, mask
);
236 /* Signed bitfield extract. */
237 static void gen_sbfx(TCGv_i32 var
, int shift
, int width
)
242 tcg_gen_sari_i32(var
, var
, shift
);
243 if (shift
+ width
< 32) {
244 signbit
= 1u << (width
- 1);
245 tcg_gen_andi_i32(var
, var
, (1u << width
) - 1);
246 tcg_gen_xori_i32(var
, var
, signbit
);
247 tcg_gen_subi_i32(var
, var
, signbit
);
251 /* Return (b << 32) + a. Mark inputs as dead */
252 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
254 TCGv_i64 tmp64
= tcg_temp_new_i64();
256 tcg_gen_extu_i32_i64(tmp64
, b
);
257 tcg_temp_free_i32(b
);
258 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
259 tcg_gen_add_i64(a
, tmp64
, a
);
261 tcg_temp_free_i64(tmp64
);
265 /* Return (b << 32) - a. Mark inputs as dead. */
266 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
268 TCGv_i64 tmp64
= tcg_temp_new_i64();
270 tcg_gen_extu_i32_i64(tmp64
, b
);
271 tcg_temp_free_i32(b
);
272 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
273 tcg_gen_sub_i64(a
, tmp64
, a
);
275 tcg_temp_free_i64(tmp64
);
279 /* 32x32->64 multiply. Marks inputs as dead. */
280 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
282 TCGv_i32 lo
= tcg_temp_new_i32();
283 TCGv_i32 hi
= tcg_temp_new_i32();
286 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
287 tcg_temp_free_i32(a
);
288 tcg_temp_free_i32(b
);
290 ret
= tcg_temp_new_i64();
291 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
292 tcg_temp_free_i32(lo
);
293 tcg_temp_free_i32(hi
);
298 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
300 TCGv_i32 lo
= tcg_temp_new_i32();
301 TCGv_i32 hi
= tcg_temp_new_i32();
304 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
305 tcg_temp_free_i32(a
);
306 tcg_temp_free_i32(b
);
308 ret
= tcg_temp_new_i64();
309 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
310 tcg_temp_free_i32(lo
);
311 tcg_temp_free_i32(hi
);
316 /* Swap low and high halfwords. */
317 static void gen_swap_half(TCGv_i32 var
)
319 TCGv_i32 tmp
= tcg_temp_new_i32();
320 tcg_gen_shri_i32(tmp
, var
, 16);
321 tcg_gen_shli_i32(var
, var
, 16);
322 tcg_gen_or_i32(var
, var
, tmp
);
323 tcg_temp_free_i32(tmp
);
326 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
327 tmp = (t0 ^ t1) & 0x8000;
330 t0 = (t0 + t1) ^ tmp;
333 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
335 TCGv_i32 tmp
= tcg_temp_new_i32();
336 tcg_gen_xor_i32(tmp
, t0
, t1
);
337 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
338 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
339 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
340 tcg_gen_add_i32(t0
, t0
, t1
);
341 tcg_gen_xor_i32(t0
, t0
, tmp
);
342 tcg_temp_free_i32(tmp
);
343 tcg_temp_free_i32(t1
);
346 /* Set CF to the top bit of var. */
347 static void gen_set_CF_bit31(TCGv_i32 var
)
349 tcg_gen_shri_i32(cpu_CF
, var
, 31);
352 /* Set N and Z flags from var. */
353 static inline void gen_logic_CC(TCGv_i32 var
)
355 tcg_gen_mov_i32(cpu_NF
, var
);
356 tcg_gen_mov_i32(cpu_ZF
, var
);
360 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
362 tcg_gen_add_i32(t0
, t0
, t1
);
363 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
366 /* dest = T0 + T1 + CF. */
367 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
369 tcg_gen_add_i32(dest
, t0
, t1
);
370 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
373 /* dest = T0 - T1 + CF - 1. */
374 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
376 tcg_gen_sub_i32(dest
, t0
, t1
);
377 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
378 tcg_gen_subi_i32(dest
, dest
, 1);
381 /* dest = T0 + T1. Compute C, N, V and Z flags */
382 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
384 TCGv_i32 tmp
= tcg_temp_new_i32();
385 tcg_gen_movi_i32(tmp
, 0);
386 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
387 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
388 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
389 tcg_gen_xor_i32(tmp
, t0
, t1
);
390 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
391 tcg_temp_free_i32(tmp
);
392 tcg_gen_mov_i32(dest
, cpu_NF
);
395 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
396 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
398 TCGv_i32 tmp
= tcg_temp_new_i32();
399 if (TCG_TARGET_HAS_add2_i32
) {
400 tcg_gen_movi_i32(tmp
, 0);
401 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
402 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
404 TCGv_i64 q0
= tcg_temp_new_i64();
405 TCGv_i64 q1
= tcg_temp_new_i64();
406 tcg_gen_extu_i32_i64(q0
, t0
);
407 tcg_gen_extu_i32_i64(q1
, t1
);
408 tcg_gen_add_i64(q0
, q0
, q1
);
409 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
410 tcg_gen_add_i64(q0
, q0
, q1
);
411 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
412 tcg_temp_free_i64(q0
);
413 tcg_temp_free_i64(q1
);
415 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
416 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
417 tcg_gen_xor_i32(tmp
, t0
, t1
);
418 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
419 tcg_temp_free_i32(tmp
);
420 tcg_gen_mov_i32(dest
, cpu_NF
);
423 /* dest = T0 - T1. Compute C, N, V and Z flags */
424 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
427 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
428 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
429 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
430 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
431 tmp
= tcg_temp_new_i32();
432 tcg_gen_xor_i32(tmp
, t0
, t1
);
433 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
434 tcg_temp_free_i32(tmp
);
435 tcg_gen_mov_i32(dest
, cpu_NF
);
438 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
439 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
441 TCGv_i32 tmp
= tcg_temp_new_i32();
442 tcg_gen_not_i32(tmp
, t1
);
443 gen_adc_CC(dest
, t0
, tmp
);
444 tcg_temp_free_i32(tmp
);
447 #define GEN_SHIFT(name) \
448 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
450 TCGv_i32 tmp1, tmp2, tmp3; \
451 tmp1 = tcg_temp_new_i32(); \
452 tcg_gen_andi_i32(tmp1, t1, 0xff); \
453 tmp2 = tcg_const_i32(0); \
454 tmp3 = tcg_const_i32(0x1f); \
455 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
456 tcg_temp_free_i32(tmp3); \
457 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
458 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
459 tcg_temp_free_i32(tmp2); \
460 tcg_temp_free_i32(tmp1); \
466 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
469 tmp1
= tcg_temp_new_i32();
470 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
471 tmp2
= tcg_const_i32(0x1f);
472 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
473 tcg_temp_free_i32(tmp2
);
474 tcg_gen_sar_i32(dest
, t0
, tmp1
);
475 tcg_temp_free_i32(tmp1
);
478 static void tcg_gen_abs_i32(TCGv_i32 dest
, TCGv_i32 src
)
480 TCGv_i32 c0
= tcg_const_i32(0);
481 TCGv_i32 tmp
= tcg_temp_new_i32();
482 tcg_gen_neg_i32(tmp
, src
);
483 tcg_gen_movcond_i32(TCG_COND_GT
, dest
, src
, c0
, src
, tmp
);
484 tcg_temp_free_i32(c0
);
485 tcg_temp_free_i32(tmp
);
488 static void shifter_out_im(TCGv_i32 var
, int shift
)
491 tcg_gen_andi_i32(cpu_CF
, var
, 1);
493 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
495 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
500 /* Shift by immediate. Includes special handling for shift == 0. */
501 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
502 int shift
, int flags
)
508 shifter_out_im(var
, 32 - shift
);
509 tcg_gen_shli_i32(var
, var
, shift
);
515 tcg_gen_shri_i32(cpu_CF
, var
, 31);
517 tcg_gen_movi_i32(var
, 0);
520 shifter_out_im(var
, shift
- 1);
521 tcg_gen_shri_i32(var
, var
, shift
);
528 shifter_out_im(var
, shift
- 1);
531 tcg_gen_sari_i32(var
, var
, shift
);
533 case 3: /* ROR/RRX */
536 shifter_out_im(var
, shift
- 1);
537 tcg_gen_rotri_i32(var
, var
, shift
); break;
539 TCGv_i32 tmp
= tcg_temp_new_i32();
540 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
542 shifter_out_im(var
, 0);
543 tcg_gen_shri_i32(var
, var
, 1);
544 tcg_gen_or_i32(var
, var
, tmp
);
545 tcg_temp_free_i32(tmp
);
550 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
551 TCGv_i32 shift
, int flags
)
555 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
556 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
557 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
558 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
563 gen_shl(var
, var
, shift
);
566 gen_shr(var
, var
, shift
);
569 gen_sar(var
, var
, shift
);
571 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
572 tcg_gen_rotr_i32(var
, var
, shift
); break;
575 tcg_temp_free_i32(shift
);
578 #define PAS_OP(pfx) \
580 case 0: gen_pas_helper(glue(pfx,add16)); break; \
581 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
582 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
583 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
584 case 4: gen_pas_helper(glue(pfx,add8)); break; \
585 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
587 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
592 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
594 tmp
= tcg_temp_new_ptr();
595 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
597 tcg_temp_free_ptr(tmp
);
600 tmp
= tcg_temp_new_ptr();
601 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
603 tcg_temp_free_ptr(tmp
);
605 #undef gen_pas_helper
606 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
619 #undef gen_pas_helper
624 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
625 #define PAS_OP(pfx) \
627 case 0: gen_pas_helper(glue(pfx,add8)); break; \
628 case 1: gen_pas_helper(glue(pfx,add16)); break; \
629 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
630 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
631 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
632 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
634 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
639 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
641 tmp
= tcg_temp_new_ptr();
642 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
644 tcg_temp_free_ptr(tmp
);
647 tmp
= tcg_temp_new_ptr();
648 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
650 tcg_temp_free_ptr(tmp
);
652 #undef gen_pas_helper
653 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
666 #undef gen_pas_helper
672 * generate a conditional branch based on ARM condition code cc.
673 * This is common between ARM and Aarch64 targets.
675 void arm_gen_test_cc(int cc
, int label
)
682 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
685 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
688 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_CF
, 0, label
);
691 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
694 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_NF
, 0, label
);
697 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_NF
, 0, label
);
700 tcg_gen_brcondi_i32(TCG_COND_LT
, cpu_VF
, 0, label
);
703 tcg_gen_brcondi_i32(TCG_COND_GE
, cpu_VF
, 0, label
);
705 case 8: /* hi: C && !Z */
706 inv
= gen_new_label();
707 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, inv
);
708 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_ZF
, 0, label
);
711 case 9: /* ls: !C || Z */
712 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_CF
, 0, label
);
713 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
715 case 10: /* ge: N == V -> N ^ V == 0 */
716 tmp
= tcg_temp_new_i32();
717 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
718 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
719 tcg_temp_free_i32(tmp
);
721 case 11: /* lt: N != V -> N ^ V != 0 */
722 tmp
= tcg_temp_new_i32();
723 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
724 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
725 tcg_temp_free_i32(tmp
);
727 case 12: /* gt: !Z && N == V */
728 inv
= gen_new_label();
729 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, inv
);
730 tmp
= tcg_temp_new_i32();
731 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
732 tcg_gen_brcondi_i32(TCG_COND_GE
, tmp
, 0, label
);
733 tcg_temp_free_i32(tmp
);
736 case 13: /* le: Z || N != V */
737 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ZF
, 0, label
);
738 tmp
= tcg_temp_new_i32();
739 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
740 tcg_gen_brcondi_i32(TCG_COND_LT
, tmp
, 0, label
);
741 tcg_temp_free_i32(tmp
);
744 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
749 static const uint8_t table_logic_cc
[16] = {
768 /* Set PC and Thumb state from an immediate address. */
769 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
773 s
->is_jmp
= DISAS_UPDATE
;
774 if (s
->thumb
!= (addr
& 1)) {
775 tmp
= tcg_temp_new_i32();
776 tcg_gen_movi_i32(tmp
, addr
& 1);
777 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
778 tcg_temp_free_i32(tmp
);
780 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
783 /* Set PC and Thumb state from var. var is marked as dead. */
784 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
786 s
->is_jmp
= DISAS_UPDATE
;
787 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
788 tcg_gen_andi_i32(var
, var
, 1);
789 store_cpu_field(var
, thumb
);
792 /* Variant of store_reg which uses branch&exchange logic when storing
793 to r15 in ARM architecture v7 and above. The source must be a temporary
794 and will be marked as dead. */
795 static inline void store_reg_bx(CPUARMState
*env
, DisasContext
*s
,
796 int reg
, TCGv_i32 var
)
798 if (reg
== 15 && ENABLE_ARCH_7
) {
801 store_reg(s
, reg
, var
);
805 /* Variant of store_reg which uses branch&exchange logic when storing
806 * to r15 in ARM architecture v5T and above. This is used for storing
807 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
808 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
809 static inline void store_reg_from_load(CPUARMState
*env
, DisasContext
*s
,
810 int reg
, TCGv_i32 var
)
812 if (reg
== 15 && ENABLE_ARCH_5
) {
815 store_reg(s
, reg
, var
);
819 /* Abstractions of "generate code to do a guest load/store for
820 * AArch32", where a vaddr is always 32 bits (and is zero
821 * extended if we're a 64 bit core) and data is also
822 * 32 bits unless specifically doing a 64 bit access.
823 * These functions work like tcg_gen_qemu_{ld,st}* except
824 * that the address argument is TCGv_i32 rather than TCGv.
826 #if TARGET_LONG_BITS == 32
828 #define DO_GEN_LD(SUFF, OPC) \
829 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
831 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
834 #define DO_GEN_ST(SUFF, OPC) \
835 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
837 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
840 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
842 tcg_gen_qemu_ld_i64(val
, addr
, index
, MO_TEQ
);
845 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
847 tcg_gen_qemu_st_i64(val
, addr
, index
, MO_TEQ
);
852 #define DO_GEN_LD(SUFF, OPC) \
853 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
855 TCGv addr64 = tcg_temp_new(); \
856 tcg_gen_extu_i32_i64(addr64, addr); \
857 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
858 tcg_temp_free(addr64); \
861 #define DO_GEN_ST(SUFF, OPC) \
862 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
864 TCGv addr64 = tcg_temp_new(); \
865 tcg_gen_extu_i32_i64(addr64, addr); \
866 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
867 tcg_temp_free(addr64); \
870 static inline void gen_aa32_ld64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
872 TCGv addr64
= tcg_temp_new();
873 tcg_gen_extu_i32_i64(addr64
, addr
);
874 tcg_gen_qemu_ld_i64(val
, addr64
, index
, MO_TEQ
);
875 tcg_temp_free(addr64
);
878 static inline void gen_aa32_st64(TCGv_i64 val
, TCGv_i32 addr
, int index
)
880 TCGv addr64
= tcg_temp_new();
881 tcg_gen_extu_i32_i64(addr64
, addr
);
882 tcg_gen_qemu_st_i64(val
, addr64
, index
, MO_TEQ
);
883 tcg_temp_free(addr64
);
890 DO_GEN_LD(16s
, MO_TESW
)
891 DO_GEN_LD(16u, MO_TEUW
)
892 DO_GEN_LD(32u, MO_TEUL
)
894 DO_GEN_ST(16, MO_TEUW
)
895 DO_GEN_ST(32, MO_TEUL
)
897 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
899 tcg_gen_movi_i32(cpu_R
[15], val
);
902 /* Force a TB lookup after an instruction that changes the CPU state. */
903 static inline void gen_lookup_tb(DisasContext
*s
)
905 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
906 s
->is_jmp
= DISAS_UPDATE
;
909 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
912 int val
, rm
, shift
, shiftop
;
915 if (!(insn
& (1 << 25))) {
918 if (!(insn
& (1 << 23)))
921 tcg_gen_addi_i32(var
, var
, val
);
925 shift
= (insn
>> 7) & 0x1f;
926 shiftop
= (insn
>> 5) & 3;
927 offset
= load_reg(s
, rm
);
928 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
929 if (!(insn
& (1 << 23)))
930 tcg_gen_sub_i32(var
, var
, offset
);
932 tcg_gen_add_i32(var
, var
, offset
);
933 tcg_temp_free_i32(offset
);
937 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
938 int extra
, TCGv_i32 var
)
943 if (insn
& (1 << 22)) {
945 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
946 if (!(insn
& (1 << 23)))
950 tcg_gen_addi_i32(var
, var
, val
);
954 tcg_gen_addi_i32(var
, var
, extra
);
956 offset
= load_reg(s
, rm
);
957 if (!(insn
& (1 << 23)))
958 tcg_gen_sub_i32(var
, var
, offset
);
960 tcg_gen_add_i32(var
, var
, offset
);
961 tcg_temp_free_i32(offset
);
965 static TCGv_ptr
get_fpstatus_ptr(int neon
)
967 TCGv_ptr statusptr
= tcg_temp_new_ptr();
970 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
972 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
974 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
978 #define VFP_OP2(name) \
979 static inline void gen_vfp_##name(int dp) \
981 TCGv_ptr fpst = get_fpstatus_ptr(0); \
983 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
985 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
987 tcg_temp_free_ptr(fpst); \
997 static inline void gen_vfp_F1_mul(int dp
)
999 /* Like gen_vfp_mul() but put result in F1 */
1000 TCGv_ptr fpst
= get_fpstatus_ptr(0);
1002 gen_helper_vfp_muld(cpu_F1d
, cpu_F0d
, cpu_F1d
, fpst
);
1004 gen_helper_vfp_muls(cpu_F1s
, cpu_F0s
, cpu_F1s
, fpst
);
1006 tcg_temp_free_ptr(fpst
);
1009 static inline void gen_vfp_F1_neg(int dp
)
1011 /* Like gen_vfp_neg() but put result in F1 */
1013 gen_helper_vfp_negd(cpu_F1d
, cpu_F0d
);
1015 gen_helper_vfp_negs(cpu_F1s
, cpu_F0s
);
1019 static inline void gen_vfp_abs(int dp
)
1022 gen_helper_vfp_absd(cpu_F0d
, cpu_F0d
);
1024 gen_helper_vfp_abss(cpu_F0s
, cpu_F0s
);
1027 static inline void gen_vfp_neg(int dp
)
1030 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
1032 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
1035 static inline void gen_vfp_sqrt(int dp
)
1038 gen_helper_vfp_sqrtd(cpu_F0d
, cpu_F0d
, cpu_env
);
1040 gen_helper_vfp_sqrts(cpu_F0s
, cpu_F0s
, cpu_env
);
1043 static inline void gen_vfp_cmp(int dp
)
1046 gen_helper_vfp_cmpd(cpu_F0d
, cpu_F1d
, cpu_env
);
1048 gen_helper_vfp_cmps(cpu_F0s
, cpu_F1s
, cpu_env
);
1051 static inline void gen_vfp_cmpe(int dp
)
1054 gen_helper_vfp_cmped(cpu_F0d
, cpu_F1d
, cpu_env
);
1056 gen_helper_vfp_cmpes(cpu_F0s
, cpu_F1s
, cpu_env
);
1059 static inline void gen_vfp_F1_ld0(int dp
)
1062 tcg_gen_movi_i64(cpu_F1d
, 0);
1064 tcg_gen_movi_i32(cpu_F1s
, 0);
1067 #define VFP_GEN_ITOF(name) \
1068 static inline void gen_vfp_##name(int dp, int neon) \
1070 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1072 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1074 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1076 tcg_temp_free_ptr(statusptr); \
1083 #define VFP_GEN_FTOI(name) \
1084 static inline void gen_vfp_##name(int dp, int neon) \
1086 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1088 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1090 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1092 tcg_temp_free_ptr(statusptr); \
1101 #define VFP_GEN_FIX(name, round) \
1102 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1104 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1105 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1107 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1110 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1113 tcg_temp_free_i32(tmp_shift); \
1114 tcg_temp_free_ptr(statusptr); \
1116 VFP_GEN_FIX(tosh
, _round_to_zero
)
1117 VFP_GEN_FIX(tosl
, _round_to_zero
)
1118 VFP_GEN_FIX(touh
, _round_to_zero
)
1119 VFP_GEN_FIX(toul
, _round_to_zero
)
1126 static inline void gen_vfp_ld(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1129 gen_aa32_ld64(cpu_F0d
, addr
, IS_USER(s
));
1131 gen_aa32_ld32u(cpu_F0s
, addr
, IS_USER(s
));
1135 static inline void gen_vfp_st(DisasContext
*s
, int dp
, TCGv_i32 addr
)
1138 gen_aa32_st64(cpu_F0d
, addr
, IS_USER(s
));
1140 gen_aa32_st32(cpu_F0s
, addr
, IS_USER(s
));
1145 vfp_reg_offset (int dp
, int reg
)
1148 return offsetof(CPUARMState
, vfp
.regs
[reg
]);
1150 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1151 + offsetof(CPU_DoubleU
, l
.upper
);
1153 return offsetof(CPUARMState
, vfp
.regs
[reg
>> 1])
1154 + offsetof(CPU_DoubleU
, l
.lower
);
1158 /* Return the offset of a 32-bit piece of a NEON register.
1159 zero is the least significant end of the register. */
1161 neon_reg_offset (int reg
, int n
)
1165 return vfp_reg_offset(0, sreg
);
1168 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1170 TCGv_i32 tmp
= tcg_temp_new_i32();
1171 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1175 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1177 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1178 tcg_temp_free_i32(var
);
1181 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1183 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1186 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1188 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1191 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1192 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1193 #define tcg_gen_st_f32 tcg_gen_st_i32
1194 #define tcg_gen_st_f64 tcg_gen_st_i64
1196 static inline void gen_mov_F0_vreg(int dp
, int reg
)
1199 tcg_gen_ld_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1201 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1204 static inline void gen_mov_F1_vreg(int dp
, int reg
)
1207 tcg_gen_ld_f64(cpu_F1d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1209 tcg_gen_ld_f32(cpu_F1s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1212 static inline void gen_mov_vreg_F0(int dp
, int reg
)
1215 tcg_gen_st_f64(cpu_F0d
, cpu_env
, vfp_reg_offset(dp
, reg
));
1217 tcg_gen_st_f32(cpu_F0s
, cpu_env
, vfp_reg_offset(dp
, reg
));
1220 #define ARM_CP_RW_BIT (1 << 20)
1222 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1224 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1227 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1229 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1232 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1234 TCGv_i32 var
= tcg_temp_new_i32();
1235 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1239 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1241 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1242 tcg_temp_free_i32(var
);
1245 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1247 iwmmxt_store_reg(cpu_M0
, rn
);
1250 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1252 iwmmxt_load_reg(cpu_M0
, rn
);
1255 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1257 iwmmxt_load_reg(cpu_V1
, rn
);
1258 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1261 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1263 iwmmxt_load_reg(cpu_V1
, rn
);
1264 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1267 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1269 iwmmxt_load_reg(cpu_V1
, rn
);
1270 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1273 #define IWMMXT_OP(name) \
1274 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1276 iwmmxt_load_reg(cpu_V1, rn); \
1277 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1280 #define IWMMXT_OP_ENV(name) \
1281 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1283 iwmmxt_load_reg(cpu_V1, rn); \
1284 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1287 #define IWMMXT_OP_ENV_SIZE(name) \
1288 IWMMXT_OP_ENV(name##b) \
1289 IWMMXT_OP_ENV(name##w) \
1290 IWMMXT_OP_ENV(name##l)
1292 #define IWMMXT_OP_ENV1(name) \
1293 static inline void gen_op_iwmmxt_##name##_M0(void) \
1295 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1309 IWMMXT_OP_ENV_SIZE(unpackl
)
1310 IWMMXT_OP_ENV_SIZE(unpackh
)
1312 IWMMXT_OP_ENV1(unpacklub
)
1313 IWMMXT_OP_ENV1(unpackluw
)
1314 IWMMXT_OP_ENV1(unpacklul
)
1315 IWMMXT_OP_ENV1(unpackhub
)
1316 IWMMXT_OP_ENV1(unpackhuw
)
1317 IWMMXT_OP_ENV1(unpackhul
)
1318 IWMMXT_OP_ENV1(unpacklsb
)
1319 IWMMXT_OP_ENV1(unpacklsw
)
1320 IWMMXT_OP_ENV1(unpacklsl
)
1321 IWMMXT_OP_ENV1(unpackhsb
)
1322 IWMMXT_OP_ENV1(unpackhsw
)
1323 IWMMXT_OP_ENV1(unpackhsl
)
1325 IWMMXT_OP_ENV_SIZE(cmpeq
)
1326 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1327 IWMMXT_OP_ENV_SIZE(cmpgts
)
1329 IWMMXT_OP_ENV_SIZE(mins
)
1330 IWMMXT_OP_ENV_SIZE(minu
)
1331 IWMMXT_OP_ENV_SIZE(maxs
)
1332 IWMMXT_OP_ENV_SIZE(maxu
)
1334 IWMMXT_OP_ENV_SIZE(subn
)
1335 IWMMXT_OP_ENV_SIZE(addn
)
1336 IWMMXT_OP_ENV_SIZE(subu
)
1337 IWMMXT_OP_ENV_SIZE(addu
)
1338 IWMMXT_OP_ENV_SIZE(subs
)
1339 IWMMXT_OP_ENV_SIZE(adds
)
1341 IWMMXT_OP_ENV(avgb0
)
1342 IWMMXT_OP_ENV(avgb1
)
1343 IWMMXT_OP_ENV(avgw0
)
1344 IWMMXT_OP_ENV(avgw1
)
1348 IWMMXT_OP_ENV(packuw
)
1349 IWMMXT_OP_ENV(packul
)
1350 IWMMXT_OP_ENV(packuq
)
1351 IWMMXT_OP_ENV(packsw
)
1352 IWMMXT_OP_ENV(packsl
)
1353 IWMMXT_OP_ENV(packsq
)
1355 static void gen_op_iwmmxt_set_mup(void)
1358 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1359 tcg_gen_ori_i32(tmp
, tmp
, 2);
1360 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1363 static void gen_op_iwmmxt_set_cup(void)
1366 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1367 tcg_gen_ori_i32(tmp
, tmp
, 1);
1368 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1371 static void gen_op_iwmmxt_setpsr_nz(void)
1373 TCGv_i32 tmp
= tcg_temp_new_i32();
1374 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1375 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1378 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1380 iwmmxt_load_reg(cpu_V1
, rn
);
1381 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1382 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1385 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1392 rd
= (insn
>> 16) & 0xf;
1393 tmp
= load_reg(s
, rd
);
1395 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1396 if (insn
& (1 << 24)) {
1398 if (insn
& (1 << 23))
1399 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1401 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1402 tcg_gen_mov_i32(dest
, tmp
);
1403 if (insn
& (1 << 21))
1404 store_reg(s
, rd
, tmp
);
1406 tcg_temp_free_i32(tmp
);
1407 } else if (insn
& (1 << 21)) {
1409 tcg_gen_mov_i32(dest
, tmp
);
1410 if (insn
& (1 << 23))
1411 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1413 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1414 store_reg(s
, rd
, tmp
);
1415 } else if (!(insn
& (1 << 23)))
1420 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1422 int rd
= (insn
>> 0) & 0xf;
1425 if (insn
& (1 << 8)) {
1426 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1429 tmp
= iwmmxt_load_creg(rd
);
1432 tmp
= tcg_temp_new_i32();
1433 iwmmxt_load_reg(cpu_V0
, rd
);
1434 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
1436 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1437 tcg_gen_mov_i32(dest
, tmp
);
1438 tcg_temp_free_i32(tmp
);
1442 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1443 (ie. an undefined instruction). */
1444 static int disas_iwmmxt_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
1447 int rdhi
, rdlo
, rd0
, rd1
, i
;
1449 TCGv_i32 tmp
, tmp2
, tmp3
;
1451 if ((insn
& 0x0e000e00) == 0x0c000000) {
1452 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1454 rdlo
= (insn
>> 12) & 0xf;
1455 rdhi
= (insn
>> 16) & 0xf;
1456 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1457 iwmmxt_load_reg(cpu_V0
, wrd
);
1458 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1459 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1460 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1461 } else { /* TMCRR */
1462 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1463 iwmmxt_store_reg(cpu_V0
, wrd
);
1464 gen_op_iwmmxt_set_mup();
1469 wrd
= (insn
>> 12) & 0xf;
1470 addr
= tcg_temp_new_i32();
1471 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1472 tcg_temp_free_i32(addr
);
1475 if (insn
& ARM_CP_RW_BIT
) {
1476 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1477 tmp
= tcg_temp_new_i32();
1478 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1479 iwmmxt_store_creg(wrd
, tmp
);
1482 if (insn
& (1 << 8)) {
1483 if (insn
& (1 << 22)) { /* WLDRD */
1484 gen_aa32_ld64(cpu_M0
, addr
, IS_USER(s
));
1486 } else { /* WLDRW wRd */
1487 tmp
= tcg_temp_new_i32();
1488 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
1491 tmp
= tcg_temp_new_i32();
1492 if (insn
& (1 << 22)) { /* WLDRH */
1493 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
1494 } else { /* WLDRB */
1495 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
1499 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1500 tcg_temp_free_i32(tmp
);
1502 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1505 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1506 tmp
= iwmmxt_load_creg(wrd
);
1507 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1509 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1510 tmp
= tcg_temp_new_i32();
1511 if (insn
& (1 << 8)) {
1512 if (insn
& (1 << 22)) { /* WSTRD */
1513 gen_aa32_st64(cpu_M0
, addr
, IS_USER(s
));
1514 } else { /* WSTRW wRd */
1515 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1516 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
1519 if (insn
& (1 << 22)) { /* WSTRH */
1520 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1521 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
1522 } else { /* WSTRB */
1523 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1524 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
1528 tcg_temp_free_i32(tmp
);
1530 tcg_temp_free_i32(addr
);
1534 if ((insn
& 0x0f000000) != 0x0e000000)
1537 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1538 case 0x000: /* WOR */
1539 wrd
= (insn
>> 12) & 0xf;
1540 rd0
= (insn
>> 0) & 0xf;
1541 rd1
= (insn
>> 16) & 0xf;
1542 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1543 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1544 gen_op_iwmmxt_setpsr_nz();
1545 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1546 gen_op_iwmmxt_set_mup();
1547 gen_op_iwmmxt_set_cup();
1549 case 0x011: /* TMCR */
1552 rd
= (insn
>> 12) & 0xf;
1553 wrd
= (insn
>> 16) & 0xf;
1555 case ARM_IWMMXT_wCID
:
1556 case ARM_IWMMXT_wCASF
:
1558 case ARM_IWMMXT_wCon
:
1559 gen_op_iwmmxt_set_cup();
1561 case ARM_IWMMXT_wCSSF
:
1562 tmp
= iwmmxt_load_creg(wrd
);
1563 tmp2
= load_reg(s
, rd
);
1564 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1565 tcg_temp_free_i32(tmp2
);
1566 iwmmxt_store_creg(wrd
, tmp
);
1568 case ARM_IWMMXT_wCGR0
:
1569 case ARM_IWMMXT_wCGR1
:
1570 case ARM_IWMMXT_wCGR2
:
1571 case ARM_IWMMXT_wCGR3
:
1572 gen_op_iwmmxt_set_cup();
1573 tmp
= load_reg(s
, rd
);
1574 iwmmxt_store_creg(wrd
, tmp
);
1580 case 0x100: /* WXOR */
1581 wrd
= (insn
>> 12) & 0xf;
1582 rd0
= (insn
>> 0) & 0xf;
1583 rd1
= (insn
>> 16) & 0xf;
1584 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1585 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1586 gen_op_iwmmxt_setpsr_nz();
1587 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1588 gen_op_iwmmxt_set_mup();
1589 gen_op_iwmmxt_set_cup();
1591 case 0x111: /* TMRC */
1594 rd
= (insn
>> 12) & 0xf;
1595 wrd
= (insn
>> 16) & 0xf;
1596 tmp
= iwmmxt_load_creg(wrd
);
1597 store_reg(s
, rd
, tmp
);
1599 case 0x300: /* WANDN */
1600 wrd
= (insn
>> 12) & 0xf;
1601 rd0
= (insn
>> 0) & 0xf;
1602 rd1
= (insn
>> 16) & 0xf;
1603 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1604 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1605 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1606 gen_op_iwmmxt_setpsr_nz();
1607 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1608 gen_op_iwmmxt_set_mup();
1609 gen_op_iwmmxt_set_cup();
1611 case 0x200: /* WAND */
1612 wrd
= (insn
>> 12) & 0xf;
1613 rd0
= (insn
>> 0) & 0xf;
1614 rd1
= (insn
>> 16) & 0xf;
1615 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1616 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1617 gen_op_iwmmxt_setpsr_nz();
1618 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1619 gen_op_iwmmxt_set_mup();
1620 gen_op_iwmmxt_set_cup();
1622 case 0x810: case 0xa10: /* WMADD */
1623 wrd
= (insn
>> 12) & 0xf;
1624 rd0
= (insn
>> 0) & 0xf;
1625 rd1
= (insn
>> 16) & 0xf;
1626 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1627 if (insn
& (1 << 21))
1628 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1630 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1631 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1632 gen_op_iwmmxt_set_mup();
1634 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1635 wrd
= (insn
>> 12) & 0xf;
1636 rd0
= (insn
>> 16) & 0xf;
1637 rd1
= (insn
>> 0) & 0xf;
1638 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1639 switch ((insn
>> 22) & 3) {
1641 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1644 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1647 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1652 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1653 gen_op_iwmmxt_set_mup();
1654 gen_op_iwmmxt_set_cup();
1656 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1657 wrd
= (insn
>> 12) & 0xf;
1658 rd0
= (insn
>> 16) & 0xf;
1659 rd1
= (insn
>> 0) & 0xf;
1660 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1661 switch ((insn
>> 22) & 3) {
1663 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1666 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1669 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1674 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1675 gen_op_iwmmxt_set_mup();
1676 gen_op_iwmmxt_set_cup();
1678 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1679 wrd
= (insn
>> 12) & 0xf;
1680 rd0
= (insn
>> 16) & 0xf;
1681 rd1
= (insn
>> 0) & 0xf;
1682 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1683 if (insn
& (1 << 22))
1684 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1686 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1687 if (!(insn
& (1 << 20)))
1688 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1689 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1690 gen_op_iwmmxt_set_mup();
1692 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1693 wrd
= (insn
>> 12) & 0xf;
1694 rd0
= (insn
>> 16) & 0xf;
1695 rd1
= (insn
>> 0) & 0xf;
1696 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1697 if (insn
& (1 << 21)) {
1698 if (insn
& (1 << 20))
1699 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1701 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1703 if (insn
& (1 << 20))
1704 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1706 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1708 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1709 gen_op_iwmmxt_set_mup();
1711 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1712 wrd
= (insn
>> 12) & 0xf;
1713 rd0
= (insn
>> 16) & 0xf;
1714 rd1
= (insn
>> 0) & 0xf;
1715 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1716 if (insn
& (1 << 21))
1717 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1719 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1720 if (!(insn
& (1 << 20))) {
1721 iwmmxt_load_reg(cpu_V1
, wrd
);
1722 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1724 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1725 gen_op_iwmmxt_set_mup();
1727 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1728 wrd
= (insn
>> 12) & 0xf;
1729 rd0
= (insn
>> 16) & 0xf;
1730 rd1
= (insn
>> 0) & 0xf;
1731 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1732 switch ((insn
>> 22) & 3) {
1734 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1737 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1740 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1745 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1746 gen_op_iwmmxt_set_mup();
1747 gen_op_iwmmxt_set_cup();
1749 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1750 wrd
= (insn
>> 12) & 0xf;
1751 rd0
= (insn
>> 16) & 0xf;
1752 rd1
= (insn
>> 0) & 0xf;
1753 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1754 if (insn
& (1 << 22)) {
1755 if (insn
& (1 << 20))
1756 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1758 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1760 if (insn
& (1 << 20))
1761 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1763 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1765 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1766 gen_op_iwmmxt_set_mup();
1767 gen_op_iwmmxt_set_cup();
1769 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1770 wrd
= (insn
>> 12) & 0xf;
1771 rd0
= (insn
>> 16) & 0xf;
1772 rd1
= (insn
>> 0) & 0xf;
1773 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1774 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1775 tcg_gen_andi_i32(tmp
, tmp
, 7);
1776 iwmmxt_load_reg(cpu_V1
, rd1
);
1777 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1778 tcg_temp_free_i32(tmp
);
1779 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1780 gen_op_iwmmxt_set_mup();
1782 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1783 if (((insn
>> 6) & 3) == 3)
1785 rd
= (insn
>> 12) & 0xf;
1786 wrd
= (insn
>> 16) & 0xf;
1787 tmp
= load_reg(s
, rd
);
1788 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1789 switch ((insn
>> 6) & 3) {
1791 tmp2
= tcg_const_i32(0xff);
1792 tmp3
= tcg_const_i32((insn
& 7) << 3);
1795 tmp2
= tcg_const_i32(0xffff);
1796 tmp3
= tcg_const_i32((insn
& 3) << 4);
1799 tmp2
= tcg_const_i32(0xffffffff);
1800 tmp3
= tcg_const_i32((insn
& 1) << 5);
1803 TCGV_UNUSED_I32(tmp2
);
1804 TCGV_UNUSED_I32(tmp3
);
1806 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1807 tcg_temp_free_i32(tmp3
);
1808 tcg_temp_free_i32(tmp2
);
1809 tcg_temp_free_i32(tmp
);
1810 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1811 gen_op_iwmmxt_set_mup();
1813 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1814 rd
= (insn
>> 12) & 0xf;
1815 wrd
= (insn
>> 16) & 0xf;
1816 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1818 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1819 tmp
= tcg_temp_new_i32();
1820 switch ((insn
>> 22) & 3) {
1822 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1823 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1825 tcg_gen_ext8s_i32(tmp
, tmp
);
1827 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1831 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1832 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1834 tcg_gen_ext16s_i32(tmp
, tmp
);
1836 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1840 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1841 tcg_gen_trunc_i64_i32(tmp
, cpu_M0
);
1844 store_reg(s
, rd
, tmp
);
1846 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1847 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1849 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1850 switch ((insn
>> 22) & 3) {
1852 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1855 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1858 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1861 tcg_gen_shli_i32(tmp
, tmp
, 28);
1863 tcg_temp_free_i32(tmp
);
1865 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1866 if (((insn
>> 6) & 3) == 3)
1868 rd
= (insn
>> 12) & 0xf;
1869 wrd
= (insn
>> 16) & 0xf;
1870 tmp
= load_reg(s
, rd
);
1871 switch ((insn
>> 6) & 3) {
1873 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
1876 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
1879 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
1882 tcg_temp_free_i32(tmp
);
1883 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1884 gen_op_iwmmxt_set_mup();
1886 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1887 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1889 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1890 tmp2
= tcg_temp_new_i32();
1891 tcg_gen_mov_i32(tmp2
, tmp
);
1892 switch ((insn
>> 22) & 3) {
1894 for (i
= 0; i
< 7; i
++) {
1895 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1896 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1900 for (i
= 0; i
< 3; i
++) {
1901 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1902 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1906 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1907 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
1911 tcg_temp_free_i32(tmp2
);
1912 tcg_temp_free_i32(tmp
);
1914 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1915 wrd
= (insn
>> 12) & 0xf;
1916 rd0
= (insn
>> 16) & 0xf;
1917 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1918 switch ((insn
>> 22) & 3) {
1920 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
1923 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
1926 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
1931 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1932 gen_op_iwmmxt_set_mup();
1934 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1935 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1937 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1938 tmp2
= tcg_temp_new_i32();
1939 tcg_gen_mov_i32(tmp2
, tmp
);
1940 switch ((insn
>> 22) & 3) {
1942 for (i
= 0; i
< 7; i
++) {
1943 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
1944 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1948 for (i
= 0; i
< 3; i
++) {
1949 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
1950 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1954 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
1955 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
1959 tcg_temp_free_i32(tmp2
);
1960 tcg_temp_free_i32(tmp
);
1962 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1963 rd
= (insn
>> 12) & 0xf;
1964 rd0
= (insn
>> 16) & 0xf;
1965 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
1967 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1968 tmp
= tcg_temp_new_i32();
1969 switch ((insn
>> 22) & 3) {
1971 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
1974 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
1977 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
1980 store_reg(s
, rd
, tmp
);
1982 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1983 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1984 wrd
= (insn
>> 12) & 0xf;
1985 rd0
= (insn
>> 16) & 0xf;
1986 rd1
= (insn
>> 0) & 0xf;
1987 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1988 switch ((insn
>> 22) & 3) {
1990 if (insn
& (1 << 21))
1991 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
1993 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
1996 if (insn
& (1 << 21))
1997 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
1999 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2002 if (insn
& (1 << 21))
2003 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2005 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2010 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2011 gen_op_iwmmxt_set_mup();
2012 gen_op_iwmmxt_set_cup();
2014 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2015 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2016 wrd
= (insn
>> 12) & 0xf;
2017 rd0
= (insn
>> 16) & 0xf;
2018 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2019 switch ((insn
>> 22) & 3) {
2021 if (insn
& (1 << 21))
2022 gen_op_iwmmxt_unpacklsb_M0();
2024 gen_op_iwmmxt_unpacklub_M0();
2027 if (insn
& (1 << 21))
2028 gen_op_iwmmxt_unpacklsw_M0();
2030 gen_op_iwmmxt_unpackluw_M0();
2033 if (insn
& (1 << 21))
2034 gen_op_iwmmxt_unpacklsl_M0();
2036 gen_op_iwmmxt_unpacklul_M0();
2041 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2042 gen_op_iwmmxt_set_mup();
2043 gen_op_iwmmxt_set_cup();
2045 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2046 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2047 wrd
= (insn
>> 12) & 0xf;
2048 rd0
= (insn
>> 16) & 0xf;
2049 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2050 switch ((insn
>> 22) & 3) {
2052 if (insn
& (1 << 21))
2053 gen_op_iwmmxt_unpackhsb_M0();
2055 gen_op_iwmmxt_unpackhub_M0();
2058 if (insn
& (1 << 21))
2059 gen_op_iwmmxt_unpackhsw_M0();
2061 gen_op_iwmmxt_unpackhuw_M0();
2064 if (insn
& (1 << 21))
2065 gen_op_iwmmxt_unpackhsl_M0();
2067 gen_op_iwmmxt_unpackhul_M0();
2072 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2073 gen_op_iwmmxt_set_mup();
2074 gen_op_iwmmxt_set_cup();
2076 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2077 case 0x214: case 0x614: case 0xa14: case 0xe14:
2078 if (((insn
>> 22) & 3) == 0)
2080 wrd
= (insn
>> 12) & 0xf;
2081 rd0
= (insn
>> 16) & 0xf;
2082 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2083 tmp
= tcg_temp_new_i32();
2084 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2085 tcg_temp_free_i32(tmp
);
2088 switch ((insn
>> 22) & 3) {
2090 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2093 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2096 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2099 tcg_temp_free_i32(tmp
);
2100 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2101 gen_op_iwmmxt_set_mup();
2102 gen_op_iwmmxt_set_cup();
2104 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2105 case 0x014: case 0x414: case 0x814: case 0xc14:
2106 if (((insn
>> 22) & 3) == 0)
2108 wrd
= (insn
>> 12) & 0xf;
2109 rd0
= (insn
>> 16) & 0xf;
2110 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2111 tmp
= tcg_temp_new_i32();
2112 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2113 tcg_temp_free_i32(tmp
);
2116 switch ((insn
>> 22) & 3) {
2118 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2121 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2124 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2127 tcg_temp_free_i32(tmp
);
2128 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2129 gen_op_iwmmxt_set_mup();
2130 gen_op_iwmmxt_set_cup();
2132 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2133 case 0x114: case 0x514: case 0x914: case 0xd14:
2134 if (((insn
>> 22) & 3) == 0)
2136 wrd
= (insn
>> 12) & 0xf;
2137 rd0
= (insn
>> 16) & 0xf;
2138 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2139 tmp
= tcg_temp_new_i32();
2140 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2141 tcg_temp_free_i32(tmp
);
2144 switch ((insn
>> 22) & 3) {
2146 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2149 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2152 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2155 tcg_temp_free_i32(tmp
);
2156 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2157 gen_op_iwmmxt_set_mup();
2158 gen_op_iwmmxt_set_cup();
2160 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2161 case 0x314: case 0x714: case 0xb14: case 0xf14:
2162 if (((insn
>> 22) & 3) == 0)
2164 wrd
= (insn
>> 12) & 0xf;
2165 rd0
= (insn
>> 16) & 0xf;
2166 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2167 tmp
= tcg_temp_new_i32();
2168 switch ((insn
>> 22) & 3) {
2170 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2171 tcg_temp_free_i32(tmp
);
2174 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2177 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2178 tcg_temp_free_i32(tmp
);
2181 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2184 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2185 tcg_temp_free_i32(tmp
);
2188 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2191 tcg_temp_free_i32(tmp
);
2192 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2193 gen_op_iwmmxt_set_mup();
2194 gen_op_iwmmxt_set_cup();
2196 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2197 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2198 wrd
= (insn
>> 12) & 0xf;
2199 rd0
= (insn
>> 16) & 0xf;
2200 rd1
= (insn
>> 0) & 0xf;
2201 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2202 switch ((insn
>> 22) & 3) {
2204 if (insn
& (1 << 21))
2205 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2207 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2210 if (insn
& (1 << 21))
2211 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2213 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2216 if (insn
& (1 << 21))
2217 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2219 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2224 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2225 gen_op_iwmmxt_set_mup();
2227 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2228 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2229 wrd
= (insn
>> 12) & 0xf;
2230 rd0
= (insn
>> 16) & 0xf;
2231 rd1
= (insn
>> 0) & 0xf;
2232 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2233 switch ((insn
>> 22) & 3) {
2235 if (insn
& (1 << 21))
2236 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2238 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2241 if (insn
& (1 << 21))
2242 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2244 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2247 if (insn
& (1 << 21))
2248 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2250 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2255 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2256 gen_op_iwmmxt_set_mup();
2258 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2259 case 0x402: case 0x502: case 0x602: case 0x702:
2260 wrd
= (insn
>> 12) & 0xf;
2261 rd0
= (insn
>> 16) & 0xf;
2262 rd1
= (insn
>> 0) & 0xf;
2263 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2264 tmp
= tcg_const_i32((insn
>> 20) & 3);
2265 iwmmxt_load_reg(cpu_V1
, rd1
);
2266 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2267 tcg_temp_free_i32(tmp
);
2268 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2269 gen_op_iwmmxt_set_mup();
2271 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2272 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2273 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2274 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2275 wrd
= (insn
>> 12) & 0xf;
2276 rd0
= (insn
>> 16) & 0xf;
2277 rd1
= (insn
>> 0) & 0xf;
2278 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2279 switch ((insn
>> 20) & 0xf) {
2281 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2284 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2287 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2290 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2293 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2296 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2299 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2302 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2305 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2310 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2311 gen_op_iwmmxt_set_mup();
2312 gen_op_iwmmxt_set_cup();
2314 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2315 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2316 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2317 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2318 wrd
= (insn
>> 12) & 0xf;
2319 rd0
= (insn
>> 16) & 0xf;
2320 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2321 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2322 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2323 tcg_temp_free_i32(tmp
);
2324 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2325 gen_op_iwmmxt_set_mup();
2326 gen_op_iwmmxt_set_cup();
2328 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2329 case 0x418: case 0x518: case 0x618: case 0x718:
2330 case 0x818: case 0x918: case 0xa18: case 0xb18:
2331 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2332 wrd
= (insn
>> 12) & 0xf;
2333 rd0
= (insn
>> 16) & 0xf;
2334 rd1
= (insn
>> 0) & 0xf;
2335 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2336 switch ((insn
>> 20) & 0xf) {
2338 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2341 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2344 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2347 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2350 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2353 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2356 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2359 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2362 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2367 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2368 gen_op_iwmmxt_set_mup();
2369 gen_op_iwmmxt_set_cup();
2371 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2372 case 0x408: case 0x508: case 0x608: case 0x708:
2373 case 0x808: case 0x908: case 0xa08: case 0xb08:
2374 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2375 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2377 wrd
= (insn
>> 12) & 0xf;
2378 rd0
= (insn
>> 16) & 0xf;
2379 rd1
= (insn
>> 0) & 0xf;
2380 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2381 switch ((insn
>> 22) & 3) {
2383 if (insn
& (1 << 21))
2384 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2386 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2389 if (insn
& (1 << 21))
2390 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2392 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2395 if (insn
& (1 << 21))
2396 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2398 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2401 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2402 gen_op_iwmmxt_set_mup();
2403 gen_op_iwmmxt_set_cup();
2405 case 0x201: case 0x203: case 0x205: case 0x207:
2406 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2407 case 0x211: case 0x213: case 0x215: case 0x217:
2408 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2409 wrd
= (insn
>> 5) & 0xf;
2410 rd0
= (insn
>> 12) & 0xf;
2411 rd1
= (insn
>> 0) & 0xf;
2412 if (rd0
== 0xf || rd1
== 0xf)
2414 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2415 tmp
= load_reg(s
, rd0
);
2416 tmp2
= load_reg(s
, rd1
);
2417 switch ((insn
>> 16) & 0xf) {
2418 case 0x0: /* TMIA */
2419 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2421 case 0x8: /* TMIAPH */
2422 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2424 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2425 if (insn
& (1 << 16))
2426 tcg_gen_shri_i32(tmp
, tmp
, 16);
2427 if (insn
& (1 << 17))
2428 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2429 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2432 tcg_temp_free_i32(tmp2
);
2433 tcg_temp_free_i32(tmp
);
2436 tcg_temp_free_i32(tmp2
);
2437 tcg_temp_free_i32(tmp
);
2438 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2439 gen_op_iwmmxt_set_mup();
2448 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2449 (ie. an undefined instruction). */
2450 static int disas_dsp_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2452 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2455 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2456 /* Multiply with Internal Accumulate Format */
2457 rd0
= (insn
>> 12) & 0xf;
2459 acc
= (insn
>> 5) & 7;
2464 tmp
= load_reg(s
, rd0
);
2465 tmp2
= load_reg(s
, rd1
);
2466 switch ((insn
>> 16) & 0xf) {
2468 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2470 case 0x8: /* MIAPH */
2471 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2473 case 0xc: /* MIABB */
2474 case 0xd: /* MIABT */
2475 case 0xe: /* MIATB */
2476 case 0xf: /* MIATT */
2477 if (insn
& (1 << 16))
2478 tcg_gen_shri_i32(tmp
, tmp
, 16);
2479 if (insn
& (1 << 17))
2480 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2481 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2486 tcg_temp_free_i32(tmp2
);
2487 tcg_temp_free_i32(tmp
);
2489 gen_op_iwmmxt_movq_wRn_M0(acc
);
2493 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2494 /* Internal Accumulator Access Format */
2495 rdhi
= (insn
>> 16) & 0xf;
2496 rdlo
= (insn
>> 12) & 0xf;
2502 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2503 iwmmxt_load_reg(cpu_V0
, acc
);
2504 tcg_gen_trunc_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2505 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2506 tcg_gen_trunc_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2507 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2509 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2510 iwmmxt_store_reg(cpu_V0
, acc
);
2518 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2519 #define VFP_SREG(insn, bigbit, smallbit) \
2520 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2521 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2522 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2523 reg = (((insn) >> (bigbit)) & 0x0f) \
2524 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2526 if (insn & (1 << (smallbit))) \
2528 reg = ((insn) >> (bigbit)) & 0x0f; \
2531 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2532 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2533 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2534 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2535 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2536 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2538 /* Move between integer and VFP cores. */
2539 static TCGv_i32
gen_vfp_mrs(void)
2541 TCGv_i32 tmp
= tcg_temp_new_i32();
2542 tcg_gen_mov_i32(tmp
, cpu_F0s
);
2546 static void gen_vfp_msr(TCGv_i32 tmp
)
2548 tcg_gen_mov_i32(cpu_F0s
, tmp
);
2549 tcg_temp_free_i32(tmp
);
2552 static void gen_neon_dup_u8(TCGv_i32 var
, int shift
)
2554 TCGv_i32 tmp
= tcg_temp_new_i32();
2556 tcg_gen_shri_i32(var
, var
, shift
);
2557 tcg_gen_ext8u_i32(var
, var
);
2558 tcg_gen_shli_i32(tmp
, var
, 8);
2559 tcg_gen_or_i32(var
, var
, tmp
);
2560 tcg_gen_shli_i32(tmp
, var
, 16);
2561 tcg_gen_or_i32(var
, var
, tmp
);
2562 tcg_temp_free_i32(tmp
);
2565 static void gen_neon_dup_low16(TCGv_i32 var
)
2567 TCGv_i32 tmp
= tcg_temp_new_i32();
2568 tcg_gen_ext16u_i32(var
, var
);
2569 tcg_gen_shli_i32(tmp
, var
, 16);
2570 tcg_gen_or_i32(var
, var
, tmp
);
2571 tcg_temp_free_i32(tmp
);
2574 static void gen_neon_dup_high16(TCGv_i32 var
)
2576 TCGv_i32 tmp
= tcg_temp_new_i32();
2577 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2578 tcg_gen_shri_i32(tmp
, var
, 16);
2579 tcg_gen_or_i32(var
, var
, tmp
);
2580 tcg_temp_free_i32(tmp
);
2583 static TCGv_i32
gen_load_and_replicate(DisasContext
*s
, TCGv_i32 addr
, int size
)
2585 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2586 TCGv_i32 tmp
= tcg_temp_new_i32();
2589 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
2590 gen_neon_dup_u8(tmp
, 0);
2593 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
2594 gen_neon_dup_low16(tmp
);
2597 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
2599 default: /* Avoid compiler warnings. */
2605 static int handle_vsel(uint32_t insn
, uint32_t rd
, uint32_t rn
, uint32_t rm
,
2608 uint32_t cc
= extract32(insn
, 20, 2);
2611 TCGv_i64 frn
, frm
, dest
;
2612 TCGv_i64 tmp
, zero
, zf
, nf
, vf
;
2614 zero
= tcg_const_i64(0);
2616 frn
= tcg_temp_new_i64();
2617 frm
= tcg_temp_new_i64();
2618 dest
= tcg_temp_new_i64();
2620 zf
= tcg_temp_new_i64();
2621 nf
= tcg_temp_new_i64();
2622 vf
= tcg_temp_new_i64();
2624 tcg_gen_extu_i32_i64(zf
, cpu_ZF
);
2625 tcg_gen_ext_i32_i64(nf
, cpu_NF
);
2626 tcg_gen_ext_i32_i64(vf
, cpu_VF
);
2628 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2629 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2632 tcg_gen_movcond_i64(TCG_COND_EQ
, dest
, zf
, zero
,
2636 tcg_gen_movcond_i64(TCG_COND_LT
, dest
, vf
, zero
,
2639 case 2: /* ge: N == V -> N ^ V == 0 */
2640 tmp
= tcg_temp_new_i64();
2641 tcg_gen_xor_i64(tmp
, vf
, nf
);
2642 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2644 tcg_temp_free_i64(tmp
);
2646 case 3: /* gt: !Z && N == V */
2647 tcg_gen_movcond_i64(TCG_COND_NE
, dest
, zf
, zero
,
2649 tmp
= tcg_temp_new_i64();
2650 tcg_gen_xor_i64(tmp
, vf
, nf
);
2651 tcg_gen_movcond_i64(TCG_COND_GE
, dest
, tmp
, zero
,
2653 tcg_temp_free_i64(tmp
);
2656 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2657 tcg_temp_free_i64(frn
);
2658 tcg_temp_free_i64(frm
);
2659 tcg_temp_free_i64(dest
);
2661 tcg_temp_free_i64(zf
);
2662 tcg_temp_free_i64(nf
);
2663 tcg_temp_free_i64(vf
);
2665 tcg_temp_free_i64(zero
);
2667 TCGv_i32 frn
, frm
, dest
;
2670 zero
= tcg_const_i32(0);
2672 frn
= tcg_temp_new_i32();
2673 frm
= tcg_temp_new_i32();
2674 dest
= tcg_temp_new_i32();
2675 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2676 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2679 tcg_gen_movcond_i32(TCG_COND_EQ
, dest
, cpu_ZF
, zero
,
2683 tcg_gen_movcond_i32(TCG_COND_LT
, dest
, cpu_VF
, zero
,
2686 case 2: /* ge: N == V -> N ^ V == 0 */
2687 tmp
= tcg_temp_new_i32();
2688 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2689 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2691 tcg_temp_free_i32(tmp
);
2693 case 3: /* gt: !Z && N == V */
2694 tcg_gen_movcond_i32(TCG_COND_NE
, dest
, cpu_ZF
, zero
,
2696 tmp
= tcg_temp_new_i32();
2697 tcg_gen_xor_i32(tmp
, cpu_VF
, cpu_NF
);
2698 tcg_gen_movcond_i32(TCG_COND_GE
, dest
, tmp
, zero
,
2700 tcg_temp_free_i32(tmp
);
2703 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2704 tcg_temp_free_i32(frn
);
2705 tcg_temp_free_i32(frm
);
2706 tcg_temp_free_i32(dest
);
2708 tcg_temp_free_i32(zero
);
2714 static int handle_vminmaxnm(uint32_t insn
, uint32_t rd
, uint32_t rn
,
2715 uint32_t rm
, uint32_t dp
)
2717 uint32_t vmin
= extract32(insn
, 6, 1);
2718 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2721 TCGv_i64 frn
, frm
, dest
;
2723 frn
= tcg_temp_new_i64();
2724 frm
= tcg_temp_new_i64();
2725 dest
= tcg_temp_new_i64();
2727 tcg_gen_ld_f64(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2728 tcg_gen_ld_f64(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2730 gen_helper_vfp_minnumd(dest
, frn
, frm
, fpst
);
2732 gen_helper_vfp_maxnumd(dest
, frn
, frm
, fpst
);
2734 tcg_gen_st_f64(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2735 tcg_temp_free_i64(frn
);
2736 tcg_temp_free_i64(frm
);
2737 tcg_temp_free_i64(dest
);
2739 TCGv_i32 frn
, frm
, dest
;
2741 frn
= tcg_temp_new_i32();
2742 frm
= tcg_temp_new_i32();
2743 dest
= tcg_temp_new_i32();
2745 tcg_gen_ld_f32(frn
, cpu_env
, vfp_reg_offset(dp
, rn
));
2746 tcg_gen_ld_f32(frm
, cpu_env
, vfp_reg_offset(dp
, rm
));
2748 gen_helper_vfp_minnums(dest
, frn
, frm
, fpst
);
2750 gen_helper_vfp_maxnums(dest
, frn
, frm
, fpst
);
2752 tcg_gen_st_f32(dest
, cpu_env
, vfp_reg_offset(dp
, rd
));
2753 tcg_temp_free_i32(frn
);
2754 tcg_temp_free_i32(frm
);
2755 tcg_temp_free_i32(dest
);
2758 tcg_temp_free_ptr(fpst
);
2762 static int handle_vrint(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2765 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2768 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2769 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2774 tcg_op
= tcg_temp_new_i64();
2775 tcg_res
= tcg_temp_new_i64();
2776 tcg_gen_ld_f64(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2777 gen_helper_rintd(tcg_res
, tcg_op
, fpst
);
2778 tcg_gen_st_f64(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2779 tcg_temp_free_i64(tcg_op
);
2780 tcg_temp_free_i64(tcg_res
);
2784 tcg_op
= tcg_temp_new_i32();
2785 tcg_res
= tcg_temp_new_i32();
2786 tcg_gen_ld_f32(tcg_op
, cpu_env
, vfp_reg_offset(dp
, rm
));
2787 gen_helper_rints(tcg_res
, tcg_op
, fpst
);
2788 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(dp
, rd
));
2789 tcg_temp_free_i32(tcg_op
);
2790 tcg_temp_free_i32(tcg_res
);
2793 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2794 tcg_temp_free_i32(tcg_rmode
);
2796 tcg_temp_free_ptr(fpst
);
2800 static int handle_vcvt(uint32_t insn
, uint32_t rd
, uint32_t rm
, uint32_t dp
,
2803 bool is_signed
= extract32(insn
, 7, 1);
2804 TCGv_ptr fpst
= get_fpstatus_ptr(0);
2805 TCGv_i32 tcg_rmode
, tcg_shift
;
2807 tcg_shift
= tcg_const_i32(0);
2809 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rounding
));
2810 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2813 TCGv_i64 tcg_double
, tcg_res
;
2815 /* Rd is encoded as a single precision register even when the source
2816 * is double precision.
2818 rd
= ((rd
<< 1) & 0x1e) | ((rd
>> 4) & 0x1);
2819 tcg_double
= tcg_temp_new_i64();
2820 tcg_res
= tcg_temp_new_i64();
2821 tcg_tmp
= tcg_temp_new_i32();
2822 tcg_gen_ld_f64(tcg_double
, cpu_env
, vfp_reg_offset(1, rm
));
2824 gen_helper_vfp_tosld(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2826 gen_helper_vfp_tould(tcg_res
, tcg_double
, tcg_shift
, fpst
);
2828 tcg_gen_trunc_i64_i32(tcg_tmp
, tcg_res
);
2829 tcg_gen_st_f32(tcg_tmp
, cpu_env
, vfp_reg_offset(0, rd
));
2830 tcg_temp_free_i32(tcg_tmp
);
2831 tcg_temp_free_i64(tcg_res
);
2832 tcg_temp_free_i64(tcg_double
);
2834 TCGv_i32 tcg_single
, tcg_res
;
2835 tcg_single
= tcg_temp_new_i32();
2836 tcg_res
= tcg_temp_new_i32();
2837 tcg_gen_ld_f32(tcg_single
, cpu_env
, vfp_reg_offset(0, rm
));
2839 gen_helper_vfp_tosls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2841 gen_helper_vfp_touls(tcg_res
, tcg_single
, tcg_shift
, fpst
);
2843 tcg_gen_st_f32(tcg_res
, cpu_env
, vfp_reg_offset(0, rd
));
2844 tcg_temp_free_i32(tcg_res
);
2845 tcg_temp_free_i32(tcg_single
);
2848 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
2849 tcg_temp_free_i32(tcg_rmode
);
2851 tcg_temp_free_i32(tcg_shift
);
2853 tcg_temp_free_ptr(fpst
);
2858 /* Table for converting the most common AArch32 encoding of
2859 * rounding mode to arm_fprounding order (which matches the
2860 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2862 static const uint8_t fp_decode_rm
[] = {
2869 static int disas_vfp_v8_insn(CPUARMState
*env
, DisasContext
*s
, uint32_t insn
)
2871 uint32_t rd
, rn
, rm
, dp
= extract32(insn
, 8, 1);
2873 if (!arm_feature(env
, ARM_FEATURE_V8
)) {
2878 VFP_DREG_D(rd
, insn
);
2879 VFP_DREG_N(rn
, insn
);
2880 VFP_DREG_M(rm
, insn
);
2882 rd
= VFP_SREG_D(insn
);
2883 rn
= VFP_SREG_N(insn
);
2884 rm
= VFP_SREG_M(insn
);
2887 if ((insn
& 0x0f800e50) == 0x0e000a00) {
2888 return handle_vsel(insn
, rd
, rn
, rm
, dp
);
2889 } else if ((insn
& 0x0fb00e10) == 0x0e800a00) {
2890 return handle_vminmaxnm(insn
, rd
, rn
, rm
, dp
);
2891 } else if ((insn
& 0x0fbc0ed0) == 0x0eb80a40) {
2892 /* VRINTA, VRINTN, VRINTP, VRINTM */
2893 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2894 return handle_vrint(insn
, rd
, rm
, dp
, rounding
);
2895 } else if ((insn
& 0x0fbc0e50) == 0x0ebc0a40) {
2896 /* VCVTA, VCVTN, VCVTP, VCVTM */
2897 int rounding
= fp_decode_rm
[extract32(insn
, 16, 2)];
2898 return handle_vcvt(insn
, rd
, rm
, dp
, rounding
);
2903 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2904 (ie. an undefined instruction). */
2905 static int disas_vfp_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
2907 uint32_t rd
, rn
, rm
, op
, i
, n
, offset
, delta_d
, delta_m
, bank_mask
;
2913 if (!arm_feature(env
, ARM_FEATURE_VFP
))
2916 if (!s
->vfp_enabled
) {
2917 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2918 if ((insn
& 0x0fe00fff) != 0x0ee00a10)
2920 rn
= (insn
>> 16) & 0xf;
2921 if (rn
!= ARM_VFP_FPSID
&& rn
!= ARM_VFP_FPEXC
2922 && rn
!= ARM_VFP_MVFR1
&& rn
!= ARM_VFP_MVFR0
)
2926 if (extract32(insn
, 28, 4) == 0xf) {
2927 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2928 * only used in v8 and above.
2930 return disas_vfp_v8_insn(env
, s
, insn
);
2933 dp
= ((insn
& 0xf00) == 0xb00);
2934 switch ((insn
>> 24) & 0xf) {
2936 if (insn
& (1 << 4)) {
2937 /* single register transfer */
2938 rd
= (insn
>> 12) & 0xf;
2943 VFP_DREG_N(rn
, insn
);
2946 if (insn
& 0x00c00060
2947 && !arm_feature(env
, ARM_FEATURE_NEON
))
2950 pass
= (insn
>> 21) & 1;
2951 if (insn
& (1 << 22)) {
2953 offset
= ((insn
>> 5) & 3) * 8;
2954 } else if (insn
& (1 << 5)) {
2956 offset
= (insn
& (1 << 6)) ? 16 : 0;
2961 if (insn
& ARM_CP_RW_BIT
) {
2963 tmp
= neon_load_reg(rn
, pass
);
2967 tcg_gen_shri_i32(tmp
, tmp
, offset
);
2968 if (insn
& (1 << 23))
2974 if (insn
& (1 << 23)) {
2976 tcg_gen_shri_i32(tmp
, tmp
, 16);
2982 tcg_gen_sari_i32(tmp
, tmp
, 16);
2991 store_reg(s
, rd
, tmp
);
2994 tmp
= load_reg(s
, rd
);
2995 if (insn
& (1 << 23)) {
2998 gen_neon_dup_u8(tmp
, 0);
2999 } else if (size
== 1) {
3000 gen_neon_dup_low16(tmp
);
3002 for (n
= 0; n
<= pass
* 2; n
++) {
3003 tmp2
= tcg_temp_new_i32();
3004 tcg_gen_mov_i32(tmp2
, tmp
);
3005 neon_store_reg(rn
, n
, tmp2
);
3007 neon_store_reg(rn
, n
, tmp
);
3012 tmp2
= neon_load_reg(rn
, pass
);
3013 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 8);
3014 tcg_temp_free_i32(tmp2
);
3017 tmp2
= neon_load_reg(rn
, pass
);
3018 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, offset
, 16);
3019 tcg_temp_free_i32(tmp2
);
3024 neon_store_reg(rn
, pass
, tmp
);
3028 if ((insn
& 0x6f) != 0x00)
3030 rn
= VFP_SREG_N(insn
);
3031 if (insn
& ARM_CP_RW_BIT
) {
3033 if (insn
& (1 << 21)) {
3034 /* system register */
3039 /* VFP2 allows access to FSID from userspace.
3040 VFP3 restricts all id registers to privileged
3043 && arm_feature(env
, ARM_FEATURE_VFP3
))
3045 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3050 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3052 case ARM_VFP_FPINST
:
3053 case ARM_VFP_FPINST2
:
3054 /* Not present in VFP3. */
3056 || arm_feature(env
, ARM_FEATURE_VFP3
))
3058 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3062 tmp
= load_cpu_field(vfp
.xregs
[ARM_VFP_FPSCR
]);
3063 tcg_gen_andi_i32(tmp
, tmp
, 0xf0000000);
3065 tmp
= tcg_temp_new_i32();
3066 gen_helper_vfp_get_fpscr(tmp
, cpu_env
);
3072 || !arm_feature(env
, ARM_FEATURE_MVFR
))
3074 tmp
= load_cpu_field(vfp
.xregs
[rn
]);
3080 gen_mov_F0_vreg(0, rn
);
3081 tmp
= gen_vfp_mrs();
3084 /* Set the 4 flag bits in the CPSR. */
3086 tcg_temp_free_i32(tmp
);
3088 store_reg(s
, rd
, tmp
);
3092 if (insn
& (1 << 21)) {
3094 /* system register */
3099 /* Writes are ignored. */
3102 tmp
= load_reg(s
, rd
);
3103 gen_helper_vfp_set_fpscr(cpu_env
, tmp
);
3104 tcg_temp_free_i32(tmp
);
3110 /* TODO: VFP subarchitecture support.
3111 * For now, keep the EN bit only */
3112 tmp
= load_reg(s
, rd
);
3113 tcg_gen_andi_i32(tmp
, tmp
, 1 << 30);
3114 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3117 case ARM_VFP_FPINST
:
3118 case ARM_VFP_FPINST2
:
3119 tmp
= load_reg(s
, rd
);
3120 store_cpu_field(tmp
, vfp
.xregs
[rn
]);
3126 tmp
= load_reg(s
, rd
);
3128 gen_mov_vreg_F0(0, rn
);
3133 /* data processing */
3134 /* The opcode is in bits 23, 21, 20 and 6. */
3135 op
= ((insn
>> 20) & 8) | ((insn
>> 19) & 6) | ((insn
>> 6) & 1);
3139 rn
= ((insn
>> 15) & 0x1e) | ((insn
>> 7) & 1);
3141 /* rn is register number */
3142 VFP_DREG_N(rn
, insn
);
3145 if (op
== 15 && (rn
== 15 || ((rn
& 0x1c) == 0x18))) {
3146 /* Integer or single precision destination. */
3147 rd
= VFP_SREG_D(insn
);
3149 VFP_DREG_D(rd
, insn
);
3152 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14))) {
3153 /* VCVT from int is always from S reg regardless of dp bit.
3154 * VCVT with immediate frac_bits has same format as SREG_M
3156 rm
= VFP_SREG_M(insn
);
3158 VFP_DREG_M(rm
, insn
);
3161 rn
= VFP_SREG_N(insn
);
3162 if (op
== 15 && rn
== 15) {
3163 /* Double precision destination. */
3164 VFP_DREG_D(rd
, insn
);
3166 rd
= VFP_SREG_D(insn
);
3168 /* NB that we implicitly rely on the encoding for the frac_bits
3169 * in VCVT of fixed to float being the same as that of an SREG_M
3171 rm
= VFP_SREG_M(insn
);
3174 veclen
= s
->vec_len
;
3175 if (op
== 15 && rn
> 3)
3178 /* Shut up compiler warnings. */
3189 /* Figure out what type of vector operation this is. */
3190 if ((rd
& bank_mask
) == 0) {
3195 delta_d
= (s
->vec_stride
>> 1) + 1;
3197 delta_d
= s
->vec_stride
+ 1;
3199 if ((rm
& bank_mask
) == 0) {
3200 /* mixed scalar/vector */
3209 /* Load the initial operands. */
3214 /* Integer source */
3215 gen_mov_F0_vreg(0, rm
);
3220 gen_mov_F0_vreg(dp
, rd
);
3221 gen_mov_F1_vreg(dp
, rm
);
3225 /* Compare with zero */
3226 gen_mov_F0_vreg(dp
, rd
);
3237 /* Source and destination the same. */
3238 gen_mov_F0_vreg(dp
, rd
);
3244 /* VCVTB, VCVTT: only present with the halfprec extension,
3245 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3247 if (dp
|| !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3250 /* Otherwise fall through */
3252 /* One source operand. */
3253 gen_mov_F0_vreg(dp
, rm
);
3257 /* Two source operands. */
3258 gen_mov_F0_vreg(dp
, rn
);
3259 gen_mov_F1_vreg(dp
, rm
);
3263 /* Perform the calculation. */
3265 case 0: /* VMLA: fd + (fn * fm) */
3266 /* Note that order of inputs to the add matters for NaNs */
3268 gen_mov_F0_vreg(dp
, rd
);
3271 case 1: /* VMLS: fd + -(fn * fm) */
3274 gen_mov_F0_vreg(dp
, rd
);
3277 case 2: /* VNMLS: -fd + (fn * fm) */
3278 /* Note that it isn't valid to replace (-A + B) with (B - A)
3279 * or similar plausible looking simplifications
3280 * because this will give wrong results for NaNs.
3283 gen_mov_F0_vreg(dp
, rd
);
3287 case 3: /* VNMLA: -fd + -(fn * fm) */
3290 gen_mov_F0_vreg(dp
, rd
);
3294 case 4: /* mul: fn * fm */
3297 case 5: /* nmul: -(fn * fm) */
3301 case 6: /* add: fn + fm */
3304 case 7: /* sub: fn - fm */
3307 case 8: /* div: fn / fm */
3310 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3311 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3312 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3313 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3314 /* These are fused multiply-add, and must be done as one
3315 * floating point operation with no rounding between the
3316 * multiplication and addition steps.
3317 * NB that doing the negations here as separate steps is
3318 * correct : an input NaN should come out with its sign bit
3319 * flipped if it is a negated-input.
3321 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3329 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3331 frd
= tcg_temp_new_i64();
3332 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3335 gen_helper_vfp_negd(frd
, frd
);
3337 fpst
= get_fpstatus_ptr(0);
3338 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3339 cpu_F1d
, frd
, fpst
);
3340 tcg_temp_free_ptr(fpst
);
3341 tcg_temp_free_i64(frd
);
3347 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3349 frd
= tcg_temp_new_i32();
3350 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3352 gen_helper_vfp_negs(frd
, frd
);
3354 fpst
= get_fpstatus_ptr(0);
3355 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3356 cpu_F1s
, frd
, fpst
);
3357 tcg_temp_free_ptr(fpst
);
3358 tcg_temp_free_i32(frd
);
3361 case 14: /* fconst */
3362 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3365 n
= (insn
<< 12) & 0x80000000;
3366 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3373 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3380 tcg_gen_movi_i32(cpu_F0s
, n
);
3383 case 15: /* extension space */
3397 case 4: /* vcvtb.f32.f16 */
3398 tmp
= gen_vfp_mrs();
3399 tcg_gen_ext16u_i32(tmp
, tmp
);
3400 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3401 tcg_temp_free_i32(tmp
);
3403 case 5: /* vcvtt.f32.f16 */
3404 tmp
= gen_vfp_mrs();
3405 tcg_gen_shri_i32(tmp
, tmp
, 16);
3406 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
, cpu_env
);
3407 tcg_temp_free_i32(tmp
);
3409 case 6: /* vcvtb.f16.f32 */
3410 tmp
= tcg_temp_new_i32();
3411 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3412 gen_mov_F0_vreg(0, rd
);
3413 tmp2
= gen_vfp_mrs();
3414 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3415 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3416 tcg_temp_free_i32(tmp2
);
3419 case 7: /* vcvtt.f16.f32 */
3420 tmp
= tcg_temp_new_i32();
3421 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
3422 tcg_gen_shli_i32(tmp
, tmp
, 16);
3423 gen_mov_F0_vreg(0, rd
);
3424 tmp2
= gen_vfp_mrs();
3425 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3426 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3427 tcg_temp_free_i32(tmp2
);
3439 case 11: /* cmpez */
3443 case 12: /* vrintr */
3445 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3447 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3449 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3451 tcg_temp_free_ptr(fpst
);
3454 case 13: /* vrintz */
3456 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3458 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3459 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3461 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3463 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3465 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3466 tcg_temp_free_i32(tcg_rmode
);
3467 tcg_temp_free_ptr(fpst
);
3470 case 14: /* vrintx */
3472 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3474 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3476 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3478 tcg_temp_free_ptr(fpst
);
3481 case 15: /* single<->double conversion */
3483 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3485 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3487 case 16: /* fuito */
3488 gen_vfp_uito(dp
, 0);
3490 case 17: /* fsito */
3491 gen_vfp_sito(dp
, 0);
3493 case 20: /* fshto */
3494 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3496 gen_vfp_shto(dp
, 16 - rm
, 0);
3498 case 21: /* fslto */
3499 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3501 gen_vfp_slto(dp
, 32 - rm
, 0);
3503 case 22: /* fuhto */
3504 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3506 gen_vfp_uhto(dp
, 16 - rm
, 0);
3508 case 23: /* fulto */
3509 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3511 gen_vfp_ulto(dp
, 32 - rm
, 0);
3513 case 24: /* ftoui */
3514 gen_vfp_toui(dp
, 0);
3516 case 25: /* ftouiz */
3517 gen_vfp_touiz(dp
, 0);
3519 case 26: /* ftosi */
3520 gen_vfp_tosi(dp
, 0);
3522 case 27: /* ftosiz */
3523 gen_vfp_tosiz(dp
, 0);
3525 case 28: /* ftosh */
3526 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3528 gen_vfp_tosh(dp
, 16 - rm
, 0);
3530 case 29: /* ftosl */
3531 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3533 gen_vfp_tosl(dp
, 32 - rm
, 0);
3535 case 30: /* ftouh */
3536 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3538 gen_vfp_touh(dp
, 16 - rm
, 0);
3540 case 31: /* ftoul */
3541 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3543 gen_vfp_toul(dp
, 32 - rm
, 0);
3545 default: /* undefined */
3549 default: /* undefined */
3553 /* Write back the result. */
3554 if (op
== 15 && (rn
>= 8 && rn
<= 11))
3555 ; /* Comparison, do nothing. */
3556 else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18))
3557 /* VCVT double to int: always integer result. */
3558 gen_mov_vreg_F0(0, rd
);
3559 else if (op
== 15 && rn
== 15)
3561 gen_mov_vreg_F0(!dp
, rd
);
3563 gen_mov_vreg_F0(dp
, rd
);
3565 /* break out of the loop if we have finished */
3569 if (op
== 15 && delta_m
== 0) {
3570 /* single source one-many */
3572 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3574 gen_mov_vreg_F0(dp
, rd
);
3578 /* Setup the next operands. */
3580 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3584 /* One source operand. */
3585 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3587 gen_mov_F0_vreg(dp
, rm
);
3589 /* Two source operands. */
3590 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3592 gen_mov_F0_vreg(dp
, rn
);
3594 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3596 gen_mov_F1_vreg(dp
, rm
);
3604 if ((insn
& 0x03e00000) == 0x00400000) {
3605 /* two-register transfer */
3606 rn
= (insn
>> 16) & 0xf;
3607 rd
= (insn
>> 12) & 0xf;
3609 VFP_DREG_M(rm
, insn
);
3611 rm
= VFP_SREG_M(insn
);
3614 if (insn
& ARM_CP_RW_BIT
) {
3617 gen_mov_F0_vreg(0, rm
* 2);
3618 tmp
= gen_vfp_mrs();
3619 store_reg(s
, rd
, tmp
);
3620 gen_mov_F0_vreg(0, rm
* 2 + 1);
3621 tmp
= gen_vfp_mrs();
3622 store_reg(s
, rn
, tmp
);
3624 gen_mov_F0_vreg(0, rm
);
3625 tmp
= gen_vfp_mrs();
3626 store_reg(s
, rd
, tmp
);
3627 gen_mov_F0_vreg(0, rm
+ 1);
3628 tmp
= gen_vfp_mrs();
3629 store_reg(s
, rn
, tmp
);
3634 tmp
= load_reg(s
, rd
);
3636 gen_mov_vreg_F0(0, rm
* 2);
3637 tmp
= load_reg(s
, rn
);
3639 gen_mov_vreg_F0(0, rm
* 2 + 1);
3641 tmp
= load_reg(s
, rd
);
3643 gen_mov_vreg_F0(0, rm
);
3644 tmp
= load_reg(s
, rn
);
3646 gen_mov_vreg_F0(0, rm
+ 1);
3651 rn
= (insn
>> 16) & 0xf;
3653 VFP_DREG_D(rd
, insn
);
3655 rd
= VFP_SREG_D(insn
);
3656 if ((insn
& 0x01200000) == 0x01000000) {
3657 /* Single load/store */
3658 offset
= (insn
& 0xff) << 2;
3659 if ((insn
& (1 << 23)) == 0)
3661 if (s
->thumb
&& rn
== 15) {
3662 /* This is actually UNPREDICTABLE */
3663 addr
= tcg_temp_new_i32();
3664 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3666 addr
= load_reg(s
, rn
);
3668 tcg_gen_addi_i32(addr
, addr
, offset
);
3669 if (insn
& (1 << 20)) {
3670 gen_vfp_ld(s
, dp
, addr
);
3671 gen_mov_vreg_F0(dp
, rd
);
3673 gen_mov_F0_vreg(dp
, rd
);
3674 gen_vfp_st(s
, dp
, addr
);
3676 tcg_temp_free_i32(addr
);
3678 /* load/store multiple */
3679 int w
= insn
& (1 << 21);
3681 n
= (insn
>> 1) & 0x7f;
3685 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3686 /* P == U , W == 1 => UNDEF */
3689 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3690 /* UNPREDICTABLE cases for bad immediates: we choose to
3691 * UNDEF to avoid generating huge numbers of TCG ops
3695 if (rn
== 15 && w
) {
3696 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3700 if (s
->thumb
&& rn
== 15) {
3701 /* This is actually UNPREDICTABLE */
3702 addr
= tcg_temp_new_i32();
3703 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3705 addr
= load_reg(s
, rn
);
3707 if (insn
& (1 << 24)) /* pre-decrement */
3708 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3714 for (i
= 0; i
< n
; i
++) {
3715 if (insn
& ARM_CP_RW_BIT
) {
3717 gen_vfp_ld(s
, dp
, addr
);
3718 gen_mov_vreg_F0(dp
, rd
+ i
);
3721 gen_mov_F0_vreg(dp
, rd
+ i
);
3722 gen_vfp_st(s
, dp
, addr
);
3724 tcg_gen_addi_i32(addr
, addr
, offset
);
3728 if (insn
& (1 << 24))
3729 offset
= -offset
* n
;
3730 else if (dp
&& (insn
& 1))
3736 tcg_gen_addi_i32(addr
, addr
, offset
);
3737 store_reg(s
, rn
, addr
);
3739 tcg_temp_free_i32(addr
);
3745 /* Should never happen. */
3751 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3753 TranslationBlock
*tb
;
3756 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3758 gen_set_pc_im(s
, dest
);
3759 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3761 gen_set_pc_im(s
, dest
);
3766 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3768 if (unlikely(s
->singlestep_enabled
)) {
3769 /* An indirect jump so that we still trigger the debug exception. */
3774 gen_goto_tb(s
, 0, dest
);
3775 s
->is_jmp
= DISAS_TB_JUMP
;
3779 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3782 tcg_gen_sari_i32(t0
, t0
, 16);
3786 tcg_gen_sari_i32(t1
, t1
, 16);
3789 tcg_gen_mul_i32(t0
, t0
, t1
);
3792 /* Return the mask of PSR bits set by a MSR instruction. */
3793 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3797 if (flags
& (1 << 0))
3799 if (flags
& (1 << 1))
3801 if (flags
& (1 << 2))
3803 if (flags
& (1 << 3))
3806 /* Mask out undefined bits. */
3807 mask
&= ~CPSR_RESERVED
;
3808 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3810 if (!arm_feature(env
, ARM_FEATURE_V5
))
3811 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3812 if (!arm_feature(env
, ARM_FEATURE_V6
))
3813 mask
&= ~(CPSR_E
| CPSR_GE
);
3814 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3816 /* Mask out execution state bits. */
3819 /* Mask out privileged bits. */
3825 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3826 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3830 /* ??? This is also undefined in system mode. */
3834 tmp
= load_cpu_field(spsr
);
3835 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3836 tcg_gen_andi_i32(t0
, t0
, mask
);
3837 tcg_gen_or_i32(tmp
, tmp
, t0
);
3838 store_cpu_field(tmp
, spsr
);
3840 gen_set_cpsr(t0
, mask
);
3842 tcg_temp_free_i32(t0
);
3847 /* Returns nonzero if access to the PSR is not permitted. */
3848 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3851 tmp
= tcg_temp_new_i32();
3852 tcg_gen_movi_i32(tmp
, val
);
3853 return gen_set_psr(s
, mask
, spsr
, tmp
);
3856 /* Generate an old-style exception return. Marks pc as dead. */
3857 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3860 store_reg(s
, 15, pc
);
3861 tmp
= load_cpu_field(spsr
);
3862 gen_set_cpsr(tmp
, 0xffffffff);
3863 tcg_temp_free_i32(tmp
);
3864 s
->is_jmp
= DISAS_UPDATE
;
3867 /* Generate a v6 exception return. Marks both values as dead. */
3868 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3870 gen_set_cpsr(cpsr
, 0xffffffff);
3871 tcg_temp_free_i32(cpsr
);
3872 store_reg(s
, 15, pc
);
3873 s
->is_jmp
= DISAS_UPDATE
;
3877 gen_set_condexec (DisasContext
*s
)
3879 if (s
->condexec_mask
) {
3880 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3881 TCGv_i32 tmp
= tcg_temp_new_i32();
3882 tcg_gen_movi_i32(tmp
, val
);
3883 store_cpu_field(tmp
, condexec_bits
);
3887 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3889 gen_set_condexec(s
);
3890 gen_set_pc_im(s
, s
->pc
- offset
);
3891 gen_exception(excp
);
3892 s
->is_jmp
= DISAS_JUMP
;
3895 static void gen_nop_hint(DisasContext
*s
, int val
)
3899 gen_set_pc_im(s
, s
->pc
);
3900 s
->is_jmp
= DISAS_WFI
;
3905 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3911 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3913 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3916 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3917 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3918 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3923 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3926 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3927 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3928 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3933 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3934 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3935 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3936 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3937 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3939 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3940 switch ((size << 1) | u) { \
3942 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3945 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3948 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3951 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3954 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3957 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3959 default: return 1; \
3962 #define GEN_NEON_INTEGER_OP(name) do { \
3963 switch ((size << 1) | u) { \
3965 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3968 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3971 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3974 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3977 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3980 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3982 default: return 1; \
3985 static TCGv_i32
neon_load_scratch(int scratch
)
3987 TCGv_i32 tmp
= tcg_temp_new_i32();
3988 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3992 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
3994 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3995 tcg_temp_free_i32(var
);
3998 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4002 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4004 gen_neon_dup_high16(tmp
);
4006 gen_neon_dup_low16(tmp
);
4009 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4014 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4017 if (!q
&& size
== 2) {
4020 tmp
= tcg_const_i32(rd
);
4021 tmp2
= tcg_const_i32(rm
);
4025 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4028 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4031 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4039 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4042 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4048 tcg_temp_free_i32(tmp
);
4049 tcg_temp_free_i32(tmp2
);
4053 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4056 if (!q
&& size
== 2) {
4059 tmp
= tcg_const_i32(rd
);
4060 tmp2
= tcg_const_i32(rm
);
4064 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4067 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4070 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4078 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4081 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4087 tcg_temp_free_i32(tmp
);
4088 tcg_temp_free_i32(tmp2
);
4092 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4096 rd
= tcg_temp_new_i32();
4097 tmp
= tcg_temp_new_i32();
4099 tcg_gen_shli_i32(rd
, t0
, 8);
4100 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4101 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4102 tcg_gen_or_i32(rd
, rd
, tmp
);
4104 tcg_gen_shri_i32(t1
, t1
, 8);
4105 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4106 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4107 tcg_gen_or_i32(t1
, t1
, tmp
);
4108 tcg_gen_mov_i32(t0
, rd
);
4110 tcg_temp_free_i32(tmp
);
4111 tcg_temp_free_i32(rd
);
4114 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4118 rd
= tcg_temp_new_i32();
4119 tmp
= tcg_temp_new_i32();
4121 tcg_gen_shli_i32(rd
, t0
, 16);
4122 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4123 tcg_gen_or_i32(rd
, rd
, tmp
);
4124 tcg_gen_shri_i32(t1
, t1
, 16);
4125 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4126 tcg_gen_or_i32(t1
, t1
, tmp
);
4127 tcg_gen_mov_i32(t0
, rd
);
4129 tcg_temp_free_i32(tmp
);
4130 tcg_temp_free_i32(rd
);
4138 } neon_ls_element_type
[11] = {
4152 /* Translate a NEON load/store element instruction. Return nonzero if the
4153 instruction is invalid. */
4154 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4173 if (!s
->vfp_enabled
)
4175 VFP_DREG_D(rd
, insn
);
4176 rn
= (insn
>> 16) & 0xf;
4178 load
= (insn
& (1 << 21)) != 0;
4179 if ((insn
& (1 << 23)) == 0) {
4180 /* Load store all elements. */
4181 op
= (insn
>> 8) & 0xf;
4182 size
= (insn
>> 6) & 3;
4185 /* Catch UNDEF cases for bad values of align field */
4188 if (((insn
>> 5) & 1) == 1) {
4193 if (((insn
>> 4) & 3) == 3) {
4200 nregs
= neon_ls_element_type
[op
].nregs
;
4201 interleave
= neon_ls_element_type
[op
].interleave
;
4202 spacing
= neon_ls_element_type
[op
].spacing
;
4203 if (size
== 3 && (interleave
| spacing
) != 1)
4205 addr
= tcg_temp_new_i32();
4206 load_reg_var(s
, addr
, rn
);
4207 stride
= (1 << size
) * interleave
;
4208 for (reg
= 0; reg
< nregs
; reg
++) {
4209 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4210 load_reg_var(s
, addr
, rn
);
4211 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4212 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4213 load_reg_var(s
, addr
, rn
);
4214 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4217 tmp64
= tcg_temp_new_i64();
4219 gen_aa32_ld64(tmp64
, addr
, IS_USER(s
));
4220 neon_store_reg64(tmp64
, rd
);
4222 neon_load_reg64(tmp64
, rd
);
4223 gen_aa32_st64(tmp64
, addr
, IS_USER(s
));
4225 tcg_temp_free_i64(tmp64
);
4226 tcg_gen_addi_i32(addr
, addr
, stride
);
4228 for (pass
= 0; pass
< 2; pass
++) {
4231 tmp
= tcg_temp_new_i32();
4232 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
4233 neon_store_reg(rd
, pass
, tmp
);
4235 tmp
= neon_load_reg(rd
, pass
);
4236 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
4237 tcg_temp_free_i32(tmp
);
4239 tcg_gen_addi_i32(addr
, addr
, stride
);
4240 } else if (size
== 1) {
4242 tmp
= tcg_temp_new_i32();
4243 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
4244 tcg_gen_addi_i32(addr
, addr
, stride
);
4245 tmp2
= tcg_temp_new_i32();
4246 gen_aa32_ld16u(tmp2
, addr
, IS_USER(s
));
4247 tcg_gen_addi_i32(addr
, addr
, stride
);
4248 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4249 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4250 tcg_temp_free_i32(tmp2
);
4251 neon_store_reg(rd
, pass
, tmp
);
4253 tmp
= neon_load_reg(rd
, pass
);
4254 tmp2
= tcg_temp_new_i32();
4255 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4256 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
4257 tcg_temp_free_i32(tmp
);
4258 tcg_gen_addi_i32(addr
, addr
, stride
);
4259 gen_aa32_st16(tmp2
, addr
, IS_USER(s
));
4260 tcg_temp_free_i32(tmp2
);
4261 tcg_gen_addi_i32(addr
, addr
, stride
);
4263 } else /* size == 0 */ {
4265 TCGV_UNUSED_I32(tmp2
);
4266 for (n
= 0; n
< 4; n
++) {
4267 tmp
= tcg_temp_new_i32();
4268 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
4269 tcg_gen_addi_i32(addr
, addr
, stride
);
4273 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4274 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4275 tcg_temp_free_i32(tmp
);
4278 neon_store_reg(rd
, pass
, tmp2
);
4280 tmp2
= neon_load_reg(rd
, pass
);
4281 for (n
= 0; n
< 4; n
++) {
4282 tmp
= tcg_temp_new_i32();
4284 tcg_gen_mov_i32(tmp
, tmp2
);
4286 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4288 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
4289 tcg_temp_free_i32(tmp
);
4290 tcg_gen_addi_i32(addr
, addr
, stride
);
4292 tcg_temp_free_i32(tmp2
);
4299 tcg_temp_free_i32(addr
);
4302 size
= (insn
>> 10) & 3;
4304 /* Load single element to all lanes. */
4305 int a
= (insn
>> 4) & 1;
4309 size
= (insn
>> 6) & 3;
4310 nregs
= ((insn
>> 8) & 3) + 1;
4313 if (nregs
!= 4 || a
== 0) {
4316 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4319 if (nregs
== 1 && a
== 1 && size
== 0) {
4322 if (nregs
== 3 && a
== 1) {
4325 addr
= tcg_temp_new_i32();
4326 load_reg_var(s
, addr
, rn
);
4328 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4329 tmp
= gen_load_and_replicate(s
, addr
, size
);
4330 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4331 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4332 if (insn
& (1 << 5)) {
4333 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4334 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4336 tcg_temp_free_i32(tmp
);
4338 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4339 stride
= (insn
& (1 << 5)) ? 2 : 1;
4340 for (reg
= 0; reg
< nregs
; reg
++) {
4341 tmp
= gen_load_and_replicate(s
, addr
, size
);
4342 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4343 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4344 tcg_temp_free_i32(tmp
);
4345 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4349 tcg_temp_free_i32(addr
);
4350 stride
= (1 << size
) * nregs
;
4352 /* Single element. */
4353 int idx
= (insn
>> 4) & 0xf;
4354 pass
= (insn
>> 7) & 1;
4357 shift
= ((insn
>> 5) & 3) * 8;
4361 shift
= ((insn
>> 6) & 1) * 16;
4362 stride
= (insn
& (1 << 5)) ? 2 : 1;
4366 stride
= (insn
& (1 << 6)) ? 2 : 1;
4371 nregs
= ((insn
>> 8) & 3) + 1;
4372 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4375 if (((idx
& (1 << size
)) != 0) ||
4376 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4381 if ((idx
& 1) != 0) {
4386 if (size
== 2 && (idx
& 2) != 0) {
4391 if ((size
== 2) && ((idx
& 3) == 3)) {
4398 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4399 /* Attempts to write off the end of the register file
4400 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4401 * the neon_load_reg() would write off the end of the array.
4405 addr
= tcg_temp_new_i32();
4406 load_reg_var(s
, addr
, rn
);
4407 for (reg
= 0; reg
< nregs
; reg
++) {
4409 tmp
= tcg_temp_new_i32();
4412 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
4415 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
4418 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
4420 default: /* Avoid compiler warnings. */
4424 tmp2
= neon_load_reg(rd
, pass
);
4425 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4426 shift
, size
? 16 : 8);
4427 tcg_temp_free_i32(tmp2
);
4429 neon_store_reg(rd
, pass
, tmp
);
4430 } else { /* Store */
4431 tmp
= neon_load_reg(rd
, pass
);
4433 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4436 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
4439 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
4442 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
4445 tcg_temp_free_i32(tmp
);
4448 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4450 tcg_temp_free_i32(addr
);
4451 stride
= nregs
* (1 << size
);
4457 base
= load_reg(s
, rn
);
4459 tcg_gen_addi_i32(base
, base
, stride
);
4462 index
= load_reg(s
, rm
);
4463 tcg_gen_add_i32(base
, base
, index
);
4464 tcg_temp_free_i32(index
);
4466 store_reg(s
, rn
, base
);
4471 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4472 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4474 tcg_gen_and_i32(t
, t
, c
);
4475 tcg_gen_andc_i32(f
, f
, c
);
4476 tcg_gen_or_i32(dest
, t
, f
);
4479 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4482 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4483 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4484 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4489 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4492 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4493 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4494 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4499 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4502 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4503 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4504 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4509 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4512 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4513 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4514 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4519 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4525 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4526 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4531 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4532 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4539 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4540 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4545 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4546 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4553 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4557 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4558 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4559 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4564 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4565 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4566 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4570 tcg_temp_free_i32(src
);
4573 static inline void gen_neon_addl(int size
)
4576 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4577 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4578 case 2: tcg_gen_add_i64(CPU_V001
); break;
4583 static inline void gen_neon_subl(int size
)
4586 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4587 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4588 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4593 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4596 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4597 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4599 tcg_gen_neg_i64(var
, var
);
4605 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4608 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4609 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4614 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4619 switch ((size
<< 1) | u
) {
4620 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4621 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4622 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4623 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4625 tmp
= gen_muls_i64_i32(a
, b
);
4626 tcg_gen_mov_i64(dest
, tmp
);
4627 tcg_temp_free_i64(tmp
);
4630 tmp
= gen_mulu_i64_i32(a
, b
);
4631 tcg_gen_mov_i64(dest
, tmp
);
4632 tcg_temp_free_i64(tmp
);
4637 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4638 Don't forget to clean them now. */
4640 tcg_temp_free_i32(a
);
4641 tcg_temp_free_i32(b
);
4645 static void gen_neon_narrow_op(int op
, int u
, int size
,
4646 TCGv_i32 dest
, TCGv_i64 src
)
4650 gen_neon_unarrow_sats(size
, dest
, src
);
4652 gen_neon_narrow(size
, dest
, src
);
4656 gen_neon_narrow_satu(size
, dest
, src
);
4658 gen_neon_narrow_sats(size
, dest
, src
);
4663 /* Symbolic constants for op fields for Neon 3-register same-length.
4664 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4667 #define NEON_3R_VHADD 0
4668 #define NEON_3R_VQADD 1
4669 #define NEON_3R_VRHADD 2
4670 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4671 #define NEON_3R_VHSUB 4
4672 #define NEON_3R_VQSUB 5
4673 #define NEON_3R_VCGT 6
4674 #define NEON_3R_VCGE 7
4675 #define NEON_3R_VSHL 8
4676 #define NEON_3R_VQSHL 9
4677 #define NEON_3R_VRSHL 10
4678 #define NEON_3R_VQRSHL 11
4679 #define NEON_3R_VMAX 12
4680 #define NEON_3R_VMIN 13
4681 #define NEON_3R_VABD 14
4682 #define NEON_3R_VABA 15
4683 #define NEON_3R_VADD_VSUB 16
4684 #define NEON_3R_VTST_VCEQ 17
4685 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4686 #define NEON_3R_VMUL 19
4687 #define NEON_3R_VPMAX 20
4688 #define NEON_3R_VPMIN 21
4689 #define NEON_3R_VQDMULH_VQRDMULH 22
4690 #define NEON_3R_VPADD 23
4691 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4692 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4693 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4694 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4695 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4696 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4697 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4699 static const uint8_t neon_3r_sizes
[] = {
4700 [NEON_3R_VHADD
] = 0x7,
4701 [NEON_3R_VQADD
] = 0xf,
4702 [NEON_3R_VRHADD
] = 0x7,
4703 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4704 [NEON_3R_VHSUB
] = 0x7,
4705 [NEON_3R_VQSUB
] = 0xf,
4706 [NEON_3R_VCGT
] = 0x7,
4707 [NEON_3R_VCGE
] = 0x7,
4708 [NEON_3R_VSHL
] = 0xf,
4709 [NEON_3R_VQSHL
] = 0xf,
4710 [NEON_3R_VRSHL
] = 0xf,
4711 [NEON_3R_VQRSHL
] = 0xf,
4712 [NEON_3R_VMAX
] = 0x7,
4713 [NEON_3R_VMIN
] = 0x7,
4714 [NEON_3R_VABD
] = 0x7,
4715 [NEON_3R_VABA
] = 0x7,
4716 [NEON_3R_VADD_VSUB
] = 0xf,
4717 [NEON_3R_VTST_VCEQ
] = 0x7,
4718 [NEON_3R_VML
] = 0x7,
4719 [NEON_3R_VMUL
] = 0x7,
4720 [NEON_3R_VPMAX
] = 0x7,
4721 [NEON_3R_VPMIN
] = 0x7,
4722 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4723 [NEON_3R_VPADD
] = 0x7,
4724 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4725 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4726 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4727 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4728 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4729 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4730 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4733 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4734 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4737 #define NEON_2RM_VREV64 0
4738 #define NEON_2RM_VREV32 1
4739 #define NEON_2RM_VREV16 2
4740 #define NEON_2RM_VPADDL 4
4741 #define NEON_2RM_VPADDL_U 5
4742 #define NEON_2RM_AESE 6 /* Includes AESD */
4743 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4744 #define NEON_2RM_VCLS 8
4745 #define NEON_2RM_VCLZ 9
4746 #define NEON_2RM_VCNT 10
4747 #define NEON_2RM_VMVN 11
4748 #define NEON_2RM_VPADAL 12
4749 #define NEON_2RM_VPADAL_U 13
4750 #define NEON_2RM_VQABS 14
4751 #define NEON_2RM_VQNEG 15
4752 #define NEON_2RM_VCGT0 16
4753 #define NEON_2RM_VCGE0 17
4754 #define NEON_2RM_VCEQ0 18
4755 #define NEON_2RM_VCLE0 19
4756 #define NEON_2RM_VCLT0 20
4757 #define NEON_2RM_VABS 22
4758 #define NEON_2RM_VNEG 23
4759 #define NEON_2RM_VCGT0_F 24
4760 #define NEON_2RM_VCGE0_F 25
4761 #define NEON_2RM_VCEQ0_F 26
4762 #define NEON_2RM_VCLE0_F 27
4763 #define NEON_2RM_VCLT0_F 28
4764 #define NEON_2RM_VABS_F 30
4765 #define NEON_2RM_VNEG_F 31
4766 #define NEON_2RM_VSWP 32
4767 #define NEON_2RM_VTRN 33
4768 #define NEON_2RM_VUZP 34
4769 #define NEON_2RM_VZIP 35
4770 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4771 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4772 #define NEON_2RM_VSHLL 38
4773 #define NEON_2RM_VRINTN 40
4774 #define NEON_2RM_VRINTX 41
4775 #define NEON_2RM_VRINTA 42
4776 #define NEON_2RM_VRINTZ 43
4777 #define NEON_2RM_VCVT_F16_F32 44
4778 #define NEON_2RM_VRINTM 45
4779 #define NEON_2RM_VCVT_F32_F16 46
4780 #define NEON_2RM_VRINTP 47
4781 #define NEON_2RM_VCVTAU 48
4782 #define NEON_2RM_VCVTAS 49
4783 #define NEON_2RM_VCVTNU 50
4784 #define NEON_2RM_VCVTNS 51
4785 #define NEON_2RM_VCVTPU 52
4786 #define NEON_2RM_VCVTPS 53
4787 #define NEON_2RM_VCVTMU 54
4788 #define NEON_2RM_VCVTMS 55
4789 #define NEON_2RM_VRECPE 56
4790 #define NEON_2RM_VRSQRTE 57
4791 #define NEON_2RM_VRECPE_F 58
4792 #define NEON_2RM_VRSQRTE_F 59
4793 #define NEON_2RM_VCVT_FS 60
4794 #define NEON_2RM_VCVT_FU 61
4795 #define NEON_2RM_VCVT_SF 62
4796 #define NEON_2RM_VCVT_UF 63
4798 static int neon_2rm_is_float_op(int op
)
4800 /* Return true if this neon 2reg-misc op is float-to-float */
4801 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4802 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4803 op
== NEON_2RM_VRINTM
||
4804 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4805 op
>= NEON_2RM_VRECPE_F
);
4808 /* Each entry in this array has bit n set if the insn allows
4809 * size value n (otherwise it will UNDEF). Since unallocated
4810 * op values will have no bits set they always UNDEF.
4812 static const uint8_t neon_2rm_sizes
[] = {
4813 [NEON_2RM_VREV64
] = 0x7,
4814 [NEON_2RM_VREV32
] = 0x3,
4815 [NEON_2RM_VREV16
] = 0x1,
4816 [NEON_2RM_VPADDL
] = 0x7,
4817 [NEON_2RM_VPADDL_U
] = 0x7,
4818 [NEON_2RM_AESE
] = 0x1,
4819 [NEON_2RM_AESMC
] = 0x1,
4820 [NEON_2RM_VCLS
] = 0x7,
4821 [NEON_2RM_VCLZ
] = 0x7,
4822 [NEON_2RM_VCNT
] = 0x1,
4823 [NEON_2RM_VMVN
] = 0x1,
4824 [NEON_2RM_VPADAL
] = 0x7,
4825 [NEON_2RM_VPADAL_U
] = 0x7,
4826 [NEON_2RM_VQABS
] = 0x7,
4827 [NEON_2RM_VQNEG
] = 0x7,
4828 [NEON_2RM_VCGT0
] = 0x7,
4829 [NEON_2RM_VCGE0
] = 0x7,
4830 [NEON_2RM_VCEQ0
] = 0x7,
4831 [NEON_2RM_VCLE0
] = 0x7,
4832 [NEON_2RM_VCLT0
] = 0x7,
4833 [NEON_2RM_VABS
] = 0x7,
4834 [NEON_2RM_VNEG
] = 0x7,
4835 [NEON_2RM_VCGT0_F
] = 0x4,
4836 [NEON_2RM_VCGE0_F
] = 0x4,
4837 [NEON_2RM_VCEQ0_F
] = 0x4,
4838 [NEON_2RM_VCLE0_F
] = 0x4,
4839 [NEON_2RM_VCLT0_F
] = 0x4,
4840 [NEON_2RM_VABS_F
] = 0x4,
4841 [NEON_2RM_VNEG_F
] = 0x4,
4842 [NEON_2RM_VSWP
] = 0x1,
4843 [NEON_2RM_VTRN
] = 0x7,
4844 [NEON_2RM_VUZP
] = 0x7,
4845 [NEON_2RM_VZIP
] = 0x7,
4846 [NEON_2RM_VMOVN
] = 0x7,
4847 [NEON_2RM_VQMOVN
] = 0x7,
4848 [NEON_2RM_VSHLL
] = 0x7,
4849 [NEON_2RM_VRINTN
] = 0x4,
4850 [NEON_2RM_VRINTX
] = 0x4,
4851 [NEON_2RM_VRINTA
] = 0x4,
4852 [NEON_2RM_VRINTZ
] = 0x4,
4853 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4854 [NEON_2RM_VRINTM
] = 0x4,
4855 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4856 [NEON_2RM_VRINTP
] = 0x4,
4857 [NEON_2RM_VCVTAU
] = 0x4,
4858 [NEON_2RM_VCVTAS
] = 0x4,
4859 [NEON_2RM_VCVTNU
] = 0x4,
4860 [NEON_2RM_VCVTNS
] = 0x4,
4861 [NEON_2RM_VCVTPU
] = 0x4,
4862 [NEON_2RM_VCVTPS
] = 0x4,
4863 [NEON_2RM_VCVTMU
] = 0x4,
4864 [NEON_2RM_VCVTMS
] = 0x4,
4865 [NEON_2RM_VRECPE
] = 0x4,
4866 [NEON_2RM_VRSQRTE
] = 0x4,
4867 [NEON_2RM_VRECPE_F
] = 0x4,
4868 [NEON_2RM_VRSQRTE_F
] = 0x4,
4869 [NEON_2RM_VCVT_FS
] = 0x4,
4870 [NEON_2RM_VCVT_FU
] = 0x4,
4871 [NEON_2RM_VCVT_SF
] = 0x4,
4872 [NEON_2RM_VCVT_UF
] = 0x4,
4875 /* Translate a NEON data processing instruction. Return nonzero if the
4876 instruction is invalid.
4877 We process data in a mixture of 32-bit and 64-bit chunks.
4878 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4880 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4892 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4895 if (!s
->vfp_enabled
)
4897 q
= (insn
& (1 << 6)) != 0;
4898 u
= (insn
>> 24) & 1;
4899 VFP_DREG_D(rd
, insn
);
4900 VFP_DREG_N(rn
, insn
);
4901 VFP_DREG_M(rm
, insn
);
4902 size
= (insn
>> 20) & 3;
4903 if ((insn
& (1 << 23)) == 0) {
4904 /* Three register same length. */
4905 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4906 /* Catch invalid op and bad size combinations: UNDEF */
4907 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4910 /* All insns of this form UNDEF for either this condition or the
4911 * superset of cases "Q==1"; we catch the latter later.
4913 if (q
&& ((rd
| rn
| rm
) & 1)) {
4916 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4917 /* 64-bit element instructions. */
4918 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4919 neon_load_reg64(cpu_V0
, rn
+ pass
);
4920 neon_load_reg64(cpu_V1
, rm
+ pass
);
4924 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4927 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4933 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4936 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4942 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4944 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4949 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4952 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4958 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4960 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4963 case NEON_3R_VQRSHL
:
4965 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4968 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4972 case NEON_3R_VADD_VSUB
:
4974 tcg_gen_sub_i64(CPU_V001
);
4976 tcg_gen_add_i64(CPU_V001
);
4982 neon_store_reg64(cpu_V0
, rd
+ pass
);
4991 case NEON_3R_VQRSHL
:
4994 /* Shift instruction operands are reversed. */
5009 case NEON_3R_FLOAT_ARITH
:
5010 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5012 case NEON_3R_FLOAT_MINMAX
:
5013 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5015 case NEON_3R_FLOAT_CMP
:
5017 /* no encoding for U=0 C=1x */
5021 case NEON_3R_FLOAT_ACMP
:
5026 case NEON_3R_FLOAT_MISC
:
5027 /* VMAXNM/VMINNM in ARMv8 */
5028 if (u
&& !arm_feature(env
, ARM_FEATURE_V8
)) {
5033 if (u
&& (size
!= 0)) {
5034 /* UNDEF on invalid size for polynomial subcase */
5039 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
5047 if (pairwise
&& q
) {
5048 /* All the pairwise insns UNDEF if Q is set */
5052 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5057 tmp
= neon_load_reg(rn
, 0);
5058 tmp2
= neon_load_reg(rn
, 1);
5060 tmp
= neon_load_reg(rm
, 0);
5061 tmp2
= neon_load_reg(rm
, 1);
5065 tmp
= neon_load_reg(rn
, pass
);
5066 tmp2
= neon_load_reg(rm
, pass
);
5070 GEN_NEON_INTEGER_OP(hadd
);
5073 GEN_NEON_INTEGER_OP_ENV(qadd
);
5075 case NEON_3R_VRHADD
:
5076 GEN_NEON_INTEGER_OP(rhadd
);
5078 case NEON_3R_LOGIC
: /* Logic ops. */
5079 switch ((u
<< 2) | size
) {
5081 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5084 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5087 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5090 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5093 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5096 tmp3
= neon_load_reg(rd
, pass
);
5097 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5098 tcg_temp_free_i32(tmp3
);
5101 tmp3
= neon_load_reg(rd
, pass
);
5102 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5103 tcg_temp_free_i32(tmp3
);
5106 tmp3
= neon_load_reg(rd
, pass
);
5107 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5108 tcg_temp_free_i32(tmp3
);
5113 GEN_NEON_INTEGER_OP(hsub
);
5116 GEN_NEON_INTEGER_OP_ENV(qsub
);
5119 GEN_NEON_INTEGER_OP(cgt
);
5122 GEN_NEON_INTEGER_OP(cge
);
5125 GEN_NEON_INTEGER_OP(shl
);
5128 GEN_NEON_INTEGER_OP_ENV(qshl
);
5131 GEN_NEON_INTEGER_OP(rshl
);
5133 case NEON_3R_VQRSHL
:
5134 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5137 GEN_NEON_INTEGER_OP(max
);
5140 GEN_NEON_INTEGER_OP(min
);
5143 GEN_NEON_INTEGER_OP(abd
);
5146 GEN_NEON_INTEGER_OP(abd
);
5147 tcg_temp_free_i32(tmp2
);
5148 tmp2
= neon_load_reg(rd
, pass
);
5149 gen_neon_add(size
, tmp
, tmp2
);
5151 case NEON_3R_VADD_VSUB
:
5152 if (!u
) { /* VADD */
5153 gen_neon_add(size
, tmp
, tmp2
);
5156 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5157 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5158 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5163 case NEON_3R_VTST_VCEQ
:
5164 if (!u
) { /* VTST */
5166 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5167 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5168 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5173 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5174 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5175 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5180 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5182 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5183 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5184 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5187 tcg_temp_free_i32(tmp2
);
5188 tmp2
= neon_load_reg(rd
, pass
);
5190 gen_neon_rsb(size
, tmp
, tmp2
);
5192 gen_neon_add(size
, tmp
, tmp2
);
5196 if (u
) { /* polynomial */
5197 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5198 } else { /* Integer */
5200 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5201 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5202 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5208 GEN_NEON_INTEGER_OP(pmax
);
5211 GEN_NEON_INTEGER_OP(pmin
);
5213 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5214 if (!u
) { /* VQDMULH */
5217 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5220 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5224 } else { /* VQRDMULH */
5227 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5230 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5238 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5239 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5240 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5244 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5246 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5247 switch ((u
<< 2) | size
) {
5250 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5253 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5256 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5261 tcg_temp_free_ptr(fpstatus
);
5264 case NEON_3R_FLOAT_MULTIPLY
:
5266 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5267 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5269 tcg_temp_free_i32(tmp2
);
5270 tmp2
= neon_load_reg(rd
, pass
);
5272 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5274 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5277 tcg_temp_free_ptr(fpstatus
);
5280 case NEON_3R_FLOAT_CMP
:
5282 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5284 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5287 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5289 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5292 tcg_temp_free_ptr(fpstatus
);
5295 case NEON_3R_FLOAT_ACMP
:
5297 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5299 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5301 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5303 tcg_temp_free_ptr(fpstatus
);
5306 case NEON_3R_FLOAT_MINMAX
:
5308 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5310 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5312 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5314 tcg_temp_free_ptr(fpstatus
);
5317 case NEON_3R_FLOAT_MISC
:
5320 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5322 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5324 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5326 tcg_temp_free_ptr(fpstatus
);
5329 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5331 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5337 /* VFMA, VFMS: fused multiply-add */
5338 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5339 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5342 gen_helper_vfp_negs(tmp
, tmp
);
5344 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5345 tcg_temp_free_i32(tmp3
);
5346 tcg_temp_free_ptr(fpstatus
);
5352 tcg_temp_free_i32(tmp2
);
5354 /* Save the result. For elementwise operations we can put it
5355 straight into the destination register. For pairwise operations
5356 we have to be careful to avoid clobbering the source operands. */
5357 if (pairwise
&& rd
== rm
) {
5358 neon_store_scratch(pass
, tmp
);
5360 neon_store_reg(rd
, pass
, tmp
);
5364 if (pairwise
&& rd
== rm
) {
5365 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5366 tmp
= neon_load_scratch(pass
);
5367 neon_store_reg(rd
, pass
, tmp
);
5370 /* End of 3 register same size operations. */
5371 } else if (insn
& (1 << 4)) {
5372 if ((insn
& 0x00380080) != 0) {
5373 /* Two registers and shift. */
5374 op
= (insn
>> 8) & 0xf;
5375 if (insn
& (1 << 7)) {
5383 while ((insn
& (1 << (size
+ 19))) == 0)
5386 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5387 /* To avoid excessive duplication of ops we implement shift
5388 by immediate using the variable shift operations. */
5390 /* Shift by immediate:
5391 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5392 if (q
&& ((rd
| rm
) & 1)) {
5395 if (!u
&& (op
== 4 || op
== 6)) {
5398 /* Right shifts are encoded as N - shift, where N is the
5399 element size in bits. */
5401 shift
= shift
- (1 << (size
+ 3));
5409 imm
= (uint8_t) shift
;
5414 imm
= (uint16_t) shift
;
5425 for (pass
= 0; pass
< count
; pass
++) {
5427 neon_load_reg64(cpu_V0
, rm
+ pass
);
5428 tcg_gen_movi_i64(cpu_V1
, imm
);
5433 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5435 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5440 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5442 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5445 case 5: /* VSHL, VSLI */
5446 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5448 case 6: /* VQSHLU */
5449 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5454 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5457 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5462 if (op
== 1 || op
== 3) {
5464 neon_load_reg64(cpu_V1
, rd
+ pass
);
5465 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5466 } else if (op
== 4 || (op
== 5 && u
)) {
5468 neon_load_reg64(cpu_V1
, rd
+ pass
);
5470 if (shift
< -63 || shift
> 63) {
5474 mask
= 0xffffffffffffffffull
>> -shift
;
5476 mask
= 0xffffffffffffffffull
<< shift
;
5479 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5480 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5482 neon_store_reg64(cpu_V0
, rd
+ pass
);
5483 } else { /* size < 3 */
5484 /* Operands in T0 and T1. */
5485 tmp
= neon_load_reg(rm
, pass
);
5486 tmp2
= tcg_temp_new_i32();
5487 tcg_gen_movi_i32(tmp2
, imm
);
5491 GEN_NEON_INTEGER_OP(shl
);
5495 GEN_NEON_INTEGER_OP(rshl
);
5498 case 5: /* VSHL, VSLI */
5500 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5501 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5502 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5506 case 6: /* VQSHLU */
5509 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5513 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5517 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5525 GEN_NEON_INTEGER_OP_ENV(qshl
);
5528 tcg_temp_free_i32(tmp2
);
5530 if (op
== 1 || op
== 3) {
5532 tmp2
= neon_load_reg(rd
, pass
);
5533 gen_neon_add(size
, tmp
, tmp2
);
5534 tcg_temp_free_i32(tmp2
);
5535 } else if (op
== 4 || (op
== 5 && u
)) {
5540 mask
= 0xff >> -shift
;
5542 mask
= (uint8_t)(0xff << shift
);
5548 mask
= 0xffff >> -shift
;
5550 mask
= (uint16_t)(0xffff << shift
);
5554 if (shift
< -31 || shift
> 31) {
5558 mask
= 0xffffffffu
>> -shift
;
5560 mask
= 0xffffffffu
<< shift
;
5566 tmp2
= neon_load_reg(rd
, pass
);
5567 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5568 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5569 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5570 tcg_temp_free_i32(tmp2
);
5572 neon_store_reg(rd
, pass
, tmp
);
5575 } else if (op
< 10) {
5576 /* Shift by immediate and narrow:
5577 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5578 int input_unsigned
= (op
== 8) ? !u
: u
;
5582 shift
= shift
- (1 << (size
+ 3));
5585 tmp64
= tcg_const_i64(shift
);
5586 neon_load_reg64(cpu_V0
, rm
);
5587 neon_load_reg64(cpu_V1
, rm
+ 1);
5588 for (pass
= 0; pass
< 2; pass
++) {
5596 if (input_unsigned
) {
5597 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5599 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5602 if (input_unsigned
) {
5603 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5605 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5608 tmp
= tcg_temp_new_i32();
5609 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5610 neon_store_reg(rd
, pass
, tmp
);
5612 tcg_temp_free_i64(tmp64
);
5615 imm
= (uint16_t)shift
;
5619 imm
= (uint32_t)shift
;
5621 tmp2
= tcg_const_i32(imm
);
5622 tmp4
= neon_load_reg(rm
+ 1, 0);
5623 tmp5
= neon_load_reg(rm
+ 1, 1);
5624 for (pass
= 0; pass
< 2; pass
++) {
5626 tmp
= neon_load_reg(rm
, 0);
5630 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5633 tmp3
= neon_load_reg(rm
, 1);
5637 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5639 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5640 tcg_temp_free_i32(tmp
);
5641 tcg_temp_free_i32(tmp3
);
5642 tmp
= tcg_temp_new_i32();
5643 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5644 neon_store_reg(rd
, pass
, tmp
);
5646 tcg_temp_free_i32(tmp2
);
5648 } else if (op
== 10) {
5650 if (q
|| (rd
& 1)) {
5653 tmp
= neon_load_reg(rm
, 0);
5654 tmp2
= neon_load_reg(rm
, 1);
5655 for (pass
= 0; pass
< 2; pass
++) {
5659 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5662 /* The shift is less than the width of the source
5663 type, so we can just shift the whole register. */
5664 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5665 /* Widen the result of shift: we need to clear
5666 * the potential overflow bits resulting from
5667 * left bits of the narrow input appearing as
5668 * right bits of left the neighbour narrow
5670 if (size
< 2 || !u
) {
5673 imm
= (0xffu
>> (8 - shift
));
5675 } else if (size
== 1) {
5676 imm
= 0xffff >> (16 - shift
);
5679 imm
= 0xffffffff >> (32 - shift
);
5682 imm64
= imm
| (((uint64_t)imm
) << 32);
5686 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5689 neon_store_reg64(cpu_V0
, rd
+ pass
);
5691 } else if (op
>= 14) {
5692 /* VCVT fixed-point. */
5693 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5696 /* We have already masked out the must-be-1 top bit of imm6,
5697 * hence this 32-shift where the ARM ARM has 64-imm6.
5700 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5701 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5704 gen_vfp_ulto(0, shift
, 1);
5706 gen_vfp_slto(0, shift
, 1);
5709 gen_vfp_toul(0, shift
, 1);
5711 gen_vfp_tosl(0, shift
, 1);
5713 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5718 } else { /* (insn & 0x00380080) == 0 */
5720 if (q
&& (rd
& 1)) {
5724 op
= (insn
>> 8) & 0xf;
5725 /* One register and immediate. */
5726 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5727 invert
= (insn
& (1 << 5)) != 0;
5728 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5729 * We choose to not special-case this and will behave as if a
5730 * valid constant encoding of 0 had been given.
5749 imm
= (imm
<< 8) | (imm
<< 24);
5752 imm
= (imm
<< 8) | 0xff;
5755 imm
= (imm
<< 16) | 0xffff;
5758 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5766 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5767 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5773 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5774 if (op
& 1 && op
< 12) {
5775 tmp
= neon_load_reg(rd
, pass
);
5777 /* The immediate value has already been inverted, so
5779 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5781 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5785 tmp
= tcg_temp_new_i32();
5786 if (op
== 14 && invert
) {
5790 for (n
= 0; n
< 4; n
++) {
5791 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5792 val
|= 0xff << (n
* 8);
5794 tcg_gen_movi_i32(tmp
, val
);
5796 tcg_gen_movi_i32(tmp
, imm
);
5799 neon_store_reg(rd
, pass
, tmp
);
5802 } else { /* (insn & 0x00800010 == 0x00800000) */
5804 op
= (insn
>> 8) & 0xf;
5805 if ((insn
& (1 << 6)) == 0) {
5806 /* Three registers of different lengths. */
5810 /* undefreq: bit 0 : UNDEF if size != 0
5811 * bit 1 : UNDEF if size == 0
5812 * bit 2 : UNDEF if U == 1
5813 * Note that [1:0] set implies 'always UNDEF'
5816 /* prewiden, src1_wide, src2_wide, undefreq */
5817 static const int neon_3reg_wide
[16][4] = {
5818 {1, 0, 0, 0}, /* VADDL */
5819 {1, 1, 0, 0}, /* VADDW */
5820 {1, 0, 0, 0}, /* VSUBL */
5821 {1, 1, 0, 0}, /* VSUBW */
5822 {0, 1, 1, 0}, /* VADDHN */
5823 {0, 0, 0, 0}, /* VABAL */
5824 {0, 1, 1, 0}, /* VSUBHN */
5825 {0, 0, 0, 0}, /* VABDL */
5826 {0, 0, 0, 0}, /* VMLAL */
5827 {0, 0, 0, 6}, /* VQDMLAL */
5828 {0, 0, 0, 0}, /* VMLSL */
5829 {0, 0, 0, 6}, /* VQDMLSL */
5830 {0, 0, 0, 0}, /* Integer VMULL */
5831 {0, 0, 0, 2}, /* VQDMULL */
5832 {0, 0, 0, 5}, /* Polynomial VMULL */
5833 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5836 prewiden
= neon_3reg_wide
[op
][0];
5837 src1_wide
= neon_3reg_wide
[op
][1];
5838 src2_wide
= neon_3reg_wide
[op
][2];
5839 undefreq
= neon_3reg_wide
[op
][3];
5841 if (((undefreq
& 1) && (size
!= 0)) ||
5842 ((undefreq
& 2) && (size
== 0)) ||
5843 ((undefreq
& 4) && u
)) {
5846 if ((src1_wide
&& (rn
& 1)) ||
5847 (src2_wide
&& (rm
& 1)) ||
5848 (!src2_wide
&& (rd
& 1))) {
5852 /* Avoid overlapping operands. Wide source operands are
5853 always aligned so will never overlap with wide
5854 destinations in problematic ways. */
5855 if (rd
== rm
&& !src2_wide
) {
5856 tmp
= neon_load_reg(rm
, 1);
5857 neon_store_scratch(2, tmp
);
5858 } else if (rd
== rn
&& !src1_wide
) {
5859 tmp
= neon_load_reg(rn
, 1);
5860 neon_store_scratch(2, tmp
);
5862 TCGV_UNUSED_I32(tmp3
);
5863 for (pass
= 0; pass
< 2; pass
++) {
5865 neon_load_reg64(cpu_V0
, rn
+ pass
);
5866 TCGV_UNUSED_I32(tmp
);
5868 if (pass
== 1 && rd
== rn
) {
5869 tmp
= neon_load_scratch(2);
5871 tmp
= neon_load_reg(rn
, pass
);
5874 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5878 neon_load_reg64(cpu_V1
, rm
+ pass
);
5879 TCGV_UNUSED_I32(tmp2
);
5881 if (pass
== 1 && rd
== rm
) {
5882 tmp2
= neon_load_scratch(2);
5884 tmp2
= neon_load_reg(rm
, pass
);
5887 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5891 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5892 gen_neon_addl(size
);
5894 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5895 gen_neon_subl(size
);
5897 case 5: case 7: /* VABAL, VABDL */
5898 switch ((size
<< 1) | u
) {
5900 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5903 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5906 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5909 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5912 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5915 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5919 tcg_temp_free_i32(tmp2
);
5920 tcg_temp_free_i32(tmp
);
5922 case 8: case 9: case 10: case 11: case 12: case 13:
5923 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5924 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5926 case 14: /* Polynomial VMULL */
5927 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5928 tcg_temp_free_i32(tmp2
);
5929 tcg_temp_free_i32(tmp
);
5931 default: /* 15 is RESERVED: caught earlier */
5936 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5937 neon_store_reg64(cpu_V0
, rd
+ pass
);
5938 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5940 neon_load_reg64(cpu_V1
, rd
+ pass
);
5942 case 10: /* VMLSL */
5943 gen_neon_negl(cpu_V0
, size
);
5945 case 5: case 8: /* VABAL, VMLAL */
5946 gen_neon_addl(size
);
5948 case 9: case 11: /* VQDMLAL, VQDMLSL */
5949 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5951 gen_neon_negl(cpu_V0
, size
);
5953 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5958 neon_store_reg64(cpu_V0
, rd
+ pass
);
5959 } else if (op
== 4 || op
== 6) {
5960 /* Narrowing operation. */
5961 tmp
= tcg_temp_new_i32();
5965 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5968 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5971 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5972 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5979 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5982 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5985 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5986 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
5987 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
5995 neon_store_reg(rd
, 0, tmp3
);
5996 neon_store_reg(rd
, 1, tmp
);
5999 /* Write back the result. */
6000 neon_store_reg64(cpu_V0
, rd
+ pass
);
6004 /* Two registers and a scalar. NB that for ops of this form
6005 * the ARM ARM labels bit 24 as Q, but it is in our variable
6012 case 1: /* Float VMLA scalar */
6013 case 5: /* Floating point VMLS scalar */
6014 case 9: /* Floating point VMUL scalar */
6019 case 0: /* Integer VMLA scalar */
6020 case 4: /* Integer VMLS scalar */
6021 case 8: /* Integer VMUL scalar */
6022 case 12: /* VQDMULH scalar */
6023 case 13: /* VQRDMULH scalar */
6024 if (u
&& ((rd
| rn
) & 1)) {
6027 tmp
= neon_get_scalar(size
, rm
);
6028 neon_store_scratch(0, tmp
);
6029 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6030 tmp
= neon_load_scratch(0);
6031 tmp2
= neon_load_reg(rn
, pass
);
6034 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6036 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6038 } else if (op
== 13) {
6040 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6042 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6044 } else if (op
& 1) {
6045 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6046 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6047 tcg_temp_free_ptr(fpstatus
);
6050 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6051 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6052 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6056 tcg_temp_free_i32(tmp2
);
6059 tmp2
= neon_load_reg(rd
, pass
);
6062 gen_neon_add(size
, tmp
, tmp2
);
6066 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6067 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6068 tcg_temp_free_ptr(fpstatus
);
6072 gen_neon_rsb(size
, tmp
, tmp2
);
6076 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6077 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6078 tcg_temp_free_ptr(fpstatus
);
6084 tcg_temp_free_i32(tmp2
);
6086 neon_store_reg(rd
, pass
, tmp
);
6089 case 3: /* VQDMLAL scalar */
6090 case 7: /* VQDMLSL scalar */
6091 case 11: /* VQDMULL scalar */
6096 case 2: /* VMLAL sclar */
6097 case 6: /* VMLSL scalar */
6098 case 10: /* VMULL scalar */
6102 tmp2
= neon_get_scalar(size
, rm
);
6103 /* We need a copy of tmp2 because gen_neon_mull
6104 * deletes it during pass 0. */
6105 tmp4
= tcg_temp_new_i32();
6106 tcg_gen_mov_i32(tmp4
, tmp2
);
6107 tmp3
= neon_load_reg(rn
, 1);
6109 for (pass
= 0; pass
< 2; pass
++) {
6111 tmp
= neon_load_reg(rn
, 0);
6116 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6118 neon_load_reg64(cpu_V1
, rd
+ pass
);
6122 gen_neon_negl(cpu_V0
, size
);
6125 gen_neon_addl(size
);
6128 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6130 gen_neon_negl(cpu_V0
, size
);
6132 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6138 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6143 neon_store_reg64(cpu_V0
, rd
+ pass
);
6148 default: /* 14 and 15 are RESERVED */
6152 } else { /* size == 3 */
6155 imm
= (insn
>> 8) & 0xf;
6160 if (q
&& ((rd
| rn
| rm
) & 1)) {
6165 neon_load_reg64(cpu_V0
, rn
);
6167 neon_load_reg64(cpu_V1
, rn
+ 1);
6169 } else if (imm
== 8) {
6170 neon_load_reg64(cpu_V0
, rn
+ 1);
6172 neon_load_reg64(cpu_V1
, rm
);
6175 tmp64
= tcg_temp_new_i64();
6177 neon_load_reg64(cpu_V0
, rn
);
6178 neon_load_reg64(tmp64
, rn
+ 1);
6180 neon_load_reg64(cpu_V0
, rn
+ 1);
6181 neon_load_reg64(tmp64
, rm
);
6183 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6184 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6185 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6187 neon_load_reg64(cpu_V1
, rm
);
6189 neon_load_reg64(cpu_V1
, rm
+ 1);
6192 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6193 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6194 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6195 tcg_temp_free_i64(tmp64
);
6198 neon_load_reg64(cpu_V0
, rn
);
6199 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6200 neon_load_reg64(cpu_V1
, rm
);
6201 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6202 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6204 neon_store_reg64(cpu_V0
, rd
);
6206 neon_store_reg64(cpu_V1
, rd
+ 1);
6208 } else if ((insn
& (1 << 11)) == 0) {
6209 /* Two register misc. */
6210 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6211 size
= (insn
>> 18) & 3;
6212 /* UNDEF for unknown op values and bad op-size combinations */
6213 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6216 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6217 q
&& ((rm
| rd
) & 1)) {
6221 case NEON_2RM_VREV64
:
6222 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6223 tmp
= neon_load_reg(rm
, pass
* 2);
6224 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6226 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6227 case 1: gen_swap_half(tmp
); break;
6228 case 2: /* no-op */ break;
6231 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6233 neon_store_reg(rd
, pass
* 2, tmp2
);
6236 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6237 case 1: gen_swap_half(tmp2
); break;
6240 neon_store_reg(rd
, pass
* 2, tmp2
);
6244 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6245 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6246 for (pass
= 0; pass
< q
+ 1; pass
++) {
6247 tmp
= neon_load_reg(rm
, pass
* 2);
6248 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6249 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6250 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6252 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6253 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6254 case 2: tcg_gen_add_i64(CPU_V001
); break;
6257 if (op
>= NEON_2RM_VPADAL
) {
6259 neon_load_reg64(cpu_V1
, rd
+ pass
);
6260 gen_neon_addl(size
);
6262 neon_store_reg64(cpu_V0
, rd
+ pass
);
6268 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6269 tmp
= neon_load_reg(rm
, n
);
6270 tmp2
= neon_load_reg(rd
, n
+ 1);
6271 neon_store_reg(rm
, n
, tmp2
);
6272 neon_store_reg(rd
, n
+ 1, tmp
);
6279 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6284 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6288 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6289 /* also VQMOVUN; op field and mnemonics don't line up */
6293 TCGV_UNUSED_I32(tmp2
);
6294 for (pass
= 0; pass
< 2; pass
++) {
6295 neon_load_reg64(cpu_V0
, rm
+ pass
);
6296 tmp
= tcg_temp_new_i32();
6297 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6302 neon_store_reg(rd
, 0, tmp2
);
6303 neon_store_reg(rd
, 1, tmp
);
6307 case NEON_2RM_VSHLL
:
6308 if (q
|| (rd
& 1)) {
6311 tmp
= neon_load_reg(rm
, 0);
6312 tmp2
= neon_load_reg(rm
, 1);
6313 for (pass
= 0; pass
< 2; pass
++) {
6316 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6317 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6318 neon_store_reg64(cpu_V0
, rd
+ pass
);
6321 case NEON_2RM_VCVT_F16_F32
:
6322 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6326 tmp
= tcg_temp_new_i32();
6327 tmp2
= tcg_temp_new_i32();
6328 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6329 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6330 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6331 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6332 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6333 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6334 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6335 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6336 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6337 neon_store_reg(rd
, 0, tmp2
);
6338 tmp2
= tcg_temp_new_i32();
6339 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6340 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6341 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6342 neon_store_reg(rd
, 1, tmp2
);
6343 tcg_temp_free_i32(tmp
);
6345 case NEON_2RM_VCVT_F32_F16
:
6346 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6350 tmp3
= tcg_temp_new_i32();
6351 tmp
= neon_load_reg(rm
, 0);
6352 tmp2
= neon_load_reg(rm
, 1);
6353 tcg_gen_ext16u_i32(tmp3
, tmp
);
6354 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6355 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6356 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6357 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6358 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6359 tcg_temp_free_i32(tmp
);
6360 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6361 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6362 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6363 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6364 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6365 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6366 tcg_temp_free_i32(tmp2
);
6367 tcg_temp_free_i32(tmp3
);
6369 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6370 if (!arm_feature(env
, ARM_FEATURE_V8_AES
)
6371 || ((rm
| rd
) & 1)) {
6374 tmp
= tcg_const_i32(rd
);
6375 tmp2
= tcg_const_i32(rm
);
6377 /* Bit 6 is the lowest opcode bit; it distinguishes between
6378 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6380 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6382 if (op
== NEON_2RM_AESE
) {
6383 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6385 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6387 tcg_temp_free_i32(tmp
);
6388 tcg_temp_free_i32(tmp2
);
6389 tcg_temp_free_i32(tmp3
);
6393 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6394 if (neon_2rm_is_float_op(op
)) {
6395 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6396 neon_reg_offset(rm
, pass
));
6397 TCGV_UNUSED_I32(tmp
);
6399 tmp
= neon_load_reg(rm
, pass
);
6402 case NEON_2RM_VREV32
:
6404 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6405 case 1: gen_swap_half(tmp
); break;
6409 case NEON_2RM_VREV16
:
6414 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6415 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6416 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6422 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6423 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6424 case 2: gen_helper_clz(tmp
, tmp
); break;
6429 gen_helper_neon_cnt_u8(tmp
, tmp
);
6432 tcg_gen_not_i32(tmp
, tmp
);
6434 case NEON_2RM_VQABS
:
6437 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6440 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6443 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6448 case NEON_2RM_VQNEG
:
6451 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6454 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6457 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6462 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6463 tmp2
= tcg_const_i32(0);
6465 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6466 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6467 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6470 tcg_temp_free_i32(tmp2
);
6471 if (op
== NEON_2RM_VCLE0
) {
6472 tcg_gen_not_i32(tmp
, tmp
);
6475 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6476 tmp2
= tcg_const_i32(0);
6478 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6479 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6480 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6483 tcg_temp_free_i32(tmp2
);
6484 if (op
== NEON_2RM_VCLT0
) {
6485 tcg_gen_not_i32(tmp
, tmp
);
6488 case NEON_2RM_VCEQ0
:
6489 tmp2
= tcg_const_i32(0);
6491 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6492 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6493 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6496 tcg_temp_free_i32(tmp2
);
6500 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6501 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6502 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6507 tmp2
= tcg_const_i32(0);
6508 gen_neon_rsb(size
, tmp
, tmp2
);
6509 tcg_temp_free_i32(tmp2
);
6511 case NEON_2RM_VCGT0_F
:
6513 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6514 tmp2
= tcg_const_i32(0);
6515 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6516 tcg_temp_free_i32(tmp2
);
6517 tcg_temp_free_ptr(fpstatus
);
6520 case NEON_2RM_VCGE0_F
:
6522 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6523 tmp2
= tcg_const_i32(0);
6524 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6525 tcg_temp_free_i32(tmp2
);
6526 tcg_temp_free_ptr(fpstatus
);
6529 case NEON_2RM_VCEQ0_F
:
6531 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6532 tmp2
= tcg_const_i32(0);
6533 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6534 tcg_temp_free_i32(tmp2
);
6535 tcg_temp_free_ptr(fpstatus
);
6538 case NEON_2RM_VCLE0_F
:
6540 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6541 tmp2
= tcg_const_i32(0);
6542 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6543 tcg_temp_free_i32(tmp2
);
6544 tcg_temp_free_ptr(fpstatus
);
6547 case NEON_2RM_VCLT0_F
:
6549 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6550 tmp2
= tcg_const_i32(0);
6551 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6552 tcg_temp_free_i32(tmp2
);
6553 tcg_temp_free_ptr(fpstatus
);
6556 case NEON_2RM_VABS_F
:
6559 case NEON_2RM_VNEG_F
:
6563 tmp2
= neon_load_reg(rd
, pass
);
6564 neon_store_reg(rm
, pass
, tmp2
);
6567 tmp2
= neon_load_reg(rd
, pass
);
6569 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6570 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6573 neon_store_reg(rm
, pass
, tmp2
);
6575 case NEON_2RM_VRINTN
:
6576 case NEON_2RM_VRINTA
:
6577 case NEON_2RM_VRINTM
:
6578 case NEON_2RM_VRINTP
:
6579 case NEON_2RM_VRINTZ
:
6582 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6585 if (op
== NEON_2RM_VRINTZ
) {
6586 rmode
= FPROUNDING_ZERO
;
6588 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6591 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6592 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6594 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6595 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6597 tcg_temp_free_ptr(fpstatus
);
6598 tcg_temp_free_i32(tcg_rmode
);
6601 case NEON_2RM_VRINTX
:
6603 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6604 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6605 tcg_temp_free_ptr(fpstatus
);
6608 case NEON_2RM_VCVTAU
:
6609 case NEON_2RM_VCVTAS
:
6610 case NEON_2RM_VCVTNU
:
6611 case NEON_2RM_VCVTNS
:
6612 case NEON_2RM_VCVTPU
:
6613 case NEON_2RM_VCVTPS
:
6614 case NEON_2RM_VCVTMU
:
6615 case NEON_2RM_VCVTMS
:
6617 bool is_signed
= !extract32(insn
, 7, 1);
6618 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6619 TCGv_i32 tcg_rmode
, tcg_shift
;
6620 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6622 tcg_shift
= tcg_const_i32(0);
6623 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6624 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6628 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6631 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6635 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6637 tcg_temp_free_i32(tcg_rmode
);
6638 tcg_temp_free_i32(tcg_shift
);
6639 tcg_temp_free_ptr(fpst
);
6642 case NEON_2RM_VRECPE
:
6643 gen_helper_recpe_u32(tmp
, tmp
, cpu_env
);
6645 case NEON_2RM_VRSQRTE
:
6646 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6648 case NEON_2RM_VRECPE_F
:
6649 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6651 case NEON_2RM_VRSQRTE_F
:
6652 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6654 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6657 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6660 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6661 gen_vfp_tosiz(0, 1);
6663 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6664 gen_vfp_touiz(0, 1);
6667 /* Reserved op values were caught by the
6668 * neon_2rm_sizes[] check earlier.
6672 if (neon_2rm_is_float_op(op
)) {
6673 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6674 neon_reg_offset(rd
, pass
));
6676 neon_store_reg(rd
, pass
, tmp
);
6681 } else if ((insn
& (1 << 10)) == 0) {
6683 int n
= ((insn
>> 8) & 3) + 1;
6684 if ((rn
+ n
) > 32) {
6685 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6686 * helper function running off the end of the register file.
6691 if (insn
& (1 << 6)) {
6692 tmp
= neon_load_reg(rd
, 0);
6694 tmp
= tcg_temp_new_i32();
6695 tcg_gen_movi_i32(tmp
, 0);
6697 tmp2
= neon_load_reg(rm
, 0);
6698 tmp4
= tcg_const_i32(rn
);
6699 tmp5
= tcg_const_i32(n
);
6700 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6701 tcg_temp_free_i32(tmp
);
6702 if (insn
& (1 << 6)) {
6703 tmp
= neon_load_reg(rd
, 1);
6705 tmp
= tcg_temp_new_i32();
6706 tcg_gen_movi_i32(tmp
, 0);
6708 tmp3
= neon_load_reg(rm
, 1);
6709 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6710 tcg_temp_free_i32(tmp5
);
6711 tcg_temp_free_i32(tmp4
);
6712 neon_store_reg(rd
, 0, tmp2
);
6713 neon_store_reg(rd
, 1, tmp3
);
6714 tcg_temp_free_i32(tmp
);
6715 } else if ((insn
& 0x380) == 0) {
6717 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6720 if (insn
& (1 << 19)) {
6721 tmp
= neon_load_reg(rm
, 1);
6723 tmp
= neon_load_reg(rm
, 0);
6725 if (insn
& (1 << 16)) {
6726 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6727 } else if (insn
& (1 << 17)) {
6728 if ((insn
>> 18) & 1)
6729 gen_neon_dup_high16(tmp
);
6731 gen_neon_dup_low16(tmp
);
6733 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6734 tmp2
= tcg_temp_new_i32();
6735 tcg_gen_mov_i32(tmp2
, tmp
);
6736 neon_store_reg(rd
, pass
, tmp2
);
6738 tcg_temp_free_i32(tmp
);
6747 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6749 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6750 const ARMCPRegInfo
*ri
;
6752 cpnum
= (insn
>> 8) & 0xf;
6753 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6754 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6757 /* First check for coprocessor space used for actual instructions */
6761 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6762 return disas_iwmmxt_insn(env
, s
, insn
);
6763 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6764 return disas_dsp_insn(env
, s
, insn
);
6771 /* Otherwise treat as a generic register access */
6772 is64
= (insn
& (1 << 25)) == 0;
6773 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6781 opc1
= (insn
>> 4) & 0xf;
6783 rt2
= (insn
>> 16) & 0xf;
6785 crn
= (insn
>> 16) & 0xf;
6786 opc1
= (insn
>> 21) & 7;
6787 opc2
= (insn
>> 5) & 7;
6790 isread
= (insn
>> 20) & 1;
6791 rt
= (insn
>> 12) & 0xf;
6793 ri
= get_arm_cp_reginfo(s
->cp_regs
,
6794 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6796 /* Check access permissions */
6797 if (!cp_access_ok(s
->current_pl
, ri
, isread
)) {
6801 /* Handle special cases first */
6802 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6809 gen_set_pc_im(s
, s
->pc
);
6810 s
->is_jmp
= DISAS_WFI
;
6816 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6825 if (ri
->type
& ARM_CP_CONST
) {
6826 tmp64
= tcg_const_i64(ri
->resetvalue
);
6827 } else if (ri
->readfn
) {
6829 gen_set_pc_im(s
, s
->pc
);
6830 tmp64
= tcg_temp_new_i64();
6831 tmpptr
= tcg_const_ptr(ri
);
6832 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6833 tcg_temp_free_ptr(tmpptr
);
6835 tmp64
= tcg_temp_new_i64();
6836 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6838 tmp
= tcg_temp_new_i32();
6839 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6840 store_reg(s
, rt
, tmp
);
6841 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6842 tmp
= tcg_temp_new_i32();
6843 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6844 tcg_temp_free_i64(tmp64
);
6845 store_reg(s
, rt2
, tmp
);
6848 if (ri
->type
& ARM_CP_CONST
) {
6849 tmp
= tcg_const_i32(ri
->resetvalue
);
6850 } else if (ri
->readfn
) {
6852 gen_set_pc_im(s
, s
->pc
);
6853 tmp
= tcg_temp_new_i32();
6854 tmpptr
= tcg_const_ptr(ri
);
6855 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6856 tcg_temp_free_ptr(tmpptr
);
6858 tmp
= load_cpu_offset(ri
->fieldoffset
);
6861 /* Destination register of r15 for 32 bit loads sets
6862 * the condition codes from the high 4 bits of the value
6865 tcg_temp_free_i32(tmp
);
6867 store_reg(s
, rt
, tmp
);
6872 if (ri
->type
& ARM_CP_CONST
) {
6873 /* If not forbidden by access permissions, treat as WI */
6878 TCGv_i32 tmplo
, tmphi
;
6879 TCGv_i64 tmp64
= tcg_temp_new_i64();
6880 tmplo
= load_reg(s
, rt
);
6881 tmphi
= load_reg(s
, rt2
);
6882 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6883 tcg_temp_free_i32(tmplo
);
6884 tcg_temp_free_i32(tmphi
);
6886 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6887 gen_set_pc_im(s
, s
->pc
);
6888 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6889 tcg_temp_free_ptr(tmpptr
);
6891 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6893 tcg_temp_free_i64(tmp64
);
6898 gen_set_pc_im(s
, s
->pc
);
6899 tmp
= load_reg(s
, rt
);
6900 tmpptr
= tcg_const_ptr(ri
);
6901 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6902 tcg_temp_free_ptr(tmpptr
);
6903 tcg_temp_free_i32(tmp
);
6905 TCGv_i32 tmp
= load_reg(s
, rt
);
6906 store_cpu_offset(tmp
, ri
->fieldoffset
);
6911 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6912 /* I/O operations must end the TB here (whether read or write) */
6915 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6916 /* We default to ending the TB on a coprocessor register write,
6917 * but allow this to be suppressed by the register definition
6918 * (usually only necessary to work around guest bugs).
6930 /* Store a 64-bit value to a register pair. Clobbers val. */
6931 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
6934 tmp
= tcg_temp_new_i32();
6935 tcg_gen_trunc_i64_i32(tmp
, val
);
6936 store_reg(s
, rlow
, tmp
);
6937 tmp
= tcg_temp_new_i32();
6938 tcg_gen_shri_i64(val
, val
, 32);
6939 tcg_gen_trunc_i64_i32(tmp
, val
);
6940 store_reg(s
, rhigh
, tmp
);
6943 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6944 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
6949 /* Load value and extend to 64 bits. */
6950 tmp
= tcg_temp_new_i64();
6951 tmp2
= load_reg(s
, rlow
);
6952 tcg_gen_extu_i32_i64(tmp
, tmp2
);
6953 tcg_temp_free_i32(tmp2
);
6954 tcg_gen_add_i64(val
, val
, tmp
);
6955 tcg_temp_free_i64(tmp
);
6958 /* load and add a 64-bit value from a register pair. */
6959 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
6965 /* Load 64-bit value rd:rn. */
6966 tmpl
= load_reg(s
, rlow
);
6967 tmph
= load_reg(s
, rhigh
);
6968 tmp
= tcg_temp_new_i64();
6969 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
6970 tcg_temp_free_i32(tmpl
);
6971 tcg_temp_free_i32(tmph
);
6972 tcg_gen_add_i64(val
, val
, tmp
);
6973 tcg_temp_free_i64(tmp
);
6976 /* Set N and Z flags from hi|lo. */
6977 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
6979 tcg_gen_mov_i32(cpu_NF
, hi
);
6980 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
6983 /* Load/Store exclusive instructions are implemented by remembering
6984 the value/address loaded, and seeing if these are the same
6985 when the store is performed. This should be sufficient to implement
6986 the architecturally mandated semantics, and avoids having to monitor
6989 In system emulation mode only one CPU will be running at once, so
6990 this sequence is effectively atomic. In user emulation mode we
6991 throw an exception and handle the atomic operation elsewhere. */
6992 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
6993 TCGv_i32 addr
, int size
)
6995 TCGv_i32 tmp
= tcg_temp_new_i32();
6999 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
7002 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7006 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7013 TCGv_i32 tmp2
= tcg_temp_new_i32();
7014 TCGv_i32 tmp3
= tcg_temp_new_i32();
7016 tcg_gen_addi_i32(tmp2
, addr
, 4);
7017 gen_aa32_ld32u(tmp3
, tmp2
, IS_USER(s
));
7018 tcg_temp_free_i32(tmp2
);
7019 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7020 store_reg(s
, rt2
, tmp3
);
7022 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7025 store_reg(s
, rt
, tmp
);
7026 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7029 static void gen_clrex(DisasContext
*s
)
7031 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7034 #ifdef CONFIG_USER_ONLY
7035 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7036 TCGv_i32 addr
, int size
)
7038 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7039 tcg_gen_movi_i32(cpu_exclusive_info
,
7040 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7041 gen_exception_insn(s
, 4, EXCP_STREX
);
7044 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7045 TCGv_i32 addr
, int size
)
7048 TCGv_i64 val64
, extaddr
;
7052 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7058 fail_label
= gen_new_label();
7059 done_label
= gen_new_label();
7060 extaddr
= tcg_temp_new_i64();
7061 tcg_gen_extu_i32_i64(extaddr
, addr
);
7062 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7063 tcg_temp_free_i64(extaddr
);
7065 tmp
= tcg_temp_new_i32();
7068 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
7071 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7075 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7081 val64
= tcg_temp_new_i64();
7083 TCGv_i32 tmp2
= tcg_temp_new_i32();
7084 TCGv_i32 tmp3
= tcg_temp_new_i32();
7085 tcg_gen_addi_i32(tmp2
, addr
, 4);
7086 gen_aa32_ld32u(tmp3
, tmp2
, IS_USER(s
));
7087 tcg_temp_free_i32(tmp2
);
7088 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7089 tcg_temp_free_i32(tmp3
);
7091 tcg_gen_extu_i32_i64(val64
, tmp
);
7093 tcg_temp_free_i32(tmp
);
7095 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7096 tcg_temp_free_i64(val64
);
7098 tmp
= load_reg(s
, rt
);
7101 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7104 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7108 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7113 tcg_temp_free_i32(tmp
);
7115 tcg_gen_addi_i32(addr
, addr
, 4);
7116 tmp
= load_reg(s
, rt2
);
7117 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7118 tcg_temp_free_i32(tmp
);
7120 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7121 tcg_gen_br(done_label
);
7122 gen_set_label(fail_label
);
7123 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7124 gen_set_label(done_label
);
7125 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7132 * @mode: mode field from insn (which stack to store to)
7133 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7134 * @writeback: true if writeback bit set
7136 * Generate code for the SRS (Store Return State) insn.
7138 static void gen_srs(DisasContext
*s
,
7139 uint32_t mode
, uint32_t amode
, bool writeback
)
7142 TCGv_i32 addr
= tcg_temp_new_i32();
7143 TCGv_i32 tmp
= tcg_const_i32(mode
);
7144 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7145 tcg_temp_free_i32(tmp
);
7162 tcg_gen_addi_i32(addr
, addr
, offset
);
7163 tmp
= load_reg(s
, 14);
7164 gen_aa32_st32(tmp
, addr
, 0);
7165 tcg_temp_free_i32(tmp
);
7166 tmp
= load_cpu_field(spsr
);
7167 tcg_gen_addi_i32(addr
, addr
, 4);
7168 gen_aa32_st32(tmp
, addr
, 0);
7169 tcg_temp_free_i32(tmp
);
7187 tcg_gen_addi_i32(addr
, addr
, offset
);
7188 tmp
= tcg_const_i32(mode
);
7189 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7190 tcg_temp_free_i32(tmp
);
7192 tcg_temp_free_i32(addr
);
7195 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
7197 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7204 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
7207 /* M variants do not implement ARM mode. */
7212 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7213 * choose to UNDEF. In ARMv5 and above the space is used
7214 * for miscellaneous unconditional instructions.
7218 /* Unconditional instructions. */
7219 if (((insn
>> 25) & 7) == 1) {
7220 /* NEON Data processing. */
7221 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7224 if (disas_neon_data_insn(env
, s
, insn
))
7228 if ((insn
& 0x0f100000) == 0x04000000) {
7229 /* NEON load/store. */
7230 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7233 if (disas_neon_ls_insn(env
, s
, insn
))
7237 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7239 if (disas_vfp_insn(env
, s
, insn
)) {
7244 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7245 ((insn
& 0x0f30f010) == 0x0710f000)) {
7246 if ((insn
& (1 << 22)) == 0) {
7248 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7252 /* Otherwise PLD; v5TE+ */
7256 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7257 ((insn
& 0x0f70f010) == 0x0650f000)) {
7259 return; /* PLI; V7 */
7261 if (((insn
& 0x0f700000) == 0x04100000) ||
7262 ((insn
& 0x0f700010) == 0x06100000)) {
7263 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7266 return; /* v7MP: Unallocated memory hint: must NOP */
7269 if ((insn
& 0x0ffffdff) == 0x01010000) {
7272 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7273 /* Dynamic endianness switching not implemented. */
7274 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7278 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7279 switch ((insn
>> 4) & 0xf) {
7288 /* We don't emulate caches so these are a no-op. */
7293 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7299 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7301 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7307 rn
= (insn
>> 16) & 0xf;
7308 addr
= load_reg(s
, rn
);
7309 i
= (insn
>> 23) & 3;
7311 case 0: offset
= -4; break; /* DA */
7312 case 1: offset
= 0; break; /* IA */
7313 case 2: offset
= -8; break; /* DB */
7314 case 3: offset
= 4; break; /* IB */
7318 tcg_gen_addi_i32(addr
, addr
, offset
);
7319 /* Load PC into tmp and CPSR into tmp2. */
7320 tmp
= tcg_temp_new_i32();
7321 gen_aa32_ld32u(tmp
, addr
, 0);
7322 tcg_gen_addi_i32(addr
, addr
, 4);
7323 tmp2
= tcg_temp_new_i32();
7324 gen_aa32_ld32u(tmp2
, addr
, 0);
7325 if (insn
& (1 << 21)) {
7326 /* Base writeback. */
7328 case 0: offset
= -8; break;
7329 case 1: offset
= 4; break;
7330 case 2: offset
= -4; break;
7331 case 3: offset
= 0; break;
7335 tcg_gen_addi_i32(addr
, addr
, offset
);
7336 store_reg(s
, rn
, addr
);
7338 tcg_temp_free_i32(addr
);
7340 gen_rfe(s
, tmp
, tmp2
);
7342 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7343 /* branch link and change to thumb (blx <offset>) */
7346 val
= (uint32_t)s
->pc
;
7347 tmp
= tcg_temp_new_i32();
7348 tcg_gen_movi_i32(tmp
, val
);
7349 store_reg(s
, 14, tmp
);
7350 /* Sign-extend the 24-bit offset */
7351 offset
= (((int32_t)insn
) << 8) >> 8;
7352 /* offset * 4 + bit24 * 2 + (thumb bit) */
7353 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7354 /* pipeline offset */
7356 /* protected by ARCH(5); above, near the start of uncond block */
7359 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7360 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7361 /* iWMMXt register transfer. */
7362 if (env
->cp15
.c15_cpar
& (1 << 1))
7363 if (!disas_iwmmxt_insn(env
, s
, insn
))
7366 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7367 /* Coprocessor double register transfer. */
7369 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7370 /* Additional coprocessor register transfer. */
7371 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7374 /* cps (privileged) */
7378 if (insn
& (1 << 19)) {
7379 if (insn
& (1 << 8))
7381 if (insn
& (1 << 7))
7383 if (insn
& (1 << 6))
7385 if (insn
& (1 << 18))
7388 if (insn
& (1 << 17)) {
7390 val
|= (insn
& 0x1f);
7393 gen_set_psr_im(s
, mask
, 0, val
);
7400 /* if not always execute, we generate a conditional jump to
7402 s
->condlabel
= gen_new_label();
7403 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7406 if ((insn
& 0x0f900000) == 0x03000000) {
7407 if ((insn
& (1 << 21)) == 0) {
7409 rd
= (insn
>> 12) & 0xf;
7410 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7411 if ((insn
& (1 << 22)) == 0) {
7413 tmp
= tcg_temp_new_i32();
7414 tcg_gen_movi_i32(tmp
, val
);
7417 tmp
= load_reg(s
, rd
);
7418 tcg_gen_ext16u_i32(tmp
, tmp
);
7419 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7421 store_reg(s
, rd
, tmp
);
7423 if (((insn
>> 12) & 0xf) != 0xf)
7425 if (((insn
>> 16) & 0xf) == 0) {
7426 gen_nop_hint(s
, insn
& 0xff);
7428 /* CPSR = immediate */
7430 shift
= ((insn
>> 8) & 0xf) * 2;
7432 val
= (val
>> shift
) | (val
<< (32 - shift
));
7433 i
= ((insn
& (1 << 22)) != 0);
7434 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7438 } else if ((insn
& 0x0f900000) == 0x01000000
7439 && (insn
& 0x00000090) != 0x00000090) {
7440 /* miscellaneous instructions */
7441 op1
= (insn
>> 21) & 3;
7442 sh
= (insn
>> 4) & 0xf;
7445 case 0x0: /* move program status register */
7448 tmp
= load_reg(s
, rm
);
7449 i
= ((op1
& 2) != 0);
7450 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7454 rd
= (insn
>> 12) & 0xf;
7458 tmp
= load_cpu_field(spsr
);
7460 tmp
= tcg_temp_new_i32();
7461 gen_helper_cpsr_read(tmp
, cpu_env
);
7463 store_reg(s
, rd
, tmp
);
7468 /* branch/exchange thumb (bx). */
7470 tmp
= load_reg(s
, rm
);
7472 } else if (op1
== 3) {
7475 rd
= (insn
>> 12) & 0xf;
7476 tmp
= load_reg(s
, rm
);
7477 gen_helper_clz(tmp
, tmp
);
7478 store_reg(s
, rd
, tmp
);
7486 /* Trivial implementation equivalent to bx. */
7487 tmp
= load_reg(s
, rm
);
7498 /* branch link/exchange thumb (blx) */
7499 tmp
= load_reg(s
, rm
);
7500 tmp2
= tcg_temp_new_i32();
7501 tcg_gen_movi_i32(tmp2
, s
->pc
);
7502 store_reg(s
, 14, tmp2
);
7505 case 0x5: /* saturating add/subtract */
7507 rd
= (insn
>> 12) & 0xf;
7508 rn
= (insn
>> 16) & 0xf;
7509 tmp
= load_reg(s
, rm
);
7510 tmp2
= load_reg(s
, rn
);
7512 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7514 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7516 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7517 tcg_temp_free_i32(tmp2
);
7518 store_reg(s
, rd
, tmp
);
7521 /* SMC instruction (op1 == 3)
7522 and undefined instructions (op1 == 0 || op1 == 2)
7529 gen_exception_insn(s
, 4, EXCP_BKPT
);
7531 case 0x8: /* signed multiply */
7536 rs
= (insn
>> 8) & 0xf;
7537 rn
= (insn
>> 12) & 0xf;
7538 rd
= (insn
>> 16) & 0xf;
7540 /* (32 * 16) >> 16 */
7541 tmp
= load_reg(s
, rm
);
7542 tmp2
= load_reg(s
, rs
);
7544 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7547 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7548 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7549 tmp
= tcg_temp_new_i32();
7550 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7551 tcg_temp_free_i64(tmp64
);
7552 if ((sh
& 2) == 0) {
7553 tmp2
= load_reg(s
, rn
);
7554 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7555 tcg_temp_free_i32(tmp2
);
7557 store_reg(s
, rd
, tmp
);
7560 tmp
= load_reg(s
, rm
);
7561 tmp2
= load_reg(s
, rs
);
7562 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7563 tcg_temp_free_i32(tmp2
);
7565 tmp64
= tcg_temp_new_i64();
7566 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7567 tcg_temp_free_i32(tmp
);
7568 gen_addq(s
, tmp64
, rn
, rd
);
7569 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7570 tcg_temp_free_i64(tmp64
);
7573 tmp2
= load_reg(s
, rn
);
7574 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7575 tcg_temp_free_i32(tmp2
);
7577 store_reg(s
, rd
, tmp
);
7584 } else if (((insn
& 0x0e000000) == 0 &&
7585 (insn
& 0x00000090) != 0x90) ||
7586 ((insn
& 0x0e000000) == (1 << 25))) {
7587 int set_cc
, logic_cc
, shiftop
;
7589 op1
= (insn
>> 21) & 0xf;
7590 set_cc
= (insn
>> 20) & 1;
7591 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7593 /* data processing instruction */
7594 if (insn
& (1 << 25)) {
7595 /* immediate operand */
7597 shift
= ((insn
>> 8) & 0xf) * 2;
7599 val
= (val
>> shift
) | (val
<< (32 - shift
));
7601 tmp2
= tcg_temp_new_i32();
7602 tcg_gen_movi_i32(tmp2
, val
);
7603 if (logic_cc
&& shift
) {
7604 gen_set_CF_bit31(tmp2
);
7609 tmp2
= load_reg(s
, rm
);
7610 shiftop
= (insn
>> 5) & 3;
7611 if (!(insn
& (1 << 4))) {
7612 shift
= (insn
>> 7) & 0x1f;
7613 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7615 rs
= (insn
>> 8) & 0xf;
7616 tmp
= load_reg(s
, rs
);
7617 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7620 if (op1
!= 0x0f && op1
!= 0x0d) {
7621 rn
= (insn
>> 16) & 0xf;
7622 tmp
= load_reg(s
, rn
);
7624 TCGV_UNUSED_I32(tmp
);
7626 rd
= (insn
>> 12) & 0xf;
7629 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7633 store_reg_bx(env
, s
, rd
, tmp
);
7636 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7640 store_reg_bx(env
, s
, rd
, tmp
);
7643 if (set_cc
&& rd
== 15) {
7644 /* SUBS r15, ... is used for exception return. */
7648 gen_sub_CC(tmp
, tmp
, tmp2
);
7649 gen_exception_return(s
, tmp
);
7652 gen_sub_CC(tmp
, tmp
, tmp2
);
7654 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7656 store_reg_bx(env
, s
, rd
, tmp
);
7661 gen_sub_CC(tmp
, tmp2
, tmp
);
7663 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7665 store_reg_bx(env
, s
, rd
, tmp
);
7669 gen_add_CC(tmp
, tmp
, tmp2
);
7671 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7673 store_reg_bx(env
, s
, rd
, tmp
);
7677 gen_adc_CC(tmp
, tmp
, tmp2
);
7679 gen_add_carry(tmp
, tmp
, tmp2
);
7681 store_reg_bx(env
, s
, rd
, tmp
);
7685 gen_sbc_CC(tmp
, tmp
, tmp2
);
7687 gen_sub_carry(tmp
, tmp
, tmp2
);
7689 store_reg_bx(env
, s
, rd
, tmp
);
7693 gen_sbc_CC(tmp
, tmp2
, tmp
);
7695 gen_sub_carry(tmp
, tmp2
, tmp
);
7697 store_reg_bx(env
, s
, rd
, tmp
);
7701 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7704 tcg_temp_free_i32(tmp
);
7708 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7711 tcg_temp_free_i32(tmp
);
7715 gen_sub_CC(tmp
, tmp
, tmp2
);
7717 tcg_temp_free_i32(tmp
);
7721 gen_add_CC(tmp
, tmp
, tmp2
);
7723 tcg_temp_free_i32(tmp
);
7726 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7730 store_reg_bx(env
, s
, rd
, tmp
);
7733 if (logic_cc
&& rd
== 15) {
7734 /* MOVS r15, ... is used for exception return. */
7738 gen_exception_return(s
, tmp2
);
7743 store_reg_bx(env
, s
, rd
, tmp2
);
7747 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7751 store_reg_bx(env
, s
, rd
, tmp
);
7755 tcg_gen_not_i32(tmp2
, tmp2
);
7759 store_reg_bx(env
, s
, rd
, tmp2
);
7762 if (op1
!= 0x0f && op1
!= 0x0d) {
7763 tcg_temp_free_i32(tmp2
);
7766 /* other instructions */
7767 op1
= (insn
>> 24) & 0xf;
7771 /* multiplies, extra load/stores */
7772 sh
= (insn
>> 5) & 3;
7775 rd
= (insn
>> 16) & 0xf;
7776 rn
= (insn
>> 12) & 0xf;
7777 rs
= (insn
>> 8) & 0xf;
7779 op1
= (insn
>> 20) & 0xf;
7781 case 0: case 1: case 2: case 3: case 6:
7783 tmp
= load_reg(s
, rs
);
7784 tmp2
= load_reg(s
, rm
);
7785 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7786 tcg_temp_free_i32(tmp2
);
7787 if (insn
& (1 << 22)) {
7788 /* Subtract (mls) */
7790 tmp2
= load_reg(s
, rn
);
7791 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7792 tcg_temp_free_i32(tmp2
);
7793 } else if (insn
& (1 << 21)) {
7795 tmp2
= load_reg(s
, rn
);
7796 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7797 tcg_temp_free_i32(tmp2
);
7799 if (insn
& (1 << 20))
7801 store_reg(s
, rd
, tmp
);
7804 /* 64 bit mul double accumulate (UMAAL) */
7806 tmp
= load_reg(s
, rs
);
7807 tmp2
= load_reg(s
, rm
);
7808 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7809 gen_addq_lo(s
, tmp64
, rn
);
7810 gen_addq_lo(s
, tmp64
, rd
);
7811 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7812 tcg_temp_free_i64(tmp64
);
7814 case 8: case 9: case 10: case 11:
7815 case 12: case 13: case 14: case 15:
7816 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7817 tmp
= load_reg(s
, rs
);
7818 tmp2
= load_reg(s
, rm
);
7819 if (insn
& (1 << 22)) {
7820 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
7822 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
7824 if (insn
& (1 << 21)) { /* mult accumulate */
7825 TCGv_i32 al
= load_reg(s
, rn
);
7826 TCGv_i32 ah
= load_reg(s
, rd
);
7827 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
7828 tcg_temp_free_i32(al
);
7829 tcg_temp_free_i32(ah
);
7831 if (insn
& (1 << 20)) {
7832 gen_logicq_cc(tmp
, tmp2
);
7834 store_reg(s
, rn
, tmp
);
7835 store_reg(s
, rd
, tmp2
);
7841 rn
= (insn
>> 16) & 0xf;
7842 rd
= (insn
>> 12) & 0xf;
7843 if (insn
& (1 << 23)) {
7844 /* load/store exclusive */
7845 int op2
= (insn
>> 8) & 3;
7846 op1
= (insn
>> 21) & 0x3;
7849 case 0: /* lda/stl */
7855 case 1: /* reserved */
7857 case 2: /* ldaex/stlex */
7860 case 3: /* ldrex/strex */
7869 addr
= tcg_temp_local_new_i32();
7870 load_reg_var(s
, addr
, rn
);
7872 /* Since the emulation does not have barriers,
7873 the acquire/release semantics need no special
7876 if (insn
& (1 << 20)) {
7877 tmp
= tcg_temp_new_i32();
7880 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7883 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
7886 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7891 store_reg(s
, rd
, tmp
);
7894 tmp
= load_reg(s
, rm
);
7897 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7900 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7903 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7908 tcg_temp_free_i32(tmp
);
7910 } else if (insn
& (1 << 20)) {
7913 gen_load_exclusive(s
, rd
, 15, addr
, 2);
7915 case 1: /* ldrexd */
7916 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
7918 case 2: /* ldrexb */
7919 gen_load_exclusive(s
, rd
, 15, addr
, 0);
7921 case 3: /* ldrexh */
7922 gen_load_exclusive(s
, rd
, 15, addr
, 1);
7931 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
7933 case 1: /* strexd */
7934 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
7936 case 2: /* strexb */
7937 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
7939 case 3: /* strexh */
7940 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
7946 tcg_temp_free_i32(addr
);
7948 /* SWP instruction */
7951 /* ??? This is not really atomic. However we know
7952 we never have multiple CPUs running in parallel,
7953 so it is good enough. */
7954 addr
= load_reg(s
, rn
);
7955 tmp
= load_reg(s
, rm
);
7956 tmp2
= tcg_temp_new_i32();
7957 if (insn
& (1 << 22)) {
7958 gen_aa32_ld8u(tmp2
, addr
, IS_USER(s
));
7959 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7961 gen_aa32_ld32u(tmp2
, addr
, IS_USER(s
));
7962 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7964 tcg_temp_free_i32(tmp
);
7965 tcg_temp_free_i32(addr
);
7966 store_reg(s
, rd
, tmp2
);
7972 /* Misc load/store */
7973 rn
= (insn
>> 16) & 0xf;
7974 rd
= (insn
>> 12) & 0xf;
7975 addr
= load_reg(s
, rn
);
7976 if (insn
& (1 << 24))
7977 gen_add_datah_offset(s
, insn
, 0, addr
);
7979 if (insn
& (1 << 20)) {
7981 tmp
= tcg_temp_new_i32();
7984 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7987 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
7991 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
7995 } else if (sh
& 2) {
8000 tmp
= load_reg(s
, rd
);
8001 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8002 tcg_temp_free_i32(tmp
);
8003 tcg_gen_addi_i32(addr
, addr
, 4);
8004 tmp
= load_reg(s
, rd
+ 1);
8005 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8006 tcg_temp_free_i32(tmp
);
8010 tmp
= tcg_temp_new_i32();
8011 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8012 store_reg(s
, rd
, tmp
);
8013 tcg_gen_addi_i32(addr
, addr
, 4);
8014 tmp
= tcg_temp_new_i32();
8015 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8019 address_offset
= -4;
8022 tmp
= load_reg(s
, rd
);
8023 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
8024 tcg_temp_free_i32(tmp
);
8027 /* Perform base writeback before the loaded value to
8028 ensure correct behavior with overlapping index registers.
8029 ldrd with base writeback is is undefined if the
8030 destination and index registers overlap. */
8031 if (!(insn
& (1 << 24))) {
8032 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8033 store_reg(s
, rn
, addr
);
8034 } else if (insn
& (1 << 21)) {
8036 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8037 store_reg(s
, rn
, addr
);
8039 tcg_temp_free_i32(addr
);
8042 /* Complete the load. */
8043 store_reg(s
, rd
, tmp
);
8052 if (insn
& (1 << 4)) {
8054 /* Armv6 Media instructions. */
8056 rn
= (insn
>> 16) & 0xf;
8057 rd
= (insn
>> 12) & 0xf;
8058 rs
= (insn
>> 8) & 0xf;
8059 switch ((insn
>> 23) & 3) {
8060 case 0: /* Parallel add/subtract. */
8061 op1
= (insn
>> 20) & 7;
8062 tmp
= load_reg(s
, rn
);
8063 tmp2
= load_reg(s
, rm
);
8064 sh
= (insn
>> 5) & 7;
8065 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8067 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8068 tcg_temp_free_i32(tmp2
);
8069 store_reg(s
, rd
, tmp
);
8072 if ((insn
& 0x00700020) == 0) {
8073 /* Halfword pack. */
8074 tmp
= load_reg(s
, rn
);
8075 tmp2
= load_reg(s
, rm
);
8076 shift
= (insn
>> 7) & 0x1f;
8077 if (insn
& (1 << 6)) {
8081 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8082 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8083 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8087 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8088 tcg_gen_ext16u_i32(tmp
, tmp
);
8089 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8091 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8092 tcg_temp_free_i32(tmp2
);
8093 store_reg(s
, rd
, tmp
);
8094 } else if ((insn
& 0x00200020) == 0x00200000) {
8096 tmp
= load_reg(s
, rm
);
8097 shift
= (insn
>> 7) & 0x1f;
8098 if (insn
& (1 << 6)) {
8101 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8103 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8105 sh
= (insn
>> 16) & 0x1f;
8106 tmp2
= tcg_const_i32(sh
);
8107 if (insn
& (1 << 22))
8108 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8110 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8111 tcg_temp_free_i32(tmp2
);
8112 store_reg(s
, rd
, tmp
);
8113 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8115 tmp
= load_reg(s
, rm
);
8116 sh
= (insn
>> 16) & 0x1f;
8117 tmp2
= tcg_const_i32(sh
);
8118 if (insn
& (1 << 22))
8119 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8121 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8122 tcg_temp_free_i32(tmp2
);
8123 store_reg(s
, rd
, tmp
);
8124 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8126 tmp
= load_reg(s
, rn
);
8127 tmp2
= load_reg(s
, rm
);
8128 tmp3
= tcg_temp_new_i32();
8129 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8130 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8131 tcg_temp_free_i32(tmp3
);
8132 tcg_temp_free_i32(tmp2
);
8133 store_reg(s
, rd
, tmp
);
8134 } else if ((insn
& 0x000003e0) == 0x00000060) {
8135 tmp
= load_reg(s
, rm
);
8136 shift
= (insn
>> 10) & 3;
8137 /* ??? In many cases it's not necessary to do a
8138 rotate, a shift is sufficient. */
8140 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8141 op1
= (insn
>> 20) & 7;
8143 case 0: gen_sxtb16(tmp
); break;
8144 case 2: gen_sxtb(tmp
); break;
8145 case 3: gen_sxth(tmp
); break;
8146 case 4: gen_uxtb16(tmp
); break;
8147 case 6: gen_uxtb(tmp
); break;
8148 case 7: gen_uxth(tmp
); break;
8149 default: goto illegal_op
;
8152 tmp2
= load_reg(s
, rn
);
8153 if ((op1
& 3) == 0) {
8154 gen_add16(tmp
, tmp2
);
8156 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8157 tcg_temp_free_i32(tmp2
);
8160 store_reg(s
, rd
, tmp
);
8161 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8163 tmp
= load_reg(s
, rm
);
8164 if (insn
& (1 << 22)) {
8165 if (insn
& (1 << 7)) {
8169 gen_helper_rbit(tmp
, tmp
);
8172 if (insn
& (1 << 7))
8175 tcg_gen_bswap32_i32(tmp
, tmp
);
8177 store_reg(s
, rd
, tmp
);
8182 case 2: /* Multiplies (Type 3). */
8183 switch ((insn
>> 20) & 0x7) {
8185 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8186 /* op2 not 00x or 11x : UNDEF */
8189 /* Signed multiply most significant [accumulate].
8190 (SMMUL, SMMLA, SMMLS) */
8191 tmp
= load_reg(s
, rm
);
8192 tmp2
= load_reg(s
, rs
);
8193 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8196 tmp
= load_reg(s
, rd
);
8197 if (insn
& (1 << 6)) {
8198 tmp64
= gen_subq_msw(tmp64
, tmp
);
8200 tmp64
= gen_addq_msw(tmp64
, tmp
);
8203 if (insn
& (1 << 5)) {
8204 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8206 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8207 tmp
= tcg_temp_new_i32();
8208 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8209 tcg_temp_free_i64(tmp64
);
8210 store_reg(s
, rn
, tmp
);
8214 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8215 if (insn
& (1 << 7)) {
8218 tmp
= load_reg(s
, rm
);
8219 tmp2
= load_reg(s
, rs
);
8220 if (insn
& (1 << 5))
8221 gen_swap_half(tmp2
);
8222 gen_smul_dual(tmp
, tmp2
);
8223 if (insn
& (1 << 6)) {
8224 /* This subtraction cannot overflow. */
8225 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8227 /* This addition cannot overflow 32 bits;
8228 * however it may overflow considered as a signed
8229 * operation, in which case we must set the Q flag.
8231 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8233 tcg_temp_free_i32(tmp2
);
8234 if (insn
& (1 << 22)) {
8235 /* smlald, smlsld */
8236 tmp64
= tcg_temp_new_i64();
8237 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8238 tcg_temp_free_i32(tmp
);
8239 gen_addq(s
, tmp64
, rd
, rn
);
8240 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8241 tcg_temp_free_i64(tmp64
);
8243 /* smuad, smusd, smlad, smlsd */
8246 tmp2
= load_reg(s
, rd
);
8247 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8248 tcg_temp_free_i32(tmp2
);
8250 store_reg(s
, rn
, tmp
);
8256 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
8259 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8262 tmp
= load_reg(s
, rm
);
8263 tmp2
= load_reg(s
, rs
);
8264 if (insn
& (1 << 21)) {
8265 gen_helper_udiv(tmp
, tmp
, tmp2
);
8267 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8269 tcg_temp_free_i32(tmp2
);
8270 store_reg(s
, rn
, tmp
);
8277 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8279 case 0: /* Unsigned sum of absolute differences. */
8281 tmp
= load_reg(s
, rm
);
8282 tmp2
= load_reg(s
, rs
);
8283 gen_helper_usad8(tmp
, tmp
, tmp2
);
8284 tcg_temp_free_i32(tmp2
);
8286 tmp2
= load_reg(s
, rd
);
8287 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8288 tcg_temp_free_i32(tmp2
);
8290 store_reg(s
, rn
, tmp
);
8292 case 0x20: case 0x24: case 0x28: case 0x2c:
8293 /* Bitfield insert/clear. */
8295 shift
= (insn
>> 7) & 0x1f;
8296 i
= (insn
>> 16) & 0x1f;
8299 tmp
= tcg_temp_new_i32();
8300 tcg_gen_movi_i32(tmp
, 0);
8302 tmp
= load_reg(s
, rm
);
8305 tmp2
= load_reg(s
, rd
);
8306 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8307 tcg_temp_free_i32(tmp2
);
8309 store_reg(s
, rd
, tmp
);
8311 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8312 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8314 tmp
= load_reg(s
, rm
);
8315 shift
= (insn
>> 7) & 0x1f;
8316 i
= ((insn
>> 16) & 0x1f) + 1;
8321 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8323 gen_sbfx(tmp
, shift
, i
);
8326 store_reg(s
, rd
, tmp
);
8336 /* Check for undefined extension instructions
8337 * per the ARM Bible IE:
8338 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8340 sh
= (0xf << 20) | (0xf << 4);
8341 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8345 /* load/store byte/word */
8346 rn
= (insn
>> 16) & 0xf;
8347 rd
= (insn
>> 12) & 0xf;
8348 tmp2
= load_reg(s
, rn
);
8349 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
8350 if (insn
& (1 << 24))
8351 gen_add_data_offset(s
, insn
, tmp2
);
8352 if (insn
& (1 << 20)) {
8354 tmp
= tcg_temp_new_i32();
8355 if (insn
& (1 << 22)) {
8356 gen_aa32_ld8u(tmp
, tmp2
, i
);
8358 gen_aa32_ld32u(tmp
, tmp2
, i
);
8362 tmp
= load_reg(s
, rd
);
8363 if (insn
& (1 << 22)) {
8364 gen_aa32_st8(tmp
, tmp2
, i
);
8366 gen_aa32_st32(tmp
, tmp2
, i
);
8368 tcg_temp_free_i32(tmp
);
8370 if (!(insn
& (1 << 24))) {
8371 gen_add_data_offset(s
, insn
, tmp2
);
8372 store_reg(s
, rn
, tmp2
);
8373 } else if (insn
& (1 << 21)) {
8374 store_reg(s
, rn
, tmp2
);
8376 tcg_temp_free_i32(tmp2
);
8378 if (insn
& (1 << 20)) {
8379 /* Complete the load. */
8380 store_reg_from_load(env
, s
, rd
, tmp
);
8386 int j
, n
, user
, loaded_base
;
8387 TCGv_i32 loaded_var
;
8388 /* load/store multiple words */
8389 /* XXX: store correct base if write back */
8391 if (insn
& (1 << 22)) {
8393 goto illegal_op
; /* only usable in supervisor mode */
8395 if ((insn
& (1 << 15)) == 0)
8398 rn
= (insn
>> 16) & 0xf;
8399 addr
= load_reg(s
, rn
);
8401 /* compute total size */
8403 TCGV_UNUSED_I32(loaded_var
);
8406 if (insn
& (1 << i
))
8409 /* XXX: test invalid n == 0 case ? */
8410 if (insn
& (1 << 23)) {
8411 if (insn
& (1 << 24)) {
8413 tcg_gen_addi_i32(addr
, addr
, 4);
8415 /* post increment */
8418 if (insn
& (1 << 24)) {
8420 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8422 /* post decrement */
8424 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8429 if (insn
& (1 << i
)) {
8430 if (insn
& (1 << 20)) {
8432 tmp
= tcg_temp_new_i32();
8433 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8435 tmp2
= tcg_const_i32(i
);
8436 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8437 tcg_temp_free_i32(tmp2
);
8438 tcg_temp_free_i32(tmp
);
8439 } else if (i
== rn
) {
8443 store_reg_from_load(env
, s
, i
, tmp
);
8448 /* special case: r15 = PC + 8 */
8449 val
= (long)s
->pc
+ 4;
8450 tmp
= tcg_temp_new_i32();
8451 tcg_gen_movi_i32(tmp
, val
);
8453 tmp
= tcg_temp_new_i32();
8454 tmp2
= tcg_const_i32(i
);
8455 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8456 tcg_temp_free_i32(tmp2
);
8458 tmp
= load_reg(s
, i
);
8460 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8461 tcg_temp_free_i32(tmp
);
8464 /* no need to add after the last transfer */
8466 tcg_gen_addi_i32(addr
, addr
, 4);
8469 if (insn
& (1 << 21)) {
8471 if (insn
& (1 << 23)) {
8472 if (insn
& (1 << 24)) {
8475 /* post increment */
8476 tcg_gen_addi_i32(addr
, addr
, 4);
8479 if (insn
& (1 << 24)) {
8482 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8484 /* post decrement */
8485 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8488 store_reg(s
, rn
, addr
);
8490 tcg_temp_free_i32(addr
);
8493 store_reg(s
, rn
, loaded_var
);
8495 if ((insn
& (1 << 22)) && !user
) {
8496 /* Restore CPSR from SPSR. */
8497 tmp
= load_cpu_field(spsr
);
8498 gen_set_cpsr(tmp
, 0xffffffff);
8499 tcg_temp_free_i32(tmp
);
8500 s
->is_jmp
= DISAS_UPDATE
;
8509 /* branch (and link) */
8510 val
= (int32_t)s
->pc
;
8511 if (insn
& (1 << 24)) {
8512 tmp
= tcg_temp_new_i32();
8513 tcg_gen_movi_i32(tmp
, val
);
8514 store_reg(s
, 14, tmp
);
8516 offset
= sextract32(insn
<< 2, 0, 26);
8524 if (((insn
>> 8) & 0xe) == 10) {
8526 if (disas_vfp_insn(env
, s
, insn
)) {
8529 } else if (disas_coproc_insn(env
, s
, insn
)) {
8536 gen_set_pc_im(s
, s
->pc
);
8537 s
->is_jmp
= DISAS_SWI
;
8541 gen_exception_insn(s
, 4, EXCP_UDEF
);
8547 /* Return true if this is a Thumb-2 logical op. */
8549 thumb2_logic_op(int op
)
8554 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8555 then set condition code flags based on the result of the operation.
8556 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8557 to the high bit of T1.
8558 Returns zero if the opcode is valid. */
8561 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8562 TCGv_i32 t0
, TCGv_i32 t1
)
8569 tcg_gen_and_i32(t0
, t0
, t1
);
8573 tcg_gen_andc_i32(t0
, t0
, t1
);
8577 tcg_gen_or_i32(t0
, t0
, t1
);
8581 tcg_gen_orc_i32(t0
, t0
, t1
);
8585 tcg_gen_xor_i32(t0
, t0
, t1
);
8590 gen_add_CC(t0
, t0
, t1
);
8592 tcg_gen_add_i32(t0
, t0
, t1
);
8596 gen_adc_CC(t0
, t0
, t1
);
8602 gen_sbc_CC(t0
, t0
, t1
);
8604 gen_sub_carry(t0
, t0
, t1
);
8609 gen_sub_CC(t0
, t0
, t1
);
8611 tcg_gen_sub_i32(t0
, t0
, t1
);
8615 gen_sub_CC(t0
, t1
, t0
);
8617 tcg_gen_sub_i32(t0
, t1
, t0
);
8619 default: /* 5, 6, 7, 9, 12, 15. */
8625 gen_set_CF_bit31(t1
);
8630 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8632 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8634 uint32_t insn
, imm
, shift
, offset
;
8635 uint32_t rd
, rn
, rm
, rs
;
8646 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8647 || arm_feature (env
, ARM_FEATURE_M
))) {
8648 /* Thumb-1 cores may need to treat bl and blx as a pair of
8649 16-bit instructions to get correct prefetch abort behavior. */
8651 if ((insn
& (1 << 12)) == 0) {
8653 /* Second half of blx. */
8654 offset
= ((insn
& 0x7ff) << 1);
8655 tmp
= load_reg(s
, 14);
8656 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8657 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8659 tmp2
= tcg_temp_new_i32();
8660 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8661 store_reg(s
, 14, tmp2
);
8665 if (insn
& (1 << 11)) {
8666 /* Second half of bl. */
8667 offset
= ((insn
& 0x7ff) << 1) | 1;
8668 tmp
= load_reg(s
, 14);
8669 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8671 tmp2
= tcg_temp_new_i32();
8672 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8673 store_reg(s
, 14, tmp2
);
8677 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
8678 /* Instruction spans a page boundary. Implement it as two
8679 16-bit instructions in case the second half causes an
8681 offset
= ((int32_t)insn
<< 21) >> 9;
8682 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8685 /* Fall through to 32-bit decode. */
8688 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8690 insn
|= (uint32_t)insn_hw1
<< 16;
8692 if ((insn
& 0xf800e800) != 0xf000e800) {
8696 rn
= (insn
>> 16) & 0xf;
8697 rs
= (insn
>> 12) & 0xf;
8698 rd
= (insn
>> 8) & 0xf;
8700 switch ((insn
>> 25) & 0xf) {
8701 case 0: case 1: case 2: case 3:
8702 /* 16-bit instructions. Should never happen. */
8705 if (insn
& (1 << 22)) {
8706 /* Other load/store, table branch. */
8707 if (insn
& 0x01200000) {
8708 /* Load/store doubleword. */
8710 addr
= tcg_temp_new_i32();
8711 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8713 addr
= load_reg(s
, rn
);
8715 offset
= (insn
& 0xff) * 4;
8716 if ((insn
& (1 << 23)) == 0)
8718 if (insn
& (1 << 24)) {
8719 tcg_gen_addi_i32(addr
, addr
, offset
);
8722 if (insn
& (1 << 20)) {
8724 tmp
= tcg_temp_new_i32();
8725 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8726 store_reg(s
, rs
, tmp
);
8727 tcg_gen_addi_i32(addr
, addr
, 4);
8728 tmp
= tcg_temp_new_i32();
8729 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8730 store_reg(s
, rd
, tmp
);
8733 tmp
= load_reg(s
, rs
);
8734 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8735 tcg_temp_free_i32(tmp
);
8736 tcg_gen_addi_i32(addr
, addr
, 4);
8737 tmp
= load_reg(s
, rd
);
8738 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8739 tcg_temp_free_i32(tmp
);
8741 if (insn
& (1 << 21)) {
8742 /* Base writeback. */
8745 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8746 store_reg(s
, rn
, addr
);
8748 tcg_temp_free_i32(addr
);
8750 } else if ((insn
& (1 << 23)) == 0) {
8751 /* Load/store exclusive word. */
8752 addr
= tcg_temp_local_new_i32();
8753 load_reg_var(s
, addr
, rn
);
8754 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8755 if (insn
& (1 << 20)) {
8756 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8758 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8760 tcg_temp_free_i32(addr
);
8761 } else if ((insn
& (7 << 5)) == 0) {
8764 addr
= tcg_temp_new_i32();
8765 tcg_gen_movi_i32(addr
, s
->pc
);
8767 addr
= load_reg(s
, rn
);
8769 tmp
= load_reg(s
, rm
);
8770 tcg_gen_add_i32(addr
, addr
, tmp
);
8771 if (insn
& (1 << 4)) {
8773 tcg_gen_add_i32(addr
, addr
, tmp
);
8774 tcg_temp_free_i32(tmp
);
8775 tmp
= tcg_temp_new_i32();
8776 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8778 tcg_temp_free_i32(tmp
);
8779 tmp
= tcg_temp_new_i32();
8780 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8782 tcg_temp_free_i32(addr
);
8783 tcg_gen_shli_i32(tmp
, tmp
, 1);
8784 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8785 store_reg(s
, 15, tmp
);
8787 int op2
= (insn
>> 6) & 0x3;
8788 op
= (insn
>> 4) & 0x3;
8793 /* Load/store exclusive byte/halfword/doubleword */
8800 /* Load-acquire/store-release */
8806 /* Load-acquire/store-release exclusive */
8810 addr
= tcg_temp_local_new_i32();
8811 load_reg_var(s
, addr
, rn
);
8813 if (insn
& (1 << 20)) {
8814 tmp
= tcg_temp_new_i32();
8817 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8820 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8823 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8828 store_reg(s
, rs
, tmp
);
8830 tmp
= load_reg(s
, rs
);
8833 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
8836 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
8839 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8844 tcg_temp_free_i32(tmp
);
8846 } else if (insn
& (1 << 20)) {
8847 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8849 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8851 tcg_temp_free_i32(addr
);
8854 /* Load/store multiple, RFE, SRS. */
8855 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8856 /* RFE, SRS: not available in user mode or on M profile */
8857 if (IS_USER(s
) || IS_M(env
)) {
8860 if (insn
& (1 << 20)) {
8862 addr
= load_reg(s
, rn
);
8863 if ((insn
& (1 << 24)) == 0)
8864 tcg_gen_addi_i32(addr
, addr
, -8);
8865 /* Load PC into tmp and CPSR into tmp2. */
8866 tmp
= tcg_temp_new_i32();
8867 gen_aa32_ld32u(tmp
, addr
, 0);
8868 tcg_gen_addi_i32(addr
, addr
, 4);
8869 tmp2
= tcg_temp_new_i32();
8870 gen_aa32_ld32u(tmp2
, addr
, 0);
8871 if (insn
& (1 << 21)) {
8872 /* Base writeback. */
8873 if (insn
& (1 << 24)) {
8874 tcg_gen_addi_i32(addr
, addr
, 4);
8876 tcg_gen_addi_i32(addr
, addr
, -4);
8878 store_reg(s
, rn
, addr
);
8880 tcg_temp_free_i32(addr
);
8882 gen_rfe(s
, tmp
, tmp2
);
8885 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
8889 int i
, loaded_base
= 0;
8890 TCGv_i32 loaded_var
;
8891 /* Load/store multiple. */
8892 addr
= load_reg(s
, rn
);
8894 for (i
= 0; i
< 16; i
++) {
8895 if (insn
& (1 << i
))
8898 if (insn
& (1 << 24)) {
8899 tcg_gen_addi_i32(addr
, addr
, -offset
);
8902 TCGV_UNUSED_I32(loaded_var
);
8903 for (i
= 0; i
< 16; i
++) {
8904 if ((insn
& (1 << i
)) == 0)
8906 if (insn
& (1 << 20)) {
8908 tmp
= tcg_temp_new_i32();
8909 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8912 } else if (i
== rn
) {
8916 store_reg(s
, i
, tmp
);
8920 tmp
= load_reg(s
, i
);
8921 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8922 tcg_temp_free_i32(tmp
);
8924 tcg_gen_addi_i32(addr
, addr
, 4);
8927 store_reg(s
, rn
, loaded_var
);
8929 if (insn
& (1 << 21)) {
8930 /* Base register writeback. */
8931 if (insn
& (1 << 24)) {
8932 tcg_gen_addi_i32(addr
, addr
, -offset
);
8934 /* Fault if writeback register is in register list. */
8935 if (insn
& (1 << rn
))
8937 store_reg(s
, rn
, addr
);
8939 tcg_temp_free_i32(addr
);
8946 op
= (insn
>> 21) & 0xf;
8948 /* Halfword pack. */
8949 tmp
= load_reg(s
, rn
);
8950 tmp2
= load_reg(s
, rm
);
8951 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
8952 if (insn
& (1 << 5)) {
8956 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8957 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8958 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8962 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8963 tcg_gen_ext16u_i32(tmp
, tmp
);
8964 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8966 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8967 tcg_temp_free_i32(tmp2
);
8968 store_reg(s
, rd
, tmp
);
8970 /* Data processing register constant shift. */
8972 tmp
= tcg_temp_new_i32();
8973 tcg_gen_movi_i32(tmp
, 0);
8975 tmp
= load_reg(s
, rn
);
8977 tmp2
= load_reg(s
, rm
);
8979 shiftop
= (insn
>> 4) & 3;
8980 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
8981 conds
= (insn
& (1 << 20)) != 0;
8982 logic_cc
= (conds
&& thumb2_logic_op(op
));
8983 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8984 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
8986 tcg_temp_free_i32(tmp2
);
8988 store_reg(s
, rd
, tmp
);
8990 tcg_temp_free_i32(tmp
);
8994 case 13: /* Misc data processing. */
8995 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
8996 if (op
< 4 && (insn
& 0xf000) != 0xf000)
8999 case 0: /* Register controlled shift. */
9000 tmp
= load_reg(s
, rn
);
9001 tmp2
= load_reg(s
, rm
);
9002 if ((insn
& 0x70) != 0)
9004 op
= (insn
>> 21) & 3;
9005 logic_cc
= (insn
& (1 << 20)) != 0;
9006 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9009 store_reg_bx(env
, s
, rd
, tmp
);
9011 case 1: /* Sign/zero extend. */
9012 tmp
= load_reg(s
, rm
);
9013 shift
= (insn
>> 4) & 3;
9014 /* ??? In many cases it's not necessary to do a
9015 rotate, a shift is sufficient. */
9017 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9018 op
= (insn
>> 20) & 7;
9020 case 0: gen_sxth(tmp
); break;
9021 case 1: gen_uxth(tmp
); break;
9022 case 2: gen_sxtb16(tmp
); break;
9023 case 3: gen_uxtb16(tmp
); break;
9024 case 4: gen_sxtb(tmp
); break;
9025 case 5: gen_uxtb(tmp
); break;
9026 default: goto illegal_op
;
9029 tmp2
= load_reg(s
, rn
);
9030 if ((op
>> 1) == 1) {
9031 gen_add16(tmp
, tmp2
);
9033 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9034 tcg_temp_free_i32(tmp2
);
9037 store_reg(s
, rd
, tmp
);
9039 case 2: /* SIMD add/subtract. */
9040 op
= (insn
>> 20) & 7;
9041 shift
= (insn
>> 4) & 7;
9042 if ((op
& 3) == 3 || (shift
& 3) == 3)
9044 tmp
= load_reg(s
, rn
);
9045 tmp2
= load_reg(s
, rm
);
9046 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9047 tcg_temp_free_i32(tmp2
);
9048 store_reg(s
, rd
, tmp
);
9050 case 3: /* Other data processing. */
9051 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9053 /* Saturating add/subtract. */
9054 tmp
= load_reg(s
, rn
);
9055 tmp2
= load_reg(s
, rm
);
9057 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9059 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9061 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9062 tcg_temp_free_i32(tmp2
);
9064 tmp
= load_reg(s
, rn
);
9066 case 0x0a: /* rbit */
9067 gen_helper_rbit(tmp
, tmp
);
9069 case 0x08: /* rev */
9070 tcg_gen_bswap32_i32(tmp
, tmp
);
9072 case 0x09: /* rev16 */
9075 case 0x0b: /* revsh */
9078 case 0x10: /* sel */
9079 tmp2
= load_reg(s
, rm
);
9080 tmp3
= tcg_temp_new_i32();
9081 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9082 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9083 tcg_temp_free_i32(tmp3
);
9084 tcg_temp_free_i32(tmp2
);
9086 case 0x18: /* clz */
9087 gen_helper_clz(tmp
, tmp
);
9093 store_reg(s
, rd
, tmp
);
9095 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9096 op
= (insn
>> 4) & 0xf;
9097 tmp
= load_reg(s
, rn
);
9098 tmp2
= load_reg(s
, rm
);
9099 switch ((insn
>> 20) & 7) {
9100 case 0: /* 32 x 32 -> 32 */
9101 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9102 tcg_temp_free_i32(tmp2
);
9104 tmp2
= load_reg(s
, rs
);
9106 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9108 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9109 tcg_temp_free_i32(tmp2
);
9112 case 1: /* 16 x 16 -> 32 */
9113 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9114 tcg_temp_free_i32(tmp2
);
9116 tmp2
= load_reg(s
, rs
);
9117 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9118 tcg_temp_free_i32(tmp2
);
9121 case 2: /* Dual multiply add. */
9122 case 4: /* Dual multiply subtract. */
9124 gen_swap_half(tmp2
);
9125 gen_smul_dual(tmp
, tmp2
);
9126 if (insn
& (1 << 22)) {
9127 /* This subtraction cannot overflow. */
9128 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9130 /* This addition cannot overflow 32 bits;
9131 * however it may overflow considered as a signed
9132 * operation, in which case we must set the Q flag.
9134 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9136 tcg_temp_free_i32(tmp2
);
9139 tmp2
= load_reg(s
, rs
);
9140 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9141 tcg_temp_free_i32(tmp2
);
9144 case 3: /* 32 * 16 -> 32msb */
9146 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9149 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9150 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9151 tmp
= tcg_temp_new_i32();
9152 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9153 tcg_temp_free_i64(tmp64
);
9156 tmp2
= load_reg(s
, rs
);
9157 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9158 tcg_temp_free_i32(tmp2
);
9161 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9162 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9164 tmp
= load_reg(s
, rs
);
9165 if (insn
& (1 << 20)) {
9166 tmp64
= gen_addq_msw(tmp64
, tmp
);
9168 tmp64
= gen_subq_msw(tmp64
, tmp
);
9171 if (insn
& (1 << 4)) {
9172 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9174 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9175 tmp
= tcg_temp_new_i32();
9176 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9177 tcg_temp_free_i64(tmp64
);
9179 case 7: /* Unsigned sum of absolute differences. */
9180 gen_helper_usad8(tmp
, tmp
, tmp2
);
9181 tcg_temp_free_i32(tmp2
);
9183 tmp2
= load_reg(s
, rs
);
9184 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9185 tcg_temp_free_i32(tmp2
);
9189 store_reg(s
, rd
, tmp
);
9191 case 6: case 7: /* 64-bit multiply, Divide. */
9192 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9193 tmp
= load_reg(s
, rn
);
9194 tmp2
= load_reg(s
, rm
);
9195 if ((op
& 0x50) == 0x10) {
9197 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
9201 gen_helper_udiv(tmp
, tmp
, tmp2
);
9203 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9204 tcg_temp_free_i32(tmp2
);
9205 store_reg(s
, rd
, tmp
);
9206 } else if ((op
& 0xe) == 0xc) {
9207 /* Dual multiply accumulate long. */
9209 gen_swap_half(tmp2
);
9210 gen_smul_dual(tmp
, tmp2
);
9212 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9214 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9216 tcg_temp_free_i32(tmp2
);
9218 tmp64
= tcg_temp_new_i64();
9219 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9220 tcg_temp_free_i32(tmp
);
9221 gen_addq(s
, tmp64
, rs
, rd
);
9222 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9223 tcg_temp_free_i64(tmp64
);
9226 /* Unsigned 64-bit multiply */
9227 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9231 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9232 tcg_temp_free_i32(tmp2
);
9233 tmp64
= tcg_temp_new_i64();
9234 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9235 tcg_temp_free_i32(tmp
);
9237 /* Signed 64-bit multiply */
9238 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9243 gen_addq_lo(s
, tmp64
, rs
);
9244 gen_addq_lo(s
, tmp64
, rd
);
9245 } else if (op
& 0x40) {
9246 /* 64-bit accumulate. */
9247 gen_addq(s
, tmp64
, rs
, rd
);
9249 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9250 tcg_temp_free_i64(tmp64
);
9255 case 6: case 7: case 14: case 15:
9257 if (((insn
>> 24) & 3) == 3) {
9258 /* Translate into the equivalent ARM encoding. */
9259 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9260 if (disas_neon_data_insn(env
, s
, insn
))
9262 } else if (((insn
>> 8) & 0xe) == 10) {
9263 if (disas_vfp_insn(env
, s
, insn
)) {
9267 if (insn
& (1 << 28))
9269 if (disas_coproc_insn (env
, s
, insn
))
9273 case 8: case 9: case 10: case 11:
9274 if (insn
& (1 << 15)) {
9275 /* Branches, misc control. */
9276 if (insn
& 0x5000) {
9277 /* Unconditional branch. */
9278 /* signextend(hw1[10:0]) -> offset[:12]. */
9279 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9280 /* hw1[10:0] -> offset[11:1]. */
9281 offset
|= (insn
& 0x7ff) << 1;
9282 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9283 offset[24:22] already have the same value because of the
9284 sign extension above. */
9285 offset
^= ((~insn
) & (1 << 13)) << 10;
9286 offset
^= ((~insn
) & (1 << 11)) << 11;
9288 if (insn
& (1 << 14)) {
9289 /* Branch and link. */
9290 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9294 if (insn
& (1 << 12)) {
9299 offset
&= ~(uint32_t)2;
9300 /* thumb2 bx, no need to check */
9301 gen_bx_im(s
, offset
);
9303 } else if (((insn
>> 23) & 7) == 7) {
9305 if (insn
& (1 << 13))
9308 if (insn
& (1 << 26)) {
9309 /* Secure monitor call (v6Z) */
9310 qemu_log_mask(LOG_UNIMP
,
9311 "arm: unimplemented secure monitor call\n");
9312 goto illegal_op
; /* not implemented. */
9314 op
= (insn
>> 20) & 7;
9316 case 0: /* msr cpsr. */
9318 tmp
= load_reg(s
, rn
);
9319 addr
= tcg_const_i32(insn
& 0xff);
9320 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9321 tcg_temp_free_i32(addr
);
9322 tcg_temp_free_i32(tmp
);
9327 case 1: /* msr spsr. */
9330 tmp
= load_reg(s
, rn
);
9332 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9336 case 2: /* cps, nop-hint. */
9337 if (((insn
>> 8) & 7) == 0) {
9338 gen_nop_hint(s
, insn
& 0xff);
9340 /* Implemented as NOP in user mode. */
9345 if (insn
& (1 << 10)) {
9346 if (insn
& (1 << 7))
9348 if (insn
& (1 << 6))
9350 if (insn
& (1 << 5))
9352 if (insn
& (1 << 9))
9353 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9355 if (insn
& (1 << 8)) {
9357 imm
|= (insn
& 0x1f);
9360 gen_set_psr_im(s
, offset
, 0, imm
);
9363 case 3: /* Special control operations. */
9365 op
= (insn
>> 4) & 0xf;
9373 /* These execute as NOPs. */
9380 /* Trivial implementation equivalent to bx. */
9381 tmp
= load_reg(s
, rn
);
9384 case 5: /* Exception return. */
9388 if (rn
!= 14 || rd
!= 15) {
9391 tmp
= load_reg(s
, rn
);
9392 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9393 gen_exception_return(s
, tmp
);
9395 case 6: /* mrs cpsr. */
9396 tmp
= tcg_temp_new_i32();
9398 addr
= tcg_const_i32(insn
& 0xff);
9399 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9400 tcg_temp_free_i32(addr
);
9402 gen_helper_cpsr_read(tmp
, cpu_env
);
9404 store_reg(s
, rd
, tmp
);
9406 case 7: /* mrs spsr. */
9407 /* Not accessible in user mode. */
9408 if (IS_USER(s
) || IS_M(env
))
9410 tmp
= load_cpu_field(spsr
);
9411 store_reg(s
, rd
, tmp
);
9416 /* Conditional branch. */
9417 op
= (insn
>> 22) & 0xf;
9418 /* Generate a conditional jump to next instruction. */
9419 s
->condlabel
= gen_new_label();
9420 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9423 /* offset[11:1] = insn[10:0] */
9424 offset
= (insn
& 0x7ff) << 1;
9425 /* offset[17:12] = insn[21:16]. */
9426 offset
|= (insn
& 0x003f0000) >> 4;
9427 /* offset[31:20] = insn[26]. */
9428 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9429 /* offset[18] = insn[13]. */
9430 offset
|= (insn
& (1 << 13)) << 5;
9431 /* offset[19] = insn[11]. */
9432 offset
|= (insn
& (1 << 11)) << 8;
9434 /* jump to the offset */
9435 gen_jmp(s
, s
->pc
+ offset
);
9438 /* Data processing immediate. */
9439 if (insn
& (1 << 25)) {
9440 if (insn
& (1 << 24)) {
9441 if (insn
& (1 << 20))
9443 /* Bitfield/Saturate. */
9444 op
= (insn
>> 21) & 7;
9446 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9448 tmp
= tcg_temp_new_i32();
9449 tcg_gen_movi_i32(tmp
, 0);
9451 tmp
= load_reg(s
, rn
);
9454 case 2: /* Signed bitfield extract. */
9456 if (shift
+ imm
> 32)
9459 gen_sbfx(tmp
, shift
, imm
);
9461 case 6: /* Unsigned bitfield extract. */
9463 if (shift
+ imm
> 32)
9466 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9468 case 3: /* Bitfield insert/clear. */
9471 imm
= imm
+ 1 - shift
;
9473 tmp2
= load_reg(s
, rd
);
9474 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9475 tcg_temp_free_i32(tmp2
);
9480 default: /* Saturate. */
9483 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9485 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9487 tmp2
= tcg_const_i32(imm
);
9490 if ((op
& 1) && shift
== 0)
9491 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9493 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9496 if ((op
& 1) && shift
== 0)
9497 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9499 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9501 tcg_temp_free_i32(tmp2
);
9504 store_reg(s
, rd
, tmp
);
9506 imm
= ((insn
& 0x04000000) >> 15)
9507 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9508 if (insn
& (1 << 22)) {
9509 /* 16-bit immediate. */
9510 imm
|= (insn
>> 4) & 0xf000;
9511 if (insn
& (1 << 23)) {
9513 tmp
= load_reg(s
, rd
);
9514 tcg_gen_ext16u_i32(tmp
, tmp
);
9515 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9518 tmp
= tcg_temp_new_i32();
9519 tcg_gen_movi_i32(tmp
, imm
);
9522 /* Add/sub 12-bit immediate. */
9524 offset
= s
->pc
& ~(uint32_t)3;
9525 if (insn
& (1 << 23))
9529 tmp
= tcg_temp_new_i32();
9530 tcg_gen_movi_i32(tmp
, offset
);
9532 tmp
= load_reg(s
, rn
);
9533 if (insn
& (1 << 23))
9534 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9536 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9539 store_reg(s
, rd
, tmp
);
9542 int shifter_out
= 0;
9543 /* modified 12-bit immediate. */
9544 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9545 imm
= (insn
& 0xff);
9548 /* Nothing to do. */
9550 case 1: /* 00XY00XY */
9553 case 2: /* XY00XY00 */
9557 case 3: /* XYXYXYXY */
9561 default: /* Rotated constant. */
9562 shift
= (shift
<< 1) | (imm
>> 7);
9564 imm
= imm
<< (32 - shift
);
9568 tmp2
= tcg_temp_new_i32();
9569 tcg_gen_movi_i32(tmp2
, imm
);
9570 rn
= (insn
>> 16) & 0xf;
9572 tmp
= tcg_temp_new_i32();
9573 tcg_gen_movi_i32(tmp
, 0);
9575 tmp
= load_reg(s
, rn
);
9577 op
= (insn
>> 21) & 0xf;
9578 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9579 shifter_out
, tmp
, tmp2
))
9581 tcg_temp_free_i32(tmp2
);
9582 rd
= (insn
>> 8) & 0xf;
9584 store_reg(s
, rd
, tmp
);
9586 tcg_temp_free_i32(tmp
);
9591 case 12: /* Load/store single data item. */
9596 if ((insn
& 0x01100000) == 0x01000000) {
9597 if (disas_neon_ls_insn(env
, s
, insn
))
9601 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
9603 if (!(insn
& (1 << 20))) {
9607 /* Byte or halfword load space with dest == r15 : memory hints.
9608 * Catch them early so we don't emit pointless addressing code.
9609 * This space is a mix of:
9610 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9611 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9613 * unallocated hints, which must be treated as NOPs
9614 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9615 * which is easiest for the decoding logic
9616 * Some space which must UNDEF
9618 int op1
= (insn
>> 23) & 3;
9619 int op2
= (insn
>> 6) & 0x3f;
9624 /* UNPREDICTABLE, unallocated hint or
9625 * PLD/PLDW/PLI (literal)
9630 return 0; /* PLD/PLDW/PLI or unallocated hint */
9632 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
9633 return 0; /* PLD/PLDW/PLI or unallocated hint */
9635 /* UNDEF space, or an UNPREDICTABLE */
9641 addr
= tcg_temp_new_i32();
9643 /* s->pc has already been incremented by 4. */
9644 imm
= s
->pc
& 0xfffffffc;
9645 if (insn
& (1 << 23))
9646 imm
+= insn
& 0xfff;
9648 imm
-= insn
& 0xfff;
9649 tcg_gen_movi_i32(addr
, imm
);
9651 addr
= load_reg(s
, rn
);
9652 if (insn
& (1 << 23)) {
9653 /* Positive offset. */
9655 tcg_gen_addi_i32(addr
, addr
, imm
);
9658 switch ((insn
>> 8) & 0xf) {
9659 case 0x0: /* Shifted Register. */
9660 shift
= (insn
>> 4) & 0xf;
9662 tcg_temp_free_i32(addr
);
9665 tmp
= load_reg(s
, rm
);
9667 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9668 tcg_gen_add_i32(addr
, addr
, tmp
);
9669 tcg_temp_free_i32(tmp
);
9671 case 0xc: /* Negative offset. */
9672 tcg_gen_addi_i32(addr
, addr
, -imm
);
9674 case 0xe: /* User privilege. */
9675 tcg_gen_addi_i32(addr
, addr
, imm
);
9678 case 0x9: /* Post-decrement. */
9681 case 0xb: /* Post-increment. */
9685 case 0xd: /* Pre-decrement. */
9688 case 0xf: /* Pre-increment. */
9689 tcg_gen_addi_i32(addr
, addr
, imm
);
9693 tcg_temp_free_i32(addr
);
9698 if (insn
& (1 << 20)) {
9700 tmp
= tcg_temp_new_i32();
9703 gen_aa32_ld8u(tmp
, addr
, user
);
9706 gen_aa32_ld8s(tmp
, addr
, user
);
9709 gen_aa32_ld16u(tmp
, addr
, user
);
9712 gen_aa32_ld16s(tmp
, addr
, user
);
9715 gen_aa32_ld32u(tmp
, addr
, user
);
9718 tcg_temp_free_i32(tmp
);
9719 tcg_temp_free_i32(addr
);
9725 store_reg(s
, rs
, tmp
);
9729 tmp
= load_reg(s
, rs
);
9732 gen_aa32_st8(tmp
, addr
, user
);
9735 gen_aa32_st16(tmp
, addr
, user
);
9738 gen_aa32_st32(tmp
, addr
, user
);
9741 tcg_temp_free_i32(tmp
);
9742 tcg_temp_free_i32(addr
);
9745 tcg_temp_free_i32(tmp
);
9748 tcg_gen_addi_i32(addr
, addr
, imm
);
9750 store_reg(s
, rn
, addr
);
9752 tcg_temp_free_i32(addr
);
9764 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9766 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9773 if (s
->condexec_mask
) {
9774 cond
= s
->condexec_cond
;
9775 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9776 s
->condlabel
= gen_new_label();
9777 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
9782 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9785 switch (insn
>> 12) {
9789 op
= (insn
>> 11) & 3;
9792 rn
= (insn
>> 3) & 7;
9793 tmp
= load_reg(s
, rn
);
9794 if (insn
& (1 << 10)) {
9796 tmp2
= tcg_temp_new_i32();
9797 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9800 rm
= (insn
>> 6) & 7;
9801 tmp2
= load_reg(s
, rm
);
9803 if (insn
& (1 << 9)) {
9804 if (s
->condexec_mask
)
9805 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9807 gen_sub_CC(tmp
, tmp
, tmp2
);
9809 if (s
->condexec_mask
)
9810 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9812 gen_add_CC(tmp
, tmp
, tmp2
);
9814 tcg_temp_free_i32(tmp2
);
9815 store_reg(s
, rd
, tmp
);
9817 /* shift immediate */
9818 rm
= (insn
>> 3) & 7;
9819 shift
= (insn
>> 6) & 0x1f;
9820 tmp
= load_reg(s
, rm
);
9821 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9822 if (!s
->condexec_mask
)
9824 store_reg(s
, rd
, tmp
);
9828 /* arithmetic large immediate */
9829 op
= (insn
>> 11) & 3;
9830 rd
= (insn
>> 8) & 0x7;
9831 if (op
== 0) { /* mov */
9832 tmp
= tcg_temp_new_i32();
9833 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9834 if (!s
->condexec_mask
)
9836 store_reg(s
, rd
, tmp
);
9838 tmp
= load_reg(s
, rd
);
9839 tmp2
= tcg_temp_new_i32();
9840 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9843 gen_sub_CC(tmp
, tmp
, tmp2
);
9844 tcg_temp_free_i32(tmp
);
9845 tcg_temp_free_i32(tmp2
);
9848 if (s
->condexec_mask
)
9849 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9851 gen_add_CC(tmp
, tmp
, tmp2
);
9852 tcg_temp_free_i32(tmp2
);
9853 store_reg(s
, rd
, tmp
);
9856 if (s
->condexec_mask
)
9857 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9859 gen_sub_CC(tmp
, tmp
, tmp2
);
9860 tcg_temp_free_i32(tmp2
);
9861 store_reg(s
, rd
, tmp
);
9867 if (insn
& (1 << 11)) {
9868 rd
= (insn
>> 8) & 7;
9869 /* load pc-relative. Bit 1 of PC is ignored. */
9870 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9871 val
&= ~(uint32_t)2;
9872 addr
= tcg_temp_new_i32();
9873 tcg_gen_movi_i32(addr
, val
);
9874 tmp
= tcg_temp_new_i32();
9875 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9876 tcg_temp_free_i32(addr
);
9877 store_reg(s
, rd
, tmp
);
9880 if (insn
& (1 << 10)) {
9881 /* data processing extended or blx */
9882 rd
= (insn
& 7) | ((insn
>> 4) & 8);
9883 rm
= (insn
>> 3) & 0xf;
9884 op
= (insn
>> 8) & 3;
9887 tmp
= load_reg(s
, rd
);
9888 tmp2
= load_reg(s
, rm
);
9889 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9890 tcg_temp_free_i32(tmp2
);
9891 store_reg(s
, rd
, tmp
);
9894 tmp
= load_reg(s
, rd
);
9895 tmp2
= load_reg(s
, rm
);
9896 gen_sub_CC(tmp
, tmp
, tmp2
);
9897 tcg_temp_free_i32(tmp2
);
9898 tcg_temp_free_i32(tmp
);
9900 case 2: /* mov/cpy */
9901 tmp
= load_reg(s
, rm
);
9902 store_reg(s
, rd
, tmp
);
9904 case 3:/* branch [and link] exchange thumb register */
9905 tmp
= load_reg(s
, rm
);
9906 if (insn
& (1 << 7)) {
9908 val
= (uint32_t)s
->pc
| 1;
9909 tmp2
= tcg_temp_new_i32();
9910 tcg_gen_movi_i32(tmp2
, val
);
9911 store_reg(s
, 14, tmp2
);
9913 /* already thumb, no need to check */
9920 /* data processing register */
9922 rm
= (insn
>> 3) & 7;
9923 op
= (insn
>> 6) & 0xf;
9924 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
9925 /* the shift/rotate ops want the operands backwards */
9934 if (op
== 9) { /* neg */
9935 tmp
= tcg_temp_new_i32();
9936 tcg_gen_movi_i32(tmp
, 0);
9937 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
9938 tmp
= load_reg(s
, rd
);
9940 TCGV_UNUSED_I32(tmp
);
9943 tmp2
= load_reg(s
, rm
);
9946 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
9947 if (!s
->condexec_mask
)
9951 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
9952 if (!s
->condexec_mask
)
9956 if (s
->condexec_mask
) {
9957 gen_shl(tmp2
, tmp2
, tmp
);
9959 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9964 if (s
->condexec_mask
) {
9965 gen_shr(tmp2
, tmp2
, tmp
);
9967 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9972 if (s
->condexec_mask
) {
9973 gen_sar(tmp2
, tmp2
, tmp
);
9975 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
9980 if (s
->condexec_mask
) {
9983 gen_adc_CC(tmp
, tmp
, tmp2
);
9987 if (s
->condexec_mask
) {
9988 gen_sub_carry(tmp
, tmp
, tmp2
);
9990 gen_sbc_CC(tmp
, tmp
, tmp2
);
9994 if (s
->condexec_mask
) {
9995 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
9996 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
9998 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10002 case 0x8: /* tst */
10003 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10007 case 0x9: /* neg */
10008 if (s
->condexec_mask
)
10009 tcg_gen_neg_i32(tmp
, tmp2
);
10011 gen_sub_CC(tmp
, tmp
, tmp2
);
10013 case 0xa: /* cmp */
10014 gen_sub_CC(tmp
, tmp
, tmp2
);
10017 case 0xb: /* cmn */
10018 gen_add_CC(tmp
, tmp
, tmp2
);
10021 case 0xc: /* orr */
10022 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10023 if (!s
->condexec_mask
)
10026 case 0xd: /* mul */
10027 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10028 if (!s
->condexec_mask
)
10031 case 0xe: /* bic */
10032 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10033 if (!s
->condexec_mask
)
10036 case 0xf: /* mvn */
10037 tcg_gen_not_i32(tmp2
, tmp2
);
10038 if (!s
->condexec_mask
)
10039 gen_logic_CC(tmp2
);
10046 store_reg(s
, rm
, tmp2
);
10048 tcg_temp_free_i32(tmp
);
10050 store_reg(s
, rd
, tmp
);
10051 tcg_temp_free_i32(tmp2
);
10054 tcg_temp_free_i32(tmp
);
10055 tcg_temp_free_i32(tmp2
);
10060 /* load/store register offset. */
10062 rn
= (insn
>> 3) & 7;
10063 rm
= (insn
>> 6) & 7;
10064 op
= (insn
>> 9) & 7;
10065 addr
= load_reg(s
, rn
);
10066 tmp
= load_reg(s
, rm
);
10067 tcg_gen_add_i32(addr
, addr
, tmp
);
10068 tcg_temp_free_i32(tmp
);
10070 if (op
< 3) { /* store */
10071 tmp
= load_reg(s
, rd
);
10073 tmp
= tcg_temp_new_i32();
10078 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10081 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
10084 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
10086 case 3: /* ldrsb */
10087 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
10090 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10093 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
10096 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
10098 case 7: /* ldrsh */
10099 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
10102 if (op
>= 3) { /* load */
10103 store_reg(s
, rd
, tmp
);
10105 tcg_temp_free_i32(tmp
);
10107 tcg_temp_free_i32(addr
);
10111 /* load/store word immediate offset */
10113 rn
= (insn
>> 3) & 7;
10114 addr
= load_reg(s
, rn
);
10115 val
= (insn
>> 4) & 0x7c;
10116 tcg_gen_addi_i32(addr
, addr
, val
);
10118 if (insn
& (1 << 11)) {
10120 tmp
= tcg_temp_new_i32();
10121 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10122 store_reg(s
, rd
, tmp
);
10125 tmp
= load_reg(s
, rd
);
10126 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10127 tcg_temp_free_i32(tmp
);
10129 tcg_temp_free_i32(addr
);
10133 /* load/store byte immediate offset */
10135 rn
= (insn
>> 3) & 7;
10136 addr
= load_reg(s
, rn
);
10137 val
= (insn
>> 6) & 0x1f;
10138 tcg_gen_addi_i32(addr
, addr
, val
);
10140 if (insn
& (1 << 11)) {
10142 tmp
= tcg_temp_new_i32();
10143 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
10144 store_reg(s
, rd
, tmp
);
10147 tmp
= load_reg(s
, rd
);
10148 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
10149 tcg_temp_free_i32(tmp
);
10151 tcg_temp_free_i32(addr
);
10155 /* load/store halfword immediate offset */
10157 rn
= (insn
>> 3) & 7;
10158 addr
= load_reg(s
, rn
);
10159 val
= (insn
>> 5) & 0x3e;
10160 tcg_gen_addi_i32(addr
, addr
, val
);
10162 if (insn
& (1 << 11)) {
10164 tmp
= tcg_temp_new_i32();
10165 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
10166 store_reg(s
, rd
, tmp
);
10169 tmp
= load_reg(s
, rd
);
10170 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
10171 tcg_temp_free_i32(tmp
);
10173 tcg_temp_free_i32(addr
);
10177 /* load/store from stack */
10178 rd
= (insn
>> 8) & 7;
10179 addr
= load_reg(s
, 13);
10180 val
= (insn
& 0xff) * 4;
10181 tcg_gen_addi_i32(addr
, addr
, val
);
10183 if (insn
& (1 << 11)) {
10185 tmp
= tcg_temp_new_i32();
10186 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10187 store_reg(s
, rd
, tmp
);
10190 tmp
= load_reg(s
, rd
);
10191 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10192 tcg_temp_free_i32(tmp
);
10194 tcg_temp_free_i32(addr
);
10198 /* add to high reg */
10199 rd
= (insn
>> 8) & 7;
10200 if (insn
& (1 << 11)) {
10202 tmp
= load_reg(s
, 13);
10204 /* PC. bit 1 is ignored. */
10205 tmp
= tcg_temp_new_i32();
10206 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10208 val
= (insn
& 0xff) * 4;
10209 tcg_gen_addi_i32(tmp
, tmp
, val
);
10210 store_reg(s
, rd
, tmp
);
10215 op
= (insn
>> 8) & 0xf;
10218 /* adjust stack pointer */
10219 tmp
= load_reg(s
, 13);
10220 val
= (insn
& 0x7f) * 4;
10221 if (insn
& (1 << 7))
10222 val
= -(int32_t)val
;
10223 tcg_gen_addi_i32(tmp
, tmp
, val
);
10224 store_reg(s
, 13, tmp
);
10227 case 2: /* sign/zero extend. */
10230 rm
= (insn
>> 3) & 7;
10231 tmp
= load_reg(s
, rm
);
10232 switch ((insn
>> 6) & 3) {
10233 case 0: gen_sxth(tmp
); break;
10234 case 1: gen_sxtb(tmp
); break;
10235 case 2: gen_uxth(tmp
); break;
10236 case 3: gen_uxtb(tmp
); break;
10238 store_reg(s
, rd
, tmp
);
10240 case 4: case 5: case 0xc: case 0xd:
10242 addr
= load_reg(s
, 13);
10243 if (insn
& (1 << 8))
10247 for (i
= 0; i
< 8; i
++) {
10248 if (insn
& (1 << i
))
10251 if ((insn
& (1 << 11)) == 0) {
10252 tcg_gen_addi_i32(addr
, addr
, -offset
);
10254 for (i
= 0; i
< 8; i
++) {
10255 if (insn
& (1 << i
)) {
10256 if (insn
& (1 << 11)) {
10258 tmp
= tcg_temp_new_i32();
10259 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10260 store_reg(s
, i
, tmp
);
10263 tmp
= load_reg(s
, i
);
10264 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10265 tcg_temp_free_i32(tmp
);
10267 /* advance to the next address. */
10268 tcg_gen_addi_i32(addr
, addr
, 4);
10271 TCGV_UNUSED_I32(tmp
);
10272 if (insn
& (1 << 8)) {
10273 if (insn
& (1 << 11)) {
10275 tmp
= tcg_temp_new_i32();
10276 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10277 /* don't set the pc until the rest of the instruction
10281 tmp
= load_reg(s
, 14);
10282 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10283 tcg_temp_free_i32(tmp
);
10285 tcg_gen_addi_i32(addr
, addr
, 4);
10287 if ((insn
& (1 << 11)) == 0) {
10288 tcg_gen_addi_i32(addr
, addr
, -offset
);
10290 /* write back the new stack pointer */
10291 store_reg(s
, 13, addr
);
10292 /* set the new PC value */
10293 if ((insn
& 0x0900) == 0x0900) {
10294 store_reg_from_load(env
, s
, 15, tmp
);
10298 case 1: case 3: case 9: case 11: /* czb */
10300 tmp
= load_reg(s
, rm
);
10301 s
->condlabel
= gen_new_label();
10303 if (insn
& (1 << 11))
10304 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10306 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10307 tcg_temp_free_i32(tmp
);
10308 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10309 val
= (uint32_t)s
->pc
+ 2;
10314 case 15: /* IT, nop-hint. */
10315 if ((insn
& 0xf) == 0) {
10316 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10320 s
->condexec_cond
= (insn
>> 4) & 0xe;
10321 s
->condexec_mask
= insn
& 0x1f;
10322 /* No actual code generated for this insn, just setup state. */
10325 case 0xe: /* bkpt */
10327 gen_exception_insn(s
, 2, EXCP_BKPT
);
10330 case 0xa: /* rev */
10332 rn
= (insn
>> 3) & 0x7;
10334 tmp
= load_reg(s
, rn
);
10335 switch ((insn
>> 6) & 3) {
10336 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10337 case 1: gen_rev16(tmp
); break;
10338 case 3: gen_revsh(tmp
); break;
10339 default: goto illegal_op
;
10341 store_reg(s
, rd
, tmp
);
10345 switch ((insn
>> 5) & 7) {
10349 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10350 /* Dynamic endianness switching not implemented. */
10351 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10362 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10365 addr
= tcg_const_i32(19);
10366 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10367 tcg_temp_free_i32(addr
);
10371 addr
= tcg_const_i32(16);
10372 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10373 tcg_temp_free_i32(addr
);
10375 tcg_temp_free_i32(tmp
);
10378 if (insn
& (1 << 4)) {
10379 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10383 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10398 /* load/store multiple */
10399 TCGv_i32 loaded_var
;
10400 TCGV_UNUSED_I32(loaded_var
);
10401 rn
= (insn
>> 8) & 0x7;
10402 addr
= load_reg(s
, rn
);
10403 for (i
= 0; i
< 8; i
++) {
10404 if (insn
& (1 << i
)) {
10405 if (insn
& (1 << 11)) {
10407 tmp
= tcg_temp_new_i32();
10408 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10412 store_reg(s
, i
, tmp
);
10416 tmp
= load_reg(s
, i
);
10417 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10418 tcg_temp_free_i32(tmp
);
10420 /* advance to the next address */
10421 tcg_gen_addi_i32(addr
, addr
, 4);
10424 if ((insn
& (1 << rn
)) == 0) {
10425 /* base reg not in list: base register writeback */
10426 store_reg(s
, rn
, addr
);
10428 /* base reg in list: if load, complete it now */
10429 if (insn
& (1 << 11)) {
10430 store_reg(s
, rn
, loaded_var
);
10432 tcg_temp_free_i32(addr
);
10437 /* conditional branch or swi */
10438 cond
= (insn
>> 8) & 0xf;
10444 gen_set_pc_im(s
, s
->pc
);
10445 s
->is_jmp
= DISAS_SWI
;
10448 /* generate a conditional jump to next instruction */
10449 s
->condlabel
= gen_new_label();
10450 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10453 /* jump to the offset */
10454 val
= (uint32_t)s
->pc
+ 2;
10455 offset
= ((int32_t)insn
<< 24) >> 24;
10456 val
+= offset
<< 1;
10461 if (insn
& (1 << 11)) {
10462 if (disas_thumb2_insn(env
, s
, insn
))
10466 /* unconditional branch */
10467 val
= (uint32_t)s
->pc
;
10468 offset
= ((int32_t)insn
<< 21) >> 21;
10469 val
+= (offset
<< 1) + 2;
10474 if (disas_thumb2_insn(env
, s
, insn
))
10480 gen_exception_insn(s
, 4, EXCP_UDEF
);
10484 gen_exception_insn(s
, 2, EXCP_UDEF
);
10487 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10488 basic block 'tb'. If search_pc is TRUE, also generate PC
10489 information for each intermediate instruction. */
10490 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10491 TranslationBlock
*tb
,
10494 CPUState
*cs
= CPU(cpu
);
10495 CPUARMState
*env
= &cpu
->env
;
10496 DisasContext dc1
, *dc
= &dc1
;
10498 uint16_t *gen_opc_end
;
10500 target_ulong pc_start
;
10501 target_ulong next_page_start
;
10505 /* generate intermediate code */
10507 /* The A64 decoder has its own top level loop, because it doesn't need
10508 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10510 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10511 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
10519 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10521 dc
->is_jmp
= DISAS_NEXT
;
10523 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10527 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10528 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10529 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10530 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10531 #if !defined(CONFIG_USER_ONLY)
10532 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10534 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10535 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10536 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10537 dc
->cp_regs
= cpu
->cp_regs
;
10538 dc
->current_pl
= arm_current_pl(env
);
10540 cpu_F0s
= tcg_temp_new_i32();
10541 cpu_F1s
= tcg_temp_new_i32();
10542 cpu_F0d
= tcg_temp_new_i64();
10543 cpu_F1d
= tcg_temp_new_i64();
10546 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10547 cpu_M0
= tcg_temp_new_i64();
10548 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10551 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10552 if (max_insns
== 0)
10553 max_insns
= CF_COUNT_MASK
;
10557 tcg_clear_temp_count();
10559 /* A note on handling of the condexec (IT) bits:
10561 * We want to avoid the overhead of having to write the updated condexec
10562 * bits back to the CPUARMState for every instruction in an IT block. So:
10563 * (1) if the condexec bits are not already zero then we write
10564 * zero back into the CPUARMState now. This avoids complications trying
10565 * to do it at the end of the block. (For example if we don't do this
10566 * it's hard to identify whether we can safely skip writing condexec
10567 * at the end of the TB, which we definitely want to do for the case
10568 * where a TB doesn't do anything with the IT state at all.)
10569 * (2) if we are going to leave the TB then we call gen_set_condexec()
10570 * which will write the correct value into CPUARMState if zero is wrong.
10571 * This is done both for leaving the TB at the end, and for leaving
10572 * it because of an exception we know will happen, which is done in
10573 * gen_exception_insn(). The latter is necessary because we need to
10574 * leave the TB with the PC/IT state just prior to execution of the
10575 * instruction which caused the exception.
10576 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10577 * then the CPUARMState will be wrong and we need to reset it.
10578 * This is handled in the same way as restoration of the
10579 * PC in these situations: we will be called again with search_pc=1
10580 * and generate a mapping of the condexec bits for each PC in
10581 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10582 * this to restore the condexec bits.
10584 * Note that there are no instructions which can read the condexec
10585 * bits, and none which can write non-static values to them, so
10586 * we don't need to care about whether CPUARMState is correct in the
10590 /* Reset the conditional execution bits immediately. This avoids
10591 complications trying to do it at the end of the block. */
10592 if (dc
->condexec_mask
|| dc
->condexec_cond
)
10594 TCGv_i32 tmp
= tcg_temp_new_i32();
10595 tcg_gen_movi_i32(tmp
, 0);
10596 store_cpu_field(tmp
, condexec_bits
);
10599 #ifdef CONFIG_USER_ONLY
10600 /* Intercept jump to the magic kernel page. */
10601 if (dc
->pc
>= 0xffff0000) {
10602 /* We always get here via a jump, so know we are not in a
10603 conditional execution block. */
10604 gen_exception(EXCP_KERNEL_TRAP
);
10605 dc
->is_jmp
= DISAS_UPDATE
;
10609 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
10610 /* We always get here via a jump, so know we are not in a
10611 conditional execution block. */
10612 gen_exception(EXCP_EXCEPTION_EXIT
);
10613 dc
->is_jmp
= DISAS_UPDATE
;
10618 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
10619 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
10620 if (bp
->pc
== dc
->pc
) {
10621 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
10622 /* Advance PC so that clearing the breakpoint will
10623 invalidate this TB. */
10625 goto done_generating
;
10630 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10634 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10636 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
10637 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
10638 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
10639 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
10642 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
10645 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
10646 tcg_gen_debug_insn_start(dc
->pc
);
10650 disas_thumb_insn(env
, dc
);
10651 if (dc
->condexec_mask
) {
10652 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
10653 | ((dc
->condexec_mask
>> 4) & 1);
10654 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
10655 if (dc
->condexec_mask
== 0) {
10656 dc
->condexec_cond
= 0;
10660 disas_arm_insn(env
, dc
);
10663 if (dc
->condjmp
&& !dc
->is_jmp
) {
10664 gen_set_label(dc
->condlabel
);
10668 if (tcg_check_temp_count()) {
10669 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
10673 /* Translation stops when a conditional branch is encountered.
10674 * Otherwise the subsequent code could get translated several times.
10675 * Also stop translation when a page boundary is reached. This
10676 * ensures prefetch aborts occur at the right place. */
10678 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
10679 !cs
->singlestep_enabled
&&
10681 dc
->pc
< next_page_start
&&
10682 num_insns
< max_insns
);
10684 if (tb
->cflags
& CF_LAST_IO
) {
10686 /* FIXME: This can theoretically happen with self-modifying
10688 cpu_abort(env
, "IO on conditional branch instruction");
10693 /* At this stage dc->condjmp will only be set when the skipped
10694 instruction was a conditional branch or trap, and the PC has
10695 already been written. */
10696 if (unlikely(cs
->singlestep_enabled
)) {
10697 /* Make sure the pc is updated, and raise a debug exception. */
10699 gen_set_condexec(dc
);
10700 if (dc
->is_jmp
== DISAS_SWI
) {
10701 gen_exception(EXCP_SWI
);
10703 gen_exception(EXCP_DEBUG
);
10705 gen_set_label(dc
->condlabel
);
10707 if (dc
->condjmp
|| !dc
->is_jmp
) {
10708 gen_set_pc_im(dc
, dc
->pc
);
10711 gen_set_condexec(dc
);
10712 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
10713 gen_exception(EXCP_SWI
);
10715 /* FIXME: Single stepping a WFI insn will not halt
10717 gen_exception(EXCP_DEBUG
);
10720 /* While branches must always occur at the end of an IT block,
10721 there are a few other things that can cause us to terminate
10722 the TB in the middle of an IT block:
10723 - Exception generating instructions (bkpt, swi, undefined).
10725 - Hardware watchpoints.
10726 Hardware breakpoints have already been handled and skip this code.
10728 gen_set_condexec(dc
);
10729 switch(dc
->is_jmp
) {
10731 gen_goto_tb(dc
, 1, dc
->pc
);
10736 /* indicate that the hash table must be used to find the next TB */
10737 tcg_gen_exit_tb(0);
10739 case DISAS_TB_JUMP
:
10740 /* nothing more to generate */
10743 gen_helper_wfi(cpu_env
);
10746 gen_exception(EXCP_SWI
);
10750 gen_set_label(dc
->condlabel
);
10751 gen_set_condexec(dc
);
10752 gen_goto_tb(dc
, 1, dc
->pc
);
10758 gen_tb_end(tb
, num_insns
);
10759 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
10762 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
10763 qemu_log("----------------\n");
10764 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
10765 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
10766 dc
->thumb
| (dc
->bswap_code
<< 1));
10771 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10774 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10776 tb
->size
= dc
->pc
- pc_start
;
10777 tb
->icount
= num_insns
;
10781 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
10783 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
10786 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10788 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
10791 static const char *cpu_mode_names
[16] = {
10792 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10793 "???", "???", "???", "und", "???", "???", "???", "sys"
10796 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
10799 ARMCPU
*cpu
= ARM_CPU(cs
);
10800 CPUARMState
*env
= &cpu
->env
;
10804 for(i
=0;i
<16;i
++) {
10805 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10807 cpu_fprintf(f
, "\n");
10809 cpu_fprintf(f
, " ");
10811 psr
= cpsr_read(env
);
10812 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10814 psr
& (1 << 31) ? 'N' : '-',
10815 psr
& (1 << 30) ? 'Z' : '-',
10816 psr
& (1 << 29) ? 'C' : '-',
10817 psr
& (1 << 28) ? 'V' : '-',
10818 psr
& CPSR_T
? 'T' : 'A',
10819 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10821 if (flags
& CPU_DUMP_FPU
) {
10822 int numvfpregs
= 0;
10823 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10826 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10829 for (i
= 0; i
< numvfpregs
; i
++) {
10830 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10831 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10832 i
* 2, (uint32_t)v
,
10833 i
* 2 + 1, (uint32_t)(v
>> 32),
10836 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10840 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10843 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
10844 env
->condexec_bits
= 0;
10846 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10847 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];