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 disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2764 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2766 if (!arm_feature(env, ARM_FEATURE_V8)) {
2771 VFP_DREG_D(rd, insn);
2772 VFP_DREG_N(rn, insn);
2773 VFP_DREG_M(rm, insn);
2775 rd = VFP_SREG_D(insn);
2776 rn = VFP_SREG_N(insn);
2777 rm = VFP_SREG_M(insn);
2780 if ((insn & 0x0f800e50) == 0x0e000a00) {
2781 return handle_vsel(insn, rd, rn, rm, dp);
2782 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2783 return handle_vminmaxnm(insn, rd, rn, rm, dp);
2788 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2789 (ie. an undefined instruction). */
2790 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2792 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2798 if (!arm_feature(env, ARM_FEATURE_VFP))
2801 if (!s->vfp_enabled) {
2802 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2803 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2805 rn = (insn >> 16) & 0xf;
2806 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2807 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2811 if (extract32(insn, 28, 4) == 0xf) {
2812 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2813 * only used in v8 and above.
2815 return disas_vfp_v8_insn(env, s, insn);
2818 dp = ((insn & 0xf00) == 0xb00);
2819 switch ((insn >> 24) & 0xf) {
2821 if (insn & (1 << 4)) {
2822 /* single register transfer */
2823 rd = (insn >> 12) & 0xf;
2828 VFP_DREG_N(rn, insn);
2831 if (insn & 0x00c00060
2832 && !arm_feature(env, ARM_FEATURE_NEON))
2835 pass = (insn >> 21) & 1;
2836 if (insn & (1 << 22)) {
2838 offset = ((insn >> 5) & 3) * 8;
2839 } else if (insn & (1 << 5)) {
2841 offset = (insn & (1 << 6)) ? 16 : 0;
2846 if (insn & ARM_CP_RW_BIT) {
2848 tmp = neon_load_reg(rn, pass);
2852 tcg_gen_shri_i32(tmp, tmp, offset);
2853 if (insn & (1 << 23))
2859 if (insn & (1 << 23)) {
2861 tcg_gen_shri_i32(tmp, tmp, 16);
2867 tcg_gen_sari_i32(tmp, tmp, 16);
2876 store_reg(s, rd, tmp);
2879 tmp = load_reg(s, rd);
2880 if (insn & (1 << 23)) {
2883 gen_neon_dup_u8(tmp, 0);
2884 } else if (size == 1) {
2885 gen_neon_dup_low16(tmp);
2887 for (n = 0; n <= pass * 2; n++) {
2888 tmp2 = tcg_temp_new_i32();
2889 tcg_gen_mov_i32(tmp2, tmp);
2890 neon_store_reg(rn, n, tmp2);
2892 neon_store_reg(rn, n, tmp);
2897 tmp2 = neon_load_reg(rn, pass);
2898 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2899 tcg_temp_free_i32(tmp2);
2902 tmp2 = neon_load_reg(rn, pass);
2903 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2904 tcg_temp_free_i32(tmp2);
2909 neon_store_reg(rn, pass, tmp);
2913 if ((insn & 0x6f) != 0x00)
2915 rn = VFP_SREG_N(insn);
2916 if (insn & ARM_CP_RW_BIT) {
2918 if (insn & (1 << 21)) {
2919 /* system register */
2924 /* VFP2 allows access to FSID from userspace.
2925 VFP3 restricts all id registers to privileged
2928 && arm_feature(env, ARM_FEATURE_VFP3))
2930 tmp = load_cpu_field(vfp.xregs[rn]);
2935 tmp = load_cpu_field(vfp.xregs[rn]);
2937 case ARM_VFP_FPINST:
2938 case ARM_VFP_FPINST2:
2939 /* Not present in VFP3. */
2941 || arm_feature(env, ARM_FEATURE_VFP3))
2943 tmp = load_cpu_field(vfp.xregs[rn]);
2947 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2948 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2950 tmp = tcg_temp_new_i32();
2951 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2957 || !arm_feature(env, ARM_FEATURE_MVFR))
2959 tmp = load_cpu_field(vfp.xregs[rn]);
2965 gen_mov_F0_vreg(0, rn);
2966 tmp = gen_vfp_mrs();
2969 /* Set the 4 flag bits in the CPSR. */
2971 tcg_temp_free_i32(tmp);
2973 store_reg(s, rd, tmp);
2977 if (insn & (1 << 21)) {
2979 /* system register */
2984 /* Writes are ignored. */
2987 tmp = load_reg(s, rd);
2988 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2989 tcg_temp_free_i32(tmp);
2995 /* TODO: VFP subarchitecture support.
2996 * For now, keep the EN bit only */
2997 tmp = load_reg(s, rd);
2998 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2999 store_cpu_field(tmp, vfp.xregs[rn]);
3002 case ARM_VFP_FPINST:
3003 case ARM_VFP_FPINST2:
3004 tmp = load_reg(s, rd);
3005 store_cpu_field(tmp, vfp.xregs[rn]);
3011 tmp = load_reg(s, rd);
3013 gen_mov_vreg_F0(0, rn);
3018 /* data processing */
3019 /* The opcode is in bits 23, 21, 20 and 6. */
3020 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3024 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3026 /* rn is register number */
3027 VFP_DREG_N(rn, insn);
3030 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3031 /* Integer or single precision destination. */
3032 rd = VFP_SREG_D(insn);
3034 VFP_DREG_D(rd, insn);
3037 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3038 /* VCVT from int is always from S reg regardless of dp bit.
3039 * VCVT with immediate frac_bits has same format as SREG_M
3041 rm = VFP_SREG_M(insn);
3043 VFP_DREG_M(rm, insn);
3046 rn = VFP_SREG_N(insn);
3047 if (op == 15 && rn == 15) {
3048 /* Double precision destination. */
3049 VFP_DREG_D(rd, insn);
3051 rd = VFP_SREG_D(insn);
3053 /* NB that we implicitly rely on the encoding for the frac_bits
3054 * in VCVT of fixed to float being the same as that of an SREG_M
3056 rm = VFP_SREG_M(insn);
3059 veclen = s->vec_len;
3060 if (op == 15 && rn > 3)
3063 /* Shut up compiler warnings. */
3074 /* Figure out what type of vector operation this is. */
3075 if ((rd & bank_mask) == 0) {
3080 delta_d = (s->vec_stride >> 1) + 1;
3082 delta_d = s->vec_stride + 1;
3084 if ((rm & bank_mask) == 0) {
3085 /* mixed scalar/vector */
3094 /* Load the initial operands. */
3099 /* Integer source */
3100 gen_mov_F0_vreg(0, rm);
3105 gen_mov_F0_vreg(dp, rd);
3106 gen_mov_F1_vreg(dp, rm);
3110 /* Compare with zero */
3111 gen_mov_F0_vreg(dp, rd);
3122 /* Source and destination the same. */
3123 gen_mov_F0_vreg(dp, rd);
3129 /* VCVTB, VCVTT: only present with the halfprec extension,
3130 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3132 if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3135 /* Otherwise fall through */
3137 /* One source operand. */
3138 gen_mov_F0_vreg(dp, rm);
3142 /* Two source operands. */
3143 gen_mov_F0_vreg(dp, rn);
3144 gen_mov_F1_vreg(dp, rm);
3148 /* Perform the calculation. */
3150 case 0: /* VMLA: fd + (fn * fm) */
3151 /* Note that order of inputs to the add matters for NaNs */
3153 gen_mov_F0_vreg(dp, rd);
3156 case 1: /* VMLS: fd + -(fn * fm) */
3159 gen_mov_F0_vreg(dp, rd);
3162 case 2: /* VNMLS: -fd + (fn * fm) */
3163 /* Note that it isn't valid to replace (-A + B) with (B - A)
3164 * or similar plausible looking simplifications
3165 * because this will give wrong results for NaNs.
3168 gen_mov_F0_vreg(dp, rd);
3172 case 3: /* VNMLA: -fd + -(fn * fm) */
3175 gen_mov_F0_vreg(dp, rd);
3179 case 4: /* mul: fn * fm */
3182 case 5: /* nmul: -(fn * fm) */
3186 case 6: /* add: fn + fm */
3189 case 7: /* sub: fn - fm */
3192 case 8: /* div: fn / fm */
3195 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3196 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3197 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3198 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3199 /* These are fused multiply-add, and must be done as one
3200 * floating point operation with no rounding between the
3201 * multiplication and addition steps.
3202 * NB that doing the negations here as separate steps is
3203 * correct : an input NaN should come out with its sign bit
3204 * flipped if it is a negated-input.
3206 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3214 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3216 frd = tcg_temp_new_i64();
3217 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3220 gen_helper_vfp_negd(frd, frd);
3222 fpst = get_fpstatus_ptr(0);
3223 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3224 cpu_F1d, frd, fpst);
3225 tcg_temp_free_ptr(fpst);
3226 tcg_temp_free_i64(frd);
3232 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3234 frd = tcg_temp_new_i32();
3235 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3237 gen_helper_vfp_negs(frd, frd);
3239 fpst = get_fpstatus_ptr(0);
3240 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3241 cpu_F1s, frd, fpst);
3242 tcg_temp_free_ptr(fpst);
3243 tcg_temp_free_i32(frd);
3246 case 14: /* fconst */
3247 if (!arm_feature(env, ARM_FEATURE_VFP3))
3250 n = (insn << 12) & 0x80000000;
3251 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3258 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3265 tcg_gen_movi_i32(cpu_F0s, n);
3268 case 15: /* extension space */
3282 case 4: /* vcvtb.f32.f16 */
3283 tmp = gen_vfp_mrs();
3284 tcg_gen_ext16u_i32(tmp, tmp);
3285 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3286 tcg_temp_free_i32(tmp);
3288 case 5: /* vcvtt.f32.f16 */
3289 tmp = gen_vfp_mrs();
3290 tcg_gen_shri_i32(tmp, tmp, 16);
3291 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3292 tcg_temp_free_i32(tmp);
3294 case 6: /* vcvtb.f16.f32 */
3295 tmp = tcg_temp_new_i32();
3296 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3297 gen_mov_F0_vreg(0, rd);
3298 tmp2 = gen_vfp_mrs();
3299 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3300 tcg_gen_or_i32(tmp, tmp, tmp2);
3301 tcg_temp_free_i32(tmp2);
3304 case 7: /* vcvtt.f16.f32 */
3305 tmp = tcg_temp_new_i32();
3306 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3307 tcg_gen_shli_i32(tmp, tmp, 16);
3308 gen_mov_F0_vreg(0, rd);
3309 tmp2 = gen_vfp_mrs();
3310 tcg_gen_ext16u_i32(tmp2, tmp2);
3311 tcg_gen_or_i32(tmp, tmp, tmp2);
3312 tcg_temp_free_i32(tmp2);
3324 case 11: /* cmpez */
3328 case 15: /* single<->double conversion */
3330 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3332 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3334 case 16: /* fuito */
3335 gen_vfp_uito(dp, 0);
3337 case 17: /* fsito */
3338 gen_vfp_sito(dp, 0);
3340 case 20: /* fshto */
3341 if (!arm_feature(env, ARM_FEATURE_VFP3))
3343 gen_vfp_shto(dp, 16 - rm, 0);
3345 case 21: /* fslto */
3346 if (!arm_feature(env, ARM_FEATURE_VFP3))
3348 gen_vfp_slto(dp, 32 - rm, 0);
3350 case 22: /* fuhto */
3351 if (!arm_feature(env, ARM_FEATURE_VFP3))
3353 gen_vfp_uhto(dp, 16 - rm, 0);
3355 case 23: /* fulto */
3356 if (!arm_feature(env, ARM_FEATURE_VFP3))
3358 gen_vfp_ulto(dp, 32 - rm, 0);
3360 case 24: /* ftoui */
3361 gen_vfp_toui(dp, 0);
3363 case 25: /* ftouiz */
3364 gen_vfp_touiz(dp, 0);
3366 case 26: /* ftosi */
3367 gen_vfp_tosi(dp, 0);
3369 case 27: /* ftosiz */
3370 gen_vfp_tosiz(dp, 0);
3372 case 28: /* ftosh */
3373 if (!arm_feature(env, ARM_FEATURE_VFP3))
3375 gen_vfp_tosh(dp, 16 - rm, 0);
3377 case 29: /* ftosl */
3378 if (!arm_feature(env, ARM_FEATURE_VFP3))
3380 gen_vfp_tosl(dp, 32 - rm, 0);
3382 case 30: /* ftouh */
3383 if (!arm_feature(env, ARM_FEATURE_VFP3))
3385 gen_vfp_touh(dp, 16 - rm, 0);
3387 case 31: /* ftoul */
3388 if (!arm_feature(env, ARM_FEATURE_VFP3))
3390 gen_vfp_toul(dp, 32 - rm, 0);
3392 default: /* undefined */
3396 default: /* undefined */
3400 /* Write back the result. */
3401 if (op == 15 && (rn >= 8 && rn <= 11))
3402 ; /* Comparison, do nothing. */
3403 else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3404 /* VCVT double to int: always integer result. */
3405 gen_mov_vreg_F0(0, rd);
3406 else if (op == 15 && rn == 15)
3408 gen_mov_vreg_F0(!dp, rd);
3410 gen_mov_vreg_F0(dp, rd);
3412 /* break out of the loop if we have finished */
3416 if (op == 15 && delta_m == 0) {
3417 /* single source one-many */
3419 rd = ((rd + delta_d) & (bank_mask - 1))
3421 gen_mov_vreg_F0(dp, rd);
3425 /* Setup the next operands. */
3427 rd = ((rd + delta_d) & (bank_mask - 1))
3431 /* One source operand. */
3432 rm = ((rm + delta_m) & (bank_mask - 1))
3434 gen_mov_F0_vreg(dp, rm);
3436 /* Two source operands. */
3437 rn = ((rn + delta_d) & (bank_mask - 1))
3439 gen_mov_F0_vreg(dp, rn);
3441 rm = ((rm + delta_m) & (bank_mask - 1))
3443 gen_mov_F1_vreg(dp, rm);
3451 if ((insn & 0x03e00000) == 0x00400000) {
3452 /* two-register transfer */
3453 rn = (insn >> 16) & 0xf;
3454 rd = (insn >> 12) & 0xf;
3456 VFP_DREG_M(rm, insn);
3458 rm = VFP_SREG_M(insn);
3461 if (insn & ARM_CP_RW_BIT) {
3464 gen_mov_F0_vreg(0, rm * 2);
3465 tmp = gen_vfp_mrs();
3466 store_reg(s, rd, tmp);
3467 gen_mov_F0_vreg(0, rm * 2 + 1);
3468 tmp = gen_vfp_mrs();
3469 store_reg(s, rn, tmp);
3471 gen_mov_F0_vreg(0, rm);
3472 tmp = gen_vfp_mrs();
3473 store_reg(s, rd, tmp);
3474 gen_mov_F0_vreg(0, rm + 1);
3475 tmp = gen_vfp_mrs();
3476 store_reg(s, rn, tmp);
3481 tmp = load_reg(s, rd);
3483 gen_mov_vreg_F0(0, rm * 2);
3484 tmp = load_reg(s, rn);
3486 gen_mov_vreg_F0(0, rm * 2 + 1);
3488 tmp = load_reg(s, rd);
3490 gen_mov_vreg_F0(0, rm);
3491 tmp = load_reg(s, rn);
3493 gen_mov_vreg_F0(0, rm + 1);
3498 rn = (insn >> 16) & 0xf;
3500 VFP_DREG_D(rd, insn);
3502 rd = VFP_SREG_D(insn);
3503 if ((insn & 0x01200000) == 0x01000000) {
3504 /* Single load/store */
3505 offset = (insn & 0xff) << 2;
3506 if ((insn & (1 << 23)) == 0)
3508 if (s->thumb && rn == 15) {
3509 /* This is actually UNPREDICTABLE */
3510 addr = tcg_temp_new_i32();
3511 tcg_gen_movi_i32(addr, s->pc & ~2);
3513 addr = load_reg(s, rn);
3515 tcg_gen_addi_i32(addr, addr, offset);
3516 if (insn & (1 << 20)) {
3517 gen_vfp_ld(s, dp, addr);
3518 gen_mov_vreg_F0(dp, rd);
3520 gen_mov_F0_vreg(dp, rd);
3521 gen_vfp_st(s, dp, addr);
3523 tcg_temp_free_i32(addr);
3525 /* load/store multiple */
3526 int w = insn & (1 << 21);
3528 n = (insn >> 1) & 0x7f;
3532 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3533 /* P == U , W == 1 => UNDEF */
3536 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3537 /* UNPREDICTABLE cases for bad immediates: we choose to
3538 * UNDEF to avoid generating huge numbers of TCG ops
3542 if (rn == 15 && w) {
3543 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3547 if (s->thumb && rn == 15) {
3548 /* This is actually UNPREDICTABLE */
3549 addr = tcg_temp_new_i32();
3550 tcg_gen_movi_i32(addr, s->pc & ~2);
3552 addr = load_reg(s, rn);
3554 if (insn & (1 << 24)) /* pre-decrement */
3555 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3561 for (i = 0; i < n; i++) {
3562 if (insn & ARM_CP_RW_BIT) {
3564 gen_vfp_ld(s, dp, addr);
3565 gen_mov_vreg_F0(dp, rd + i);
3568 gen_mov_F0_vreg(dp, rd + i);
3569 gen_vfp_st(s, dp, addr);
3571 tcg_gen_addi_i32(addr, addr, offset);
3575 if (insn & (1 << 24))
3576 offset = -offset * n;
3577 else if (dp && (insn & 1))
3583 tcg_gen_addi_i32(addr, addr, offset);
3584 store_reg(s, rn, addr);
3586 tcg_temp_free_i32(addr);
3592 /* Should never happen. */
3598 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3600 TranslationBlock *tb;
3603 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3605 gen_set_pc_im(s, dest);
3606 tcg_gen_exit_tb((uintptr_t)tb + n);
3608 gen_set_pc_im(s, dest);
3613 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3615 if (unlikely(s->singlestep_enabled)) {
3616 /* An indirect jump so that we still trigger the debug exception. */
3621 gen_goto_tb(s, 0, dest);
3622 s->is_jmp = DISAS_TB_JUMP;
3626 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3629 tcg_gen_sari_i32(t0, t0, 16);
3633 tcg_gen_sari_i32(t1, t1, 16);
3636 tcg_gen_mul_i32(t0, t0, t1);
3639 /* Return the mask of PSR bits set by a MSR instruction. */
3640 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3644 if (flags & (1 << 0))
3646 if (flags & (1 << 1))
3648 if (flags & (1 << 2))
3650 if (flags & (1 << 3))
3653 /* Mask out undefined bits. */
3654 mask &= ~CPSR_RESERVED;
3655 if (!arm_feature(env, ARM_FEATURE_V4T))
3657 if (!arm_feature(env, ARM_FEATURE_V5))
3658 mask &= ~CPSR_Q; /* V5TE in reality*/
3659 if (!arm_feature(env, ARM_FEATURE_V6))
3660 mask &= ~(CPSR_E | CPSR_GE);
3661 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3663 /* Mask out execution state bits. */
3666 /* Mask out privileged bits. */
3672 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3673 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3677 /* ??? This is also undefined in system mode. */
3681 tmp = load_cpu_field(spsr);
3682 tcg_gen_andi_i32(tmp, tmp, ~mask);
3683 tcg_gen_andi_i32(t0, t0, mask);
3684 tcg_gen_or_i32(tmp, tmp, t0);
3685 store_cpu_field(tmp, spsr);
3687 gen_set_cpsr(t0, mask);
3689 tcg_temp_free_i32(t0);
3694 /* Returns nonzero if access to the PSR is not permitted. */
3695 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3698 tmp = tcg_temp_new_i32();
3699 tcg_gen_movi_i32(tmp, val);
3700 return gen_set_psr(s, mask, spsr, tmp);
3703 /* Generate an old-style exception return. Marks pc as dead. */
3704 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3707 store_reg(s, 15, pc);
3708 tmp = load_cpu_field(spsr);
3709 gen_set_cpsr(tmp, 0xffffffff);
3710 tcg_temp_free_i32(tmp);
3711 s->is_jmp = DISAS_UPDATE;
3714 /* Generate a v6 exception return. Marks both values as dead. */
3715 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3717 gen_set_cpsr(cpsr, 0xffffffff);
3718 tcg_temp_free_i32(cpsr);
3719 store_reg(s, 15, pc);
3720 s->is_jmp = DISAS_UPDATE;
3724 gen_set_condexec (DisasContext *s)
3726 if (s->condexec_mask) {
3727 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3728 TCGv_i32 tmp = tcg_temp_new_i32();
3729 tcg_gen_movi_i32(tmp, val);
3730 store_cpu_field(tmp, condexec_bits);
3734 static void gen_exception_insn(DisasContext *s, int offset, int excp)
3736 gen_set_condexec(s);
3737 gen_set_pc_im(s, s->pc - offset);
3738 gen_exception(excp);
3739 s->is_jmp = DISAS_JUMP;
3742 static void gen_nop_hint(DisasContext *s, int val)
3746 gen_set_pc_im(s, s->pc);
3747 s->is_jmp = DISAS_WFI;
3752 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3758 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3760 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3763 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3764 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3765 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3770 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3773 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3774 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3775 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3780 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3781 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3782 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3783 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3784 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3786 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3787 switch ((size << 1) | u) { \
3789 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3792 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3795 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3798 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3801 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3804 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3806 default: return 1; \
3809 #define GEN_NEON_INTEGER_OP(name) do { \
3810 switch ((size << 1) | u) { \
3812 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3815 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3818 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3821 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3824 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3827 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3829 default: return 1; \
3832 static TCGv_i32 neon_load_scratch(int scratch)
3834 TCGv_i32 tmp = tcg_temp_new_i32();
3835 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3839 static void neon_store_scratch(int scratch, TCGv_i32 var)
3841 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3842 tcg_temp_free_i32(var);
3845 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3849 tmp = neon_load_reg(reg & 7, reg >> 4);
3851 gen_neon_dup_high16(tmp);
3853 gen_neon_dup_low16(tmp);
3856 tmp = neon_load_reg(reg & 15, reg >> 4);
3861 static int gen_neon_unzip(int rd, int rm, int size, int q)
3864 if (!q && size == 2) {
3867 tmp = tcg_const_i32(rd);
3868 tmp2 = tcg_const_i32(rm);
3872 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3875 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3878 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3886 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3889 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3895 tcg_temp_free_i32(tmp);
3896 tcg_temp_free_i32(tmp2);
3900 static int gen_neon_zip(int rd, int rm, int size, int q)
3903 if (!q && size == 2) {
3906 tmp = tcg_const_i32(rd);
3907 tmp2 = tcg_const_i32(rm);
3911 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3914 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3917 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3925 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3928 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3934 tcg_temp_free_i32(tmp);
3935 tcg_temp_free_i32(tmp2);
3939 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3943 rd = tcg_temp_new_i32();
3944 tmp = tcg_temp_new_i32();
3946 tcg_gen_shli_i32(rd, t0, 8);
3947 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3948 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3949 tcg_gen_or_i32(rd, rd, tmp);
3951 tcg_gen_shri_i32(t1, t1, 8);
3952 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3953 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3954 tcg_gen_or_i32(t1, t1, tmp);
3955 tcg_gen_mov_i32(t0, rd);
3957 tcg_temp_free_i32(tmp);
3958 tcg_temp_free_i32(rd);
3961 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3965 rd = tcg_temp_new_i32();
3966 tmp = tcg_temp_new_i32();
3968 tcg_gen_shli_i32(rd, t0, 16);
3969 tcg_gen_andi_i32(tmp, t1, 0xffff);
3970 tcg_gen_or_i32(rd, rd, tmp);
3971 tcg_gen_shri_i32(t1, t1, 16);
3972 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3973 tcg_gen_or_i32(t1, t1, tmp);
3974 tcg_gen_mov_i32(t0, rd);
3976 tcg_temp_free_i32(tmp);
3977 tcg_temp_free_i32(rd);
3985 } neon_ls_element_type[11] = {
3999 /* Translate a NEON load/store element instruction. Return nonzero if the
4000 instruction is invalid. */
4001 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4020 if (!s->vfp_enabled)
4022 VFP_DREG_D(rd, insn);
4023 rn = (insn >> 16) & 0xf;
4025 load = (insn & (1 << 21)) != 0;
4026 if ((insn & (1 << 23)) == 0) {
4027 /* Load store all elements. */
4028 op = (insn >> 8) & 0xf;
4029 size = (insn >> 6) & 3;
4032 /* Catch UNDEF cases for bad values of align field */
4035 if (((insn >> 5) & 1) == 1) {
4040 if (((insn >> 4) & 3) == 3) {
4047 nregs = neon_ls_element_type[op].nregs;
4048 interleave = neon_ls_element_type[op].interleave;
4049 spacing = neon_ls_element_type[op].spacing;
4050 if (size == 3 && (interleave | spacing) != 1)
4052 addr = tcg_temp_new_i32();
4053 load_reg_var(s, addr, rn);
4054 stride = (1 << size) * interleave;
4055 for (reg = 0; reg < nregs; reg++) {
4056 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4057 load_reg_var(s, addr, rn);
4058 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4059 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4060 load_reg_var(s, addr, rn);
4061 tcg_gen_addi_i32(addr, addr, 1 << size);
4064 tmp64 = tcg_temp_new_i64();
4066 gen_aa32_ld64(tmp64, addr, IS_USER(s));
4067 neon_store_reg64(tmp64, rd);
4069 neon_load_reg64(tmp64, rd);
4070 gen_aa32_st64(tmp64, addr, IS_USER(s));
4072 tcg_temp_free_i64(tmp64);
4073 tcg_gen_addi_i32(addr, addr, stride);
4075 for (pass = 0; pass < 2; pass++) {
4078 tmp = tcg_temp_new_i32();
4079 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4080 neon_store_reg(rd, pass, tmp);
4082 tmp = neon_load_reg(rd, pass);
4083 gen_aa32_st32(tmp, addr, IS_USER(s));
4084 tcg_temp_free_i32(tmp);
4086 tcg_gen_addi_i32(addr, addr, stride);
4087 } else if (size == 1) {
4089 tmp = tcg_temp_new_i32();
4090 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4091 tcg_gen_addi_i32(addr, addr, stride);
4092 tmp2 = tcg_temp_new_i32();
4093 gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4094 tcg_gen_addi_i32(addr, addr, stride);
4095 tcg_gen_shli_i32(tmp2, tmp2, 16);
4096 tcg_gen_or_i32(tmp, tmp, tmp2);
4097 tcg_temp_free_i32(tmp2);
4098 neon_store_reg(rd, pass, tmp);
4100 tmp = neon_load_reg(rd, pass);
4101 tmp2 = tcg_temp_new_i32();
4102 tcg_gen_shri_i32(tmp2, tmp, 16);
4103 gen_aa32_st16(tmp, addr, IS_USER(s));
4104 tcg_temp_free_i32(tmp);
4105 tcg_gen_addi_i32(addr, addr, stride);
4106 gen_aa32_st16(tmp2, addr, IS_USER(s));
4107 tcg_temp_free_i32(tmp2);
4108 tcg_gen_addi_i32(addr, addr, stride);
4110 } else /* size == 0 */ {
4112 TCGV_UNUSED_I32(tmp2);
4113 for (n = 0; n < 4; n++) {
4114 tmp = tcg_temp_new_i32();
4115 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4116 tcg_gen_addi_i32(addr, addr, stride);
4120 tcg_gen_shli_i32(tmp, tmp, n * 8);
4121 tcg_gen_or_i32(tmp2, tmp2, tmp);
4122 tcg_temp_free_i32(tmp);
4125 neon_store_reg(rd, pass, tmp2);
4127 tmp2 = neon_load_reg(rd, pass);
4128 for (n = 0; n < 4; n++) {
4129 tmp = tcg_temp_new_i32();
4131 tcg_gen_mov_i32(tmp, tmp2);
4133 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4135 gen_aa32_st8(tmp, addr, IS_USER(s));
4136 tcg_temp_free_i32(tmp);
4137 tcg_gen_addi_i32(addr, addr, stride);
4139 tcg_temp_free_i32(tmp2);
4146 tcg_temp_free_i32(addr);
4149 size = (insn >> 10) & 3;
4151 /* Load single element to all lanes. */
4152 int a = (insn >> 4) & 1;
4156 size = (insn >> 6) & 3;
4157 nregs = ((insn >> 8) & 3) + 1;
4160 if (nregs != 4 || a == 0) {
4163 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4166 if (nregs == 1 && a == 1 && size == 0) {
4169 if (nregs == 3 && a == 1) {
4172 addr = tcg_temp_new_i32();
4173 load_reg_var(s, addr, rn);
4175 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4176 tmp = gen_load_and_replicate(s, addr, size);
4177 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4178 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4179 if (insn & (1 << 5)) {
4180 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4181 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4183 tcg_temp_free_i32(tmp);
4185 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4186 stride = (insn & (1 << 5)) ? 2 : 1;
4187 for (reg = 0; reg < nregs; reg++) {
4188 tmp = gen_load_and_replicate(s, addr, size);
4189 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4190 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4191 tcg_temp_free_i32(tmp);
4192 tcg_gen_addi_i32(addr, addr, 1 << size);
4196 tcg_temp_free_i32(addr);
4197 stride = (1 << size) * nregs;
4199 /* Single element. */
4200 int idx = (insn >> 4) & 0xf;
4201 pass = (insn >> 7) & 1;
4204 shift = ((insn >> 5) & 3) * 8;
4208 shift = ((insn >> 6) & 1) * 16;
4209 stride = (insn & (1 << 5)) ? 2 : 1;
4213 stride = (insn & (1 << 6)) ? 2 : 1;
4218 nregs = ((insn >> 8) & 3) + 1;
4219 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4222 if (((idx & (1 << size)) != 0) ||
4223 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4228 if ((idx & 1) != 0) {
4233 if (size == 2 && (idx & 2) != 0) {
4238 if ((size == 2) && ((idx & 3) == 3)) {
4245 if ((rd + stride * (nregs - 1)) > 31) {
4246 /* Attempts to write off the end of the register file
4247 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4248 * the neon_load_reg() would write off the end of the array.
4252 addr = tcg_temp_new_i32();
4253 load_reg_var(s, addr, rn);
4254 for (reg = 0; reg < nregs; reg++) {
4256 tmp = tcg_temp_new_i32();
4259 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4262 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4265 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4267 default: /* Avoid compiler warnings. */
4271 tmp2 = neon_load_reg(rd, pass);
4272 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4273 shift, size ? 16 : 8);
4274 tcg_temp_free_i32(tmp2);
4276 neon_store_reg(rd, pass, tmp);
4277 } else { /* Store */
4278 tmp = neon_load_reg(rd, pass);
4280 tcg_gen_shri_i32(tmp, tmp, shift);
4283 gen_aa32_st8(tmp, addr, IS_USER(s));
4286 gen_aa32_st16(tmp, addr, IS_USER(s));
4289 gen_aa32_st32(tmp, addr, IS_USER(s));
4292 tcg_temp_free_i32(tmp);
4295 tcg_gen_addi_i32(addr, addr, 1 << size);
4297 tcg_temp_free_i32(addr);
4298 stride = nregs * (1 << size);
4304 base = load_reg(s, rn);
4306 tcg_gen_addi_i32(base, base, stride);
4309 index = load_reg(s, rm);
4310 tcg_gen_add_i32(base, base, index);
4311 tcg_temp_free_i32(index);
4313 store_reg(s, rn, base);
4318 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4319 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4321 tcg_gen_and_i32(t, t, c);
4322 tcg_gen_andc_i32(f, f, c);
4323 tcg_gen_or_i32(dest, t, f);
4326 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4329 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4330 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4331 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4336 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4339 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4340 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4341 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4346 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4349 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4350 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4351 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4356 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4359 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4360 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4361 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4366 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4372 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4373 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4378 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4379 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4386 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4387 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4392 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4393 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4400 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4404 case 0: gen_helper_neon_widen_u8(dest, src); break;
4405 case 1: gen_helper_neon_widen_u16(dest, src); break;
4406 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4411 case 0: gen_helper_neon_widen_s8(dest, src); break;
4412 case 1: gen_helper_neon_widen_s16(dest, src); break;
4413 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4417 tcg_temp_free_i32(src);
4420 static inline void gen_neon_addl(int size)
4423 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4424 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4425 case 2: tcg_gen_add_i64(CPU_V001); break;
4430 static inline void gen_neon_subl(int size)
4433 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4434 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4435 case 2: tcg_gen_sub_i64(CPU_V001); break;
4440 static inline void gen_neon_negl(TCGv_i64 var, int size)
4443 case 0: gen_helper_neon_negl_u16(var, var); break;
4444 case 1: gen_helper_neon_negl_u32(var, var); break;
4446 tcg_gen_neg_i64(var, var);
4452 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4455 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4456 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4461 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4466 switch ((size << 1) | u) {
4467 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4468 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4469 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4470 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4472 tmp = gen_muls_i64_i32(a, b);
4473 tcg_gen_mov_i64(dest, tmp);
4474 tcg_temp_free_i64(tmp);
4477 tmp = gen_mulu_i64_i32(a, b);
4478 tcg_gen_mov_i64(dest, tmp);
4479 tcg_temp_free_i64(tmp);
4484 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4485 Don't forget to clean them now. */
4487 tcg_temp_free_i32(a);
4488 tcg_temp_free_i32(b);
4492 static void gen_neon_narrow_op(int op, int u, int size,
4493 TCGv_i32 dest, TCGv_i64 src)
4497 gen_neon_unarrow_sats(size, dest, src);
4499 gen_neon_narrow(size, dest, src);
4503 gen_neon_narrow_satu(size, dest, src);
4505 gen_neon_narrow_sats(size, dest, src);
4510 /* Symbolic constants for op fields for Neon 3-register same-length.
4511 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4514 #define NEON_3R_VHADD 0
4515 #define NEON_3R_VQADD 1
4516 #define NEON_3R_VRHADD 2
4517 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4518 #define NEON_3R_VHSUB 4
4519 #define NEON_3R_VQSUB 5
4520 #define NEON_3R_VCGT 6
4521 #define NEON_3R_VCGE 7
4522 #define NEON_3R_VSHL 8
4523 #define NEON_3R_VQSHL 9
4524 #define NEON_3R_VRSHL 10
4525 #define NEON_3R_VQRSHL 11
4526 #define NEON_3R_VMAX 12
4527 #define NEON_3R_VMIN 13
4528 #define NEON_3R_VABD 14
4529 #define NEON_3R_VABA 15
4530 #define NEON_3R_VADD_VSUB 16
4531 #define NEON_3R_VTST_VCEQ 17
4532 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4533 #define NEON_3R_VMUL 19
4534 #define NEON_3R_VPMAX 20
4535 #define NEON_3R_VPMIN 21
4536 #define NEON_3R_VQDMULH_VQRDMULH 22
4537 #define NEON_3R_VPADD 23
4538 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4539 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4540 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4541 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4542 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4543 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4544 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4546 static const uint8_t neon_3r_sizes[] = {
4547 [NEON_3R_VHADD] = 0x7,
4548 [NEON_3R_VQADD] = 0xf,
4549 [NEON_3R_VRHADD] = 0x7,
4550 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4551 [NEON_3R_VHSUB] = 0x7,
4552 [NEON_3R_VQSUB] = 0xf,
4553 [NEON_3R_VCGT] = 0x7,
4554 [NEON_3R_VCGE] = 0x7,
4555 [NEON_3R_VSHL] = 0xf,
4556 [NEON_3R_VQSHL] = 0xf,
4557 [NEON_3R_VRSHL] = 0xf,
4558 [NEON_3R_VQRSHL] = 0xf,
4559 [NEON_3R_VMAX] = 0x7,
4560 [NEON_3R_VMIN] = 0x7,
4561 [NEON_3R_VABD] = 0x7,
4562 [NEON_3R_VABA] = 0x7,
4563 [NEON_3R_VADD_VSUB] = 0xf,
4564 [NEON_3R_VTST_VCEQ] = 0x7,
4565 [NEON_3R_VML] = 0x7,
4566 [NEON_3R_VMUL] = 0x7,
4567 [NEON_3R_VPMAX] = 0x7,
4568 [NEON_3R_VPMIN] = 0x7,
4569 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4570 [NEON_3R_VPADD] = 0x7,
4571 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4572 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4573 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4574 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4575 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4576 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4577 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4580 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4581 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4584 #define NEON_2RM_VREV64 0
4585 #define NEON_2RM_VREV32 1
4586 #define NEON_2RM_VREV16 2
4587 #define NEON_2RM_VPADDL 4
4588 #define NEON_2RM_VPADDL_U 5
4589 #define NEON_2RM_AESE 6 /* Includes AESD */
4590 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4591 #define NEON_2RM_VCLS 8
4592 #define NEON_2RM_VCLZ 9
4593 #define NEON_2RM_VCNT 10
4594 #define NEON_2RM_VMVN 11
4595 #define NEON_2RM_VPADAL 12
4596 #define NEON_2RM_VPADAL_U 13
4597 #define NEON_2RM_VQABS 14
4598 #define NEON_2RM_VQNEG 15
4599 #define NEON_2RM_VCGT0 16
4600 #define NEON_2RM_VCGE0 17
4601 #define NEON_2RM_VCEQ0 18
4602 #define NEON_2RM_VCLE0 19
4603 #define NEON_2RM_VCLT0 20
4604 #define NEON_2RM_VABS 22
4605 #define NEON_2RM_VNEG 23
4606 #define NEON_2RM_VCGT0_F 24
4607 #define NEON_2RM_VCGE0_F 25
4608 #define NEON_2RM_VCEQ0_F 26
4609 #define NEON_2RM_VCLE0_F 27
4610 #define NEON_2RM_VCLT0_F 28
4611 #define NEON_2RM_VABS_F 30
4612 #define NEON_2RM_VNEG_F 31
4613 #define NEON_2RM_VSWP 32
4614 #define NEON_2RM_VTRN 33
4615 #define NEON_2RM_VUZP 34
4616 #define NEON_2RM_VZIP 35
4617 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4618 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4619 #define NEON_2RM_VSHLL 38
4620 #define NEON_2RM_VCVT_F16_F32 44
4621 #define NEON_2RM_VCVT_F32_F16 46
4622 #define NEON_2RM_VRECPE 56
4623 #define NEON_2RM_VRSQRTE 57
4624 #define NEON_2RM_VRECPE_F 58
4625 #define NEON_2RM_VRSQRTE_F 59
4626 #define NEON_2RM_VCVT_FS 60
4627 #define NEON_2RM_VCVT_FU 61
4628 #define NEON_2RM_VCVT_SF 62
4629 #define NEON_2RM_VCVT_UF 63
4631 static int neon_2rm_is_float_op(int op)
4633 /* Return true if this neon 2reg-misc op is float-to-float */
4634 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4635 op >= NEON_2RM_VRECPE_F);
4638 /* Each entry in this array has bit n set if the insn allows
4639 * size value n (otherwise it will UNDEF). Since unallocated
4640 * op values will have no bits set they always UNDEF.
4642 static const uint8_t neon_2rm_sizes[] = {
4643 [NEON_2RM_VREV64] = 0x7,
4644 [NEON_2RM_VREV32] = 0x3,
4645 [NEON_2RM_VREV16] = 0x1,
4646 [NEON_2RM_VPADDL] = 0x7,
4647 [NEON_2RM_VPADDL_U] = 0x7,
4648 [NEON_2RM_AESE] = 0x1,
4649 [NEON_2RM_AESMC] = 0x1,
4650 [NEON_2RM_VCLS] = 0x7,
4651 [NEON_2RM_VCLZ] = 0x7,
4652 [NEON_2RM_VCNT] = 0x1,
4653 [NEON_2RM_VMVN] = 0x1,
4654 [NEON_2RM_VPADAL] = 0x7,
4655 [NEON_2RM_VPADAL_U] = 0x7,
4656 [NEON_2RM_VQABS] = 0x7,
4657 [NEON_2RM_VQNEG] = 0x7,
4658 [NEON_2RM_VCGT0] = 0x7,
4659 [NEON_2RM_VCGE0] = 0x7,
4660 [NEON_2RM_VCEQ0] = 0x7,
4661 [NEON_2RM_VCLE0] = 0x7,
4662 [NEON_2RM_VCLT0] = 0x7,
4663 [NEON_2RM_VABS] = 0x7,
4664 [NEON_2RM_VNEG] = 0x7,
4665 [NEON_2RM_VCGT0_F] = 0x4,
4666 [NEON_2RM_VCGE0_F] = 0x4,
4667 [NEON_2RM_VCEQ0_F] = 0x4,
4668 [NEON_2RM_VCLE0_F] = 0x4,
4669 [NEON_2RM_VCLT0_F] = 0x4,
4670 [NEON_2RM_VABS_F] = 0x4,
4671 [NEON_2RM_VNEG_F] = 0x4,
4672 [NEON_2RM_VSWP] = 0x1,
4673 [NEON_2RM_VTRN] = 0x7,
4674 [NEON_2RM_VUZP] = 0x7,
4675 [NEON_2RM_VZIP] = 0x7,
4676 [NEON_2RM_VMOVN] = 0x7,
4677 [NEON_2RM_VQMOVN] = 0x7,
4678 [NEON_2RM_VSHLL] = 0x7,
4679 [NEON_2RM_VCVT_F16_F32] = 0x2,
4680 [NEON_2RM_VCVT_F32_F16] = 0x2,
4681 [NEON_2RM_VRECPE] = 0x4,
4682 [NEON_2RM_VRSQRTE] = 0x4,
4683 [NEON_2RM_VRECPE_F] = 0x4,
4684 [NEON_2RM_VRSQRTE_F] = 0x4,
4685 [NEON_2RM_VCVT_FS] = 0x4,
4686 [NEON_2RM_VCVT_FU] = 0x4,
4687 [NEON_2RM_VCVT_SF] = 0x4,
4688 [NEON_2RM_VCVT_UF] = 0x4,
4691 /* Translate a NEON data processing instruction. Return nonzero if the
4692 instruction is invalid.
4693 We process data in a mixture of 32-bit and 64-bit chunks.
4694 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4696 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4708 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4711 if (!s->vfp_enabled)
4713 q = (insn & (1 << 6)) != 0;
4714 u = (insn >> 24) & 1;
4715 VFP_DREG_D(rd, insn);
4716 VFP_DREG_N(rn, insn);
4717 VFP_DREG_M(rm, insn);
4718 size = (insn >> 20) & 3;
4719 if ((insn & (1 << 23)) == 0) {
4720 /* Three register same length. */
4721 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4722 /* Catch invalid op and bad size combinations: UNDEF */
4723 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4726 /* All insns of this form UNDEF for either this condition or the
4727 * superset of cases "Q==1"; we catch the latter later.
4729 if (q && ((rd | rn | rm) & 1)) {
4732 if (size == 3 && op != NEON_3R_LOGIC) {
4733 /* 64-bit element instructions. */
4734 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4735 neon_load_reg64(cpu_V0, rn + pass);
4736 neon_load_reg64(cpu_V1, rm + pass);
4740 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4743 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4749 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4752 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4758 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4760 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4765 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4768 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4774 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4776 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4779 case NEON_3R_VQRSHL:
4781 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4784 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4788 case NEON_3R_VADD_VSUB:
4790 tcg_gen_sub_i64(CPU_V001);
4792 tcg_gen_add_i64(CPU_V001);
4798 neon_store_reg64(cpu_V0, rd + pass);
4807 case NEON_3R_VQRSHL:
4810 /* Shift instruction operands are reversed. */
4825 case NEON_3R_FLOAT_ARITH:
4826 pairwise = (u && size < 2); /* if VPADD (float) */
4828 case NEON_3R_FLOAT_MINMAX:
4829 pairwise = u; /* if VPMIN/VPMAX (float) */
4831 case NEON_3R_FLOAT_CMP:
4833 /* no encoding for U=0 C=1x */
4837 case NEON_3R_FLOAT_ACMP:
4842 case NEON_3R_FLOAT_MISC:
4843 /* VMAXNM/VMINNM in ARMv8 */
4844 if (u && !arm_feature(env, ARM_FEATURE_V8)) {
4849 if (u && (size != 0)) {
4850 /* UNDEF on invalid size for polynomial subcase */
4855 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4863 if (pairwise && q) {
4864 /* All the pairwise insns UNDEF if Q is set */
4868 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4873 tmp = neon_load_reg(rn, 0);
4874 tmp2 = neon_load_reg(rn, 1);
4876 tmp = neon_load_reg(rm, 0);
4877 tmp2 = neon_load_reg(rm, 1);
4881 tmp = neon_load_reg(rn, pass);
4882 tmp2 = neon_load_reg(rm, pass);
4886 GEN_NEON_INTEGER_OP(hadd);
4889 GEN_NEON_INTEGER_OP_ENV(qadd);
4891 case NEON_3R_VRHADD:
4892 GEN_NEON_INTEGER_OP(rhadd);
4894 case NEON_3R_LOGIC: /* Logic ops. */
4895 switch ((u << 2) | size) {
4897 tcg_gen_and_i32(tmp, tmp, tmp2);
4900 tcg_gen_andc_i32(tmp, tmp, tmp2);
4903 tcg_gen_or_i32(tmp, tmp, tmp2);
4906 tcg_gen_orc_i32(tmp, tmp, tmp2);
4909 tcg_gen_xor_i32(tmp, tmp, tmp2);
4912 tmp3 = neon_load_reg(rd, pass);
4913 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4914 tcg_temp_free_i32(tmp3);
4917 tmp3 = neon_load_reg(rd, pass);
4918 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4919 tcg_temp_free_i32(tmp3);
4922 tmp3 = neon_load_reg(rd, pass);
4923 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4924 tcg_temp_free_i32(tmp3);
4929 GEN_NEON_INTEGER_OP(hsub);
4932 GEN_NEON_INTEGER_OP_ENV(qsub);
4935 GEN_NEON_INTEGER_OP(cgt);
4938 GEN_NEON_INTEGER_OP(cge);
4941 GEN_NEON_INTEGER_OP(shl);
4944 GEN_NEON_INTEGER_OP_ENV(qshl);
4947 GEN_NEON_INTEGER_OP(rshl);
4949 case NEON_3R_VQRSHL:
4950 GEN_NEON_INTEGER_OP_ENV(qrshl);
4953 GEN_NEON_INTEGER_OP(max);
4956 GEN_NEON_INTEGER_OP(min);
4959 GEN_NEON_INTEGER_OP(abd);
4962 GEN_NEON_INTEGER_OP(abd);
4963 tcg_temp_free_i32(tmp2);
4964 tmp2 = neon_load_reg(rd, pass);
4965 gen_neon_add(size, tmp, tmp2);
4967 case NEON_3R_VADD_VSUB:
4968 if (!u) { /* VADD */
4969 gen_neon_add(size, tmp, tmp2);
4972 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4973 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4974 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4979 case NEON_3R_VTST_VCEQ:
4980 if (!u) { /* VTST */
4982 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4983 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4984 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4989 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4990 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4991 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4996 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4998 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4999 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5000 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5003 tcg_temp_free_i32(tmp2);
5004 tmp2 = neon_load_reg(rd, pass);
5006 gen_neon_rsb(size, tmp, tmp2);
5008 gen_neon_add(size, tmp, tmp2);
5012 if (u) { /* polynomial */
5013 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5014 } else { /* Integer */
5016 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5017 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5018 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5024 GEN_NEON_INTEGER_OP(pmax);
5027 GEN_NEON_INTEGER_OP(pmin);
5029 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5030 if (!u) { /* VQDMULH */
5033 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5036 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5040 } else { /* VQRDMULH */
5043 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5046 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5054 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5055 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5056 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5060 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5062 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5063 switch ((u << 2) | size) {
5066 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5069 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5072 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5077 tcg_temp_free_ptr(fpstatus);
5080 case NEON_3R_FLOAT_MULTIPLY:
5082 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5083 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5085 tcg_temp_free_i32(tmp2);
5086 tmp2 = neon_load_reg(rd, pass);
5088 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5090 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5093 tcg_temp_free_ptr(fpstatus);
5096 case NEON_3R_FLOAT_CMP:
5098 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5100 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5103 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5105 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5108 tcg_temp_free_ptr(fpstatus);
5111 case NEON_3R_FLOAT_ACMP:
5113 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5115 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5117 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5119 tcg_temp_free_ptr(fpstatus);
5122 case NEON_3R_FLOAT_MINMAX:
5124 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5126 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5128 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5130 tcg_temp_free_ptr(fpstatus);
5133 case NEON_3R_FLOAT_MISC:
5136 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5138 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5140 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5142 tcg_temp_free_ptr(fpstatus);
5145 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5147 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5153 /* VFMA, VFMS: fused multiply-add */
5154 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5155 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5158 gen_helper_vfp_negs(tmp, tmp);
5160 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5161 tcg_temp_free_i32(tmp3);
5162 tcg_temp_free_ptr(fpstatus);
5168 tcg_temp_free_i32(tmp2);
5170 /* Save the result. For elementwise operations we can put it
5171 straight into the destination register. For pairwise operations
5172 we have to be careful to avoid clobbering the source operands. */
5173 if (pairwise && rd == rm) {
5174 neon_store_scratch(pass, tmp);
5176 neon_store_reg(rd, pass, tmp);
5180 if (pairwise && rd == rm) {
5181 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5182 tmp = neon_load_scratch(pass);
5183 neon_store_reg(rd, pass, tmp);
5186 /* End of 3 register same size operations. */
5187 } else if (insn & (1 << 4)) {
5188 if ((insn & 0x00380080) != 0) {
5189 /* Two registers and shift. */
5190 op = (insn >> 8) & 0xf;
5191 if (insn & (1 << 7)) {
5199 while ((insn & (1 << (size + 19))) == 0)
5202 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5203 /* To avoid excessive duplication of ops we implement shift
5204 by immediate using the variable shift operations. */
5206 /* Shift by immediate:
5207 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5208 if (q && ((rd | rm) & 1)) {
5211 if (!u && (op == 4 || op == 6)) {
5214 /* Right shifts are encoded as N - shift, where N is the
5215 element size in bits. */
5217 shift = shift - (1 << (size + 3));
5225 imm = (uint8_t) shift;
5230 imm = (uint16_t) shift;
5241 for (pass = 0; pass < count; pass++) {
5243 neon_load_reg64(cpu_V0, rm + pass);
5244 tcg_gen_movi_i64(cpu_V1, imm);
5249 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5251 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5256 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5258 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5261 case 5: /* VSHL, VSLI */
5262 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5264 case 6: /* VQSHLU */
5265 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5270 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5273 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5278 if (op == 1 || op == 3) {
5280 neon_load_reg64(cpu_V1, rd + pass);
5281 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5282 } else if (op == 4 || (op == 5 && u)) {
5284 neon_load_reg64(cpu_V1, rd + pass);
5286 if (shift < -63 || shift > 63) {
5290 mask = 0xffffffffffffffffull >> -shift;
5292 mask = 0xffffffffffffffffull << shift;
5295 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5296 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5298 neon_store_reg64(cpu_V0, rd + pass);
5299 } else { /* size < 3 */
5300 /* Operands in T0 and T1. */
5301 tmp = neon_load_reg(rm, pass);
5302 tmp2 = tcg_temp_new_i32();
5303 tcg_gen_movi_i32(tmp2, imm);
5307 GEN_NEON_INTEGER_OP(shl);
5311 GEN_NEON_INTEGER_OP(rshl);
5314 case 5: /* VSHL, VSLI */
5316 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5317 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5318 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5322 case 6: /* VQSHLU */
5325 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5329 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5333 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5341 GEN_NEON_INTEGER_OP_ENV(qshl);
5344 tcg_temp_free_i32(tmp2);
5346 if (op == 1 || op == 3) {
5348 tmp2 = neon_load_reg(rd, pass);
5349 gen_neon_add(size, tmp, tmp2);
5350 tcg_temp_free_i32(tmp2);
5351 } else if (op == 4 || (op == 5 && u)) {
5356 mask = 0xff >> -shift;
5358 mask = (uint8_t)(0xff << shift);
5364 mask = 0xffff >> -shift;
5366 mask = (uint16_t)(0xffff << shift);
5370 if (shift < -31 || shift > 31) {
5374 mask = 0xffffffffu >> -shift;
5376 mask = 0xffffffffu << shift;
5382 tmp2 = neon_load_reg(rd, pass);
5383 tcg_gen_andi_i32(tmp, tmp, mask);
5384 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5385 tcg_gen_or_i32(tmp, tmp, tmp2);
5386 tcg_temp_free_i32(tmp2);
5388 neon_store_reg(rd, pass, tmp);
5391 } else if (op < 10) {
5392 /* Shift by immediate and narrow:
5393 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5394 int input_unsigned = (op == 8) ? !u : u;
5398 shift = shift - (1 << (size + 3));
5401 tmp64 = tcg_const_i64(shift);
5402 neon_load_reg64(cpu_V0, rm);
5403 neon_load_reg64(cpu_V1, rm + 1);
5404 for (pass = 0; pass < 2; pass++) {
5412 if (input_unsigned) {
5413 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5415 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5418 if (input_unsigned) {
5419 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5421 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5424 tmp = tcg_temp_new_i32();
5425 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5426 neon_store_reg(rd, pass, tmp);
5428 tcg_temp_free_i64(tmp64);
5431 imm = (uint16_t)shift;
5435 imm = (uint32_t)shift;
5437 tmp2 = tcg_const_i32(imm);
5438 tmp4 = neon_load_reg(rm + 1, 0);
5439 tmp5 = neon_load_reg(rm + 1, 1);
5440 for (pass = 0; pass < 2; pass++) {
5442 tmp = neon_load_reg(rm, 0);
5446 gen_neon_shift_narrow(size, tmp, tmp2, q,
5449 tmp3 = neon_load_reg(rm, 1);
5453 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5455 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5456 tcg_temp_free_i32(tmp);
5457 tcg_temp_free_i32(tmp3);
5458 tmp = tcg_temp_new_i32();
5459 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5460 neon_store_reg(rd, pass, tmp);
5462 tcg_temp_free_i32(tmp2);
5464 } else if (op == 10) {
5466 if (q || (rd & 1)) {
5469 tmp = neon_load_reg(rm, 0);
5470 tmp2 = neon_load_reg(rm, 1);
5471 for (pass = 0; pass < 2; pass++) {
5475 gen_neon_widen(cpu_V0, tmp, size, u);
5478 /* The shift is less than the width of the source
5479 type, so we can just shift the whole register. */
5480 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5481 /* Widen the result of shift: we need to clear
5482 * the potential overflow bits resulting from
5483 * left bits of the narrow input appearing as
5484 * right bits of left the neighbour narrow
5486 if (size < 2 || !u) {
5489 imm = (0xffu >> (8 - shift));
5491 } else if (size == 1) {
5492 imm = 0xffff >> (16 - shift);
5495 imm = 0xffffffff >> (32 - shift);
5498 imm64 = imm | (((uint64_t)imm) << 32);
5502 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5505 neon_store_reg64(cpu_V0, rd + pass);
5507 } else if (op >= 14) {
5508 /* VCVT fixed-point. */
5509 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5512 /* We have already masked out the must-be-1 top bit of imm6,
5513 * hence this 32-shift where the ARM ARM has 64-imm6.
5516 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5517 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5520 gen_vfp_ulto(0, shift, 1);
5522 gen_vfp_slto(0, shift, 1);
5525 gen_vfp_toul(0, shift, 1);
5527 gen_vfp_tosl(0, shift, 1);
5529 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5534 } else { /* (insn & 0x00380080) == 0 */
5536 if (q && (rd & 1)) {
5540 op = (insn >> 8) & 0xf;
5541 /* One register and immediate. */
5542 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5543 invert = (insn & (1 << 5)) != 0;
5544 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5545 * We choose to not special-case this and will behave as if a
5546 * valid constant encoding of 0 had been given.
5565 imm = (imm << 8) | (imm << 24);
5568 imm = (imm << 8) | 0xff;
5571 imm = (imm << 16) | 0xffff;
5574 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5582 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5583 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5589 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5590 if (op & 1 && op < 12) {
5591 tmp = neon_load_reg(rd, pass);
5593 /* The immediate value has already been inverted, so
5595 tcg_gen_andi_i32(tmp, tmp, imm);
5597 tcg_gen_ori_i32(tmp, tmp, imm);
5601 tmp = tcg_temp_new_i32();
5602 if (op == 14 && invert) {
5606 for (n = 0; n < 4; n++) {
5607 if (imm & (1 << (n + (pass & 1) * 4)))
5608 val |= 0xff << (n * 8);
5610 tcg_gen_movi_i32(tmp, val);
5612 tcg_gen_movi_i32(tmp, imm);
5615 neon_store_reg(rd, pass, tmp);
5618 } else { /* (insn & 0x00800010 == 0x00800000) */
5620 op = (insn >> 8) & 0xf;
5621 if ((insn & (1 << 6)) == 0) {
5622 /* Three registers of different lengths. */
5626 /* undefreq: bit 0 : UNDEF if size != 0
5627 * bit 1 : UNDEF if size == 0
5628 * bit 2 : UNDEF if U == 1
5629 * Note that [1:0] set implies 'always UNDEF'
5632 /* prewiden, src1_wide, src2_wide, undefreq */
5633 static const int neon_3reg_wide[16][4] = {
5634 {1, 0, 0, 0}, /* VADDL */
5635 {1, 1, 0, 0}, /* VADDW */
5636 {1, 0, 0, 0}, /* VSUBL */
5637 {1, 1, 0, 0}, /* VSUBW */
5638 {0, 1, 1, 0}, /* VADDHN */
5639 {0, 0, 0, 0}, /* VABAL */
5640 {0, 1, 1, 0}, /* VSUBHN */
5641 {0, 0, 0, 0}, /* VABDL */
5642 {0, 0, 0, 0}, /* VMLAL */
5643 {0, 0, 0, 6}, /* VQDMLAL */
5644 {0, 0, 0, 0}, /* VMLSL */
5645 {0, 0, 0, 6}, /* VQDMLSL */
5646 {0, 0, 0, 0}, /* Integer VMULL */
5647 {0, 0, 0, 2}, /* VQDMULL */
5648 {0, 0, 0, 5}, /* Polynomial VMULL */
5649 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5652 prewiden = neon_3reg_wide[op][0];
5653 src1_wide = neon_3reg_wide[op][1];
5654 src2_wide = neon_3reg_wide[op][2];
5655 undefreq = neon_3reg_wide[op][3];
5657 if (((undefreq & 1) && (size != 0)) ||
5658 ((undefreq & 2) && (size == 0)) ||
5659 ((undefreq & 4) && u)) {
5662 if ((src1_wide && (rn & 1)) ||
5663 (src2_wide && (rm & 1)) ||
5664 (!src2_wide && (rd & 1))) {
5668 /* Avoid overlapping operands. Wide source operands are
5669 always aligned so will never overlap with wide
5670 destinations in problematic ways. */
5671 if (rd == rm && !src2_wide) {
5672 tmp = neon_load_reg(rm, 1);
5673 neon_store_scratch(2, tmp);
5674 } else if (rd == rn && !src1_wide) {
5675 tmp = neon_load_reg(rn, 1);
5676 neon_store_scratch(2, tmp);
5678 TCGV_UNUSED_I32(tmp3);
5679 for (pass = 0; pass < 2; pass++) {
5681 neon_load_reg64(cpu_V0, rn + pass);
5682 TCGV_UNUSED_I32(tmp);
5684 if (pass == 1 && rd == rn) {
5685 tmp = neon_load_scratch(2);
5687 tmp = neon_load_reg(rn, pass);
5690 gen_neon_widen(cpu_V0, tmp, size, u);
5694 neon_load_reg64(cpu_V1, rm + pass);
5695 TCGV_UNUSED_I32(tmp2);
5697 if (pass == 1 && rd == rm) {
5698 tmp2 = neon_load_scratch(2);
5700 tmp2 = neon_load_reg(rm, pass);
5703 gen_neon_widen(cpu_V1, tmp2, size, u);
5707 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5708 gen_neon_addl(size);
5710 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5711 gen_neon_subl(size);
5713 case 5: case 7: /* VABAL, VABDL */
5714 switch ((size << 1) | u) {
5716 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5719 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5722 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5725 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5728 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5731 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5735 tcg_temp_free_i32(tmp2);
5736 tcg_temp_free_i32(tmp);
5738 case 8: case 9: case 10: case 11: case 12: case 13:
5739 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5740 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5742 case 14: /* Polynomial VMULL */
5743 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5744 tcg_temp_free_i32(tmp2);
5745 tcg_temp_free_i32(tmp);
5747 default: /* 15 is RESERVED: caught earlier */
5752 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5753 neon_store_reg64(cpu_V0, rd + pass);
5754 } else if (op == 5 || (op >= 8 && op <= 11)) {
5756 neon_load_reg64(cpu_V1, rd + pass);
5758 case 10: /* VMLSL */
5759 gen_neon_negl(cpu_V0, size);
5761 case 5: case 8: /* VABAL, VMLAL */
5762 gen_neon_addl(size);
5764 case 9: case 11: /* VQDMLAL, VQDMLSL */
5765 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5767 gen_neon_negl(cpu_V0, size);
5769 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5774 neon_store_reg64(cpu_V0, rd + pass);
5775 } else if (op == 4 || op == 6) {
5776 /* Narrowing operation. */
5777 tmp = tcg_temp_new_i32();
5781 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5784 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5787 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5788 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5795 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5798 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5801 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5802 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5803 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5811 neon_store_reg(rd, 0, tmp3);
5812 neon_store_reg(rd, 1, tmp);
5815 /* Write back the result. */
5816 neon_store_reg64(cpu_V0, rd + pass);
5820 /* Two registers and a scalar. NB that for ops of this form
5821 * the ARM ARM labels bit 24 as Q, but it is in our variable
5828 case 1: /* Float VMLA scalar */
5829 case 5: /* Floating point VMLS scalar */
5830 case 9: /* Floating point VMUL scalar */
5835 case 0: /* Integer VMLA scalar */
5836 case 4: /* Integer VMLS scalar */
5837 case 8: /* Integer VMUL scalar */
5838 case 12: /* VQDMULH scalar */
5839 case 13: /* VQRDMULH scalar */
5840 if (u && ((rd | rn) & 1)) {
5843 tmp = neon_get_scalar(size, rm);
5844 neon_store_scratch(0, tmp);
5845 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5846 tmp = neon_load_scratch(0);
5847 tmp2 = neon_load_reg(rn, pass);
5850 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5852 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5854 } else if (op == 13) {
5856 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5858 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5860 } else if (op & 1) {
5861 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5862 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5863 tcg_temp_free_ptr(fpstatus);
5866 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5867 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5868 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5872 tcg_temp_free_i32(tmp2);
5875 tmp2 = neon_load_reg(rd, pass);
5878 gen_neon_add(size, tmp, tmp2);
5882 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5883 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5884 tcg_temp_free_ptr(fpstatus);
5888 gen_neon_rsb(size, tmp, tmp2);
5892 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5893 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5894 tcg_temp_free_ptr(fpstatus);
5900 tcg_temp_free_i32(tmp2);
5902 neon_store_reg(rd, pass, tmp);
5905 case 3: /* VQDMLAL scalar */
5906 case 7: /* VQDMLSL scalar */
5907 case 11: /* VQDMULL scalar */
5912 case 2: /* VMLAL sclar */
5913 case 6: /* VMLSL scalar */
5914 case 10: /* VMULL scalar */
5918 tmp2 = neon_get_scalar(size, rm);
5919 /* We need a copy of tmp2 because gen_neon_mull
5920 * deletes it during pass 0. */
5921 tmp4 = tcg_temp_new_i32();
5922 tcg_gen_mov_i32(tmp4, tmp2);
5923 tmp3 = neon_load_reg(rn, 1);
5925 for (pass = 0; pass < 2; pass++) {
5927 tmp = neon_load_reg(rn, 0);
5932 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5934 neon_load_reg64(cpu_V1, rd + pass);
5938 gen_neon_negl(cpu_V0, size);
5941 gen_neon_addl(size);
5944 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5946 gen_neon_negl(cpu_V0, size);
5948 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5954 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5959 neon_store_reg64(cpu_V0, rd + pass);
5964 default: /* 14 and 15 are RESERVED */
5968 } else { /* size == 3 */
5971 imm = (insn >> 8) & 0xf;
5976 if (q && ((rd | rn | rm) & 1)) {
5981 neon_load_reg64(cpu_V0, rn);
5983 neon_load_reg64(cpu_V1, rn + 1);
5985 } else if (imm == 8) {
5986 neon_load_reg64(cpu_V0, rn + 1);
5988 neon_load_reg64(cpu_V1, rm);
5991 tmp64 = tcg_temp_new_i64();
5993 neon_load_reg64(cpu_V0, rn);
5994 neon_load_reg64(tmp64, rn + 1);
5996 neon_load_reg64(cpu_V0, rn + 1);
5997 neon_load_reg64(tmp64, rm);
5999 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6000 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6001 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6003 neon_load_reg64(cpu_V1, rm);
6005 neon_load_reg64(cpu_V1, rm + 1);
6008 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6009 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6010 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6011 tcg_temp_free_i64(tmp64);
6014 neon_load_reg64(cpu_V0, rn);
6015 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6016 neon_load_reg64(cpu_V1, rm);
6017 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6018 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6020 neon_store_reg64(cpu_V0, rd);
6022 neon_store_reg64(cpu_V1, rd + 1);
6024 } else if ((insn & (1 << 11)) == 0) {
6025 /* Two register misc. */
6026 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6027 size = (insn >> 18) & 3;
6028 /* UNDEF for unknown op values and bad op-size combinations */
6029 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6032 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6033 q && ((rm | rd) & 1)) {
6037 case NEON_2RM_VREV64:
6038 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6039 tmp = neon_load_reg(rm, pass * 2);
6040 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6042 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6043 case 1: gen_swap_half(tmp); break;
6044 case 2: /* no-op */ break;
6047 neon_store_reg(rd, pass * 2 + 1, tmp);
6049 neon_store_reg(rd, pass * 2, tmp2);
6052 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6053 case 1: gen_swap_half(tmp2); break;
6056 neon_store_reg(rd, pass * 2, tmp2);
6060 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6061 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6062 for (pass = 0; pass < q + 1; pass++) {
6063 tmp = neon_load_reg(rm, pass * 2);
6064 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6065 tmp = neon_load_reg(rm, pass * 2 + 1);
6066 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6068 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6069 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6070 case 2: tcg_gen_add_i64(CPU_V001); break;
6073 if (op >= NEON_2RM_VPADAL) {
6075 neon_load_reg64(cpu_V1, rd + pass);
6076 gen_neon_addl(size);
6078 neon_store_reg64(cpu_V0, rd + pass);
6084 for (n = 0; n < (q ? 4 : 2); n += 2) {
6085 tmp = neon_load_reg(rm, n);
6086 tmp2 = neon_load_reg(rd, n + 1);
6087 neon_store_reg(rm, n, tmp2);
6088 neon_store_reg(rd, n + 1, tmp);
6095 if (gen_neon_unzip(rd, rm, size, q)) {
6100 if (gen_neon_zip(rd, rm, size, q)) {
6104 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6105 /* also VQMOVUN; op field and mnemonics don't line up */
6109 TCGV_UNUSED_I32(tmp2);
6110 for (pass = 0; pass < 2; pass++) {
6111 neon_load_reg64(cpu_V0, rm + pass);
6112 tmp = tcg_temp_new_i32();
6113 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6118 neon_store_reg(rd, 0, tmp2);
6119 neon_store_reg(rd, 1, tmp);
6123 case NEON_2RM_VSHLL:
6124 if (q || (rd & 1)) {
6127 tmp = neon_load_reg(rm, 0);
6128 tmp2 = neon_load_reg(rm, 1);
6129 for (pass = 0; pass < 2; pass++) {
6132 gen_neon_widen(cpu_V0, tmp, size, 1);
6133 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6134 neon_store_reg64(cpu_V0, rd + pass);
6137 case NEON_2RM_VCVT_F16_F32:
6138 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6142 tmp = tcg_temp_new_i32();
6143 tmp2 = tcg_temp_new_i32();
6144 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6145 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6146 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6147 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6148 tcg_gen_shli_i32(tmp2, tmp2, 16);
6149 tcg_gen_or_i32(tmp2, tmp2, tmp);
6150 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6151 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6152 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6153 neon_store_reg(rd, 0, tmp2);
6154 tmp2 = tcg_temp_new_i32();
6155 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6156 tcg_gen_shli_i32(tmp2, tmp2, 16);
6157 tcg_gen_or_i32(tmp2, tmp2, tmp);
6158 neon_store_reg(rd, 1, tmp2);
6159 tcg_temp_free_i32(tmp);
6161 case NEON_2RM_VCVT_F32_F16:
6162 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6166 tmp3 = tcg_temp_new_i32();
6167 tmp = neon_load_reg(rm, 0);
6168 tmp2 = neon_load_reg(rm, 1);
6169 tcg_gen_ext16u_i32(tmp3, tmp);
6170 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6171 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6172 tcg_gen_shri_i32(tmp3, tmp, 16);
6173 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6174 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6175 tcg_temp_free_i32(tmp);
6176 tcg_gen_ext16u_i32(tmp3, tmp2);
6177 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6178 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6179 tcg_gen_shri_i32(tmp3, tmp2, 16);
6180 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6181 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6182 tcg_temp_free_i32(tmp2);
6183 tcg_temp_free_i32(tmp3);
6185 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6186 if (!arm_feature(env, ARM_FEATURE_V8_AES)
6187 || ((rm | rd) & 1)) {
6190 tmp = tcg_const_i32(rd);
6191 tmp2 = tcg_const_i32(rm);
6193 /* Bit 6 is the lowest opcode bit; it distinguishes between
6194 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6196 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6198 if (op == NEON_2RM_AESE) {
6199 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6201 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6203 tcg_temp_free_i32(tmp);
6204 tcg_temp_free_i32(tmp2);
6205 tcg_temp_free_i32(tmp3);
6209 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6210 if (neon_2rm_is_float_op(op)) {
6211 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6212 neon_reg_offset(rm, pass));
6213 TCGV_UNUSED_I32(tmp);
6215 tmp = neon_load_reg(rm, pass);
6218 case NEON_2RM_VREV32:
6220 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6221 case 1: gen_swap_half(tmp); break;
6225 case NEON_2RM_VREV16:
6230 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6231 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6232 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6238 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6239 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6240 case 2: gen_helper_clz(tmp, tmp); break;
6245 gen_helper_neon_cnt_u8(tmp, tmp);
6248 tcg_gen_not_i32(tmp, tmp);
6250 case NEON_2RM_VQABS:
6253 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6256 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6259 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6264 case NEON_2RM_VQNEG:
6267 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6270 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6273 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6278 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6279 tmp2 = tcg_const_i32(0);
6281 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6282 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6283 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6286 tcg_temp_free_i32(tmp2);
6287 if (op == NEON_2RM_VCLE0) {
6288 tcg_gen_not_i32(tmp, tmp);
6291 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6292 tmp2 = tcg_const_i32(0);
6294 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6295 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6296 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6299 tcg_temp_free_i32(tmp2);
6300 if (op == NEON_2RM_VCLT0) {
6301 tcg_gen_not_i32(tmp, tmp);
6304 case NEON_2RM_VCEQ0:
6305 tmp2 = tcg_const_i32(0);
6307 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6308 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6309 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6312 tcg_temp_free_i32(tmp2);
6316 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6317 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6318 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6323 tmp2 = tcg_const_i32(0);
6324 gen_neon_rsb(size, tmp, tmp2);
6325 tcg_temp_free_i32(tmp2);
6327 case NEON_2RM_VCGT0_F:
6329 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6330 tmp2 = tcg_const_i32(0);
6331 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6332 tcg_temp_free_i32(tmp2);
6333 tcg_temp_free_ptr(fpstatus);
6336 case NEON_2RM_VCGE0_F:
6338 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6339 tmp2 = tcg_const_i32(0);
6340 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6341 tcg_temp_free_i32(tmp2);
6342 tcg_temp_free_ptr(fpstatus);
6345 case NEON_2RM_VCEQ0_F:
6347 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6348 tmp2 = tcg_const_i32(0);
6349 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6350 tcg_temp_free_i32(tmp2);
6351 tcg_temp_free_ptr(fpstatus);
6354 case NEON_2RM_VCLE0_F:
6356 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6357 tmp2 = tcg_const_i32(0);
6358 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6359 tcg_temp_free_i32(tmp2);
6360 tcg_temp_free_ptr(fpstatus);
6363 case NEON_2RM_VCLT0_F:
6365 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6366 tmp2 = tcg_const_i32(0);
6367 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6368 tcg_temp_free_i32(tmp2);
6369 tcg_temp_free_ptr(fpstatus);
6372 case NEON_2RM_VABS_F:
6375 case NEON_2RM_VNEG_F:
6379 tmp2 = neon_load_reg(rd, pass);
6380 neon_store_reg(rm, pass, tmp2);
6383 tmp2 = neon_load_reg(rd, pass);
6385 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6386 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6389 neon_store_reg(rm, pass, tmp2);
6391 case NEON_2RM_VRECPE:
6392 gen_helper_recpe_u32(tmp, tmp, cpu_env);
6394 case NEON_2RM_VRSQRTE:
6395 gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6397 case NEON_2RM_VRECPE_F:
6398 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6400 case NEON_2RM_VRSQRTE_F:
6401 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6403 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6406 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6409 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6410 gen_vfp_tosiz(0, 1);
6412 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6413 gen_vfp_touiz(0, 1);
6416 /* Reserved op values were caught by the
6417 * neon_2rm_sizes[] check earlier.
6421 if (neon_2rm_is_float_op(op)) {
6422 tcg_gen_st_f32(cpu_F0s, cpu_env,
6423 neon_reg_offset(rd, pass));
6425 neon_store_reg(rd, pass, tmp);
6430 } else if ((insn & (1 << 10)) == 0) {
6432 int n = ((insn >> 8) & 3) + 1;
6433 if ((rn + n) > 32) {
6434 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6435 * helper function running off the end of the register file.
6440 if (insn & (1 << 6)) {
6441 tmp = neon_load_reg(rd, 0);
6443 tmp = tcg_temp_new_i32();
6444 tcg_gen_movi_i32(tmp, 0);
6446 tmp2 = neon_load_reg(rm, 0);
6447 tmp4 = tcg_const_i32(rn);
6448 tmp5 = tcg_const_i32(n);
6449 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6450 tcg_temp_free_i32(tmp);
6451 if (insn & (1 << 6)) {
6452 tmp = neon_load_reg(rd, 1);
6454 tmp = tcg_temp_new_i32();
6455 tcg_gen_movi_i32(tmp, 0);
6457 tmp3 = neon_load_reg(rm, 1);
6458 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6459 tcg_temp_free_i32(tmp5);
6460 tcg_temp_free_i32(tmp4);
6461 neon_store_reg(rd, 0, tmp2);
6462 neon_store_reg(rd, 1, tmp3);
6463 tcg_temp_free_i32(tmp);
6464 } else if ((insn & 0x380) == 0) {
6466 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6469 if (insn & (1 << 19)) {
6470 tmp = neon_load_reg(rm, 1);
6472 tmp = neon_load_reg(rm, 0);
6474 if (insn & (1 << 16)) {
6475 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6476 } else if (insn & (1 << 17)) {
6477 if ((insn >> 18) & 1)
6478 gen_neon_dup_high16(tmp);
6480 gen_neon_dup_low16(tmp);
6482 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6483 tmp2 = tcg_temp_new_i32();
6484 tcg_gen_mov_i32(tmp2, tmp);
6485 neon_store_reg(rd, pass, tmp2);
6487 tcg_temp_free_i32(tmp);
6496 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6498 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6499 const ARMCPRegInfo *ri;
6501 cpnum = (insn >> 8) & 0xf;
6502 if (arm_feature(env, ARM_FEATURE_XSCALE)
6503 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6506 /* First check for coprocessor space used for actual instructions */
6510 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6511 return disas_iwmmxt_insn(env, s, insn);
6512 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6513 return disas_dsp_insn(env, s, insn);
6520 /* Otherwise treat as a generic register access */
6521 is64 = (insn & (1 << 25)) == 0;
6522 if (!is64 && ((insn & (1 << 4)) == 0)) {
6530 opc1 = (insn >> 4) & 0xf;
6532 rt2 = (insn >> 16) & 0xf;
6534 crn = (insn >> 16) & 0xf;
6535 opc1 = (insn >> 21) & 7;
6536 opc2 = (insn >> 5) & 7;
6539 isread = (insn >> 20) & 1;
6540 rt = (insn >> 12) & 0xf;
6542 ri = get_arm_cp_reginfo(s->cp_regs,
6543 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6545 /* Check access permissions */
6546 if (!cp_access_ok(s->current_pl, ri, isread)) {
6550 /* Handle special cases first */
6551 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6558 gen_set_pc_im(s, s->pc);
6559 s->is_jmp = DISAS_WFI;
6565 if (use_icount && (ri->type & ARM_CP_IO)) {
6574 if (ri->type & ARM_CP_CONST) {
6575 tmp64 = tcg_const_i64(ri->resetvalue);
6576 } else if (ri->readfn) {
6578 gen_set_pc_im(s, s->pc);
6579 tmp64 = tcg_temp_new_i64();
6580 tmpptr = tcg_const_ptr(ri);
6581 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6582 tcg_temp_free_ptr(tmpptr);
6584 tmp64 = tcg_temp_new_i64();
6585 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6587 tmp = tcg_temp_new_i32();
6588 tcg_gen_trunc_i64_i32(tmp, tmp64);
6589 store_reg(s, rt, tmp);
6590 tcg_gen_shri_i64(tmp64, tmp64, 32);
6591 tmp = tcg_temp_new_i32();
6592 tcg_gen_trunc_i64_i32(tmp, tmp64);
6593 tcg_temp_free_i64(tmp64);
6594 store_reg(s, rt2, tmp);
6597 if (ri->type & ARM_CP_CONST) {
6598 tmp = tcg_const_i32(ri->resetvalue);
6599 } else if (ri->readfn) {
6601 gen_set_pc_im(s, s->pc);
6602 tmp = tcg_temp_new_i32();
6603 tmpptr = tcg_const_ptr(ri);
6604 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6605 tcg_temp_free_ptr(tmpptr);
6607 tmp = load_cpu_offset(ri->fieldoffset);
6610 /* Destination register of r15 for 32 bit loads sets
6611 * the condition codes from the high 4 bits of the value
6614 tcg_temp_free_i32(tmp);
6616 store_reg(s, rt, tmp);
6621 if (ri->type & ARM_CP_CONST) {
6622 /* If not forbidden by access permissions, treat as WI */
6627 TCGv_i32 tmplo, tmphi;
6628 TCGv_i64 tmp64 = tcg_temp_new_i64();
6629 tmplo = load_reg(s, rt);
6630 tmphi = load_reg(s, rt2);
6631 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6632 tcg_temp_free_i32(tmplo);
6633 tcg_temp_free_i32(tmphi);
6635 TCGv_ptr tmpptr = tcg_const_ptr(ri);
6636 gen_set_pc_im(s, s->pc);
6637 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6638 tcg_temp_free_ptr(tmpptr);
6640 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6642 tcg_temp_free_i64(tmp64);
6647 gen_set_pc_im(s, s->pc);
6648 tmp = load_reg(s, rt);
6649 tmpptr = tcg_const_ptr(ri);
6650 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6651 tcg_temp_free_ptr(tmpptr);
6652 tcg_temp_free_i32(tmp);
6654 TCGv_i32 tmp = load_reg(s, rt);
6655 store_cpu_offset(tmp, ri->fieldoffset);
6660 if (use_icount && (ri->type & ARM_CP_IO)) {
6661 /* I/O operations must end the TB here (whether read or write) */
6664 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6665 /* We default to ending the TB on a coprocessor register write,
6666 * but allow this to be suppressed by the register definition
6667 * (usually only necessary to work around guest bugs).
6679 /* Store a 64-bit value to a register pair. Clobbers val. */
6680 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6683 tmp = tcg_temp_new_i32();
6684 tcg_gen_trunc_i64_i32(tmp, val);
6685 store_reg(s, rlow, tmp);
6686 tmp = tcg_temp_new_i32();
6687 tcg_gen_shri_i64(val, val, 32);
6688 tcg_gen_trunc_i64_i32(tmp, val);
6689 store_reg(s, rhigh, tmp);
6692 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6693 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6698 /* Load value and extend to 64 bits. */
6699 tmp = tcg_temp_new_i64();
6700 tmp2 = load_reg(s, rlow);
6701 tcg_gen_extu_i32_i64(tmp, tmp2);
6702 tcg_temp_free_i32(tmp2);
6703 tcg_gen_add_i64(val, val, tmp);
6704 tcg_temp_free_i64(tmp);
6707 /* load and add a 64-bit value from a register pair. */
6708 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6714 /* Load 64-bit value rd:rn. */
6715 tmpl = load_reg(s, rlow);
6716 tmph = load_reg(s, rhigh);
6717 tmp = tcg_temp_new_i64();
6718 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6719 tcg_temp_free_i32(tmpl);
6720 tcg_temp_free_i32(tmph);
6721 tcg_gen_add_i64(val, val, tmp);
6722 tcg_temp_free_i64(tmp);
6725 /* Set N and Z flags from hi|lo. */
6726 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6728 tcg_gen_mov_i32(cpu_NF, hi);
6729 tcg_gen_or_i32(cpu_ZF, lo, hi);
6732 /* Load/Store exclusive instructions are implemented by remembering
6733 the value/address loaded, and seeing if these are the same
6734 when the store is performed. This should be sufficient to implement
6735 the architecturally mandated semantics, and avoids having to monitor
6738 In system emulation mode only one CPU will be running at once, so
6739 this sequence is effectively atomic. In user emulation mode we
6740 throw an exception and handle the atomic operation elsewhere. */
6741 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6742 TCGv_i32 addr, int size)
6744 TCGv_i32 tmp = tcg_temp_new_i32();
6748 gen_aa32_ld8u(tmp, addr, IS_USER(s));
6751 gen_aa32_ld16u(tmp, addr, IS_USER(s));
6755 gen_aa32_ld32u(tmp, addr, IS_USER(s));
6762 TCGv_i32 tmp2 = tcg_temp_new_i32();
6763 TCGv_i32 tmp3 = tcg_temp_new_i32();
6765 tcg_gen_addi_i32(tmp2, addr, 4);
6766 gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
6767 tcg_temp_free_i32(tmp2);
6768 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
6769 store_reg(s, rt2, tmp3);
6771 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
6774 store_reg(s, rt, tmp);
6775 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
6778 static void gen_clrex(DisasContext *s)
6780 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6783 #ifdef CONFIG_USER_ONLY
6784 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6785 TCGv_i32 addr, int size)
6787 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
6788 tcg_gen_movi_i32(cpu_exclusive_info,
6789 size | (rd << 4) | (rt << 8) | (rt2 << 12));
6790 gen_exception_insn(s, 4, EXCP_STREX);
6793 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6794 TCGv_i32 addr, int size)
6797 TCGv_i64 val64, extaddr;
6801 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6807 fail_label = gen_new_label();
6808 done_label = gen_new_label();
6809 extaddr = tcg_temp_new_i64();
6810 tcg_gen_extu_i32_i64(extaddr, addr);
6811 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
6812 tcg_temp_free_i64(extaddr);
6814 tmp = tcg_temp_new_i32();
6817 gen_aa32_ld8u(tmp, addr, IS_USER(s));
6820 gen_aa32_ld16u(tmp, addr, IS_USER(s));
6824 gen_aa32_ld32u(tmp, addr, IS_USER(s));
6830 val64 = tcg_temp_new_i64();
6832 TCGv_i32 tmp2 = tcg_temp_new_i32();
6833 TCGv_i32 tmp3 = tcg_temp_new_i32();
6834 tcg_gen_addi_i32(tmp2, addr, 4);
6835 gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
6836 tcg_temp_free_i32(tmp2);
6837 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
6838 tcg_temp_free_i32(tmp3);
6840 tcg_gen_extu_i32_i64(val64, tmp);
6842 tcg_temp_free_i32(tmp);
6844 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
6845 tcg_temp_free_i64(val64);
6847 tmp = load_reg(s, rt);
6850 gen_aa32_st8(tmp, addr, IS_USER(s));
6853 gen_aa32_st16(tmp, addr, IS_USER(s));
6857 gen_aa32_st32(tmp, addr, IS_USER(s));
6862 tcg_temp_free_i32(tmp);
6864 tcg_gen_addi_i32(addr, addr, 4);
6865 tmp = load_reg(s, rt2);
6866 gen_aa32_st32(tmp, addr, IS_USER(s));
6867 tcg_temp_free_i32(tmp);
6869 tcg_gen_movi_i32(cpu_R[rd], 0);
6870 tcg_gen_br(done_label);
6871 gen_set_label(fail_label);
6872 tcg_gen_movi_i32(cpu_R[rd], 1);
6873 gen_set_label(done_label);
6874 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6881 * @mode: mode field from insn (which stack to store to)
6882 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6883 * @writeback: true if writeback bit set
6885 * Generate code for the SRS (Store Return State) insn.
6887 static void gen_srs(DisasContext *s,
6888 uint32_t mode, uint32_t amode, bool writeback)
6891 TCGv_i32 addr = tcg_temp_new_i32();
6892 TCGv_i32 tmp = tcg_const_i32(mode);
6893 gen_helper_get_r13_banked(addr, cpu_env, tmp);
6894 tcg_temp_free_i32(tmp);
6911 tcg_gen_addi_i32(addr, addr, offset);
6912 tmp = load_reg(s, 14);
6913 gen_aa32_st32(tmp, addr, 0);
6914 tcg_temp_free_i32(tmp);
6915 tmp = load_cpu_field(spsr);
6916 tcg_gen_addi_i32(addr, addr, 4);
6917 gen_aa32_st32(tmp, addr, 0);
6918 tcg_temp_free_i32(tmp);
6936 tcg_gen_addi_i32(addr, addr, offset);
6937 tmp = tcg_const_i32(mode);
6938 gen_helper_set_r13_banked(cpu_env, tmp, addr);
6939 tcg_temp_free_i32(tmp);
6941 tcg_temp_free_i32(addr);
6944 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6946 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6953 insn = arm_ldl_code(env, s->pc, s->bswap_code);
6956 /* M variants do not implement ARM mode. */
6961 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6962 * choose to UNDEF. In ARMv5 and above the space is used
6963 * for miscellaneous unconditional instructions.
6967 /* Unconditional instructions. */
6968 if (((insn >> 25) & 7) == 1) {
6969 /* NEON Data processing. */
6970 if (!arm_feature(env, ARM_FEATURE_NEON))
6973 if (disas_neon_data_insn(env, s, insn))
6977 if ((insn & 0x0f100000) == 0x04000000) {
6978 /* NEON load/store. */
6979 if (!arm_feature(env, ARM_FEATURE_NEON))
6982 if (disas_neon_ls_insn(env, s, insn))
6986 if ((insn & 0x0f000e10) == 0x0e000a00) {
6988 if (disas_vfp_insn(env, s, insn)) {
6993 if (((insn & 0x0f30f000) == 0x0510f000) ||
6994 ((insn & 0x0f30f010) == 0x0710f000)) {
6995 if ((insn & (1 << 22)) == 0) {
6997 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7001 /* Otherwise PLD; v5TE+ */
7005 if (((insn & 0x0f70f000) == 0x0450f000) ||
7006 ((insn & 0x0f70f010) == 0x0650f000)) {
7008 return; /* PLI; V7 */
7010 if (((insn & 0x0f700000) == 0x04100000) ||
7011 ((insn & 0x0f700010) == 0x06100000)) {
7012 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7015 return; /* v7MP: Unallocated memory hint: must NOP */
7018 if ((insn & 0x0ffffdff) == 0x01010000) {
7021 if (((insn >> 9) & 1) != s->bswap_code) {
7022 /* Dynamic endianness switching not implemented. */
7023 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7027 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7028 switch ((insn >> 4) & 0xf) {
7037 /* We don't emulate caches so these are a no-op. */
7042 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7048 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7050 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7056 rn = (insn >> 16) & 0xf;
7057 addr = load_reg(s, rn);
7058 i = (insn >> 23) & 3;
7060 case 0: offset = -4; break; /* DA */
7061 case 1: offset = 0; break; /* IA */
7062 case 2: offset = -8; break; /* DB */
7063 case 3: offset = 4; break; /* IB */
7067 tcg_gen_addi_i32(addr, addr, offset);
7068 /* Load PC into tmp and CPSR into tmp2. */
7069 tmp = tcg_temp_new_i32();
7070 gen_aa32_ld32u(tmp, addr, 0);
7071 tcg_gen_addi_i32(addr, addr, 4);
7072 tmp2 = tcg_temp_new_i32();
7073 gen_aa32_ld32u(tmp2, addr, 0);
7074 if (insn & (1 << 21)) {
7075 /* Base writeback. */
7077 case 0: offset = -8; break;
7078 case 1: offset = 4; break;
7079 case 2: offset = -4; break;
7080 case 3: offset = 0; break;
7084 tcg_gen_addi_i32(addr, addr, offset);
7085 store_reg(s, rn, addr);
7087 tcg_temp_free_i32(addr);
7089 gen_rfe(s, tmp, tmp2);
7091 } else if ((insn & 0x0e000000) == 0x0a000000) {
7092 /* branch link and change to thumb (blx <offset>) */
7095 val = (uint32_t)s->pc;
7096 tmp = tcg_temp_new_i32();
7097 tcg_gen_movi_i32(tmp, val);
7098 store_reg(s, 14, tmp);
7099 /* Sign-extend the 24-bit offset */
7100 offset = (((int32_t)insn) << 8) >> 8;
7101 /* offset * 4 + bit24 * 2 + (thumb bit) */
7102 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7103 /* pipeline offset */
7105 /* protected by ARCH(5); above, near the start of uncond block */
7108 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7109 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7110 /* iWMMXt register transfer. */
7111 if (env->cp15.c15_cpar & (1 << 1))
7112 if (!disas_iwmmxt_insn(env, s, insn))
7115 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7116 /* Coprocessor double register transfer. */
7118 } else if ((insn & 0x0f000010) == 0x0e000010) {
7119 /* Additional coprocessor register transfer. */
7120 } else if ((insn & 0x0ff10020) == 0x01000000) {
7123 /* cps (privileged) */
7127 if (insn & (1 << 19)) {
7128 if (insn & (1 << 8))
7130 if (insn & (1 << 7))
7132 if (insn & (1 << 6))
7134 if (insn & (1 << 18))
7137 if (insn & (1 << 17)) {
7139 val |= (insn & 0x1f);
7142 gen_set_psr_im(s, mask, 0, val);
7149 /* if not always execute, we generate a conditional jump to
7151 s->condlabel = gen_new_label();
7152 arm_gen_test_cc(cond ^ 1, s->condlabel);
7155 if ((insn & 0x0f900000) == 0x03000000) {
7156 if ((insn & (1 << 21)) == 0) {
7158 rd = (insn >> 12) & 0xf;
7159 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7160 if ((insn & (1 << 22)) == 0) {
7162 tmp = tcg_temp_new_i32();
7163 tcg_gen_movi_i32(tmp, val);
7166 tmp = load_reg(s, rd);
7167 tcg_gen_ext16u_i32(tmp, tmp);
7168 tcg_gen_ori_i32(tmp, tmp, val << 16);
7170 store_reg(s, rd, tmp);
7172 if (((insn >> 12) & 0xf) != 0xf)
7174 if (((insn >> 16) & 0xf) == 0) {
7175 gen_nop_hint(s, insn & 0xff);
7177 /* CPSR = immediate */
7179 shift = ((insn >> 8) & 0xf) * 2;
7181 val = (val >> shift) | (val << (32 - shift));
7182 i = ((insn & (1 << 22)) != 0);
7183 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7187 } else if ((insn & 0x0f900000) == 0x01000000
7188 && (insn & 0x00000090) != 0x00000090) {
7189 /* miscellaneous instructions */
7190 op1 = (insn >> 21) & 3;
7191 sh = (insn >> 4) & 0xf;
7194 case 0x0: /* move program status register */
7197 tmp = load_reg(s, rm);
7198 i = ((op1 & 2) != 0);
7199 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7203 rd = (insn >> 12) & 0xf;
7207 tmp = load_cpu_field(spsr);
7209 tmp = tcg_temp_new_i32();
7210 gen_helper_cpsr_read(tmp, cpu_env);
7212 store_reg(s, rd, tmp);
7217 /* branch/exchange thumb (bx). */
7219 tmp = load_reg(s, rm);
7221 } else if (op1 == 3) {
7224 rd = (insn >> 12) & 0xf;
7225 tmp = load_reg(s, rm);
7226 gen_helper_clz(tmp, tmp);
7227 store_reg(s, rd, tmp);
7235 /* Trivial implementation equivalent to bx. */
7236 tmp = load_reg(s, rm);
7247 /* branch link/exchange thumb (blx) */
7248 tmp = load_reg(s, rm);
7249 tmp2 = tcg_temp_new_i32();
7250 tcg_gen_movi_i32(tmp2, s->pc);
7251 store_reg(s, 14, tmp2);
7254 case 0x5: /* saturating add/subtract */
7256 rd = (insn >> 12) & 0xf;
7257 rn = (insn >> 16) & 0xf;
7258 tmp = load_reg(s, rm);
7259 tmp2 = load_reg(s, rn);
7261 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7263 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7265 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7266 tcg_temp_free_i32(tmp2);
7267 store_reg(s, rd, tmp);
7270 /* SMC instruction (op1 == 3)
7271 and undefined instructions (op1 == 0 || op1 == 2)
7278 gen_exception_insn(s, 4, EXCP_BKPT);
7280 case 0x8: /* signed multiply */
7285 rs = (insn >> 8) & 0xf;
7286 rn = (insn >> 12) & 0xf;
7287 rd = (insn >> 16) & 0xf;
7289 /* (32 * 16) >> 16 */
7290 tmp = load_reg(s, rm);
7291 tmp2 = load_reg(s, rs);
7293 tcg_gen_sari_i32(tmp2, tmp2, 16);
7296 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7297 tcg_gen_shri_i64(tmp64, tmp64, 16);
7298 tmp = tcg_temp_new_i32();
7299 tcg_gen_trunc_i64_i32(tmp, tmp64);
7300 tcg_temp_free_i64(tmp64);
7301 if ((sh & 2) == 0) {
7302 tmp2 = load_reg(s, rn);
7303 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7304 tcg_temp_free_i32(tmp2);
7306 store_reg(s, rd, tmp);
7309 tmp = load_reg(s, rm);
7310 tmp2 = load_reg(s, rs);
7311 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7312 tcg_temp_free_i32(tmp2);
7314 tmp64 = tcg_temp_new_i64();
7315 tcg_gen_ext_i32_i64(tmp64, tmp);
7316 tcg_temp_free_i32(tmp);
7317 gen_addq(s, tmp64, rn, rd);
7318 gen_storeq_reg(s, rn, rd, tmp64);
7319 tcg_temp_free_i64(tmp64);
7322 tmp2 = load_reg(s, rn);
7323 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7324 tcg_temp_free_i32(tmp2);
7326 store_reg(s, rd, tmp);
7333 } else if (((insn & 0x0e000000) == 0 &&
7334 (insn & 0x00000090) != 0x90) ||
7335 ((insn & 0x0e000000) == (1 << 25))) {
7336 int set_cc, logic_cc, shiftop;
7338 op1 = (insn >> 21) & 0xf;
7339 set_cc = (insn >> 20) & 1;
7340 logic_cc = table_logic_cc[op1] & set_cc;
7342 /* data processing instruction */
7343 if (insn & (1 << 25)) {
7344 /* immediate operand */
7346 shift = ((insn >> 8) & 0xf) * 2;
7348 val = (val >> shift) | (val << (32 - shift));
7350 tmp2 = tcg_temp_new_i32();
7351 tcg_gen_movi_i32(tmp2, val);
7352 if (logic_cc && shift) {
7353 gen_set_CF_bit31(tmp2);
7358 tmp2 = load_reg(s, rm);
7359 shiftop = (insn >> 5) & 3;
7360 if (!(insn & (1 << 4))) {
7361 shift = (insn >> 7) & 0x1f;
7362 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7364 rs = (insn >> 8) & 0xf;
7365 tmp = load_reg(s, rs);
7366 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7369 if (op1 != 0x0f && op1 != 0x0d) {
7370 rn = (insn >> 16) & 0xf;
7371 tmp = load_reg(s, rn);
7373 TCGV_UNUSED_I32(tmp);
7375 rd = (insn >> 12) & 0xf;
7378 tcg_gen_and_i32(tmp, tmp, tmp2);
7382 store_reg_bx(env, s, rd, tmp);
7385 tcg_gen_xor_i32(tmp, tmp, tmp2);
7389 store_reg_bx(env, s, rd, tmp);
7392 if (set_cc && rd == 15) {
7393 /* SUBS r15, ... is used for exception return. */
7397 gen_sub_CC(tmp, tmp, tmp2);
7398 gen_exception_return(s, tmp);
7401 gen_sub_CC(tmp, tmp, tmp2);
7403 tcg_gen_sub_i32(tmp, tmp, tmp2);
7405 store_reg_bx(env, s, rd, tmp);
7410 gen_sub_CC(tmp, tmp2, tmp);
7412 tcg_gen_sub_i32(tmp, tmp2, tmp);
7414 store_reg_bx(env, s, rd, tmp);
7418 gen_add_CC(tmp, tmp, tmp2);
7420 tcg_gen_add_i32(tmp, tmp, tmp2);
7422 store_reg_bx(env, s, rd, tmp);
7426 gen_adc_CC(tmp, tmp, tmp2);
7428 gen_add_carry(tmp, tmp, tmp2);
7430 store_reg_bx(env, s, rd, tmp);
7434 gen_sbc_CC(tmp, tmp, tmp2);
7436 gen_sub_carry(tmp, tmp, tmp2);
7438 store_reg_bx(env, s, rd, tmp);
7442 gen_sbc_CC(tmp, tmp2, tmp);
7444 gen_sub_carry(tmp, tmp2, tmp);
7446 store_reg_bx(env, s, rd, tmp);
7450 tcg_gen_and_i32(tmp, tmp, tmp2);
7453 tcg_temp_free_i32(tmp);
7457 tcg_gen_xor_i32(tmp, tmp, tmp2);
7460 tcg_temp_free_i32(tmp);
7464 gen_sub_CC(tmp, tmp, tmp2);
7466 tcg_temp_free_i32(tmp);
7470 gen_add_CC(tmp, tmp, tmp2);
7472 tcg_temp_free_i32(tmp);
7475 tcg_gen_or_i32(tmp, tmp, tmp2);
7479 store_reg_bx(env, s, rd, tmp);
7482 if (logic_cc && rd == 15) {
7483 /* MOVS r15, ... is used for exception return. */
7487 gen_exception_return(s, tmp2);
7492 store_reg_bx(env, s, rd, tmp2);
7496 tcg_gen_andc_i32(tmp, tmp, tmp2);
7500 store_reg_bx(env, s, rd, tmp);
7504 tcg_gen_not_i32(tmp2, tmp2);
7508 store_reg_bx(env, s, rd, tmp2);
7511 if (op1 != 0x0f && op1 != 0x0d) {
7512 tcg_temp_free_i32(tmp2);
7515 /* other instructions */
7516 op1 = (insn >> 24) & 0xf;
7520 /* multiplies, extra load/stores */
7521 sh = (insn >> 5) & 3;
7524 rd = (insn >> 16) & 0xf;
7525 rn = (insn >> 12) & 0xf;
7526 rs = (insn >> 8) & 0xf;
7528 op1 = (insn >> 20) & 0xf;
7530 case 0: case 1: case 2: case 3: case 6:
7532 tmp = load_reg(s, rs);
7533 tmp2 = load_reg(s, rm);
7534 tcg_gen_mul_i32(tmp, tmp, tmp2);
7535 tcg_temp_free_i32(tmp2);
7536 if (insn & (1 << 22)) {
7537 /* Subtract (mls) */
7539 tmp2 = load_reg(s, rn);
7540 tcg_gen_sub_i32(tmp, tmp2, tmp);
7541 tcg_temp_free_i32(tmp2);
7542 } else if (insn & (1 << 21)) {
7544 tmp2 = load_reg(s, rn);
7545 tcg_gen_add_i32(tmp, tmp, tmp2);
7546 tcg_temp_free_i32(tmp2);
7548 if (insn & (1 << 20))
7550 store_reg(s, rd, tmp);
7553 /* 64 bit mul double accumulate (UMAAL) */
7555 tmp = load_reg(s, rs);
7556 tmp2 = load_reg(s, rm);
7557 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7558 gen_addq_lo(s, tmp64, rn);
7559 gen_addq_lo(s, tmp64, rd);
7560 gen_storeq_reg(s, rn, rd, tmp64);
7561 tcg_temp_free_i64(tmp64);
7563 case 8: case 9: case 10: case 11:
7564 case 12: case 13: case 14: case 15:
7565 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7566 tmp = load_reg(s, rs);
7567 tmp2 = load_reg(s, rm);
7568 if (insn & (1 << 22)) {
7569 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7571 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7573 if (insn & (1 << 21)) { /* mult accumulate */
7574 TCGv_i32 al = load_reg(s, rn);
7575 TCGv_i32 ah = load_reg(s, rd);
7576 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7577 tcg_temp_free_i32(al);
7578 tcg_temp_free_i32(ah);
7580 if (insn & (1 << 20)) {
7581 gen_logicq_cc(tmp, tmp2);
7583 store_reg(s, rn, tmp);
7584 store_reg(s, rd, tmp2);
7590 rn = (insn >> 16) & 0xf;
7591 rd = (insn >> 12) & 0xf;
7592 if (insn & (1 << 23)) {
7593 /* load/store exclusive */
7594 int op2 = (insn >> 8) & 3;
7595 op1 = (insn >> 21) & 0x3;
7598 case 0: /* lda/stl */
7604 case 1: /* reserved */
7606 case 2: /* ldaex/stlex */
7609 case 3: /* ldrex/strex */
7618 addr = tcg_temp_local_new_i32();
7619 load_reg_var(s, addr, rn);
7621 /* Since the emulation does not have barriers,
7622 the acquire/release semantics need no special
7625 if (insn & (1 << 20)) {
7626 tmp = tcg_temp_new_i32();
7629 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7632 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7635 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7640 store_reg(s, rd, tmp);
7643 tmp = load_reg(s, rm);
7646 gen_aa32_st32(tmp, addr, IS_USER(s));
7649 gen_aa32_st8(tmp, addr, IS_USER(s));
7652 gen_aa32_st16(tmp, addr, IS_USER(s));
7657 tcg_temp_free_i32(tmp);
7659 } else if (insn & (1 << 20)) {
7662 gen_load_exclusive(s, rd, 15, addr, 2);
7664 case 1: /* ldrexd */
7665 gen_load_exclusive(s, rd, rd + 1, addr, 3);
7667 case 2: /* ldrexb */
7668 gen_load_exclusive(s, rd, 15, addr, 0);
7670 case 3: /* ldrexh */
7671 gen_load_exclusive(s, rd, 15, addr, 1);
7680 gen_store_exclusive(s, rd, rm, 15, addr, 2);
7682 case 1: /* strexd */
7683 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7685 case 2: /* strexb */
7686 gen_store_exclusive(s, rd, rm, 15, addr, 0);
7688 case 3: /* strexh */
7689 gen_store_exclusive(s, rd, rm, 15, addr, 1);
7695 tcg_temp_free_i32(addr);
7697 /* SWP instruction */
7700 /* ??? This is not really atomic. However we know
7701 we never have multiple CPUs running in parallel,
7702 so it is good enough. */
7703 addr = load_reg(s, rn);
7704 tmp = load_reg(s, rm);
7705 tmp2 = tcg_temp_new_i32();
7706 if (insn & (1 << 22)) {
7707 gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7708 gen_aa32_st8(tmp, addr, IS_USER(s));
7710 gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7711 gen_aa32_st32(tmp, addr, IS_USER(s));
7713 tcg_temp_free_i32(tmp);
7714 tcg_temp_free_i32(addr);
7715 store_reg(s, rd, tmp2);
7721 /* Misc load/store */
7722 rn = (insn >> 16) & 0xf;
7723 rd = (insn >> 12) & 0xf;
7724 addr = load_reg(s, rn);
7725 if (insn & (1 << 24))
7726 gen_add_datah_offset(s, insn, 0, addr);
7728 if (insn & (1 << 20)) {
7730 tmp = tcg_temp_new_i32();
7733 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7736 gen_aa32_ld8s(tmp, addr, IS_USER(s));
7740 gen_aa32_ld16s(tmp, addr, IS_USER(s));
7744 } else if (sh & 2) {
7749 tmp = load_reg(s, rd);
7750 gen_aa32_st32(tmp, addr, IS_USER(s));
7751 tcg_temp_free_i32(tmp);
7752 tcg_gen_addi_i32(addr, addr, 4);
7753 tmp = load_reg(s, rd + 1);
7754 gen_aa32_st32(tmp, addr, IS_USER(s));
7755 tcg_temp_free_i32(tmp);
7759 tmp = tcg_temp_new_i32();
7760 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7761 store_reg(s, rd, tmp);
7762 tcg_gen_addi_i32(addr, addr, 4);
7763 tmp = tcg_temp_new_i32();
7764 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7768 address_offset = -4;
7771 tmp = load_reg(s, rd);
7772 gen_aa32_st16(tmp, addr, IS_USER(s));
7773 tcg_temp_free_i32(tmp);
7776 /* Perform base writeback before the loaded value to
7777 ensure correct behavior with overlapping index registers.
7778 ldrd with base writeback is is undefined if the
7779 destination and index registers overlap. */
7780 if (!(insn & (1 << 24))) {
7781 gen_add_datah_offset(s, insn, address_offset, addr);
7782 store_reg(s, rn, addr);
7783 } else if (insn & (1 << 21)) {
7785 tcg_gen_addi_i32(addr, addr, address_offset);
7786 store_reg(s, rn, addr);
7788 tcg_temp_free_i32(addr);
7791 /* Complete the load. */
7792 store_reg(s, rd, tmp);
7801 if (insn & (1 << 4)) {
7803 /* Armv6 Media instructions. */
7805 rn = (insn >> 16) & 0xf;
7806 rd = (insn >> 12) & 0xf;
7807 rs = (insn >> 8) & 0xf;
7808 switch ((insn >> 23) & 3) {
7809 case 0: /* Parallel add/subtract. */
7810 op1 = (insn >> 20) & 7;
7811 tmp = load_reg(s, rn);
7812 tmp2 = load_reg(s, rm);
7813 sh = (insn >> 5) & 7;
7814 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7816 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7817 tcg_temp_free_i32(tmp2);
7818 store_reg(s, rd, tmp);
7821 if ((insn & 0x00700020) == 0) {
7822 /* Halfword pack. */
7823 tmp = load_reg(s, rn);
7824 tmp2 = load_reg(s, rm);
7825 shift = (insn >> 7) & 0x1f;
7826 if (insn & (1 << 6)) {
7830 tcg_gen_sari_i32(tmp2, tmp2, shift);
7831 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7832 tcg_gen_ext16u_i32(tmp2, tmp2);
7836 tcg_gen_shli_i32(tmp2, tmp2, shift);
7837 tcg_gen_ext16u_i32(tmp, tmp);
7838 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7840 tcg_gen_or_i32(tmp, tmp, tmp2);
7841 tcg_temp_free_i32(tmp2);
7842 store_reg(s, rd, tmp);
7843 } else if ((insn & 0x00200020) == 0x00200000) {
7845 tmp = load_reg(s, rm);
7846 shift = (insn >> 7) & 0x1f;
7847 if (insn & (1 << 6)) {
7850 tcg_gen_sari_i32(tmp, tmp, shift);
7852 tcg_gen_shli_i32(tmp, tmp, shift);
7854 sh = (insn >> 16) & 0x1f;
7855 tmp2 = tcg_const_i32(sh);
7856 if (insn & (1 << 22))
7857 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7859 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7860 tcg_temp_free_i32(tmp2);
7861 store_reg(s, rd, tmp);
7862 } else if ((insn & 0x00300fe0) == 0x00200f20) {
7864 tmp = load_reg(s, rm);
7865 sh = (insn >> 16) & 0x1f;
7866 tmp2 = tcg_const_i32(sh);
7867 if (insn & (1 << 22))
7868 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7870 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7871 tcg_temp_free_i32(tmp2);
7872 store_reg(s, rd, tmp);
7873 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
7875 tmp = load_reg(s, rn);
7876 tmp2 = load_reg(s, rm);
7877 tmp3 = tcg_temp_new_i32();
7878 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7879 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7880 tcg_temp_free_i32(tmp3);
7881 tcg_temp_free_i32(tmp2);
7882 store_reg(s, rd, tmp);
7883 } else if ((insn & 0x000003e0) == 0x00000060) {
7884 tmp = load_reg(s, rm);
7885 shift = (insn >> 10) & 3;
7886 /* ??? In many cases it's not necessary to do a
7887 rotate, a shift is sufficient. */
7889 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7890 op1 = (insn >> 20) & 7;
7892 case 0: gen_sxtb16(tmp); break;
7893 case 2: gen_sxtb(tmp); break;
7894 case 3: gen_sxth(tmp); break;
7895 case 4: gen_uxtb16(tmp); break;
7896 case 6: gen_uxtb(tmp); break;
7897 case 7: gen_uxth(tmp); break;
7898 default: goto illegal_op;
7901 tmp2 = load_reg(s, rn);
7902 if ((op1 & 3) == 0) {
7903 gen_add16(tmp, tmp2);
7905 tcg_gen_add_i32(tmp, tmp, tmp2);
7906 tcg_temp_free_i32(tmp2);
7909 store_reg(s, rd, tmp);
7910 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
7912 tmp = load_reg(s, rm);
7913 if (insn & (1 << 22)) {
7914 if (insn & (1 << 7)) {
7918 gen_helper_rbit(tmp, tmp);
7921 if (insn & (1 << 7))
7924 tcg_gen_bswap32_i32(tmp, tmp);
7926 store_reg(s, rd, tmp);
7931 case 2: /* Multiplies (Type 3). */
7932 switch ((insn >> 20) & 0x7) {
7934 if (((insn >> 6) ^ (insn >> 7)) & 1) {
7935 /* op2 not 00x or 11x : UNDEF */
7938 /* Signed multiply most significant [accumulate].
7939 (SMMUL, SMMLA, SMMLS) */
7940 tmp = load_reg(s, rm);
7941 tmp2 = load_reg(s, rs);
7942 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7945 tmp = load_reg(s, rd);
7946 if (insn & (1 << 6)) {
7947 tmp64 = gen_subq_msw(tmp64, tmp);
7949 tmp64 = gen_addq_msw(tmp64, tmp);
7952 if (insn & (1 << 5)) {
7953 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7955 tcg_gen_shri_i64(tmp64, tmp64, 32);
7956 tmp = tcg_temp_new_i32();
7957 tcg_gen_trunc_i64_i32(tmp, tmp64);
7958 tcg_temp_free_i64(tmp64);
7959 store_reg(s, rn, tmp);
7963 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7964 if (insn & (1 << 7)) {
7967 tmp = load_reg(s, rm);
7968 tmp2 = load_reg(s, rs);
7969 if (insn & (1 << 5))
7970 gen_swap_half(tmp2);
7971 gen_smul_dual(tmp, tmp2);
7972 if (insn & (1 << 6)) {
7973 /* This subtraction cannot overflow. */
7974 tcg_gen_sub_i32(tmp, tmp, tmp2);
7976 /* This addition cannot overflow 32 bits;
7977 * however it may overflow considered as a signed
7978 * operation, in which case we must set the Q flag.
7980 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7982 tcg_temp_free_i32(tmp2);
7983 if (insn & (1 << 22)) {
7984 /* smlald, smlsld */
7985 tmp64 = tcg_temp_new_i64();
7986 tcg_gen_ext_i32_i64(tmp64, tmp);
7987 tcg_temp_free_i32(tmp);
7988 gen_addq(s, tmp64, rd, rn);
7989 gen_storeq_reg(s, rd, rn, tmp64);
7990 tcg_temp_free_i64(tmp64);
7992 /* smuad, smusd, smlad, smlsd */
7995 tmp2 = load_reg(s, rd);
7996 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7997 tcg_temp_free_i32(tmp2);
7999 store_reg(s, rn, tmp);
8005 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8008 if (((insn >> 5) & 7) || (rd != 15)) {
8011 tmp = load_reg(s, rm);
8012 tmp2 = load_reg(s, rs);
8013 if (insn & (1 << 21)) {
8014 gen_helper_udiv(tmp, tmp, tmp2);
8016 gen_helper_sdiv(tmp, tmp, tmp2);
8018 tcg_temp_free_i32(tmp2);
8019 store_reg(s, rn, tmp);
8026 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8028 case 0: /* Unsigned sum of absolute differences. */
8030 tmp = load_reg(s, rm);
8031 tmp2 = load_reg(s, rs);
8032 gen_helper_usad8(tmp, tmp, tmp2);
8033 tcg_temp_free_i32(tmp2);
8035 tmp2 = load_reg(s, rd);
8036 tcg_gen_add_i32(tmp, tmp, tmp2);
8037 tcg_temp_free_i32(tmp2);
8039 store_reg(s, rn, tmp);
8041 case 0x20: case 0x24: case 0x28: case 0x2c:
8042 /* Bitfield insert/clear. */
8044 shift = (insn >> 7) & 0x1f;
8045 i = (insn >> 16) & 0x1f;
8048 tmp = tcg_temp_new_i32();
8049 tcg_gen_movi_i32(tmp, 0);
8051 tmp = load_reg(s, rm);
8054 tmp2 = load_reg(s, rd);
8055 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8056 tcg_temp_free_i32(tmp2);
8058 store_reg(s, rd, tmp);
8060 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8061 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8063 tmp = load_reg(s, rm);
8064 shift = (insn >> 7) & 0x1f;
8065 i = ((insn >> 16) & 0x1f) + 1;
8070 gen_ubfx(tmp, shift, (1u << i) - 1);
8072 gen_sbfx(tmp, shift, i);
8075 store_reg(s, rd, tmp);
8085 /* Check for undefined extension instructions
8086 * per the ARM Bible IE:
8087 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8089 sh = (0xf << 20) | (0xf << 4);
8090 if (op1 == 0x7 && ((insn & sh) == sh))
8094 /* load/store byte/word */
8095 rn = (insn >> 16) & 0xf;
8096 rd = (insn >> 12) & 0xf;
8097 tmp2 = load_reg(s, rn);
8098 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8099 if (insn & (1 << 24))
8100 gen_add_data_offset(s, insn, tmp2);
8101 if (insn & (1 << 20)) {
8103 tmp = tcg_temp_new_i32();
8104 if (insn & (1 << 22)) {
8105 gen_aa32_ld8u(tmp, tmp2, i);
8107 gen_aa32_ld32u(tmp, tmp2, i);
8111 tmp = load_reg(s, rd);
8112 if (insn & (1 << 22)) {
8113 gen_aa32_st8(tmp, tmp2, i);
8115 gen_aa32_st32(tmp, tmp2, i);
8117 tcg_temp_free_i32(tmp);
8119 if (!(insn & (1 << 24))) {
8120 gen_add_data_offset(s, insn, tmp2);
8121 store_reg(s, rn, tmp2);
8122 } else if (insn & (1 << 21)) {
8123 store_reg(s, rn, tmp2);
8125 tcg_temp_free_i32(tmp2);
8127 if (insn & (1 << 20)) {
8128 /* Complete the load. */
8129 store_reg_from_load(env, s, rd, tmp);
8135 int j, n, user, loaded_base;
8136 TCGv_i32 loaded_var;
8137 /* load/store multiple words */
8138 /* XXX: store correct base if write back */
8140 if (insn & (1 << 22)) {
8142 goto illegal_op; /* only usable in supervisor mode */
8144 if ((insn & (1 << 15)) == 0)
8147 rn = (insn >> 16) & 0xf;
8148 addr = load_reg(s, rn);
8150 /* compute total size */
8152 TCGV_UNUSED_I32(loaded_var);
8155 if (insn & (1 << i))
8158 /* XXX: test invalid n == 0 case ? */
8159 if (insn & (1 << 23)) {
8160 if (insn & (1 << 24)) {
8162 tcg_gen_addi_i32(addr, addr, 4);
8164 /* post increment */
8167 if (insn & (1 << 24)) {
8169 tcg_gen_addi_i32(addr, addr, -(n * 4));
8171 /* post decrement */
8173 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8178 if (insn & (1 << i)) {
8179 if (insn & (1 << 20)) {
8181 tmp = tcg_temp_new_i32();
8182 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8184 tmp2 = tcg_const_i32(i);
8185 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8186 tcg_temp_free_i32(tmp2);
8187 tcg_temp_free_i32(tmp);
8188 } else if (i == rn) {
8192 store_reg_from_load(env, s, i, tmp);
8197 /* special case: r15 = PC + 8 */
8198 val = (long)s->pc + 4;
8199 tmp = tcg_temp_new_i32();
8200 tcg_gen_movi_i32(tmp, val);
8202 tmp = tcg_temp_new_i32();
8203 tmp2 = tcg_const_i32(i);
8204 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8205 tcg_temp_free_i32(tmp2);
8207 tmp = load_reg(s, i);
8209 gen_aa32_st32(tmp, addr, IS_USER(s));
8210 tcg_temp_free_i32(tmp);
8213 /* no need to add after the last transfer */
8215 tcg_gen_addi_i32(addr, addr, 4);
8218 if (insn & (1 << 21)) {
8220 if (insn & (1 << 23)) {
8221 if (insn & (1 << 24)) {
8224 /* post increment */
8225 tcg_gen_addi_i32(addr, addr, 4);
8228 if (insn & (1 << 24)) {
8231 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8233 /* post decrement */
8234 tcg_gen_addi_i32(addr, addr, -(n * 4));
8237 store_reg(s, rn, addr);
8239 tcg_temp_free_i32(addr);
8242 store_reg(s, rn, loaded_var);
8244 if ((insn & (1 << 22)) && !user) {
8245 /* Restore CPSR from SPSR. */
8246 tmp = load_cpu_field(spsr);
8247 gen_set_cpsr(tmp, 0xffffffff);
8248 tcg_temp_free_i32(tmp);
8249 s->is_jmp = DISAS_UPDATE;
8258 /* branch (and link) */
8259 val = (int32_t)s->pc;
8260 if (insn & (1 << 24)) {
8261 tmp = tcg_temp_new_i32();
8262 tcg_gen_movi_i32(tmp, val);
8263 store_reg(s, 14, tmp);
8265 offset = sextract32(insn << 2, 0, 26);
8273 if (((insn >> 8) & 0xe) == 10) {
8275 if (disas_vfp_insn(env, s, insn)) {
8278 } else if (disas_coproc_insn(env, s, insn)) {
8285 gen_set_pc_im(s, s->pc);
8286 s->is_jmp = DISAS_SWI;
8290 gen_exception_insn(s, 4, EXCP_UDEF);
8296 /* Return true if this is a Thumb-2 logical op. */
8298 thumb2_logic_op(int op)
8303 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8304 then set condition code flags based on the result of the operation.
8305 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8306 to the high bit of T1.
8307 Returns zero if the opcode is valid. */
8310 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8311 TCGv_i32 t0, TCGv_i32 t1)
8318 tcg_gen_and_i32(t0, t0, t1);
8322 tcg_gen_andc_i32(t0, t0, t1);
8326 tcg_gen_or_i32(t0, t0, t1);
8330 tcg_gen_orc_i32(t0, t0, t1);
8334 tcg_gen_xor_i32(t0, t0, t1);
8339 gen_add_CC(t0, t0, t1);
8341 tcg_gen_add_i32(t0, t0, t1);
8345 gen_adc_CC(t0, t0, t1);
8351 gen_sbc_CC(t0, t0, t1);
8353 gen_sub_carry(t0, t0, t1);
8358 gen_sub_CC(t0, t0, t1);
8360 tcg_gen_sub_i32(t0, t0, t1);
8364 gen_sub_CC(t0, t1, t0);
8366 tcg_gen_sub_i32(t0, t1, t0);
8368 default: /* 5, 6, 7, 9, 12, 15. */
8374 gen_set_CF_bit31(t1);
8379 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8381 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8383 uint32_t insn, imm, shift, offset;
8384 uint32_t rd, rn, rm, rs;
8395 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8396 || arm_feature (env, ARM_FEATURE_M))) {
8397 /* Thumb-1 cores may need to treat bl and blx as a pair of
8398 16-bit instructions to get correct prefetch abort behavior. */
8400 if ((insn & (1 << 12)) == 0) {
8402 /* Second half of blx. */
8403 offset = ((insn & 0x7ff) << 1);
8404 tmp = load_reg(s, 14);
8405 tcg_gen_addi_i32(tmp, tmp, offset);
8406 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8408 tmp2 = tcg_temp_new_i32();
8409 tcg_gen_movi_i32(tmp2, s->pc | 1);
8410 store_reg(s, 14, tmp2);
8414 if (insn & (1 << 11)) {
8415 /* Second half of bl. */
8416 offset = ((insn & 0x7ff) << 1) | 1;
8417 tmp = load_reg(s, 14);
8418 tcg_gen_addi_i32(tmp, tmp, offset);
8420 tmp2 = tcg_temp_new_i32();
8421 tcg_gen_movi_i32(tmp2, s->pc | 1);
8422 store_reg(s, 14, tmp2);
8426 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8427 /* Instruction spans a page boundary. Implement it as two
8428 16-bit instructions in case the second half causes an
8430 offset = ((int32_t)insn << 21) >> 9;
8431 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8434 /* Fall through to 32-bit decode. */
8437 insn = arm_lduw_code(env, s->pc, s->bswap_code);
8439 insn |= (uint32_t)insn_hw1 << 16;
8441 if ((insn & 0xf800e800) != 0xf000e800) {
8445 rn = (insn >> 16) & 0xf;
8446 rs = (insn >> 12) & 0xf;
8447 rd = (insn >> 8) & 0xf;
8449 switch ((insn >> 25) & 0xf) {
8450 case 0: case 1: case 2: case 3:
8451 /* 16-bit instructions. Should never happen. */
8454 if (insn & (1 << 22)) {
8455 /* Other load/store, table branch. */
8456 if (insn & 0x01200000) {
8457 /* Load/store doubleword. */
8459 addr = tcg_temp_new_i32();
8460 tcg_gen_movi_i32(addr, s->pc & ~3);
8462 addr = load_reg(s, rn);
8464 offset = (insn & 0xff) * 4;
8465 if ((insn & (1 << 23)) == 0)
8467 if (insn & (1 << 24)) {
8468 tcg_gen_addi_i32(addr, addr, offset);
8471 if (insn & (1 << 20)) {
8473 tmp = tcg_temp_new_i32();
8474 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8475 store_reg(s, rs, tmp);
8476 tcg_gen_addi_i32(addr, addr, 4);
8477 tmp = tcg_temp_new_i32();
8478 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8479 store_reg(s, rd, tmp);
8482 tmp = load_reg(s, rs);
8483 gen_aa32_st32(tmp, addr, IS_USER(s));
8484 tcg_temp_free_i32(tmp);
8485 tcg_gen_addi_i32(addr, addr, 4);
8486 tmp = load_reg(s, rd);
8487 gen_aa32_st32(tmp, addr, IS_USER(s));
8488 tcg_temp_free_i32(tmp);
8490 if (insn & (1 << 21)) {
8491 /* Base writeback. */
8494 tcg_gen_addi_i32(addr, addr, offset - 4);
8495 store_reg(s, rn, addr);
8497 tcg_temp_free_i32(addr);
8499 } else if ((insn & (1 << 23)) == 0) {
8500 /* Load/store exclusive word. */
8501 addr = tcg_temp_local_new_i32();
8502 load_reg_var(s, addr, rn);
8503 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8504 if (insn & (1 << 20)) {
8505 gen_load_exclusive(s, rs, 15, addr, 2);
8507 gen_store_exclusive(s, rd, rs, 15, addr, 2);
8509 tcg_temp_free_i32(addr);
8510 } else if ((insn & (7 << 5)) == 0) {
8513 addr = tcg_temp_new_i32();
8514 tcg_gen_movi_i32(addr, s->pc);
8516 addr = load_reg(s, rn);
8518 tmp = load_reg(s, rm);
8519 tcg_gen_add_i32(addr, addr, tmp);
8520 if (insn & (1 << 4)) {
8522 tcg_gen_add_i32(addr, addr, tmp);
8523 tcg_temp_free_i32(tmp);
8524 tmp = tcg_temp_new_i32();
8525 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8527 tcg_temp_free_i32(tmp);
8528 tmp = tcg_temp_new_i32();
8529 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8531 tcg_temp_free_i32(addr);
8532 tcg_gen_shli_i32(tmp, tmp, 1);
8533 tcg_gen_addi_i32(tmp, tmp, s->pc);
8534 store_reg(s, 15, tmp);
8536 int op2 = (insn >> 6) & 0x3;
8537 op = (insn >> 4) & 0x3;
8542 /* Load/store exclusive byte/halfword/doubleword */
8549 /* Load-acquire/store-release */
8555 /* Load-acquire/store-release exclusive */
8559 addr = tcg_temp_local_new_i32();
8560 load_reg_var(s, addr, rn);
8562 if (insn & (1 << 20)) {
8563 tmp = tcg_temp_new_i32();
8566 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8569 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8572 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8577 store_reg(s, rs, tmp);
8579 tmp = load_reg(s, rs);
8582 gen_aa32_st8(tmp, addr, IS_USER(s));
8585 gen_aa32_st16(tmp, addr, IS_USER(s));
8588 gen_aa32_st32(tmp, addr, IS_USER(s));
8593 tcg_temp_free_i32(tmp);
8595 } else if (insn & (1 << 20)) {
8596 gen_load_exclusive(s, rs, rd, addr, op);
8598 gen_store_exclusive(s, rm, rs, rd, addr, op);
8600 tcg_temp_free_i32(addr);
8603 /* Load/store multiple, RFE, SRS. */
8604 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8605 /* RFE, SRS: not available in user mode or on M profile */
8606 if (IS_USER(s) || IS_M(env)) {
8609 if (insn & (1 << 20)) {
8611 addr = load_reg(s, rn);
8612 if ((insn & (1 << 24)) == 0)
8613 tcg_gen_addi_i32(addr, addr, -8);
8614 /* Load PC into tmp and CPSR into tmp2. */
8615 tmp = tcg_temp_new_i32();
8616 gen_aa32_ld32u(tmp, addr, 0);
8617 tcg_gen_addi_i32(addr, addr, 4);
8618 tmp2 = tcg_temp_new_i32();
8619 gen_aa32_ld32u(tmp2, addr, 0);
8620 if (insn & (1 << 21)) {
8621 /* Base writeback. */
8622 if (insn & (1 << 24)) {
8623 tcg_gen_addi_i32(addr, addr, 4);
8625 tcg_gen_addi_i32(addr, addr, -4);
8627 store_reg(s, rn, addr);
8629 tcg_temp_free_i32(addr);
8631 gen_rfe(s, tmp, tmp2);
8634 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8638 int i, loaded_base = 0;
8639 TCGv_i32 loaded_var;
8640 /* Load/store multiple. */
8641 addr = load_reg(s, rn);
8643 for (i = 0; i < 16; i++) {
8644 if (insn & (1 << i))
8647 if (insn & (1 << 24)) {
8648 tcg_gen_addi_i32(addr, addr, -offset);
8651 TCGV_UNUSED_I32(loaded_var);
8652 for (i = 0; i < 16; i++) {
8653 if ((insn & (1 << i)) == 0)
8655 if (insn & (1 << 20)) {
8657 tmp = tcg_temp_new_i32();
8658 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8661 } else if (i == rn) {
8665 store_reg(s, i, tmp);
8669 tmp = load_reg(s, i);
8670 gen_aa32_st32(tmp, addr, IS_USER(s));
8671 tcg_temp_free_i32(tmp);
8673 tcg_gen_addi_i32(addr, addr, 4);
8676 store_reg(s, rn, loaded_var);
8678 if (insn & (1 << 21)) {
8679 /* Base register writeback. */
8680 if (insn & (1 << 24)) {
8681 tcg_gen_addi_i32(addr, addr, -offset);
8683 /* Fault if writeback register is in register list. */
8684 if (insn & (1 << rn))
8686 store_reg(s, rn, addr);
8688 tcg_temp_free_i32(addr);
8695 op = (insn >> 21) & 0xf;
8697 /* Halfword pack. */
8698 tmp = load_reg(s, rn);
8699 tmp2 = load_reg(s, rm);
8700 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8701 if (insn & (1 << 5)) {
8705 tcg_gen_sari_i32(tmp2, tmp2, shift);
8706 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8707 tcg_gen_ext16u_i32(tmp2, tmp2);
8711 tcg_gen_shli_i32(tmp2, tmp2, shift);
8712 tcg_gen_ext16u_i32(tmp, tmp);
8713 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8715 tcg_gen_or_i32(tmp, tmp, tmp2);
8716 tcg_temp_free_i32(tmp2);
8717 store_reg(s, rd, tmp);
8719 /* Data processing register constant shift. */
8721 tmp = tcg_temp_new_i32();
8722 tcg_gen_movi_i32(tmp, 0);
8724 tmp = load_reg(s, rn);
8726 tmp2 = load_reg(s, rm);
8728 shiftop = (insn >> 4) & 3;
8729 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8730 conds = (insn & (1 << 20)) != 0;
8731 logic_cc = (conds && thumb2_logic_op(op));
8732 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8733 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8735 tcg_temp_free_i32(tmp2);
8737 store_reg(s, rd, tmp);
8739 tcg_temp_free_i32(tmp);
8743 case 13: /* Misc data processing. */
8744 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8745 if (op < 4 && (insn & 0xf000) != 0xf000)
8748 case 0: /* Register controlled shift. */
8749 tmp = load_reg(s, rn);
8750 tmp2 = load_reg(s, rm);
8751 if ((insn & 0x70) != 0)
8753 op = (insn >> 21) & 3;
8754 logic_cc = (insn & (1 << 20)) != 0;
8755 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8758 store_reg_bx(env, s, rd, tmp);
8760 case 1: /* Sign/zero extend. */
8761 tmp = load_reg(s, rm);
8762 shift = (insn >> 4) & 3;
8763 /* ??? In many cases it's not necessary to do a
8764 rotate, a shift is sufficient. */
8766 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8767 op = (insn >> 20) & 7;
8769 case 0: gen_sxth(tmp); break;
8770 case 1: gen_uxth(tmp); break;
8771 case 2: gen_sxtb16(tmp); break;
8772 case 3: gen_uxtb16(tmp); break;
8773 case 4: gen_sxtb(tmp); break;
8774 case 5: gen_uxtb(tmp); break;
8775 default: goto illegal_op;
8778 tmp2 = load_reg(s, rn);
8779 if ((op >> 1) == 1) {
8780 gen_add16(tmp, tmp2);
8782 tcg_gen_add_i32(tmp, tmp, tmp2);
8783 tcg_temp_free_i32(tmp2);
8786 store_reg(s, rd, tmp);
8788 case 2: /* SIMD add/subtract. */
8789 op = (insn >> 20) & 7;
8790 shift = (insn >> 4) & 7;
8791 if ((op & 3) == 3 || (shift & 3) == 3)
8793 tmp = load_reg(s, rn);
8794 tmp2 = load_reg(s, rm);
8795 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8796 tcg_temp_free_i32(tmp2);
8797 store_reg(s, rd, tmp);
8799 case 3: /* Other data processing. */
8800 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8802 /* Saturating add/subtract. */
8803 tmp = load_reg(s, rn);
8804 tmp2 = load_reg(s, rm);
8806 gen_helper_double_saturate(tmp, cpu_env, tmp);
8808 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8810 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8811 tcg_temp_free_i32(tmp2);
8813 tmp = load_reg(s, rn);
8815 case 0x0a: /* rbit */
8816 gen_helper_rbit(tmp, tmp);
8818 case 0x08: /* rev */
8819 tcg_gen_bswap32_i32(tmp, tmp);
8821 case 0x09: /* rev16 */
8824 case 0x0b: /* revsh */
8827 case 0x10: /* sel */
8828 tmp2 = load_reg(s, rm);
8829 tmp3 = tcg_temp_new_i32();
8830 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8831 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8832 tcg_temp_free_i32(tmp3);
8833 tcg_temp_free_i32(tmp2);
8835 case 0x18: /* clz */
8836 gen_helper_clz(tmp, tmp);
8842 store_reg(s, rd, tmp);
8844 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8845 op = (insn >> 4) & 0xf;
8846 tmp = load_reg(s, rn);
8847 tmp2 = load_reg(s, rm);
8848 switch ((insn >> 20) & 7) {
8849 case 0: /* 32 x 32 -> 32 */
8850 tcg_gen_mul_i32(tmp, tmp, tmp2);
8851 tcg_temp_free_i32(tmp2);
8853 tmp2 = load_reg(s, rs);
8855 tcg_gen_sub_i32(tmp, tmp2, tmp);
8857 tcg_gen_add_i32(tmp, tmp, tmp2);
8858 tcg_temp_free_i32(tmp2);
8861 case 1: /* 16 x 16 -> 32 */
8862 gen_mulxy(tmp, tmp2, op & 2, op & 1);
8863 tcg_temp_free_i32(tmp2);
8865 tmp2 = load_reg(s, rs);
8866 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8867 tcg_temp_free_i32(tmp2);
8870 case 2: /* Dual multiply add. */
8871 case 4: /* Dual multiply subtract. */
8873 gen_swap_half(tmp2);
8874 gen_smul_dual(tmp, tmp2);
8875 if (insn & (1 << 22)) {
8876 /* This subtraction cannot overflow. */
8877 tcg_gen_sub_i32(tmp, tmp, tmp2);
8879 /* This addition cannot overflow 32 bits;
8880 * however it may overflow considered as a signed
8881 * operation, in which case we must set the Q flag.
8883 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8885 tcg_temp_free_i32(tmp2);
8888 tmp2 = load_reg(s, rs);
8889 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8890 tcg_temp_free_i32(tmp2);
8893 case 3: /* 32 * 16 -> 32msb */
8895 tcg_gen_sari_i32(tmp2, tmp2, 16);
8898 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8899 tcg_gen_shri_i64(tmp64, tmp64, 16);
8900 tmp = tcg_temp_new_i32();
8901 tcg_gen_trunc_i64_i32(tmp, tmp64);
8902 tcg_temp_free_i64(tmp64);
8905 tmp2 = load_reg(s, rs);
8906 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8907 tcg_temp_free_i32(tmp2);
8910 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8911 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8913 tmp = load_reg(s, rs);
8914 if (insn & (1 << 20)) {
8915 tmp64 = gen_addq_msw(tmp64, tmp);
8917 tmp64 = gen_subq_msw(tmp64, tmp);
8920 if (insn & (1 << 4)) {
8921 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8923 tcg_gen_shri_i64(tmp64, tmp64, 32);
8924 tmp = tcg_temp_new_i32();
8925 tcg_gen_trunc_i64_i32(tmp, tmp64);
8926 tcg_temp_free_i64(tmp64);
8928 case 7: /* Unsigned sum of absolute differences. */
8929 gen_helper_usad8(tmp, tmp, tmp2);
8930 tcg_temp_free_i32(tmp2);
8932 tmp2 = load_reg(s, rs);
8933 tcg_gen_add_i32(tmp, tmp, tmp2);
8934 tcg_temp_free_i32(tmp2);
8938 store_reg(s, rd, tmp);
8940 case 6: case 7: /* 64-bit multiply, Divide. */
8941 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8942 tmp = load_reg(s, rn);
8943 tmp2 = load_reg(s, rm);
8944 if ((op & 0x50) == 0x10) {
8946 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8950 gen_helper_udiv(tmp, tmp, tmp2);
8952 gen_helper_sdiv(tmp, tmp, tmp2);
8953 tcg_temp_free_i32(tmp2);
8954 store_reg(s, rd, tmp);
8955 } else if ((op & 0xe) == 0xc) {
8956 /* Dual multiply accumulate long. */
8958 gen_swap_half(tmp2);
8959 gen_smul_dual(tmp, tmp2);
8961 tcg_gen_sub_i32(tmp, tmp, tmp2);
8963 tcg_gen_add_i32(tmp, tmp, tmp2);
8965 tcg_temp_free_i32(tmp2);
8967 tmp64 = tcg_temp_new_i64();
8968 tcg_gen_ext_i32_i64(tmp64, tmp);
8969 tcg_temp_free_i32(tmp);
8970 gen_addq(s, tmp64, rs, rd);
8971 gen_storeq_reg(s, rs, rd, tmp64);
8972 tcg_temp_free_i64(tmp64);
8975 /* Unsigned 64-bit multiply */
8976 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8980 gen_mulxy(tmp, tmp2, op & 2, op & 1);
8981 tcg_temp_free_i32(tmp2);
8982 tmp64 = tcg_temp_new_i64();
8983 tcg_gen_ext_i32_i64(tmp64, tmp);
8984 tcg_temp_free_i32(tmp);
8986 /* Signed 64-bit multiply */
8987 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8992 gen_addq_lo(s, tmp64, rs);
8993 gen_addq_lo(s, tmp64, rd);
8994 } else if (op & 0x40) {
8995 /* 64-bit accumulate. */
8996 gen_addq(s, tmp64, rs, rd);
8998 gen_storeq_reg(s, rs, rd, tmp64);
8999 tcg_temp_free_i64(tmp64);
9004 case 6: case 7: case 14: case 15:
9006 if (((insn >> 24) & 3) == 3) {
9007 /* Translate into the equivalent ARM encoding. */
9008 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9009 if (disas_neon_data_insn(env, s, insn))
9011 } else if (((insn >> 8) & 0xe) == 10) {
9012 if (disas_vfp_insn(env, s, insn)) {
9016 if (insn & (1 << 28))
9018 if (disas_coproc_insn (env, s, insn))
9022 case 8: case 9: case 10: case 11:
9023 if (insn & (1 << 15)) {
9024 /* Branches, misc control. */
9025 if (insn & 0x5000) {
9026 /* Unconditional branch. */
9027 /* signextend(hw1[10:0]) -> offset[:12]. */
9028 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9029 /* hw1[10:0] -> offset[11:1]. */
9030 offset |= (insn & 0x7ff) << 1;
9031 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9032 offset[24:22] already have the same value because of the
9033 sign extension above. */
9034 offset ^= ((~insn) & (1 << 13)) << 10;
9035 offset ^= ((~insn) & (1 << 11)) << 11;
9037 if (insn & (1 << 14)) {
9038 /* Branch and link. */
9039 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9043 if (insn & (1 << 12)) {
9048 offset &= ~(uint32_t)2;
9049 /* thumb2 bx, no need to check */
9050 gen_bx_im(s, offset);
9052 } else if (((insn >> 23) & 7) == 7) {
9054 if (insn & (1 << 13))
9057 if (insn & (1 << 26)) {
9058 /* Secure monitor call (v6Z) */
9059 qemu_log_mask(LOG_UNIMP,
9060 "arm: unimplemented secure monitor call\n");
9061 goto illegal_op; /* not implemented. */
9063 op = (insn >> 20) & 7;
9065 case 0: /* msr cpsr. */
9067 tmp = load_reg(s, rn);
9068 addr = tcg_const_i32(insn & 0xff);
9069 gen_helper_v7m_msr(cpu_env, addr, tmp);
9070 tcg_temp_free_i32(addr);
9071 tcg_temp_free_i32(tmp);
9076 case 1: /* msr spsr. */
9079 tmp = load_reg(s, rn);
9081 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9085 case 2: /* cps, nop-hint. */
9086 if (((insn >> 8) & 7) == 0) {
9087 gen_nop_hint(s, insn & 0xff);
9089 /* Implemented as NOP in user mode. */
9094 if (insn & (1 << 10)) {
9095 if (insn & (1 << 7))
9097 if (insn & (1 << 6))
9099 if (insn & (1 << 5))
9101 if (insn & (1 << 9))
9102 imm = CPSR_A | CPSR_I | CPSR_F;
9104 if (insn & (1 << 8)) {
9106 imm |= (insn & 0x1f);
9109 gen_set_psr_im(s, offset, 0, imm);
9112 case 3: /* Special control operations. */
9114 op = (insn >> 4) & 0xf;
9122 /* These execute as NOPs. */
9129 /* Trivial implementation equivalent to bx. */
9130 tmp = load_reg(s, rn);
9133 case 5: /* Exception return. */
9137 if (rn != 14 || rd != 15) {
9140 tmp = load_reg(s, rn);
9141 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9142 gen_exception_return(s, tmp);
9144 case 6: /* mrs cpsr. */
9145 tmp = tcg_temp_new_i32();
9147 addr = tcg_const_i32(insn & 0xff);
9148 gen_helper_v7m_mrs(tmp, cpu_env, addr);
9149 tcg_temp_free_i32(addr);
9151 gen_helper_cpsr_read(tmp, cpu_env);
9153 store_reg(s, rd, tmp);
9155 case 7: /* mrs spsr. */
9156 /* Not accessible in user mode. */
9157 if (IS_USER(s) || IS_M(env))
9159 tmp = load_cpu_field(spsr);
9160 store_reg(s, rd, tmp);
9165 /* Conditional branch. */
9166 op = (insn >> 22) & 0xf;
9167 /* Generate a conditional jump to next instruction. */
9168 s->condlabel = gen_new_label();
9169 arm_gen_test_cc(op ^ 1, s->condlabel);
9172 /* offset[11:1] = insn[10:0] */
9173 offset = (insn & 0x7ff) << 1;
9174 /* offset[17:12] = insn[21:16]. */
9175 offset |= (insn & 0x003f0000) >> 4;
9176 /* offset[31:20] = insn[26]. */
9177 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9178 /* offset[18] = insn[13]. */
9179 offset |= (insn & (1 << 13)) << 5;
9180 /* offset[19] = insn[11]. */
9181 offset |= (insn & (1 << 11)) << 8;
9183 /* jump to the offset */
9184 gen_jmp(s, s->pc + offset);
9187 /* Data processing immediate. */
9188 if (insn & (1 << 25)) {
9189 if (insn & (1 << 24)) {
9190 if (insn & (1 << 20))
9192 /* Bitfield/Saturate. */
9193 op = (insn >> 21) & 7;
9195 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9197 tmp = tcg_temp_new_i32();
9198 tcg_gen_movi_i32(tmp, 0);
9200 tmp = load_reg(s, rn);
9203 case 2: /* Signed bitfield extract. */
9205 if (shift + imm > 32)
9208 gen_sbfx(tmp, shift, imm);
9210 case 6: /* Unsigned bitfield extract. */
9212 if (shift + imm > 32)
9215 gen_ubfx(tmp, shift, (1u << imm) - 1);
9217 case 3: /* Bitfield insert/clear. */
9220 imm = imm + 1 - shift;
9222 tmp2 = load_reg(s, rd);
9223 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9224 tcg_temp_free_i32(tmp2);
9229 default: /* Saturate. */
9232 tcg_gen_sari_i32(tmp, tmp, shift);
9234 tcg_gen_shli_i32(tmp, tmp, shift);
9236 tmp2 = tcg_const_i32(imm);
9239 if ((op & 1) && shift == 0)
9240 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9242 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9245 if ((op & 1) && shift == 0)
9246 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9248 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9250 tcg_temp_free_i32(tmp2);
9253 store_reg(s, rd, tmp);
9255 imm = ((insn & 0x04000000) >> 15)
9256 | ((insn & 0x7000) >> 4) | (insn & 0xff);
9257 if (insn & (1 << 22)) {
9258 /* 16-bit immediate. */
9259 imm |= (insn >> 4) & 0xf000;
9260 if (insn & (1 << 23)) {
9262 tmp = load_reg(s, rd);
9263 tcg_gen_ext16u_i32(tmp, tmp);
9264 tcg_gen_ori_i32(tmp, tmp, imm << 16);
9267 tmp = tcg_temp_new_i32();
9268 tcg_gen_movi_i32(tmp, imm);
9271 /* Add/sub 12-bit immediate. */
9273 offset = s->pc & ~(uint32_t)3;
9274 if (insn & (1 << 23))
9278 tmp = tcg_temp_new_i32();
9279 tcg_gen_movi_i32(tmp, offset);
9281 tmp = load_reg(s, rn);
9282 if (insn & (1 << 23))
9283 tcg_gen_subi_i32(tmp, tmp, imm);
9285 tcg_gen_addi_i32(tmp, tmp, imm);
9288 store_reg(s, rd, tmp);
9291 int shifter_out = 0;
9292 /* modified 12-bit immediate. */
9293 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9294 imm = (insn & 0xff);
9297 /* Nothing to do. */
9299 case 1: /* 00XY00XY */
9302 case 2: /* XY00XY00 */
9306 case 3: /* XYXYXYXY */
9310 default: /* Rotated constant. */
9311 shift = (shift << 1) | (imm >> 7);
9313 imm = imm << (32 - shift);
9317 tmp2 = tcg_temp_new_i32();
9318 tcg_gen_movi_i32(tmp2, imm);
9319 rn = (insn >> 16) & 0xf;
9321 tmp = tcg_temp_new_i32();
9322 tcg_gen_movi_i32(tmp, 0);
9324 tmp = load_reg(s, rn);
9326 op = (insn >> 21) & 0xf;
9327 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9328 shifter_out, tmp, tmp2))
9330 tcg_temp_free_i32(tmp2);
9331 rd = (insn >> 8) & 0xf;
9333 store_reg(s, rd, tmp);
9335 tcg_temp_free_i32(tmp);
9340 case 12: /* Load/store single data item. */
9345 if ((insn & 0x01100000) == 0x01000000) {
9346 if (disas_neon_ls_insn(env, s, insn))
9350 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9352 if (!(insn & (1 << 20))) {
9356 /* Byte or halfword load space with dest == r15 : memory hints.
9357 * Catch them early so we don't emit pointless addressing code.
9358 * This space is a mix of:
9359 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9360 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9362 * unallocated hints, which must be treated as NOPs
9363 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9364 * which is easiest for the decoding logic
9365 * Some space which must UNDEF
9367 int op1 = (insn >> 23) & 3;
9368 int op2 = (insn >> 6) & 0x3f;
9373 /* UNPREDICTABLE, unallocated hint or
9374 * PLD/PLDW/PLI (literal)
9379 return 0; /* PLD/PLDW/PLI or unallocated hint */
9381 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9382 return 0; /* PLD/PLDW/PLI or unallocated hint */
9384 /* UNDEF space, or an UNPREDICTABLE */
9390 addr = tcg_temp_new_i32();
9392 /* s->pc has already been incremented by 4. */
9393 imm = s->pc & 0xfffffffc;
9394 if (insn & (1 << 23))
9395 imm += insn & 0xfff;
9397 imm -= insn & 0xfff;
9398 tcg_gen_movi_i32(addr, imm);
9400 addr = load_reg(s, rn);
9401 if (insn & (1 << 23)) {
9402 /* Positive offset. */
9404 tcg_gen_addi_i32(addr, addr, imm);
9407 switch ((insn >> 8) & 0xf) {
9408 case 0x0: /* Shifted Register. */
9409 shift = (insn >> 4) & 0xf;
9411 tcg_temp_free_i32(addr);
9414 tmp = load_reg(s, rm);
9416 tcg_gen_shli_i32(tmp, tmp, shift);
9417 tcg_gen_add_i32(addr, addr, tmp);
9418 tcg_temp_free_i32(tmp);
9420 case 0xc: /* Negative offset. */
9421 tcg_gen_addi_i32(addr, addr, -imm);
9423 case 0xe: /* User privilege. */
9424 tcg_gen_addi_i32(addr, addr, imm);
9427 case 0x9: /* Post-decrement. */
9430 case 0xb: /* Post-increment. */
9434 case 0xd: /* Pre-decrement. */
9437 case 0xf: /* Pre-increment. */
9438 tcg_gen_addi_i32(addr, addr, imm);
9442 tcg_temp_free_i32(addr);
9447 if (insn & (1 << 20)) {
9449 tmp = tcg_temp_new_i32();
9452 gen_aa32_ld8u(tmp, addr, user);
9455 gen_aa32_ld8s(tmp, addr, user);
9458 gen_aa32_ld16u(tmp, addr, user);
9461 gen_aa32_ld16s(tmp, addr, user);
9464 gen_aa32_ld32u(tmp, addr, user);
9467 tcg_temp_free_i32(tmp);
9468 tcg_temp_free_i32(addr);
9474 store_reg(s, rs, tmp);
9478 tmp = load_reg(s, rs);
9481 gen_aa32_st8(tmp, addr, user);
9484 gen_aa32_st16(tmp, addr, user);
9487 gen_aa32_st32(tmp, addr, user);
9490 tcg_temp_free_i32(tmp);
9491 tcg_temp_free_i32(addr);
9494 tcg_temp_free_i32(tmp);
9497 tcg_gen_addi_i32(addr, addr, imm);
9499 store_reg(s, rn, addr);
9501 tcg_temp_free_i32(addr);
9513 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9515 uint32_t val, insn, op, rm, rn, rd, shift, cond;
9522 if (s->condexec_mask) {
9523 cond = s->condexec_cond;
9524 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9525 s->condlabel = gen_new_label();
9526 arm_gen_test_cc(cond ^ 1, s->condlabel);
9531 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9534 switch (insn >> 12) {
9538 op = (insn >> 11) & 3;
9541 rn = (insn >> 3) & 7;
9542 tmp = load_reg(s, rn);
9543 if (insn & (1 << 10)) {
9545 tmp2 = tcg_temp_new_i32();
9546 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9549 rm = (insn >> 6) & 7;
9550 tmp2 = load_reg(s, rm);
9552 if (insn & (1 << 9)) {
9553 if (s->condexec_mask)
9554 tcg_gen_sub_i32(tmp, tmp, tmp2);
9556 gen_sub_CC(tmp, tmp, tmp2);
9558 if (s->condexec_mask)
9559 tcg_gen_add_i32(tmp, tmp, tmp2);
9561 gen_add_CC(tmp, tmp, tmp2);
9563 tcg_temp_free_i32(tmp2);
9564 store_reg(s, rd, tmp);
9566 /* shift immediate */
9567 rm = (insn >> 3) & 7;
9568 shift = (insn >> 6) & 0x1f;
9569 tmp = load_reg(s, rm);
9570 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9571 if (!s->condexec_mask)
9573 store_reg(s, rd, tmp);
9577 /* arithmetic large immediate */
9578 op = (insn >> 11) & 3;
9579 rd = (insn >> 8) & 0x7;
9580 if (op == 0) { /* mov */
9581 tmp = tcg_temp_new_i32();
9582 tcg_gen_movi_i32(tmp, insn & 0xff);
9583 if (!s->condexec_mask)
9585 store_reg(s, rd, tmp);
9587 tmp = load_reg(s, rd);
9588 tmp2 = tcg_temp_new_i32();
9589 tcg_gen_movi_i32(tmp2, insn & 0xff);
9592 gen_sub_CC(tmp, tmp, tmp2);
9593 tcg_temp_free_i32(tmp);
9594 tcg_temp_free_i32(tmp2);
9597 if (s->condexec_mask)
9598 tcg_gen_add_i32(tmp, tmp, tmp2);
9600 gen_add_CC(tmp, tmp, tmp2);
9601 tcg_temp_free_i32(tmp2);
9602 store_reg(s, rd, tmp);
9605 if (s->condexec_mask)
9606 tcg_gen_sub_i32(tmp, tmp, tmp2);
9608 gen_sub_CC(tmp, tmp, tmp2);
9609 tcg_temp_free_i32(tmp2);
9610 store_reg(s, rd, tmp);
9616 if (insn & (1 << 11)) {
9617 rd = (insn >> 8) & 7;
9618 /* load pc-relative. Bit 1 of PC is ignored. */
9619 val = s->pc + 2 + ((insn & 0xff) * 4);
9620 val &= ~(uint32_t)2;
9621 addr = tcg_temp_new_i32();
9622 tcg_gen_movi_i32(addr, val);
9623 tmp = tcg_temp_new_i32();
9624 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9625 tcg_temp_free_i32(addr);
9626 store_reg(s, rd, tmp);
9629 if (insn & (1 << 10)) {
9630 /* data processing extended or blx */
9631 rd = (insn & 7) | ((insn >> 4) & 8);
9632 rm = (insn >> 3) & 0xf;
9633 op = (insn >> 8) & 3;
9636 tmp = load_reg(s, rd);
9637 tmp2 = load_reg(s, rm);
9638 tcg_gen_add_i32(tmp, tmp, tmp2);
9639 tcg_temp_free_i32(tmp2);
9640 store_reg(s, rd, tmp);
9643 tmp = load_reg(s, rd);
9644 tmp2 = load_reg(s, rm);
9645 gen_sub_CC(tmp, tmp, tmp2);
9646 tcg_temp_free_i32(tmp2);
9647 tcg_temp_free_i32(tmp);
9649 case 2: /* mov/cpy */
9650 tmp = load_reg(s, rm);
9651 store_reg(s, rd, tmp);
9653 case 3:/* branch [and link] exchange thumb register */
9654 tmp = load_reg(s, rm);
9655 if (insn & (1 << 7)) {
9657 val = (uint32_t)s->pc | 1;
9658 tmp2 = tcg_temp_new_i32();
9659 tcg_gen_movi_i32(tmp2, val);
9660 store_reg(s, 14, tmp2);
9662 /* already thumb, no need to check */
9669 /* data processing register */
9671 rm = (insn >> 3) & 7;
9672 op = (insn >> 6) & 0xf;
9673 if (op == 2 || op == 3 || op == 4 || op == 7) {
9674 /* the shift/rotate ops want the operands backwards */
9683 if (op == 9) { /* neg */
9684 tmp = tcg_temp_new_i32();
9685 tcg_gen_movi_i32(tmp, 0);
9686 } else if (op != 0xf) { /* mvn doesn't read its first operand */
9687 tmp = load_reg(s, rd);
9689 TCGV_UNUSED_I32(tmp);
9692 tmp2 = load_reg(s, rm);
9695 tcg_gen_and_i32(tmp, tmp, tmp2);
9696 if (!s->condexec_mask)
9700 tcg_gen_xor_i32(tmp, tmp, tmp2);
9701 if (!s->condexec_mask)
9705 if (s->condexec_mask) {
9706 gen_shl(tmp2, tmp2, tmp);
9708 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9713 if (s->condexec_mask) {
9714 gen_shr(tmp2, tmp2, tmp);
9716 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9721 if (s->condexec_mask) {
9722 gen_sar(tmp2, tmp2, tmp);
9724 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9729 if (s->condexec_mask) {
9732 gen_adc_CC(tmp, tmp, tmp2);
9736 if (s->condexec_mask) {
9737 gen_sub_carry(tmp, tmp, tmp2);
9739 gen_sbc_CC(tmp, tmp, tmp2);
9743 if (s->condexec_mask) {
9744 tcg_gen_andi_i32(tmp, tmp, 0x1f);
9745 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9747 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9752 tcg_gen_and_i32(tmp, tmp, tmp2);
9757 if (s->condexec_mask)
9758 tcg_gen_neg_i32(tmp, tmp2);
9760 gen_sub_CC(tmp, tmp, tmp2);
9763 gen_sub_CC(tmp, tmp, tmp2);
9767 gen_add_CC(tmp, tmp, tmp2);
9771 tcg_gen_or_i32(tmp, tmp, tmp2);
9772 if (!s->condexec_mask)
9776 tcg_gen_mul_i32(tmp, tmp, tmp2);
9777 if (!s->condexec_mask)
9781 tcg_gen_andc_i32(tmp, tmp, tmp2);
9782 if (!s->condexec_mask)
9786 tcg_gen_not_i32(tmp2, tmp2);
9787 if (!s->condexec_mask)
9795 store_reg(s, rm, tmp2);
9797 tcg_temp_free_i32(tmp);
9799 store_reg(s, rd, tmp);
9800 tcg_temp_free_i32(tmp2);
9803 tcg_temp_free_i32(tmp);
9804 tcg_temp_free_i32(tmp2);
9809 /* load/store register offset. */
9811 rn = (insn >> 3) & 7;
9812 rm = (insn >> 6) & 7;
9813 op = (insn >> 9) & 7;
9814 addr = load_reg(s, rn);
9815 tmp = load_reg(s, rm);
9816 tcg_gen_add_i32(addr, addr, tmp);
9817 tcg_temp_free_i32(tmp);
9819 if (op < 3) { /* store */
9820 tmp = load_reg(s, rd);
9822 tmp = tcg_temp_new_i32();
9827 gen_aa32_st32(tmp, addr, IS_USER(s));
9830 gen_aa32_st16(tmp, addr, IS_USER(s));
9833 gen_aa32_st8(tmp, addr, IS_USER(s));
9836 gen_aa32_ld8s(tmp, addr, IS_USER(s));
9839 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9842 gen_aa32_ld16u(tmp, addr, IS_USER(s));
9845 gen_aa32_ld8u(tmp, addr, IS_USER(s));
9848 gen_aa32_ld16s(tmp, addr, IS_USER(s));
9851 if (op >= 3) { /* load */
9852 store_reg(s, rd, tmp);
9854 tcg_temp_free_i32(tmp);
9856 tcg_temp_free_i32(addr);
9860 /* load/store word immediate offset */
9862 rn = (insn >> 3) & 7;
9863 addr = load_reg(s, rn);
9864 val = (insn >> 4) & 0x7c;
9865 tcg_gen_addi_i32(addr, addr, val);
9867 if (insn & (1 << 11)) {
9869 tmp = tcg_temp_new_i32();
9870 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9871 store_reg(s, rd, tmp);
9874 tmp = load_reg(s, rd);
9875 gen_aa32_st32(tmp, addr, IS_USER(s));
9876 tcg_temp_free_i32(tmp);
9878 tcg_temp_free_i32(addr);
9882 /* load/store byte immediate offset */
9884 rn = (insn >> 3) & 7;
9885 addr = load_reg(s, rn);
9886 val = (insn >> 6) & 0x1f;
9887 tcg_gen_addi_i32(addr, addr, val);
9889 if (insn & (1 << 11)) {
9891 tmp = tcg_temp_new_i32();
9892 gen_aa32_ld8u(tmp, addr, IS_USER(s));
9893 store_reg(s, rd, tmp);
9896 tmp = load_reg(s, rd);
9897 gen_aa32_st8(tmp, addr, IS_USER(s));
9898 tcg_temp_free_i32(tmp);
9900 tcg_temp_free_i32(addr);
9904 /* load/store halfword immediate offset */
9906 rn = (insn >> 3) & 7;
9907 addr = load_reg(s, rn);
9908 val = (insn >> 5) & 0x3e;
9909 tcg_gen_addi_i32(addr, addr, val);
9911 if (insn & (1 << 11)) {
9913 tmp = tcg_temp_new_i32();
9914 gen_aa32_ld16u(tmp, addr, IS_USER(s));
9915 store_reg(s, rd, tmp);
9918 tmp = load_reg(s, rd);
9919 gen_aa32_st16(tmp, addr, IS_USER(s));
9920 tcg_temp_free_i32(tmp);
9922 tcg_temp_free_i32(addr);
9926 /* load/store from stack */
9927 rd = (insn >> 8) & 7;
9928 addr = load_reg(s, 13);
9929 val = (insn & 0xff) * 4;
9930 tcg_gen_addi_i32(addr, addr, val);
9932 if (insn & (1 << 11)) {
9934 tmp = tcg_temp_new_i32();
9935 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9936 store_reg(s, rd, tmp);
9939 tmp = load_reg(s, rd);
9940 gen_aa32_st32(tmp, addr, IS_USER(s));
9941 tcg_temp_free_i32(tmp);
9943 tcg_temp_free_i32(addr);
9947 /* add to high reg */
9948 rd = (insn >> 8) & 7;
9949 if (insn & (1 << 11)) {
9951 tmp = load_reg(s, 13);
9953 /* PC. bit 1 is ignored. */
9954 tmp = tcg_temp_new_i32();
9955 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9957 val = (insn & 0xff) * 4;
9958 tcg_gen_addi_i32(tmp, tmp, val);
9959 store_reg(s, rd, tmp);
9964 op = (insn >> 8) & 0xf;
9967 /* adjust stack pointer */
9968 tmp = load_reg(s, 13);
9969 val = (insn & 0x7f) * 4;
9970 if (insn & (1 << 7))
9971 val = -(int32_t)val;
9972 tcg_gen_addi_i32(tmp, tmp, val);
9973 store_reg(s, 13, tmp);
9976 case 2: /* sign/zero extend. */
9979 rm = (insn >> 3) & 7;
9980 tmp = load_reg(s, rm);
9981 switch ((insn >> 6) & 3) {
9982 case 0: gen_sxth(tmp); break;
9983 case 1: gen_sxtb(tmp); break;
9984 case 2: gen_uxth(tmp); break;
9985 case 3: gen_uxtb(tmp); break;
9987 store_reg(s, rd, tmp);
9989 case 4: case 5: case 0xc: case 0xd:
9991 addr = load_reg(s, 13);
9992 if (insn & (1 << 8))
9996 for (i = 0; i < 8; i++) {
9997 if (insn & (1 << i))
10000 if ((insn & (1 << 11)) == 0) {
10001 tcg_gen_addi_i32(addr, addr, -offset);
10003 for (i = 0; i < 8; i++) {
10004 if (insn & (1 << i)) {
10005 if (insn & (1 << 11)) {
10007 tmp = tcg_temp_new_i32();
10008 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10009 store_reg(s, i, tmp);
10012 tmp = load_reg(s, i);
10013 gen_aa32_st32(tmp, addr, IS_USER(s));
10014 tcg_temp_free_i32(tmp);
10016 /* advance to the next address. */
10017 tcg_gen_addi_i32(addr, addr, 4);
10020 TCGV_UNUSED_I32(tmp);
10021 if (insn & (1 << 8)) {
10022 if (insn & (1 << 11)) {
10024 tmp = tcg_temp_new_i32();
10025 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10026 /* don't set the pc until the rest of the instruction
10030 tmp = load_reg(s, 14);
10031 gen_aa32_st32(tmp, addr, IS_USER(s));
10032 tcg_temp_free_i32(tmp);
10034 tcg_gen_addi_i32(addr, addr, 4);
10036 if ((insn & (1 << 11)) == 0) {
10037 tcg_gen_addi_i32(addr, addr, -offset);
10039 /* write back the new stack pointer */
10040 store_reg(s, 13, addr);
10041 /* set the new PC value */
10042 if ((insn & 0x0900) == 0x0900) {
10043 store_reg_from_load(env, s, 15, tmp);
10047 case 1: case 3: case 9: case 11: /* czb */
10049 tmp = load_reg(s, rm);
10050 s->condlabel = gen_new_label();
10052 if (insn & (1 << 11))
10053 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10055 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10056 tcg_temp_free_i32(tmp);
10057 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10058 val = (uint32_t)s->pc + 2;
10063 case 15: /* IT, nop-hint. */
10064 if ((insn & 0xf) == 0) {
10065 gen_nop_hint(s, (insn >> 4) & 0xf);
10069 s->condexec_cond = (insn >> 4) & 0xe;
10070 s->condexec_mask = insn & 0x1f;
10071 /* No actual code generated for this insn, just setup state. */
10074 case 0xe: /* bkpt */
10076 gen_exception_insn(s, 2, EXCP_BKPT);
10079 case 0xa: /* rev */
10081 rn = (insn >> 3) & 0x7;
10083 tmp = load_reg(s, rn);
10084 switch ((insn >> 6) & 3) {
10085 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10086 case 1: gen_rev16(tmp); break;
10087 case 3: gen_revsh(tmp); break;
10088 default: goto illegal_op;
10090 store_reg(s, rd, tmp);
10094 switch ((insn >> 5) & 7) {
10098 if (((insn >> 3) & 1) != s->bswap_code) {
10099 /* Dynamic endianness switching not implemented. */
10100 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10111 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10114 addr = tcg_const_i32(19);
10115 gen_helper_v7m_msr(cpu_env, addr, tmp);
10116 tcg_temp_free_i32(addr);
10120 addr = tcg_const_i32(16);
10121 gen_helper_v7m_msr(cpu_env, addr, tmp);
10122 tcg_temp_free_i32(addr);
10124 tcg_temp_free_i32(tmp);
10127 if (insn & (1 << 4)) {
10128 shift = CPSR_A | CPSR_I | CPSR_F;
10132 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10147 /* load/store multiple */
10148 TCGv_i32 loaded_var;
10149 TCGV_UNUSED_I32(loaded_var);
10150 rn = (insn >> 8) & 0x7;
10151 addr = load_reg(s, rn);
10152 for (i = 0; i < 8; i++) {
10153 if (insn & (1 << i)) {
10154 if (insn & (1 << 11)) {
10156 tmp = tcg_temp_new_i32();
10157 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10161 store_reg(s, i, tmp);
10165 tmp = load_reg(s, i);
10166 gen_aa32_st32(tmp, addr, IS_USER(s));
10167 tcg_temp_free_i32(tmp);
10169 /* advance to the next address */
10170 tcg_gen_addi_i32(addr, addr, 4);
10173 if ((insn & (1 << rn)) == 0) {
10174 /* base reg not in list: base register writeback */
10175 store_reg(s, rn, addr);
10177 /* base reg in list: if load, complete it now */
10178 if (insn & (1 << 11)) {
10179 store_reg(s, rn, loaded_var);
10181 tcg_temp_free_i32(addr);
10186 /* conditional branch or swi */
10187 cond = (insn >> 8) & 0xf;
10193 gen_set_pc_im(s, s->pc);
10194 s->is_jmp = DISAS_SWI;
10197 /* generate a conditional jump to next instruction */
10198 s->condlabel = gen_new_label();
10199 arm_gen_test_cc(cond ^ 1, s->condlabel);
10202 /* jump to the offset */
10203 val = (uint32_t)s->pc + 2;
10204 offset = ((int32_t)insn << 24) >> 24;
10205 val += offset << 1;
10210 if (insn & (1 << 11)) {
10211 if (disas_thumb2_insn(env, s, insn))
10215 /* unconditional branch */
10216 val = (uint32_t)s->pc;
10217 offset = ((int32_t)insn << 21) >> 21;
10218 val += (offset << 1) + 2;
10223 if (disas_thumb2_insn(env, s, insn))
10229 gen_exception_insn(s, 4, EXCP_UDEF);
10233 gen_exception_insn(s, 2, EXCP_UDEF);
10236 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10237 basic block 'tb'. If search_pc is TRUE, also generate PC
10238 information for each intermediate instruction. */
10239 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10240 TranslationBlock *tb,
10243 CPUState *cs = CPU(cpu);
10244 CPUARMState *env = &cpu->env;
10245 DisasContext dc1, *dc = &dc1;
10247 uint16_t *gen_opc_end;
10249 target_ulong pc_start;
10250 target_ulong next_page_start;
10254 /* generate intermediate code */
10256 /* The A64 decoder has its own top level loop, because it doesn't need
10257 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10259 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10260 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10268 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10270 dc->is_jmp = DISAS_NEXT;
10272 dc->singlestep_enabled = cs->singlestep_enabled;
10276 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10277 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10278 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10279 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10280 #if !defined(CONFIG_USER_ONLY)
10281 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10283 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10284 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10285 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10286 dc->cp_regs = cpu->cp_regs;
10287 dc->current_pl = arm_current_pl(env);
10289 cpu_F0s = tcg_temp_new_i32();
10290 cpu_F1s = tcg_temp_new_i32();
10291 cpu_F0d = tcg_temp_new_i64();
10292 cpu_F1d = tcg_temp_new_i64();
10295 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10296 cpu_M0 = tcg_temp_new_i64();
10297 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10300 max_insns = tb->cflags & CF_COUNT_MASK;
10301 if (max_insns == 0)
10302 max_insns = CF_COUNT_MASK;
10306 tcg_clear_temp_count();
10308 /* A note on handling of the condexec (IT) bits:
10310 * We want to avoid the overhead of having to write the updated condexec
10311 * bits back to the CPUARMState for every instruction in an IT block. So:
10312 * (1) if the condexec bits are not already zero then we write
10313 * zero back into the CPUARMState now. This avoids complications trying
10314 * to do it at the end of the block. (For example if we don't do this
10315 * it's hard to identify whether we can safely skip writing condexec
10316 * at the end of the TB, which we definitely want to do for the case
10317 * where a TB doesn't do anything with the IT state at all.)
10318 * (2) if we are going to leave the TB then we call gen_set_condexec()
10319 * which will write the correct value into CPUARMState if zero is wrong.
10320 * This is done both for leaving the TB at the end, and for leaving
10321 * it because of an exception we know will happen, which is done in
10322 * gen_exception_insn(). The latter is necessary because we need to
10323 * leave the TB with the PC/IT state just prior to execution of the
10324 * instruction which caused the exception.
10325 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10326 * then the CPUARMState will be wrong and we need to reset it.
10327 * This is handled in the same way as restoration of the
10328 * PC in these situations: we will be called again with search_pc=1
10329 * and generate a mapping of the condexec bits for each PC in
10330 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10331 * this to restore the condexec bits.
10333 * Note that there are no instructions which can read the condexec
10334 * bits, and none which can write non-static values to them, so
10335 * we don't need to care about whether CPUARMState is correct in the
10339 /* Reset the conditional execution bits immediately. This avoids
10340 complications trying to do it at the end of the block. */
10341 if (dc->condexec_mask || dc->condexec_cond)
10343 TCGv_i32 tmp = tcg_temp_new_i32();
10344 tcg_gen_movi_i32(tmp, 0);
10345 store_cpu_field(tmp, condexec_bits);
10348 #ifdef CONFIG_USER_ONLY
10349 /* Intercept jump to the magic kernel page. */
10350 if (dc->pc >= 0xffff0000) {
10351 /* We always get here via a jump, so know we are not in a
10352 conditional execution block. */
10353 gen_exception(EXCP_KERNEL_TRAP);
10354 dc->is_jmp = DISAS_UPDATE;
10358 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10359 /* We always get here via a jump, so know we are not in a
10360 conditional execution block. */
10361 gen_exception(EXCP_EXCEPTION_EXIT);
10362 dc->is_jmp = DISAS_UPDATE;
10367 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10368 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10369 if (bp->pc == dc->pc) {
10370 gen_exception_insn(dc, 0, EXCP_DEBUG);
10371 /* Advance PC so that clearing the breakpoint will
10372 invalidate this TB. */
10374 goto done_generating;
10379 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10383 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10385 tcg_ctx.gen_opc_pc[lj] = dc->pc;
10386 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10387 tcg_ctx.gen_opc_instr_start[lj] = 1;
10388 tcg_ctx.gen_opc_icount[lj] = num_insns;
10391 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10394 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10395 tcg_gen_debug_insn_start(dc->pc);
10399 disas_thumb_insn(env, dc);
10400 if (dc->condexec_mask) {
10401 dc->condexec_cond = (dc->condexec_cond & 0xe)
10402 | ((dc->condexec_mask >> 4) & 1);
10403 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10404 if (dc->condexec_mask == 0) {
10405 dc->condexec_cond = 0;
10409 disas_arm_insn(env, dc);
10412 if (dc->condjmp && !dc->is_jmp) {
10413 gen_set_label(dc->condlabel);
10417 if (tcg_check_temp_count()) {
10418 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10422 /* Translation stops when a conditional branch is encountered.
10423 * Otherwise the subsequent code could get translated several times.
10424 * Also stop translation when a page boundary is reached. This
10425 * ensures prefetch aborts occur at the right place. */
10427 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10428 !cs->singlestep_enabled &&
10430 dc->pc < next_page_start &&
10431 num_insns < max_insns);
10433 if (tb->cflags & CF_LAST_IO) {
10435 /* FIXME: This can theoretically happen with self-modifying
10437 cpu_abort(env, "IO on conditional branch instruction");
10442 /* At this stage dc->condjmp will only be set when the skipped
10443 instruction was a conditional branch or trap, and the PC has
10444 already been written. */
10445 if (unlikely(cs->singlestep_enabled)) {
10446 /* Make sure the pc is updated, and raise a debug exception. */
10448 gen_set_condexec(dc);
10449 if (dc->is_jmp == DISAS_SWI) {
10450 gen_exception(EXCP_SWI);
10452 gen_exception(EXCP_DEBUG);
10454 gen_set_label(dc->condlabel);
10456 if (dc->condjmp || !dc->is_jmp) {
10457 gen_set_pc_im(dc, dc->pc);
10460 gen_set_condexec(dc);
10461 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10462 gen_exception(EXCP_SWI);
10464 /* FIXME: Single stepping a WFI insn will not halt
10466 gen_exception(EXCP_DEBUG);
10469 /* While branches must always occur at the end of an IT block,
10470 there are a few other things that can cause us to terminate
10471 the TB in the middle of an IT block:
10472 - Exception generating instructions (bkpt, swi, undefined).
10474 - Hardware watchpoints.
10475 Hardware breakpoints have already been handled and skip this code.
10477 gen_set_condexec(dc);
10478 switch(dc->is_jmp) {
10480 gen_goto_tb(dc, 1, dc->pc);
10485 /* indicate that the hash table must be used to find the next TB */
10486 tcg_gen_exit_tb(0);
10488 case DISAS_TB_JUMP:
10489 /* nothing more to generate */
10492 gen_helper_wfi(cpu_env);
10495 gen_exception(EXCP_SWI);
10499 gen_set_label(dc->condlabel);
10500 gen_set_condexec(dc);
10501 gen_goto_tb(dc, 1, dc->pc);
10507 gen_tb_end(tb, num_insns);
10508 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
10511 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10512 qemu_log("----------------\n");
10513 qemu_log("IN: %s\n", lookup_symbol(pc_start));
10514 log_target_disas(env, pc_start, dc->pc - pc_start,
10515 dc->thumb | (dc->bswap_code << 1));
10520 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10523 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10525 tb->size = dc->pc - pc_start;
10526 tb->icount = num_insns;
10530 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10532 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10535 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10537 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10540 static const char *cpu_mode_names[16] = {
10541 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10542 "???", "???", "???", "und", "???", "???", "???", "sys"
10545 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10548 ARMCPU *cpu = ARM_CPU(cs);
10549 CPUARMState *env = &cpu->env;
10553 for(i=0;i<16;i++) {
10554 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10556 cpu_fprintf(f, "\n");
10558 cpu_fprintf(f, " ");
10560 psr = cpsr_read(env);
10561 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10563 psr & (1 << 31) ? 'N' : '-',
10564 psr & (1 << 30) ? 'Z' : '-',
10565 psr & (1 << 29) ? 'C' : '-',
10566 psr & (1 << 28) ? 'V' : '-',
10567 psr & CPSR_T ? 'T' : 'A',
10568 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10570 if (flags & CPU_DUMP_FPU) {
10571 int numvfpregs = 0;
10572 if (arm_feature(env, ARM_FEATURE_VFP)) {
10575 if (arm_feature(env, ARM_FEATURE_VFP3)) {
10578 for (i = 0; i < numvfpregs; i++) {
10579 uint64_t v = float64_val(env->vfp.regs[i]);
10580 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10581 i * 2, (uint32_t)v,
10582 i * 2 + 1, (uint32_t)(v >> 32),
10585 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10589 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10592 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10593 env->condexec_bits = 0;
10595 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10596 env->condexec_bits = gen_opc_condexec_bits[pc_pos];