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 ((rn
& 0x1e) == 0x6))) {
3147 /* Integer or single/half precision destination. */
3148 rd
= VFP_SREG_D(insn
);
3150 VFP_DREG_D(rd
, insn
);
3153 (((rn
& 0x1c) == 0x10) || ((rn
& 0x14) == 0x14) ||
3154 ((rn
& 0x1e) == 0x4))) {
3155 /* VCVT from int or half precision is always from S reg
3156 * regardless of dp bit. VCVT with immediate frac_bits
3157 * has same format as SREG_M.
3159 rm
= VFP_SREG_M(insn
);
3161 VFP_DREG_M(rm
, insn
);
3164 rn
= VFP_SREG_N(insn
);
3165 if (op
== 15 && rn
== 15) {
3166 /* Double precision destination. */
3167 VFP_DREG_D(rd
, insn
);
3169 rd
= VFP_SREG_D(insn
);
3171 /* NB that we implicitly rely on the encoding for the frac_bits
3172 * in VCVT of fixed to float being the same as that of an SREG_M
3174 rm
= VFP_SREG_M(insn
);
3177 veclen
= s
->vec_len
;
3178 if (op
== 15 && rn
> 3)
3181 /* Shut up compiler warnings. */
3192 /* Figure out what type of vector operation this is. */
3193 if ((rd
& bank_mask
) == 0) {
3198 delta_d
= (s
->vec_stride
>> 1) + 1;
3200 delta_d
= s
->vec_stride
+ 1;
3202 if ((rm
& bank_mask
) == 0) {
3203 /* mixed scalar/vector */
3212 /* Load the initial operands. */
3217 /* Integer source */
3218 gen_mov_F0_vreg(0, rm
);
3223 gen_mov_F0_vreg(dp
, rd
);
3224 gen_mov_F1_vreg(dp
, rm
);
3228 /* Compare with zero */
3229 gen_mov_F0_vreg(dp
, rd
);
3240 /* Source and destination the same. */
3241 gen_mov_F0_vreg(dp
, rd
);
3247 /* VCVTB, VCVTT: only present with the halfprec extension
3248 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3249 * (we choose to UNDEF)
3251 if ((dp
&& !arm_feature(env
, ARM_FEATURE_V8
)) ||
3252 !arm_feature(env
, ARM_FEATURE_VFP_FP16
)) {
3255 if (!extract32(rn
, 1, 1)) {
3256 /* Half precision source. */
3257 gen_mov_F0_vreg(0, rm
);
3260 /* Otherwise fall through */
3262 /* One source operand. */
3263 gen_mov_F0_vreg(dp
, rm
);
3267 /* Two source operands. */
3268 gen_mov_F0_vreg(dp
, rn
);
3269 gen_mov_F1_vreg(dp
, rm
);
3273 /* Perform the calculation. */
3275 case 0: /* VMLA: fd + (fn * fm) */
3276 /* Note that order of inputs to the add matters for NaNs */
3278 gen_mov_F0_vreg(dp
, rd
);
3281 case 1: /* VMLS: fd + -(fn * fm) */
3284 gen_mov_F0_vreg(dp
, rd
);
3287 case 2: /* VNMLS: -fd + (fn * fm) */
3288 /* Note that it isn't valid to replace (-A + B) with (B - A)
3289 * or similar plausible looking simplifications
3290 * because this will give wrong results for NaNs.
3293 gen_mov_F0_vreg(dp
, rd
);
3297 case 3: /* VNMLA: -fd + -(fn * fm) */
3300 gen_mov_F0_vreg(dp
, rd
);
3304 case 4: /* mul: fn * fm */
3307 case 5: /* nmul: -(fn * fm) */
3311 case 6: /* add: fn + fm */
3314 case 7: /* sub: fn - fm */
3317 case 8: /* div: fn / fm */
3320 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3321 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3322 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3323 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3324 /* These are fused multiply-add, and must be done as one
3325 * floating point operation with no rounding between the
3326 * multiplication and addition steps.
3327 * NB that doing the negations here as separate steps is
3328 * correct : an input NaN should come out with its sign bit
3329 * flipped if it is a negated-input.
3331 if (!arm_feature(env
, ARM_FEATURE_VFP4
)) {
3339 gen_helper_vfp_negd(cpu_F0d
, cpu_F0d
);
3341 frd
= tcg_temp_new_i64();
3342 tcg_gen_ld_f64(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3345 gen_helper_vfp_negd(frd
, frd
);
3347 fpst
= get_fpstatus_ptr(0);
3348 gen_helper_vfp_muladdd(cpu_F0d
, cpu_F0d
,
3349 cpu_F1d
, frd
, fpst
);
3350 tcg_temp_free_ptr(fpst
);
3351 tcg_temp_free_i64(frd
);
3357 gen_helper_vfp_negs(cpu_F0s
, cpu_F0s
);
3359 frd
= tcg_temp_new_i32();
3360 tcg_gen_ld_f32(frd
, cpu_env
, vfp_reg_offset(dp
, rd
));
3362 gen_helper_vfp_negs(frd
, frd
);
3364 fpst
= get_fpstatus_ptr(0);
3365 gen_helper_vfp_muladds(cpu_F0s
, cpu_F0s
,
3366 cpu_F1s
, frd
, fpst
);
3367 tcg_temp_free_ptr(fpst
);
3368 tcg_temp_free_i32(frd
);
3371 case 14: /* fconst */
3372 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3375 n
= (insn
<< 12) & 0x80000000;
3376 i
= ((insn
>> 12) & 0x70) | (insn
& 0xf);
3383 tcg_gen_movi_i64(cpu_F0d
, ((uint64_t)n
) << 32);
3390 tcg_gen_movi_i32(cpu_F0s
, n
);
3393 case 15: /* extension space */
3407 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3408 tmp
= gen_vfp_mrs();
3409 tcg_gen_ext16u_i32(tmp
, tmp
);
3411 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3414 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3417 tcg_temp_free_i32(tmp
);
3419 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3420 tmp
= gen_vfp_mrs();
3421 tcg_gen_shri_i32(tmp
, tmp
, 16);
3423 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d
, tmp
,
3426 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s
, tmp
,
3429 tcg_temp_free_i32(tmp
);
3431 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3432 tmp
= tcg_temp_new_i32();
3434 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3437 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3440 gen_mov_F0_vreg(0, rd
);
3441 tmp2
= gen_vfp_mrs();
3442 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
3443 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3444 tcg_temp_free_i32(tmp2
);
3447 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3448 tmp
= tcg_temp_new_i32();
3450 gen_helper_vfp_fcvt_f64_to_f16(tmp
, cpu_F0d
,
3453 gen_helper_vfp_fcvt_f32_to_f16(tmp
, cpu_F0s
,
3456 tcg_gen_shli_i32(tmp
, tmp
, 16);
3457 gen_mov_F0_vreg(0, rd
);
3458 tmp2
= gen_vfp_mrs();
3459 tcg_gen_ext16u_i32(tmp2
, tmp2
);
3460 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
3461 tcg_temp_free_i32(tmp2
);
3473 case 11: /* cmpez */
3477 case 12: /* vrintr */
3479 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3481 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3483 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3485 tcg_temp_free_ptr(fpst
);
3488 case 13: /* vrintz */
3490 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3492 tcg_rmode
= tcg_const_i32(float_round_to_zero
);
3493 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3495 gen_helper_rintd(cpu_F0d
, cpu_F0d
, fpst
);
3497 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpst
);
3499 gen_helper_set_rmode(tcg_rmode
, tcg_rmode
, cpu_env
);
3500 tcg_temp_free_i32(tcg_rmode
);
3501 tcg_temp_free_ptr(fpst
);
3504 case 14: /* vrintx */
3506 TCGv_ptr fpst
= get_fpstatus_ptr(0);
3508 gen_helper_rintd_exact(cpu_F0d
, cpu_F0d
, fpst
);
3510 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpst
);
3512 tcg_temp_free_ptr(fpst
);
3515 case 15: /* single<->double conversion */
3517 gen_helper_vfp_fcvtsd(cpu_F0s
, cpu_F0d
, cpu_env
);
3519 gen_helper_vfp_fcvtds(cpu_F0d
, cpu_F0s
, cpu_env
);
3521 case 16: /* fuito */
3522 gen_vfp_uito(dp
, 0);
3524 case 17: /* fsito */
3525 gen_vfp_sito(dp
, 0);
3527 case 20: /* fshto */
3528 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3530 gen_vfp_shto(dp
, 16 - rm
, 0);
3532 case 21: /* fslto */
3533 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3535 gen_vfp_slto(dp
, 32 - rm
, 0);
3537 case 22: /* fuhto */
3538 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3540 gen_vfp_uhto(dp
, 16 - rm
, 0);
3542 case 23: /* fulto */
3543 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3545 gen_vfp_ulto(dp
, 32 - rm
, 0);
3547 case 24: /* ftoui */
3548 gen_vfp_toui(dp
, 0);
3550 case 25: /* ftouiz */
3551 gen_vfp_touiz(dp
, 0);
3553 case 26: /* ftosi */
3554 gen_vfp_tosi(dp
, 0);
3556 case 27: /* ftosiz */
3557 gen_vfp_tosiz(dp
, 0);
3559 case 28: /* ftosh */
3560 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3562 gen_vfp_tosh(dp
, 16 - rm
, 0);
3564 case 29: /* ftosl */
3565 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3567 gen_vfp_tosl(dp
, 32 - rm
, 0);
3569 case 30: /* ftouh */
3570 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3572 gen_vfp_touh(dp
, 16 - rm
, 0);
3574 case 31: /* ftoul */
3575 if (!arm_feature(env
, ARM_FEATURE_VFP3
))
3577 gen_vfp_toul(dp
, 32 - rm
, 0);
3579 default: /* undefined */
3583 default: /* undefined */
3587 /* Write back the result. */
3588 if (op
== 15 && (rn
>= 8 && rn
<= 11)) {
3589 /* Comparison, do nothing. */
3590 } else if (op
== 15 && dp
&& ((rn
& 0x1c) == 0x18 ||
3591 (rn
& 0x1e) == 0x6)) {
3592 /* VCVT double to int: always integer result.
3593 * VCVT double to half precision is always a single
3596 gen_mov_vreg_F0(0, rd
);
3597 } else if (op
== 15 && rn
== 15) {
3599 gen_mov_vreg_F0(!dp
, rd
);
3601 gen_mov_vreg_F0(dp
, rd
);
3604 /* break out of the loop if we have finished */
3608 if (op
== 15 && delta_m
== 0) {
3609 /* single source one-many */
3611 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3613 gen_mov_vreg_F0(dp
, rd
);
3617 /* Setup the next operands. */
3619 rd
= ((rd
+ delta_d
) & (bank_mask
- 1))
3623 /* One source operand. */
3624 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3626 gen_mov_F0_vreg(dp
, rm
);
3628 /* Two source operands. */
3629 rn
= ((rn
+ delta_d
) & (bank_mask
- 1))
3631 gen_mov_F0_vreg(dp
, rn
);
3633 rm
= ((rm
+ delta_m
) & (bank_mask
- 1))
3635 gen_mov_F1_vreg(dp
, rm
);
3643 if ((insn
& 0x03e00000) == 0x00400000) {
3644 /* two-register transfer */
3645 rn
= (insn
>> 16) & 0xf;
3646 rd
= (insn
>> 12) & 0xf;
3648 VFP_DREG_M(rm
, insn
);
3650 rm
= VFP_SREG_M(insn
);
3653 if (insn
& ARM_CP_RW_BIT
) {
3656 gen_mov_F0_vreg(0, rm
* 2);
3657 tmp
= gen_vfp_mrs();
3658 store_reg(s
, rd
, tmp
);
3659 gen_mov_F0_vreg(0, rm
* 2 + 1);
3660 tmp
= gen_vfp_mrs();
3661 store_reg(s
, rn
, tmp
);
3663 gen_mov_F0_vreg(0, rm
);
3664 tmp
= gen_vfp_mrs();
3665 store_reg(s
, rd
, tmp
);
3666 gen_mov_F0_vreg(0, rm
+ 1);
3667 tmp
= gen_vfp_mrs();
3668 store_reg(s
, rn
, tmp
);
3673 tmp
= load_reg(s
, rd
);
3675 gen_mov_vreg_F0(0, rm
* 2);
3676 tmp
= load_reg(s
, rn
);
3678 gen_mov_vreg_F0(0, rm
* 2 + 1);
3680 tmp
= load_reg(s
, rd
);
3682 gen_mov_vreg_F0(0, rm
);
3683 tmp
= load_reg(s
, rn
);
3685 gen_mov_vreg_F0(0, rm
+ 1);
3690 rn
= (insn
>> 16) & 0xf;
3692 VFP_DREG_D(rd
, insn
);
3694 rd
= VFP_SREG_D(insn
);
3695 if ((insn
& 0x01200000) == 0x01000000) {
3696 /* Single load/store */
3697 offset
= (insn
& 0xff) << 2;
3698 if ((insn
& (1 << 23)) == 0)
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 tcg_gen_addi_i32(addr
, addr
, offset
);
3708 if (insn
& (1 << 20)) {
3709 gen_vfp_ld(s
, dp
, addr
);
3710 gen_mov_vreg_F0(dp
, rd
);
3712 gen_mov_F0_vreg(dp
, rd
);
3713 gen_vfp_st(s
, dp
, addr
);
3715 tcg_temp_free_i32(addr
);
3717 /* load/store multiple */
3718 int w
= insn
& (1 << 21);
3720 n
= (insn
>> 1) & 0x7f;
3724 if (w
&& !(((insn
>> 23) ^ (insn
>> 24)) & 1)) {
3725 /* P == U , W == 1 => UNDEF */
3728 if (n
== 0 || (rd
+ n
) > 32 || (dp
&& n
> 16)) {
3729 /* UNPREDICTABLE cases for bad immediates: we choose to
3730 * UNDEF to avoid generating huge numbers of TCG ops
3734 if (rn
== 15 && w
) {
3735 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3739 if (s
->thumb
&& rn
== 15) {
3740 /* This is actually UNPREDICTABLE */
3741 addr
= tcg_temp_new_i32();
3742 tcg_gen_movi_i32(addr
, s
->pc
& ~2);
3744 addr
= load_reg(s
, rn
);
3746 if (insn
& (1 << 24)) /* pre-decrement */
3747 tcg_gen_addi_i32(addr
, addr
, -((insn
& 0xff) << 2));
3753 for (i
= 0; i
< n
; i
++) {
3754 if (insn
& ARM_CP_RW_BIT
) {
3756 gen_vfp_ld(s
, dp
, addr
);
3757 gen_mov_vreg_F0(dp
, rd
+ i
);
3760 gen_mov_F0_vreg(dp
, rd
+ i
);
3761 gen_vfp_st(s
, dp
, addr
);
3763 tcg_gen_addi_i32(addr
, addr
, offset
);
3767 if (insn
& (1 << 24))
3768 offset
= -offset
* n
;
3769 else if (dp
&& (insn
& 1))
3775 tcg_gen_addi_i32(addr
, addr
, offset
);
3776 store_reg(s
, rn
, addr
);
3778 tcg_temp_free_i32(addr
);
3784 /* Should never happen. */
3790 static inline void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
3792 TranslationBlock
*tb
;
3795 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
3797 gen_set_pc_im(s
, dest
);
3798 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3800 gen_set_pc_im(s
, dest
);
3805 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
3807 if (unlikely(s
->singlestep_enabled
)) {
3808 /* An indirect jump so that we still trigger the debug exception. */
3813 gen_goto_tb(s
, 0, dest
);
3814 s
->is_jmp
= DISAS_TB_JUMP
;
3818 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
3821 tcg_gen_sari_i32(t0
, t0
, 16);
3825 tcg_gen_sari_i32(t1
, t1
, 16);
3828 tcg_gen_mul_i32(t0
, t0
, t1
);
3831 /* Return the mask of PSR bits set by a MSR instruction. */
3832 static uint32_t msr_mask(CPUARMState
*env
, DisasContext
*s
, int flags
, int spsr
) {
3836 if (flags
& (1 << 0))
3838 if (flags
& (1 << 1))
3840 if (flags
& (1 << 2))
3842 if (flags
& (1 << 3))
3845 /* Mask out undefined bits. */
3846 mask
&= ~CPSR_RESERVED
;
3847 if (!arm_feature(env
, ARM_FEATURE_V4T
))
3849 if (!arm_feature(env
, ARM_FEATURE_V5
))
3850 mask
&= ~CPSR_Q
; /* V5TE in reality*/
3851 if (!arm_feature(env
, ARM_FEATURE_V6
))
3852 mask
&= ~(CPSR_E
| CPSR_GE
);
3853 if (!arm_feature(env
, ARM_FEATURE_THUMB2
))
3855 /* Mask out execution state bits. */
3858 /* Mask out privileged bits. */
3864 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3865 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3869 /* ??? This is also undefined in system mode. */
3873 tmp
= load_cpu_field(spsr
);
3874 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3875 tcg_gen_andi_i32(t0
, t0
, mask
);
3876 tcg_gen_or_i32(tmp
, tmp
, t0
);
3877 store_cpu_field(tmp
, spsr
);
3879 gen_set_cpsr(t0
, mask
);
3881 tcg_temp_free_i32(t0
);
3886 /* Returns nonzero if access to the PSR is not permitted. */
3887 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3890 tmp
= tcg_temp_new_i32();
3891 tcg_gen_movi_i32(tmp
, val
);
3892 return gen_set_psr(s
, mask
, spsr
, tmp
);
3895 /* Generate an old-style exception return. Marks pc as dead. */
3896 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3899 store_reg(s
, 15, pc
);
3900 tmp
= load_cpu_field(spsr
);
3901 gen_set_cpsr(tmp
, 0xffffffff);
3902 tcg_temp_free_i32(tmp
);
3903 s
->is_jmp
= DISAS_UPDATE
;
3906 /* Generate a v6 exception return. Marks both values as dead. */
3907 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3909 gen_set_cpsr(cpsr
, 0xffffffff);
3910 tcg_temp_free_i32(cpsr
);
3911 store_reg(s
, 15, pc
);
3912 s
->is_jmp
= DISAS_UPDATE
;
3916 gen_set_condexec (DisasContext
*s
)
3918 if (s
->condexec_mask
) {
3919 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
3920 TCGv_i32 tmp
= tcg_temp_new_i32();
3921 tcg_gen_movi_i32(tmp
, val
);
3922 store_cpu_field(tmp
, condexec_bits
);
3926 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
)
3928 gen_set_condexec(s
);
3929 gen_set_pc_im(s
, s
->pc
- offset
);
3930 gen_exception(excp
);
3931 s
->is_jmp
= DISAS_JUMP
;
3934 static void gen_nop_hint(DisasContext
*s
, int val
)
3938 gen_set_pc_im(s
, s
->pc
);
3939 s
->is_jmp
= DISAS_WFI
;
3942 gen_set_pc_im(s
, s
->pc
);
3943 s
->is_jmp
= DISAS_WFE
;
3947 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3953 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3955 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3958 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3959 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3960 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3965 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3968 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3969 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3970 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3975 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3976 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3977 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3978 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3979 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3981 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3982 switch ((size << 1) | u) { \
3984 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3987 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3990 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3993 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3996 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3999 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4001 default: return 1; \
4004 #define GEN_NEON_INTEGER_OP(name) do { \
4005 switch ((size << 1) | u) { \
4007 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4010 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4013 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4016 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4019 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4022 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4024 default: return 1; \
4027 static TCGv_i32
neon_load_scratch(int scratch
)
4029 TCGv_i32 tmp
= tcg_temp_new_i32();
4030 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4034 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
4036 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
4037 tcg_temp_free_i32(var
);
4040 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
4044 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
4046 gen_neon_dup_high16(tmp
);
4048 gen_neon_dup_low16(tmp
);
4051 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
4056 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
4059 if (!q
&& size
== 2) {
4062 tmp
= tcg_const_i32(rd
);
4063 tmp2
= tcg_const_i32(rm
);
4067 gen_helper_neon_qunzip8(cpu_env
, tmp
, tmp2
);
4070 gen_helper_neon_qunzip16(cpu_env
, tmp
, tmp2
);
4073 gen_helper_neon_qunzip32(cpu_env
, tmp
, tmp2
);
4081 gen_helper_neon_unzip8(cpu_env
, tmp
, tmp2
);
4084 gen_helper_neon_unzip16(cpu_env
, tmp
, tmp2
);
4090 tcg_temp_free_i32(tmp
);
4091 tcg_temp_free_i32(tmp2
);
4095 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
4098 if (!q
&& size
== 2) {
4101 tmp
= tcg_const_i32(rd
);
4102 tmp2
= tcg_const_i32(rm
);
4106 gen_helper_neon_qzip8(cpu_env
, tmp
, tmp2
);
4109 gen_helper_neon_qzip16(cpu_env
, tmp
, tmp2
);
4112 gen_helper_neon_qzip32(cpu_env
, tmp
, tmp2
);
4120 gen_helper_neon_zip8(cpu_env
, tmp
, tmp2
);
4123 gen_helper_neon_zip16(cpu_env
, tmp
, tmp2
);
4129 tcg_temp_free_i32(tmp
);
4130 tcg_temp_free_i32(tmp2
);
4134 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
4138 rd
= tcg_temp_new_i32();
4139 tmp
= tcg_temp_new_i32();
4141 tcg_gen_shli_i32(rd
, t0
, 8);
4142 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
4143 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
4144 tcg_gen_or_i32(rd
, rd
, tmp
);
4146 tcg_gen_shri_i32(t1
, t1
, 8);
4147 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
4148 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
4149 tcg_gen_or_i32(t1
, t1
, tmp
);
4150 tcg_gen_mov_i32(t0
, rd
);
4152 tcg_temp_free_i32(tmp
);
4153 tcg_temp_free_i32(rd
);
4156 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
4160 rd
= tcg_temp_new_i32();
4161 tmp
= tcg_temp_new_i32();
4163 tcg_gen_shli_i32(rd
, t0
, 16);
4164 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
4165 tcg_gen_or_i32(rd
, rd
, tmp
);
4166 tcg_gen_shri_i32(t1
, t1
, 16);
4167 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
4168 tcg_gen_or_i32(t1
, t1
, tmp
);
4169 tcg_gen_mov_i32(t0
, rd
);
4171 tcg_temp_free_i32(tmp
);
4172 tcg_temp_free_i32(rd
);
4180 } neon_ls_element_type
[11] = {
4194 /* Translate a NEON load/store element instruction. Return nonzero if the
4195 instruction is invalid. */
4196 static int disas_neon_ls_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4215 if (!s
->vfp_enabled
)
4217 VFP_DREG_D(rd
, insn
);
4218 rn
= (insn
>> 16) & 0xf;
4220 load
= (insn
& (1 << 21)) != 0;
4221 if ((insn
& (1 << 23)) == 0) {
4222 /* Load store all elements. */
4223 op
= (insn
>> 8) & 0xf;
4224 size
= (insn
>> 6) & 3;
4227 /* Catch UNDEF cases for bad values of align field */
4230 if (((insn
>> 5) & 1) == 1) {
4235 if (((insn
>> 4) & 3) == 3) {
4242 nregs
= neon_ls_element_type
[op
].nregs
;
4243 interleave
= neon_ls_element_type
[op
].interleave
;
4244 spacing
= neon_ls_element_type
[op
].spacing
;
4245 if (size
== 3 && (interleave
| spacing
) != 1)
4247 addr
= tcg_temp_new_i32();
4248 load_reg_var(s
, addr
, rn
);
4249 stride
= (1 << size
) * interleave
;
4250 for (reg
= 0; reg
< nregs
; reg
++) {
4251 if (interleave
> 2 || (interleave
== 2 && nregs
== 2)) {
4252 load_reg_var(s
, addr
, rn
);
4253 tcg_gen_addi_i32(addr
, addr
, (1 << size
) * reg
);
4254 } else if (interleave
== 2 && nregs
== 4 && reg
== 2) {
4255 load_reg_var(s
, addr
, rn
);
4256 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4259 tmp64
= tcg_temp_new_i64();
4261 gen_aa32_ld64(tmp64
, addr
, IS_USER(s
));
4262 neon_store_reg64(tmp64
, rd
);
4264 neon_load_reg64(tmp64
, rd
);
4265 gen_aa32_st64(tmp64
, addr
, IS_USER(s
));
4267 tcg_temp_free_i64(tmp64
);
4268 tcg_gen_addi_i32(addr
, addr
, stride
);
4270 for (pass
= 0; pass
< 2; pass
++) {
4273 tmp
= tcg_temp_new_i32();
4274 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
4275 neon_store_reg(rd
, pass
, tmp
);
4277 tmp
= neon_load_reg(rd
, pass
);
4278 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
4279 tcg_temp_free_i32(tmp
);
4281 tcg_gen_addi_i32(addr
, addr
, stride
);
4282 } else if (size
== 1) {
4284 tmp
= tcg_temp_new_i32();
4285 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
4286 tcg_gen_addi_i32(addr
, addr
, stride
);
4287 tmp2
= tcg_temp_new_i32();
4288 gen_aa32_ld16u(tmp2
, addr
, IS_USER(s
));
4289 tcg_gen_addi_i32(addr
, addr
, stride
);
4290 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
4291 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
4292 tcg_temp_free_i32(tmp2
);
4293 neon_store_reg(rd
, pass
, tmp
);
4295 tmp
= neon_load_reg(rd
, pass
);
4296 tmp2
= tcg_temp_new_i32();
4297 tcg_gen_shri_i32(tmp2
, tmp
, 16);
4298 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
4299 tcg_temp_free_i32(tmp
);
4300 tcg_gen_addi_i32(addr
, addr
, stride
);
4301 gen_aa32_st16(tmp2
, addr
, IS_USER(s
));
4302 tcg_temp_free_i32(tmp2
);
4303 tcg_gen_addi_i32(addr
, addr
, stride
);
4305 } else /* size == 0 */ {
4307 TCGV_UNUSED_I32(tmp2
);
4308 for (n
= 0; n
< 4; n
++) {
4309 tmp
= tcg_temp_new_i32();
4310 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
4311 tcg_gen_addi_i32(addr
, addr
, stride
);
4315 tcg_gen_shli_i32(tmp
, tmp
, n
* 8);
4316 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
4317 tcg_temp_free_i32(tmp
);
4320 neon_store_reg(rd
, pass
, tmp2
);
4322 tmp2
= neon_load_reg(rd
, pass
);
4323 for (n
= 0; n
< 4; n
++) {
4324 tmp
= tcg_temp_new_i32();
4326 tcg_gen_mov_i32(tmp
, tmp2
);
4328 tcg_gen_shri_i32(tmp
, tmp2
, n
* 8);
4330 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
4331 tcg_temp_free_i32(tmp
);
4332 tcg_gen_addi_i32(addr
, addr
, stride
);
4334 tcg_temp_free_i32(tmp2
);
4341 tcg_temp_free_i32(addr
);
4344 size
= (insn
>> 10) & 3;
4346 /* Load single element to all lanes. */
4347 int a
= (insn
>> 4) & 1;
4351 size
= (insn
>> 6) & 3;
4352 nregs
= ((insn
>> 8) & 3) + 1;
4355 if (nregs
!= 4 || a
== 0) {
4358 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4361 if (nregs
== 1 && a
== 1 && size
== 0) {
4364 if (nregs
== 3 && a
== 1) {
4367 addr
= tcg_temp_new_i32();
4368 load_reg_var(s
, addr
, rn
);
4370 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4371 tmp
= gen_load_and_replicate(s
, addr
, size
);
4372 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4373 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4374 if (insn
& (1 << 5)) {
4375 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 0));
4376 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
+ 1, 1));
4378 tcg_temp_free_i32(tmp
);
4380 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4381 stride
= (insn
& (1 << 5)) ? 2 : 1;
4382 for (reg
= 0; reg
< nregs
; reg
++) {
4383 tmp
= gen_load_and_replicate(s
, addr
, size
);
4384 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 0));
4385 tcg_gen_st_i32(tmp
, cpu_env
, neon_reg_offset(rd
, 1));
4386 tcg_temp_free_i32(tmp
);
4387 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4391 tcg_temp_free_i32(addr
);
4392 stride
= (1 << size
) * nregs
;
4394 /* Single element. */
4395 int idx
= (insn
>> 4) & 0xf;
4396 pass
= (insn
>> 7) & 1;
4399 shift
= ((insn
>> 5) & 3) * 8;
4403 shift
= ((insn
>> 6) & 1) * 16;
4404 stride
= (insn
& (1 << 5)) ? 2 : 1;
4408 stride
= (insn
& (1 << 6)) ? 2 : 1;
4413 nregs
= ((insn
>> 8) & 3) + 1;
4414 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4417 if (((idx
& (1 << size
)) != 0) ||
4418 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
4423 if ((idx
& 1) != 0) {
4428 if (size
== 2 && (idx
& 2) != 0) {
4433 if ((size
== 2) && ((idx
& 3) == 3)) {
4440 if ((rd
+ stride
* (nregs
- 1)) > 31) {
4441 /* Attempts to write off the end of the register file
4442 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4443 * the neon_load_reg() would write off the end of the array.
4447 addr
= tcg_temp_new_i32();
4448 load_reg_var(s
, addr
, rn
);
4449 for (reg
= 0; reg
< nregs
; reg
++) {
4451 tmp
= tcg_temp_new_i32();
4454 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
4457 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
4460 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
4462 default: /* Avoid compiler warnings. */
4466 tmp2
= neon_load_reg(rd
, pass
);
4467 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
,
4468 shift
, size
? 16 : 8);
4469 tcg_temp_free_i32(tmp2
);
4471 neon_store_reg(rd
, pass
, tmp
);
4472 } else { /* Store */
4473 tmp
= neon_load_reg(rd
, pass
);
4475 tcg_gen_shri_i32(tmp
, tmp
, shift
);
4478 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
4481 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
4484 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
4487 tcg_temp_free_i32(tmp
);
4490 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
4492 tcg_temp_free_i32(addr
);
4493 stride
= nregs
* (1 << size
);
4499 base
= load_reg(s
, rn
);
4501 tcg_gen_addi_i32(base
, base
, stride
);
4504 index
= load_reg(s
, rm
);
4505 tcg_gen_add_i32(base
, base
, index
);
4506 tcg_temp_free_i32(index
);
4508 store_reg(s
, rn
, base
);
4513 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4514 static void gen_neon_bsl(TCGv_i32 dest
, TCGv_i32 t
, TCGv_i32 f
, TCGv_i32 c
)
4516 tcg_gen_and_i32(t
, t
, c
);
4517 tcg_gen_andc_i32(f
, f
, c
);
4518 tcg_gen_or_i32(dest
, t
, f
);
4521 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4524 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
4525 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
4526 case 2: tcg_gen_trunc_i64_i32(dest
, src
); break;
4531 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4534 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
4535 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
4536 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
4541 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4544 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
4545 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
4546 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
4551 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
4554 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
4555 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
4556 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
4561 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
4567 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
4568 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
4573 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
4574 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
4581 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
4582 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
4587 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
4588 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
4595 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
4599 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
4600 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
4601 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
4606 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
4607 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
4608 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
4612 tcg_temp_free_i32(src
);
4615 static inline void gen_neon_addl(int size
)
4618 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
4619 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
4620 case 2: tcg_gen_add_i64(CPU_V001
); break;
4625 static inline void gen_neon_subl(int size
)
4628 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
4629 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
4630 case 2: tcg_gen_sub_i64(CPU_V001
); break;
4635 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
4638 case 0: gen_helper_neon_negl_u16(var
, var
); break;
4639 case 1: gen_helper_neon_negl_u32(var
, var
); break;
4641 tcg_gen_neg_i64(var
, var
);
4647 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
4650 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
4651 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
4656 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
4661 switch ((size
<< 1) | u
) {
4662 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
4663 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
4664 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
4665 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
4667 tmp
= gen_muls_i64_i32(a
, b
);
4668 tcg_gen_mov_i64(dest
, tmp
);
4669 tcg_temp_free_i64(tmp
);
4672 tmp
= gen_mulu_i64_i32(a
, b
);
4673 tcg_gen_mov_i64(dest
, tmp
);
4674 tcg_temp_free_i64(tmp
);
4679 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4680 Don't forget to clean them now. */
4682 tcg_temp_free_i32(a
);
4683 tcg_temp_free_i32(b
);
4687 static void gen_neon_narrow_op(int op
, int u
, int size
,
4688 TCGv_i32 dest
, TCGv_i64 src
)
4692 gen_neon_unarrow_sats(size
, dest
, src
);
4694 gen_neon_narrow(size
, dest
, src
);
4698 gen_neon_narrow_satu(size
, dest
, src
);
4700 gen_neon_narrow_sats(size
, dest
, src
);
4705 /* Symbolic constants for op fields for Neon 3-register same-length.
4706 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4709 #define NEON_3R_VHADD 0
4710 #define NEON_3R_VQADD 1
4711 #define NEON_3R_VRHADD 2
4712 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4713 #define NEON_3R_VHSUB 4
4714 #define NEON_3R_VQSUB 5
4715 #define NEON_3R_VCGT 6
4716 #define NEON_3R_VCGE 7
4717 #define NEON_3R_VSHL 8
4718 #define NEON_3R_VQSHL 9
4719 #define NEON_3R_VRSHL 10
4720 #define NEON_3R_VQRSHL 11
4721 #define NEON_3R_VMAX 12
4722 #define NEON_3R_VMIN 13
4723 #define NEON_3R_VABD 14
4724 #define NEON_3R_VABA 15
4725 #define NEON_3R_VADD_VSUB 16
4726 #define NEON_3R_VTST_VCEQ 17
4727 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4728 #define NEON_3R_VMUL 19
4729 #define NEON_3R_VPMAX 20
4730 #define NEON_3R_VPMIN 21
4731 #define NEON_3R_VQDMULH_VQRDMULH 22
4732 #define NEON_3R_VPADD 23
4733 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4734 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4735 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4736 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4737 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4738 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4739 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4741 static const uint8_t neon_3r_sizes
[] = {
4742 [NEON_3R_VHADD
] = 0x7,
4743 [NEON_3R_VQADD
] = 0xf,
4744 [NEON_3R_VRHADD
] = 0x7,
4745 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4746 [NEON_3R_VHSUB
] = 0x7,
4747 [NEON_3R_VQSUB
] = 0xf,
4748 [NEON_3R_VCGT
] = 0x7,
4749 [NEON_3R_VCGE
] = 0x7,
4750 [NEON_3R_VSHL
] = 0xf,
4751 [NEON_3R_VQSHL
] = 0xf,
4752 [NEON_3R_VRSHL
] = 0xf,
4753 [NEON_3R_VQRSHL
] = 0xf,
4754 [NEON_3R_VMAX
] = 0x7,
4755 [NEON_3R_VMIN
] = 0x7,
4756 [NEON_3R_VABD
] = 0x7,
4757 [NEON_3R_VABA
] = 0x7,
4758 [NEON_3R_VADD_VSUB
] = 0xf,
4759 [NEON_3R_VTST_VCEQ
] = 0x7,
4760 [NEON_3R_VML
] = 0x7,
4761 [NEON_3R_VMUL
] = 0x7,
4762 [NEON_3R_VPMAX
] = 0x7,
4763 [NEON_3R_VPMIN
] = 0x7,
4764 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4765 [NEON_3R_VPADD
] = 0x7,
4766 [NEON_3R_VFM
] = 0x5, /* size bit 1 encodes op */
4767 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4768 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4769 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4770 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4771 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4772 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4775 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4776 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4779 #define NEON_2RM_VREV64 0
4780 #define NEON_2RM_VREV32 1
4781 #define NEON_2RM_VREV16 2
4782 #define NEON_2RM_VPADDL 4
4783 #define NEON_2RM_VPADDL_U 5
4784 #define NEON_2RM_AESE 6 /* Includes AESD */
4785 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4786 #define NEON_2RM_VCLS 8
4787 #define NEON_2RM_VCLZ 9
4788 #define NEON_2RM_VCNT 10
4789 #define NEON_2RM_VMVN 11
4790 #define NEON_2RM_VPADAL 12
4791 #define NEON_2RM_VPADAL_U 13
4792 #define NEON_2RM_VQABS 14
4793 #define NEON_2RM_VQNEG 15
4794 #define NEON_2RM_VCGT0 16
4795 #define NEON_2RM_VCGE0 17
4796 #define NEON_2RM_VCEQ0 18
4797 #define NEON_2RM_VCLE0 19
4798 #define NEON_2RM_VCLT0 20
4799 #define NEON_2RM_VABS 22
4800 #define NEON_2RM_VNEG 23
4801 #define NEON_2RM_VCGT0_F 24
4802 #define NEON_2RM_VCGE0_F 25
4803 #define NEON_2RM_VCEQ0_F 26
4804 #define NEON_2RM_VCLE0_F 27
4805 #define NEON_2RM_VCLT0_F 28
4806 #define NEON_2RM_VABS_F 30
4807 #define NEON_2RM_VNEG_F 31
4808 #define NEON_2RM_VSWP 32
4809 #define NEON_2RM_VTRN 33
4810 #define NEON_2RM_VUZP 34
4811 #define NEON_2RM_VZIP 35
4812 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4813 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4814 #define NEON_2RM_VSHLL 38
4815 #define NEON_2RM_VRINTN 40
4816 #define NEON_2RM_VRINTX 41
4817 #define NEON_2RM_VRINTA 42
4818 #define NEON_2RM_VRINTZ 43
4819 #define NEON_2RM_VCVT_F16_F32 44
4820 #define NEON_2RM_VRINTM 45
4821 #define NEON_2RM_VCVT_F32_F16 46
4822 #define NEON_2RM_VRINTP 47
4823 #define NEON_2RM_VCVTAU 48
4824 #define NEON_2RM_VCVTAS 49
4825 #define NEON_2RM_VCVTNU 50
4826 #define NEON_2RM_VCVTNS 51
4827 #define NEON_2RM_VCVTPU 52
4828 #define NEON_2RM_VCVTPS 53
4829 #define NEON_2RM_VCVTMU 54
4830 #define NEON_2RM_VCVTMS 55
4831 #define NEON_2RM_VRECPE 56
4832 #define NEON_2RM_VRSQRTE 57
4833 #define NEON_2RM_VRECPE_F 58
4834 #define NEON_2RM_VRSQRTE_F 59
4835 #define NEON_2RM_VCVT_FS 60
4836 #define NEON_2RM_VCVT_FU 61
4837 #define NEON_2RM_VCVT_SF 62
4838 #define NEON_2RM_VCVT_UF 63
4840 static int neon_2rm_is_float_op(int op
)
4842 /* Return true if this neon 2reg-misc op is float-to-float */
4843 return (op
== NEON_2RM_VABS_F
|| op
== NEON_2RM_VNEG_F
||
4844 (op
>= NEON_2RM_VRINTN
&& op
<= NEON_2RM_VRINTZ
) ||
4845 op
== NEON_2RM_VRINTM
||
4846 (op
>= NEON_2RM_VRINTP
&& op
<= NEON_2RM_VCVTMS
) ||
4847 op
>= NEON_2RM_VRECPE_F
);
4850 /* Each entry in this array has bit n set if the insn allows
4851 * size value n (otherwise it will UNDEF). Since unallocated
4852 * op values will have no bits set they always UNDEF.
4854 static const uint8_t neon_2rm_sizes
[] = {
4855 [NEON_2RM_VREV64
] = 0x7,
4856 [NEON_2RM_VREV32
] = 0x3,
4857 [NEON_2RM_VREV16
] = 0x1,
4858 [NEON_2RM_VPADDL
] = 0x7,
4859 [NEON_2RM_VPADDL_U
] = 0x7,
4860 [NEON_2RM_AESE
] = 0x1,
4861 [NEON_2RM_AESMC
] = 0x1,
4862 [NEON_2RM_VCLS
] = 0x7,
4863 [NEON_2RM_VCLZ
] = 0x7,
4864 [NEON_2RM_VCNT
] = 0x1,
4865 [NEON_2RM_VMVN
] = 0x1,
4866 [NEON_2RM_VPADAL
] = 0x7,
4867 [NEON_2RM_VPADAL_U
] = 0x7,
4868 [NEON_2RM_VQABS
] = 0x7,
4869 [NEON_2RM_VQNEG
] = 0x7,
4870 [NEON_2RM_VCGT0
] = 0x7,
4871 [NEON_2RM_VCGE0
] = 0x7,
4872 [NEON_2RM_VCEQ0
] = 0x7,
4873 [NEON_2RM_VCLE0
] = 0x7,
4874 [NEON_2RM_VCLT0
] = 0x7,
4875 [NEON_2RM_VABS
] = 0x7,
4876 [NEON_2RM_VNEG
] = 0x7,
4877 [NEON_2RM_VCGT0_F
] = 0x4,
4878 [NEON_2RM_VCGE0_F
] = 0x4,
4879 [NEON_2RM_VCEQ0_F
] = 0x4,
4880 [NEON_2RM_VCLE0_F
] = 0x4,
4881 [NEON_2RM_VCLT0_F
] = 0x4,
4882 [NEON_2RM_VABS_F
] = 0x4,
4883 [NEON_2RM_VNEG_F
] = 0x4,
4884 [NEON_2RM_VSWP
] = 0x1,
4885 [NEON_2RM_VTRN
] = 0x7,
4886 [NEON_2RM_VUZP
] = 0x7,
4887 [NEON_2RM_VZIP
] = 0x7,
4888 [NEON_2RM_VMOVN
] = 0x7,
4889 [NEON_2RM_VQMOVN
] = 0x7,
4890 [NEON_2RM_VSHLL
] = 0x7,
4891 [NEON_2RM_VRINTN
] = 0x4,
4892 [NEON_2RM_VRINTX
] = 0x4,
4893 [NEON_2RM_VRINTA
] = 0x4,
4894 [NEON_2RM_VRINTZ
] = 0x4,
4895 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4896 [NEON_2RM_VRINTM
] = 0x4,
4897 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4898 [NEON_2RM_VRINTP
] = 0x4,
4899 [NEON_2RM_VCVTAU
] = 0x4,
4900 [NEON_2RM_VCVTAS
] = 0x4,
4901 [NEON_2RM_VCVTNU
] = 0x4,
4902 [NEON_2RM_VCVTNS
] = 0x4,
4903 [NEON_2RM_VCVTPU
] = 0x4,
4904 [NEON_2RM_VCVTPS
] = 0x4,
4905 [NEON_2RM_VCVTMU
] = 0x4,
4906 [NEON_2RM_VCVTMS
] = 0x4,
4907 [NEON_2RM_VRECPE
] = 0x4,
4908 [NEON_2RM_VRSQRTE
] = 0x4,
4909 [NEON_2RM_VRECPE_F
] = 0x4,
4910 [NEON_2RM_VRSQRTE_F
] = 0x4,
4911 [NEON_2RM_VCVT_FS
] = 0x4,
4912 [NEON_2RM_VCVT_FU
] = 0x4,
4913 [NEON_2RM_VCVT_SF
] = 0x4,
4914 [NEON_2RM_VCVT_UF
] = 0x4,
4917 /* Translate a NEON data processing instruction. Return nonzero if the
4918 instruction is invalid.
4919 We process data in a mixture of 32-bit and 64-bit chunks.
4920 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4922 static int disas_neon_data_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
4934 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4937 if (!s
->vfp_enabled
)
4939 q
= (insn
& (1 << 6)) != 0;
4940 u
= (insn
>> 24) & 1;
4941 VFP_DREG_D(rd
, insn
);
4942 VFP_DREG_N(rn
, insn
);
4943 VFP_DREG_M(rm
, insn
);
4944 size
= (insn
>> 20) & 3;
4945 if ((insn
& (1 << 23)) == 0) {
4946 /* Three register same length. */
4947 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4948 /* Catch invalid op and bad size combinations: UNDEF */
4949 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4952 /* All insns of this form UNDEF for either this condition or the
4953 * superset of cases "Q==1"; we catch the latter later.
4955 if (q
&& ((rd
| rn
| rm
) & 1)) {
4958 if (size
== 3 && op
!= NEON_3R_LOGIC
) {
4959 /* 64-bit element instructions. */
4960 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4961 neon_load_reg64(cpu_V0
, rn
+ pass
);
4962 neon_load_reg64(cpu_V1
, rm
+ pass
);
4966 gen_helper_neon_qadd_u64(cpu_V0
, cpu_env
,
4969 gen_helper_neon_qadd_s64(cpu_V0
, cpu_env
,
4975 gen_helper_neon_qsub_u64(cpu_V0
, cpu_env
,
4978 gen_helper_neon_qsub_s64(cpu_V0
, cpu_env
,
4984 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4986 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4991 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4994 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5000 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5002 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5005 case NEON_3R_VQRSHL
:
5007 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5010 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5014 case NEON_3R_VADD_VSUB
:
5016 tcg_gen_sub_i64(CPU_V001
);
5018 tcg_gen_add_i64(CPU_V001
);
5024 neon_store_reg64(cpu_V0
, rd
+ pass
);
5033 case NEON_3R_VQRSHL
:
5036 /* Shift instruction operands are reversed. */
5051 case NEON_3R_FLOAT_ARITH
:
5052 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5054 case NEON_3R_FLOAT_MINMAX
:
5055 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5057 case NEON_3R_FLOAT_CMP
:
5059 /* no encoding for U=0 C=1x */
5063 case NEON_3R_FLOAT_ACMP
:
5068 case NEON_3R_FLOAT_MISC
:
5069 /* VMAXNM/VMINNM in ARMv8 */
5070 if (u
&& !arm_feature(env
, ARM_FEATURE_V8
)) {
5075 if (u
&& (size
!= 0)) {
5076 /* UNDEF on invalid size for polynomial subcase */
5081 if (!arm_feature(env
, ARM_FEATURE_VFP4
) || u
) {
5089 if (pairwise
&& q
) {
5090 /* All the pairwise insns UNDEF if Q is set */
5094 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5099 tmp
= neon_load_reg(rn
, 0);
5100 tmp2
= neon_load_reg(rn
, 1);
5102 tmp
= neon_load_reg(rm
, 0);
5103 tmp2
= neon_load_reg(rm
, 1);
5107 tmp
= neon_load_reg(rn
, pass
);
5108 tmp2
= neon_load_reg(rm
, pass
);
5112 GEN_NEON_INTEGER_OP(hadd
);
5115 GEN_NEON_INTEGER_OP_ENV(qadd
);
5117 case NEON_3R_VRHADD
:
5118 GEN_NEON_INTEGER_OP(rhadd
);
5120 case NEON_3R_LOGIC
: /* Logic ops. */
5121 switch ((u
<< 2) | size
) {
5123 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
5126 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
5129 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5132 tcg_gen_orc_i32(tmp
, tmp
, tmp2
);
5135 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
5138 tmp3
= neon_load_reg(rd
, pass
);
5139 gen_neon_bsl(tmp
, tmp
, tmp2
, tmp3
);
5140 tcg_temp_free_i32(tmp3
);
5143 tmp3
= neon_load_reg(rd
, pass
);
5144 gen_neon_bsl(tmp
, tmp
, tmp3
, tmp2
);
5145 tcg_temp_free_i32(tmp3
);
5148 tmp3
= neon_load_reg(rd
, pass
);
5149 gen_neon_bsl(tmp
, tmp3
, tmp
, tmp2
);
5150 tcg_temp_free_i32(tmp3
);
5155 GEN_NEON_INTEGER_OP(hsub
);
5158 GEN_NEON_INTEGER_OP_ENV(qsub
);
5161 GEN_NEON_INTEGER_OP(cgt
);
5164 GEN_NEON_INTEGER_OP(cge
);
5167 GEN_NEON_INTEGER_OP(shl
);
5170 GEN_NEON_INTEGER_OP_ENV(qshl
);
5173 GEN_NEON_INTEGER_OP(rshl
);
5175 case NEON_3R_VQRSHL
:
5176 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5179 GEN_NEON_INTEGER_OP(max
);
5182 GEN_NEON_INTEGER_OP(min
);
5185 GEN_NEON_INTEGER_OP(abd
);
5188 GEN_NEON_INTEGER_OP(abd
);
5189 tcg_temp_free_i32(tmp2
);
5190 tmp2
= neon_load_reg(rd
, pass
);
5191 gen_neon_add(size
, tmp
, tmp2
);
5193 case NEON_3R_VADD_VSUB
:
5194 if (!u
) { /* VADD */
5195 gen_neon_add(size
, tmp
, tmp2
);
5198 case 0: gen_helper_neon_sub_u8(tmp
, tmp
, tmp2
); break;
5199 case 1: gen_helper_neon_sub_u16(tmp
, tmp
, tmp2
); break;
5200 case 2: tcg_gen_sub_i32(tmp
, tmp
, tmp2
); break;
5205 case NEON_3R_VTST_VCEQ
:
5206 if (!u
) { /* VTST */
5208 case 0: gen_helper_neon_tst_u8(tmp
, tmp
, tmp2
); break;
5209 case 1: gen_helper_neon_tst_u16(tmp
, tmp
, tmp2
); break;
5210 case 2: gen_helper_neon_tst_u32(tmp
, tmp
, tmp2
); break;
5215 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
5216 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
5217 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
5222 case NEON_3R_VML
: /* VMLA, VMLAL, VMLS,VMLSL */
5224 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5225 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5226 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5229 tcg_temp_free_i32(tmp2
);
5230 tmp2
= neon_load_reg(rd
, pass
);
5232 gen_neon_rsb(size
, tmp
, tmp2
);
5234 gen_neon_add(size
, tmp
, tmp2
);
5238 if (u
) { /* polynomial */
5239 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5240 } else { /* Integer */
5242 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5243 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5244 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5250 GEN_NEON_INTEGER_OP(pmax
);
5253 GEN_NEON_INTEGER_OP(pmin
);
5255 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5256 if (!u
) { /* VQDMULH */
5259 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5262 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5266 } else { /* VQRDMULH */
5269 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5272 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5280 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5281 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5282 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5286 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5288 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5289 switch ((u
<< 2) | size
) {
5292 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5295 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5298 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5303 tcg_temp_free_ptr(fpstatus
);
5306 case NEON_3R_FLOAT_MULTIPLY
:
5308 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5309 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5311 tcg_temp_free_i32(tmp2
);
5312 tmp2
= neon_load_reg(rd
, pass
);
5314 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5316 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5319 tcg_temp_free_ptr(fpstatus
);
5322 case NEON_3R_FLOAT_CMP
:
5324 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5326 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5329 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5331 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5334 tcg_temp_free_ptr(fpstatus
);
5337 case NEON_3R_FLOAT_ACMP
:
5339 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5341 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5343 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5345 tcg_temp_free_ptr(fpstatus
);
5348 case NEON_3R_FLOAT_MINMAX
:
5350 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5352 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5354 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5356 tcg_temp_free_ptr(fpstatus
);
5359 case NEON_3R_FLOAT_MISC
:
5362 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5364 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5366 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5368 tcg_temp_free_ptr(fpstatus
);
5371 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5373 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5379 /* VFMA, VFMS: fused multiply-add */
5380 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5381 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5384 gen_helper_vfp_negs(tmp
, tmp
);
5386 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5387 tcg_temp_free_i32(tmp3
);
5388 tcg_temp_free_ptr(fpstatus
);
5394 tcg_temp_free_i32(tmp2
);
5396 /* Save the result. For elementwise operations we can put it
5397 straight into the destination register. For pairwise operations
5398 we have to be careful to avoid clobbering the source operands. */
5399 if (pairwise
&& rd
== rm
) {
5400 neon_store_scratch(pass
, tmp
);
5402 neon_store_reg(rd
, pass
, tmp
);
5406 if (pairwise
&& rd
== rm
) {
5407 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5408 tmp
= neon_load_scratch(pass
);
5409 neon_store_reg(rd
, pass
, tmp
);
5412 /* End of 3 register same size operations. */
5413 } else if (insn
& (1 << 4)) {
5414 if ((insn
& 0x00380080) != 0) {
5415 /* Two registers and shift. */
5416 op
= (insn
>> 8) & 0xf;
5417 if (insn
& (1 << 7)) {
5425 while ((insn
& (1 << (size
+ 19))) == 0)
5428 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5429 /* To avoid excessive duplication of ops we implement shift
5430 by immediate using the variable shift operations. */
5432 /* Shift by immediate:
5433 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5434 if (q
&& ((rd
| rm
) & 1)) {
5437 if (!u
&& (op
== 4 || op
== 6)) {
5440 /* Right shifts are encoded as N - shift, where N is the
5441 element size in bits. */
5443 shift
= shift
- (1 << (size
+ 3));
5451 imm
= (uint8_t) shift
;
5456 imm
= (uint16_t) shift
;
5467 for (pass
= 0; pass
< count
; pass
++) {
5469 neon_load_reg64(cpu_V0
, rm
+ pass
);
5470 tcg_gen_movi_i64(cpu_V1
, imm
);
5475 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5477 gen_helper_neon_shl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5482 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5484 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5487 case 5: /* VSHL, VSLI */
5488 gen_helper_neon_shl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5490 case 6: /* VQSHLU */
5491 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5496 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5499 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5504 if (op
== 1 || op
== 3) {
5506 neon_load_reg64(cpu_V1
, rd
+ pass
);
5507 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5508 } else if (op
== 4 || (op
== 5 && u
)) {
5510 neon_load_reg64(cpu_V1
, rd
+ pass
);
5512 if (shift
< -63 || shift
> 63) {
5516 mask
= 0xffffffffffffffffull
>> -shift
;
5518 mask
= 0xffffffffffffffffull
<< shift
;
5521 tcg_gen_andi_i64(cpu_V1
, cpu_V1
, ~mask
);
5522 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5524 neon_store_reg64(cpu_V0
, rd
+ pass
);
5525 } else { /* size < 3 */
5526 /* Operands in T0 and T1. */
5527 tmp
= neon_load_reg(rm
, pass
);
5528 tmp2
= tcg_temp_new_i32();
5529 tcg_gen_movi_i32(tmp2
, imm
);
5533 GEN_NEON_INTEGER_OP(shl
);
5537 GEN_NEON_INTEGER_OP(rshl
);
5540 case 5: /* VSHL, VSLI */
5542 case 0: gen_helper_neon_shl_u8(tmp
, tmp
, tmp2
); break;
5543 case 1: gen_helper_neon_shl_u16(tmp
, tmp
, tmp2
); break;
5544 case 2: gen_helper_neon_shl_u32(tmp
, tmp
, tmp2
); break;
5548 case 6: /* VQSHLU */
5551 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5555 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5559 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5567 GEN_NEON_INTEGER_OP_ENV(qshl
);
5570 tcg_temp_free_i32(tmp2
);
5572 if (op
== 1 || op
== 3) {
5574 tmp2
= neon_load_reg(rd
, pass
);
5575 gen_neon_add(size
, tmp
, tmp2
);
5576 tcg_temp_free_i32(tmp2
);
5577 } else if (op
== 4 || (op
== 5 && u
)) {
5582 mask
= 0xff >> -shift
;
5584 mask
= (uint8_t)(0xff << shift
);
5590 mask
= 0xffff >> -shift
;
5592 mask
= (uint16_t)(0xffff << shift
);
5596 if (shift
< -31 || shift
> 31) {
5600 mask
= 0xffffffffu
>> -shift
;
5602 mask
= 0xffffffffu
<< shift
;
5608 tmp2
= neon_load_reg(rd
, pass
);
5609 tcg_gen_andi_i32(tmp
, tmp
, mask
);
5610 tcg_gen_andi_i32(tmp2
, tmp2
, ~mask
);
5611 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
5612 tcg_temp_free_i32(tmp2
);
5614 neon_store_reg(rd
, pass
, tmp
);
5617 } else if (op
< 10) {
5618 /* Shift by immediate and narrow:
5619 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5620 int input_unsigned
= (op
== 8) ? !u
: u
;
5624 shift
= shift
- (1 << (size
+ 3));
5627 tmp64
= tcg_const_i64(shift
);
5628 neon_load_reg64(cpu_V0
, rm
);
5629 neon_load_reg64(cpu_V1
, rm
+ 1);
5630 for (pass
= 0; pass
< 2; pass
++) {
5638 if (input_unsigned
) {
5639 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5641 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5644 if (input_unsigned
) {
5645 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5647 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5650 tmp
= tcg_temp_new_i32();
5651 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5652 neon_store_reg(rd
, pass
, tmp
);
5654 tcg_temp_free_i64(tmp64
);
5657 imm
= (uint16_t)shift
;
5661 imm
= (uint32_t)shift
;
5663 tmp2
= tcg_const_i32(imm
);
5664 tmp4
= neon_load_reg(rm
+ 1, 0);
5665 tmp5
= neon_load_reg(rm
+ 1, 1);
5666 for (pass
= 0; pass
< 2; pass
++) {
5668 tmp
= neon_load_reg(rm
, 0);
5672 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5675 tmp3
= neon_load_reg(rm
, 1);
5679 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5681 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5682 tcg_temp_free_i32(tmp
);
5683 tcg_temp_free_i32(tmp3
);
5684 tmp
= tcg_temp_new_i32();
5685 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5686 neon_store_reg(rd
, pass
, tmp
);
5688 tcg_temp_free_i32(tmp2
);
5690 } else if (op
== 10) {
5692 if (q
|| (rd
& 1)) {
5695 tmp
= neon_load_reg(rm
, 0);
5696 tmp2
= neon_load_reg(rm
, 1);
5697 for (pass
= 0; pass
< 2; pass
++) {
5701 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5704 /* The shift is less than the width of the source
5705 type, so we can just shift the whole register. */
5706 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5707 /* Widen the result of shift: we need to clear
5708 * the potential overflow bits resulting from
5709 * left bits of the narrow input appearing as
5710 * right bits of left the neighbour narrow
5712 if (size
< 2 || !u
) {
5715 imm
= (0xffu
>> (8 - shift
));
5717 } else if (size
== 1) {
5718 imm
= 0xffff >> (16 - shift
);
5721 imm
= 0xffffffff >> (32 - shift
);
5724 imm64
= imm
| (((uint64_t)imm
) << 32);
5728 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5731 neon_store_reg64(cpu_V0
, rd
+ pass
);
5733 } else if (op
>= 14) {
5734 /* VCVT fixed-point. */
5735 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5738 /* We have already masked out the must-be-1 top bit of imm6,
5739 * hence this 32-shift where the ARM ARM has 64-imm6.
5742 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5743 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, pass
));
5746 gen_vfp_ulto(0, shift
, 1);
5748 gen_vfp_slto(0, shift
, 1);
5751 gen_vfp_toul(0, shift
, 1);
5753 gen_vfp_tosl(0, shift
, 1);
5755 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, pass
));
5760 } else { /* (insn & 0x00380080) == 0 */
5762 if (q
&& (rd
& 1)) {
5766 op
= (insn
>> 8) & 0xf;
5767 /* One register and immediate. */
5768 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5769 invert
= (insn
& (1 << 5)) != 0;
5770 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5771 * We choose to not special-case this and will behave as if a
5772 * valid constant encoding of 0 had been given.
5791 imm
= (imm
<< 8) | (imm
<< 24);
5794 imm
= (imm
<< 8) | 0xff;
5797 imm
= (imm
<< 16) | 0xffff;
5800 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5808 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5809 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5815 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5816 if (op
& 1 && op
< 12) {
5817 tmp
= neon_load_reg(rd
, pass
);
5819 /* The immediate value has already been inverted, so
5821 tcg_gen_andi_i32(tmp
, tmp
, imm
);
5823 tcg_gen_ori_i32(tmp
, tmp
, imm
);
5827 tmp
= tcg_temp_new_i32();
5828 if (op
== 14 && invert
) {
5832 for (n
= 0; n
< 4; n
++) {
5833 if (imm
& (1 << (n
+ (pass
& 1) * 4)))
5834 val
|= 0xff << (n
* 8);
5836 tcg_gen_movi_i32(tmp
, val
);
5838 tcg_gen_movi_i32(tmp
, imm
);
5841 neon_store_reg(rd
, pass
, tmp
);
5844 } else { /* (insn & 0x00800010 == 0x00800000) */
5846 op
= (insn
>> 8) & 0xf;
5847 if ((insn
& (1 << 6)) == 0) {
5848 /* Three registers of different lengths. */
5852 /* undefreq: bit 0 : UNDEF if size != 0
5853 * bit 1 : UNDEF if size == 0
5854 * bit 2 : UNDEF if U == 1
5855 * Note that [1:0] set implies 'always UNDEF'
5858 /* prewiden, src1_wide, src2_wide, undefreq */
5859 static const int neon_3reg_wide
[16][4] = {
5860 {1, 0, 0, 0}, /* VADDL */
5861 {1, 1, 0, 0}, /* VADDW */
5862 {1, 0, 0, 0}, /* VSUBL */
5863 {1, 1, 0, 0}, /* VSUBW */
5864 {0, 1, 1, 0}, /* VADDHN */
5865 {0, 0, 0, 0}, /* VABAL */
5866 {0, 1, 1, 0}, /* VSUBHN */
5867 {0, 0, 0, 0}, /* VABDL */
5868 {0, 0, 0, 0}, /* VMLAL */
5869 {0, 0, 0, 6}, /* VQDMLAL */
5870 {0, 0, 0, 0}, /* VMLSL */
5871 {0, 0, 0, 6}, /* VQDMLSL */
5872 {0, 0, 0, 0}, /* Integer VMULL */
5873 {0, 0, 0, 2}, /* VQDMULL */
5874 {0, 0, 0, 5}, /* Polynomial VMULL */
5875 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5878 prewiden
= neon_3reg_wide
[op
][0];
5879 src1_wide
= neon_3reg_wide
[op
][1];
5880 src2_wide
= neon_3reg_wide
[op
][2];
5881 undefreq
= neon_3reg_wide
[op
][3];
5883 if (((undefreq
& 1) && (size
!= 0)) ||
5884 ((undefreq
& 2) && (size
== 0)) ||
5885 ((undefreq
& 4) && u
)) {
5888 if ((src1_wide
&& (rn
& 1)) ||
5889 (src2_wide
&& (rm
& 1)) ||
5890 (!src2_wide
&& (rd
& 1))) {
5894 /* Avoid overlapping operands. Wide source operands are
5895 always aligned so will never overlap with wide
5896 destinations in problematic ways. */
5897 if (rd
== rm
&& !src2_wide
) {
5898 tmp
= neon_load_reg(rm
, 1);
5899 neon_store_scratch(2, tmp
);
5900 } else if (rd
== rn
&& !src1_wide
) {
5901 tmp
= neon_load_reg(rn
, 1);
5902 neon_store_scratch(2, tmp
);
5904 TCGV_UNUSED_I32(tmp3
);
5905 for (pass
= 0; pass
< 2; pass
++) {
5907 neon_load_reg64(cpu_V0
, rn
+ pass
);
5908 TCGV_UNUSED_I32(tmp
);
5910 if (pass
== 1 && rd
== rn
) {
5911 tmp
= neon_load_scratch(2);
5913 tmp
= neon_load_reg(rn
, pass
);
5916 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5920 neon_load_reg64(cpu_V1
, rm
+ pass
);
5921 TCGV_UNUSED_I32(tmp2
);
5923 if (pass
== 1 && rd
== rm
) {
5924 tmp2
= neon_load_scratch(2);
5926 tmp2
= neon_load_reg(rm
, pass
);
5929 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5933 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5934 gen_neon_addl(size
);
5936 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5937 gen_neon_subl(size
);
5939 case 5: case 7: /* VABAL, VABDL */
5940 switch ((size
<< 1) | u
) {
5942 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5945 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5948 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5951 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5954 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5957 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5961 tcg_temp_free_i32(tmp2
);
5962 tcg_temp_free_i32(tmp
);
5964 case 8: case 9: case 10: case 11: case 12: case 13:
5965 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5966 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5968 case 14: /* Polynomial VMULL */
5969 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5970 tcg_temp_free_i32(tmp2
);
5971 tcg_temp_free_i32(tmp
);
5973 default: /* 15 is RESERVED: caught earlier */
5978 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5979 neon_store_reg64(cpu_V0
, rd
+ pass
);
5980 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5982 neon_load_reg64(cpu_V1
, rd
+ pass
);
5984 case 10: /* VMLSL */
5985 gen_neon_negl(cpu_V0
, size
);
5987 case 5: case 8: /* VABAL, VMLAL */
5988 gen_neon_addl(size
);
5990 case 9: case 11: /* VQDMLAL, VQDMLSL */
5991 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5993 gen_neon_negl(cpu_V0
, size
);
5995 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6000 neon_store_reg64(cpu_V0
, rd
+ pass
);
6001 } else if (op
== 4 || op
== 6) {
6002 /* Narrowing operation. */
6003 tmp
= tcg_temp_new_i32();
6007 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6010 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6013 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6014 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6021 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6024 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6027 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6028 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6029 tcg_gen_trunc_i64_i32(tmp
, cpu_V0
);
6037 neon_store_reg(rd
, 0, tmp3
);
6038 neon_store_reg(rd
, 1, tmp
);
6041 /* Write back the result. */
6042 neon_store_reg64(cpu_V0
, rd
+ pass
);
6046 /* Two registers and a scalar. NB that for ops of this form
6047 * the ARM ARM labels bit 24 as Q, but it is in our variable
6054 case 1: /* Float VMLA scalar */
6055 case 5: /* Floating point VMLS scalar */
6056 case 9: /* Floating point VMUL scalar */
6061 case 0: /* Integer VMLA scalar */
6062 case 4: /* Integer VMLS scalar */
6063 case 8: /* Integer VMUL scalar */
6064 case 12: /* VQDMULH scalar */
6065 case 13: /* VQRDMULH scalar */
6066 if (u
&& ((rd
| rn
) & 1)) {
6069 tmp
= neon_get_scalar(size
, rm
);
6070 neon_store_scratch(0, tmp
);
6071 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6072 tmp
= neon_load_scratch(0);
6073 tmp2
= neon_load_reg(rn
, pass
);
6076 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6078 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6080 } else if (op
== 13) {
6082 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6084 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6086 } else if (op
& 1) {
6087 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6088 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6089 tcg_temp_free_ptr(fpstatus
);
6092 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6093 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6094 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6098 tcg_temp_free_i32(tmp2
);
6101 tmp2
= neon_load_reg(rd
, pass
);
6104 gen_neon_add(size
, tmp
, tmp2
);
6108 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6109 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6110 tcg_temp_free_ptr(fpstatus
);
6114 gen_neon_rsb(size
, tmp
, tmp2
);
6118 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6119 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6120 tcg_temp_free_ptr(fpstatus
);
6126 tcg_temp_free_i32(tmp2
);
6128 neon_store_reg(rd
, pass
, tmp
);
6131 case 3: /* VQDMLAL scalar */
6132 case 7: /* VQDMLSL scalar */
6133 case 11: /* VQDMULL scalar */
6138 case 2: /* VMLAL sclar */
6139 case 6: /* VMLSL scalar */
6140 case 10: /* VMULL scalar */
6144 tmp2
= neon_get_scalar(size
, rm
);
6145 /* We need a copy of tmp2 because gen_neon_mull
6146 * deletes it during pass 0. */
6147 tmp4
= tcg_temp_new_i32();
6148 tcg_gen_mov_i32(tmp4
, tmp2
);
6149 tmp3
= neon_load_reg(rn
, 1);
6151 for (pass
= 0; pass
< 2; pass
++) {
6153 tmp
= neon_load_reg(rn
, 0);
6158 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6160 neon_load_reg64(cpu_V1
, rd
+ pass
);
6164 gen_neon_negl(cpu_V0
, size
);
6167 gen_neon_addl(size
);
6170 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6172 gen_neon_negl(cpu_V0
, size
);
6174 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6180 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6185 neon_store_reg64(cpu_V0
, rd
+ pass
);
6190 default: /* 14 and 15 are RESERVED */
6194 } else { /* size == 3 */
6197 imm
= (insn
>> 8) & 0xf;
6202 if (q
&& ((rd
| rn
| rm
) & 1)) {
6207 neon_load_reg64(cpu_V0
, rn
);
6209 neon_load_reg64(cpu_V1
, rn
+ 1);
6211 } else if (imm
== 8) {
6212 neon_load_reg64(cpu_V0
, rn
+ 1);
6214 neon_load_reg64(cpu_V1
, rm
);
6217 tmp64
= tcg_temp_new_i64();
6219 neon_load_reg64(cpu_V0
, rn
);
6220 neon_load_reg64(tmp64
, rn
+ 1);
6222 neon_load_reg64(cpu_V0
, rn
+ 1);
6223 neon_load_reg64(tmp64
, rm
);
6225 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6226 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6227 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6229 neon_load_reg64(cpu_V1
, rm
);
6231 neon_load_reg64(cpu_V1
, rm
+ 1);
6234 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6235 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6236 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6237 tcg_temp_free_i64(tmp64
);
6240 neon_load_reg64(cpu_V0
, rn
);
6241 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6242 neon_load_reg64(cpu_V1
, rm
);
6243 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6244 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6246 neon_store_reg64(cpu_V0
, rd
);
6248 neon_store_reg64(cpu_V1
, rd
+ 1);
6250 } else if ((insn
& (1 << 11)) == 0) {
6251 /* Two register misc. */
6252 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6253 size
= (insn
>> 18) & 3;
6254 /* UNDEF for unknown op values and bad op-size combinations */
6255 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6258 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6259 q
&& ((rm
| rd
) & 1)) {
6263 case NEON_2RM_VREV64
:
6264 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6265 tmp
= neon_load_reg(rm
, pass
* 2);
6266 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6268 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6269 case 1: gen_swap_half(tmp
); break;
6270 case 2: /* no-op */ break;
6273 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6275 neon_store_reg(rd
, pass
* 2, tmp2
);
6278 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6279 case 1: gen_swap_half(tmp2
); break;
6282 neon_store_reg(rd
, pass
* 2, tmp2
);
6286 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6287 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6288 for (pass
= 0; pass
< q
+ 1; pass
++) {
6289 tmp
= neon_load_reg(rm
, pass
* 2);
6290 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6291 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6292 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6294 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6295 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6296 case 2: tcg_gen_add_i64(CPU_V001
); break;
6299 if (op
>= NEON_2RM_VPADAL
) {
6301 neon_load_reg64(cpu_V1
, rd
+ pass
);
6302 gen_neon_addl(size
);
6304 neon_store_reg64(cpu_V0
, rd
+ pass
);
6310 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6311 tmp
= neon_load_reg(rm
, n
);
6312 tmp2
= neon_load_reg(rd
, n
+ 1);
6313 neon_store_reg(rm
, n
, tmp2
);
6314 neon_store_reg(rd
, n
+ 1, tmp
);
6321 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6326 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6330 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6331 /* also VQMOVUN; op field and mnemonics don't line up */
6335 TCGV_UNUSED_I32(tmp2
);
6336 for (pass
= 0; pass
< 2; pass
++) {
6337 neon_load_reg64(cpu_V0
, rm
+ pass
);
6338 tmp
= tcg_temp_new_i32();
6339 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6344 neon_store_reg(rd
, 0, tmp2
);
6345 neon_store_reg(rd
, 1, tmp
);
6349 case NEON_2RM_VSHLL
:
6350 if (q
|| (rd
& 1)) {
6353 tmp
= neon_load_reg(rm
, 0);
6354 tmp2
= neon_load_reg(rm
, 1);
6355 for (pass
= 0; pass
< 2; pass
++) {
6358 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6359 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6360 neon_store_reg64(cpu_V0
, rd
+ pass
);
6363 case NEON_2RM_VCVT_F16_F32
:
6364 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6368 tmp
= tcg_temp_new_i32();
6369 tmp2
= tcg_temp_new_i32();
6370 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 0));
6371 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6372 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 1));
6373 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6374 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6375 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6376 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 2));
6377 gen_helper_neon_fcvt_f32_to_f16(tmp
, cpu_F0s
, cpu_env
);
6378 tcg_gen_ld_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rm
, 3));
6379 neon_store_reg(rd
, 0, tmp2
);
6380 tmp2
= tcg_temp_new_i32();
6381 gen_helper_neon_fcvt_f32_to_f16(tmp2
, cpu_F0s
, cpu_env
);
6382 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6383 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6384 neon_store_reg(rd
, 1, tmp2
);
6385 tcg_temp_free_i32(tmp
);
6387 case NEON_2RM_VCVT_F32_F16
:
6388 if (!arm_feature(env
, ARM_FEATURE_VFP_FP16
) ||
6392 tmp3
= tcg_temp_new_i32();
6393 tmp
= neon_load_reg(rm
, 0);
6394 tmp2
= neon_load_reg(rm
, 1);
6395 tcg_gen_ext16u_i32(tmp3
, tmp
);
6396 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6397 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 0));
6398 tcg_gen_shri_i32(tmp3
, tmp
, 16);
6399 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6400 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 1));
6401 tcg_temp_free_i32(tmp
);
6402 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6403 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6404 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 2));
6405 tcg_gen_shri_i32(tmp3
, tmp2
, 16);
6406 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s
, tmp3
, cpu_env
);
6407 tcg_gen_st_f32(cpu_F0s
, cpu_env
, neon_reg_offset(rd
, 3));
6408 tcg_temp_free_i32(tmp2
);
6409 tcg_temp_free_i32(tmp3
);
6411 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6412 if (!arm_feature(env
, ARM_FEATURE_V8_AES
)
6413 || ((rm
| rd
) & 1)) {
6416 tmp
= tcg_const_i32(rd
);
6417 tmp2
= tcg_const_i32(rm
);
6419 /* Bit 6 is the lowest opcode bit; it distinguishes between
6420 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6422 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6424 if (op
== NEON_2RM_AESE
) {
6425 gen_helper_crypto_aese(cpu_env
, tmp
, tmp2
, tmp3
);
6427 gen_helper_crypto_aesmc(cpu_env
, tmp
, tmp2
, tmp3
);
6429 tcg_temp_free_i32(tmp
);
6430 tcg_temp_free_i32(tmp2
);
6431 tcg_temp_free_i32(tmp3
);
6435 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6436 if (neon_2rm_is_float_op(op
)) {
6437 tcg_gen_ld_f32(cpu_F0s
, cpu_env
,
6438 neon_reg_offset(rm
, pass
));
6439 TCGV_UNUSED_I32(tmp
);
6441 tmp
= neon_load_reg(rm
, pass
);
6444 case NEON_2RM_VREV32
:
6446 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6447 case 1: gen_swap_half(tmp
); break;
6451 case NEON_2RM_VREV16
:
6456 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6457 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6458 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6464 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6465 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6466 case 2: gen_helper_clz(tmp
, tmp
); break;
6471 gen_helper_neon_cnt_u8(tmp
, tmp
);
6474 tcg_gen_not_i32(tmp
, tmp
);
6476 case NEON_2RM_VQABS
:
6479 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6482 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6485 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6490 case NEON_2RM_VQNEG
:
6493 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6496 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6499 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6504 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6505 tmp2
= tcg_const_i32(0);
6507 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6508 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6509 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6512 tcg_temp_free_i32(tmp2
);
6513 if (op
== NEON_2RM_VCLE0
) {
6514 tcg_gen_not_i32(tmp
, tmp
);
6517 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6518 tmp2
= tcg_const_i32(0);
6520 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6521 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6522 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6525 tcg_temp_free_i32(tmp2
);
6526 if (op
== NEON_2RM_VCLT0
) {
6527 tcg_gen_not_i32(tmp
, tmp
);
6530 case NEON_2RM_VCEQ0
:
6531 tmp2
= tcg_const_i32(0);
6533 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6534 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6535 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6538 tcg_temp_free_i32(tmp2
);
6542 case 0: gen_helper_neon_abs_s8(tmp
, tmp
); break;
6543 case 1: gen_helper_neon_abs_s16(tmp
, tmp
); break;
6544 case 2: tcg_gen_abs_i32(tmp
, tmp
); break;
6549 tmp2
= tcg_const_i32(0);
6550 gen_neon_rsb(size
, tmp
, tmp2
);
6551 tcg_temp_free_i32(tmp2
);
6553 case NEON_2RM_VCGT0_F
:
6555 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6556 tmp2
= tcg_const_i32(0);
6557 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6558 tcg_temp_free_i32(tmp2
);
6559 tcg_temp_free_ptr(fpstatus
);
6562 case NEON_2RM_VCGE0_F
:
6564 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6565 tmp2
= tcg_const_i32(0);
6566 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6567 tcg_temp_free_i32(tmp2
);
6568 tcg_temp_free_ptr(fpstatus
);
6571 case NEON_2RM_VCEQ0_F
:
6573 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6574 tmp2
= tcg_const_i32(0);
6575 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6576 tcg_temp_free_i32(tmp2
);
6577 tcg_temp_free_ptr(fpstatus
);
6580 case NEON_2RM_VCLE0_F
:
6582 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6583 tmp2
= tcg_const_i32(0);
6584 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6585 tcg_temp_free_i32(tmp2
);
6586 tcg_temp_free_ptr(fpstatus
);
6589 case NEON_2RM_VCLT0_F
:
6591 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6592 tmp2
= tcg_const_i32(0);
6593 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6594 tcg_temp_free_i32(tmp2
);
6595 tcg_temp_free_ptr(fpstatus
);
6598 case NEON_2RM_VABS_F
:
6601 case NEON_2RM_VNEG_F
:
6605 tmp2
= neon_load_reg(rd
, pass
);
6606 neon_store_reg(rm
, pass
, tmp2
);
6609 tmp2
= neon_load_reg(rd
, pass
);
6611 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6612 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6615 neon_store_reg(rm
, pass
, tmp2
);
6617 case NEON_2RM_VRINTN
:
6618 case NEON_2RM_VRINTA
:
6619 case NEON_2RM_VRINTM
:
6620 case NEON_2RM_VRINTP
:
6621 case NEON_2RM_VRINTZ
:
6624 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6627 if (op
== NEON_2RM_VRINTZ
) {
6628 rmode
= FPROUNDING_ZERO
;
6630 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6633 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6634 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6636 gen_helper_rints(cpu_F0s
, cpu_F0s
, fpstatus
);
6637 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6639 tcg_temp_free_ptr(fpstatus
);
6640 tcg_temp_free_i32(tcg_rmode
);
6643 case NEON_2RM_VRINTX
:
6645 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6646 gen_helper_rints_exact(cpu_F0s
, cpu_F0s
, fpstatus
);
6647 tcg_temp_free_ptr(fpstatus
);
6650 case NEON_2RM_VCVTAU
:
6651 case NEON_2RM_VCVTAS
:
6652 case NEON_2RM_VCVTNU
:
6653 case NEON_2RM_VCVTNS
:
6654 case NEON_2RM_VCVTPU
:
6655 case NEON_2RM_VCVTPS
:
6656 case NEON_2RM_VCVTMU
:
6657 case NEON_2RM_VCVTMS
:
6659 bool is_signed
= !extract32(insn
, 7, 1);
6660 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6661 TCGv_i32 tcg_rmode
, tcg_shift
;
6662 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6664 tcg_shift
= tcg_const_i32(0);
6665 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6666 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6670 gen_helper_vfp_tosls(cpu_F0s
, cpu_F0s
,
6673 gen_helper_vfp_touls(cpu_F0s
, cpu_F0s
,
6677 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6679 tcg_temp_free_i32(tcg_rmode
);
6680 tcg_temp_free_i32(tcg_shift
);
6681 tcg_temp_free_ptr(fpst
);
6684 case NEON_2RM_VRECPE
:
6686 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6687 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6688 tcg_temp_free_ptr(fpstatus
);
6691 case NEON_2RM_VRSQRTE
:
6692 gen_helper_rsqrte_u32(tmp
, tmp
, cpu_env
);
6694 case NEON_2RM_VRECPE_F
:
6696 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6697 gen_helper_recpe_f32(cpu_F0s
, cpu_F0s
, fpstatus
);
6698 tcg_temp_free_ptr(fpstatus
);
6701 case NEON_2RM_VRSQRTE_F
:
6702 gen_helper_rsqrte_f32(cpu_F0s
, cpu_F0s
, cpu_env
);
6704 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6707 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6710 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6711 gen_vfp_tosiz(0, 1);
6713 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6714 gen_vfp_touiz(0, 1);
6717 /* Reserved op values were caught by the
6718 * neon_2rm_sizes[] check earlier.
6722 if (neon_2rm_is_float_op(op
)) {
6723 tcg_gen_st_f32(cpu_F0s
, cpu_env
,
6724 neon_reg_offset(rd
, pass
));
6726 neon_store_reg(rd
, pass
, tmp
);
6731 } else if ((insn
& (1 << 10)) == 0) {
6733 int n
= ((insn
>> 8) & 3) + 1;
6734 if ((rn
+ n
) > 32) {
6735 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6736 * helper function running off the end of the register file.
6741 if (insn
& (1 << 6)) {
6742 tmp
= neon_load_reg(rd
, 0);
6744 tmp
= tcg_temp_new_i32();
6745 tcg_gen_movi_i32(tmp
, 0);
6747 tmp2
= neon_load_reg(rm
, 0);
6748 tmp4
= tcg_const_i32(rn
);
6749 tmp5
= tcg_const_i32(n
);
6750 gen_helper_neon_tbl(tmp2
, cpu_env
, tmp2
, tmp
, tmp4
, tmp5
);
6751 tcg_temp_free_i32(tmp
);
6752 if (insn
& (1 << 6)) {
6753 tmp
= neon_load_reg(rd
, 1);
6755 tmp
= tcg_temp_new_i32();
6756 tcg_gen_movi_i32(tmp
, 0);
6758 tmp3
= neon_load_reg(rm
, 1);
6759 gen_helper_neon_tbl(tmp3
, cpu_env
, tmp3
, tmp
, tmp4
, tmp5
);
6760 tcg_temp_free_i32(tmp5
);
6761 tcg_temp_free_i32(tmp4
);
6762 neon_store_reg(rd
, 0, tmp2
);
6763 neon_store_reg(rd
, 1, tmp3
);
6764 tcg_temp_free_i32(tmp
);
6765 } else if ((insn
& 0x380) == 0) {
6767 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6770 if (insn
& (1 << 19)) {
6771 tmp
= neon_load_reg(rm
, 1);
6773 tmp
= neon_load_reg(rm
, 0);
6775 if (insn
& (1 << 16)) {
6776 gen_neon_dup_u8(tmp
, ((insn
>> 17) & 3) * 8);
6777 } else if (insn
& (1 << 17)) {
6778 if ((insn
>> 18) & 1)
6779 gen_neon_dup_high16(tmp
);
6781 gen_neon_dup_low16(tmp
);
6783 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6784 tmp2
= tcg_temp_new_i32();
6785 tcg_gen_mov_i32(tmp2
, tmp
);
6786 neon_store_reg(rd
, pass
, tmp2
);
6788 tcg_temp_free_i32(tmp
);
6797 static int disas_coproc_insn(CPUARMState
* env
, DisasContext
*s
, uint32_t insn
)
6799 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6800 const ARMCPRegInfo
*ri
;
6802 cpnum
= (insn
>> 8) & 0xf;
6803 if (arm_feature(env
, ARM_FEATURE_XSCALE
)
6804 && ((env
->cp15
.c15_cpar
^ 0x3fff) & (1 << cpnum
)))
6807 /* First check for coprocessor space used for actual instructions */
6811 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
6812 return disas_iwmmxt_insn(env
, s
, insn
);
6813 } else if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
6814 return disas_dsp_insn(env
, s
, insn
);
6821 /* Otherwise treat as a generic register access */
6822 is64
= (insn
& (1 << 25)) == 0;
6823 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6831 opc1
= (insn
>> 4) & 0xf;
6833 rt2
= (insn
>> 16) & 0xf;
6835 crn
= (insn
>> 16) & 0xf;
6836 opc1
= (insn
>> 21) & 7;
6837 opc2
= (insn
>> 5) & 7;
6840 isread
= (insn
>> 20) & 1;
6841 rt
= (insn
>> 12) & 0xf;
6843 ri
= get_arm_cp_reginfo(s
->cp_regs
,
6844 ENCODE_CP_REG(cpnum
, is64
, crn
, crm
, opc1
, opc2
));
6846 /* Check access permissions */
6847 if (!cp_access_ok(s
->current_pl
, ri
, isread
)) {
6852 /* Emit code to perform further access permissions checks at
6853 * runtime; this may result in an exception.
6856 gen_set_pc_im(s
, s
->pc
);
6857 tmpptr
= tcg_const_ptr(ri
);
6858 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
);
6859 tcg_temp_free_ptr(tmpptr
);
6862 /* Handle special cases first */
6863 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
6870 gen_set_pc_im(s
, s
->pc
);
6871 s
->is_jmp
= DISAS_WFI
;
6877 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6886 if (ri
->type
& ARM_CP_CONST
) {
6887 tmp64
= tcg_const_i64(ri
->resetvalue
);
6888 } else if (ri
->readfn
) {
6890 tmp64
= tcg_temp_new_i64();
6891 tmpptr
= tcg_const_ptr(ri
);
6892 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
6893 tcg_temp_free_ptr(tmpptr
);
6895 tmp64
= tcg_temp_new_i64();
6896 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6898 tmp
= tcg_temp_new_i32();
6899 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6900 store_reg(s
, rt
, tmp
);
6901 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
6902 tmp
= tcg_temp_new_i32();
6903 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
6904 tcg_temp_free_i64(tmp64
);
6905 store_reg(s
, rt2
, tmp
);
6908 if (ri
->type
& ARM_CP_CONST
) {
6909 tmp
= tcg_const_i32(ri
->resetvalue
);
6910 } else if (ri
->readfn
) {
6912 tmp
= tcg_temp_new_i32();
6913 tmpptr
= tcg_const_ptr(ri
);
6914 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
6915 tcg_temp_free_ptr(tmpptr
);
6917 tmp
= load_cpu_offset(ri
->fieldoffset
);
6920 /* Destination register of r15 for 32 bit loads sets
6921 * the condition codes from the high 4 bits of the value
6924 tcg_temp_free_i32(tmp
);
6926 store_reg(s
, rt
, tmp
);
6931 if (ri
->type
& ARM_CP_CONST
) {
6932 /* If not forbidden by access permissions, treat as WI */
6937 TCGv_i32 tmplo
, tmphi
;
6938 TCGv_i64 tmp64
= tcg_temp_new_i64();
6939 tmplo
= load_reg(s
, rt
);
6940 tmphi
= load_reg(s
, rt2
);
6941 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
6942 tcg_temp_free_i32(tmplo
);
6943 tcg_temp_free_i32(tmphi
);
6945 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
6946 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
6947 tcg_temp_free_ptr(tmpptr
);
6949 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
6951 tcg_temp_free_i64(tmp64
);
6956 tmp
= load_reg(s
, rt
);
6957 tmpptr
= tcg_const_ptr(ri
);
6958 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
6959 tcg_temp_free_ptr(tmpptr
);
6960 tcg_temp_free_i32(tmp
);
6962 TCGv_i32 tmp
= load_reg(s
, rt
);
6963 store_cpu_offset(tmp
, ri
->fieldoffset
);
6968 if (use_icount
&& (ri
->type
& ARM_CP_IO
)) {
6969 /* I/O operations must end the TB here (whether read or write) */
6972 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
6973 /* We default to ending the TB on a coprocessor register write,
6974 * but allow this to be suppressed by the register definition
6975 * (usually only necessary to work around guest bugs).
6983 /* Unknown register; this might be a guest error or a QEMU
6984 * unimplemented feature.
6987 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
6988 "64 bit system register cp:%d opc1: %d crm:%d\n",
6989 isread
? "read" : "write", cpnum
, opc1
, crm
);
6991 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
6992 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
6993 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
);
7000 /* Store a 64-bit value to a register pair. Clobbers val. */
7001 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7004 tmp
= tcg_temp_new_i32();
7005 tcg_gen_trunc_i64_i32(tmp
, val
);
7006 store_reg(s
, rlow
, tmp
);
7007 tmp
= tcg_temp_new_i32();
7008 tcg_gen_shri_i64(val
, val
, 32);
7009 tcg_gen_trunc_i64_i32(tmp
, val
);
7010 store_reg(s
, rhigh
, tmp
);
7013 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7014 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7019 /* Load value and extend to 64 bits. */
7020 tmp
= tcg_temp_new_i64();
7021 tmp2
= load_reg(s
, rlow
);
7022 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7023 tcg_temp_free_i32(tmp2
);
7024 tcg_gen_add_i64(val
, val
, tmp
);
7025 tcg_temp_free_i64(tmp
);
7028 /* load and add a 64-bit value from a register pair. */
7029 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7035 /* Load 64-bit value rd:rn. */
7036 tmpl
= load_reg(s
, rlow
);
7037 tmph
= load_reg(s
, rhigh
);
7038 tmp
= tcg_temp_new_i64();
7039 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7040 tcg_temp_free_i32(tmpl
);
7041 tcg_temp_free_i32(tmph
);
7042 tcg_gen_add_i64(val
, val
, tmp
);
7043 tcg_temp_free_i64(tmp
);
7046 /* Set N and Z flags from hi|lo. */
7047 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7049 tcg_gen_mov_i32(cpu_NF
, hi
);
7050 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7053 /* Load/Store exclusive instructions are implemented by remembering
7054 the value/address loaded, and seeing if these are the same
7055 when the store is performed. This should be sufficient to implement
7056 the architecturally mandated semantics, and avoids having to monitor
7059 In system emulation mode only one CPU will be running at once, so
7060 this sequence is effectively atomic. In user emulation mode we
7061 throw an exception and handle the atomic operation elsewhere. */
7062 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7063 TCGv_i32 addr
, int size
)
7065 TCGv_i32 tmp
= tcg_temp_new_i32();
7069 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
7072 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7076 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7083 TCGv_i32 tmp2
= tcg_temp_new_i32();
7084 TCGv_i32 tmp3
= tcg_temp_new_i32();
7086 tcg_gen_addi_i32(tmp2
, addr
, 4);
7087 gen_aa32_ld32u(tmp3
, tmp2
, IS_USER(s
));
7088 tcg_temp_free_i32(tmp2
);
7089 tcg_gen_concat_i32_i64(cpu_exclusive_val
, tmp
, tmp3
);
7090 store_reg(s
, rt2
, tmp3
);
7092 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7095 store_reg(s
, rt
, tmp
);
7096 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7099 static void gen_clrex(DisasContext
*s
)
7101 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7104 #ifdef CONFIG_USER_ONLY
7105 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7106 TCGv_i32 addr
, int size
)
7108 tcg_gen_extu_i32_i64(cpu_exclusive_test
, addr
);
7109 tcg_gen_movi_i32(cpu_exclusive_info
,
7110 size
| (rd
<< 4) | (rt
<< 8) | (rt2
<< 12));
7111 gen_exception_insn(s
, 4, EXCP_STREX
);
7114 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7115 TCGv_i32 addr
, int size
)
7118 TCGv_i64 val64
, extaddr
;
7122 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7128 fail_label
= gen_new_label();
7129 done_label
= gen_new_label();
7130 extaddr
= tcg_temp_new_i64();
7131 tcg_gen_extu_i32_i64(extaddr
, addr
);
7132 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7133 tcg_temp_free_i64(extaddr
);
7135 tmp
= tcg_temp_new_i32();
7138 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
7141 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7145 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7151 val64
= tcg_temp_new_i64();
7153 TCGv_i32 tmp2
= tcg_temp_new_i32();
7154 TCGv_i32 tmp3
= tcg_temp_new_i32();
7155 tcg_gen_addi_i32(tmp2
, addr
, 4);
7156 gen_aa32_ld32u(tmp3
, tmp2
, IS_USER(s
));
7157 tcg_temp_free_i32(tmp2
);
7158 tcg_gen_concat_i32_i64(val64
, tmp
, tmp3
);
7159 tcg_temp_free_i32(tmp3
);
7161 tcg_gen_extu_i32_i64(val64
, tmp
);
7163 tcg_temp_free_i32(tmp
);
7165 tcg_gen_brcond_i64(TCG_COND_NE
, val64
, cpu_exclusive_val
, fail_label
);
7166 tcg_temp_free_i64(val64
);
7168 tmp
= load_reg(s
, rt
);
7171 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
7174 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
7178 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7183 tcg_temp_free_i32(tmp
);
7185 tcg_gen_addi_i32(addr
, addr
, 4);
7186 tmp
= load_reg(s
, rt2
);
7187 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
7188 tcg_temp_free_i32(tmp
);
7190 tcg_gen_movi_i32(cpu_R
[rd
], 0);
7191 tcg_gen_br(done_label
);
7192 gen_set_label(fail_label
);
7193 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7194 gen_set_label(done_label
);
7195 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7202 * @mode: mode field from insn (which stack to store to)
7203 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7204 * @writeback: true if writeback bit set
7206 * Generate code for the SRS (Store Return State) insn.
7208 static void gen_srs(DisasContext
*s
,
7209 uint32_t mode
, uint32_t amode
, bool writeback
)
7212 TCGv_i32 addr
= tcg_temp_new_i32();
7213 TCGv_i32 tmp
= tcg_const_i32(mode
);
7214 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7215 tcg_temp_free_i32(tmp
);
7232 tcg_gen_addi_i32(addr
, addr
, offset
);
7233 tmp
= load_reg(s
, 14);
7234 gen_aa32_st32(tmp
, addr
, 0);
7235 tcg_temp_free_i32(tmp
);
7236 tmp
= load_cpu_field(spsr
);
7237 tcg_gen_addi_i32(addr
, addr
, 4);
7238 gen_aa32_st32(tmp
, addr
, 0);
7239 tcg_temp_free_i32(tmp
);
7257 tcg_gen_addi_i32(addr
, addr
, offset
);
7258 tmp
= tcg_const_i32(mode
);
7259 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7260 tcg_temp_free_i32(tmp
);
7262 tcg_temp_free_i32(addr
);
7265 static void disas_arm_insn(CPUARMState
* env
, DisasContext
*s
)
7267 unsigned int cond
, insn
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7274 insn
= arm_ldl_code(env
, s
->pc
, s
->bswap_code
);
7277 /* M variants do not implement ARM mode. */
7282 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7283 * choose to UNDEF. In ARMv5 and above the space is used
7284 * for miscellaneous unconditional instructions.
7288 /* Unconditional instructions. */
7289 if (((insn
>> 25) & 7) == 1) {
7290 /* NEON Data processing. */
7291 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7294 if (disas_neon_data_insn(env
, s
, insn
))
7298 if ((insn
& 0x0f100000) == 0x04000000) {
7299 /* NEON load/store. */
7300 if (!arm_feature(env
, ARM_FEATURE_NEON
))
7303 if (disas_neon_ls_insn(env
, s
, insn
))
7307 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7309 if (disas_vfp_insn(env
, s
, insn
)) {
7314 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7315 ((insn
& 0x0f30f010) == 0x0710f000)) {
7316 if ((insn
& (1 << 22)) == 0) {
7318 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7322 /* Otherwise PLD; v5TE+ */
7326 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7327 ((insn
& 0x0f70f010) == 0x0650f000)) {
7329 return; /* PLI; V7 */
7331 if (((insn
& 0x0f700000) == 0x04100000) ||
7332 ((insn
& 0x0f700010) == 0x06100000)) {
7333 if (!arm_feature(env
, ARM_FEATURE_V7MP
)) {
7336 return; /* v7MP: Unallocated memory hint: must NOP */
7339 if ((insn
& 0x0ffffdff) == 0x01010000) {
7342 if (((insn
>> 9) & 1) != s
->bswap_code
) {
7343 /* Dynamic endianness switching not implemented. */
7344 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
7348 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7349 switch ((insn
>> 4) & 0xf) {
7358 /* We don't emulate caches so these are a no-op. */
7363 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7369 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7371 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7377 rn
= (insn
>> 16) & 0xf;
7378 addr
= load_reg(s
, rn
);
7379 i
= (insn
>> 23) & 3;
7381 case 0: offset
= -4; break; /* DA */
7382 case 1: offset
= 0; break; /* IA */
7383 case 2: offset
= -8; break; /* DB */
7384 case 3: offset
= 4; break; /* IB */
7388 tcg_gen_addi_i32(addr
, addr
, offset
);
7389 /* Load PC into tmp and CPSR into tmp2. */
7390 tmp
= tcg_temp_new_i32();
7391 gen_aa32_ld32u(tmp
, addr
, 0);
7392 tcg_gen_addi_i32(addr
, addr
, 4);
7393 tmp2
= tcg_temp_new_i32();
7394 gen_aa32_ld32u(tmp2
, addr
, 0);
7395 if (insn
& (1 << 21)) {
7396 /* Base writeback. */
7398 case 0: offset
= -8; break;
7399 case 1: offset
= 4; break;
7400 case 2: offset
= -4; break;
7401 case 3: offset
= 0; break;
7405 tcg_gen_addi_i32(addr
, addr
, offset
);
7406 store_reg(s
, rn
, addr
);
7408 tcg_temp_free_i32(addr
);
7410 gen_rfe(s
, tmp
, tmp2
);
7412 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7413 /* branch link and change to thumb (blx <offset>) */
7416 val
= (uint32_t)s
->pc
;
7417 tmp
= tcg_temp_new_i32();
7418 tcg_gen_movi_i32(tmp
, val
);
7419 store_reg(s
, 14, tmp
);
7420 /* Sign-extend the 24-bit offset */
7421 offset
= (((int32_t)insn
) << 8) >> 8;
7422 /* offset * 4 + bit24 * 2 + (thumb bit) */
7423 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7424 /* pipeline offset */
7426 /* protected by ARCH(5); above, near the start of uncond block */
7429 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7430 if (arm_feature(env
, ARM_FEATURE_IWMMXT
)) {
7431 /* iWMMXt register transfer. */
7432 if (env
->cp15
.c15_cpar
& (1 << 1))
7433 if (!disas_iwmmxt_insn(env
, s
, insn
))
7436 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7437 /* Coprocessor double register transfer. */
7439 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7440 /* Additional coprocessor register transfer. */
7441 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7444 /* cps (privileged) */
7448 if (insn
& (1 << 19)) {
7449 if (insn
& (1 << 8))
7451 if (insn
& (1 << 7))
7453 if (insn
& (1 << 6))
7455 if (insn
& (1 << 18))
7458 if (insn
& (1 << 17)) {
7460 val
|= (insn
& 0x1f);
7463 gen_set_psr_im(s
, mask
, 0, val
);
7470 /* if not always execute, we generate a conditional jump to
7472 s
->condlabel
= gen_new_label();
7473 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7476 if ((insn
& 0x0f900000) == 0x03000000) {
7477 if ((insn
& (1 << 21)) == 0) {
7479 rd
= (insn
>> 12) & 0xf;
7480 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7481 if ((insn
& (1 << 22)) == 0) {
7483 tmp
= tcg_temp_new_i32();
7484 tcg_gen_movi_i32(tmp
, val
);
7487 tmp
= load_reg(s
, rd
);
7488 tcg_gen_ext16u_i32(tmp
, tmp
);
7489 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7491 store_reg(s
, rd
, tmp
);
7493 if (((insn
>> 12) & 0xf) != 0xf)
7495 if (((insn
>> 16) & 0xf) == 0) {
7496 gen_nop_hint(s
, insn
& 0xff);
7498 /* CPSR = immediate */
7500 shift
= ((insn
>> 8) & 0xf) * 2;
7502 val
= (val
>> shift
) | (val
<< (32 - shift
));
7503 i
= ((insn
& (1 << 22)) != 0);
7504 if (gen_set_psr_im(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, val
))
7508 } else if ((insn
& 0x0f900000) == 0x01000000
7509 && (insn
& 0x00000090) != 0x00000090) {
7510 /* miscellaneous instructions */
7511 op1
= (insn
>> 21) & 3;
7512 sh
= (insn
>> 4) & 0xf;
7515 case 0x0: /* move program status register */
7518 tmp
= load_reg(s
, rm
);
7519 i
= ((op1
& 2) != 0);
7520 if (gen_set_psr(s
, msr_mask(env
, s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7524 rd
= (insn
>> 12) & 0xf;
7528 tmp
= load_cpu_field(spsr
);
7530 tmp
= tcg_temp_new_i32();
7531 gen_helper_cpsr_read(tmp
, cpu_env
);
7533 store_reg(s
, rd
, tmp
);
7538 /* branch/exchange thumb (bx). */
7540 tmp
= load_reg(s
, rm
);
7542 } else if (op1
== 3) {
7545 rd
= (insn
>> 12) & 0xf;
7546 tmp
= load_reg(s
, rm
);
7547 gen_helper_clz(tmp
, tmp
);
7548 store_reg(s
, rd
, tmp
);
7556 /* Trivial implementation equivalent to bx. */
7557 tmp
= load_reg(s
, rm
);
7568 /* branch link/exchange thumb (blx) */
7569 tmp
= load_reg(s
, rm
);
7570 tmp2
= tcg_temp_new_i32();
7571 tcg_gen_movi_i32(tmp2
, s
->pc
);
7572 store_reg(s
, 14, tmp2
);
7578 uint32_t c
= extract32(insn
, 8, 4);
7580 /* Check this CPU supports ARMv8 CRC instructions.
7581 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7582 * Bits 8, 10 and 11 should be zero.
7584 if (!arm_feature(env
, ARM_FEATURE_CRC
) || op1
== 0x3 ||
7589 rn
= extract32(insn
, 16, 4);
7590 rd
= extract32(insn
, 12, 4);
7592 tmp
= load_reg(s
, rn
);
7593 tmp2
= load_reg(s
, rm
);
7594 tmp3
= tcg_const_i32(1 << op1
);
7596 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
7598 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
7600 tcg_temp_free_i32(tmp2
);
7601 tcg_temp_free_i32(tmp3
);
7602 store_reg(s
, rd
, tmp
);
7605 case 0x5: /* saturating add/subtract */
7607 rd
= (insn
>> 12) & 0xf;
7608 rn
= (insn
>> 16) & 0xf;
7609 tmp
= load_reg(s
, rm
);
7610 tmp2
= load_reg(s
, rn
);
7612 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
7614 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7616 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
7617 tcg_temp_free_i32(tmp2
);
7618 store_reg(s
, rd
, tmp
);
7621 /* SMC instruction (op1 == 3)
7622 and undefined instructions (op1 == 0 || op1 == 2)
7629 gen_exception_insn(s
, 4, EXCP_BKPT
);
7631 case 0x8: /* signed multiply */
7636 rs
= (insn
>> 8) & 0xf;
7637 rn
= (insn
>> 12) & 0xf;
7638 rd
= (insn
>> 16) & 0xf;
7640 /* (32 * 16) >> 16 */
7641 tmp
= load_reg(s
, rm
);
7642 tmp2
= load_reg(s
, rs
);
7644 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
7647 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
7648 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
7649 tmp
= tcg_temp_new_i32();
7650 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
7651 tcg_temp_free_i64(tmp64
);
7652 if ((sh
& 2) == 0) {
7653 tmp2
= load_reg(s
, rn
);
7654 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7655 tcg_temp_free_i32(tmp2
);
7657 store_reg(s
, rd
, tmp
);
7660 tmp
= load_reg(s
, rm
);
7661 tmp2
= load_reg(s
, rs
);
7662 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
7663 tcg_temp_free_i32(tmp2
);
7665 tmp64
= tcg_temp_new_i64();
7666 tcg_gen_ext_i32_i64(tmp64
, tmp
);
7667 tcg_temp_free_i32(tmp
);
7668 gen_addq(s
, tmp64
, rn
, rd
);
7669 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7670 tcg_temp_free_i64(tmp64
);
7673 tmp2
= load_reg(s
, rn
);
7674 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
7675 tcg_temp_free_i32(tmp2
);
7677 store_reg(s
, rd
, tmp
);
7684 } else if (((insn
& 0x0e000000) == 0 &&
7685 (insn
& 0x00000090) != 0x90) ||
7686 ((insn
& 0x0e000000) == (1 << 25))) {
7687 int set_cc
, logic_cc
, shiftop
;
7689 op1
= (insn
>> 21) & 0xf;
7690 set_cc
= (insn
>> 20) & 1;
7691 logic_cc
= table_logic_cc
[op1
] & set_cc
;
7693 /* data processing instruction */
7694 if (insn
& (1 << 25)) {
7695 /* immediate operand */
7697 shift
= ((insn
>> 8) & 0xf) * 2;
7699 val
= (val
>> shift
) | (val
<< (32 - shift
));
7701 tmp2
= tcg_temp_new_i32();
7702 tcg_gen_movi_i32(tmp2
, val
);
7703 if (logic_cc
&& shift
) {
7704 gen_set_CF_bit31(tmp2
);
7709 tmp2
= load_reg(s
, rm
);
7710 shiftop
= (insn
>> 5) & 3;
7711 if (!(insn
& (1 << 4))) {
7712 shift
= (insn
>> 7) & 0x1f;
7713 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
7715 rs
= (insn
>> 8) & 0xf;
7716 tmp
= load_reg(s
, rs
);
7717 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
7720 if (op1
!= 0x0f && op1
!= 0x0d) {
7721 rn
= (insn
>> 16) & 0xf;
7722 tmp
= load_reg(s
, rn
);
7724 TCGV_UNUSED_I32(tmp
);
7726 rd
= (insn
>> 12) & 0xf;
7729 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7733 store_reg_bx(env
, s
, rd
, tmp
);
7736 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7740 store_reg_bx(env
, s
, rd
, tmp
);
7743 if (set_cc
&& rd
== 15) {
7744 /* SUBS r15, ... is used for exception return. */
7748 gen_sub_CC(tmp
, tmp
, tmp2
);
7749 gen_exception_return(s
, tmp
);
7752 gen_sub_CC(tmp
, tmp
, tmp2
);
7754 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
7756 store_reg_bx(env
, s
, rd
, tmp
);
7761 gen_sub_CC(tmp
, tmp2
, tmp
);
7763 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7765 store_reg_bx(env
, s
, rd
, tmp
);
7769 gen_add_CC(tmp
, tmp
, tmp2
);
7771 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7773 store_reg_bx(env
, s
, rd
, tmp
);
7777 gen_adc_CC(tmp
, tmp
, tmp2
);
7779 gen_add_carry(tmp
, tmp
, tmp2
);
7781 store_reg_bx(env
, s
, rd
, tmp
);
7785 gen_sbc_CC(tmp
, tmp
, tmp2
);
7787 gen_sub_carry(tmp
, tmp
, tmp2
);
7789 store_reg_bx(env
, s
, rd
, tmp
);
7793 gen_sbc_CC(tmp
, tmp2
, tmp
);
7795 gen_sub_carry(tmp
, tmp2
, tmp
);
7797 store_reg_bx(env
, s
, rd
, tmp
);
7801 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
7804 tcg_temp_free_i32(tmp
);
7808 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
7811 tcg_temp_free_i32(tmp
);
7815 gen_sub_CC(tmp
, tmp
, tmp2
);
7817 tcg_temp_free_i32(tmp
);
7821 gen_add_CC(tmp
, tmp
, tmp2
);
7823 tcg_temp_free_i32(tmp
);
7826 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
7830 store_reg_bx(env
, s
, rd
, tmp
);
7833 if (logic_cc
&& rd
== 15) {
7834 /* MOVS r15, ... is used for exception return. */
7838 gen_exception_return(s
, tmp2
);
7843 store_reg_bx(env
, s
, rd
, tmp2
);
7847 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
7851 store_reg_bx(env
, s
, rd
, tmp
);
7855 tcg_gen_not_i32(tmp2
, tmp2
);
7859 store_reg_bx(env
, s
, rd
, tmp2
);
7862 if (op1
!= 0x0f && op1
!= 0x0d) {
7863 tcg_temp_free_i32(tmp2
);
7866 /* other instructions */
7867 op1
= (insn
>> 24) & 0xf;
7871 /* multiplies, extra load/stores */
7872 sh
= (insn
>> 5) & 3;
7875 rd
= (insn
>> 16) & 0xf;
7876 rn
= (insn
>> 12) & 0xf;
7877 rs
= (insn
>> 8) & 0xf;
7879 op1
= (insn
>> 20) & 0xf;
7881 case 0: case 1: case 2: case 3: case 6:
7883 tmp
= load_reg(s
, rs
);
7884 tmp2
= load_reg(s
, rm
);
7885 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
7886 tcg_temp_free_i32(tmp2
);
7887 if (insn
& (1 << 22)) {
7888 /* Subtract (mls) */
7890 tmp2
= load_reg(s
, rn
);
7891 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
7892 tcg_temp_free_i32(tmp2
);
7893 } else if (insn
& (1 << 21)) {
7895 tmp2
= load_reg(s
, rn
);
7896 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
7897 tcg_temp_free_i32(tmp2
);
7899 if (insn
& (1 << 20))
7901 store_reg(s
, rd
, tmp
);
7904 /* 64 bit mul double accumulate (UMAAL) */
7906 tmp
= load_reg(s
, rs
);
7907 tmp2
= load_reg(s
, rm
);
7908 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
7909 gen_addq_lo(s
, tmp64
, rn
);
7910 gen_addq_lo(s
, tmp64
, rd
);
7911 gen_storeq_reg(s
, rn
, rd
, tmp64
);
7912 tcg_temp_free_i64(tmp64
);
7914 case 8: case 9: case 10: case 11:
7915 case 12: case 13: case 14: case 15:
7916 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7917 tmp
= load_reg(s
, rs
);
7918 tmp2
= load_reg(s
, rm
);
7919 if (insn
& (1 << 22)) {
7920 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
7922 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
7924 if (insn
& (1 << 21)) { /* mult accumulate */
7925 TCGv_i32 al
= load_reg(s
, rn
);
7926 TCGv_i32 ah
= load_reg(s
, rd
);
7927 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
7928 tcg_temp_free_i32(al
);
7929 tcg_temp_free_i32(ah
);
7931 if (insn
& (1 << 20)) {
7932 gen_logicq_cc(tmp
, tmp2
);
7934 store_reg(s
, rn
, tmp
);
7935 store_reg(s
, rd
, tmp2
);
7941 rn
= (insn
>> 16) & 0xf;
7942 rd
= (insn
>> 12) & 0xf;
7943 if (insn
& (1 << 23)) {
7944 /* load/store exclusive */
7945 int op2
= (insn
>> 8) & 3;
7946 op1
= (insn
>> 21) & 0x3;
7949 case 0: /* lda/stl */
7955 case 1: /* reserved */
7957 case 2: /* ldaex/stlex */
7960 case 3: /* ldrex/strex */
7969 addr
= tcg_temp_local_new_i32();
7970 load_reg_var(s
, addr
, rn
);
7972 /* Since the emulation does not have barriers,
7973 the acquire/release semantics need no special
7976 if (insn
& (1 << 20)) {
7977 tmp
= tcg_temp_new_i32();
7980 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
7983 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
7986 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
7991 store_reg(s
, rd
, tmp
);
7994 tmp
= load_reg(s
, rm
);
7997 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8000 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
8003 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
8008 tcg_temp_free_i32(tmp
);
8010 } else if (insn
& (1 << 20)) {
8013 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8015 case 1: /* ldrexd */
8016 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8018 case 2: /* ldrexb */
8019 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8021 case 3: /* ldrexh */
8022 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8031 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8033 case 1: /* strexd */
8034 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8036 case 2: /* strexb */
8037 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8039 case 3: /* strexh */
8040 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8046 tcg_temp_free_i32(addr
);
8048 /* SWP instruction */
8051 /* ??? This is not really atomic. However we know
8052 we never have multiple CPUs running in parallel,
8053 so it is good enough. */
8054 addr
= load_reg(s
, rn
);
8055 tmp
= load_reg(s
, rm
);
8056 tmp2
= tcg_temp_new_i32();
8057 if (insn
& (1 << 22)) {
8058 gen_aa32_ld8u(tmp2
, addr
, IS_USER(s
));
8059 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
8061 gen_aa32_ld32u(tmp2
, addr
, IS_USER(s
));
8062 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8064 tcg_temp_free_i32(tmp
);
8065 tcg_temp_free_i32(addr
);
8066 store_reg(s
, rd
, tmp2
);
8072 /* Misc load/store */
8073 rn
= (insn
>> 16) & 0xf;
8074 rd
= (insn
>> 12) & 0xf;
8075 addr
= load_reg(s
, rn
);
8076 if (insn
& (1 << 24))
8077 gen_add_datah_offset(s
, insn
, 0, addr
);
8079 if (insn
& (1 << 20)) {
8081 tmp
= tcg_temp_new_i32();
8084 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8087 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
8091 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
8095 } else if (sh
& 2) {
8100 tmp
= load_reg(s
, rd
);
8101 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8102 tcg_temp_free_i32(tmp
);
8103 tcg_gen_addi_i32(addr
, addr
, 4);
8104 tmp
= load_reg(s
, rd
+ 1);
8105 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8106 tcg_temp_free_i32(tmp
);
8110 tmp
= tcg_temp_new_i32();
8111 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8112 store_reg(s
, rd
, tmp
);
8113 tcg_gen_addi_i32(addr
, addr
, 4);
8114 tmp
= tcg_temp_new_i32();
8115 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8119 address_offset
= -4;
8122 tmp
= load_reg(s
, rd
);
8123 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
8124 tcg_temp_free_i32(tmp
);
8127 /* Perform base writeback before the loaded value to
8128 ensure correct behavior with overlapping index registers.
8129 ldrd with base writeback is is undefined if the
8130 destination and index registers overlap. */
8131 if (!(insn
& (1 << 24))) {
8132 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8133 store_reg(s
, rn
, addr
);
8134 } else if (insn
& (1 << 21)) {
8136 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8137 store_reg(s
, rn
, addr
);
8139 tcg_temp_free_i32(addr
);
8142 /* Complete the load. */
8143 store_reg(s
, rd
, tmp
);
8152 if (insn
& (1 << 4)) {
8154 /* Armv6 Media instructions. */
8156 rn
= (insn
>> 16) & 0xf;
8157 rd
= (insn
>> 12) & 0xf;
8158 rs
= (insn
>> 8) & 0xf;
8159 switch ((insn
>> 23) & 3) {
8160 case 0: /* Parallel add/subtract. */
8161 op1
= (insn
>> 20) & 7;
8162 tmp
= load_reg(s
, rn
);
8163 tmp2
= load_reg(s
, rm
);
8164 sh
= (insn
>> 5) & 7;
8165 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8167 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8168 tcg_temp_free_i32(tmp2
);
8169 store_reg(s
, rd
, tmp
);
8172 if ((insn
& 0x00700020) == 0) {
8173 /* Halfword pack. */
8174 tmp
= load_reg(s
, rn
);
8175 tmp2
= load_reg(s
, rm
);
8176 shift
= (insn
>> 7) & 0x1f;
8177 if (insn
& (1 << 6)) {
8181 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8182 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8183 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8187 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8188 tcg_gen_ext16u_i32(tmp
, tmp
);
8189 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8191 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8192 tcg_temp_free_i32(tmp2
);
8193 store_reg(s
, rd
, tmp
);
8194 } else if ((insn
& 0x00200020) == 0x00200000) {
8196 tmp
= load_reg(s
, rm
);
8197 shift
= (insn
>> 7) & 0x1f;
8198 if (insn
& (1 << 6)) {
8201 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8203 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8205 sh
= (insn
>> 16) & 0x1f;
8206 tmp2
= tcg_const_i32(sh
);
8207 if (insn
& (1 << 22))
8208 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8210 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8211 tcg_temp_free_i32(tmp2
);
8212 store_reg(s
, rd
, tmp
);
8213 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8215 tmp
= load_reg(s
, rm
);
8216 sh
= (insn
>> 16) & 0x1f;
8217 tmp2
= tcg_const_i32(sh
);
8218 if (insn
& (1 << 22))
8219 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8221 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8222 tcg_temp_free_i32(tmp2
);
8223 store_reg(s
, rd
, tmp
);
8224 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8226 tmp
= load_reg(s
, rn
);
8227 tmp2
= load_reg(s
, rm
);
8228 tmp3
= tcg_temp_new_i32();
8229 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8230 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8231 tcg_temp_free_i32(tmp3
);
8232 tcg_temp_free_i32(tmp2
);
8233 store_reg(s
, rd
, tmp
);
8234 } else if ((insn
& 0x000003e0) == 0x00000060) {
8235 tmp
= load_reg(s
, rm
);
8236 shift
= (insn
>> 10) & 3;
8237 /* ??? In many cases it's not necessary to do a
8238 rotate, a shift is sufficient. */
8240 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8241 op1
= (insn
>> 20) & 7;
8243 case 0: gen_sxtb16(tmp
); break;
8244 case 2: gen_sxtb(tmp
); break;
8245 case 3: gen_sxth(tmp
); break;
8246 case 4: gen_uxtb16(tmp
); break;
8247 case 6: gen_uxtb(tmp
); break;
8248 case 7: gen_uxth(tmp
); break;
8249 default: goto illegal_op
;
8252 tmp2
= load_reg(s
, rn
);
8253 if ((op1
& 3) == 0) {
8254 gen_add16(tmp
, tmp2
);
8256 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8257 tcg_temp_free_i32(tmp2
);
8260 store_reg(s
, rd
, tmp
);
8261 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8263 tmp
= load_reg(s
, rm
);
8264 if (insn
& (1 << 22)) {
8265 if (insn
& (1 << 7)) {
8269 gen_helper_rbit(tmp
, tmp
);
8272 if (insn
& (1 << 7))
8275 tcg_gen_bswap32_i32(tmp
, tmp
);
8277 store_reg(s
, rd
, tmp
);
8282 case 2: /* Multiplies (Type 3). */
8283 switch ((insn
>> 20) & 0x7) {
8285 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8286 /* op2 not 00x or 11x : UNDEF */
8289 /* Signed multiply most significant [accumulate].
8290 (SMMUL, SMMLA, SMMLS) */
8291 tmp
= load_reg(s
, rm
);
8292 tmp2
= load_reg(s
, rs
);
8293 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8296 tmp
= load_reg(s
, rd
);
8297 if (insn
& (1 << 6)) {
8298 tmp64
= gen_subq_msw(tmp64
, tmp
);
8300 tmp64
= gen_addq_msw(tmp64
, tmp
);
8303 if (insn
& (1 << 5)) {
8304 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8306 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8307 tmp
= tcg_temp_new_i32();
8308 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
8309 tcg_temp_free_i64(tmp64
);
8310 store_reg(s
, rn
, tmp
);
8314 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8315 if (insn
& (1 << 7)) {
8318 tmp
= load_reg(s
, rm
);
8319 tmp2
= load_reg(s
, rs
);
8320 if (insn
& (1 << 5))
8321 gen_swap_half(tmp2
);
8322 gen_smul_dual(tmp
, tmp2
);
8323 if (insn
& (1 << 6)) {
8324 /* This subtraction cannot overflow. */
8325 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8327 /* This addition cannot overflow 32 bits;
8328 * however it may overflow considered as a signed
8329 * operation, in which case we must set the Q flag.
8331 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8333 tcg_temp_free_i32(tmp2
);
8334 if (insn
& (1 << 22)) {
8335 /* smlald, smlsld */
8336 tmp64
= tcg_temp_new_i64();
8337 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8338 tcg_temp_free_i32(tmp
);
8339 gen_addq(s
, tmp64
, rd
, rn
);
8340 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8341 tcg_temp_free_i64(tmp64
);
8343 /* smuad, smusd, smlad, smlsd */
8346 tmp2
= load_reg(s
, rd
);
8347 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8348 tcg_temp_free_i32(tmp2
);
8350 store_reg(s
, rn
, tmp
);
8356 if (!arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
8359 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8362 tmp
= load_reg(s
, rm
);
8363 tmp2
= load_reg(s
, rs
);
8364 if (insn
& (1 << 21)) {
8365 gen_helper_udiv(tmp
, tmp
, tmp2
);
8367 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8369 tcg_temp_free_i32(tmp2
);
8370 store_reg(s
, rn
, tmp
);
8377 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8379 case 0: /* Unsigned sum of absolute differences. */
8381 tmp
= load_reg(s
, rm
);
8382 tmp2
= load_reg(s
, rs
);
8383 gen_helper_usad8(tmp
, tmp
, tmp2
);
8384 tcg_temp_free_i32(tmp2
);
8386 tmp2
= load_reg(s
, rd
);
8387 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8388 tcg_temp_free_i32(tmp2
);
8390 store_reg(s
, rn
, tmp
);
8392 case 0x20: case 0x24: case 0x28: case 0x2c:
8393 /* Bitfield insert/clear. */
8395 shift
= (insn
>> 7) & 0x1f;
8396 i
= (insn
>> 16) & 0x1f;
8399 tmp
= tcg_temp_new_i32();
8400 tcg_gen_movi_i32(tmp
, 0);
8402 tmp
= load_reg(s
, rm
);
8405 tmp2
= load_reg(s
, rd
);
8406 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8407 tcg_temp_free_i32(tmp2
);
8409 store_reg(s
, rd
, tmp
);
8411 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8412 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8414 tmp
= load_reg(s
, rm
);
8415 shift
= (insn
>> 7) & 0x1f;
8416 i
= ((insn
>> 16) & 0x1f) + 1;
8421 gen_ubfx(tmp
, shift
, (1u << i
) - 1);
8423 gen_sbfx(tmp
, shift
, i
);
8426 store_reg(s
, rd
, tmp
);
8436 /* Check for undefined extension instructions
8437 * per the ARM Bible IE:
8438 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8440 sh
= (0xf << 20) | (0xf << 4);
8441 if (op1
== 0x7 && ((insn
& sh
) == sh
))
8445 /* load/store byte/word */
8446 rn
= (insn
>> 16) & 0xf;
8447 rd
= (insn
>> 12) & 0xf;
8448 tmp2
= load_reg(s
, rn
);
8449 i
= (IS_USER(s
) || (insn
& 0x01200000) == 0x00200000);
8450 if (insn
& (1 << 24))
8451 gen_add_data_offset(s
, insn
, tmp2
);
8452 if (insn
& (1 << 20)) {
8454 tmp
= tcg_temp_new_i32();
8455 if (insn
& (1 << 22)) {
8456 gen_aa32_ld8u(tmp
, tmp2
, i
);
8458 gen_aa32_ld32u(tmp
, tmp2
, i
);
8462 tmp
= load_reg(s
, rd
);
8463 if (insn
& (1 << 22)) {
8464 gen_aa32_st8(tmp
, tmp2
, i
);
8466 gen_aa32_st32(tmp
, tmp2
, i
);
8468 tcg_temp_free_i32(tmp
);
8470 if (!(insn
& (1 << 24))) {
8471 gen_add_data_offset(s
, insn
, tmp2
);
8472 store_reg(s
, rn
, tmp2
);
8473 } else if (insn
& (1 << 21)) {
8474 store_reg(s
, rn
, tmp2
);
8476 tcg_temp_free_i32(tmp2
);
8478 if (insn
& (1 << 20)) {
8479 /* Complete the load. */
8480 store_reg_from_load(env
, s
, rd
, tmp
);
8486 int j
, n
, user
, loaded_base
;
8487 TCGv_i32 loaded_var
;
8488 /* load/store multiple words */
8489 /* XXX: store correct base if write back */
8491 if (insn
& (1 << 22)) {
8493 goto illegal_op
; /* only usable in supervisor mode */
8495 if ((insn
& (1 << 15)) == 0)
8498 rn
= (insn
>> 16) & 0xf;
8499 addr
= load_reg(s
, rn
);
8501 /* compute total size */
8503 TCGV_UNUSED_I32(loaded_var
);
8506 if (insn
& (1 << i
))
8509 /* XXX: test invalid n == 0 case ? */
8510 if (insn
& (1 << 23)) {
8511 if (insn
& (1 << 24)) {
8513 tcg_gen_addi_i32(addr
, addr
, 4);
8515 /* post increment */
8518 if (insn
& (1 << 24)) {
8520 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8522 /* post decrement */
8524 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8529 if (insn
& (1 << i
)) {
8530 if (insn
& (1 << 20)) {
8532 tmp
= tcg_temp_new_i32();
8533 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8535 tmp2
= tcg_const_i32(i
);
8536 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
8537 tcg_temp_free_i32(tmp2
);
8538 tcg_temp_free_i32(tmp
);
8539 } else if (i
== rn
) {
8543 store_reg_from_load(env
, s
, i
, tmp
);
8548 /* special case: r15 = PC + 8 */
8549 val
= (long)s
->pc
+ 4;
8550 tmp
= tcg_temp_new_i32();
8551 tcg_gen_movi_i32(tmp
, val
);
8553 tmp
= tcg_temp_new_i32();
8554 tmp2
= tcg_const_i32(i
);
8555 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
8556 tcg_temp_free_i32(tmp2
);
8558 tmp
= load_reg(s
, i
);
8560 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8561 tcg_temp_free_i32(tmp
);
8564 /* no need to add after the last transfer */
8566 tcg_gen_addi_i32(addr
, addr
, 4);
8569 if (insn
& (1 << 21)) {
8571 if (insn
& (1 << 23)) {
8572 if (insn
& (1 << 24)) {
8575 /* post increment */
8576 tcg_gen_addi_i32(addr
, addr
, 4);
8579 if (insn
& (1 << 24)) {
8582 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
8584 /* post decrement */
8585 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
8588 store_reg(s
, rn
, addr
);
8590 tcg_temp_free_i32(addr
);
8593 store_reg(s
, rn
, loaded_var
);
8595 if ((insn
& (1 << 22)) && !user
) {
8596 /* Restore CPSR from SPSR. */
8597 tmp
= load_cpu_field(spsr
);
8598 gen_set_cpsr(tmp
, 0xffffffff);
8599 tcg_temp_free_i32(tmp
);
8600 s
->is_jmp
= DISAS_UPDATE
;
8609 /* branch (and link) */
8610 val
= (int32_t)s
->pc
;
8611 if (insn
& (1 << 24)) {
8612 tmp
= tcg_temp_new_i32();
8613 tcg_gen_movi_i32(tmp
, val
);
8614 store_reg(s
, 14, tmp
);
8616 offset
= sextract32(insn
<< 2, 0, 26);
8624 if (((insn
>> 8) & 0xe) == 10) {
8626 if (disas_vfp_insn(env
, s
, insn
)) {
8629 } else if (disas_coproc_insn(env
, s
, insn
)) {
8636 gen_set_pc_im(s
, s
->pc
);
8637 s
->is_jmp
= DISAS_SWI
;
8641 gen_exception_insn(s
, 4, EXCP_UDEF
);
8647 /* Return true if this is a Thumb-2 logical op. */
8649 thumb2_logic_op(int op
)
8654 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8655 then set condition code flags based on the result of the operation.
8656 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8657 to the high bit of T1.
8658 Returns zero if the opcode is valid. */
8661 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
8662 TCGv_i32 t0
, TCGv_i32 t1
)
8669 tcg_gen_and_i32(t0
, t0
, t1
);
8673 tcg_gen_andc_i32(t0
, t0
, t1
);
8677 tcg_gen_or_i32(t0
, t0
, t1
);
8681 tcg_gen_orc_i32(t0
, t0
, t1
);
8685 tcg_gen_xor_i32(t0
, t0
, t1
);
8690 gen_add_CC(t0
, t0
, t1
);
8692 tcg_gen_add_i32(t0
, t0
, t1
);
8696 gen_adc_CC(t0
, t0
, t1
);
8702 gen_sbc_CC(t0
, t0
, t1
);
8704 gen_sub_carry(t0
, t0
, t1
);
8709 gen_sub_CC(t0
, t0
, t1
);
8711 tcg_gen_sub_i32(t0
, t0
, t1
);
8715 gen_sub_CC(t0
, t1
, t0
);
8717 tcg_gen_sub_i32(t0
, t1
, t0
);
8719 default: /* 5, 6, 7, 9, 12, 15. */
8725 gen_set_CF_bit31(t1
);
8730 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8732 static int disas_thumb2_insn(CPUARMState
*env
, DisasContext
*s
, uint16_t insn_hw1
)
8734 uint32_t insn
, imm
, shift
, offset
;
8735 uint32_t rd
, rn
, rm
, rs
;
8746 if (!(arm_feature(env
, ARM_FEATURE_THUMB2
)
8747 || arm_feature (env
, ARM_FEATURE_M
))) {
8748 /* Thumb-1 cores may need to treat bl and blx as a pair of
8749 16-bit instructions to get correct prefetch abort behavior. */
8751 if ((insn
& (1 << 12)) == 0) {
8753 /* Second half of blx. */
8754 offset
= ((insn
& 0x7ff) << 1);
8755 tmp
= load_reg(s
, 14);
8756 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8757 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
8759 tmp2
= tcg_temp_new_i32();
8760 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8761 store_reg(s
, 14, tmp2
);
8765 if (insn
& (1 << 11)) {
8766 /* Second half of bl. */
8767 offset
= ((insn
& 0x7ff) << 1) | 1;
8768 tmp
= load_reg(s
, 14);
8769 tcg_gen_addi_i32(tmp
, tmp
, offset
);
8771 tmp2
= tcg_temp_new_i32();
8772 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
8773 store_reg(s
, 14, tmp2
);
8777 if ((s
->pc
& ~TARGET_PAGE_MASK
) == 0) {
8778 /* Instruction spans a page boundary. Implement it as two
8779 16-bit instructions in case the second half causes an
8781 offset
= ((int32_t)insn
<< 21) >> 9;
8782 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + offset
);
8785 /* Fall through to 32-bit decode. */
8788 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
8790 insn
|= (uint32_t)insn_hw1
<< 16;
8792 if ((insn
& 0xf800e800) != 0xf000e800) {
8796 rn
= (insn
>> 16) & 0xf;
8797 rs
= (insn
>> 12) & 0xf;
8798 rd
= (insn
>> 8) & 0xf;
8800 switch ((insn
>> 25) & 0xf) {
8801 case 0: case 1: case 2: case 3:
8802 /* 16-bit instructions. Should never happen. */
8805 if (insn
& (1 << 22)) {
8806 /* Other load/store, table branch. */
8807 if (insn
& 0x01200000) {
8808 /* Load/store doubleword. */
8810 addr
= tcg_temp_new_i32();
8811 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
8813 addr
= load_reg(s
, rn
);
8815 offset
= (insn
& 0xff) * 4;
8816 if ((insn
& (1 << 23)) == 0)
8818 if (insn
& (1 << 24)) {
8819 tcg_gen_addi_i32(addr
, addr
, offset
);
8822 if (insn
& (1 << 20)) {
8824 tmp
= tcg_temp_new_i32();
8825 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8826 store_reg(s
, rs
, tmp
);
8827 tcg_gen_addi_i32(addr
, addr
, 4);
8828 tmp
= tcg_temp_new_i32();
8829 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8830 store_reg(s
, rd
, tmp
);
8833 tmp
= load_reg(s
, rs
);
8834 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8835 tcg_temp_free_i32(tmp
);
8836 tcg_gen_addi_i32(addr
, addr
, 4);
8837 tmp
= load_reg(s
, rd
);
8838 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8839 tcg_temp_free_i32(tmp
);
8841 if (insn
& (1 << 21)) {
8842 /* Base writeback. */
8845 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
8846 store_reg(s
, rn
, addr
);
8848 tcg_temp_free_i32(addr
);
8850 } else if ((insn
& (1 << 23)) == 0) {
8851 /* Load/store exclusive word. */
8852 addr
= tcg_temp_local_new_i32();
8853 load_reg_var(s
, addr
, rn
);
8854 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
8855 if (insn
& (1 << 20)) {
8856 gen_load_exclusive(s
, rs
, 15, addr
, 2);
8858 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
8860 tcg_temp_free_i32(addr
);
8861 } else if ((insn
& (7 << 5)) == 0) {
8864 addr
= tcg_temp_new_i32();
8865 tcg_gen_movi_i32(addr
, s
->pc
);
8867 addr
= load_reg(s
, rn
);
8869 tmp
= load_reg(s
, rm
);
8870 tcg_gen_add_i32(addr
, addr
, tmp
);
8871 if (insn
& (1 << 4)) {
8873 tcg_gen_add_i32(addr
, addr
, tmp
);
8874 tcg_temp_free_i32(tmp
);
8875 tmp
= tcg_temp_new_i32();
8876 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8878 tcg_temp_free_i32(tmp
);
8879 tmp
= tcg_temp_new_i32();
8880 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8882 tcg_temp_free_i32(addr
);
8883 tcg_gen_shli_i32(tmp
, tmp
, 1);
8884 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
8885 store_reg(s
, 15, tmp
);
8887 int op2
= (insn
>> 6) & 0x3;
8888 op
= (insn
>> 4) & 0x3;
8893 /* Load/store exclusive byte/halfword/doubleword */
8900 /* Load-acquire/store-release */
8906 /* Load-acquire/store-release exclusive */
8910 addr
= tcg_temp_local_new_i32();
8911 load_reg_var(s
, addr
, rn
);
8913 if (insn
& (1 << 20)) {
8914 tmp
= tcg_temp_new_i32();
8917 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
8920 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
8923 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
8928 store_reg(s
, rs
, tmp
);
8930 tmp
= load_reg(s
, rs
);
8933 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
8936 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
8939 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
8944 tcg_temp_free_i32(tmp
);
8946 } else if (insn
& (1 << 20)) {
8947 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
8949 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
8951 tcg_temp_free_i32(addr
);
8954 /* Load/store multiple, RFE, SRS. */
8955 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
8956 /* RFE, SRS: not available in user mode or on M profile */
8957 if (IS_USER(s
) || IS_M(env
)) {
8960 if (insn
& (1 << 20)) {
8962 addr
= load_reg(s
, rn
);
8963 if ((insn
& (1 << 24)) == 0)
8964 tcg_gen_addi_i32(addr
, addr
, -8);
8965 /* Load PC into tmp and CPSR into tmp2. */
8966 tmp
= tcg_temp_new_i32();
8967 gen_aa32_ld32u(tmp
, addr
, 0);
8968 tcg_gen_addi_i32(addr
, addr
, 4);
8969 tmp2
= tcg_temp_new_i32();
8970 gen_aa32_ld32u(tmp2
, addr
, 0);
8971 if (insn
& (1 << 21)) {
8972 /* Base writeback. */
8973 if (insn
& (1 << 24)) {
8974 tcg_gen_addi_i32(addr
, addr
, 4);
8976 tcg_gen_addi_i32(addr
, addr
, -4);
8978 store_reg(s
, rn
, addr
);
8980 tcg_temp_free_i32(addr
);
8982 gen_rfe(s
, tmp
, tmp2
);
8985 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
8989 int i
, loaded_base
= 0;
8990 TCGv_i32 loaded_var
;
8991 /* Load/store multiple. */
8992 addr
= load_reg(s
, rn
);
8994 for (i
= 0; i
< 16; i
++) {
8995 if (insn
& (1 << i
))
8998 if (insn
& (1 << 24)) {
8999 tcg_gen_addi_i32(addr
, addr
, -offset
);
9002 TCGV_UNUSED_I32(loaded_var
);
9003 for (i
= 0; i
< 16; i
++) {
9004 if ((insn
& (1 << i
)) == 0)
9006 if (insn
& (1 << 20)) {
9008 tmp
= tcg_temp_new_i32();
9009 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
9012 } else if (i
== rn
) {
9016 store_reg(s
, i
, tmp
);
9020 tmp
= load_reg(s
, i
);
9021 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
9022 tcg_temp_free_i32(tmp
);
9024 tcg_gen_addi_i32(addr
, addr
, 4);
9027 store_reg(s
, rn
, loaded_var
);
9029 if (insn
& (1 << 21)) {
9030 /* Base register writeback. */
9031 if (insn
& (1 << 24)) {
9032 tcg_gen_addi_i32(addr
, addr
, -offset
);
9034 /* Fault if writeback register is in register list. */
9035 if (insn
& (1 << rn
))
9037 store_reg(s
, rn
, addr
);
9039 tcg_temp_free_i32(addr
);
9046 op
= (insn
>> 21) & 0xf;
9048 /* Halfword pack. */
9049 tmp
= load_reg(s
, rn
);
9050 tmp2
= load_reg(s
, rm
);
9051 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9052 if (insn
& (1 << 5)) {
9056 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9057 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9058 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9062 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9063 tcg_gen_ext16u_i32(tmp
, tmp
);
9064 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9066 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9067 tcg_temp_free_i32(tmp2
);
9068 store_reg(s
, rd
, tmp
);
9070 /* Data processing register constant shift. */
9072 tmp
= tcg_temp_new_i32();
9073 tcg_gen_movi_i32(tmp
, 0);
9075 tmp
= load_reg(s
, rn
);
9077 tmp2
= load_reg(s
, rm
);
9079 shiftop
= (insn
>> 4) & 3;
9080 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9081 conds
= (insn
& (1 << 20)) != 0;
9082 logic_cc
= (conds
&& thumb2_logic_op(op
));
9083 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9084 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9086 tcg_temp_free_i32(tmp2
);
9088 store_reg(s
, rd
, tmp
);
9090 tcg_temp_free_i32(tmp
);
9094 case 13: /* Misc data processing. */
9095 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9096 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9099 case 0: /* Register controlled shift. */
9100 tmp
= load_reg(s
, rn
);
9101 tmp2
= load_reg(s
, rm
);
9102 if ((insn
& 0x70) != 0)
9104 op
= (insn
>> 21) & 3;
9105 logic_cc
= (insn
& (1 << 20)) != 0;
9106 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9109 store_reg_bx(env
, s
, rd
, tmp
);
9111 case 1: /* Sign/zero extend. */
9112 tmp
= load_reg(s
, rm
);
9113 shift
= (insn
>> 4) & 3;
9114 /* ??? In many cases it's not necessary to do a
9115 rotate, a shift is sufficient. */
9117 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9118 op
= (insn
>> 20) & 7;
9120 case 0: gen_sxth(tmp
); break;
9121 case 1: gen_uxth(tmp
); break;
9122 case 2: gen_sxtb16(tmp
); break;
9123 case 3: gen_uxtb16(tmp
); break;
9124 case 4: gen_sxtb(tmp
); break;
9125 case 5: gen_uxtb(tmp
); break;
9126 default: goto illegal_op
;
9129 tmp2
= load_reg(s
, rn
);
9130 if ((op
>> 1) == 1) {
9131 gen_add16(tmp
, tmp2
);
9133 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9134 tcg_temp_free_i32(tmp2
);
9137 store_reg(s
, rd
, tmp
);
9139 case 2: /* SIMD add/subtract. */
9140 op
= (insn
>> 20) & 7;
9141 shift
= (insn
>> 4) & 7;
9142 if ((op
& 3) == 3 || (shift
& 3) == 3)
9144 tmp
= load_reg(s
, rn
);
9145 tmp2
= load_reg(s
, rm
);
9146 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9147 tcg_temp_free_i32(tmp2
);
9148 store_reg(s
, rd
, tmp
);
9150 case 3: /* Other data processing. */
9151 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9153 /* Saturating add/subtract. */
9154 tmp
= load_reg(s
, rn
);
9155 tmp2
= load_reg(s
, rm
);
9157 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9159 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9161 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9162 tcg_temp_free_i32(tmp2
);
9164 tmp
= load_reg(s
, rn
);
9166 case 0x0a: /* rbit */
9167 gen_helper_rbit(tmp
, tmp
);
9169 case 0x08: /* rev */
9170 tcg_gen_bswap32_i32(tmp
, tmp
);
9172 case 0x09: /* rev16 */
9175 case 0x0b: /* revsh */
9178 case 0x10: /* sel */
9179 tmp2
= load_reg(s
, rm
);
9180 tmp3
= tcg_temp_new_i32();
9181 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9182 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9183 tcg_temp_free_i32(tmp3
);
9184 tcg_temp_free_i32(tmp2
);
9186 case 0x18: /* clz */
9187 gen_helper_clz(tmp
, tmp
);
9197 uint32_t sz
= op
& 0x3;
9198 uint32_t c
= op
& 0x8;
9200 if (!arm_feature(env
, ARM_FEATURE_CRC
)) {
9204 tmp2
= load_reg(s
, rm
);
9205 tmp3
= tcg_const_i32(1 << sz
);
9207 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
9209 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
9211 tcg_temp_free_i32(tmp2
);
9212 tcg_temp_free_i32(tmp3
);
9219 store_reg(s
, rd
, tmp
);
9221 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9222 op
= (insn
>> 4) & 0xf;
9223 tmp
= load_reg(s
, rn
);
9224 tmp2
= load_reg(s
, rm
);
9225 switch ((insn
>> 20) & 7) {
9226 case 0: /* 32 x 32 -> 32 */
9227 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
9228 tcg_temp_free_i32(tmp2
);
9230 tmp2
= load_reg(s
, rs
);
9232 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
9234 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9235 tcg_temp_free_i32(tmp2
);
9238 case 1: /* 16 x 16 -> 32 */
9239 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9240 tcg_temp_free_i32(tmp2
);
9242 tmp2
= load_reg(s
, rs
);
9243 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9244 tcg_temp_free_i32(tmp2
);
9247 case 2: /* Dual multiply add. */
9248 case 4: /* Dual multiply subtract. */
9250 gen_swap_half(tmp2
);
9251 gen_smul_dual(tmp
, tmp2
);
9252 if (insn
& (1 << 22)) {
9253 /* This subtraction cannot overflow. */
9254 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9256 /* This addition cannot overflow 32 bits;
9257 * however it may overflow considered as a signed
9258 * operation, in which case we must set the Q flag.
9260 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9262 tcg_temp_free_i32(tmp2
);
9265 tmp2
= load_reg(s
, rs
);
9266 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9267 tcg_temp_free_i32(tmp2
);
9270 case 3: /* 32 * 16 -> 32msb */
9272 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
9275 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9276 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
9277 tmp
= tcg_temp_new_i32();
9278 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9279 tcg_temp_free_i64(tmp64
);
9282 tmp2
= load_reg(s
, rs
);
9283 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
9284 tcg_temp_free_i32(tmp2
);
9287 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9288 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9290 tmp
= load_reg(s
, rs
);
9291 if (insn
& (1 << 20)) {
9292 tmp64
= gen_addq_msw(tmp64
, tmp
);
9294 tmp64
= gen_subq_msw(tmp64
, tmp
);
9297 if (insn
& (1 << 4)) {
9298 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
9300 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
9301 tmp
= tcg_temp_new_i32();
9302 tcg_gen_trunc_i64_i32(tmp
, tmp64
);
9303 tcg_temp_free_i64(tmp64
);
9305 case 7: /* Unsigned sum of absolute differences. */
9306 gen_helper_usad8(tmp
, tmp
, tmp2
);
9307 tcg_temp_free_i32(tmp2
);
9309 tmp2
= load_reg(s
, rs
);
9310 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9311 tcg_temp_free_i32(tmp2
);
9315 store_reg(s
, rd
, tmp
);
9317 case 6: case 7: /* 64-bit multiply, Divide. */
9318 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
9319 tmp
= load_reg(s
, rn
);
9320 tmp2
= load_reg(s
, rm
);
9321 if ((op
& 0x50) == 0x10) {
9323 if (!arm_feature(env
, ARM_FEATURE_THUMB_DIV
)) {
9327 gen_helper_udiv(tmp
, tmp
, tmp2
);
9329 gen_helper_sdiv(tmp
, tmp
, tmp2
);
9330 tcg_temp_free_i32(tmp2
);
9331 store_reg(s
, rd
, tmp
);
9332 } else if ((op
& 0xe) == 0xc) {
9333 /* Dual multiply accumulate long. */
9335 gen_swap_half(tmp2
);
9336 gen_smul_dual(tmp
, tmp2
);
9338 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9340 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9342 tcg_temp_free_i32(tmp2
);
9344 tmp64
= tcg_temp_new_i64();
9345 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9346 tcg_temp_free_i32(tmp
);
9347 gen_addq(s
, tmp64
, rs
, rd
);
9348 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9349 tcg_temp_free_i64(tmp64
);
9352 /* Unsigned 64-bit multiply */
9353 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
9357 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
9358 tcg_temp_free_i32(tmp2
);
9359 tmp64
= tcg_temp_new_i64();
9360 tcg_gen_ext_i32_i64(tmp64
, tmp
);
9361 tcg_temp_free_i32(tmp
);
9363 /* Signed 64-bit multiply */
9364 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
9369 gen_addq_lo(s
, tmp64
, rs
);
9370 gen_addq_lo(s
, tmp64
, rd
);
9371 } else if (op
& 0x40) {
9372 /* 64-bit accumulate. */
9373 gen_addq(s
, tmp64
, rs
, rd
);
9375 gen_storeq_reg(s
, rs
, rd
, tmp64
);
9376 tcg_temp_free_i64(tmp64
);
9381 case 6: case 7: case 14: case 15:
9383 if (((insn
>> 24) & 3) == 3) {
9384 /* Translate into the equivalent ARM encoding. */
9385 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
9386 if (disas_neon_data_insn(env
, s
, insn
))
9388 } else if (((insn
>> 8) & 0xe) == 10) {
9389 if (disas_vfp_insn(env
, s
, insn
)) {
9393 if (insn
& (1 << 28))
9395 if (disas_coproc_insn (env
, s
, insn
))
9399 case 8: case 9: case 10: case 11:
9400 if (insn
& (1 << 15)) {
9401 /* Branches, misc control. */
9402 if (insn
& 0x5000) {
9403 /* Unconditional branch. */
9404 /* signextend(hw1[10:0]) -> offset[:12]. */
9405 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
9406 /* hw1[10:0] -> offset[11:1]. */
9407 offset
|= (insn
& 0x7ff) << 1;
9408 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9409 offset[24:22] already have the same value because of the
9410 sign extension above. */
9411 offset
^= ((~insn
) & (1 << 13)) << 10;
9412 offset
^= ((~insn
) & (1 << 11)) << 11;
9414 if (insn
& (1 << 14)) {
9415 /* Branch and link. */
9416 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
9420 if (insn
& (1 << 12)) {
9425 offset
&= ~(uint32_t)2;
9426 /* thumb2 bx, no need to check */
9427 gen_bx_im(s
, offset
);
9429 } else if (((insn
>> 23) & 7) == 7) {
9431 if (insn
& (1 << 13))
9434 if (insn
& (1 << 26)) {
9435 /* Secure monitor call (v6Z) */
9436 qemu_log_mask(LOG_UNIMP
,
9437 "arm: unimplemented secure monitor call\n");
9438 goto illegal_op
; /* not implemented. */
9440 op
= (insn
>> 20) & 7;
9442 case 0: /* msr cpsr. */
9444 tmp
= load_reg(s
, rn
);
9445 addr
= tcg_const_i32(insn
& 0xff);
9446 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
9447 tcg_temp_free_i32(addr
);
9448 tcg_temp_free_i32(tmp
);
9453 case 1: /* msr spsr. */
9456 tmp
= load_reg(s
, rn
);
9458 msr_mask(env
, s
, (insn
>> 8) & 0xf, op
== 1),
9462 case 2: /* cps, nop-hint. */
9463 if (((insn
>> 8) & 7) == 0) {
9464 gen_nop_hint(s
, insn
& 0xff);
9466 /* Implemented as NOP in user mode. */
9471 if (insn
& (1 << 10)) {
9472 if (insn
& (1 << 7))
9474 if (insn
& (1 << 6))
9476 if (insn
& (1 << 5))
9478 if (insn
& (1 << 9))
9479 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
9481 if (insn
& (1 << 8)) {
9483 imm
|= (insn
& 0x1f);
9486 gen_set_psr_im(s
, offset
, 0, imm
);
9489 case 3: /* Special control operations. */
9491 op
= (insn
>> 4) & 0xf;
9499 /* These execute as NOPs. */
9506 /* Trivial implementation equivalent to bx. */
9507 tmp
= load_reg(s
, rn
);
9510 case 5: /* Exception return. */
9514 if (rn
!= 14 || rd
!= 15) {
9517 tmp
= load_reg(s
, rn
);
9518 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
9519 gen_exception_return(s
, tmp
);
9521 case 6: /* mrs cpsr. */
9522 tmp
= tcg_temp_new_i32();
9524 addr
= tcg_const_i32(insn
& 0xff);
9525 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
9526 tcg_temp_free_i32(addr
);
9528 gen_helper_cpsr_read(tmp
, cpu_env
);
9530 store_reg(s
, rd
, tmp
);
9532 case 7: /* mrs spsr. */
9533 /* Not accessible in user mode. */
9534 if (IS_USER(s
) || IS_M(env
))
9536 tmp
= load_cpu_field(spsr
);
9537 store_reg(s
, rd
, tmp
);
9542 /* Conditional branch. */
9543 op
= (insn
>> 22) & 0xf;
9544 /* Generate a conditional jump to next instruction. */
9545 s
->condlabel
= gen_new_label();
9546 arm_gen_test_cc(op
^ 1, s
->condlabel
);
9549 /* offset[11:1] = insn[10:0] */
9550 offset
= (insn
& 0x7ff) << 1;
9551 /* offset[17:12] = insn[21:16]. */
9552 offset
|= (insn
& 0x003f0000) >> 4;
9553 /* offset[31:20] = insn[26]. */
9554 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
9555 /* offset[18] = insn[13]. */
9556 offset
|= (insn
& (1 << 13)) << 5;
9557 /* offset[19] = insn[11]. */
9558 offset
|= (insn
& (1 << 11)) << 8;
9560 /* jump to the offset */
9561 gen_jmp(s
, s
->pc
+ offset
);
9564 /* Data processing immediate. */
9565 if (insn
& (1 << 25)) {
9566 if (insn
& (1 << 24)) {
9567 if (insn
& (1 << 20))
9569 /* Bitfield/Saturate. */
9570 op
= (insn
>> 21) & 7;
9572 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9574 tmp
= tcg_temp_new_i32();
9575 tcg_gen_movi_i32(tmp
, 0);
9577 tmp
= load_reg(s
, rn
);
9580 case 2: /* Signed bitfield extract. */
9582 if (shift
+ imm
> 32)
9585 gen_sbfx(tmp
, shift
, imm
);
9587 case 6: /* Unsigned bitfield extract. */
9589 if (shift
+ imm
> 32)
9592 gen_ubfx(tmp
, shift
, (1u << imm
) - 1);
9594 case 3: /* Bitfield insert/clear. */
9597 imm
= imm
+ 1 - shift
;
9599 tmp2
= load_reg(s
, rd
);
9600 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
9601 tcg_temp_free_i32(tmp2
);
9606 default: /* Saturate. */
9609 tcg_gen_sari_i32(tmp
, tmp
, shift
);
9611 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9613 tmp2
= tcg_const_i32(imm
);
9616 if ((op
& 1) && shift
== 0)
9617 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
9619 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
9622 if ((op
& 1) && shift
== 0)
9623 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
9625 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
9627 tcg_temp_free_i32(tmp2
);
9630 store_reg(s
, rd
, tmp
);
9632 imm
= ((insn
& 0x04000000) >> 15)
9633 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
9634 if (insn
& (1 << 22)) {
9635 /* 16-bit immediate. */
9636 imm
|= (insn
>> 4) & 0xf000;
9637 if (insn
& (1 << 23)) {
9639 tmp
= load_reg(s
, rd
);
9640 tcg_gen_ext16u_i32(tmp
, tmp
);
9641 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
9644 tmp
= tcg_temp_new_i32();
9645 tcg_gen_movi_i32(tmp
, imm
);
9648 /* Add/sub 12-bit immediate. */
9650 offset
= s
->pc
& ~(uint32_t)3;
9651 if (insn
& (1 << 23))
9655 tmp
= tcg_temp_new_i32();
9656 tcg_gen_movi_i32(tmp
, offset
);
9658 tmp
= load_reg(s
, rn
);
9659 if (insn
& (1 << 23))
9660 tcg_gen_subi_i32(tmp
, tmp
, imm
);
9662 tcg_gen_addi_i32(tmp
, tmp
, imm
);
9665 store_reg(s
, rd
, tmp
);
9668 int shifter_out
= 0;
9669 /* modified 12-bit immediate. */
9670 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
9671 imm
= (insn
& 0xff);
9674 /* Nothing to do. */
9676 case 1: /* 00XY00XY */
9679 case 2: /* XY00XY00 */
9683 case 3: /* XYXYXYXY */
9687 default: /* Rotated constant. */
9688 shift
= (shift
<< 1) | (imm
>> 7);
9690 imm
= imm
<< (32 - shift
);
9694 tmp2
= tcg_temp_new_i32();
9695 tcg_gen_movi_i32(tmp2
, imm
);
9696 rn
= (insn
>> 16) & 0xf;
9698 tmp
= tcg_temp_new_i32();
9699 tcg_gen_movi_i32(tmp
, 0);
9701 tmp
= load_reg(s
, rn
);
9703 op
= (insn
>> 21) & 0xf;
9704 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
9705 shifter_out
, tmp
, tmp2
))
9707 tcg_temp_free_i32(tmp2
);
9708 rd
= (insn
>> 8) & 0xf;
9710 store_reg(s
, rd
, tmp
);
9712 tcg_temp_free_i32(tmp
);
9717 case 12: /* Load/store single data item. */
9722 if ((insn
& 0x01100000) == 0x01000000) {
9723 if (disas_neon_ls_insn(env
, s
, insn
))
9727 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
9729 if (!(insn
& (1 << 20))) {
9733 /* Byte or halfword load space with dest == r15 : memory hints.
9734 * Catch them early so we don't emit pointless addressing code.
9735 * This space is a mix of:
9736 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9737 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9739 * unallocated hints, which must be treated as NOPs
9740 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9741 * which is easiest for the decoding logic
9742 * Some space which must UNDEF
9744 int op1
= (insn
>> 23) & 3;
9745 int op2
= (insn
>> 6) & 0x3f;
9750 /* UNPREDICTABLE, unallocated hint or
9751 * PLD/PLDW/PLI (literal)
9756 return 0; /* PLD/PLDW/PLI or unallocated hint */
9758 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
9759 return 0; /* PLD/PLDW/PLI or unallocated hint */
9761 /* UNDEF space, or an UNPREDICTABLE */
9767 addr
= tcg_temp_new_i32();
9769 /* s->pc has already been incremented by 4. */
9770 imm
= s
->pc
& 0xfffffffc;
9771 if (insn
& (1 << 23))
9772 imm
+= insn
& 0xfff;
9774 imm
-= insn
& 0xfff;
9775 tcg_gen_movi_i32(addr
, imm
);
9777 addr
= load_reg(s
, rn
);
9778 if (insn
& (1 << 23)) {
9779 /* Positive offset. */
9781 tcg_gen_addi_i32(addr
, addr
, imm
);
9784 switch ((insn
>> 8) & 0xf) {
9785 case 0x0: /* Shifted Register. */
9786 shift
= (insn
>> 4) & 0xf;
9788 tcg_temp_free_i32(addr
);
9791 tmp
= load_reg(s
, rm
);
9793 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9794 tcg_gen_add_i32(addr
, addr
, tmp
);
9795 tcg_temp_free_i32(tmp
);
9797 case 0xc: /* Negative offset. */
9798 tcg_gen_addi_i32(addr
, addr
, -imm
);
9800 case 0xe: /* User privilege. */
9801 tcg_gen_addi_i32(addr
, addr
, imm
);
9804 case 0x9: /* Post-decrement. */
9807 case 0xb: /* Post-increment. */
9811 case 0xd: /* Pre-decrement. */
9814 case 0xf: /* Pre-increment. */
9815 tcg_gen_addi_i32(addr
, addr
, imm
);
9819 tcg_temp_free_i32(addr
);
9824 if (insn
& (1 << 20)) {
9826 tmp
= tcg_temp_new_i32();
9829 gen_aa32_ld8u(tmp
, addr
, user
);
9832 gen_aa32_ld8s(tmp
, addr
, user
);
9835 gen_aa32_ld16u(tmp
, addr
, user
);
9838 gen_aa32_ld16s(tmp
, addr
, user
);
9841 gen_aa32_ld32u(tmp
, addr
, user
);
9844 tcg_temp_free_i32(tmp
);
9845 tcg_temp_free_i32(addr
);
9851 store_reg(s
, rs
, tmp
);
9855 tmp
= load_reg(s
, rs
);
9858 gen_aa32_st8(tmp
, addr
, user
);
9861 gen_aa32_st16(tmp
, addr
, user
);
9864 gen_aa32_st32(tmp
, addr
, user
);
9867 tcg_temp_free_i32(tmp
);
9868 tcg_temp_free_i32(addr
);
9871 tcg_temp_free_i32(tmp
);
9874 tcg_gen_addi_i32(addr
, addr
, imm
);
9876 store_reg(s
, rn
, addr
);
9878 tcg_temp_free_i32(addr
);
9890 static void disas_thumb_insn(CPUARMState
*env
, DisasContext
*s
)
9892 uint32_t val
, insn
, op
, rm
, rn
, rd
, shift
, cond
;
9899 if (s
->condexec_mask
) {
9900 cond
= s
->condexec_cond
;
9901 if (cond
!= 0x0e) { /* Skip conditional when condition is AL. */
9902 s
->condlabel
= gen_new_label();
9903 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
9908 insn
= arm_lduw_code(env
, s
->pc
, s
->bswap_code
);
9911 switch (insn
>> 12) {
9915 op
= (insn
>> 11) & 3;
9918 rn
= (insn
>> 3) & 7;
9919 tmp
= load_reg(s
, rn
);
9920 if (insn
& (1 << 10)) {
9922 tmp2
= tcg_temp_new_i32();
9923 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
9926 rm
= (insn
>> 6) & 7;
9927 tmp2
= load_reg(s
, rm
);
9929 if (insn
& (1 << 9)) {
9930 if (s
->condexec_mask
)
9931 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9933 gen_sub_CC(tmp
, tmp
, tmp2
);
9935 if (s
->condexec_mask
)
9936 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9938 gen_add_CC(tmp
, tmp
, tmp2
);
9940 tcg_temp_free_i32(tmp2
);
9941 store_reg(s
, rd
, tmp
);
9943 /* shift immediate */
9944 rm
= (insn
>> 3) & 7;
9945 shift
= (insn
>> 6) & 0x1f;
9946 tmp
= load_reg(s
, rm
);
9947 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
9948 if (!s
->condexec_mask
)
9950 store_reg(s
, rd
, tmp
);
9954 /* arithmetic large immediate */
9955 op
= (insn
>> 11) & 3;
9956 rd
= (insn
>> 8) & 0x7;
9957 if (op
== 0) { /* mov */
9958 tmp
= tcg_temp_new_i32();
9959 tcg_gen_movi_i32(tmp
, insn
& 0xff);
9960 if (!s
->condexec_mask
)
9962 store_reg(s
, rd
, tmp
);
9964 tmp
= load_reg(s
, rd
);
9965 tmp2
= tcg_temp_new_i32();
9966 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
9969 gen_sub_CC(tmp
, tmp
, tmp2
);
9970 tcg_temp_free_i32(tmp
);
9971 tcg_temp_free_i32(tmp2
);
9974 if (s
->condexec_mask
)
9975 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9977 gen_add_CC(tmp
, tmp
, tmp2
);
9978 tcg_temp_free_i32(tmp2
);
9979 store_reg(s
, rd
, tmp
);
9982 if (s
->condexec_mask
)
9983 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
9985 gen_sub_CC(tmp
, tmp
, tmp2
);
9986 tcg_temp_free_i32(tmp2
);
9987 store_reg(s
, rd
, tmp
);
9993 if (insn
& (1 << 11)) {
9994 rd
= (insn
>> 8) & 7;
9995 /* load pc-relative. Bit 1 of PC is ignored. */
9996 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
9997 val
&= ~(uint32_t)2;
9998 addr
= tcg_temp_new_i32();
9999 tcg_gen_movi_i32(addr
, val
);
10000 tmp
= tcg_temp_new_i32();
10001 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10002 tcg_temp_free_i32(addr
);
10003 store_reg(s
, rd
, tmp
);
10006 if (insn
& (1 << 10)) {
10007 /* data processing extended or blx */
10008 rd
= (insn
& 7) | ((insn
>> 4) & 8);
10009 rm
= (insn
>> 3) & 0xf;
10010 op
= (insn
>> 8) & 3;
10013 tmp
= load_reg(s
, rd
);
10014 tmp2
= load_reg(s
, rm
);
10015 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10016 tcg_temp_free_i32(tmp2
);
10017 store_reg(s
, rd
, tmp
);
10020 tmp
= load_reg(s
, rd
);
10021 tmp2
= load_reg(s
, rm
);
10022 gen_sub_CC(tmp
, tmp
, tmp2
);
10023 tcg_temp_free_i32(tmp2
);
10024 tcg_temp_free_i32(tmp
);
10026 case 2: /* mov/cpy */
10027 tmp
= load_reg(s
, rm
);
10028 store_reg(s
, rd
, tmp
);
10030 case 3:/* branch [and link] exchange thumb register */
10031 tmp
= load_reg(s
, rm
);
10032 if (insn
& (1 << 7)) {
10034 val
= (uint32_t)s
->pc
| 1;
10035 tmp2
= tcg_temp_new_i32();
10036 tcg_gen_movi_i32(tmp2
, val
);
10037 store_reg(s
, 14, tmp2
);
10039 /* already thumb, no need to check */
10046 /* data processing register */
10048 rm
= (insn
>> 3) & 7;
10049 op
= (insn
>> 6) & 0xf;
10050 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
10051 /* the shift/rotate ops want the operands backwards */
10060 if (op
== 9) { /* neg */
10061 tmp
= tcg_temp_new_i32();
10062 tcg_gen_movi_i32(tmp
, 0);
10063 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
10064 tmp
= load_reg(s
, rd
);
10066 TCGV_UNUSED_I32(tmp
);
10069 tmp2
= load_reg(s
, rm
);
10071 case 0x0: /* and */
10072 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10073 if (!s
->condexec_mask
)
10076 case 0x1: /* eor */
10077 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
10078 if (!s
->condexec_mask
)
10081 case 0x2: /* lsl */
10082 if (s
->condexec_mask
) {
10083 gen_shl(tmp2
, tmp2
, tmp
);
10085 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10086 gen_logic_CC(tmp2
);
10089 case 0x3: /* lsr */
10090 if (s
->condexec_mask
) {
10091 gen_shr(tmp2
, tmp2
, tmp
);
10093 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10094 gen_logic_CC(tmp2
);
10097 case 0x4: /* asr */
10098 if (s
->condexec_mask
) {
10099 gen_sar(tmp2
, tmp2
, tmp
);
10101 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10102 gen_logic_CC(tmp2
);
10105 case 0x5: /* adc */
10106 if (s
->condexec_mask
) {
10107 gen_adc(tmp
, tmp2
);
10109 gen_adc_CC(tmp
, tmp
, tmp2
);
10112 case 0x6: /* sbc */
10113 if (s
->condexec_mask
) {
10114 gen_sub_carry(tmp
, tmp
, tmp2
);
10116 gen_sbc_CC(tmp
, tmp
, tmp2
);
10119 case 0x7: /* ror */
10120 if (s
->condexec_mask
) {
10121 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
10122 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
10124 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
10125 gen_logic_CC(tmp2
);
10128 case 0x8: /* tst */
10129 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
10133 case 0x9: /* neg */
10134 if (s
->condexec_mask
)
10135 tcg_gen_neg_i32(tmp
, tmp2
);
10137 gen_sub_CC(tmp
, tmp
, tmp2
);
10139 case 0xa: /* cmp */
10140 gen_sub_CC(tmp
, tmp
, tmp2
);
10143 case 0xb: /* cmn */
10144 gen_add_CC(tmp
, tmp
, tmp2
);
10147 case 0xc: /* orr */
10148 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
10149 if (!s
->condexec_mask
)
10152 case 0xd: /* mul */
10153 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10154 if (!s
->condexec_mask
)
10157 case 0xe: /* bic */
10158 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
10159 if (!s
->condexec_mask
)
10162 case 0xf: /* mvn */
10163 tcg_gen_not_i32(tmp2
, tmp2
);
10164 if (!s
->condexec_mask
)
10165 gen_logic_CC(tmp2
);
10172 store_reg(s
, rm
, tmp2
);
10174 tcg_temp_free_i32(tmp
);
10176 store_reg(s
, rd
, tmp
);
10177 tcg_temp_free_i32(tmp2
);
10180 tcg_temp_free_i32(tmp
);
10181 tcg_temp_free_i32(tmp2
);
10186 /* load/store register offset. */
10188 rn
= (insn
>> 3) & 7;
10189 rm
= (insn
>> 6) & 7;
10190 op
= (insn
>> 9) & 7;
10191 addr
= load_reg(s
, rn
);
10192 tmp
= load_reg(s
, rm
);
10193 tcg_gen_add_i32(addr
, addr
, tmp
);
10194 tcg_temp_free_i32(tmp
);
10196 if (op
< 3) { /* store */
10197 tmp
= load_reg(s
, rd
);
10199 tmp
= tcg_temp_new_i32();
10204 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10207 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
10210 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
10212 case 3: /* ldrsb */
10213 gen_aa32_ld8s(tmp
, addr
, IS_USER(s
));
10216 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10219 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
10222 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
10224 case 7: /* ldrsh */
10225 gen_aa32_ld16s(tmp
, addr
, IS_USER(s
));
10228 if (op
>= 3) { /* load */
10229 store_reg(s
, rd
, tmp
);
10231 tcg_temp_free_i32(tmp
);
10233 tcg_temp_free_i32(addr
);
10237 /* load/store word immediate offset */
10239 rn
= (insn
>> 3) & 7;
10240 addr
= load_reg(s
, rn
);
10241 val
= (insn
>> 4) & 0x7c;
10242 tcg_gen_addi_i32(addr
, addr
, val
);
10244 if (insn
& (1 << 11)) {
10246 tmp
= tcg_temp_new_i32();
10247 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10248 store_reg(s
, rd
, tmp
);
10251 tmp
= load_reg(s
, rd
);
10252 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10253 tcg_temp_free_i32(tmp
);
10255 tcg_temp_free_i32(addr
);
10259 /* load/store byte immediate offset */
10261 rn
= (insn
>> 3) & 7;
10262 addr
= load_reg(s
, rn
);
10263 val
= (insn
>> 6) & 0x1f;
10264 tcg_gen_addi_i32(addr
, addr
, val
);
10266 if (insn
& (1 << 11)) {
10268 tmp
= tcg_temp_new_i32();
10269 gen_aa32_ld8u(tmp
, addr
, IS_USER(s
));
10270 store_reg(s
, rd
, tmp
);
10273 tmp
= load_reg(s
, rd
);
10274 gen_aa32_st8(tmp
, addr
, IS_USER(s
));
10275 tcg_temp_free_i32(tmp
);
10277 tcg_temp_free_i32(addr
);
10281 /* load/store halfword immediate offset */
10283 rn
= (insn
>> 3) & 7;
10284 addr
= load_reg(s
, rn
);
10285 val
= (insn
>> 5) & 0x3e;
10286 tcg_gen_addi_i32(addr
, addr
, val
);
10288 if (insn
& (1 << 11)) {
10290 tmp
= tcg_temp_new_i32();
10291 gen_aa32_ld16u(tmp
, addr
, IS_USER(s
));
10292 store_reg(s
, rd
, tmp
);
10295 tmp
= load_reg(s
, rd
);
10296 gen_aa32_st16(tmp
, addr
, IS_USER(s
));
10297 tcg_temp_free_i32(tmp
);
10299 tcg_temp_free_i32(addr
);
10303 /* load/store from stack */
10304 rd
= (insn
>> 8) & 7;
10305 addr
= load_reg(s
, 13);
10306 val
= (insn
& 0xff) * 4;
10307 tcg_gen_addi_i32(addr
, addr
, val
);
10309 if (insn
& (1 << 11)) {
10311 tmp
= tcg_temp_new_i32();
10312 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10313 store_reg(s
, rd
, tmp
);
10316 tmp
= load_reg(s
, rd
);
10317 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10318 tcg_temp_free_i32(tmp
);
10320 tcg_temp_free_i32(addr
);
10324 /* add to high reg */
10325 rd
= (insn
>> 8) & 7;
10326 if (insn
& (1 << 11)) {
10328 tmp
= load_reg(s
, 13);
10330 /* PC. bit 1 is ignored. */
10331 tmp
= tcg_temp_new_i32();
10332 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
10334 val
= (insn
& 0xff) * 4;
10335 tcg_gen_addi_i32(tmp
, tmp
, val
);
10336 store_reg(s
, rd
, tmp
);
10341 op
= (insn
>> 8) & 0xf;
10344 /* adjust stack pointer */
10345 tmp
= load_reg(s
, 13);
10346 val
= (insn
& 0x7f) * 4;
10347 if (insn
& (1 << 7))
10348 val
= -(int32_t)val
;
10349 tcg_gen_addi_i32(tmp
, tmp
, val
);
10350 store_reg(s
, 13, tmp
);
10353 case 2: /* sign/zero extend. */
10356 rm
= (insn
>> 3) & 7;
10357 tmp
= load_reg(s
, rm
);
10358 switch ((insn
>> 6) & 3) {
10359 case 0: gen_sxth(tmp
); break;
10360 case 1: gen_sxtb(tmp
); break;
10361 case 2: gen_uxth(tmp
); break;
10362 case 3: gen_uxtb(tmp
); break;
10364 store_reg(s
, rd
, tmp
);
10366 case 4: case 5: case 0xc: case 0xd:
10368 addr
= load_reg(s
, 13);
10369 if (insn
& (1 << 8))
10373 for (i
= 0; i
< 8; i
++) {
10374 if (insn
& (1 << i
))
10377 if ((insn
& (1 << 11)) == 0) {
10378 tcg_gen_addi_i32(addr
, addr
, -offset
);
10380 for (i
= 0; i
< 8; i
++) {
10381 if (insn
& (1 << i
)) {
10382 if (insn
& (1 << 11)) {
10384 tmp
= tcg_temp_new_i32();
10385 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10386 store_reg(s
, i
, tmp
);
10389 tmp
= load_reg(s
, i
);
10390 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10391 tcg_temp_free_i32(tmp
);
10393 /* advance to the next address. */
10394 tcg_gen_addi_i32(addr
, addr
, 4);
10397 TCGV_UNUSED_I32(tmp
);
10398 if (insn
& (1 << 8)) {
10399 if (insn
& (1 << 11)) {
10401 tmp
= tcg_temp_new_i32();
10402 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10403 /* don't set the pc until the rest of the instruction
10407 tmp
= load_reg(s
, 14);
10408 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10409 tcg_temp_free_i32(tmp
);
10411 tcg_gen_addi_i32(addr
, addr
, 4);
10413 if ((insn
& (1 << 11)) == 0) {
10414 tcg_gen_addi_i32(addr
, addr
, -offset
);
10416 /* write back the new stack pointer */
10417 store_reg(s
, 13, addr
);
10418 /* set the new PC value */
10419 if ((insn
& 0x0900) == 0x0900) {
10420 store_reg_from_load(env
, s
, 15, tmp
);
10424 case 1: case 3: case 9: case 11: /* czb */
10426 tmp
= load_reg(s
, rm
);
10427 s
->condlabel
= gen_new_label();
10429 if (insn
& (1 << 11))
10430 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10432 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10433 tcg_temp_free_i32(tmp
);
10434 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10435 val
= (uint32_t)s
->pc
+ 2;
10440 case 15: /* IT, nop-hint. */
10441 if ((insn
& 0xf) == 0) {
10442 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10446 s
->condexec_cond
= (insn
>> 4) & 0xe;
10447 s
->condexec_mask
= insn
& 0x1f;
10448 /* No actual code generated for this insn, just setup state. */
10451 case 0xe: /* bkpt */
10453 gen_exception_insn(s
, 2, EXCP_BKPT
);
10456 case 0xa: /* rev */
10458 rn
= (insn
>> 3) & 0x7;
10460 tmp
= load_reg(s
, rn
);
10461 switch ((insn
>> 6) & 3) {
10462 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10463 case 1: gen_rev16(tmp
); break;
10464 case 3: gen_revsh(tmp
); break;
10465 default: goto illegal_op
;
10467 store_reg(s
, rd
, tmp
);
10471 switch ((insn
>> 5) & 7) {
10475 if (((insn
>> 3) & 1) != s
->bswap_code
) {
10476 /* Dynamic endianness switching not implemented. */
10477 qemu_log_mask(LOG_UNIMP
, "arm: unimplemented setend\n");
10488 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10491 addr
= tcg_const_i32(19);
10492 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10493 tcg_temp_free_i32(addr
);
10497 addr
= tcg_const_i32(16);
10498 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10499 tcg_temp_free_i32(addr
);
10501 tcg_temp_free_i32(tmp
);
10504 if (insn
& (1 << 4)) {
10505 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10509 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10524 /* load/store multiple */
10525 TCGv_i32 loaded_var
;
10526 TCGV_UNUSED_I32(loaded_var
);
10527 rn
= (insn
>> 8) & 0x7;
10528 addr
= load_reg(s
, rn
);
10529 for (i
= 0; i
< 8; i
++) {
10530 if (insn
& (1 << i
)) {
10531 if (insn
& (1 << 11)) {
10533 tmp
= tcg_temp_new_i32();
10534 gen_aa32_ld32u(tmp
, addr
, IS_USER(s
));
10538 store_reg(s
, i
, tmp
);
10542 tmp
= load_reg(s
, i
);
10543 gen_aa32_st32(tmp
, addr
, IS_USER(s
));
10544 tcg_temp_free_i32(tmp
);
10546 /* advance to the next address */
10547 tcg_gen_addi_i32(addr
, addr
, 4);
10550 if ((insn
& (1 << rn
)) == 0) {
10551 /* base reg not in list: base register writeback */
10552 store_reg(s
, rn
, addr
);
10554 /* base reg in list: if load, complete it now */
10555 if (insn
& (1 << 11)) {
10556 store_reg(s
, rn
, loaded_var
);
10558 tcg_temp_free_i32(addr
);
10563 /* conditional branch or swi */
10564 cond
= (insn
>> 8) & 0xf;
10570 gen_set_pc_im(s
, s
->pc
);
10571 s
->is_jmp
= DISAS_SWI
;
10574 /* generate a conditional jump to next instruction */
10575 s
->condlabel
= gen_new_label();
10576 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
10579 /* jump to the offset */
10580 val
= (uint32_t)s
->pc
+ 2;
10581 offset
= ((int32_t)insn
<< 24) >> 24;
10582 val
+= offset
<< 1;
10587 if (insn
& (1 << 11)) {
10588 if (disas_thumb2_insn(env
, s
, insn
))
10592 /* unconditional branch */
10593 val
= (uint32_t)s
->pc
;
10594 offset
= ((int32_t)insn
<< 21) >> 21;
10595 val
+= (offset
<< 1) + 2;
10600 if (disas_thumb2_insn(env
, s
, insn
))
10606 gen_exception_insn(s
, 4, EXCP_UDEF
);
10610 gen_exception_insn(s
, 2, EXCP_UDEF
);
10613 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10614 basic block 'tb'. If search_pc is TRUE, also generate PC
10615 information for each intermediate instruction. */
10616 static inline void gen_intermediate_code_internal(ARMCPU
*cpu
,
10617 TranslationBlock
*tb
,
10620 CPUState
*cs
= CPU(cpu
);
10621 CPUARMState
*env
= &cpu
->env
;
10622 DisasContext dc1
, *dc
= &dc1
;
10624 uint16_t *gen_opc_end
;
10626 target_ulong pc_start
;
10627 target_ulong next_page_start
;
10631 /* generate intermediate code */
10633 /* The A64 decoder has its own top level loop, because it doesn't need
10634 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10636 if (ARM_TBFLAG_AARCH64_STATE(tb
->flags
)) {
10637 gen_intermediate_code_internal_a64(cpu
, tb
, search_pc
);
10645 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
10647 dc
->is_jmp
= DISAS_NEXT
;
10649 dc
->singlestep_enabled
= cs
->singlestep_enabled
;
10653 dc
->thumb
= ARM_TBFLAG_THUMB(tb
->flags
);
10654 dc
->bswap_code
= ARM_TBFLAG_BSWAP_CODE(tb
->flags
);
10655 dc
->condexec_mask
= (ARM_TBFLAG_CONDEXEC(tb
->flags
) & 0xf) << 1;
10656 dc
->condexec_cond
= ARM_TBFLAG_CONDEXEC(tb
->flags
) >> 4;
10657 #if !defined(CONFIG_USER_ONLY)
10658 dc
->user
= (ARM_TBFLAG_PRIV(tb
->flags
) == 0);
10660 dc
->vfp_enabled
= ARM_TBFLAG_VFPEN(tb
->flags
);
10661 dc
->vec_len
= ARM_TBFLAG_VECLEN(tb
->flags
);
10662 dc
->vec_stride
= ARM_TBFLAG_VECSTRIDE(tb
->flags
);
10663 dc
->cp_regs
= cpu
->cp_regs
;
10664 dc
->current_pl
= arm_current_pl(env
);
10665 dc
->features
= env
->features
;
10667 cpu_F0s
= tcg_temp_new_i32();
10668 cpu_F1s
= tcg_temp_new_i32();
10669 cpu_F0d
= tcg_temp_new_i64();
10670 cpu_F1d
= tcg_temp_new_i64();
10673 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10674 cpu_M0
= tcg_temp_new_i64();
10675 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
10678 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
10679 if (max_insns
== 0)
10680 max_insns
= CF_COUNT_MASK
;
10684 tcg_clear_temp_count();
10686 /* A note on handling of the condexec (IT) bits:
10688 * We want to avoid the overhead of having to write the updated condexec
10689 * bits back to the CPUARMState for every instruction in an IT block. So:
10690 * (1) if the condexec bits are not already zero then we write
10691 * zero back into the CPUARMState now. This avoids complications trying
10692 * to do it at the end of the block. (For example if we don't do this
10693 * it's hard to identify whether we can safely skip writing condexec
10694 * at the end of the TB, which we definitely want to do for the case
10695 * where a TB doesn't do anything with the IT state at all.)
10696 * (2) if we are going to leave the TB then we call gen_set_condexec()
10697 * which will write the correct value into CPUARMState if zero is wrong.
10698 * This is done both for leaving the TB at the end, and for leaving
10699 * it because of an exception we know will happen, which is done in
10700 * gen_exception_insn(). The latter is necessary because we need to
10701 * leave the TB with the PC/IT state just prior to execution of the
10702 * instruction which caused the exception.
10703 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10704 * then the CPUARMState will be wrong and we need to reset it.
10705 * This is handled in the same way as restoration of the
10706 * PC in these situations: we will be called again with search_pc=1
10707 * and generate a mapping of the condexec bits for each PC in
10708 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10709 * this to restore the condexec bits.
10711 * Note that there are no instructions which can read the condexec
10712 * bits, and none which can write non-static values to them, so
10713 * we don't need to care about whether CPUARMState is correct in the
10717 /* Reset the conditional execution bits immediately. This avoids
10718 complications trying to do it at the end of the block. */
10719 if (dc
->condexec_mask
|| dc
->condexec_cond
)
10721 TCGv_i32 tmp
= tcg_temp_new_i32();
10722 tcg_gen_movi_i32(tmp
, 0);
10723 store_cpu_field(tmp
, condexec_bits
);
10726 #ifdef CONFIG_USER_ONLY
10727 /* Intercept jump to the magic kernel page. */
10728 if (dc
->pc
>= 0xffff0000) {
10729 /* We always get here via a jump, so know we are not in a
10730 conditional execution block. */
10731 gen_exception(EXCP_KERNEL_TRAP
);
10732 dc
->is_jmp
= DISAS_UPDATE
;
10736 if (dc
->pc
>= 0xfffffff0 && IS_M(env
)) {
10737 /* We always get here via a jump, so know we are not in a
10738 conditional execution block. */
10739 gen_exception(EXCP_EXCEPTION_EXIT
);
10740 dc
->is_jmp
= DISAS_UPDATE
;
10745 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
10746 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
10747 if (bp
->pc
== dc
->pc
) {
10748 gen_exception_insn(dc
, 0, EXCP_DEBUG
);
10749 /* Advance PC so that clearing the breakpoint will
10750 invalidate this TB. */
10752 goto done_generating
;
10757 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10761 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10763 tcg_ctx
.gen_opc_pc
[lj
] = dc
->pc
;
10764 gen_opc_condexec_bits
[lj
] = (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1);
10765 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
10766 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
10769 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
10772 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
10773 tcg_gen_debug_insn_start(dc
->pc
);
10777 disas_thumb_insn(env
, dc
);
10778 if (dc
->condexec_mask
) {
10779 dc
->condexec_cond
= (dc
->condexec_cond
& 0xe)
10780 | ((dc
->condexec_mask
>> 4) & 1);
10781 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
10782 if (dc
->condexec_mask
== 0) {
10783 dc
->condexec_cond
= 0;
10787 disas_arm_insn(env
, dc
);
10790 if (dc
->condjmp
&& !dc
->is_jmp
) {
10791 gen_set_label(dc
->condlabel
);
10795 if (tcg_check_temp_count()) {
10796 fprintf(stderr
, "TCG temporary leak before "TARGET_FMT_lx
"\n",
10800 /* Translation stops when a conditional branch is encountered.
10801 * Otherwise the subsequent code could get translated several times.
10802 * Also stop translation when a page boundary is reached. This
10803 * ensures prefetch aborts occur at the right place. */
10805 } while (!dc
->is_jmp
&& tcg_ctx
.gen_opc_ptr
< gen_opc_end
&&
10806 !cs
->singlestep_enabled
&&
10808 dc
->pc
< next_page_start
&&
10809 num_insns
< max_insns
);
10811 if (tb
->cflags
& CF_LAST_IO
) {
10813 /* FIXME: This can theoretically happen with self-modifying
10815 cpu_abort(cs
, "IO on conditional branch instruction");
10820 /* At this stage dc->condjmp will only be set when the skipped
10821 instruction was a conditional branch or trap, and the PC has
10822 already been written. */
10823 if (unlikely(cs
->singlestep_enabled
)) {
10824 /* Make sure the pc is updated, and raise a debug exception. */
10826 gen_set_condexec(dc
);
10827 if (dc
->is_jmp
== DISAS_SWI
) {
10828 gen_exception(EXCP_SWI
);
10830 gen_exception(EXCP_DEBUG
);
10832 gen_set_label(dc
->condlabel
);
10834 if (dc
->condjmp
|| !dc
->is_jmp
) {
10835 gen_set_pc_im(dc
, dc
->pc
);
10838 gen_set_condexec(dc
);
10839 if (dc
->is_jmp
== DISAS_SWI
&& !dc
->condjmp
) {
10840 gen_exception(EXCP_SWI
);
10842 /* FIXME: Single stepping a WFI insn will not halt
10844 gen_exception(EXCP_DEBUG
);
10847 /* While branches must always occur at the end of an IT block,
10848 there are a few other things that can cause us to terminate
10849 the TB in the middle of an IT block:
10850 - Exception generating instructions (bkpt, swi, undefined).
10852 - Hardware watchpoints.
10853 Hardware breakpoints have already been handled and skip this code.
10855 gen_set_condexec(dc
);
10856 switch(dc
->is_jmp
) {
10858 gen_goto_tb(dc
, 1, dc
->pc
);
10863 /* indicate that the hash table must be used to find the next TB */
10864 tcg_gen_exit_tb(0);
10866 case DISAS_TB_JUMP
:
10867 /* nothing more to generate */
10870 gen_helper_wfi(cpu_env
);
10873 gen_helper_wfe(cpu_env
);
10876 gen_exception(EXCP_SWI
);
10880 gen_set_label(dc
->condlabel
);
10881 gen_set_condexec(dc
);
10882 gen_goto_tb(dc
, 1, dc
->pc
);
10888 gen_tb_end(tb
, num_insns
);
10889 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
10892 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
10893 qemu_log("----------------\n");
10894 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
10895 log_target_disas(env
, pc_start
, dc
->pc
- pc_start
,
10896 dc
->thumb
| (dc
->bswap_code
<< 1));
10901 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
10904 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
10906 tb
->size
= dc
->pc
- pc_start
;
10907 tb
->icount
= num_insns
;
10911 void gen_intermediate_code(CPUARMState
*env
, TranslationBlock
*tb
)
10913 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, false);
10916 void gen_intermediate_code_pc(CPUARMState
*env
, TranslationBlock
*tb
)
10918 gen_intermediate_code_internal(arm_env_get_cpu(env
), tb
, true);
10921 static const char *cpu_mode_names
[16] = {
10922 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10923 "???", "???", "???", "und", "???", "???", "???", "sys"
10926 void arm_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
10929 ARMCPU
*cpu
= ARM_CPU(cs
);
10930 CPUARMState
*env
= &cpu
->env
;
10934 for(i
=0;i
<16;i
++) {
10935 cpu_fprintf(f
, "R%02d=%08x", i
, env
->regs
[i
]);
10937 cpu_fprintf(f
, "\n");
10939 cpu_fprintf(f
, " ");
10941 psr
= cpsr_read(env
);
10942 cpu_fprintf(f
, "PSR=%08x %c%c%c%c %c %s%d\n",
10944 psr
& (1 << 31) ? 'N' : '-',
10945 psr
& (1 << 30) ? 'Z' : '-',
10946 psr
& (1 << 29) ? 'C' : '-',
10947 psr
& (1 << 28) ? 'V' : '-',
10948 psr
& CPSR_T
? 'T' : 'A',
10949 cpu_mode_names
[psr
& 0xf], (psr
& 0x10) ? 32 : 26);
10951 if (flags
& CPU_DUMP_FPU
) {
10952 int numvfpregs
= 0;
10953 if (arm_feature(env
, ARM_FEATURE_VFP
)) {
10956 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
10959 for (i
= 0; i
< numvfpregs
; i
++) {
10960 uint64_t v
= float64_val(env
->vfp
.regs
[i
]);
10961 cpu_fprintf(f
, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64
"\n",
10962 i
* 2, (uint32_t)v
,
10963 i
* 2 + 1, (uint32_t)(v
>> 32),
10966 cpu_fprintf(f
, "FPSCR: %08x\n", (int)env
->vfp
.xregs
[ARM_VFP_FPSCR
]);
10970 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
, int pc_pos
)
10973 env
->pc
= tcg_ctx
.gen_opc_pc
[pc_pos
];
10974 env
->condexec_bits
= 0;
10976 env
->regs
[15] = tcg_ctx
.gen_opc_pc
[pc_pos
];
10977 env
->condexec_bits
= gen_opc_condexec_bits
[pc_pos
];