4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 #include "disas/disas.h"
31 #include "qemu/bitops.h"
37 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
38 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
39 /* currently all emulated v5 cores are also v5TE, so don't bother */
40 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
41 #define ENABLE_ARCH_5J 0
42 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
43 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
44 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
45 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
48 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50 #include "translate.h"
51 static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
53 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) (s->user)
60 /* We reuse the same 64-bit temporaries for efficiency. */
61 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
62 static TCGv_i32 cpu_R[16];
63 static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
64 static TCGv_i64 cpu_exclusive_addr;
65 static TCGv_i64 cpu_exclusive_val;
66 #ifdef CONFIG_USER_ONLY
67 static TCGv_i64 cpu_exclusive_test;
68 static TCGv_i32 cpu_exclusive_info;
71 /* FIXME: These should be removed. */
72 static TCGv_i32 cpu_F0s, cpu_F1s;
73 static TCGv_i64 cpu_F0d, cpu_F1d;
75 #include "exec/gen-icount.h"
77 static const char *regnames[] =
78 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
79 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
86 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
88 for (i = 0; i < 16; i++) {
89 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
90 offsetof(CPUARMState, regs[i]),
93 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
94 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
95 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
96 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
98 cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
99 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
100 cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
101 offsetof(CPUARMState, exclusive_val), "exclusive_val");
102 #ifdef CONFIG_USER_ONLY
103 cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
104 offsetof(CPUARMState, exclusive_test), "exclusive_test");
105 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
106 offsetof(CPUARMState, exclusive_info), "exclusive_info");
109 a64_translate_init();
112 static inline TCGv_i32 load_cpu_offset(int offset)
114 TCGv_i32 tmp = tcg_temp_new_i32();
115 tcg_gen_ld_i32(tmp, cpu_env, offset);
119 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
121 static inline void store_cpu_offset(TCGv_i32 var, int offset)
123 tcg_gen_st_i32(var, cpu_env, offset);
124 tcg_temp_free_i32(var);
127 #define store_cpu_field(var, name) \
128 store_cpu_offset(var, offsetof(CPUARMState, name))
130 /* Set a variable to the value of a CPU register. */
131 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
135 /* normally, since we updated PC, we need only to add one insn */
137 addr = (long)s->pc + 2;
139 addr = (long)s->pc + 4;
140 tcg_gen_movi_i32(var, addr);
142 tcg_gen_mov_i32(var, cpu_R[reg]);
146 /* Create a new temporary and set it to the value of a CPU register. */
147 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
149 TCGv_i32 tmp = tcg_temp_new_i32();
150 load_reg_var(s, tmp, reg);
154 /* Set a CPU register. The source must be a temporary and will be
156 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
159 tcg_gen_andi_i32(var, var, ~1);
160 s->is_jmp = DISAS_JUMP;
162 tcg_gen_mov_i32(cpu_R[reg], var);
163 tcg_temp_free_i32(var);
166 /* Value extensions. */
167 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
168 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
169 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
170 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
172 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
173 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
176 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
178 TCGv_i32 tmp_mask = tcg_const_i32(mask);
179 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
180 tcg_temp_free_i32(tmp_mask);
182 /* Set NZCV flags from the high 4 bits of var. */
183 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
185 static void gen_exception(int excp)
187 TCGv_i32 tmp = tcg_temp_new_i32();
188 tcg_gen_movi_i32(tmp, excp);
189 gen_helper_exception(cpu_env, tmp);
190 tcg_temp_free_i32(tmp);
193 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
195 TCGv_i32 tmp1 = tcg_temp_new_i32();
196 TCGv_i32 tmp2 = tcg_temp_new_i32();
197 tcg_gen_ext16s_i32(tmp1, a);
198 tcg_gen_ext16s_i32(tmp2, b);
199 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
200 tcg_temp_free_i32(tmp2);
201 tcg_gen_sari_i32(a, a, 16);
202 tcg_gen_sari_i32(b, b, 16);
203 tcg_gen_mul_i32(b, b, a);
204 tcg_gen_mov_i32(a, tmp1);
205 tcg_temp_free_i32(tmp1);
208 /* Byteswap each halfword. */
209 static void gen_rev16(TCGv_i32 var)
211 TCGv_i32 tmp = tcg_temp_new_i32();
212 tcg_gen_shri_i32(tmp, var, 8);
213 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
214 tcg_gen_shli_i32(var, var, 8);
215 tcg_gen_andi_i32(var, var, 0xff00ff00);
216 tcg_gen_or_i32(var, var, tmp);
217 tcg_temp_free_i32(tmp);
220 /* Byteswap low halfword and sign extend. */
221 static void gen_revsh(TCGv_i32 var)
223 tcg_gen_ext16u_i32(var, var);
224 tcg_gen_bswap16_i32(var, var);
225 tcg_gen_ext16s_i32(var, var);
228 /* Unsigned bitfield extract. */
229 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
232 tcg_gen_shri_i32(var, var, shift);
233 tcg_gen_andi_i32(var, var, mask);
236 /* Signed bitfield extract. */
237 static void gen_sbfx(TCGv_i32 var, int shift, int width)
242 tcg_gen_sari_i32(var, var, shift);
243 if (shift + width < 32) {
244 signbit = 1u << (width - 1);
245 tcg_gen_andi_i32(var, var, (1u << width) - 1);
246 tcg_gen_xori_i32(var, var, signbit);
247 tcg_gen_subi_i32(var, var, signbit);
251 /* Return (b << 32) + a. Mark inputs as dead */
252 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
254 TCGv_i64 tmp64 = tcg_temp_new_i64();
256 tcg_gen_extu_i32_i64(tmp64, b);
257 tcg_temp_free_i32(b);
258 tcg_gen_shli_i64(tmp64, tmp64, 32);
259 tcg_gen_add_i64(a, tmp64, a);
261 tcg_temp_free_i64(tmp64);
265 /* Return (b << 32) - a. Mark inputs as dead. */
266 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
268 TCGv_i64 tmp64 = tcg_temp_new_i64();
270 tcg_gen_extu_i32_i64(tmp64, b);
271 tcg_temp_free_i32(b);
272 tcg_gen_shli_i64(tmp64, tmp64, 32);
273 tcg_gen_sub_i64(a, tmp64, a);
275 tcg_temp_free_i64(tmp64);
279 /* 32x32->64 multiply. Marks inputs as dead. */
280 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
282 TCGv_i32 lo = tcg_temp_new_i32();
283 TCGv_i32 hi = tcg_temp_new_i32();
286 tcg_gen_mulu2_i32(lo, hi, a, b);
287 tcg_temp_free_i32(a);
288 tcg_temp_free_i32(b);
290 ret = tcg_temp_new_i64();
291 tcg_gen_concat_i32_i64(ret, lo, hi);
292 tcg_temp_free_i32(lo);
293 tcg_temp_free_i32(hi);
298 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
300 TCGv_i32 lo = tcg_temp_new_i32();
301 TCGv_i32 hi = tcg_temp_new_i32();
304 tcg_gen_muls2_i32(lo, hi, a, b);
305 tcg_temp_free_i32(a);
306 tcg_temp_free_i32(b);
308 ret = tcg_temp_new_i64();
309 tcg_gen_concat_i32_i64(ret, lo, hi);
310 tcg_temp_free_i32(lo);
311 tcg_temp_free_i32(hi);
316 /* Swap low and high halfwords. */
317 static void gen_swap_half(TCGv_i32 var)
319 TCGv_i32 tmp = tcg_temp_new_i32();
320 tcg_gen_shri_i32(tmp, var, 16);
321 tcg_gen_shli_i32(var, var, 16);
322 tcg_gen_or_i32(var, var, tmp);
323 tcg_temp_free_i32(tmp);
326 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
327 tmp = (t0 ^ t1) & 0x8000;
330 t0 = (t0 + t1) ^ tmp;
333 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
335 TCGv_i32 tmp = tcg_temp_new_i32();
336 tcg_gen_xor_i32(tmp, t0, t1);
337 tcg_gen_andi_i32(tmp, tmp, 0x8000);
338 tcg_gen_andi_i32(t0, t0, ~0x8000);
339 tcg_gen_andi_i32(t1, t1, ~0x8000);
340 tcg_gen_add_i32(t0, t0, t1);
341 tcg_gen_xor_i32(t0, t0, tmp);
342 tcg_temp_free_i32(tmp);
343 tcg_temp_free_i32(t1);
346 /* Set CF to the top bit of var. */
347 static void gen_set_CF_bit31(TCGv_i32 var)
349 tcg_gen_shri_i32(cpu_CF, var, 31);
352 /* Set N and Z flags from var. */
353 static inline void gen_logic_CC(TCGv_i32 var)
355 tcg_gen_mov_i32(cpu_NF, var);
356 tcg_gen_mov_i32(cpu_ZF, var);
360 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
362 tcg_gen_add_i32(t0, t0, t1);
363 tcg_gen_add_i32(t0, t0, cpu_CF);
366 /* dest = T0 + T1 + CF. */
367 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
369 tcg_gen_add_i32(dest, t0, t1);
370 tcg_gen_add_i32(dest, dest, cpu_CF);
373 /* dest = T0 - T1 + CF - 1. */
374 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
376 tcg_gen_sub_i32(dest, t0, t1);
377 tcg_gen_add_i32(dest, dest, cpu_CF);
378 tcg_gen_subi_i32(dest, dest, 1);
381 /* dest = T0 + T1. Compute C, N, V and Z flags */
382 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
384 TCGv_i32 tmp = tcg_temp_new_i32();
385 tcg_gen_movi_i32(tmp, 0);
386 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
387 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
388 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
389 tcg_gen_xor_i32(tmp, t0, t1);
390 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
391 tcg_temp_free_i32(tmp);
392 tcg_gen_mov_i32(dest, cpu_NF);
395 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
396 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
398 TCGv_i32 tmp = tcg_temp_new_i32();
399 if (TCG_TARGET_HAS_add2_i32) {
400 tcg_gen_movi_i32(tmp, 0);
401 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
402 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
404 TCGv_i64 q0 = tcg_temp_new_i64();
405 TCGv_i64 q1 = tcg_temp_new_i64();
406 tcg_gen_extu_i32_i64(q0, t0);
407 tcg_gen_extu_i32_i64(q1, t1);
408 tcg_gen_add_i64(q0, q0, q1);
409 tcg_gen_extu_i32_i64(q1, cpu_CF);
410 tcg_gen_add_i64(q0, q0, q1);
411 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
412 tcg_temp_free_i64(q0);
413 tcg_temp_free_i64(q1);
415 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
416 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
417 tcg_gen_xor_i32(tmp, t0, t1);
418 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
419 tcg_temp_free_i32(tmp);
420 tcg_gen_mov_i32(dest, cpu_NF);
423 /* dest = T0 - T1. Compute C, N, V and Z flags */
424 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
427 tcg_gen_sub_i32(cpu_NF, t0, t1);
428 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
429 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
430 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
431 tmp = tcg_temp_new_i32();
432 tcg_gen_xor_i32(tmp, t0, t1);
433 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
434 tcg_temp_free_i32(tmp);
435 tcg_gen_mov_i32(dest, cpu_NF);
438 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
439 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
441 TCGv_i32 tmp = tcg_temp_new_i32();
442 tcg_gen_not_i32(tmp, t1);
443 gen_adc_CC(dest, t0, tmp);
444 tcg_temp_free_i32(tmp);
447 #define GEN_SHIFT(name) \
448 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
450 TCGv_i32 tmp1, tmp2, tmp3; \
451 tmp1 = tcg_temp_new_i32(); \
452 tcg_gen_andi_i32(tmp1, t1, 0xff); \
453 tmp2 = tcg_const_i32(0); \
454 tmp3 = tcg_const_i32(0x1f); \
455 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
456 tcg_temp_free_i32(tmp3); \
457 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
458 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
459 tcg_temp_free_i32(tmp2); \
460 tcg_temp_free_i32(tmp1); \
466 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
469 tmp1 = tcg_temp_new_i32();
470 tcg_gen_andi_i32(tmp1, t1, 0xff);
471 tmp2 = tcg_const_i32(0x1f);
472 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
473 tcg_temp_free_i32(tmp2);
474 tcg_gen_sar_i32(dest, t0, tmp1);
475 tcg_temp_free_i32(tmp1);
478 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
480 TCGv_i32 c0 = tcg_const_i32(0);
481 TCGv_i32 tmp = tcg_temp_new_i32();
482 tcg_gen_neg_i32(tmp, src);
483 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
484 tcg_temp_free_i32(c0);
485 tcg_temp_free_i32(tmp);
488 static void shifter_out_im(TCGv_i32 var, int shift)
491 tcg_gen_andi_i32(cpu_CF, var, 1);
493 tcg_gen_shri_i32(cpu_CF, var, shift);
495 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
500 /* Shift by immediate. Includes special handling for shift == 0. */
501 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
502 int shift, int flags)
508 shifter_out_im(var, 32 - shift);
509 tcg_gen_shli_i32(var, var, shift);
515 tcg_gen_shri_i32(cpu_CF, var, 31);
517 tcg_gen_movi_i32(var, 0);
520 shifter_out_im(var, shift - 1);
521 tcg_gen_shri_i32(var, var, shift);
528 shifter_out_im(var, shift - 1);
531 tcg_gen_sari_i32(var, var, shift);
533 case 3: /* ROR/RRX */
536 shifter_out_im(var, shift - 1);
537 tcg_gen_rotri_i32(var, var, shift); break;
539 TCGv_i32 tmp = tcg_temp_new_i32();
540 tcg_gen_shli_i32(tmp, cpu_CF, 31);
542 shifter_out_im(var, 0);
543 tcg_gen_shri_i32(var, var, 1);
544 tcg_gen_or_i32(var, var, tmp);
545 tcg_temp_free_i32(tmp);
550 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
551 TCGv_i32 shift, int flags)
555 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
556 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
557 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
558 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
563 gen_shl(var, var, shift);
566 gen_shr(var, var, shift);
569 gen_sar(var, var, shift);
571 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
572 tcg_gen_rotr_i32(var, var, shift); break;
575 tcg_temp_free_i32(shift);
578 #define PAS_OP(pfx) \
580 case 0: gen_pas_helper(glue(pfx,add16)); break; \
581 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
582 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
583 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
584 case 4: gen_pas_helper(glue(pfx,add8)); break; \
585 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
587 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
592 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
594 tmp = tcg_temp_new_ptr();
595 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
597 tcg_temp_free_ptr(tmp);
600 tmp = tcg_temp_new_ptr();
601 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
603 tcg_temp_free_ptr(tmp);
605 #undef gen_pas_helper
606 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
619 #undef gen_pas_helper
624 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
625 #define PAS_OP(pfx) \
627 case 0: gen_pas_helper(glue(pfx,add8)); break; \
628 case 1: gen_pas_helper(glue(pfx,add16)); break; \
629 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
630 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
631 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
632 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
634 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
639 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
641 tmp = tcg_temp_new_ptr();
642 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
644 tcg_temp_free_ptr(tmp);
647 tmp = tcg_temp_new_ptr();
648 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
650 tcg_temp_free_ptr(tmp);
652 #undef gen_pas_helper
653 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
666 #undef gen_pas_helper
672 * generate a conditional branch based on ARM condition code cc.
673 * This is common between ARM and Aarch64 targets.
675 void arm_gen_test_cc(int cc, int label)
682 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
685 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
688 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
691 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
694 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
697 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
700 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
703 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
705 case 8: /* hi: C && !Z */
706 inv = gen_new_label();
707 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
708 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
711 case 9: /* ls: !C || Z */
712 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
713 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
715 case 10: /* ge: N == V -> N ^ V == 0 */
716 tmp = tcg_temp_new_i32();
717 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
718 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
719 tcg_temp_free_i32(tmp);
721 case 11: /* lt: N != V -> N ^ V != 0 */
722 tmp = tcg_temp_new_i32();
723 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
724 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
725 tcg_temp_free_i32(tmp);
727 case 12: /* gt: !Z && N == V */
728 inv = gen_new_label();
729 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
730 tmp = tcg_temp_new_i32();
731 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
732 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
733 tcg_temp_free_i32(tmp);
736 case 13: /* le: Z || N != V */
737 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
738 tmp = tcg_temp_new_i32();
739 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
740 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
741 tcg_temp_free_i32(tmp);
744 fprintf(stderr, "Bad condition code 0x%x\n", cc);
749 static const uint8_t table_logic_cc[16] = {
768 /* Set PC and Thumb state from an immediate address. */
769 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
773 s->is_jmp = DISAS_UPDATE;
774 if (s->thumb != (addr & 1)) {
775 tmp = tcg_temp_new_i32();
776 tcg_gen_movi_i32(tmp, addr & 1);
777 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
778 tcg_temp_free_i32(tmp);
780 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
783 /* Set PC and Thumb state from var. var is marked as dead. */
784 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
786 s->is_jmp = DISAS_UPDATE;
787 tcg_gen_andi_i32(cpu_R[15], var, ~1);
788 tcg_gen_andi_i32(var, var, 1);
789 store_cpu_field(var, thumb);
792 /* Variant of store_reg which uses branch&exchange logic when storing
793 to r15 in ARM architecture v7 and above. The source must be a temporary
794 and will be marked as dead. */
795 static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
796 int reg, TCGv_i32 var)
798 if (reg == 15 && ENABLE_ARCH_7) {
801 store_reg(s, reg, var);
805 /* Variant of store_reg which uses branch&exchange logic when storing
806 * to r15 in ARM architecture v5T and above. This is used for storing
807 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
808 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
809 static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
810 int reg, TCGv_i32 var)
812 if (reg == 15 && ENABLE_ARCH_5) {
815 store_reg(s, reg, var);
819 /* Abstractions of "generate code to do a guest load/store for
820 * AArch32", where a vaddr is always 32 bits (and is zero
821 * extended if we're a 64 bit core) and data is also
822 * 32 bits unless specifically doing a 64 bit access.
823 * These functions work like tcg_gen_qemu_{ld,st}* except
824 * that the address argument is TCGv_i32 rather than TCGv.
826 #if TARGET_LONG_BITS == 32
828 #define DO_GEN_LD(SUFF, OPC) \
829 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
831 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
834 #define DO_GEN_ST(SUFF, OPC) \
835 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
837 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
840 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
842 tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
845 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
847 tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
852 #define DO_GEN_LD(SUFF, OPC) \
853 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
855 TCGv addr64 = tcg_temp_new(); \
856 tcg_gen_extu_i32_i64(addr64, addr); \
857 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
858 tcg_temp_free(addr64); \
861 #define DO_GEN_ST(SUFF, OPC) \
862 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
864 TCGv addr64 = tcg_temp_new(); \
865 tcg_gen_extu_i32_i64(addr64, addr); \
866 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
867 tcg_temp_free(addr64); \
870 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
872 TCGv addr64 = tcg_temp_new();
873 tcg_gen_extu_i32_i64(addr64, addr);
874 tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
875 tcg_temp_free(addr64);
878 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
880 TCGv addr64 = tcg_temp_new();
881 tcg_gen_extu_i32_i64(addr64, addr);
882 tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
883 tcg_temp_free(addr64);
890 DO_GEN_LD(16s, MO_TESW)
891 DO_GEN_LD(16u, MO_TEUW)
892 DO_GEN_LD(32u, MO_TEUL)
894 DO_GEN_ST(16, MO_TEUW)
895 DO_GEN_ST(32, MO_TEUL)
897 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
899 tcg_gen_movi_i32(cpu_R[15], val);
902 /* Force a TB lookup after an instruction that changes the CPU state. */
903 static inline void gen_lookup_tb(DisasContext *s)
905 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
906 s->is_jmp = DISAS_UPDATE;
909 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
912 int val, rm, shift, shiftop;
915 if (!(insn & (1 << 25))) {
918 if (!(insn & (1 << 23)))
921 tcg_gen_addi_i32(var, var, val);
925 shift = (insn >> 7) & 0x1f;
926 shiftop = (insn >> 5) & 3;
927 offset = load_reg(s, rm);
928 gen_arm_shift_im(offset, shiftop, shift, 0);
929 if (!(insn & (1 << 23)))
930 tcg_gen_sub_i32(var, var, offset);
932 tcg_gen_add_i32(var, var, offset);
933 tcg_temp_free_i32(offset);
937 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
938 int extra, TCGv_i32 var)
943 if (insn & (1 << 22)) {
945 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
946 if (!(insn & (1 << 23)))
950 tcg_gen_addi_i32(var, var, val);
954 tcg_gen_addi_i32(var, var, extra);
956 offset = load_reg(s, rm);
957 if (!(insn & (1 << 23)))
958 tcg_gen_sub_i32(var, var, offset);
960 tcg_gen_add_i32(var, var, offset);
961 tcg_temp_free_i32(offset);
965 static TCGv_ptr get_fpstatus_ptr(int neon)
967 TCGv_ptr statusptr = tcg_temp_new_ptr();
970 offset = offsetof(CPUARMState, vfp.standard_fp_status);
972 offset = offsetof(CPUARMState, vfp.fp_status);
974 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
978 #define VFP_OP2(name) \
979 static inline void gen_vfp_##name(int dp) \
981 TCGv_ptr fpst = get_fpstatus_ptr(0); \
983 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
985 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
987 tcg_temp_free_ptr(fpst); \
997 static inline void gen_vfp_F1_mul(int dp)
999 /* Like gen_vfp_mul() but put result in F1 */
1000 TCGv_ptr fpst = get_fpstatus_ptr(0);
1002 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1004 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1006 tcg_temp_free_ptr(fpst);
1009 static inline void gen_vfp_F1_neg(int dp)
1011 /* Like gen_vfp_neg() but put result in F1 */
1013 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1015 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1019 static inline void gen_vfp_abs(int dp)
1022 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1024 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1027 static inline void gen_vfp_neg(int dp)
1030 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1032 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1035 static inline void gen_vfp_sqrt(int dp)
1038 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1040 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1043 static inline void gen_vfp_cmp(int dp)
1046 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1048 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1051 static inline void gen_vfp_cmpe(int dp)
1054 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1056 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1059 static inline void gen_vfp_F1_ld0(int dp)
1062 tcg_gen_movi_i64(cpu_F1d, 0);
1064 tcg_gen_movi_i32(cpu_F1s, 0);
1067 #define VFP_GEN_ITOF(name) \
1068 static inline void gen_vfp_##name(int dp, int neon) \
1070 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1072 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1074 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1076 tcg_temp_free_ptr(statusptr); \
1083 #define VFP_GEN_FTOI(name) \
1084 static inline void gen_vfp_##name(int dp, int neon) \
1086 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1088 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1090 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1092 tcg_temp_free_ptr(statusptr); \
1101 #define VFP_GEN_FIX(name, round) \
1102 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1104 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1105 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1107 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1110 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1113 tcg_temp_free_i32(tmp_shift); \
1114 tcg_temp_free_ptr(statusptr); \
1116 VFP_GEN_FIX(tosh, _round_to_zero)
1117 VFP_GEN_FIX(tosl, _round_to_zero)
1118 VFP_GEN_FIX(touh, _round_to_zero)
1119 VFP_GEN_FIX(toul, _round_to_zero)
1126 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1129 gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1131 gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1135 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1138 gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1140 gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1145 vfp_reg_offset (int dp, int reg)
1148 return offsetof(CPUARMState, vfp.regs[reg]);
1150 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1151 + offsetof(CPU_DoubleU, l.upper);
1153 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1154 + offsetof(CPU_DoubleU, l.lower);
1158 /* Return the offset of a 32-bit piece of a NEON register.
1159 zero is the least significant end of the register. */
1161 neon_reg_offset (int reg, int n)
1165 return vfp_reg_offset(0, sreg);
1168 static TCGv_i32 neon_load_reg(int reg, int pass)
1170 TCGv_i32 tmp = tcg_temp_new_i32();
1171 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1175 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1177 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1178 tcg_temp_free_i32(var);
1181 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1183 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1186 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1188 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1191 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1192 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1193 #define tcg_gen_st_f32 tcg_gen_st_i32
1194 #define tcg_gen_st_f64 tcg_gen_st_i64
1196 static inline void gen_mov_F0_vreg(int dp, int reg)
1199 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1201 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1204 static inline void gen_mov_F1_vreg(int dp, int reg)
1207 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1209 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1212 static inline void gen_mov_vreg_F0(int dp, int reg)
1215 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1217 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1220 #define ARM_CP_RW_BIT (1 << 20)
1222 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1224 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1227 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1229 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1232 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1234 TCGv_i32 var = tcg_temp_new_i32();
1235 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1239 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1241 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1242 tcg_temp_free_i32(var);
1245 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1247 iwmmxt_store_reg(cpu_M0, rn);
1250 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1252 iwmmxt_load_reg(cpu_M0, rn);
1255 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1257 iwmmxt_load_reg(cpu_V1, rn);
1258 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1261 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1263 iwmmxt_load_reg(cpu_V1, rn);
1264 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1267 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1269 iwmmxt_load_reg(cpu_V1, rn);
1270 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1273 #define IWMMXT_OP(name) \
1274 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1276 iwmmxt_load_reg(cpu_V1, rn); \
1277 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1280 #define IWMMXT_OP_ENV(name) \
1281 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1283 iwmmxt_load_reg(cpu_V1, rn); \
1284 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1287 #define IWMMXT_OP_ENV_SIZE(name) \
1288 IWMMXT_OP_ENV(name##b) \
1289 IWMMXT_OP_ENV(name##w) \
1290 IWMMXT_OP_ENV(name##l)
1292 #define IWMMXT_OP_ENV1(name) \
1293 static inline void gen_op_iwmmxt_##name##_M0(void) \
1295 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1309 IWMMXT_OP_ENV_SIZE(unpackl)
1310 IWMMXT_OP_ENV_SIZE(unpackh)
1312 IWMMXT_OP_ENV1(unpacklub)
1313 IWMMXT_OP_ENV1(unpackluw)
1314 IWMMXT_OP_ENV1(unpacklul)
1315 IWMMXT_OP_ENV1(unpackhub)
1316 IWMMXT_OP_ENV1(unpackhuw)
1317 IWMMXT_OP_ENV1(unpackhul)
1318 IWMMXT_OP_ENV1(unpacklsb)
1319 IWMMXT_OP_ENV1(unpacklsw)
1320 IWMMXT_OP_ENV1(unpacklsl)
1321 IWMMXT_OP_ENV1(unpackhsb)
1322 IWMMXT_OP_ENV1(unpackhsw)
1323 IWMMXT_OP_ENV1(unpackhsl)
1325 IWMMXT_OP_ENV_SIZE(cmpeq)
1326 IWMMXT_OP_ENV_SIZE(cmpgtu)
1327 IWMMXT_OP_ENV_SIZE(cmpgts)
1329 IWMMXT_OP_ENV_SIZE(mins)
1330 IWMMXT_OP_ENV_SIZE(minu)
1331 IWMMXT_OP_ENV_SIZE(maxs)
1332 IWMMXT_OP_ENV_SIZE(maxu)
1334 IWMMXT_OP_ENV_SIZE(subn)
1335 IWMMXT_OP_ENV_SIZE(addn)
1336 IWMMXT_OP_ENV_SIZE(subu)
1337 IWMMXT_OP_ENV_SIZE(addu)
1338 IWMMXT_OP_ENV_SIZE(subs)
1339 IWMMXT_OP_ENV_SIZE(adds)
1341 IWMMXT_OP_ENV(avgb0)
1342 IWMMXT_OP_ENV(avgb1)
1343 IWMMXT_OP_ENV(avgw0)
1344 IWMMXT_OP_ENV(avgw1)
1348 IWMMXT_OP_ENV(packuw)
1349 IWMMXT_OP_ENV(packul)
1350 IWMMXT_OP_ENV(packuq)
1351 IWMMXT_OP_ENV(packsw)
1352 IWMMXT_OP_ENV(packsl)
1353 IWMMXT_OP_ENV(packsq)
1355 static void gen_op_iwmmxt_set_mup(void)
1358 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1359 tcg_gen_ori_i32(tmp, tmp, 2);
1360 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1363 static void gen_op_iwmmxt_set_cup(void)
1366 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1367 tcg_gen_ori_i32(tmp, tmp, 1);
1368 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1371 static void gen_op_iwmmxt_setpsr_nz(void)
1373 TCGv_i32 tmp = tcg_temp_new_i32();
1374 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1375 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1378 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1380 iwmmxt_load_reg(cpu_V1, rn);
1381 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1382 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1385 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1392 rd = (insn >> 16) & 0xf;
1393 tmp = load_reg(s, rd);
1395 offset = (insn & 0xff) << ((insn >> 7) & 2);
1396 if (insn & (1 << 24)) {
1398 if (insn & (1 << 23))
1399 tcg_gen_addi_i32(tmp, tmp, offset);
1401 tcg_gen_addi_i32(tmp, tmp, -offset);
1402 tcg_gen_mov_i32(dest, tmp);
1403 if (insn & (1 << 21))
1404 store_reg(s, rd, tmp);
1406 tcg_temp_free_i32(tmp);
1407 } else if (insn & (1 << 21)) {
1409 tcg_gen_mov_i32(dest, tmp);
1410 if (insn & (1 << 23))
1411 tcg_gen_addi_i32(tmp, tmp, offset);
1413 tcg_gen_addi_i32(tmp, tmp, -offset);
1414 store_reg(s, rd, tmp);
1415 } else if (!(insn & (1 << 23)))
1420 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1422 int rd = (insn >> 0) & 0xf;
1425 if (insn & (1 << 8)) {
1426 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1429 tmp = iwmmxt_load_creg(rd);
1432 tmp = tcg_temp_new_i32();
1433 iwmmxt_load_reg(cpu_V0, rd);
1434 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1436 tcg_gen_andi_i32(tmp, tmp, mask);
1437 tcg_gen_mov_i32(dest, tmp);
1438 tcg_temp_free_i32(tmp);
1442 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1443 (ie. an undefined instruction). */
1444 static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1447 int rdhi, rdlo, rd0, rd1, i;
1449 TCGv_i32 tmp, tmp2, tmp3;
1451 if ((insn & 0x0e000e00) == 0x0c000000) {
1452 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1454 rdlo = (insn >> 12) & 0xf;
1455 rdhi = (insn >> 16) & 0xf;
1456 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1457 iwmmxt_load_reg(cpu_V0, wrd);
1458 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1459 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1460 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1461 } else { /* TMCRR */
1462 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1463 iwmmxt_store_reg(cpu_V0, wrd);
1464 gen_op_iwmmxt_set_mup();
1469 wrd = (insn >> 12) & 0xf;
1470 addr = tcg_temp_new_i32();
1471 if (gen_iwmmxt_address(s, insn, addr)) {
1472 tcg_temp_free_i32(addr);
1475 if (insn & ARM_CP_RW_BIT) {
1476 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1477 tmp = tcg_temp_new_i32();
1478 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1479 iwmmxt_store_creg(wrd, tmp);
1482 if (insn & (1 << 8)) {
1483 if (insn & (1 << 22)) { /* WLDRD */
1484 gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1486 } else { /* WLDRW wRd */
1487 tmp = tcg_temp_new_i32();
1488 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1491 tmp = tcg_temp_new_i32();
1492 if (insn & (1 << 22)) { /* WLDRH */
1493 gen_aa32_ld16u(tmp, addr, IS_USER(s));
1494 } else { /* WLDRB */
1495 gen_aa32_ld8u(tmp, addr, IS_USER(s));
1499 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1500 tcg_temp_free_i32(tmp);
1502 gen_op_iwmmxt_movq_wRn_M0(wrd);
1505 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1506 tmp = iwmmxt_load_creg(wrd);
1507 gen_aa32_st32(tmp, addr, IS_USER(s));
1509 gen_op_iwmmxt_movq_M0_wRn(wrd);
1510 tmp = tcg_temp_new_i32();
1511 if (insn & (1 << 8)) {
1512 if (insn & (1 << 22)) { /* WSTRD */
1513 gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1514 } else { /* WSTRW wRd */
1515 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1516 gen_aa32_st32(tmp, addr, IS_USER(s));
1519 if (insn & (1 << 22)) { /* WSTRH */
1520 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1521 gen_aa32_st16(tmp, addr, IS_USER(s));
1522 } else { /* WSTRB */
1523 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1524 gen_aa32_st8(tmp, addr, IS_USER(s));
1528 tcg_temp_free_i32(tmp);
1530 tcg_temp_free_i32(addr);
1534 if ((insn & 0x0f000000) != 0x0e000000)
1537 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1538 case 0x000: /* WOR */
1539 wrd = (insn >> 12) & 0xf;
1540 rd0 = (insn >> 0) & 0xf;
1541 rd1 = (insn >> 16) & 0xf;
1542 gen_op_iwmmxt_movq_M0_wRn(rd0);
1543 gen_op_iwmmxt_orq_M0_wRn(rd1);
1544 gen_op_iwmmxt_setpsr_nz();
1545 gen_op_iwmmxt_movq_wRn_M0(wrd);
1546 gen_op_iwmmxt_set_mup();
1547 gen_op_iwmmxt_set_cup();
1549 case 0x011: /* TMCR */
1552 rd = (insn >> 12) & 0xf;
1553 wrd = (insn >> 16) & 0xf;
1555 case ARM_IWMMXT_wCID:
1556 case ARM_IWMMXT_wCASF:
1558 case ARM_IWMMXT_wCon:
1559 gen_op_iwmmxt_set_cup();
1561 case ARM_IWMMXT_wCSSF:
1562 tmp = iwmmxt_load_creg(wrd);
1563 tmp2 = load_reg(s, rd);
1564 tcg_gen_andc_i32(tmp, tmp, tmp2);
1565 tcg_temp_free_i32(tmp2);
1566 iwmmxt_store_creg(wrd, tmp);
1568 case ARM_IWMMXT_wCGR0:
1569 case ARM_IWMMXT_wCGR1:
1570 case ARM_IWMMXT_wCGR2:
1571 case ARM_IWMMXT_wCGR3:
1572 gen_op_iwmmxt_set_cup();
1573 tmp = load_reg(s, rd);
1574 iwmmxt_store_creg(wrd, tmp);
1580 case 0x100: /* WXOR */
1581 wrd = (insn >> 12) & 0xf;
1582 rd0 = (insn >> 0) & 0xf;
1583 rd1 = (insn >> 16) & 0xf;
1584 gen_op_iwmmxt_movq_M0_wRn(rd0);
1585 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1586 gen_op_iwmmxt_setpsr_nz();
1587 gen_op_iwmmxt_movq_wRn_M0(wrd);
1588 gen_op_iwmmxt_set_mup();
1589 gen_op_iwmmxt_set_cup();
1591 case 0x111: /* TMRC */
1594 rd = (insn >> 12) & 0xf;
1595 wrd = (insn >> 16) & 0xf;
1596 tmp = iwmmxt_load_creg(wrd);
1597 store_reg(s, rd, tmp);
1599 case 0x300: /* WANDN */
1600 wrd = (insn >> 12) & 0xf;
1601 rd0 = (insn >> 0) & 0xf;
1602 rd1 = (insn >> 16) & 0xf;
1603 gen_op_iwmmxt_movq_M0_wRn(rd0);
1604 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1605 gen_op_iwmmxt_andq_M0_wRn(rd1);
1606 gen_op_iwmmxt_setpsr_nz();
1607 gen_op_iwmmxt_movq_wRn_M0(wrd);
1608 gen_op_iwmmxt_set_mup();
1609 gen_op_iwmmxt_set_cup();
1611 case 0x200: /* WAND */
1612 wrd = (insn >> 12) & 0xf;
1613 rd0 = (insn >> 0) & 0xf;
1614 rd1 = (insn >> 16) & 0xf;
1615 gen_op_iwmmxt_movq_M0_wRn(rd0);
1616 gen_op_iwmmxt_andq_M0_wRn(rd1);
1617 gen_op_iwmmxt_setpsr_nz();
1618 gen_op_iwmmxt_movq_wRn_M0(wrd);
1619 gen_op_iwmmxt_set_mup();
1620 gen_op_iwmmxt_set_cup();
1622 case 0x810: case 0xa10: /* WMADD */
1623 wrd = (insn >> 12) & 0xf;
1624 rd0 = (insn >> 0) & 0xf;
1625 rd1 = (insn >> 16) & 0xf;
1626 gen_op_iwmmxt_movq_M0_wRn(rd0);
1627 if (insn & (1 << 21))
1628 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1630 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1631 gen_op_iwmmxt_movq_wRn_M0(wrd);
1632 gen_op_iwmmxt_set_mup();
1634 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1635 wrd = (insn >> 12) & 0xf;
1636 rd0 = (insn >> 16) & 0xf;
1637 rd1 = (insn >> 0) & 0xf;
1638 gen_op_iwmmxt_movq_M0_wRn(rd0);
1639 switch ((insn >> 22) & 3) {
1641 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1644 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1647 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1652 gen_op_iwmmxt_movq_wRn_M0(wrd);
1653 gen_op_iwmmxt_set_mup();
1654 gen_op_iwmmxt_set_cup();
1656 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1657 wrd = (insn >> 12) & 0xf;
1658 rd0 = (insn >> 16) & 0xf;
1659 rd1 = (insn >> 0) & 0xf;
1660 gen_op_iwmmxt_movq_M0_wRn(rd0);
1661 switch ((insn >> 22) & 3) {
1663 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1666 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1669 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1674 gen_op_iwmmxt_movq_wRn_M0(wrd);
1675 gen_op_iwmmxt_set_mup();
1676 gen_op_iwmmxt_set_cup();
1678 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1679 wrd = (insn >> 12) & 0xf;
1680 rd0 = (insn >> 16) & 0xf;
1681 rd1 = (insn >> 0) & 0xf;
1682 gen_op_iwmmxt_movq_M0_wRn(rd0);
1683 if (insn & (1 << 22))
1684 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1686 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1687 if (!(insn & (1 << 20)))
1688 gen_op_iwmmxt_addl_M0_wRn(wrd);
1689 gen_op_iwmmxt_movq_wRn_M0(wrd);
1690 gen_op_iwmmxt_set_mup();
1692 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1693 wrd = (insn >> 12) & 0xf;
1694 rd0 = (insn >> 16) & 0xf;
1695 rd1 = (insn >> 0) & 0xf;
1696 gen_op_iwmmxt_movq_M0_wRn(rd0);
1697 if (insn & (1 << 21)) {
1698 if (insn & (1 << 20))
1699 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1701 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1703 if (insn & (1 << 20))
1704 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1706 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1708 gen_op_iwmmxt_movq_wRn_M0(wrd);
1709 gen_op_iwmmxt_set_mup();
1711 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1712 wrd = (insn >> 12) & 0xf;
1713 rd0 = (insn >> 16) & 0xf;
1714 rd1 = (insn >> 0) & 0xf;
1715 gen_op_iwmmxt_movq_M0_wRn(rd0);
1716 if (insn & (1 << 21))
1717 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1719 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1720 if (!(insn & (1 << 20))) {
1721 iwmmxt_load_reg(cpu_V1, wrd);
1722 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1724 gen_op_iwmmxt_movq_wRn_M0(wrd);
1725 gen_op_iwmmxt_set_mup();
1727 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1728 wrd = (insn >> 12) & 0xf;
1729 rd0 = (insn >> 16) & 0xf;
1730 rd1 = (insn >> 0) & 0xf;
1731 gen_op_iwmmxt_movq_M0_wRn(rd0);
1732 switch ((insn >> 22) & 3) {
1734 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1737 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1740 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1745 gen_op_iwmmxt_movq_wRn_M0(wrd);
1746 gen_op_iwmmxt_set_mup();
1747 gen_op_iwmmxt_set_cup();
1749 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1750 wrd = (insn >> 12) & 0xf;
1751 rd0 = (insn >> 16) & 0xf;
1752 rd1 = (insn >> 0) & 0xf;
1753 gen_op_iwmmxt_movq_M0_wRn(rd0);
1754 if (insn & (1 << 22)) {
1755 if (insn & (1 << 20))
1756 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1758 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1760 if (insn & (1 << 20))
1761 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1763 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1765 gen_op_iwmmxt_movq_wRn_M0(wrd);
1766 gen_op_iwmmxt_set_mup();
1767 gen_op_iwmmxt_set_cup();
1769 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1770 wrd = (insn >> 12) & 0xf;
1771 rd0 = (insn >> 16) & 0xf;
1772 rd1 = (insn >> 0) & 0xf;
1773 gen_op_iwmmxt_movq_M0_wRn(rd0);
1774 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1775 tcg_gen_andi_i32(tmp, tmp, 7);
1776 iwmmxt_load_reg(cpu_V1, rd1);
1777 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1778 tcg_temp_free_i32(tmp);
1779 gen_op_iwmmxt_movq_wRn_M0(wrd);
1780 gen_op_iwmmxt_set_mup();
1782 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1783 if (((insn >> 6) & 3) == 3)
1785 rd = (insn >> 12) & 0xf;
1786 wrd = (insn >> 16) & 0xf;
1787 tmp = load_reg(s, rd);
1788 gen_op_iwmmxt_movq_M0_wRn(wrd);
1789 switch ((insn >> 6) & 3) {
1791 tmp2 = tcg_const_i32(0xff);
1792 tmp3 = tcg_const_i32((insn & 7) << 3);
1795 tmp2 = tcg_const_i32(0xffff);
1796 tmp3 = tcg_const_i32((insn & 3) << 4);
1799 tmp2 = tcg_const_i32(0xffffffff);
1800 tmp3 = tcg_const_i32((insn & 1) << 5);
1803 TCGV_UNUSED_I32(tmp2);
1804 TCGV_UNUSED_I32(tmp3);
1806 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1807 tcg_temp_free_i32(tmp3);
1808 tcg_temp_free_i32(tmp2);
1809 tcg_temp_free_i32(tmp);
1810 gen_op_iwmmxt_movq_wRn_M0(wrd);
1811 gen_op_iwmmxt_set_mup();
1813 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1814 rd = (insn >> 12) & 0xf;
1815 wrd = (insn >> 16) & 0xf;
1816 if (rd == 15 || ((insn >> 22) & 3) == 3)
1818 gen_op_iwmmxt_movq_M0_wRn(wrd);
1819 tmp = tcg_temp_new_i32();
1820 switch ((insn >> 22) & 3) {
1822 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1823 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1825 tcg_gen_ext8s_i32(tmp, tmp);
1827 tcg_gen_andi_i32(tmp, tmp, 0xff);
1831 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1832 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1834 tcg_gen_ext16s_i32(tmp, tmp);
1836 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1840 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1841 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1844 store_reg(s, rd, tmp);
1846 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1847 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1849 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1850 switch ((insn >> 22) & 3) {
1852 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1855 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1858 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1861 tcg_gen_shli_i32(tmp, tmp, 28);
1863 tcg_temp_free_i32(tmp);
1865 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1866 if (((insn >> 6) & 3) == 3)
1868 rd = (insn >> 12) & 0xf;
1869 wrd = (insn >> 16) & 0xf;
1870 tmp = load_reg(s, rd);
1871 switch ((insn >> 6) & 3) {
1873 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1876 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1879 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1882 tcg_temp_free_i32(tmp);
1883 gen_op_iwmmxt_movq_wRn_M0(wrd);
1884 gen_op_iwmmxt_set_mup();
1886 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1887 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1889 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1890 tmp2 = tcg_temp_new_i32();
1891 tcg_gen_mov_i32(tmp2, tmp);
1892 switch ((insn >> 22) & 3) {
1894 for (i = 0; i < 7; i ++) {
1895 tcg_gen_shli_i32(tmp2, tmp2, 4);
1896 tcg_gen_and_i32(tmp, tmp, tmp2);
1900 for (i = 0; i < 3; i ++) {
1901 tcg_gen_shli_i32(tmp2, tmp2, 8);
1902 tcg_gen_and_i32(tmp, tmp, tmp2);
1906 tcg_gen_shli_i32(tmp2, tmp2, 16);
1907 tcg_gen_and_i32(tmp, tmp, tmp2);
1911 tcg_temp_free_i32(tmp2);
1912 tcg_temp_free_i32(tmp);
1914 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1915 wrd = (insn >> 12) & 0xf;
1916 rd0 = (insn >> 16) & 0xf;
1917 gen_op_iwmmxt_movq_M0_wRn(rd0);
1918 switch ((insn >> 22) & 3) {
1920 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1923 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1926 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1931 gen_op_iwmmxt_movq_wRn_M0(wrd);
1932 gen_op_iwmmxt_set_mup();
1934 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1935 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1937 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1938 tmp2 = tcg_temp_new_i32();
1939 tcg_gen_mov_i32(tmp2, tmp);
1940 switch ((insn >> 22) & 3) {
1942 for (i = 0; i < 7; i ++) {
1943 tcg_gen_shli_i32(tmp2, tmp2, 4);
1944 tcg_gen_or_i32(tmp, tmp, tmp2);
1948 for (i = 0; i < 3; i ++) {
1949 tcg_gen_shli_i32(tmp2, tmp2, 8);
1950 tcg_gen_or_i32(tmp, tmp, tmp2);
1954 tcg_gen_shli_i32(tmp2, tmp2, 16);
1955 tcg_gen_or_i32(tmp, tmp, tmp2);
1959 tcg_temp_free_i32(tmp2);
1960 tcg_temp_free_i32(tmp);
1962 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1963 rd = (insn >> 12) & 0xf;
1964 rd0 = (insn >> 16) & 0xf;
1965 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1967 gen_op_iwmmxt_movq_M0_wRn(rd0);
1968 tmp = tcg_temp_new_i32();
1969 switch ((insn >> 22) & 3) {
1971 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1974 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1977 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1980 store_reg(s, rd, tmp);
1982 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1983 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1984 wrd = (insn >> 12) & 0xf;
1985 rd0 = (insn >> 16) & 0xf;
1986 rd1 = (insn >> 0) & 0xf;
1987 gen_op_iwmmxt_movq_M0_wRn(rd0);
1988 switch ((insn >> 22) & 3) {
1990 if (insn & (1 << 21))
1991 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1993 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1996 if (insn & (1 << 21))
1997 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
1999 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2002 if (insn & (1 << 21))
2003 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2005 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2010 gen_op_iwmmxt_movq_wRn_M0(wrd);
2011 gen_op_iwmmxt_set_mup();
2012 gen_op_iwmmxt_set_cup();
2014 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2015 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2016 wrd = (insn >> 12) & 0xf;
2017 rd0 = (insn >> 16) & 0xf;
2018 gen_op_iwmmxt_movq_M0_wRn(rd0);
2019 switch ((insn >> 22) & 3) {
2021 if (insn & (1 << 21))
2022 gen_op_iwmmxt_unpacklsb_M0();
2024 gen_op_iwmmxt_unpacklub_M0();
2027 if (insn & (1 << 21))
2028 gen_op_iwmmxt_unpacklsw_M0();
2030 gen_op_iwmmxt_unpackluw_M0();
2033 if (insn & (1 << 21))
2034 gen_op_iwmmxt_unpacklsl_M0();
2036 gen_op_iwmmxt_unpacklul_M0();
2041 gen_op_iwmmxt_movq_wRn_M0(wrd);
2042 gen_op_iwmmxt_set_mup();
2043 gen_op_iwmmxt_set_cup();
2045 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2046 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2047 wrd = (insn >> 12) & 0xf;
2048 rd0 = (insn >> 16) & 0xf;
2049 gen_op_iwmmxt_movq_M0_wRn(rd0);
2050 switch ((insn >> 22) & 3) {
2052 if (insn & (1 << 21))
2053 gen_op_iwmmxt_unpackhsb_M0();
2055 gen_op_iwmmxt_unpackhub_M0();
2058 if (insn & (1 << 21))
2059 gen_op_iwmmxt_unpackhsw_M0();
2061 gen_op_iwmmxt_unpackhuw_M0();
2064 if (insn & (1 << 21))
2065 gen_op_iwmmxt_unpackhsl_M0();
2067 gen_op_iwmmxt_unpackhul_M0();
2072 gen_op_iwmmxt_movq_wRn_M0(wrd);
2073 gen_op_iwmmxt_set_mup();
2074 gen_op_iwmmxt_set_cup();
2076 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2077 case 0x214: case 0x614: case 0xa14: case 0xe14:
2078 if (((insn >> 22) & 3) == 0)
2080 wrd = (insn >> 12) & 0xf;
2081 rd0 = (insn >> 16) & 0xf;
2082 gen_op_iwmmxt_movq_M0_wRn(rd0);
2083 tmp = tcg_temp_new_i32();
2084 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2085 tcg_temp_free_i32(tmp);
2088 switch ((insn >> 22) & 3) {
2090 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2093 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2096 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2099 tcg_temp_free_i32(tmp);
2100 gen_op_iwmmxt_movq_wRn_M0(wrd);
2101 gen_op_iwmmxt_set_mup();
2102 gen_op_iwmmxt_set_cup();
2104 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2105 case 0x014: case 0x414: case 0x814: case 0xc14:
2106 if (((insn >> 22) & 3) == 0)
2108 wrd = (insn >> 12) & 0xf;
2109 rd0 = (insn >> 16) & 0xf;
2110 gen_op_iwmmxt_movq_M0_wRn(rd0);
2111 tmp = tcg_temp_new_i32();
2112 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2113 tcg_temp_free_i32(tmp);
2116 switch ((insn >> 22) & 3) {
2118 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2121 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2124 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2127 tcg_temp_free_i32(tmp);
2128 gen_op_iwmmxt_movq_wRn_M0(wrd);
2129 gen_op_iwmmxt_set_mup();
2130 gen_op_iwmmxt_set_cup();
2132 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2133 case 0x114: case 0x514: case 0x914: case 0xd14:
2134 if (((insn >> 22) & 3) == 0)
2136 wrd = (insn >> 12) & 0xf;
2137 rd0 = (insn >> 16) & 0xf;
2138 gen_op_iwmmxt_movq_M0_wRn(rd0);
2139 tmp = tcg_temp_new_i32();
2140 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2141 tcg_temp_free_i32(tmp);
2144 switch ((insn >> 22) & 3) {
2146 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2149 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2152 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2155 tcg_temp_free_i32(tmp);
2156 gen_op_iwmmxt_movq_wRn_M0(wrd);
2157 gen_op_iwmmxt_set_mup();
2158 gen_op_iwmmxt_set_cup();
2160 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2161 case 0x314: case 0x714: case 0xb14: case 0xf14:
2162 if (((insn >> 22) & 3) == 0)
2164 wrd = (insn >> 12) & 0xf;
2165 rd0 = (insn >> 16) & 0xf;
2166 gen_op_iwmmxt_movq_M0_wRn(rd0);
2167 tmp = tcg_temp_new_i32();
2168 switch ((insn >> 22) & 3) {
2170 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2171 tcg_temp_free_i32(tmp);
2174 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2177 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2178 tcg_temp_free_i32(tmp);
2181 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2184 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2185 tcg_temp_free_i32(tmp);
2188 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2191 tcg_temp_free_i32(tmp);
2192 gen_op_iwmmxt_movq_wRn_M0(wrd);
2193 gen_op_iwmmxt_set_mup();
2194 gen_op_iwmmxt_set_cup();
2196 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2197 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2198 wrd = (insn >> 12) & 0xf;
2199 rd0 = (insn >> 16) & 0xf;
2200 rd1 = (insn >> 0) & 0xf;
2201 gen_op_iwmmxt_movq_M0_wRn(rd0);
2202 switch ((insn >> 22) & 3) {
2204 if (insn & (1 << 21))
2205 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2207 gen_op_iwmmxt_minub_M0_wRn(rd1);
2210 if (insn & (1 << 21))
2211 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2213 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2216 if (insn & (1 << 21))
2217 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2219 gen_op_iwmmxt_minul_M0_wRn(rd1);
2224 gen_op_iwmmxt_movq_wRn_M0(wrd);
2225 gen_op_iwmmxt_set_mup();
2227 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2228 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2229 wrd = (insn >> 12) & 0xf;
2230 rd0 = (insn >> 16) & 0xf;
2231 rd1 = (insn >> 0) & 0xf;
2232 gen_op_iwmmxt_movq_M0_wRn(rd0);
2233 switch ((insn >> 22) & 3) {
2235 if (insn & (1 << 21))
2236 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2238 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2241 if (insn & (1 << 21))
2242 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2244 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2247 if (insn & (1 << 21))
2248 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2250 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2255 gen_op_iwmmxt_movq_wRn_M0(wrd);
2256 gen_op_iwmmxt_set_mup();
2258 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2259 case 0x402: case 0x502: case 0x602: case 0x702:
2260 wrd = (insn >> 12) & 0xf;
2261 rd0 = (insn >> 16) & 0xf;
2262 rd1 = (insn >> 0) & 0xf;
2263 gen_op_iwmmxt_movq_M0_wRn(rd0);
2264 tmp = tcg_const_i32((insn >> 20) & 3);
2265 iwmmxt_load_reg(cpu_V1, rd1);
2266 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2267 tcg_temp_free_i32(tmp);
2268 gen_op_iwmmxt_movq_wRn_M0(wrd);
2269 gen_op_iwmmxt_set_mup();
2271 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2272 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2273 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2274 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2275 wrd = (insn >> 12) & 0xf;
2276 rd0 = (insn >> 16) & 0xf;
2277 rd1 = (insn >> 0) & 0xf;
2278 gen_op_iwmmxt_movq_M0_wRn(rd0);
2279 switch ((insn >> 20) & 0xf) {
2281 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2284 gen_op_iwmmxt_subub_M0_wRn(rd1);
2287 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2290 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2293 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2296 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2299 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2302 gen_op_iwmmxt_subul_M0_wRn(rd1);
2305 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2310 gen_op_iwmmxt_movq_wRn_M0(wrd);
2311 gen_op_iwmmxt_set_mup();
2312 gen_op_iwmmxt_set_cup();
2314 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2315 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2316 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2317 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2318 wrd = (insn >> 12) & 0xf;
2319 rd0 = (insn >> 16) & 0xf;
2320 gen_op_iwmmxt_movq_M0_wRn(rd0);
2321 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2322 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2323 tcg_temp_free_i32(tmp);
2324 gen_op_iwmmxt_movq_wRn_M0(wrd);
2325 gen_op_iwmmxt_set_mup();
2326 gen_op_iwmmxt_set_cup();
2328 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2329 case 0x418: case 0x518: case 0x618: case 0x718:
2330 case 0x818: case 0x918: case 0xa18: case 0xb18:
2331 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2332 wrd = (insn >> 12) & 0xf;
2333 rd0 = (insn >> 16) & 0xf;
2334 rd1 = (insn >> 0) & 0xf;
2335 gen_op_iwmmxt_movq_M0_wRn(rd0);
2336 switch ((insn >> 20) & 0xf) {
2338 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2341 gen_op_iwmmxt_addub_M0_wRn(rd1);
2344 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2347 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2350 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2353 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2356 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2359 gen_op_iwmmxt_addul_M0_wRn(rd1);
2362 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2367 gen_op_iwmmxt_movq_wRn_M0(wrd);
2368 gen_op_iwmmxt_set_mup();
2369 gen_op_iwmmxt_set_cup();
2371 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2372 case 0x408: case 0x508: case 0x608: case 0x708:
2373 case 0x808: case 0x908: case 0xa08: case 0xb08:
2374 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2375 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2377 wrd = (insn >> 12) & 0xf;
2378 rd0 = (insn >> 16) & 0xf;
2379 rd1 = (insn >> 0) & 0xf;
2380 gen_op_iwmmxt_movq_M0_wRn(rd0);
2381 switch ((insn >> 22) & 3) {
2383 if (insn & (1 << 21))
2384 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2386 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2389 if (insn & (1 << 21))
2390 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2392 gen_op_iwmmxt_packul_M0_wRn(rd1);
2395 if (insn & (1 << 21))
2396 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2398 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2401 gen_op_iwmmxt_movq_wRn_M0(wrd);
2402 gen_op_iwmmxt_set_mup();
2403 gen_op_iwmmxt_set_cup();
2405 case 0x201: case 0x203: case 0x205: case 0x207:
2406 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2407 case 0x211: case 0x213: case 0x215: case 0x217:
2408 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2409 wrd = (insn >> 5) & 0xf;
2410 rd0 = (insn >> 12) & 0xf;
2411 rd1 = (insn >> 0) & 0xf;
2412 if (rd0 == 0xf || rd1 == 0xf)
2414 gen_op_iwmmxt_movq_M0_wRn(wrd);
2415 tmp = load_reg(s, rd0);
2416 tmp2 = load_reg(s, rd1);
2417 switch ((insn >> 16) & 0xf) {
2418 case 0x0: /* TMIA */
2419 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2421 case 0x8: /* TMIAPH */
2422 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2424 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2425 if (insn & (1 << 16))
2426 tcg_gen_shri_i32(tmp, tmp, 16);
2427 if (insn & (1 << 17))
2428 tcg_gen_shri_i32(tmp2, tmp2, 16);
2429 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2432 tcg_temp_free_i32(tmp2);
2433 tcg_temp_free_i32(tmp);
2436 tcg_temp_free_i32(tmp2);
2437 tcg_temp_free_i32(tmp);
2438 gen_op_iwmmxt_movq_wRn_M0(wrd);
2439 gen_op_iwmmxt_set_mup();
2448 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2449 (ie. an undefined instruction). */
2450 static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2452 int acc, rd0, rd1, rdhi, rdlo;
2455 if ((insn & 0x0ff00f10) == 0x0e200010) {
2456 /* Multiply with Internal Accumulate Format */
2457 rd0 = (insn >> 12) & 0xf;
2459 acc = (insn >> 5) & 7;
2464 tmp = load_reg(s, rd0);
2465 tmp2 = load_reg(s, rd1);
2466 switch ((insn >> 16) & 0xf) {
2468 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2470 case 0x8: /* MIAPH */
2471 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2473 case 0xc: /* MIABB */
2474 case 0xd: /* MIABT */
2475 case 0xe: /* MIATB */
2476 case 0xf: /* MIATT */
2477 if (insn & (1 << 16))
2478 tcg_gen_shri_i32(tmp, tmp, 16);
2479 if (insn & (1 << 17))
2480 tcg_gen_shri_i32(tmp2, tmp2, 16);
2481 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2486 tcg_temp_free_i32(tmp2);
2487 tcg_temp_free_i32(tmp);
2489 gen_op_iwmmxt_movq_wRn_M0(acc);
2493 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2494 /* Internal Accumulator Access Format */
2495 rdhi = (insn >> 16) & 0xf;
2496 rdlo = (insn >> 12) & 0xf;
2502 if (insn & ARM_CP_RW_BIT) { /* MRA */
2503 iwmmxt_load_reg(cpu_V0, acc);
2504 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2505 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2506 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2507 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2509 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2510 iwmmxt_store_reg(cpu_V0, acc);
2518 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2519 #define VFP_SREG(insn, bigbit, smallbit) \
2520 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2521 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2522 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2523 reg = (((insn) >> (bigbit)) & 0x0f) \
2524 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2526 if (insn & (1 << (smallbit))) \
2528 reg = ((insn) >> (bigbit)) & 0x0f; \
2531 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2532 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2533 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2534 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2535 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2536 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2538 /* Move between integer and VFP cores. */
2539 static TCGv_i32 gen_vfp_mrs(void)
2541 TCGv_i32 tmp = tcg_temp_new_i32();
2542 tcg_gen_mov_i32(tmp, cpu_F0s);
2546 static void gen_vfp_msr(TCGv_i32 tmp)
2548 tcg_gen_mov_i32(cpu_F0s, tmp);
2549 tcg_temp_free_i32(tmp);
2552 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2554 TCGv_i32 tmp = tcg_temp_new_i32();
2556 tcg_gen_shri_i32(var, var, shift);
2557 tcg_gen_ext8u_i32(var, var);
2558 tcg_gen_shli_i32(tmp, var, 8);
2559 tcg_gen_or_i32(var, var, tmp);
2560 tcg_gen_shli_i32(tmp, var, 16);
2561 tcg_gen_or_i32(var, var, tmp);
2562 tcg_temp_free_i32(tmp);
2565 static void gen_neon_dup_low16(TCGv_i32 var)
2567 TCGv_i32 tmp = tcg_temp_new_i32();
2568 tcg_gen_ext16u_i32(var, var);
2569 tcg_gen_shli_i32(tmp, var, 16);
2570 tcg_gen_or_i32(var, var, tmp);
2571 tcg_temp_free_i32(tmp);
2574 static void gen_neon_dup_high16(TCGv_i32 var)
2576 TCGv_i32 tmp = tcg_temp_new_i32();
2577 tcg_gen_andi_i32(var, var, 0xffff0000);
2578 tcg_gen_shri_i32(tmp, var, 16);
2579 tcg_gen_or_i32(var, var, tmp);
2580 tcg_temp_free_i32(tmp);
2583 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2585 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2586 TCGv_i32 tmp = tcg_temp_new_i32();
2589 gen_aa32_ld8u(tmp, addr, IS_USER(s));
2590 gen_neon_dup_u8(tmp, 0);
2593 gen_aa32_ld16u(tmp, addr, IS_USER(s));
2594 gen_neon_dup_low16(tmp);
2597 gen_aa32_ld32u(tmp, addr, IS_USER(s));
2599 default: /* Avoid compiler warnings. */
2605 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2608 uint32_t cc = extract32(insn, 20, 2);
2611 TCGv_i64 frn, frm, dest;
2612 TCGv_i64 tmp, zero, zf, nf, vf;
2614 zero = tcg_const_i64(0);
2616 frn = tcg_temp_new_i64();
2617 frm = tcg_temp_new_i64();
2618 dest = tcg_temp_new_i64();
2620 zf = tcg_temp_new_i64();
2621 nf = tcg_temp_new_i64();
2622 vf = tcg_temp_new_i64();
2624 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2625 tcg_gen_ext_i32_i64(nf, cpu_NF);
2626 tcg_gen_ext_i32_i64(vf, cpu_VF);
2628 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2629 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2632 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2636 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2639 case 2: /* ge: N == V -> N ^ V == 0 */
2640 tmp = tcg_temp_new_i64();
2641 tcg_gen_xor_i64(tmp, vf, nf);
2642 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2644 tcg_temp_free_i64(tmp);
2646 case 3: /* gt: !Z && N == V */
2647 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2649 tmp = tcg_temp_new_i64();
2650 tcg_gen_xor_i64(tmp, vf, nf);
2651 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2653 tcg_temp_free_i64(tmp);
2656 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2657 tcg_temp_free_i64(frn);
2658 tcg_temp_free_i64(frm);
2659 tcg_temp_free_i64(dest);
2661 tcg_temp_free_i64(zf);
2662 tcg_temp_free_i64(nf);
2663 tcg_temp_free_i64(vf);
2665 tcg_temp_free_i64(zero);
2667 TCGv_i32 frn, frm, dest;
2670 zero = tcg_const_i32(0);
2672 frn = tcg_temp_new_i32();
2673 frm = tcg_temp_new_i32();
2674 dest = tcg_temp_new_i32();
2675 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2676 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2679 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2683 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2686 case 2: /* ge: N == V -> N ^ V == 0 */
2687 tmp = tcg_temp_new_i32();
2688 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2689 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2691 tcg_temp_free_i32(tmp);
2693 case 3: /* gt: !Z && N == V */
2694 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2696 tmp = tcg_temp_new_i32();
2697 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2698 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2700 tcg_temp_free_i32(tmp);
2703 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2704 tcg_temp_free_i32(frn);
2705 tcg_temp_free_i32(frm);
2706 tcg_temp_free_i32(dest);
2708 tcg_temp_free_i32(zero);
2714 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2715 uint32_t rm, uint32_t dp)
2717 uint32_t vmin = extract32(insn, 6, 1);
2718 TCGv_ptr fpst = get_fpstatus_ptr(0);
2721 TCGv_i64 frn, frm, dest;
2723 frn = tcg_temp_new_i64();
2724 frm = tcg_temp_new_i64();
2725 dest = tcg_temp_new_i64();
2727 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2728 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2730 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2732 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2734 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2735 tcg_temp_free_i64(frn);
2736 tcg_temp_free_i64(frm);
2737 tcg_temp_free_i64(dest);
2739 TCGv_i32 frn, frm, dest;
2741 frn = tcg_temp_new_i32();
2742 frm = tcg_temp_new_i32();
2743 dest = tcg_temp_new_i32();
2745 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2746 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2748 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2750 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2752 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2753 tcg_temp_free_i32(frn);
2754 tcg_temp_free_i32(frm);
2755 tcg_temp_free_i32(dest);
2758 tcg_temp_free_ptr(fpst);
2762 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2765 TCGv_ptr fpst = get_fpstatus_ptr(0);
2768 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2769 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2774 tcg_op = tcg_temp_new_i64();
2775 tcg_res = tcg_temp_new_i64();
2776 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2777 gen_helper_rintd(tcg_res, tcg_op, fpst);
2778 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2779 tcg_temp_free_i64(tcg_op);
2780 tcg_temp_free_i64(tcg_res);
2784 tcg_op = tcg_temp_new_i32();
2785 tcg_res = tcg_temp_new_i32();
2786 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2787 gen_helper_rints(tcg_res, tcg_op, fpst);
2788 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2789 tcg_temp_free_i32(tcg_op);
2790 tcg_temp_free_i32(tcg_res);
2793 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2794 tcg_temp_free_i32(tcg_rmode);
2796 tcg_temp_free_ptr(fpst);
2801 /* Table for converting the most common AArch32 encoding of
2802 * rounding mode to arm_fprounding order (which matches the
2803 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2805 static const uint8_t fp_decode_rm[] = {
2812 static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2814 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2816 if (!arm_feature(env, ARM_FEATURE_V8)) {
2821 VFP_DREG_D(rd, insn);
2822 VFP_DREG_N(rn, insn);
2823 VFP_DREG_M(rm, insn);
2825 rd = VFP_SREG_D(insn);
2826 rn = VFP_SREG_N(insn);
2827 rm = VFP_SREG_M(insn);
2830 if ((insn & 0x0f800e50) == 0x0e000a00) {
2831 return handle_vsel(insn, rd, rn, rm, dp);
2832 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2833 return handle_vminmaxnm(insn, rd, rn, rm, dp);
2834 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
2835 /* VRINTA, VRINTN, VRINTP, VRINTM */
2836 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2837 return handle_vrint(insn, rd, rm, dp, rounding);
2842 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2843 (ie. an undefined instruction). */
2844 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2846 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2852 if (!arm_feature(env, ARM_FEATURE_VFP))
2855 if (!s->vfp_enabled) {
2856 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2857 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2859 rn = (insn >> 16) & 0xf;
2860 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2861 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2865 if (extract32(insn, 28, 4) == 0xf) {
2866 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2867 * only used in v8 and above.
2869 return disas_vfp_v8_insn(env, s, insn);
2872 dp = ((insn & 0xf00) == 0xb00);
2873 switch ((insn >> 24) & 0xf) {
2875 if (insn & (1 << 4)) {
2876 /* single register transfer */
2877 rd = (insn >> 12) & 0xf;
2882 VFP_DREG_N(rn, insn);
2885 if (insn & 0x00c00060
2886 && !arm_feature(env, ARM_FEATURE_NEON))
2889 pass = (insn >> 21) & 1;
2890 if (insn & (1 << 22)) {
2892 offset = ((insn >> 5) & 3) * 8;
2893 } else if (insn & (1 << 5)) {
2895 offset = (insn & (1 << 6)) ? 16 : 0;
2900 if (insn & ARM_CP_RW_BIT) {
2902 tmp = neon_load_reg(rn, pass);
2906 tcg_gen_shri_i32(tmp, tmp, offset);
2907 if (insn & (1 << 23))
2913 if (insn & (1 << 23)) {
2915 tcg_gen_shri_i32(tmp, tmp, 16);
2921 tcg_gen_sari_i32(tmp, tmp, 16);
2930 store_reg(s, rd, tmp);
2933 tmp = load_reg(s, rd);
2934 if (insn & (1 << 23)) {
2937 gen_neon_dup_u8(tmp, 0);
2938 } else if (size == 1) {
2939 gen_neon_dup_low16(tmp);
2941 for (n = 0; n <= pass * 2; n++) {
2942 tmp2 = tcg_temp_new_i32();
2943 tcg_gen_mov_i32(tmp2, tmp);
2944 neon_store_reg(rn, n, tmp2);
2946 neon_store_reg(rn, n, tmp);
2951 tmp2 = neon_load_reg(rn, pass);
2952 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2953 tcg_temp_free_i32(tmp2);
2956 tmp2 = neon_load_reg(rn, pass);
2957 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2958 tcg_temp_free_i32(tmp2);
2963 neon_store_reg(rn, pass, tmp);
2967 if ((insn & 0x6f) != 0x00)
2969 rn = VFP_SREG_N(insn);
2970 if (insn & ARM_CP_RW_BIT) {
2972 if (insn & (1 << 21)) {
2973 /* system register */
2978 /* VFP2 allows access to FSID from userspace.
2979 VFP3 restricts all id registers to privileged
2982 && arm_feature(env, ARM_FEATURE_VFP3))
2984 tmp = load_cpu_field(vfp.xregs[rn]);
2989 tmp = load_cpu_field(vfp.xregs[rn]);
2991 case ARM_VFP_FPINST:
2992 case ARM_VFP_FPINST2:
2993 /* Not present in VFP3. */
2995 || arm_feature(env, ARM_FEATURE_VFP3))
2997 tmp = load_cpu_field(vfp.xregs[rn]);
3001 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3002 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3004 tmp = tcg_temp_new_i32();
3005 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3011 || !arm_feature(env, ARM_FEATURE_MVFR))
3013 tmp = load_cpu_field(vfp.xregs[rn]);
3019 gen_mov_F0_vreg(0, rn);
3020 tmp = gen_vfp_mrs();
3023 /* Set the 4 flag bits in the CPSR. */
3025 tcg_temp_free_i32(tmp);
3027 store_reg(s, rd, tmp);
3031 if (insn & (1 << 21)) {
3033 /* system register */
3038 /* Writes are ignored. */
3041 tmp = load_reg(s, rd);
3042 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3043 tcg_temp_free_i32(tmp);
3049 /* TODO: VFP subarchitecture support.
3050 * For now, keep the EN bit only */
3051 tmp = load_reg(s, rd);
3052 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3053 store_cpu_field(tmp, vfp.xregs[rn]);
3056 case ARM_VFP_FPINST:
3057 case ARM_VFP_FPINST2:
3058 tmp = load_reg(s, rd);
3059 store_cpu_field(tmp, vfp.xregs[rn]);
3065 tmp = load_reg(s, rd);
3067 gen_mov_vreg_F0(0, rn);
3072 /* data processing */
3073 /* The opcode is in bits 23, 21, 20 and 6. */
3074 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3078 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3080 /* rn is register number */
3081 VFP_DREG_N(rn, insn);
3084 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3085 /* Integer or single precision destination. */
3086 rd = VFP_SREG_D(insn);
3088 VFP_DREG_D(rd, insn);
3091 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3092 /* VCVT from int is always from S reg regardless of dp bit.
3093 * VCVT with immediate frac_bits has same format as SREG_M
3095 rm = VFP_SREG_M(insn);
3097 VFP_DREG_M(rm, insn);
3100 rn = VFP_SREG_N(insn);
3101 if (op == 15 && rn == 15) {
3102 /* Double precision destination. */
3103 VFP_DREG_D(rd, insn);
3105 rd = VFP_SREG_D(insn);
3107 /* NB that we implicitly rely on the encoding for the frac_bits
3108 * in VCVT of fixed to float being the same as that of an SREG_M
3110 rm = VFP_SREG_M(insn);
3113 veclen = s->vec_len;
3114 if (op == 15 && rn > 3)
3117 /* Shut up compiler warnings. */
3128 /* Figure out what type of vector operation this is. */
3129 if ((rd & bank_mask) == 0) {
3134 delta_d = (s->vec_stride >> 1) + 1;
3136 delta_d = s->vec_stride + 1;
3138 if ((rm & bank_mask) == 0) {
3139 /* mixed scalar/vector */
3148 /* Load the initial operands. */
3153 /* Integer source */
3154 gen_mov_F0_vreg(0, rm);
3159 gen_mov_F0_vreg(dp, rd);
3160 gen_mov_F1_vreg(dp, rm);
3164 /* Compare with zero */
3165 gen_mov_F0_vreg(dp, rd);
3176 /* Source and destination the same. */
3177 gen_mov_F0_vreg(dp, rd);
3183 /* VCVTB, VCVTT: only present with the halfprec extension,
3184 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3186 if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3189 /* Otherwise fall through */
3191 /* One source operand. */
3192 gen_mov_F0_vreg(dp, rm);
3196 /* Two source operands. */
3197 gen_mov_F0_vreg(dp, rn);
3198 gen_mov_F1_vreg(dp, rm);
3202 /* Perform the calculation. */
3204 case 0: /* VMLA: fd + (fn * fm) */
3205 /* Note that order of inputs to the add matters for NaNs */
3207 gen_mov_F0_vreg(dp, rd);
3210 case 1: /* VMLS: fd + -(fn * fm) */
3213 gen_mov_F0_vreg(dp, rd);
3216 case 2: /* VNMLS: -fd + (fn * fm) */
3217 /* Note that it isn't valid to replace (-A + B) with (B - A)
3218 * or similar plausible looking simplifications
3219 * because this will give wrong results for NaNs.
3222 gen_mov_F0_vreg(dp, rd);
3226 case 3: /* VNMLA: -fd + -(fn * fm) */
3229 gen_mov_F0_vreg(dp, rd);
3233 case 4: /* mul: fn * fm */
3236 case 5: /* nmul: -(fn * fm) */
3240 case 6: /* add: fn + fm */
3243 case 7: /* sub: fn - fm */
3246 case 8: /* div: fn / fm */
3249 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3250 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3251 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3252 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3253 /* These are fused multiply-add, and must be done as one
3254 * floating point operation with no rounding between the
3255 * multiplication and addition steps.
3256 * NB that doing the negations here as separate steps is
3257 * correct : an input NaN should come out with its sign bit
3258 * flipped if it is a negated-input.
3260 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3268 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3270 frd = tcg_temp_new_i64();
3271 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3274 gen_helper_vfp_negd(frd, frd);
3276 fpst = get_fpstatus_ptr(0);
3277 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3278 cpu_F1d, frd, fpst);
3279 tcg_temp_free_ptr(fpst);
3280 tcg_temp_free_i64(frd);
3286 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3288 frd = tcg_temp_new_i32();
3289 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3291 gen_helper_vfp_negs(frd, frd);
3293 fpst = get_fpstatus_ptr(0);
3294 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3295 cpu_F1s, frd, fpst);
3296 tcg_temp_free_ptr(fpst);
3297 tcg_temp_free_i32(frd);
3300 case 14: /* fconst */
3301 if (!arm_feature(env, ARM_FEATURE_VFP3))
3304 n = (insn << 12) & 0x80000000;
3305 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3312 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3319 tcg_gen_movi_i32(cpu_F0s, n);
3322 case 15: /* extension space */
3336 case 4: /* vcvtb.f32.f16 */
3337 tmp = gen_vfp_mrs();
3338 tcg_gen_ext16u_i32(tmp, tmp);
3339 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3340 tcg_temp_free_i32(tmp);
3342 case 5: /* vcvtt.f32.f16 */
3343 tmp = gen_vfp_mrs();
3344 tcg_gen_shri_i32(tmp, tmp, 16);
3345 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3346 tcg_temp_free_i32(tmp);
3348 case 6: /* vcvtb.f16.f32 */
3349 tmp = tcg_temp_new_i32();
3350 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3351 gen_mov_F0_vreg(0, rd);
3352 tmp2 = gen_vfp_mrs();
3353 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3354 tcg_gen_or_i32(tmp, tmp, tmp2);
3355 tcg_temp_free_i32(tmp2);
3358 case 7: /* vcvtt.f16.f32 */
3359 tmp = tcg_temp_new_i32();
3360 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3361 tcg_gen_shli_i32(tmp, tmp, 16);
3362 gen_mov_F0_vreg(0, rd);
3363 tmp2 = gen_vfp_mrs();
3364 tcg_gen_ext16u_i32(tmp2, tmp2);
3365 tcg_gen_or_i32(tmp, tmp, tmp2);
3366 tcg_temp_free_i32(tmp2);
3378 case 11: /* cmpez */
3382 case 12: /* vrintr */
3384 TCGv_ptr fpst = get_fpstatus_ptr(0);
3386 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3388 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3390 tcg_temp_free_ptr(fpst);
3393 case 13: /* vrintz */
3395 TCGv_ptr fpst = get_fpstatus_ptr(0);
3397 tcg_rmode = tcg_const_i32(float_round_to_zero);
3398 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3400 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3402 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3404 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3405 tcg_temp_free_i32(tcg_rmode);
3406 tcg_temp_free_ptr(fpst);
3409 case 14: /* vrintx */
3411 TCGv_ptr fpst = get_fpstatus_ptr(0);
3413 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3415 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3417 tcg_temp_free_ptr(fpst);
3420 case 15: /* single<->double conversion */
3422 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3424 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3426 case 16: /* fuito */
3427 gen_vfp_uito(dp, 0);
3429 case 17: /* fsito */
3430 gen_vfp_sito(dp, 0);
3432 case 20: /* fshto */
3433 if (!arm_feature(env, ARM_FEATURE_VFP3))
3435 gen_vfp_shto(dp, 16 - rm, 0);
3437 case 21: /* fslto */
3438 if (!arm_feature(env, ARM_FEATURE_VFP3))
3440 gen_vfp_slto(dp, 32 - rm, 0);
3442 case 22: /* fuhto */
3443 if (!arm_feature(env, ARM_FEATURE_VFP3))
3445 gen_vfp_uhto(dp, 16 - rm, 0);
3447 case 23: /* fulto */
3448 if (!arm_feature(env, ARM_FEATURE_VFP3))
3450 gen_vfp_ulto(dp, 32 - rm, 0);
3452 case 24: /* ftoui */
3453 gen_vfp_toui(dp, 0);
3455 case 25: /* ftouiz */
3456 gen_vfp_touiz(dp, 0);
3458 case 26: /* ftosi */
3459 gen_vfp_tosi(dp, 0);
3461 case 27: /* ftosiz */
3462 gen_vfp_tosiz(dp, 0);
3464 case 28: /* ftosh */
3465 if (!arm_feature(env, ARM_FEATURE_VFP3))
3467 gen_vfp_tosh(dp, 16 - rm, 0);
3469 case 29: /* ftosl */
3470 if (!arm_feature(env, ARM_FEATURE_VFP3))
3472 gen_vfp_tosl(dp, 32 - rm, 0);
3474 case 30: /* ftouh */
3475 if (!arm_feature(env, ARM_FEATURE_VFP3))
3477 gen_vfp_touh(dp, 16 - rm, 0);
3479 case 31: /* ftoul */
3480 if (!arm_feature(env, ARM_FEATURE_VFP3))
3482 gen_vfp_toul(dp, 32 - rm, 0);
3484 default: /* undefined */
3488 default: /* undefined */
3492 /* Write back the result. */
3493 if (op == 15 && (rn >= 8 && rn <= 11))
3494 ; /* Comparison, do nothing. */
3495 else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3496 /* VCVT double to int: always integer result. */
3497 gen_mov_vreg_F0(0, rd);
3498 else if (op == 15 && rn == 15)
3500 gen_mov_vreg_F0(!dp, rd);
3502 gen_mov_vreg_F0(dp, rd);
3504 /* break out of the loop if we have finished */
3508 if (op == 15 && delta_m == 0) {
3509 /* single source one-many */
3511 rd = ((rd + delta_d) & (bank_mask - 1))
3513 gen_mov_vreg_F0(dp, rd);
3517 /* Setup the next operands. */
3519 rd = ((rd + delta_d) & (bank_mask - 1))
3523 /* One source operand. */
3524 rm = ((rm + delta_m) & (bank_mask - 1))
3526 gen_mov_F0_vreg(dp, rm);
3528 /* Two source operands. */
3529 rn = ((rn + delta_d) & (bank_mask - 1))
3531 gen_mov_F0_vreg(dp, rn);
3533 rm = ((rm + delta_m) & (bank_mask - 1))
3535 gen_mov_F1_vreg(dp, rm);
3543 if ((insn & 0x03e00000) == 0x00400000) {
3544 /* two-register transfer */
3545 rn = (insn >> 16) & 0xf;
3546 rd = (insn >> 12) & 0xf;
3548 VFP_DREG_M(rm, insn);
3550 rm = VFP_SREG_M(insn);
3553 if (insn & ARM_CP_RW_BIT) {
3556 gen_mov_F0_vreg(0, rm * 2);
3557 tmp = gen_vfp_mrs();
3558 store_reg(s, rd, tmp);
3559 gen_mov_F0_vreg(0, rm * 2 + 1);
3560 tmp = gen_vfp_mrs();
3561 store_reg(s, rn, tmp);
3563 gen_mov_F0_vreg(0, rm);
3564 tmp = gen_vfp_mrs();
3565 store_reg(s, rd, tmp);
3566 gen_mov_F0_vreg(0, rm + 1);
3567 tmp = gen_vfp_mrs();
3568 store_reg(s, rn, tmp);
3573 tmp = load_reg(s, rd);
3575 gen_mov_vreg_F0(0, rm * 2);
3576 tmp = load_reg(s, rn);
3578 gen_mov_vreg_F0(0, rm * 2 + 1);
3580 tmp = load_reg(s, rd);
3582 gen_mov_vreg_F0(0, rm);
3583 tmp = load_reg(s, rn);
3585 gen_mov_vreg_F0(0, rm + 1);
3590 rn = (insn >> 16) & 0xf;
3592 VFP_DREG_D(rd, insn);
3594 rd = VFP_SREG_D(insn);
3595 if ((insn & 0x01200000) == 0x01000000) {
3596 /* Single load/store */
3597 offset = (insn & 0xff) << 2;
3598 if ((insn & (1 << 23)) == 0)
3600 if (s->thumb && rn == 15) {
3601 /* This is actually UNPREDICTABLE */
3602 addr = tcg_temp_new_i32();
3603 tcg_gen_movi_i32(addr, s->pc & ~2);
3605 addr = load_reg(s, rn);
3607 tcg_gen_addi_i32(addr, addr, offset);
3608 if (insn & (1 << 20)) {
3609 gen_vfp_ld(s, dp, addr);
3610 gen_mov_vreg_F0(dp, rd);
3612 gen_mov_F0_vreg(dp, rd);
3613 gen_vfp_st(s, dp, addr);
3615 tcg_temp_free_i32(addr);
3617 /* load/store multiple */
3618 int w = insn & (1 << 21);
3620 n = (insn >> 1) & 0x7f;
3624 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3625 /* P == U , W == 1 => UNDEF */
3628 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3629 /* UNPREDICTABLE cases for bad immediates: we choose to
3630 * UNDEF to avoid generating huge numbers of TCG ops
3634 if (rn == 15 && w) {
3635 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3639 if (s->thumb && rn == 15) {
3640 /* This is actually UNPREDICTABLE */
3641 addr = tcg_temp_new_i32();
3642 tcg_gen_movi_i32(addr, s->pc & ~2);
3644 addr = load_reg(s, rn);
3646 if (insn & (1 << 24)) /* pre-decrement */
3647 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3653 for (i = 0; i < n; i++) {
3654 if (insn & ARM_CP_RW_BIT) {
3656 gen_vfp_ld(s, dp, addr);
3657 gen_mov_vreg_F0(dp, rd + i);
3660 gen_mov_F0_vreg(dp, rd + i);
3661 gen_vfp_st(s, dp, addr);
3663 tcg_gen_addi_i32(addr, addr, offset);
3667 if (insn & (1 << 24))
3668 offset = -offset * n;
3669 else if (dp && (insn & 1))
3675 tcg_gen_addi_i32(addr, addr, offset);
3676 store_reg(s, rn, addr);
3678 tcg_temp_free_i32(addr);
3684 /* Should never happen. */
3690 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3692 TranslationBlock *tb;
3695 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3697 gen_set_pc_im(s, dest);
3698 tcg_gen_exit_tb((uintptr_t)tb + n);
3700 gen_set_pc_im(s, dest);
3705 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3707 if (unlikely(s->singlestep_enabled)) {
3708 /* An indirect jump so that we still trigger the debug exception. */
3713 gen_goto_tb(s, 0, dest);
3714 s->is_jmp = DISAS_TB_JUMP;
3718 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3721 tcg_gen_sari_i32(t0, t0, 16);
3725 tcg_gen_sari_i32(t1, t1, 16);
3728 tcg_gen_mul_i32(t0, t0, t1);
3731 /* Return the mask of PSR bits set by a MSR instruction. */
3732 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3736 if (flags & (1 << 0))
3738 if (flags & (1 << 1))
3740 if (flags & (1 << 2))
3742 if (flags & (1 << 3))
3745 /* Mask out undefined bits. */
3746 mask &= ~CPSR_RESERVED;
3747 if (!arm_feature(env, ARM_FEATURE_V4T))
3749 if (!arm_feature(env, ARM_FEATURE_V5))
3750 mask &= ~CPSR_Q; /* V5TE in reality*/
3751 if (!arm_feature(env, ARM_FEATURE_V6))
3752 mask &= ~(CPSR_E | CPSR_GE);
3753 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3755 /* Mask out execution state bits. */
3758 /* Mask out privileged bits. */
3764 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3765 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3769 /* ??? This is also undefined in system mode. */
3773 tmp = load_cpu_field(spsr);
3774 tcg_gen_andi_i32(tmp, tmp, ~mask);
3775 tcg_gen_andi_i32(t0, t0, mask);
3776 tcg_gen_or_i32(tmp, tmp, t0);
3777 store_cpu_field(tmp, spsr);
3779 gen_set_cpsr(t0, mask);
3781 tcg_temp_free_i32(t0);
3786 /* Returns nonzero if access to the PSR is not permitted. */
3787 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3790 tmp = tcg_temp_new_i32();
3791 tcg_gen_movi_i32(tmp, val);
3792 return gen_set_psr(s, mask, spsr, tmp);
3795 /* Generate an old-style exception return. Marks pc as dead. */
3796 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3799 store_reg(s, 15, pc);
3800 tmp = load_cpu_field(spsr);
3801 gen_set_cpsr(tmp, 0xffffffff);
3802 tcg_temp_free_i32(tmp);
3803 s->is_jmp = DISAS_UPDATE;
3806 /* Generate a v6 exception return. Marks both values as dead. */
3807 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3809 gen_set_cpsr(cpsr, 0xffffffff);
3810 tcg_temp_free_i32(cpsr);
3811 store_reg(s, 15, pc);
3812 s->is_jmp = DISAS_UPDATE;
3816 gen_set_condexec (DisasContext *s)
3818 if (s->condexec_mask) {
3819 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3820 TCGv_i32 tmp = tcg_temp_new_i32();
3821 tcg_gen_movi_i32(tmp, val);
3822 store_cpu_field(tmp, condexec_bits);
3826 static void gen_exception_insn(DisasContext *s, int offset, int excp)
3828 gen_set_condexec(s);
3829 gen_set_pc_im(s, s->pc - offset);
3830 gen_exception(excp);
3831 s->is_jmp = DISAS_JUMP;
3834 static void gen_nop_hint(DisasContext *s, int val)
3838 gen_set_pc_im(s, s->pc);
3839 s->is_jmp = DISAS_WFI;
3844 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3850 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3852 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3855 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3856 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3857 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3862 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3865 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3866 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3867 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3872 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3873 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3874 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3875 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3876 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3878 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3879 switch ((size << 1) | u) { \
3881 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3884 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3887 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3890 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3893 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3896 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3898 default: return 1; \
3901 #define GEN_NEON_INTEGER_OP(name) do { \
3902 switch ((size << 1) | u) { \
3904 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3907 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3910 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3913 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3916 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3919 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3921 default: return 1; \
3924 static TCGv_i32 neon_load_scratch(int scratch)
3926 TCGv_i32 tmp = tcg_temp_new_i32();
3927 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3931 static void neon_store_scratch(int scratch, TCGv_i32 var)
3933 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3934 tcg_temp_free_i32(var);
3937 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3941 tmp = neon_load_reg(reg & 7, reg >> 4);
3943 gen_neon_dup_high16(tmp);
3945 gen_neon_dup_low16(tmp);
3948 tmp = neon_load_reg(reg & 15, reg >> 4);
3953 static int gen_neon_unzip(int rd, int rm, int size, int q)
3956 if (!q && size == 2) {
3959 tmp = tcg_const_i32(rd);
3960 tmp2 = tcg_const_i32(rm);
3964 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3967 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3970 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3978 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3981 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3987 tcg_temp_free_i32(tmp);
3988 tcg_temp_free_i32(tmp2);
3992 static int gen_neon_zip(int rd, int rm, int size, int q)
3995 if (!q && size == 2) {
3998 tmp = tcg_const_i32(rd);
3999 tmp2 = tcg_const_i32(rm);
4003 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4006 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4009 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4017 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4020 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4026 tcg_temp_free_i32(tmp);
4027 tcg_temp_free_i32(tmp2);
4031 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4035 rd = tcg_temp_new_i32();
4036 tmp = tcg_temp_new_i32();
4038 tcg_gen_shli_i32(rd, t0, 8);
4039 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4040 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4041 tcg_gen_or_i32(rd, rd, tmp);
4043 tcg_gen_shri_i32(t1, t1, 8);
4044 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4045 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4046 tcg_gen_or_i32(t1, t1, tmp);
4047 tcg_gen_mov_i32(t0, rd);
4049 tcg_temp_free_i32(tmp);
4050 tcg_temp_free_i32(rd);
4053 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4057 rd = tcg_temp_new_i32();
4058 tmp = tcg_temp_new_i32();
4060 tcg_gen_shli_i32(rd, t0, 16);
4061 tcg_gen_andi_i32(tmp, t1, 0xffff);
4062 tcg_gen_or_i32(rd, rd, tmp);
4063 tcg_gen_shri_i32(t1, t1, 16);
4064 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4065 tcg_gen_or_i32(t1, t1, tmp);
4066 tcg_gen_mov_i32(t0, rd);
4068 tcg_temp_free_i32(tmp);
4069 tcg_temp_free_i32(rd);
4077 } neon_ls_element_type[11] = {
4091 /* Translate a NEON load/store element instruction. Return nonzero if the
4092 instruction is invalid. */
4093 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4112 if (!s->vfp_enabled)
4114 VFP_DREG_D(rd, insn);
4115 rn = (insn >> 16) & 0xf;
4117 load = (insn & (1 << 21)) != 0;
4118 if ((insn & (1 << 23)) == 0) {
4119 /* Load store all elements. */
4120 op = (insn >> 8) & 0xf;
4121 size = (insn >> 6) & 3;
4124 /* Catch UNDEF cases for bad values of align field */
4127 if (((insn >> 5) & 1) == 1) {
4132 if (((insn >> 4) & 3) == 3) {
4139 nregs = neon_ls_element_type[op].nregs;
4140 interleave = neon_ls_element_type[op].interleave;
4141 spacing = neon_ls_element_type[op].spacing;
4142 if (size == 3 && (interleave | spacing) != 1)
4144 addr = tcg_temp_new_i32();
4145 load_reg_var(s, addr, rn);
4146 stride = (1 << size) * interleave;
4147 for (reg = 0; reg < nregs; reg++) {
4148 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4149 load_reg_var(s, addr, rn);
4150 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4151 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4152 load_reg_var(s, addr, rn);
4153 tcg_gen_addi_i32(addr, addr, 1 << size);
4156 tmp64 = tcg_temp_new_i64();
4158 gen_aa32_ld64(tmp64, addr, IS_USER(s));
4159 neon_store_reg64(tmp64, rd);
4161 neon_load_reg64(tmp64, rd);
4162 gen_aa32_st64(tmp64, addr, IS_USER(s));
4164 tcg_temp_free_i64(tmp64);
4165 tcg_gen_addi_i32(addr, addr, stride);
4167 for (pass = 0; pass < 2; pass++) {
4170 tmp = tcg_temp_new_i32();
4171 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4172 neon_store_reg(rd, pass, tmp);
4174 tmp = neon_load_reg(rd, pass);
4175 gen_aa32_st32(tmp, addr, IS_USER(s));
4176 tcg_temp_free_i32(tmp);
4178 tcg_gen_addi_i32(addr, addr, stride);
4179 } else if (size == 1) {
4181 tmp = tcg_temp_new_i32();
4182 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4183 tcg_gen_addi_i32(addr, addr, stride);
4184 tmp2 = tcg_temp_new_i32();
4185 gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4186 tcg_gen_addi_i32(addr, addr, stride);
4187 tcg_gen_shli_i32(tmp2, tmp2, 16);
4188 tcg_gen_or_i32(tmp, tmp, tmp2);
4189 tcg_temp_free_i32(tmp2);
4190 neon_store_reg(rd, pass, tmp);
4192 tmp = neon_load_reg(rd, pass);
4193 tmp2 = tcg_temp_new_i32();
4194 tcg_gen_shri_i32(tmp2, tmp, 16);
4195 gen_aa32_st16(tmp, addr, IS_USER(s));
4196 tcg_temp_free_i32(tmp);
4197 tcg_gen_addi_i32(addr, addr, stride);
4198 gen_aa32_st16(tmp2, addr, IS_USER(s));
4199 tcg_temp_free_i32(tmp2);
4200 tcg_gen_addi_i32(addr, addr, stride);
4202 } else /* size == 0 */ {
4204 TCGV_UNUSED_I32(tmp2);
4205 for (n = 0; n < 4; n++) {
4206 tmp = tcg_temp_new_i32();
4207 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4208 tcg_gen_addi_i32(addr, addr, stride);
4212 tcg_gen_shli_i32(tmp, tmp, n * 8);
4213 tcg_gen_or_i32(tmp2, tmp2, tmp);
4214 tcg_temp_free_i32(tmp);
4217 neon_store_reg(rd, pass, tmp2);
4219 tmp2 = neon_load_reg(rd, pass);
4220 for (n = 0; n < 4; n++) {
4221 tmp = tcg_temp_new_i32();
4223 tcg_gen_mov_i32(tmp, tmp2);
4225 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4227 gen_aa32_st8(tmp, addr, IS_USER(s));
4228 tcg_temp_free_i32(tmp);
4229 tcg_gen_addi_i32(addr, addr, stride);
4231 tcg_temp_free_i32(tmp2);
4238 tcg_temp_free_i32(addr);
4241 size = (insn >> 10) & 3;
4243 /* Load single element to all lanes. */
4244 int a = (insn >> 4) & 1;
4248 size = (insn >> 6) & 3;
4249 nregs = ((insn >> 8) & 3) + 1;
4252 if (nregs != 4 || a == 0) {
4255 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4258 if (nregs == 1 && a == 1 && size == 0) {
4261 if (nregs == 3 && a == 1) {
4264 addr = tcg_temp_new_i32();
4265 load_reg_var(s, addr, rn);
4267 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4268 tmp = gen_load_and_replicate(s, addr, size);
4269 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4270 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4271 if (insn & (1 << 5)) {
4272 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4273 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4275 tcg_temp_free_i32(tmp);
4277 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4278 stride = (insn & (1 << 5)) ? 2 : 1;
4279 for (reg = 0; reg < nregs; reg++) {
4280 tmp = gen_load_and_replicate(s, addr, size);
4281 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4282 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4283 tcg_temp_free_i32(tmp);
4284 tcg_gen_addi_i32(addr, addr, 1 << size);
4288 tcg_temp_free_i32(addr);
4289 stride = (1 << size) * nregs;
4291 /* Single element. */
4292 int idx = (insn >> 4) & 0xf;
4293 pass = (insn >> 7) & 1;
4296 shift = ((insn >> 5) & 3) * 8;
4300 shift = ((insn >> 6) & 1) * 16;
4301 stride = (insn & (1 << 5)) ? 2 : 1;
4305 stride = (insn & (1 << 6)) ? 2 : 1;
4310 nregs = ((insn >> 8) & 3) + 1;
4311 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4314 if (((idx & (1 << size)) != 0) ||
4315 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4320 if ((idx & 1) != 0) {
4325 if (size == 2 && (idx & 2) != 0) {
4330 if ((size == 2) && ((idx & 3) == 3)) {
4337 if ((rd + stride * (nregs - 1)) > 31) {
4338 /* Attempts to write off the end of the register file
4339 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4340 * the neon_load_reg() would write off the end of the array.
4344 addr = tcg_temp_new_i32();
4345 load_reg_var(s, addr, rn);
4346 for (reg = 0; reg < nregs; reg++) {
4348 tmp = tcg_temp_new_i32();
4351 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4354 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4357 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4359 default: /* Avoid compiler warnings. */
4363 tmp2 = neon_load_reg(rd, pass);
4364 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4365 shift, size ? 16 : 8);
4366 tcg_temp_free_i32(tmp2);
4368 neon_store_reg(rd, pass, tmp);
4369 } else { /* Store */
4370 tmp = neon_load_reg(rd, pass);
4372 tcg_gen_shri_i32(tmp, tmp, shift);
4375 gen_aa32_st8(tmp, addr, IS_USER(s));
4378 gen_aa32_st16(tmp, addr, IS_USER(s));
4381 gen_aa32_st32(tmp, addr, IS_USER(s));
4384 tcg_temp_free_i32(tmp);
4387 tcg_gen_addi_i32(addr, addr, 1 << size);
4389 tcg_temp_free_i32(addr);
4390 stride = nregs * (1 << size);
4396 base = load_reg(s, rn);
4398 tcg_gen_addi_i32(base, base, stride);
4401 index = load_reg(s, rm);
4402 tcg_gen_add_i32(base, base, index);
4403 tcg_temp_free_i32(index);
4405 store_reg(s, rn, base);
4410 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4411 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4413 tcg_gen_and_i32(t, t, c);
4414 tcg_gen_andc_i32(f, f, c);
4415 tcg_gen_or_i32(dest, t, f);
4418 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4421 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4422 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4423 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4428 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4431 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4432 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4433 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4438 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4441 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4442 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4443 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4448 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4451 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4452 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4453 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4458 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4464 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4465 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4470 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4471 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4478 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4479 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4484 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4485 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4492 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4496 case 0: gen_helper_neon_widen_u8(dest, src); break;
4497 case 1: gen_helper_neon_widen_u16(dest, src); break;
4498 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4503 case 0: gen_helper_neon_widen_s8(dest, src); break;
4504 case 1: gen_helper_neon_widen_s16(dest, src); break;
4505 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4509 tcg_temp_free_i32(src);
4512 static inline void gen_neon_addl(int size)
4515 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4516 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4517 case 2: tcg_gen_add_i64(CPU_V001); break;
4522 static inline void gen_neon_subl(int size)
4525 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4526 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4527 case 2: tcg_gen_sub_i64(CPU_V001); break;
4532 static inline void gen_neon_negl(TCGv_i64 var, int size)
4535 case 0: gen_helper_neon_negl_u16(var, var); break;
4536 case 1: gen_helper_neon_negl_u32(var, var); break;
4538 tcg_gen_neg_i64(var, var);
4544 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4547 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4548 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4553 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4558 switch ((size << 1) | u) {
4559 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4560 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4561 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4562 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4564 tmp = gen_muls_i64_i32(a, b);
4565 tcg_gen_mov_i64(dest, tmp);
4566 tcg_temp_free_i64(tmp);
4569 tmp = gen_mulu_i64_i32(a, b);
4570 tcg_gen_mov_i64(dest, tmp);
4571 tcg_temp_free_i64(tmp);
4576 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4577 Don't forget to clean them now. */
4579 tcg_temp_free_i32(a);
4580 tcg_temp_free_i32(b);
4584 static void gen_neon_narrow_op(int op, int u, int size,
4585 TCGv_i32 dest, TCGv_i64 src)
4589 gen_neon_unarrow_sats(size, dest, src);
4591 gen_neon_narrow(size, dest, src);
4595 gen_neon_narrow_satu(size, dest, src);
4597 gen_neon_narrow_sats(size, dest, src);
4602 /* Symbolic constants for op fields for Neon 3-register same-length.
4603 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4606 #define NEON_3R_VHADD 0
4607 #define NEON_3R_VQADD 1
4608 #define NEON_3R_VRHADD 2
4609 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4610 #define NEON_3R_VHSUB 4
4611 #define NEON_3R_VQSUB 5
4612 #define NEON_3R_VCGT 6
4613 #define NEON_3R_VCGE 7
4614 #define NEON_3R_VSHL 8
4615 #define NEON_3R_VQSHL 9
4616 #define NEON_3R_VRSHL 10
4617 #define NEON_3R_VQRSHL 11
4618 #define NEON_3R_VMAX 12
4619 #define NEON_3R_VMIN 13
4620 #define NEON_3R_VABD 14
4621 #define NEON_3R_VABA 15
4622 #define NEON_3R_VADD_VSUB 16
4623 #define NEON_3R_VTST_VCEQ 17
4624 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4625 #define NEON_3R_VMUL 19
4626 #define NEON_3R_VPMAX 20
4627 #define NEON_3R_VPMIN 21
4628 #define NEON_3R_VQDMULH_VQRDMULH 22
4629 #define NEON_3R_VPADD 23
4630 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4631 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4632 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4633 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4634 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4635 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4636 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4638 static const uint8_t neon_3r_sizes[] = {
4639 [NEON_3R_VHADD] = 0x7,
4640 [NEON_3R_VQADD] = 0xf,
4641 [NEON_3R_VRHADD] = 0x7,
4642 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4643 [NEON_3R_VHSUB] = 0x7,
4644 [NEON_3R_VQSUB] = 0xf,
4645 [NEON_3R_VCGT] = 0x7,
4646 [NEON_3R_VCGE] = 0x7,
4647 [NEON_3R_VSHL] = 0xf,
4648 [NEON_3R_VQSHL] = 0xf,
4649 [NEON_3R_VRSHL] = 0xf,
4650 [NEON_3R_VQRSHL] = 0xf,
4651 [NEON_3R_VMAX] = 0x7,
4652 [NEON_3R_VMIN] = 0x7,
4653 [NEON_3R_VABD] = 0x7,
4654 [NEON_3R_VABA] = 0x7,
4655 [NEON_3R_VADD_VSUB] = 0xf,
4656 [NEON_3R_VTST_VCEQ] = 0x7,
4657 [NEON_3R_VML] = 0x7,
4658 [NEON_3R_VMUL] = 0x7,
4659 [NEON_3R_VPMAX] = 0x7,
4660 [NEON_3R_VPMIN] = 0x7,
4661 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4662 [NEON_3R_VPADD] = 0x7,
4663 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4664 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4665 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4666 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4667 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4668 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4669 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4672 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4673 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4676 #define NEON_2RM_VREV64 0
4677 #define NEON_2RM_VREV32 1
4678 #define NEON_2RM_VREV16 2
4679 #define NEON_2RM_VPADDL 4
4680 #define NEON_2RM_VPADDL_U 5
4681 #define NEON_2RM_AESE 6 /* Includes AESD */
4682 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4683 #define NEON_2RM_VCLS 8
4684 #define NEON_2RM_VCLZ 9
4685 #define NEON_2RM_VCNT 10
4686 #define NEON_2RM_VMVN 11
4687 #define NEON_2RM_VPADAL 12
4688 #define NEON_2RM_VPADAL_U 13
4689 #define NEON_2RM_VQABS 14
4690 #define NEON_2RM_VQNEG 15
4691 #define NEON_2RM_VCGT0 16
4692 #define NEON_2RM_VCGE0 17
4693 #define NEON_2RM_VCEQ0 18
4694 #define NEON_2RM_VCLE0 19
4695 #define NEON_2RM_VCLT0 20
4696 #define NEON_2RM_VABS 22
4697 #define NEON_2RM_VNEG 23
4698 #define NEON_2RM_VCGT0_F 24
4699 #define NEON_2RM_VCGE0_F 25
4700 #define NEON_2RM_VCEQ0_F 26
4701 #define NEON_2RM_VCLE0_F 27
4702 #define NEON_2RM_VCLT0_F 28
4703 #define NEON_2RM_VABS_F 30
4704 #define NEON_2RM_VNEG_F 31
4705 #define NEON_2RM_VSWP 32
4706 #define NEON_2RM_VTRN 33
4707 #define NEON_2RM_VUZP 34
4708 #define NEON_2RM_VZIP 35
4709 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4710 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4711 #define NEON_2RM_VSHLL 38
4712 #define NEON_2RM_VCVT_F16_F32 44
4713 #define NEON_2RM_VCVT_F32_F16 46
4714 #define NEON_2RM_VRECPE 56
4715 #define NEON_2RM_VRSQRTE 57
4716 #define NEON_2RM_VRECPE_F 58
4717 #define NEON_2RM_VRSQRTE_F 59
4718 #define NEON_2RM_VCVT_FS 60
4719 #define NEON_2RM_VCVT_FU 61
4720 #define NEON_2RM_VCVT_SF 62
4721 #define NEON_2RM_VCVT_UF 63
4723 static int neon_2rm_is_float_op(int op)
4725 /* Return true if this neon 2reg-misc op is float-to-float */
4726 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4727 op >= NEON_2RM_VRECPE_F);
4730 /* Each entry in this array has bit n set if the insn allows
4731 * size value n (otherwise it will UNDEF). Since unallocated
4732 * op values will have no bits set they always UNDEF.
4734 static const uint8_t neon_2rm_sizes[] = {
4735 [NEON_2RM_VREV64] = 0x7,
4736 [NEON_2RM_VREV32] = 0x3,
4737 [NEON_2RM_VREV16] = 0x1,
4738 [NEON_2RM_VPADDL] = 0x7,
4739 [NEON_2RM_VPADDL_U] = 0x7,
4740 [NEON_2RM_AESE] = 0x1,
4741 [NEON_2RM_AESMC] = 0x1,
4742 [NEON_2RM_VCLS] = 0x7,
4743 [NEON_2RM_VCLZ] = 0x7,
4744 [NEON_2RM_VCNT] = 0x1,
4745 [NEON_2RM_VMVN] = 0x1,
4746 [NEON_2RM_VPADAL] = 0x7,
4747 [NEON_2RM_VPADAL_U] = 0x7,
4748 [NEON_2RM_VQABS] = 0x7,
4749 [NEON_2RM_VQNEG] = 0x7,
4750 [NEON_2RM_VCGT0] = 0x7,
4751 [NEON_2RM_VCGE0] = 0x7,
4752 [NEON_2RM_VCEQ0] = 0x7,
4753 [NEON_2RM_VCLE0] = 0x7,
4754 [NEON_2RM_VCLT0] = 0x7,
4755 [NEON_2RM_VABS] = 0x7,
4756 [NEON_2RM_VNEG] = 0x7,
4757 [NEON_2RM_VCGT0_F] = 0x4,
4758 [NEON_2RM_VCGE0_F] = 0x4,
4759 [NEON_2RM_VCEQ0_F] = 0x4,
4760 [NEON_2RM_VCLE0_F] = 0x4,
4761 [NEON_2RM_VCLT0_F] = 0x4,
4762 [NEON_2RM_VABS_F] = 0x4,
4763 [NEON_2RM_VNEG_F] = 0x4,
4764 [NEON_2RM_VSWP] = 0x1,
4765 [NEON_2RM_VTRN] = 0x7,
4766 [NEON_2RM_VUZP] = 0x7,
4767 [NEON_2RM_VZIP] = 0x7,
4768 [NEON_2RM_VMOVN] = 0x7,
4769 [NEON_2RM_VQMOVN] = 0x7,
4770 [NEON_2RM_VSHLL] = 0x7,
4771 [NEON_2RM_VCVT_F16_F32] = 0x2,
4772 [NEON_2RM_VCVT_F32_F16] = 0x2,
4773 [NEON_2RM_VRECPE] = 0x4,
4774 [NEON_2RM_VRSQRTE] = 0x4,
4775 [NEON_2RM_VRECPE_F] = 0x4,
4776 [NEON_2RM_VRSQRTE_F] = 0x4,
4777 [NEON_2RM_VCVT_FS] = 0x4,
4778 [NEON_2RM_VCVT_FU] = 0x4,
4779 [NEON_2RM_VCVT_SF] = 0x4,
4780 [NEON_2RM_VCVT_UF] = 0x4,
4783 /* Translate a NEON data processing instruction. Return nonzero if the
4784 instruction is invalid.
4785 We process data in a mixture of 32-bit and 64-bit chunks.
4786 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4788 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4800 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4803 if (!s->vfp_enabled)
4805 q = (insn & (1 << 6)) != 0;
4806 u = (insn >> 24) & 1;
4807 VFP_DREG_D(rd, insn);
4808 VFP_DREG_N(rn, insn);
4809 VFP_DREG_M(rm, insn);
4810 size = (insn >> 20) & 3;
4811 if ((insn & (1 << 23)) == 0) {
4812 /* Three register same length. */
4813 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4814 /* Catch invalid op and bad size combinations: UNDEF */
4815 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4818 /* All insns of this form UNDEF for either this condition or the
4819 * superset of cases "Q==1"; we catch the latter later.
4821 if (q && ((rd | rn | rm) & 1)) {
4824 if (size == 3 && op != NEON_3R_LOGIC) {
4825 /* 64-bit element instructions. */
4826 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4827 neon_load_reg64(cpu_V0, rn + pass);
4828 neon_load_reg64(cpu_V1, rm + pass);
4832 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4835 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4841 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4844 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4850 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4852 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4857 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4860 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4866 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4868 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4871 case NEON_3R_VQRSHL:
4873 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4876 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4880 case NEON_3R_VADD_VSUB:
4882 tcg_gen_sub_i64(CPU_V001);
4884 tcg_gen_add_i64(CPU_V001);
4890 neon_store_reg64(cpu_V0, rd + pass);
4899 case NEON_3R_VQRSHL:
4902 /* Shift instruction operands are reversed. */
4917 case NEON_3R_FLOAT_ARITH:
4918 pairwise = (u && size < 2); /* if VPADD (float) */
4920 case NEON_3R_FLOAT_MINMAX:
4921 pairwise = u; /* if VPMIN/VPMAX (float) */
4923 case NEON_3R_FLOAT_CMP:
4925 /* no encoding for U=0 C=1x */
4929 case NEON_3R_FLOAT_ACMP:
4934 case NEON_3R_FLOAT_MISC:
4935 /* VMAXNM/VMINNM in ARMv8 */
4936 if (u && !arm_feature(env, ARM_FEATURE_V8)) {
4941 if (u && (size != 0)) {
4942 /* UNDEF on invalid size for polynomial subcase */
4947 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4955 if (pairwise && q) {
4956 /* All the pairwise insns UNDEF if Q is set */
4960 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4965 tmp = neon_load_reg(rn, 0);
4966 tmp2 = neon_load_reg(rn, 1);
4968 tmp = neon_load_reg(rm, 0);
4969 tmp2 = neon_load_reg(rm, 1);
4973 tmp = neon_load_reg(rn, pass);
4974 tmp2 = neon_load_reg(rm, pass);
4978 GEN_NEON_INTEGER_OP(hadd);
4981 GEN_NEON_INTEGER_OP_ENV(qadd);
4983 case NEON_3R_VRHADD:
4984 GEN_NEON_INTEGER_OP(rhadd);
4986 case NEON_3R_LOGIC: /* Logic ops. */
4987 switch ((u << 2) | size) {
4989 tcg_gen_and_i32(tmp, tmp, tmp2);
4992 tcg_gen_andc_i32(tmp, tmp, tmp2);
4995 tcg_gen_or_i32(tmp, tmp, tmp2);
4998 tcg_gen_orc_i32(tmp, tmp, tmp2);
5001 tcg_gen_xor_i32(tmp, tmp, tmp2);
5004 tmp3 = neon_load_reg(rd, pass);
5005 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5006 tcg_temp_free_i32(tmp3);
5009 tmp3 = neon_load_reg(rd, pass);
5010 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5011 tcg_temp_free_i32(tmp3);
5014 tmp3 = neon_load_reg(rd, pass);
5015 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5016 tcg_temp_free_i32(tmp3);
5021 GEN_NEON_INTEGER_OP(hsub);
5024 GEN_NEON_INTEGER_OP_ENV(qsub);
5027 GEN_NEON_INTEGER_OP(cgt);
5030 GEN_NEON_INTEGER_OP(cge);
5033 GEN_NEON_INTEGER_OP(shl);
5036 GEN_NEON_INTEGER_OP_ENV(qshl);
5039 GEN_NEON_INTEGER_OP(rshl);
5041 case NEON_3R_VQRSHL:
5042 GEN_NEON_INTEGER_OP_ENV(qrshl);
5045 GEN_NEON_INTEGER_OP(max);
5048 GEN_NEON_INTEGER_OP(min);
5051 GEN_NEON_INTEGER_OP(abd);
5054 GEN_NEON_INTEGER_OP(abd);
5055 tcg_temp_free_i32(tmp2);
5056 tmp2 = neon_load_reg(rd, pass);
5057 gen_neon_add(size, tmp, tmp2);
5059 case NEON_3R_VADD_VSUB:
5060 if (!u) { /* VADD */
5061 gen_neon_add(size, tmp, tmp2);
5064 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5065 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5066 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5071 case NEON_3R_VTST_VCEQ:
5072 if (!u) { /* VTST */
5074 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5075 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5076 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5081 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5082 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5083 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5088 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5090 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5091 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5092 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5095 tcg_temp_free_i32(tmp2);
5096 tmp2 = neon_load_reg(rd, pass);
5098 gen_neon_rsb(size, tmp, tmp2);
5100 gen_neon_add(size, tmp, tmp2);
5104 if (u) { /* polynomial */
5105 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5106 } else { /* Integer */
5108 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5109 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5110 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5116 GEN_NEON_INTEGER_OP(pmax);
5119 GEN_NEON_INTEGER_OP(pmin);
5121 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5122 if (!u) { /* VQDMULH */
5125 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5128 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5132 } else { /* VQRDMULH */
5135 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5138 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5146 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5147 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5148 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5152 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5154 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5155 switch ((u << 2) | size) {
5158 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5161 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5164 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5169 tcg_temp_free_ptr(fpstatus);
5172 case NEON_3R_FLOAT_MULTIPLY:
5174 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5175 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5177 tcg_temp_free_i32(tmp2);
5178 tmp2 = neon_load_reg(rd, pass);
5180 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5182 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5185 tcg_temp_free_ptr(fpstatus);
5188 case NEON_3R_FLOAT_CMP:
5190 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5192 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5195 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5197 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5200 tcg_temp_free_ptr(fpstatus);
5203 case NEON_3R_FLOAT_ACMP:
5205 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5207 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5209 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5211 tcg_temp_free_ptr(fpstatus);
5214 case NEON_3R_FLOAT_MINMAX:
5216 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5218 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5220 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5222 tcg_temp_free_ptr(fpstatus);
5225 case NEON_3R_FLOAT_MISC:
5228 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5230 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5232 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5234 tcg_temp_free_ptr(fpstatus);
5237 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5239 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5245 /* VFMA, VFMS: fused multiply-add */
5246 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5247 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5250 gen_helper_vfp_negs(tmp, tmp);
5252 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5253 tcg_temp_free_i32(tmp3);
5254 tcg_temp_free_ptr(fpstatus);
5260 tcg_temp_free_i32(tmp2);
5262 /* Save the result. For elementwise operations we can put it
5263 straight into the destination register. For pairwise operations
5264 we have to be careful to avoid clobbering the source operands. */
5265 if (pairwise && rd == rm) {
5266 neon_store_scratch(pass, tmp);
5268 neon_store_reg(rd, pass, tmp);
5272 if (pairwise && rd == rm) {
5273 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5274 tmp = neon_load_scratch(pass);
5275 neon_store_reg(rd, pass, tmp);
5278 /* End of 3 register same size operations. */
5279 } else if (insn & (1 << 4)) {
5280 if ((insn & 0x00380080) != 0) {
5281 /* Two registers and shift. */
5282 op = (insn >> 8) & 0xf;
5283 if (insn & (1 << 7)) {
5291 while ((insn & (1 << (size + 19))) == 0)
5294 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5295 /* To avoid excessive duplication of ops we implement shift
5296 by immediate using the variable shift operations. */
5298 /* Shift by immediate:
5299 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5300 if (q && ((rd | rm) & 1)) {
5303 if (!u && (op == 4 || op == 6)) {
5306 /* Right shifts are encoded as N - shift, where N is the
5307 element size in bits. */
5309 shift = shift - (1 << (size + 3));
5317 imm = (uint8_t) shift;
5322 imm = (uint16_t) shift;
5333 for (pass = 0; pass < count; pass++) {
5335 neon_load_reg64(cpu_V0, rm + pass);
5336 tcg_gen_movi_i64(cpu_V1, imm);
5341 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5343 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5348 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5350 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5353 case 5: /* VSHL, VSLI */
5354 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5356 case 6: /* VQSHLU */
5357 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5362 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5365 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5370 if (op == 1 || op == 3) {
5372 neon_load_reg64(cpu_V1, rd + pass);
5373 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5374 } else if (op == 4 || (op == 5 && u)) {
5376 neon_load_reg64(cpu_V1, rd + pass);
5378 if (shift < -63 || shift > 63) {
5382 mask = 0xffffffffffffffffull >> -shift;
5384 mask = 0xffffffffffffffffull << shift;
5387 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5388 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5390 neon_store_reg64(cpu_V0, rd + pass);
5391 } else { /* size < 3 */
5392 /* Operands in T0 and T1. */
5393 tmp = neon_load_reg(rm, pass);
5394 tmp2 = tcg_temp_new_i32();
5395 tcg_gen_movi_i32(tmp2, imm);
5399 GEN_NEON_INTEGER_OP(shl);
5403 GEN_NEON_INTEGER_OP(rshl);
5406 case 5: /* VSHL, VSLI */
5408 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5409 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5410 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5414 case 6: /* VQSHLU */
5417 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5421 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5425 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5433 GEN_NEON_INTEGER_OP_ENV(qshl);
5436 tcg_temp_free_i32(tmp2);
5438 if (op == 1 || op == 3) {
5440 tmp2 = neon_load_reg(rd, pass);
5441 gen_neon_add(size, tmp, tmp2);
5442 tcg_temp_free_i32(tmp2);
5443 } else if (op == 4 || (op == 5 && u)) {
5448 mask = 0xff >> -shift;
5450 mask = (uint8_t)(0xff << shift);
5456 mask = 0xffff >> -shift;
5458 mask = (uint16_t)(0xffff << shift);
5462 if (shift < -31 || shift > 31) {
5466 mask = 0xffffffffu >> -shift;
5468 mask = 0xffffffffu << shift;
5474 tmp2 = neon_load_reg(rd, pass);
5475 tcg_gen_andi_i32(tmp, tmp, mask);
5476 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5477 tcg_gen_or_i32(tmp, tmp, tmp2);
5478 tcg_temp_free_i32(tmp2);
5480 neon_store_reg(rd, pass, tmp);
5483 } else if (op < 10) {
5484 /* Shift by immediate and narrow:
5485 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5486 int input_unsigned = (op == 8) ? !u : u;
5490 shift = shift - (1 << (size + 3));
5493 tmp64 = tcg_const_i64(shift);
5494 neon_load_reg64(cpu_V0, rm);
5495 neon_load_reg64(cpu_V1, rm + 1);
5496 for (pass = 0; pass < 2; pass++) {
5504 if (input_unsigned) {
5505 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5507 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5510 if (input_unsigned) {
5511 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5513 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5516 tmp = tcg_temp_new_i32();
5517 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5518 neon_store_reg(rd, pass, tmp);
5520 tcg_temp_free_i64(tmp64);
5523 imm = (uint16_t)shift;
5527 imm = (uint32_t)shift;
5529 tmp2 = tcg_const_i32(imm);
5530 tmp4 = neon_load_reg(rm + 1, 0);
5531 tmp5 = neon_load_reg(rm + 1, 1);
5532 for (pass = 0; pass < 2; pass++) {
5534 tmp = neon_load_reg(rm, 0);
5538 gen_neon_shift_narrow(size, tmp, tmp2, q,
5541 tmp3 = neon_load_reg(rm, 1);
5545 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5547 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5548 tcg_temp_free_i32(tmp);
5549 tcg_temp_free_i32(tmp3);
5550 tmp = tcg_temp_new_i32();
5551 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5552 neon_store_reg(rd, pass, tmp);
5554 tcg_temp_free_i32(tmp2);
5556 } else if (op == 10) {
5558 if (q || (rd & 1)) {
5561 tmp = neon_load_reg(rm, 0);
5562 tmp2 = neon_load_reg(rm, 1);
5563 for (pass = 0; pass < 2; pass++) {
5567 gen_neon_widen(cpu_V0, tmp, size, u);
5570 /* The shift is less than the width of the source
5571 type, so we can just shift the whole register. */
5572 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5573 /* Widen the result of shift: we need to clear
5574 * the potential overflow bits resulting from
5575 * left bits of the narrow input appearing as
5576 * right bits of left the neighbour narrow
5578 if (size < 2 || !u) {
5581 imm = (0xffu >> (8 - shift));
5583 } else if (size == 1) {
5584 imm = 0xffff >> (16 - shift);
5587 imm = 0xffffffff >> (32 - shift);
5590 imm64 = imm | (((uint64_t)imm) << 32);
5594 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5597 neon_store_reg64(cpu_V0, rd + pass);
5599 } else if (op >= 14) {
5600 /* VCVT fixed-point. */
5601 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5604 /* We have already masked out the must-be-1 top bit of imm6,
5605 * hence this 32-shift where the ARM ARM has 64-imm6.
5608 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5609 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5612 gen_vfp_ulto(0, shift, 1);
5614 gen_vfp_slto(0, shift, 1);
5617 gen_vfp_toul(0, shift, 1);
5619 gen_vfp_tosl(0, shift, 1);
5621 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5626 } else { /* (insn & 0x00380080) == 0 */
5628 if (q && (rd & 1)) {
5632 op = (insn >> 8) & 0xf;
5633 /* One register and immediate. */
5634 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5635 invert = (insn & (1 << 5)) != 0;
5636 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5637 * We choose to not special-case this and will behave as if a
5638 * valid constant encoding of 0 had been given.
5657 imm = (imm << 8) | (imm << 24);
5660 imm = (imm << 8) | 0xff;
5663 imm = (imm << 16) | 0xffff;
5666 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5674 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5675 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5681 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5682 if (op & 1 && op < 12) {
5683 tmp = neon_load_reg(rd, pass);
5685 /* The immediate value has already been inverted, so
5687 tcg_gen_andi_i32(tmp, tmp, imm);
5689 tcg_gen_ori_i32(tmp, tmp, imm);
5693 tmp = tcg_temp_new_i32();
5694 if (op == 14 && invert) {
5698 for (n = 0; n < 4; n++) {
5699 if (imm & (1 << (n + (pass & 1) * 4)))
5700 val |= 0xff << (n * 8);
5702 tcg_gen_movi_i32(tmp, val);
5704 tcg_gen_movi_i32(tmp, imm);
5707 neon_store_reg(rd, pass, tmp);
5710 } else { /* (insn & 0x00800010 == 0x00800000) */
5712 op = (insn >> 8) & 0xf;
5713 if ((insn & (1 << 6)) == 0) {
5714 /* Three registers of different lengths. */
5718 /* undefreq: bit 0 : UNDEF if size != 0
5719 * bit 1 : UNDEF if size == 0
5720 * bit 2 : UNDEF if U == 1
5721 * Note that [1:0] set implies 'always UNDEF'
5724 /* prewiden, src1_wide, src2_wide, undefreq */
5725 static const int neon_3reg_wide[16][4] = {
5726 {1, 0, 0, 0}, /* VADDL */
5727 {1, 1, 0, 0}, /* VADDW */
5728 {1, 0, 0, 0}, /* VSUBL */
5729 {1, 1, 0, 0}, /* VSUBW */
5730 {0, 1, 1, 0}, /* VADDHN */
5731 {0, 0, 0, 0}, /* VABAL */
5732 {0, 1, 1, 0}, /* VSUBHN */
5733 {0, 0, 0, 0}, /* VABDL */
5734 {0, 0, 0, 0}, /* VMLAL */
5735 {0, 0, 0, 6}, /* VQDMLAL */
5736 {0, 0, 0, 0}, /* VMLSL */
5737 {0, 0, 0, 6}, /* VQDMLSL */
5738 {0, 0, 0, 0}, /* Integer VMULL */
5739 {0, 0, 0, 2}, /* VQDMULL */
5740 {0, 0, 0, 5}, /* Polynomial VMULL */
5741 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5744 prewiden = neon_3reg_wide[op][0];
5745 src1_wide = neon_3reg_wide[op][1];
5746 src2_wide = neon_3reg_wide[op][2];
5747 undefreq = neon_3reg_wide[op][3];
5749 if (((undefreq & 1) && (size != 0)) ||
5750 ((undefreq & 2) && (size == 0)) ||
5751 ((undefreq & 4) && u)) {
5754 if ((src1_wide && (rn & 1)) ||
5755 (src2_wide && (rm & 1)) ||
5756 (!src2_wide && (rd & 1))) {
5760 /* Avoid overlapping operands. Wide source operands are
5761 always aligned so will never overlap with wide
5762 destinations in problematic ways. */
5763 if (rd == rm && !src2_wide) {
5764 tmp = neon_load_reg(rm, 1);
5765 neon_store_scratch(2, tmp);
5766 } else if (rd == rn && !src1_wide) {
5767 tmp = neon_load_reg(rn, 1);
5768 neon_store_scratch(2, tmp);
5770 TCGV_UNUSED_I32(tmp3);
5771 for (pass = 0; pass < 2; pass++) {
5773 neon_load_reg64(cpu_V0, rn + pass);
5774 TCGV_UNUSED_I32(tmp);
5776 if (pass == 1 && rd == rn) {
5777 tmp = neon_load_scratch(2);
5779 tmp = neon_load_reg(rn, pass);
5782 gen_neon_widen(cpu_V0, tmp, size, u);
5786 neon_load_reg64(cpu_V1, rm + pass);
5787 TCGV_UNUSED_I32(tmp2);
5789 if (pass == 1 && rd == rm) {
5790 tmp2 = neon_load_scratch(2);
5792 tmp2 = neon_load_reg(rm, pass);
5795 gen_neon_widen(cpu_V1, tmp2, size, u);
5799 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5800 gen_neon_addl(size);
5802 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5803 gen_neon_subl(size);
5805 case 5: case 7: /* VABAL, VABDL */
5806 switch ((size << 1) | u) {
5808 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5811 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5814 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5817 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5820 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5823 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5827 tcg_temp_free_i32(tmp2);
5828 tcg_temp_free_i32(tmp);
5830 case 8: case 9: case 10: case 11: case 12: case 13:
5831 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5832 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5834 case 14: /* Polynomial VMULL */
5835 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5836 tcg_temp_free_i32(tmp2);
5837 tcg_temp_free_i32(tmp);
5839 default: /* 15 is RESERVED: caught earlier */
5844 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5845 neon_store_reg64(cpu_V0, rd + pass);
5846 } else if (op == 5 || (op >= 8 && op <= 11)) {
5848 neon_load_reg64(cpu_V1, rd + pass);
5850 case 10: /* VMLSL */
5851 gen_neon_negl(cpu_V0, size);
5853 case 5: case 8: /* VABAL, VMLAL */
5854 gen_neon_addl(size);
5856 case 9: case 11: /* VQDMLAL, VQDMLSL */
5857 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5859 gen_neon_negl(cpu_V0, size);
5861 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5866 neon_store_reg64(cpu_V0, rd + pass);
5867 } else if (op == 4 || op == 6) {
5868 /* Narrowing operation. */
5869 tmp = tcg_temp_new_i32();
5873 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5876 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5879 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5880 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5887 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5890 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5893 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5894 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5895 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5903 neon_store_reg(rd, 0, tmp3);
5904 neon_store_reg(rd, 1, tmp);
5907 /* Write back the result. */
5908 neon_store_reg64(cpu_V0, rd + pass);
5912 /* Two registers and a scalar. NB that for ops of this form
5913 * the ARM ARM labels bit 24 as Q, but it is in our variable
5920 case 1: /* Float VMLA scalar */
5921 case 5: /* Floating point VMLS scalar */
5922 case 9: /* Floating point VMUL scalar */
5927 case 0: /* Integer VMLA scalar */
5928 case 4: /* Integer VMLS scalar */
5929 case 8: /* Integer VMUL scalar */
5930 case 12: /* VQDMULH scalar */
5931 case 13: /* VQRDMULH scalar */
5932 if (u && ((rd | rn) & 1)) {
5935 tmp = neon_get_scalar(size, rm);
5936 neon_store_scratch(0, tmp);
5937 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5938 tmp = neon_load_scratch(0);
5939 tmp2 = neon_load_reg(rn, pass);
5942 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5944 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5946 } else if (op == 13) {
5948 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5950 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5952 } else if (op & 1) {
5953 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5954 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5955 tcg_temp_free_ptr(fpstatus);
5958 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5959 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5960 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5964 tcg_temp_free_i32(tmp2);
5967 tmp2 = neon_load_reg(rd, pass);
5970 gen_neon_add(size, tmp, tmp2);
5974 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5975 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5976 tcg_temp_free_ptr(fpstatus);
5980 gen_neon_rsb(size, tmp, tmp2);
5984 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5985 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5986 tcg_temp_free_ptr(fpstatus);
5992 tcg_temp_free_i32(tmp2);
5994 neon_store_reg(rd, pass, tmp);
5997 case 3: /* VQDMLAL scalar */
5998 case 7: /* VQDMLSL scalar */
5999 case 11: /* VQDMULL scalar */
6004 case 2: /* VMLAL sclar */
6005 case 6: /* VMLSL scalar */
6006 case 10: /* VMULL scalar */
6010 tmp2 = neon_get_scalar(size, rm);
6011 /* We need a copy of tmp2 because gen_neon_mull
6012 * deletes it during pass 0. */
6013 tmp4 = tcg_temp_new_i32();
6014 tcg_gen_mov_i32(tmp4, tmp2);
6015 tmp3 = neon_load_reg(rn, 1);
6017 for (pass = 0; pass < 2; pass++) {
6019 tmp = neon_load_reg(rn, 0);
6024 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6026 neon_load_reg64(cpu_V1, rd + pass);
6030 gen_neon_negl(cpu_V0, size);
6033 gen_neon_addl(size);
6036 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6038 gen_neon_negl(cpu_V0, size);
6040 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6046 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6051 neon_store_reg64(cpu_V0, rd + pass);
6056 default: /* 14 and 15 are RESERVED */
6060 } else { /* size == 3 */
6063 imm = (insn >> 8) & 0xf;
6068 if (q && ((rd | rn | rm) & 1)) {
6073 neon_load_reg64(cpu_V0, rn);
6075 neon_load_reg64(cpu_V1, rn + 1);
6077 } else if (imm == 8) {
6078 neon_load_reg64(cpu_V0, rn + 1);
6080 neon_load_reg64(cpu_V1, rm);
6083 tmp64 = tcg_temp_new_i64();
6085 neon_load_reg64(cpu_V0, rn);
6086 neon_load_reg64(tmp64, rn + 1);
6088 neon_load_reg64(cpu_V0, rn + 1);
6089 neon_load_reg64(tmp64, rm);
6091 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6092 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6093 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6095 neon_load_reg64(cpu_V1, rm);
6097 neon_load_reg64(cpu_V1, rm + 1);
6100 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6101 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6102 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6103 tcg_temp_free_i64(tmp64);
6106 neon_load_reg64(cpu_V0, rn);
6107 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6108 neon_load_reg64(cpu_V1, rm);
6109 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6110 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6112 neon_store_reg64(cpu_V0, rd);
6114 neon_store_reg64(cpu_V1, rd + 1);
6116 } else if ((insn & (1 << 11)) == 0) {
6117 /* Two register misc. */
6118 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6119 size = (insn >> 18) & 3;
6120 /* UNDEF for unknown op values and bad op-size combinations */
6121 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6124 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6125 q && ((rm | rd) & 1)) {
6129 case NEON_2RM_VREV64:
6130 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6131 tmp = neon_load_reg(rm, pass * 2);
6132 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6134 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6135 case 1: gen_swap_half(tmp); break;
6136 case 2: /* no-op */ break;
6139 neon_store_reg(rd, pass * 2 + 1, tmp);
6141 neon_store_reg(rd, pass * 2, tmp2);
6144 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6145 case 1: gen_swap_half(tmp2); break;
6148 neon_store_reg(rd, pass * 2, tmp2);
6152 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6153 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6154 for (pass = 0; pass < q + 1; pass++) {
6155 tmp = neon_load_reg(rm, pass * 2);
6156 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6157 tmp = neon_load_reg(rm, pass * 2 + 1);
6158 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6160 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6161 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6162 case 2: tcg_gen_add_i64(CPU_V001); break;
6165 if (op >= NEON_2RM_VPADAL) {
6167 neon_load_reg64(cpu_V1, rd + pass);
6168 gen_neon_addl(size);
6170 neon_store_reg64(cpu_V0, rd + pass);
6176 for (n = 0; n < (q ? 4 : 2); n += 2) {
6177 tmp = neon_load_reg(rm, n);
6178 tmp2 = neon_load_reg(rd, n + 1);
6179 neon_store_reg(rm, n, tmp2);
6180 neon_store_reg(rd, n + 1, tmp);
6187 if (gen_neon_unzip(rd, rm, size, q)) {
6192 if (gen_neon_zip(rd, rm, size, q)) {
6196 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6197 /* also VQMOVUN; op field and mnemonics don't line up */
6201 TCGV_UNUSED_I32(tmp2);
6202 for (pass = 0; pass < 2; pass++) {
6203 neon_load_reg64(cpu_V0, rm + pass);
6204 tmp = tcg_temp_new_i32();
6205 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6210 neon_store_reg(rd, 0, tmp2);
6211 neon_store_reg(rd, 1, tmp);
6215 case NEON_2RM_VSHLL:
6216 if (q || (rd & 1)) {
6219 tmp = neon_load_reg(rm, 0);
6220 tmp2 = neon_load_reg(rm, 1);
6221 for (pass = 0; pass < 2; pass++) {
6224 gen_neon_widen(cpu_V0, tmp, size, 1);
6225 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6226 neon_store_reg64(cpu_V0, rd + pass);
6229 case NEON_2RM_VCVT_F16_F32:
6230 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6234 tmp = tcg_temp_new_i32();
6235 tmp2 = tcg_temp_new_i32();
6236 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6237 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6238 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6239 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6240 tcg_gen_shli_i32(tmp2, tmp2, 16);
6241 tcg_gen_or_i32(tmp2, tmp2, tmp);
6242 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6243 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6244 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6245 neon_store_reg(rd, 0, tmp2);
6246 tmp2 = tcg_temp_new_i32();
6247 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6248 tcg_gen_shli_i32(tmp2, tmp2, 16);
6249 tcg_gen_or_i32(tmp2, tmp2, tmp);
6250 neon_store_reg(rd, 1, tmp2);
6251 tcg_temp_free_i32(tmp);
6253 case NEON_2RM_VCVT_F32_F16:
6254 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6258 tmp3 = tcg_temp_new_i32();
6259 tmp = neon_load_reg(rm, 0);
6260 tmp2 = neon_load_reg(rm, 1);
6261 tcg_gen_ext16u_i32(tmp3, tmp);
6262 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6263 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6264 tcg_gen_shri_i32(tmp3, tmp, 16);
6265 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6266 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6267 tcg_temp_free_i32(tmp);
6268 tcg_gen_ext16u_i32(tmp3, tmp2);
6269 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6270 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6271 tcg_gen_shri_i32(tmp3, tmp2, 16);
6272 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6273 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6274 tcg_temp_free_i32(tmp2);
6275 tcg_temp_free_i32(tmp3);
6277 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6278 if (!arm_feature(env, ARM_FEATURE_V8_AES)
6279 || ((rm | rd) & 1)) {
6282 tmp = tcg_const_i32(rd);
6283 tmp2 = tcg_const_i32(rm);
6285 /* Bit 6 is the lowest opcode bit; it distinguishes between
6286 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6288 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6290 if (op == NEON_2RM_AESE) {
6291 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6293 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6295 tcg_temp_free_i32(tmp);
6296 tcg_temp_free_i32(tmp2);
6297 tcg_temp_free_i32(tmp3);
6301 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6302 if (neon_2rm_is_float_op(op)) {
6303 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6304 neon_reg_offset(rm, pass));
6305 TCGV_UNUSED_I32(tmp);
6307 tmp = neon_load_reg(rm, pass);
6310 case NEON_2RM_VREV32:
6312 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6313 case 1: gen_swap_half(tmp); break;
6317 case NEON_2RM_VREV16:
6322 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6323 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6324 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6330 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6331 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6332 case 2: gen_helper_clz(tmp, tmp); break;
6337 gen_helper_neon_cnt_u8(tmp, tmp);
6340 tcg_gen_not_i32(tmp, tmp);
6342 case NEON_2RM_VQABS:
6345 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6348 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6351 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6356 case NEON_2RM_VQNEG:
6359 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6362 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6365 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6370 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6371 tmp2 = tcg_const_i32(0);
6373 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6374 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6375 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6378 tcg_temp_free_i32(tmp2);
6379 if (op == NEON_2RM_VCLE0) {
6380 tcg_gen_not_i32(tmp, tmp);
6383 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6384 tmp2 = tcg_const_i32(0);
6386 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6387 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6388 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6391 tcg_temp_free_i32(tmp2);
6392 if (op == NEON_2RM_VCLT0) {
6393 tcg_gen_not_i32(tmp, tmp);
6396 case NEON_2RM_VCEQ0:
6397 tmp2 = tcg_const_i32(0);
6399 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6400 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6401 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6404 tcg_temp_free_i32(tmp2);
6408 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6409 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6410 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6415 tmp2 = tcg_const_i32(0);
6416 gen_neon_rsb(size, tmp, tmp2);
6417 tcg_temp_free_i32(tmp2);
6419 case NEON_2RM_VCGT0_F:
6421 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6422 tmp2 = tcg_const_i32(0);
6423 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6424 tcg_temp_free_i32(tmp2);
6425 tcg_temp_free_ptr(fpstatus);
6428 case NEON_2RM_VCGE0_F:
6430 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6431 tmp2 = tcg_const_i32(0);
6432 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6433 tcg_temp_free_i32(tmp2);
6434 tcg_temp_free_ptr(fpstatus);
6437 case NEON_2RM_VCEQ0_F:
6439 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6440 tmp2 = tcg_const_i32(0);
6441 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6442 tcg_temp_free_i32(tmp2);
6443 tcg_temp_free_ptr(fpstatus);
6446 case NEON_2RM_VCLE0_F:
6448 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6449 tmp2 = tcg_const_i32(0);
6450 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6451 tcg_temp_free_i32(tmp2);
6452 tcg_temp_free_ptr(fpstatus);
6455 case NEON_2RM_VCLT0_F:
6457 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6458 tmp2 = tcg_const_i32(0);
6459 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6460 tcg_temp_free_i32(tmp2);
6461 tcg_temp_free_ptr(fpstatus);
6464 case NEON_2RM_VABS_F:
6467 case NEON_2RM_VNEG_F:
6471 tmp2 = neon_load_reg(rd, pass);
6472 neon_store_reg(rm, pass, tmp2);
6475 tmp2 = neon_load_reg(rd, pass);
6477 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6478 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6481 neon_store_reg(rm, pass, tmp2);
6483 case NEON_2RM_VRECPE:
6484 gen_helper_recpe_u32(tmp, tmp, cpu_env);
6486 case NEON_2RM_VRSQRTE:
6487 gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6489 case NEON_2RM_VRECPE_F:
6490 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6492 case NEON_2RM_VRSQRTE_F:
6493 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6495 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6498 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6501 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6502 gen_vfp_tosiz(0, 1);
6504 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6505 gen_vfp_touiz(0, 1);
6508 /* Reserved op values were caught by the
6509 * neon_2rm_sizes[] check earlier.
6513 if (neon_2rm_is_float_op(op)) {
6514 tcg_gen_st_f32(cpu_F0s, cpu_env,
6515 neon_reg_offset(rd, pass));
6517 neon_store_reg(rd, pass, tmp);
6522 } else if ((insn & (1 << 10)) == 0) {
6524 int n = ((insn >> 8) & 3) + 1;
6525 if ((rn + n) > 32) {
6526 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6527 * helper function running off the end of the register file.
6532 if (insn & (1 << 6)) {
6533 tmp = neon_load_reg(rd, 0);
6535 tmp = tcg_temp_new_i32();
6536 tcg_gen_movi_i32(tmp, 0);
6538 tmp2 = neon_load_reg(rm, 0);
6539 tmp4 = tcg_const_i32(rn);
6540 tmp5 = tcg_const_i32(n);
6541 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6542 tcg_temp_free_i32(tmp);
6543 if (insn & (1 << 6)) {
6544 tmp = neon_load_reg(rd, 1);
6546 tmp = tcg_temp_new_i32();
6547 tcg_gen_movi_i32(tmp, 0);
6549 tmp3 = neon_load_reg(rm, 1);
6550 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6551 tcg_temp_free_i32(tmp5);
6552 tcg_temp_free_i32(tmp4);
6553 neon_store_reg(rd, 0, tmp2);
6554 neon_store_reg(rd, 1, tmp3);
6555 tcg_temp_free_i32(tmp);
6556 } else if ((insn & 0x380) == 0) {
6558 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6561 if (insn & (1 << 19)) {
6562 tmp = neon_load_reg(rm, 1);
6564 tmp = neon_load_reg(rm, 0);
6566 if (insn & (1 << 16)) {
6567 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6568 } else if (insn & (1 << 17)) {
6569 if ((insn >> 18) & 1)
6570 gen_neon_dup_high16(tmp);
6572 gen_neon_dup_low16(tmp);
6574 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6575 tmp2 = tcg_temp_new_i32();
6576 tcg_gen_mov_i32(tmp2, tmp);
6577 neon_store_reg(rd, pass, tmp2);
6579 tcg_temp_free_i32(tmp);
6588 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6590 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6591 const ARMCPRegInfo *ri;
6593 cpnum = (insn >> 8) & 0xf;
6594 if (arm_feature(env, ARM_FEATURE_XSCALE)
6595 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6598 /* First check for coprocessor space used for actual instructions */
6602 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6603 return disas_iwmmxt_insn(env, s, insn);
6604 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6605 return disas_dsp_insn(env, s, insn);
6612 /* Otherwise treat as a generic register access */
6613 is64 = (insn & (1 << 25)) == 0;
6614 if (!is64 && ((insn & (1 << 4)) == 0)) {
6622 opc1 = (insn >> 4) & 0xf;
6624 rt2 = (insn >> 16) & 0xf;
6626 crn = (insn >> 16) & 0xf;
6627 opc1 = (insn >> 21) & 7;
6628 opc2 = (insn >> 5) & 7;
6631 isread = (insn >> 20) & 1;
6632 rt = (insn >> 12) & 0xf;
6634 ri = get_arm_cp_reginfo(s->cp_regs,
6635 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6637 /* Check access permissions */
6638 if (!cp_access_ok(s->current_pl, ri, isread)) {
6642 /* Handle special cases first */
6643 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6650 gen_set_pc_im(s, s->pc);
6651 s->is_jmp = DISAS_WFI;
6657 if (use_icount && (ri->type & ARM_CP_IO)) {
6666 if (ri->type & ARM_CP_CONST) {
6667 tmp64 = tcg_const_i64(ri->resetvalue);
6668 } else if (ri->readfn) {
6670 gen_set_pc_im(s, s->pc);
6671 tmp64 = tcg_temp_new_i64();
6672 tmpptr = tcg_const_ptr(ri);
6673 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6674 tcg_temp_free_ptr(tmpptr);
6676 tmp64 = tcg_temp_new_i64();
6677 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6679 tmp = tcg_temp_new_i32();
6680 tcg_gen_trunc_i64_i32(tmp, tmp64);
6681 store_reg(s, rt, tmp);
6682 tcg_gen_shri_i64(tmp64, tmp64, 32);
6683 tmp = tcg_temp_new_i32();
6684 tcg_gen_trunc_i64_i32(tmp, tmp64);
6685 tcg_temp_free_i64(tmp64);
6686 store_reg(s, rt2, tmp);
6689 if (ri->type & ARM_CP_CONST) {
6690 tmp = tcg_const_i32(ri->resetvalue);
6691 } else if (ri->readfn) {
6693 gen_set_pc_im(s, s->pc);
6694 tmp = tcg_temp_new_i32();
6695 tmpptr = tcg_const_ptr(ri);
6696 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6697 tcg_temp_free_ptr(tmpptr);
6699 tmp = load_cpu_offset(ri->fieldoffset);
6702 /* Destination register of r15 for 32 bit loads sets
6703 * the condition codes from the high 4 bits of the value
6706 tcg_temp_free_i32(tmp);
6708 store_reg(s, rt, tmp);
6713 if (ri->type & ARM_CP_CONST) {
6714 /* If not forbidden by access permissions, treat as WI */
6719 TCGv_i32 tmplo, tmphi;
6720 TCGv_i64 tmp64 = tcg_temp_new_i64();
6721 tmplo = load_reg(s, rt);
6722 tmphi = load_reg(s, rt2);
6723 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6724 tcg_temp_free_i32(tmplo);
6725 tcg_temp_free_i32(tmphi);
6727 TCGv_ptr tmpptr = tcg_const_ptr(ri);
6728 gen_set_pc_im(s, s->pc);
6729 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6730 tcg_temp_free_ptr(tmpptr);
6732 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6734 tcg_temp_free_i64(tmp64);
6739 gen_set_pc_im(s, s->pc);
6740 tmp = load_reg(s, rt);
6741 tmpptr = tcg_const_ptr(ri);
6742 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6743 tcg_temp_free_ptr(tmpptr);
6744 tcg_temp_free_i32(tmp);
6746 TCGv_i32 tmp = load_reg(s, rt);
6747 store_cpu_offset(tmp, ri->fieldoffset);
6752 if (use_icount && (ri->type & ARM_CP_IO)) {
6753 /* I/O operations must end the TB here (whether read or write) */
6756 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6757 /* We default to ending the TB on a coprocessor register write,
6758 * but allow this to be suppressed by the register definition
6759 * (usually only necessary to work around guest bugs).
6771 /* Store a 64-bit value to a register pair. Clobbers val. */
6772 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6775 tmp = tcg_temp_new_i32();
6776 tcg_gen_trunc_i64_i32(tmp, val);
6777 store_reg(s, rlow, tmp);
6778 tmp = tcg_temp_new_i32();
6779 tcg_gen_shri_i64(val, val, 32);
6780 tcg_gen_trunc_i64_i32(tmp, val);
6781 store_reg(s, rhigh, tmp);
6784 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6785 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6790 /* Load value and extend to 64 bits. */
6791 tmp = tcg_temp_new_i64();
6792 tmp2 = load_reg(s, rlow);
6793 tcg_gen_extu_i32_i64(tmp, tmp2);
6794 tcg_temp_free_i32(tmp2);
6795 tcg_gen_add_i64(val, val, tmp);
6796 tcg_temp_free_i64(tmp);
6799 /* load and add a 64-bit value from a register pair. */
6800 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6806 /* Load 64-bit value rd:rn. */
6807 tmpl = load_reg(s, rlow);
6808 tmph = load_reg(s, rhigh);
6809 tmp = tcg_temp_new_i64();
6810 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6811 tcg_temp_free_i32(tmpl);
6812 tcg_temp_free_i32(tmph);
6813 tcg_gen_add_i64(val, val, tmp);
6814 tcg_temp_free_i64(tmp);
6817 /* Set N and Z flags from hi|lo. */
6818 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6820 tcg_gen_mov_i32(cpu_NF, hi);
6821 tcg_gen_or_i32(cpu_ZF, lo, hi);
6824 /* Load/Store exclusive instructions are implemented by remembering
6825 the value/address loaded, and seeing if these are the same
6826 when the store is performed. This should be sufficient to implement
6827 the architecturally mandated semantics, and avoids having to monitor
6830 In system emulation mode only one CPU will be running at once, so
6831 this sequence is effectively atomic. In user emulation mode we
6832 throw an exception and handle the atomic operation elsewhere. */
6833 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6834 TCGv_i32 addr, int size)
6836 TCGv_i32 tmp = tcg_temp_new_i32();
6840 gen_aa32_ld8u(tmp, addr, IS_USER(s));
6843 gen_aa32_ld16u(tmp, addr, IS_USER(s));
6847 gen_aa32_ld32u(tmp, addr, IS_USER(s));
6854 TCGv_i32 tmp2 = tcg_temp_new_i32();
6855 TCGv_i32 tmp3 = tcg_temp_new_i32();
6857 tcg_gen_addi_i32(tmp2, addr, 4);
6858 gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
6859 tcg_temp_free_i32(tmp2);
6860 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
6861 store_reg(s, rt2, tmp3);
6863 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
6866 store_reg(s, rt, tmp);
6867 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
6870 static void gen_clrex(DisasContext *s)
6872 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6875 #ifdef CONFIG_USER_ONLY
6876 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6877 TCGv_i32 addr, int size)
6879 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
6880 tcg_gen_movi_i32(cpu_exclusive_info,
6881 size | (rd << 4) | (rt << 8) | (rt2 << 12));
6882 gen_exception_insn(s, 4, EXCP_STREX);
6885 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6886 TCGv_i32 addr, int size)
6889 TCGv_i64 val64, extaddr;
6893 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6899 fail_label = gen_new_label();
6900 done_label = gen_new_label();
6901 extaddr = tcg_temp_new_i64();
6902 tcg_gen_extu_i32_i64(extaddr, addr);
6903 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
6904 tcg_temp_free_i64(extaddr);
6906 tmp = tcg_temp_new_i32();
6909 gen_aa32_ld8u(tmp, addr, IS_USER(s));
6912 gen_aa32_ld16u(tmp, addr, IS_USER(s));
6916 gen_aa32_ld32u(tmp, addr, IS_USER(s));
6922 val64 = tcg_temp_new_i64();
6924 TCGv_i32 tmp2 = tcg_temp_new_i32();
6925 TCGv_i32 tmp3 = tcg_temp_new_i32();
6926 tcg_gen_addi_i32(tmp2, addr, 4);
6927 gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
6928 tcg_temp_free_i32(tmp2);
6929 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
6930 tcg_temp_free_i32(tmp3);
6932 tcg_gen_extu_i32_i64(val64, tmp);
6934 tcg_temp_free_i32(tmp);
6936 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
6937 tcg_temp_free_i64(val64);
6939 tmp = load_reg(s, rt);
6942 gen_aa32_st8(tmp, addr, IS_USER(s));
6945 gen_aa32_st16(tmp, addr, IS_USER(s));
6949 gen_aa32_st32(tmp, addr, IS_USER(s));
6954 tcg_temp_free_i32(tmp);
6956 tcg_gen_addi_i32(addr, addr, 4);
6957 tmp = load_reg(s, rt2);
6958 gen_aa32_st32(tmp, addr, IS_USER(s));
6959 tcg_temp_free_i32(tmp);
6961 tcg_gen_movi_i32(cpu_R[rd], 0);
6962 tcg_gen_br(done_label);
6963 gen_set_label(fail_label);
6964 tcg_gen_movi_i32(cpu_R[rd], 1);
6965 gen_set_label(done_label);
6966 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6973 * @mode: mode field from insn (which stack to store to)
6974 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6975 * @writeback: true if writeback bit set
6977 * Generate code for the SRS (Store Return State) insn.
6979 static void gen_srs(DisasContext *s,
6980 uint32_t mode, uint32_t amode, bool writeback)
6983 TCGv_i32 addr = tcg_temp_new_i32();
6984 TCGv_i32 tmp = tcg_const_i32(mode);
6985 gen_helper_get_r13_banked(addr, cpu_env, tmp);
6986 tcg_temp_free_i32(tmp);
7003 tcg_gen_addi_i32(addr, addr, offset);
7004 tmp = load_reg(s, 14);
7005 gen_aa32_st32(tmp, addr, 0);
7006 tcg_temp_free_i32(tmp);
7007 tmp = load_cpu_field(spsr);
7008 tcg_gen_addi_i32(addr, addr, 4);
7009 gen_aa32_st32(tmp, addr, 0);
7010 tcg_temp_free_i32(tmp);
7028 tcg_gen_addi_i32(addr, addr, offset);
7029 tmp = tcg_const_i32(mode);
7030 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7031 tcg_temp_free_i32(tmp);
7033 tcg_temp_free_i32(addr);
7036 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
7038 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
7045 insn = arm_ldl_code(env, s->pc, s->bswap_code);
7048 /* M variants do not implement ARM mode. */
7053 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7054 * choose to UNDEF. In ARMv5 and above the space is used
7055 * for miscellaneous unconditional instructions.
7059 /* Unconditional instructions. */
7060 if (((insn >> 25) & 7) == 1) {
7061 /* NEON Data processing. */
7062 if (!arm_feature(env, ARM_FEATURE_NEON))
7065 if (disas_neon_data_insn(env, s, insn))
7069 if ((insn & 0x0f100000) == 0x04000000) {
7070 /* NEON load/store. */
7071 if (!arm_feature(env, ARM_FEATURE_NEON))
7074 if (disas_neon_ls_insn(env, s, insn))
7078 if ((insn & 0x0f000e10) == 0x0e000a00) {
7080 if (disas_vfp_insn(env, s, insn)) {
7085 if (((insn & 0x0f30f000) == 0x0510f000) ||
7086 ((insn & 0x0f30f010) == 0x0710f000)) {
7087 if ((insn & (1 << 22)) == 0) {
7089 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7093 /* Otherwise PLD; v5TE+ */
7097 if (((insn & 0x0f70f000) == 0x0450f000) ||
7098 ((insn & 0x0f70f010) == 0x0650f000)) {
7100 return; /* PLI; V7 */
7102 if (((insn & 0x0f700000) == 0x04100000) ||
7103 ((insn & 0x0f700010) == 0x06100000)) {
7104 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7107 return; /* v7MP: Unallocated memory hint: must NOP */
7110 if ((insn & 0x0ffffdff) == 0x01010000) {
7113 if (((insn >> 9) & 1) != s->bswap_code) {
7114 /* Dynamic endianness switching not implemented. */
7115 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7119 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7120 switch ((insn >> 4) & 0xf) {
7129 /* We don't emulate caches so these are a no-op. */
7134 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7140 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7142 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7148 rn = (insn >> 16) & 0xf;
7149 addr = load_reg(s, rn);
7150 i = (insn >> 23) & 3;
7152 case 0: offset = -4; break; /* DA */
7153 case 1: offset = 0; break; /* IA */
7154 case 2: offset = -8; break; /* DB */
7155 case 3: offset = 4; break; /* IB */
7159 tcg_gen_addi_i32(addr, addr, offset);
7160 /* Load PC into tmp and CPSR into tmp2. */
7161 tmp = tcg_temp_new_i32();
7162 gen_aa32_ld32u(tmp, addr, 0);
7163 tcg_gen_addi_i32(addr, addr, 4);
7164 tmp2 = tcg_temp_new_i32();
7165 gen_aa32_ld32u(tmp2, addr, 0);
7166 if (insn & (1 << 21)) {
7167 /* Base writeback. */
7169 case 0: offset = -8; break;
7170 case 1: offset = 4; break;
7171 case 2: offset = -4; break;
7172 case 3: offset = 0; break;
7176 tcg_gen_addi_i32(addr, addr, offset);
7177 store_reg(s, rn, addr);
7179 tcg_temp_free_i32(addr);
7181 gen_rfe(s, tmp, tmp2);
7183 } else if ((insn & 0x0e000000) == 0x0a000000) {
7184 /* branch link and change to thumb (blx <offset>) */
7187 val = (uint32_t)s->pc;
7188 tmp = tcg_temp_new_i32();
7189 tcg_gen_movi_i32(tmp, val);
7190 store_reg(s, 14, tmp);
7191 /* Sign-extend the 24-bit offset */
7192 offset = (((int32_t)insn) << 8) >> 8;
7193 /* offset * 4 + bit24 * 2 + (thumb bit) */
7194 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7195 /* pipeline offset */
7197 /* protected by ARCH(5); above, near the start of uncond block */
7200 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7201 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7202 /* iWMMXt register transfer. */
7203 if (env->cp15.c15_cpar & (1 << 1))
7204 if (!disas_iwmmxt_insn(env, s, insn))
7207 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7208 /* Coprocessor double register transfer. */
7210 } else if ((insn & 0x0f000010) == 0x0e000010) {
7211 /* Additional coprocessor register transfer. */
7212 } else if ((insn & 0x0ff10020) == 0x01000000) {
7215 /* cps (privileged) */
7219 if (insn & (1 << 19)) {
7220 if (insn & (1 << 8))
7222 if (insn & (1 << 7))
7224 if (insn & (1 << 6))
7226 if (insn & (1 << 18))
7229 if (insn & (1 << 17)) {
7231 val |= (insn & 0x1f);
7234 gen_set_psr_im(s, mask, 0, val);
7241 /* if not always execute, we generate a conditional jump to
7243 s->condlabel = gen_new_label();
7244 arm_gen_test_cc(cond ^ 1, s->condlabel);
7247 if ((insn & 0x0f900000) == 0x03000000) {
7248 if ((insn & (1 << 21)) == 0) {
7250 rd = (insn >> 12) & 0xf;
7251 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7252 if ((insn & (1 << 22)) == 0) {
7254 tmp = tcg_temp_new_i32();
7255 tcg_gen_movi_i32(tmp, val);
7258 tmp = load_reg(s, rd);
7259 tcg_gen_ext16u_i32(tmp, tmp);
7260 tcg_gen_ori_i32(tmp, tmp, val << 16);
7262 store_reg(s, rd, tmp);
7264 if (((insn >> 12) & 0xf) != 0xf)
7266 if (((insn >> 16) & 0xf) == 0) {
7267 gen_nop_hint(s, insn & 0xff);
7269 /* CPSR = immediate */
7271 shift = ((insn >> 8) & 0xf) * 2;
7273 val = (val >> shift) | (val << (32 - shift));
7274 i = ((insn & (1 << 22)) != 0);
7275 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7279 } else if ((insn & 0x0f900000) == 0x01000000
7280 && (insn & 0x00000090) != 0x00000090) {
7281 /* miscellaneous instructions */
7282 op1 = (insn >> 21) & 3;
7283 sh = (insn >> 4) & 0xf;
7286 case 0x0: /* move program status register */
7289 tmp = load_reg(s, rm);
7290 i = ((op1 & 2) != 0);
7291 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7295 rd = (insn >> 12) & 0xf;
7299 tmp = load_cpu_field(spsr);
7301 tmp = tcg_temp_new_i32();
7302 gen_helper_cpsr_read(tmp, cpu_env);
7304 store_reg(s, rd, tmp);
7309 /* branch/exchange thumb (bx). */
7311 tmp = load_reg(s, rm);
7313 } else if (op1 == 3) {
7316 rd = (insn >> 12) & 0xf;
7317 tmp = load_reg(s, rm);
7318 gen_helper_clz(tmp, tmp);
7319 store_reg(s, rd, tmp);
7327 /* Trivial implementation equivalent to bx. */
7328 tmp = load_reg(s, rm);
7339 /* branch link/exchange thumb (blx) */
7340 tmp = load_reg(s, rm);
7341 tmp2 = tcg_temp_new_i32();
7342 tcg_gen_movi_i32(tmp2, s->pc);
7343 store_reg(s, 14, tmp2);
7346 case 0x5: /* saturating add/subtract */
7348 rd = (insn >> 12) & 0xf;
7349 rn = (insn >> 16) & 0xf;
7350 tmp = load_reg(s, rm);
7351 tmp2 = load_reg(s, rn);
7353 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7355 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7357 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7358 tcg_temp_free_i32(tmp2);
7359 store_reg(s, rd, tmp);
7362 /* SMC instruction (op1 == 3)
7363 and undefined instructions (op1 == 0 || op1 == 2)
7370 gen_exception_insn(s, 4, EXCP_BKPT);
7372 case 0x8: /* signed multiply */
7377 rs = (insn >> 8) & 0xf;
7378 rn = (insn >> 12) & 0xf;
7379 rd = (insn >> 16) & 0xf;
7381 /* (32 * 16) >> 16 */
7382 tmp = load_reg(s, rm);
7383 tmp2 = load_reg(s, rs);
7385 tcg_gen_sari_i32(tmp2, tmp2, 16);
7388 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7389 tcg_gen_shri_i64(tmp64, tmp64, 16);
7390 tmp = tcg_temp_new_i32();
7391 tcg_gen_trunc_i64_i32(tmp, tmp64);
7392 tcg_temp_free_i64(tmp64);
7393 if ((sh & 2) == 0) {
7394 tmp2 = load_reg(s, rn);
7395 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7396 tcg_temp_free_i32(tmp2);
7398 store_reg(s, rd, tmp);
7401 tmp = load_reg(s, rm);
7402 tmp2 = load_reg(s, rs);
7403 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7404 tcg_temp_free_i32(tmp2);
7406 tmp64 = tcg_temp_new_i64();
7407 tcg_gen_ext_i32_i64(tmp64, tmp);
7408 tcg_temp_free_i32(tmp);
7409 gen_addq(s, tmp64, rn, rd);
7410 gen_storeq_reg(s, rn, rd, tmp64);
7411 tcg_temp_free_i64(tmp64);
7414 tmp2 = load_reg(s, rn);
7415 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7416 tcg_temp_free_i32(tmp2);
7418 store_reg(s, rd, tmp);
7425 } else if (((insn & 0x0e000000) == 0 &&
7426 (insn & 0x00000090) != 0x90) ||
7427 ((insn & 0x0e000000) == (1 << 25))) {
7428 int set_cc, logic_cc, shiftop;
7430 op1 = (insn >> 21) & 0xf;
7431 set_cc = (insn >> 20) & 1;
7432 logic_cc = table_logic_cc[op1] & set_cc;
7434 /* data processing instruction */
7435 if (insn & (1 << 25)) {
7436 /* immediate operand */
7438 shift = ((insn >> 8) & 0xf) * 2;
7440 val = (val >> shift) | (val << (32 - shift));
7442 tmp2 = tcg_temp_new_i32();
7443 tcg_gen_movi_i32(tmp2, val);
7444 if (logic_cc && shift) {
7445 gen_set_CF_bit31(tmp2);
7450 tmp2 = load_reg(s, rm);
7451 shiftop = (insn >> 5) & 3;
7452 if (!(insn & (1 << 4))) {
7453 shift = (insn >> 7) & 0x1f;
7454 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7456 rs = (insn >> 8) & 0xf;
7457 tmp = load_reg(s, rs);
7458 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7461 if (op1 != 0x0f && op1 != 0x0d) {
7462 rn = (insn >> 16) & 0xf;
7463 tmp = load_reg(s, rn);
7465 TCGV_UNUSED_I32(tmp);
7467 rd = (insn >> 12) & 0xf;
7470 tcg_gen_and_i32(tmp, tmp, tmp2);
7474 store_reg_bx(env, s, rd, tmp);
7477 tcg_gen_xor_i32(tmp, tmp, tmp2);
7481 store_reg_bx(env, s, rd, tmp);
7484 if (set_cc && rd == 15) {
7485 /* SUBS r15, ... is used for exception return. */
7489 gen_sub_CC(tmp, tmp, tmp2);
7490 gen_exception_return(s, tmp);
7493 gen_sub_CC(tmp, tmp, tmp2);
7495 tcg_gen_sub_i32(tmp, tmp, tmp2);
7497 store_reg_bx(env, s, rd, tmp);
7502 gen_sub_CC(tmp, tmp2, tmp);
7504 tcg_gen_sub_i32(tmp, tmp2, tmp);
7506 store_reg_bx(env, s, rd, tmp);
7510 gen_add_CC(tmp, tmp, tmp2);
7512 tcg_gen_add_i32(tmp, tmp, tmp2);
7514 store_reg_bx(env, s, rd, tmp);
7518 gen_adc_CC(tmp, tmp, tmp2);
7520 gen_add_carry(tmp, tmp, tmp2);
7522 store_reg_bx(env, s, rd, tmp);
7526 gen_sbc_CC(tmp, tmp, tmp2);
7528 gen_sub_carry(tmp, tmp, tmp2);
7530 store_reg_bx(env, s, rd, tmp);
7534 gen_sbc_CC(tmp, tmp2, tmp);
7536 gen_sub_carry(tmp, tmp2, tmp);
7538 store_reg_bx(env, s, rd, tmp);
7542 tcg_gen_and_i32(tmp, tmp, tmp2);
7545 tcg_temp_free_i32(tmp);
7549 tcg_gen_xor_i32(tmp, tmp, tmp2);
7552 tcg_temp_free_i32(tmp);
7556 gen_sub_CC(tmp, tmp, tmp2);
7558 tcg_temp_free_i32(tmp);
7562 gen_add_CC(tmp, tmp, tmp2);
7564 tcg_temp_free_i32(tmp);
7567 tcg_gen_or_i32(tmp, tmp, tmp2);
7571 store_reg_bx(env, s, rd, tmp);
7574 if (logic_cc && rd == 15) {
7575 /* MOVS r15, ... is used for exception return. */
7579 gen_exception_return(s, tmp2);
7584 store_reg_bx(env, s, rd, tmp2);
7588 tcg_gen_andc_i32(tmp, tmp, tmp2);
7592 store_reg_bx(env, s, rd, tmp);
7596 tcg_gen_not_i32(tmp2, tmp2);
7600 store_reg_bx(env, s, rd, tmp2);
7603 if (op1 != 0x0f && op1 != 0x0d) {
7604 tcg_temp_free_i32(tmp2);
7607 /* other instructions */
7608 op1 = (insn >> 24) & 0xf;
7612 /* multiplies, extra load/stores */
7613 sh = (insn >> 5) & 3;
7616 rd = (insn >> 16) & 0xf;
7617 rn = (insn >> 12) & 0xf;
7618 rs = (insn >> 8) & 0xf;
7620 op1 = (insn >> 20) & 0xf;
7622 case 0: case 1: case 2: case 3: case 6:
7624 tmp = load_reg(s, rs);
7625 tmp2 = load_reg(s, rm);
7626 tcg_gen_mul_i32(tmp, tmp, tmp2);
7627 tcg_temp_free_i32(tmp2);
7628 if (insn & (1 << 22)) {
7629 /* Subtract (mls) */
7631 tmp2 = load_reg(s, rn);
7632 tcg_gen_sub_i32(tmp, tmp2, tmp);
7633 tcg_temp_free_i32(tmp2);
7634 } else if (insn & (1 << 21)) {
7636 tmp2 = load_reg(s, rn);
7637 tcg_gen_add_i32(tmp, tmp, tmp2);
7638 tcg_temp_free_i32(tmp2);
7640 if (insn & (1 << 20))
7642 store_reg(s, rd, tmp);
7645 /* 64 bit mul double accumulate (UMAAL) */
7647 tmp = load_reg(s, rs);
7648 tmp2 = load_reg(s, rm);
7649 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7650 gen_addq_lo(s, tmp64, rn);
7651 gen_addq_lo(s, tmp64, rd);
7652 gen_storeq_reg(s, rn, rd, tmp64);
7653 tcg_temp_free_i64(tmp64);
7655 case 8: case 9: case 10: case 11:
7656 case 12: case 13: case 14: case 15:
7657 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7658 tmp = load_reg(s, rs);
7659 tmp2 = load_reg(s, rm);
7660 if (insn & (1 << 22)) {
7661 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7663 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7665 if (insn & (1 << 21)) { /* mult accumulate */
7666 TCGv_i32 al = load_reg(s, rn);
7667 TCGv_i32 ah = load_reg(s, rd);
7668 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7669 tcg_temp_free_i32(al);
7670 tcg_temp_free_i32(ah);
7672 if (insn & (1 << 20)) {
7673 gen_logicq_cc(tmp, tmp2);
7675 store_reg(s, rn, tmp);
7676 store_reg(s, rd, tmp2);
7682 rn = (insn >> 16) & 0xf;
7683 rd = (insn >> 12) & 0xf;
7684 if (insn & (1 << 23)) {
7685 /* load/store exclusive */
7686 int op2 = (insn >> 8) & 3;
7687 op1 = (insn >> 21) & 0x3;
7690 case 0: /* lda/stl */
7696 case 1: /* reserved */
7698 case 2: /* ldaex/stlex */
7701 case 3: /* ldrex/strex */
7710 addr = tcg_temp_local_new_i32();
7711 load_reg_var(s, addr, rn);
7713 /* Since the emulation does not have barriers,
7714 the acquire/release semantics need no special
7717 if (insn & (1 << 20)) {
7718 tmp = tcg_temp_new_i32();
7721 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7724 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7727 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7732 store_reg(s, rd, tmp);
7735 tmp = load_reg(s, rm);
7738 gen_aa32_st32(tmp, addr, IS_USER(s));
7741 gen_aa32_st8(tmp, addr, IS_USER(s));
7744 gen_aa32_st16(tmp, addr, IS_USER(s));
7749 tcg_temp_free_i32(tmp);
7751 } else if (insn & (1 << 20)) {
7754 gen_load_exclusive(s, rd, 15, addr, 2);
7756 case 1: /* ldrexd */
7757 gen_load_exclusive(s, rd, rd + 1, addr, 3);
7759 case 2: /* ldrexb */
7760 gen_load_exclusive(s, rd, 15, addr, 0);
7762 case 3: /* ldrexh */
7763 gen_load_exclusive(s, rd, 15, addr, 1);
7772 gen_store_exclusive(s, rd, rm, 15, addr, 2);
7774 case 1: /* strexd */
7775 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7777 case 2: /* strexb */
7778 gen_store_exclusive(s, rd, rm, 15, addr, 0);
7780 case 3: /* strexh */
7781 gen_store_exclusive(s, rd, rm, 15, addr, 1);
7787 tcg_temp_free_i32(addr);
7789 /* SWP instruction */
7792 /* ??? This is not really atomic. However we know
7793 we never have multiple CPUs running in parallel,
7794 so it is good enough. */
7795 addr = load_reg(s, rn);
7796 tmp = load_reg(s, rm);
7797 tmp2 = tcg_temp_new_i32();
7798 if (insn & (1 << 22)) {
7799 gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7800 gen_aa32_st8(tmp, addr, IS_USER(s));
7802 gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7803 gen_aa32_st32(tmp, addr, IS_USER(s));
7805 tcg_temp_free_i32(tmp);
7806 tcg_temp_free_i32(addr);
7807 store_reg(s, rd, tmp2);
7813 /* Misc load/store */
7814 rn = (insn >> 16) & 0xf;
7815 rd = (insn >> 12) & 0xf;
7816 addr = load_reg(s, rn);
7817 if (insn & (1 << 24))
7818 gen_add_datah_offset(s, insn, 0, addr);
7820 if (insn & (1 << 20)) {
7822 tmp = tcg_temp_new_i32();
7825 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7828 gen_aa32_ld8s(tmp, addr, IS_USER(s));
7832 gen_aa32_ld16s(tmp, addr, IS_USER(s));
7836 } else if (sh & 2) {
7841 tmp = load_reg(s, rd);
7842 gen_aa32_st32(tmp, addr, IS_USER(s));
7843 tcg_temp_free_i32(tmp);
7844 tcg_gen_addi_i32(addr, addr, 4);
7845 tmp = load_reg(s, rd + 1);
7846 gen_aa32_st32(tmp, addr, IS_USER(s));
7847 tcg_temp_free_i32(tmp);
7851 tmp = tcg_temp_new_i32();
7852 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7853 store_reg(s, rd, tmp);
7854 tcg_gen_addi_i32(addr, addr, 4);
7855 tmp = tcg_temp_new_i32();
7856 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7860 address_offset = -4;
7863 tmp = load_reg(s, rd);
7864 gen_aa32_st16(tmp, addr, IS_USER(s));
7865 tcg_temp_free_i32(tmp);
7868 /* Perform base writeback before the loaded value to
7869 ensure correct behavior with overlapping index registers.
7870 ldrd with base writeback is is undefined if the
7871 destination and index registers overlap. */
7872 if (!(insn & (1 << 24))) {
7873 gen_add_datah_offset(s, insn, address_offset, addr);
7874 store_reg(s, rn, addr);
7875 } else if (insn & (1 << 21)) {
7877 tcg_gen_addi_i32(addr, addr, address_offset);
7878 store_reg(s, rn, addr);
7880 tcg_temp_free_i32(addr);
7883 /* Complete the load. */
7884 store_reg(s, rd, tmp);
7893 if (insn & (1 << 4)) {
7895 /* Armv6 Media instructions. */
7897 rn = (insn >> 16) & 0xf;
7898 rd = (insn >> 12) & 0xf;
7899 rs = (insn >> 8) & 0xf;
7900 switch ((insn >> 23) & 3) {
7901 case 0: /* Parallel add/subtract. */
7902 op1 = (insn >> 20) & 7;
7903 tmp = load_reg(s, rn);
7904 tmp2 = load_reg(s, rm);
7905 sh = (insn >> 5) & 7;
7906 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7908 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7909 tcg_temp_free_i32(tmp2);
7910 store_reg(s, rd, tmp);
7913 if ((insn & 0x00700020) == 0) {
7914 /* Halfword pack. */
7915 tmp = load_reg(s, rn);
7916 tmp2 = load_reg(s, rm);
7917 shift = (insn >> 7) & 0x1f;
7918 if (insn & (1 << 6)) {
7922 tcg_gen_sari_i32(tmp2, tmp2, shift);
7923 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7924 tcg_gen_ext16u_i32(tmp2, tmp2);
7928 tcg_gen_shli_i32(tmp2, tmp2, shift);
7929 tcg_gen_ext16u_i32(tmp, tmp);
7930 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7932 tcg_gen_or_i32(tmp, tmp, tmp2);
7933 tcg_temp_free_i32(tmp2);
7934 store_reg(s, rd, tmp);
7935 } else if ((insn & 0x00200020) == 0x00200000) {
7937 tmp = load_reg(s, rm);
7938 shift = (insn >> 7) & 0x1f;
7939 if (insn & (1 << 6)) {
7942 tcg_gen_sari_i32(tmp, tmp, shift);
7944 tcg_gen_shli_i32(tmp, tmp, shift);
7946 sh = (insn >> 16) & 0x1f;
7947 tmp2 = tcg_const_i32(sh);
7948 if (insn & (1 << 22))
7949 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7951 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7952 tcg_temp_free_i32(tmp2);
7953 store_reg(s, rd, tmp);
7954 } else if ((insn & 0x00300fe0) == 0x00200f20) {
7956 tmp = load_reg(s, rm);
7957 sh = (insn >> 16) & 0x1f;
7958 tmp2 = tcg_const_i32(sh);
7959 if (insn & (1 << 22))
7960 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7962 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7963 tcg_temp_free_i32(tmp2);
7964 store_reg(s, rd, tmp);
7965 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
7967 tmp = load_reg(s, rn);
7968 tmp2 = load_reg(s, rm);
7969 tmp3 = tcg_temp_new_i32();
7970 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7971 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7972 tcg_temp_free_i32(tmp3);
7973 tcg_temp_free_i32(tmp2);
7974 store_reg(s, rd, tmp);
7975 } else if ((insn & 0x000003e0) == 0x00000060) {
7976 tmp = load_reg(s, rm);
7977 shift = (insn >> 10) & 3;
7978 /* ??? In many cases it's not necessary to do a
7979 rotate, a shift is sufficient. */
7981 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7982 op1 = (insn >> 20) & 7;
7984 case 0: gen_sxtb16(tmp); break;
7985 case 2: gen_sxtb(tmp); break;
7986 case 3: gen_sxth(tmp); break;
7987 case 4: gen_uxtb16(tmp); break;
7988 case 6: gen_uxtb(tmp); break;
7989 case 7: gen_uxth(tmp); break;
7990 default: goto illegal_op;
7993 tmp2 = load_reg(s, rn);
7994 if ((op1 & 3) == 0) {
7995 gen_add16(tmp, tmp2);
7997 tcg_gen_add_i32(tmp, tmp, tmp2);
7998 tcg_temp_free_i32(tmp2);
8001 store_reg(s, rd, tmp);
8002 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8004 tmp = load_reg(s, rm);
8005 if (insn & (1 << 22)) {
8006 if (insn & (1 << 7)) {
8010 gen_helper_rbit(tmp, tmp);
8013 if (insn & (1 << 7))
8016 tcg_gen_bswap32_i32(tmp, tmp);
8018 store_reg(s, rd, tmp);
8023 case 2: /* Multiplies (Type 3). */
8024 switch ((insn >> 20) & 0x7) {
8026 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8027 /* op2 not 00x or 11x : UNDEF */
8030 /* Signed multiply most significant [accumulate].
8031 (SMMUL, SMMLA, SMMLS) */
8032 tmp = load_reg(s, rm);
8033 tmp2 = load_reg(s, rs);
8034 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8037 tmp = load_reg(s, rd);
8038 if (insn & (1 << 6)) {
8039 tmp64 = gen_subq_msw(tmp64, tmp);
8041 tmp64 = gen_addq_msw(tmp64, tmp);
8044 if (insn & (1 << 5)) {
8045 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8047 tcg_gen_shri_i64(tmp64, tmp64, 32);
8048 tmp = tcg_temp_new_i32();
8049 tcg_gen_trunc_i64_i32(tmp, tmp64);
8050 tcg_temp_free_i64(tmp64);
8051 store_reg(s, rn, tmp);
8055 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8056 if (insn & (1 << 7)) {
8059 tmp = load_reg(s, rm);
8060 tmp2 = load_reg(s, rs);
8061 if (insn & (1 << 5))
8062 gen_swap_half(tmp2);
8063 gen_smul_dual(tmp, tmp2);
8064 if (insn & (1 << 6)) {
8065 /* This subtraction cannot overflow. */
8066 tcg_gen_sub_i32(tmp, tmp, tmp2);
8068 /* This addition cannot overflow 32 bits;
8069 * however it may overflow considered as a signed
8070 * operation, in which case we must set the Q flag.
8072 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8074 tcg_temp_free_i32(tmp2);
8075 if (insn & (1 << 22)) {
8076 /* smlald, smlsld */
8077 tmp64 = tcg_temp_new_i64();
8078 tcg_gen_ext_i32_i64(tmp64, tmp);
8079 tcg_temp_free_i32(tmp);
8080 gen_addq(s, tmp64, rd, rn);
8081 gen_storeq_reg(s, rd, rn, tmp64);
8082 tcg_temp_free_i64(tmp64);
8084 /* smuad, smusd, smlad, smlsd */
8087 tmp2 = load_reg(s, rd);
8088 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8089 tcg_temp_free_i32(tmp2);
8091 store_reg(s, rn, tmp);
8097 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8100 if (((insn >> 5) & 7) || (rd != 15)) {
8103 tmp = load_reg(s, rm);
8104 tmp2 = load_reg(s, rs);
8105 if (insn & (1 << 21)) {
8106 gen_helper_udiv(tmp, tmp, tmp2);
8108 gen_helper_sdiv(tmp, tmp, tmp2);
8110 tcg_temp_free_i32(tmp2);
8111 store_reg(s, rn, tmp);
8118 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8120 case 0: /* Unsigned sum of absolute differences. */
8122 tmp = load_reg(s, rm);
8123 tmp2 = load_reg(s, rs);
8124 gen_helper_usad8(tmp, tmp, tmp2);
8125 tcg_temp_free_i32(tmp2);
8127 tmp2 = load_reg(s, rd);
8128 tcg_gen_add_i32(tmp, tmp, tmp2);
8129 tcg_temp_free_i32(tmp2);
8131 store_reg(s, rn, tmp);
8133 case 0x20: case 0x24: case 0x28: case 0x2c:
8134 /* Bitfield insert/clear. */
8136 shift = (insn >> 7) & 0x1f;
8137 i = (insn >> 16) & 0x1f;
8140 tmp = tcg_temp_new_i32();
8141 tcg_gen_movi_i32(tmp, 0);
8143 tmp = load_reg(s, rm);
8146 tmp2 = load_reg(s, rd);
8147 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8148 tcg_temp_free_i32(tmp2);
8150 store_reg(s, rd, tmp);
8152 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8153 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8155 tmp = load_reg(s, rm);
8156 shift = (insn >> 7) & 0x1f;
8157 i = ((insn >> 16) & 0x1f) + 1;
8162 gen_ubfx(tmp, shift, (1u << i) - 1);
8164 gen_sbfx(tmp, shift, i);
8167 store_reg(s, rd, tmp);
8177 /* Check for undefined extension instructions
8178 * per the ARM Bible IE:
8179 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8181 sh = (0xf << 20) | (0xf << 4);
8182 if (op1 == 0x7 && ((insn & sh) == sh))
8186 /* load/store byte/word */
8187 rn = (insn >> 16) & 0xf;
8188 rd = (insn >> 12) & 0xf;
8189 tmp2 = load_reg(s, rn);
8190 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8191 if (insn & (1 << 24))
8192 gen_add_data_offset(s, insn, tmp2);
8193 if (insn & (1 << 20)) {
8195 tmp = tcg_temp_new_i32();
8196 if (insn & (1 << 22)) {
8197 gen_aa32_ld8u(tmp, tmp2, i);
8199 gen_aa32_ld32u(tmp, tmp2, i);
8203 tmp = load_reg(s, rd);
8204 if (insn & (1 << 22)) {
8205 gen_aa32_st8(tmp, tmp2, i);
8207 gen_aa32_st32(tmp, tmp2, i);
8209 tcg_temp_free_i32(tmp);
8211 if (!(insn & (1 << 24))) {
8212 gen_add_data_offset(s, insn, tmp2);
8213 store_reg(s, rn, tmp2);
8214 } else if (insn & (1 << 21)) {
8215 store_reg(s, rn, tmp2);
8217 tcg_temp_free_i32(tmp2);
8219 if (insn & (1 << 20)) {
8220 /* Complete the load. */
8221 store_reg_from_load(env, s, rd, tmp);
8227 int j, n, user, loaded_base;
8228 TCGv_i32 loaded_var;
8229 /* load/store multiple words */
8230 /* XXX: store correct base if write back */
8232 if (insn & (1 << 22)) {
8234 goto illegal_op; /* only usable in supervisor mode */
8236 if ((insn & (1 << 15)) == 0)
8239 rn = (insn >> 16) & 0xf;
8240 addr = load_reg(s, rn);
8242 /* compute total size */
8244 TCGV_UNUSED_I32(loaded_var);
8247 if (insn & (1 << i))
8250 /* XXX: test invalid n == 0 case ? */
8251 if (insn & (1 << 23)) {
8252 if (insn & (1 << 24)) {
8254 tcg_gen_addi_i32(addr, addr, 4);
8256 /* post increment */
8259 if (insn & (1 << 24)) {
8261 tcg_gen_addi_i32(addr, addr, -(n * 4));
8263 /* post decrement */
8265 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8270 if (insn & (1 << i)) {
8271 if (insn & (1 << 20)) {
8273 tmp = tcg_temp_new_i32();
8274 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8276 tmp2 = tcg_const_i32(i);
8277 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8278 tcg_temp_free_i32(tmp2);
8279 tcg_temp_free_i32(tmp);
8280 } else if (i == rn) {
8284 store_reg_from_load(env, s, i, tmp);
8289 /* special case: r15 = PC + 8 */
8290 val = (long)s->pc + 4;
8291 tmp = tcg_temp_new_i32();
8292 tcg_gen_movi_i32(tmp, val);
8294 tmp = tcg_temp_new_i32();
8295 tmp2 = tcg_const_i32(i);
8296 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8297 tcg_temp_free_i32(tmp2);
8299 tmp = load_reg(s, i);
8301 gen_aa32_st32(tmp, addr, IS_USER(s));
8302 tcg_temp_free_i32(tmp);
8305 /* no need to add after the last transfer */
8307 tcg_gen_addi_i32(addr, addr, 4);
8310 if (insn & (1 << 21)) {
8312 if (insn & (1 << 23)) {
8313 if (insn & (1 << 24)) {
8316 /* post increment */
8317 tcg_gen_addi_i32(addr, addr, 4);
8320 if (insn & (1 << 24)) {
8323 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8325 /* post decrement */
8326 tcg_gen_addi_i32(addr, addr, -(n * 4));
8329 store_reg(s, rn, addr);
8331 tcg_temp_free_i32(addr);
8334 store_reg(s, rn, loaded_var);
8336 if ((insn & (1 << 22)) && !user) {
8337 /* Restore CPSR from SPSR. */
8338 tmp = load_cpu_field(spsr);
8339 gen_set_cpsr(tmp, 0xffffffff);
8340 tcg_temp_free_i32(tmp);
8341 s->is_jmp = DISAS_UPDATE;
8350 /* branch (and link) */
8351 val = (int32_t)s->pc;
8352 if (insn & (1 << 24)) {
8353 tmp = tcg_temp_new_i32();
8354 tcg_gen_movi_i32(tmp, val);
8355 store_reg(s, 14, tmp);
8357 offset = sextract32(insn << 2, 0, 26);
8365 if (((insn >> 8) & 0xe) == 10) {
8367 if (disas_vfp_insn(env, s, insn)) {
8370 } else if (disas_coproc_insn(env, s, insn)) {
8377 gen_set_pc_im(s, s->pc);
8378 s->is_jmp = DISAS_SWI;
8382 gen_exception_insn(s, 4, EXCP_UDEF);
8388 /* Return true if this is a Thumb-2 logical op. */
8390 thumb2_logic_op(int op)
8395 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8396 then set condition code flags based on the result of the operation.
8397 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8398 to the high bit of T1.
8399 Returns zero if the opcode is valid. */
8402 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8403 TCGv_i32 t0, TCGv_i32 t1)
8410 tcg_gen_and_i32(t0, t0, t1);
8414 tcg_gen_andc_i32(t0, t0, t1);
8418 tcg_gen_or_i32(t0, t0, t1);
8422 tcg_gen_orc_i32(t0, t0, t1);
8426 tcg_gen_xor_i32(t0, t0, t1);
8431 gen_add_CC(t0, t0, t1);
8433 tcg_gen_add_i32(t0, t0, t1);
8437 gen_adc_CC(t0, t0, t1);
8443 gen_sbc_CC(t0, t0, t1);
8445 gen_sub_carry(t0, t0, t1);
8450 gen_sub_CC(t0, t0, t1);
8452 tcg_gen_sub_i32(t0, t0, t1);
8456 gen_sub_CC(t0, t1, t0);
8458 tcg_gen_sub_i32(t0, t1, t0);
8460 default: /* 5, 6, 7, 9, 12, 15. */
8466 gen_set_CF_bit31(t1);
8471 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8473 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8475 uint32_t insn, imm, shift, offset;
8476 uint32_t rd, rn, rm, rs;
8487 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8488 || arm_feature (env, ARM_FEATURE_M))) {
8489 /* Thumb-1 cores may need to treat bl and blx as a pair of
8490 16-bit instructions to get correct prefetch abort behavior. */
8492 if ((insn & (1 << 12)) == 0) {
8494 /* Second half of blx. */
8495 offset = ((insn & 0x7ff) << 1);
8496 tmp = load_reg(s, 14);
8497 tcg_gen_addi_i32(tmp, tmp, offset);
8498 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8500 tmp2 = tcg_temp_new_i32();
8501 tcg_gen_movi_i32(tmp2, s->pc | 1);
8502 store_reg(s, 14, tmp2);
8506 if (insn & (1 << 11)) {
8507 /* Second half of bl. */
8508 offset = ((insn & 0x7ff) << 1) | 1;
8509 tmp = load_reg(s, 14);
8510 tcg_gen_addi_i32(tmp, tmp, offset);
8512 tmp2 = tcg_temp_new_i32();
8513 tcg_gen_movi_i32(tmp2, s->pc | 1);
8514 store_reg(s, 14, tmp2);
8518 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8519 /* Instruction spans a page boundary. Implement it as two
8520 16-bit instructions in case the second half causes an
8522 offset = ((int32_t)insn << 21) >> 9;
8523 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8526 /* Fall through to 32-bit decode. */
8529 insn = arm_lduw_code(env, s->pc, s->bswap_code);
8531 insn |= (uint32_t)insn_hw1 << 16;
8533 if ((insn & 0xf800e800) != 0xf000e800) {
8537 rn = (insn >> 16) & 0xf;
8538 rs = (insn >> 12) & 0xf;
8539 rd = (insn >> 8) & 0xf;
8541 switch ((insn >> 25) & 0xf) {
8542 case 0: case 1: case 2: case 3:
8543 /* 16-bit instructions. Should never happen. */
8546 if (insn & (1 << 22)) {
8547 /* Other load/store, table branch. */
8548 if (insn & 0x01200000) {
8549 /* Load/store doubleword. */
8551 addr = tcg_temp_new_i32();
8552 tcg_gen_movi_i32(addr, s->pc & ~3);
8554 addr = load_reg(s, rn);
8556 offset = (insn & 0xff) * 4;
8557 if ((insn & (1 << 23)) == 0)
8559 if (insn & (1 << 24)) {
8560 tcg_gen_addi_i32(addr, addr, offset);
8563 if (insn & (1 << 20)) {
8565 tmp = tcg_temp_new_i32();
8566 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8567 store_reg(s, rs, tmp);
8568 tcg_gen_addi_i32(addr, addr, 4);
8569 tmp = tcg_temp_new_i32();
8570 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8571 store_reg(s, rd, tmp);
8574 tmp = load_reg(s, rs);
8575 gen_aa32_st32(tmp, addr, IS_USER(s));
8576 tcg_temp_free_i32(tmp);
8577 tcg_gen_addi_i32(addr, addr, 4);
8578 tmp = load_reg(s, rd);
8579 gen_aa32_st32(tmp, addr, IS_USER(s));
8580 tcg_temp_free_i32(tmp);
8582 if (insn & (1 << 21)) {
8583 /* Base writeback. */
8586 tcg_gen_addi_i32(addr, addr, offset - 4);
8587 store_reg(s, rn, addr);
8589 tcg_temp_free_i32(addr);
8591 } else if ((insn & (1 << 23)) == 0) {
8592 /* Load/store exclusive word. */
8593 addr = tcg_temp_local_new_i32();
8594 load_reg_var(s, addr, rn);
8595 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8596 if (insn & (1 << 20)) {
8597 gen_load_exclusive(s, rs, 15, addr, 2);
8599 gen_store_exclusive(s, rd, rs, 15, addr, 2);
8601 tcg_temp_free_i32(addr);
8602 } else if ((insn & (7 << 5)) == 0) {
8605 addr = tcg_temp_new_i32();
8606 tcg_gen_movi_i32(addr, s->pc);
8608 addr = load_reg(s, rn);
8610 tmp = load_reg(s, rm);
8611 tcg_gen_add_i32(addr, addr, tmp);
8612 if (insn & (1 << 4)) {
8614 tcg_gen_add_i32(addr, addr, tmp);
8615 tcg_temp_free_i32(tmp);
8616 tmp = tcg_temp_new_i32();
8617 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8619 tcg_temp_free_i32(tmp);
8620 tmp = tcg_temp_new_i32();
8621 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8623 tcg_temp_free_i32(addr);
8624 tcg_gen_shli_i32(tmp, tmp, 1);
8625 tcg_gen_addi_i32(tmp, tmp, s->pc);
8626 store_reg(s, 15, tmp);
8628 int op2 = (insn >> 6) & 0x3;
8629 op = (insn >> 4) & 0x3;
8634 /* Load/store exclusive byte/halfword/doubleword */
8641 /* Load-acquire/store-release */
8647 /* Load-acquire/store-release exclusive */
8651 addr = tcg_temp_local_new_i32();
8652 load_reg_var(s, addr, rn);
8654 if (insn & (1 << 20)) {
8655 tmp = tcg_temp_new_i32();
8658 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8661 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8664 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8669 store_reg(s, rs, tmp);
8671 tmp = load_reg(s, rs);
8674 gen_aa32_st8(tmp, addr, IS_USER(s));
8677 gen_aa32_st16(tmp, addr, IS_USER(s));
8680 gen_aa32_st32(tmp, addr, IS_USER(s));
8685 tcg_temp_free_i32(tmp);
8687 } else if (insn & (1 << 20)) {
8688 gen_load_exclusive(s, rs, rd, addr, op);
8690 gen_store_exclusive(s, rm, rs, rd, addr, op);
8692 tcg_temp_free_i32(addr);
8695 /* Load/store multiple, RFE, SRS. */
8696 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8697 /* RFE, SRS: not available in user mode or on M profile */
8698 if (IS_USER(s) || IS_M(env)) {
8701 if (insn & (1 << 20)) {
8703 addr = load_reg(s, rn);
8704 if ((insn & (1 << 24)) == 0)
8705 tcg_gen_addi_i32(addr, addr, -8);
8706 /* Load PC into tmp and CPSR into tmp2. */
8707 tmp = tcg_temp_new_i32();
8708 gen_aa32_ld32u(tmp, addr, 0);
8709 tcg_gen_addi_i32(addr, addr, 4);
8710 tmp2 = tcg_temp_new_i32();
8711 gen_aa32_ld32u(tmp2, addr, 0);
8712 if (insn & (1 << 21)) {
8713 /* Base writeback. */
8714 if (insn & (1 << 24)) {
8715 tcg_gen_addi_i32(addr, addr, 4);
8717 tcg_gen_addi_i32(addr, addr, -4);
8719 store_reg(s, rn, addr);
8721 tcg_temp_free_i32(addr);
8723 gen_rfe(s, tmp, tmp2);
8726 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8730 int i, loaded_base = 0;
8731 TCGv_i32 loaded_var;
8732 /* Load/store multiple. */
8733 addr = load_reg(s, rn);
8735 for (i = 0; i < 16; i++) {
8736 if (insn & (1 << i))
8739 if (insn & (1 << 24)) {
8740 tcg_gen_addi_i32(addr, addr, -offset);
8743 TCGV_UNUSED_I32(loaded_var);
8744 for (i = 0; i < 16; i++) {
8745 if ((insn & (1 << i)) == 0)
8747 if (insn & (1 << 20)) {
8749 tmp = tcg_temp_new_i32();
8750 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8753 } else if (i == rn) {
8757 store_reg(s, i, tmp);
8761 tmp = load_reg(s, i);
8762 gen_aa32_st32(tmp, addr, IS_USER(s));
8763 tcg_temp_free_i32(tmp);
8765 tcg_gen_addi_i32(addr, addr, 4);
8768 store_reg(s, rn, loaded_var);
8770 if (insn & (1 << 21)) {
8771 /* Base register writeback. */
8772 if (insn & (1 << 24)) {
8773 tcg_gen_addi_i32(addr, addr, -offset);
8775 /* Fault if writeback register is in register list. */
8776 if (insn & (1 << rn))
8778 store_reg(s, rn, addr);
8780 tcg_temp_free_i32(addr);
8787 op = (insn >> 21) & 0xf;
8789 /* Halfword pack. */
8790 tmp = load_reg(s, rn);
8791 tmp2 = load_reg(s, rm);
8792 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8793 if (insn & (1 << 5)) {
8797 tcg_gen_sari_i32(tmp2, tmp2, shift);
8798 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8799 tcg_gen_ext16u_i32(tmp2, tmp2);
8803 tcg_gen_shli_i32(tmp2, tmp2, shift);
8804 tcg_gen_ext16u_i32(tmp, tmp);
8805 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8807 tcg_gen_or_i32(tmp, tmp, tmp2);
8808 tcg_temp_free_i32(tmp2);
8809 store_reg(s, rd, tmp);
8811 /* Data processing register constant shift. */
8813 tmp = tcg_temp_new_i32();
8814 tcg_gen_movi_i32(tmp, 0);
8816 tmp = load_reg(s, rn);
8818 tmp2 = load_reg(s, rm);
8820 shiftop = (insn >> 4) & 3;
8821 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8822 conds = (insn & (1 << 20)) != 0;
8823 logic_cc = (conds && thumb2_logic_op(op));
8824 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8825 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8827 tcg_temp_free_i32(tmp2);
8829 store_reg(s, rd, tmp);
8831 tcg_temp_free_i32(tmp);
8835 case 13: /* Misc data processing. */
8836 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8837 if (op < 4 && (insn & 0xf000) != 0xf000)
8840 case 0: /* Register controlled shift. */
8841 tmp = load_reg(s, rn);
8842 tmp2 = load_reg(s, rm);
8843 if ((insn & 0x70) != 0)
8845 op = (insn >> 21) & 3;
8846 logic_cc = (insn & (1 << 20)) != 0;
8847 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8850 store_reg_bx(env, s, rd, tmp);
8852 case 1: /* Sign/zero extend. */
8853 tmp = load_reg(s, rm);
8854 shift = (insn >> 4) & 3;
8855 /* ??? In many cases it's not necessary to do a
8856 rotate, a shift is sufficient. */
8858 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8859 op = (insn >> 20) & 7;
8861 case 0: gen_sxth(tmp); break;
8862 case 1: gen_uxth(tmp); break;
8863 case 2: gen_sxtb16(tmp); break;
8864 case 3: gen_uxtb16(tmp); break;
8865 case 4: gen_sxtb(tmp); break;
8866 case 5: gen_uxtb(tmp); break;
8867 default: goto illegal_op;
8870 tmp2 = load_reg(s, rn);
8871 if ((op >> 1) == 1) {
8872 gen_add16(tmp, tmp2);
8874 tcg_gen_add_i32(tmp, tmp, tmp2);
8875 tcg_temp_free_i32(tmp2);
8878 store_reg(s, rd, tmp);
8880 case 2: /* SIMD add/subtract. */
8881 op = (insn >> 20) & 7;
8882 shift = (insn >> 4) & 7;
8883 if ((op & 3) == 3 || (shift & 3) == 3)
8885 tmp = load_reg(s, rn);
8886 tmp2 = load_reg(s, rm);
8887 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8888 tcg_temp_free_i32(tmp2);
8889 store_reg(s, rd, tmp);
8891 case 3: /* Other data processing. */
8892 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8894 /* Saturating add/subtract. */
8895 tmp = load_reg(s, rn);
8896 tmp2 = load_reg(s, rm);
8898 gen_helper_double_saturate(tmp, cpu_env, tmp);
8900 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8902 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8903 tcg_temp_free_i32(tmp2);
8905 tmp = load_reg(s, rn);
8907 case 0x0a: /* rbit */
8908 gen_helper_rbit(tmp, tmp);
8910 case 0x08: /* rev */
8911 tcg_gen_bswap32_i32(tmp, tmp);
8913 case 0x09: /* rev16 */
8916 case 0x0b: /* revsh */
8919 case 0x10: /* sel */
8920 tmp2 = load_reg(s, rm);
8921 tmp3 = tcg_temp_new_i32();
8922 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8923 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8924 tcg_temp_free_i32(tmp3);
8925 tcg_temp_free_i32(tmp2);
8927 case 0x18: /* clz */
8928 gen_helper_clz(tmp, tmp);
8934 store_reg(s, rd, tmp);
8936 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8937 op = (insn >> 4) & 0xf;
8938 tmp = load_reg(s, rn);
8939 tmp2 = load_reg(s, rm);
8940 switch ((insn >> 20) & 7) {
8941 case 0: /* 32 x 32 -> 32 */
8942 tcg_gen_mul_i32(tmp, tmp, tmp2);
8943 tcg_temp_free_i32(tmp2);
8945 tmp2 = load_reg(s, rs);
8947 tcg_gen_sub_i32(tmp, tmp2, tmp);
8949 tcg_gen_add_i32(tmp, tmp, tmp2);
8950 tcg_temp_free_i32(tmp2);
8953 case 1: /* 16 x 16 -> 32 */
8954 gen_mulxy(tmp, tmp2, op & 2, op & 1);
8955 tcg_temp_free_i32(tmp2);
8957 tmp2 = load_reg(s, rs);
8958 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8959 tcg_temp_free_i32(tmp2);
8962 case 2: /* Dual multiply add. */
8963 case 4: /* Dual multiply subtract. */
8965 gen_swap_half(tmp2);
8966 gen_smul_dual(tmp, tmp2);
8967 if (insn & (1 << 22)) {
8968 /* This subtraction cannot overflow. */
8969 tcg_gen_sub_i32(tmp, tmp, tmp2);
8971 /* This addition cannot overflow 32 bits;
8972 * however it may overflow considered as a signed
8973 * operation, in which case we must set the Q flag.
8975 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8977 tcg_temp_free_i32(tmp2);
8980 tmp2 = load_reg(s, rs);
8981 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8982 tcg_temp_free_i32(tmp2);
8985 case 3: /* 32 * 16 -> 32msb */
8987 tcg_gen_sari_i32(tmp2, tmp2, 16);
8990 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8991 tcg_gen_shri_i64(tmp64, tmp64, 16);
8992 tmp = tcg_temp_new_i32();
8993 tcg_gen_trunc_i64_i32(tmp, tmp64);
8994 tcg_temp_free_i64(tmp64);
8997 tmp2 = load_reg(s, rs);
8998 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8999 tcg_temp_free_i32(tmp2);
9002 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9003 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9005 tmp = load_reg(s, rs);
9006 if (insn & (1 << 20)) {
9007 tmp64 = gen_addq_msw(tmp64, tmp);
9009 tmp64 = gen_subq_msw(tmp64, tmp);
9012 if (insn & (1 << 4)) {
9013 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9015 tcg_gen_shri_i64(tmp64, tmp64, 32);
9016 tmp = tcg_temp_new_i32();
9017 tcg_gen_trunc_i64_i32(tmp, tmp64);
9018 tcg_temp_free_i64(tmp64);
9020 case 7: /* Unsigned sum of absolute differences. */
9021 gen_helper_usad8(tmp, tmp, tmp2);
9022 tcg_temp_free_i32(tmp2);
9024 tmp2 = load_reg(s, rs);
9025 tcg_gen_add_i32(tmp, tmp, tmp2);
9026 tcg_temp_free_i32(tmp2);
9030 store_reg(s, rd, tmp);
9032 case 6: case 7: /* 64-bit multiply, Divide. */
9033 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9034 tmp = load_reg(s, rn);
9035 tmp2 = load_reg(s, rm);
9036 if ((op & 0x50) == 0x10) {
9038 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
9042 gen_helper_udiv(tmp, tmp, tmp2);
9044 gen_helper_sdiv(tmp, tmp, tmp2);
9045 tcg_temp_free_i32(tmp2);
9046 store_reg(s, rd, tmp);
9047 } else if ((op & 0xe) == 0xc) {
9048 /* Dual multiply accumulate long. */
9050 gen_swap_half(tmp2);
9051 gen_smul_dual(tmp, tmp2);
9053 tcg_gen_sub_i32(tmp, tmp, tmp2);
9055 tcg_gen_add_i32(tmp, tmp, tmp2);
9057 tcg_temp_free_i32(tmp2);
9059 tmp64 = tcg_temp_new_i64();
9060 tcg_gen_ext_i32_i64(tmp64, tmp);
9061 tcg_temp_free_i32(tmp);
9062 gen_addq(s, tmp64, rs, rd);
9063 gen_storeq_reg(s, rs, rd, tmp64);
9064 tcg_temp_free_i64(tmp64);
9067 /* Unsigned 64-bit multiply */
9068 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9072 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9073 tcg_temp_free_i32(tmp2);
9074 tmp64 = tcg_temp_new_i64();
9075 tcg_gen_ext_i32_i64(tmp64, tmp);
9076 tcg_temp_free_i32(tmp);
9078 /* Signed 64-bit multiply */
9079 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9084 gen_addq_lo(s, tmp64, rs);
9085 gen_addq_lo(s, tmp64, rd);
9086 } else if (op & 0x40) {
9087 /* 64-bit accumulate. */
9088 gen_addq(s, tmp64, rs, rd);
9090 gen_storeq_reg(s, rs, rd, tmp64);
9091 tcg_temp_free_i64(tmp64);
9096 case 6: case 7: case 14: case 15:
9098 if (((insn >> 24) & 3) == 3) {
9099 /* Translate into the equivalent ARM encoding. */
9100 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9101 if (disas_neon_data_insn(env, s, insn))
9103 } else if (((insn >> 8) & 0xe) == 10) {
9104 if (disas_vfp_insn(env, s, insn)) {
9108 if (insn & (1 << 28))
9110 if (disas_coproc_insn (env, s, insn))
9114 case 8: case 9: case 10: case 11:
9115 if (insn & (1 << 15)) {
9116 /* Branches, misc control. */
9117 if (insn & 0x5000) {
9118 /* Unconditional branch. */
9119 /* signextend(hw1[10:0]) -> offset[:12]. */
9120 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9121 /* hw1[10:0] -> offset[11:1]. */
9122 offset |= (insn & 0x7ff) << 1;
9123 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9124 offset[24:22] already have the same value because of the
9125 sign extension above. */
9126 offset ^= ((~insn) & (1 << 13)) << 10;
9127 offset ^= ((~insn) & (1 << 11)) << 11;
9129 if (insn & (1 << 14)) {
9130 /* Branch and link. */
9131 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9135 if (insn & (1 << 12)) {
9140 offset &= ~(uint32_t)2;
9141 /* thumb2 bx, no need to check */
9142 gen_bx_im(s, offset);
9144 } else if (((insn >> 23) & 7) == 7) {
9146 if (insn & (1 << 13))
9149 if (insn & (1 << 26)) {
9150 /* Secure monitor call (v6Z) */
9151 qemu_log_mask(LOG_UNIMP,
9152 "arm: unimplemented secure monitor call\n");
9153 goto illegal_op; /* not implemented. */
9155 op = (insn >> 20) & 7;
9157 case 0: /* msr cpsr. */
9159 tmp = load_reg(s, rn);
9160 addr = tcg_const_i32(insn & 0xff);
9161 gen_helper_v7m_msr(cpu_env, addr, tmp);
9162 tcg_temp_free_i32(addr);
9163 tcg_temp_free_i32(tmp);
9168 case 1: /* msr spsr. */
9171 tmp = load_reg(s, rn);
9173 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9177 case 2: /* cps, nop-hint. */
9178 if (((insn >> 8) & 7) == 0) {
9179 gen_nop_hint(s, insn & 0xff);
9181 /* Implemented as NOP in user mode. */
9186 if (insn & (1 << 10)) {
9187 if (insn & (1 << 7))
9189 if (insn & (1 << 6))
9191 if (insn & (1 << 5))
9193 if (insn & (1 << 9))
9194 imm = CPSR_A | CPSR_I | CPSR_F;
9196 if (insn & (1 << 8)) {
9198 imm |= (insn & 0x1f);
9201 gen_set_psr_im(s, offset, 0, imm);
9204 case 3: /* Special control operations. */
9206 op = (insn >> 4) & 0xf;
9214 /* These execute as NOPs. */
9221 /* Trivial implementation equivalent to bx. */
9222 tmp = load_reg(s, rn);
9225 case 5: /* Exception return. */
9229 if (rn != 14 || rd != 15) {
9232 tmp = load_reg(s, rn);
9233 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9234 gen_exception_return(s, tmp);
9236 case 6: /* mrs cpsr. */
9237 tmp = tcg_temp_new_i32();
9239 addr = tcg_const_i32(insn & 0xff);
9240 gen_helper_v7m_mrs(tmp, cpu_env, addr);
9241 tcg_temp_free_i32(addr);
9243 gen_helper_cpsr_read(tmp, cpu_env);
9245 store_reg(s, rd, tmp);
9247 case 7: /* mrs spsr. */
9248 /* Not accessible in user mode. */
9249 if (IS_USER(s) || IS_M(env))
9251 tmp = load_cpu_field(spsr);
9252 store_reg(s, rd, tmp);
9257 /* Conditional branch. */
9258 op = (insn >> 22) & 0xf;
9259 /* Generate a conditional jump to next instruction. */
9260 s->condlabel = gen_new_label();
9261 arm_gen_test_cc(op ^ 1, s->condlabel);
9264 /* offset[11:1] = insn[10:0] */
9265 offset = (insn & 0x7ff) << 1;
9266 /* offset[17:12] = insn[21:16]. */
9267 offset |= (insn & 0x003f0000) >> 4;
9268 /* offset[31:20] = insn[26]. */
9269 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9270 /* offset[18] = insn[13]. */
9271 offset |= (insn & (1 << 13)) << 5;
9272 /* offset[19] = insn[11]. */
9273 offset |= (insn & (1 << 11)) << 8;
9275 /* jump to the offset */
9276 gen_jmp(s, s->pc + offset);
9279 /* Data processing immediate. */
9280 if (insn & (1 << 25)) {
9281 if (insn & (1 << 24)) {
9282 if (insn & (1 << 20))
9284 /* Bitfield/Saturate. */
9285 op = (insn >> 21) & 7;
9287 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9289 tmp = tcg_temp_new_i32();
9290 tcg_gen_movi_i32(tmp, 0);
9292 tmp = load_reg(s, rn);
9295 case 2: /* Signed bitfield extract. */
9297 if (shift + imm > 32)
9300 gen_sbfx(tmp, shift, imm);
9302 case 6: /* Unsigned bitfield extract. */
9304 if (shift + imm > 32)
9307 gen_ubfx(tmp, shift, (1u << imm) - 1);
9309 case 3: /* Bitfield insert/clear. */
9312 imm = imm + 1 - shift;
9314 tmp2 = load_reg(s, rd);
9315 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9316 tcg_temp_free_i32(tmp2);
9321 default: /* Saturate. */
9324 tcg_gen_sari_i32(tmp, tmp, shift);
9326 tcg_gen_shli_i32(tmp, tmp, shift);
9328 tmp2 = tcg_const_i32(imm);
9331 if ((op & 1) && shift == 0)
9332 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9334 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9337 if ((op & 1) && shift == 0)
9338 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9340 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9342 tcg_temp_free_i32(tmp2);
9345 store_reg(s, rd, tmp);
9347 imm = ((insn & 0x04000000) >> 15)
9348 | ((insn & 0x7000) >> 4) | (insn & 0xff);
9349 if (insn & (1 << 22)) {
9350 /* 16-bit immediate. */
9351 imm |= (insn >> 4) & 0xf000;
9352 if (insn & (1 << 23)) {
9354 tmp = load_reg(s, rd);
9355 tcg_gen_ext16u_i32(tmp, tmp);
9356 tcg_gen_ori_i32(tmp, tmp, imm << 16);
9359 tmp = tcg_temp_new_i32();
9360 tcg_gen_movi_i32(tmp, imm);
9363 /* Add/sub 12-bit immediate. */
9365 offset = s->pc & ~(uint32_t)3;
9366 if (insn & (1 << 23))
9370 tmp = tcg_temp_new_i32();
9371 tcg_gen_movi_i32(tmp, offset);
9373 tmp = load_reg(s, rn);
9374 if (insn & (1 << 23))
9375 tcg_gen_subi_i32(tmp, tmp, imm);
9377 tcg_gen_addi_i32(tmp, tmp, imm);
9380 store_reg(s, rd, tmp);
9383 int shifter_out = 0;
9384 /* modified 12-bit immediate. */
9385 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9386 imm = (insn & 0xff);
9389 /* Nothing to do. */
9391 case 1: /* 00XY00XY */
9394 case 2: /* XY00XY00 */
9398 case 3: /* XYXYXYXY */
9402 default: /* Rotated constant. */
9403 shift = (shift << 1) | (imm >> 7);
9405 imm = imm << (32 - shift);
9409 tmp2 = tcg_temp_new_i32();
9410 tcg_gen_movi_i32(tmp2, imm);
9411 rn = (insn >> 16) & 0xf;
9413 tmp = tcg_temp_new_i32();
9414 tcg_gen_movi_i32(tmp, 0);
9416 tmp = load_reg(s, rn);
9418 op = (insn >> 21) & 0xf;
9419 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9420 shifter_out, tmp, tmp2))
9422 tcg_temp_free_i32(tmp2);
9423 rd = (insn >> 8) & 0xf;
9425 store_reg(s, rd, tmp);
9427 tcg_temp_free_i32(tmp);
9432 case 12: /* Load/store single data item. */
9437 if ((insn & 0x01100000) == 0x01000000) {
9438 if (disas_neon_ls_insn(env, s, insn))
9442 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9444 if (!(insn & (1 << 20))) {
9448 /* Byte or halfword load space with dest == r15 : memory hints.
9449 * Catch them early so we don't emit pointless addressing code.
9450 * This space is a mix of:
9451 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9452 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9454 * unallocated hints, which must be treated as NOPs
9455 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9456 * which is easiest for the decoding logic
9457 * Some space which must UNDEF
9459 int op1 = (insn >> 23) & 3;
9460 int op2 = (insn >> 6) & 0x3f;
9465 /* UNPREDICTABLE, unallocated hint or
9466 * PLD/PLDW/PLI (literal)
9471 return 0; /* PLD/PLDW/PLI or unallocated hint */
9473 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9474 return 0; /* PLD/PLDW/PLI or unallocated hint */
9476 /* UNDEF space, or an UNPREDICTABLE */
9482 addr = tcg_temp_new_i32();
9484 /* s->pc has already been incremented by 4. */
9485 imm = s->pc & 0xfffffffc;
9486 if (insn & (1 << 23))
9487 imm += insn & 0xfff;
9489 imm -= insn & 0xfff;
9490 tcg_gen_movi_i32(addr, imm);
9492 addr = load_reg(s, rn);
9493 if (insn & (1 << 23)) {
9494 /* Positive offset. */
9496 tcg_gen_addi_i32(addr, addr, imm);
9499 switch ((insn >> 8) & 0xf) {
9500 case 0x0: /* Shifted Register. */
9501 shift = (insn >> 4) & 0xf;
9503 tcg_temp_free_i32(addr);
9506 tmp = load_reg(s, rm);
9508 tcg_gen_shli_i32(tmp, tmp, shift);
9509 tcg_gen_add_i32(addr, addr, tmp);
9510 tcg_temp_free_i32(tmp);
9512 case 0xc: /* Negative offset. */
9513 tcg_gen_addi_i32(addr, addr, -imm);
9515 case 0xe: /* User privilege. */
9516 tcg_gen_addi_i32(addr, addr, imm);
9519 case 0x9: /* Post-decrement. */
9522 case 0xb: /* Post-increment. */
9526 case 0xd: /* Pre-decrement. */
9529 case 0xf: /* Pre-increment. */
9530 tcg_gen_addi_i32(addr, addr, imm);
9534 tcg_temp_free_i32(addr);
9539 if (insn & (1 << 20)) {
9541 tmp = tcg_temp_new_i32();
9544 gen_aa32_ld8u(tmp, addr, user);
9547 gen_aa32_ld8s(tmp, addr, user);
9550 gen_aa32_ld16u(tmp, addr, user);
9553 gen_aa32_ld16s(tmp, addr, user);
9556 gen_aa32_ld32u(tmp, addr, user);
9559 tcg_temp_free_i32(tmp);
9560 tcg_temp_free_i32(addr);
9566 store_reg(s, rs, tmp);
9570 tmp = load_reg(s, rs);
9573 gen_aa32_st8(tmp, addr, user);
9576 gen_aa32_st16(tmp, addr, user);
9579 gen_aa32_st32(tmp, addr, user);
9582 tcg_temp_free_i32(tmp);
9583 tcg_temp_free_i32(addr);
9586 tcg_temp_free_i32(tmp);
9589 tcg_gen_addi_i32(addr, addr, imm);
9591 store_reg(s, rn, addr);
9593 tcg_temp_free_i32(addr);
9605 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9607 uint32_t val, insn, op, rm, rn, rd, shift, cond;
9614 if (s->condexec_mask) {
9615 cond = s->condexec_cond;
9616 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9617 s->condlabel = gen_new_label();
9618 arm_gen_test_cc(cond ^ 1, s->condlabel);
9623 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9626 switch (insn >> 12) {
9630 op = (insn >> 11) & 3;
9633 rn = (insn >> 3) & 7;
9634 tmp = load_reg(s, rn);
9635 if (insn & (1 << 10)) {
9637 tmp2 = tcg_temp_new_i32();
9638 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9641 rm = (insn >> 6) & 7;
9642 tmp2 = load_reg(s, rm);
9644 if (insn & (1 << 9)) {
9645 if (s->condexec_mask)
9646 tcg_gen_sub_i32(tmp, tmp, tmp2);
9648 gen_sub_CC(tmp, tmp, tmp2);
9650 if (s->condexec_mask)
9651 tcg_gen_add_i32(tmp, tmp, tmp2);
9653 gen_add_CC(tmp, tmp, tmp2);
9655 tcg_temp_free_i32(tmp2);
9656 store_reg(s, rd, tmp);
9658 /* shift immediate */
9659 rm = (insn >> 3) & 7;
9660 shift = (insn >> 6) & 0x1f;
9661 tmp = load_reg(s, rm);
9662 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9663 if (!s->condexec_mask)
9665 store_reg(s, rd, tmp);
9669 /* arithmetic large immediate */
9670 op = (insn >> 11) & 3;
9671 rd = (insn >> 8) & 0x7;
9672 if (op == 0) { /* mov */
9673 tmp = tcg_temp_new_i32();
9674 tcg_gen_movi_i32(tmp, insn & 0xff);
9675 if (!s->condexec_mask)
9677 store_reg(s, rd, tmp);
9679 tmp = load_reg(s, rd);
9680 tmp2 = tcg_temp_new_i32();
9681 tcg_gen_movi_i32(tmp2, insn & 0xff);
9684 gen_sub_CC(tmp, tmp, tmp2);
9685 tcg_temp_free_i32(tmp);
9686 tcg_temp_free_i32(tmp2);
9689 if (s->condexec_mask)
9690 tcg_gen_add_i32(tmp, tmp, tmp2);
9692 gen_add_CC(tmp, tmp, tmp2);
9693 tcg_temp_free_i32(tmp2);
9694 store_reg(s, rd, tmp);
9697 if (s->condexec_mask)
9698 tcg_gen_sub_i32(tmp, tmp, tmp2);
9700 gen_sub_CC(tmp, tmp, tmp2);
9701 tcg_temp_free_i32(tmp2);
9702 store_reg(s, rd, tmp);
9708 if (insn & (1 << 11)) {
9709 rd = (insn >> 8) & 7;
9710 /* load pc-relative. Bit 1 of PC is ignored. */
9711 val = s->pc + 2 + ((insn & 0xff) * 4);
9712 val &= ~(uint32_t)2;
9713 addr = tcg_temp_new_i32();
9714 tcg_gen_movi_i32(addr, val);
9715 tmp = tcg_temp_new_i32();
9716 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9717 tcg_temp_free_i32(addr);
9718 store_reg(s, rd, tmp);
9721 if (insn & (1 << 10)) {
9722 /* data processing extended or blx */
9723 rd = (insn & 7) | ((insn >> 4) & 8);
9724 rm = (insn >> 3) & 0xf;
9725 op = (insn >> 8) & 3;
9728 tmp = load_reg(s, rd);
9729 tmp2 = load_reg(s, rm);
9730 tcg_gen_add_i32(tmp, tmp, tmp2);
9731 tcg_temp_free_i32(tmp2);
9732 store_reg(s, rd, tmp);
9735 tmp = load_reg(s, rd);
9736 tmp2 = load_reg(s, rm);
9737 gen_sub_CC(tmp, tmp, tmp2);
9738 tcg_temp_free_i32(tmp2);
9739 tcg_temp_free_i32(tmp);
9741 case 2: /* mov/cpy */
9742 tmp = load_reg(s, rm);
9743 store_reg(s, rd, tmp);
9745 case 3:/* branch [and link] exchange thumb register */
9746 tmp = load_reg(s, rm);
9747 if (insn & (1 << 7)) {
9749 val = (uint32_t)s->pc | 1;
9750 tmp2 = tcg_temp_new_i32();
9751 tcg_gen_movi_i32(tmp2, val);
9752 store_reg(s, 14, tmp2);
9754 /* already thumb, no need to check */
9761 /* data processing register */
9763 rm = (insn >> 3) & 7;
9764 op = (insn >> 6) & 0xf;
9765 if (op == 2 || op == 3 || op == 4 || op == 7) {
9766 /* the shift/rotate ops want the operands backwards */
9775 if (op == 9) { /* neg */
9776 tmp = tcg_temp_new_i32();
9777 tcg_gen_movi_i32(tmp, 0);
9778 } else if (op != 0xf) { /* mvn doesn't read its first operand */
9779 tmp = load_reg(s, rd);
9781 TCGV_UNUSED_I32(tmp);
9784 tmp2 = load_reg(s, rm);
9787 tcg_gen_and_i32(tmp, tmp, tmp2);
9788 if (!s->condexec_mask)
9792 tcg_gen_xor_i32(tmp, tmp, tmp2);
9793 if (!s->condexec_mask)
9797 if (s->condexec_mask) {
9798 gen_shl(tmp2, tmp2, tmp);
9800 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9805 if (s->condexec_mask) {
9806 gen_shr(tmp2, tmp2, tmp);
9808 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9813 if (s->condexec_mask) {
9814 gen_sar(tmp2, tmp2, tmp);
9816 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9821 if (s->condexec_mask) {
9824 gen_adc_CC(tmp, tmp, tmp2);
9828 if (s->condexec_mask) {
9829 gen_sub_carry(tmp, tmp, tmp2);
9831 gen_sbc_CC(tmp, tmp, tmp2);
9835 if (s->condexec_mask) {
9836 tcg_gen_andi_i32(tmp, tmp, 0x1f);
9837 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9839 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9844 tcg_gen_and_i32(tmp, tmp, tmp2);
9849 if (s->condexec_mask)
9850 tcg_gen_neg_i32(tmp, tmp2);
9852 gen_sub_CC(tmp, tmp, tmp2);
9855 gen_sub_CC(tmp, tmp, tmp2);
9859 gen_add_CC(tmp, tmp, tmp2);
9863 tcg_gen_or_i32(tmp, tmp, tmp2);
9864 if (!s->condexec_mask)
9868 tcg_gen_mul_i32(tmp, tmp, tmp2);
9869 if (!s->condexec_mask)
9873 tcg_gen_andc_i32(tmp, tmp, tmp2);
9874 if (!s->condexec_mask)
9878 tcg_gen_not_i32(tmp2, tmp2);
9879 if (!s->condexec_mask)
9887 store_reg(s, rm, tmp2);
9889 tcg_temp_free_i32(tmp);
9891 store_reg(s, rd, tmp);
9892 tcg_temp_free_i32(tmp2);
9895 tcg_temp_free_i32(tmp);
9896 tcg_temp_free_i32(tmp2);
9901 /* load/store register offset. */
9903 rn = (insn >> 3) & 7;
9904 rm = (insn >> 6) & 7;
9905 op = (insn >> 9) & 7;
9906 addr = load_reg(s, rn);
9907 tmp = load_reg(s, rm);
9908 tcg_gen_add_i32(addr, addr, tmp);
9909 tcg_temp_free_i32(tmp);
9911 if (op < 3) { /* store */
9912 tmp = load_reg(s, rd);
9914 tmp = tcg_temp_new_i32();
9919 gen_aa32_st32(tmp, addr, IS_USER(s));
9922 gen_aa32_st16(tmp, addr, IS_USER(s));
9925 gen_aa32_st8(tmp, addr, IS_USER(s));
9928 gen_aa32_ld8s(tmp, addr, IS_USER(s));
9931 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9934 gen_aa32_ld16u(tmp, addr, IS_USER(s));
9937 gen_aa32_ld8u(tmp, addr, IS_USER(s));
9940 gen_aa32_ld16s(tmp, addr, IS_USER(s));
9943 if (op >= 3) { /* load */
9944 store_reg(s, rd, tmp);
9946 tcg_temp_free_i32(tmp);
9948 tcg_temp_free_i32(addr);
9952 /* load/store word immediate offset */
9954 rn = (insn >> 3) & 7;
9955 addr = load_reg(s, rn);
9956 val = (insn >> 4) & 0x7c;
9957 tcg_gen_addi_i32(addr, addr, val);
9959 if (insn & (1 << 11)) {
9961 tmp = tcg_temp_new_i32();
9962 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9963 store_reg(s, rd, tmp);
9966 tmp = load_reg(s, rd);
9967 gen_aa32_st32(tmp, addr, IS_USER(s));
9968 tcg_temp_free_i32(tmp);
9970 tcg_temp_free_i32(addr);
9974 /* load/store byte immediate offset */
9976 rn = (insn >> 3) & 7;
9977 addr = load_reg(s, rn);
9978 val = (insn >> 6) & 0x1f;
9979 tcg_gen_addi_i32(addr, addr, val);
9981 if (insn & (1 << 11)) {
9983 tmp = tcg_temp_new_i32();
9984 gen_aa32_ld8u(tmp, addr, IS_USER(s));
9985 store_reg(s, rd, tmp);
9988 tmp = load_reg(s, rd);
9989 gen_aa32_st8(tmp, addr, IS_USER(s));
9990 tcg_temp_free_i32(tmp);
9992 tcg_temp_free_i32(addr);
9996 /* load/store halfword immediate offset */
9998 rn = (insn >> 3) & 7;
9999 addr = load_reg(s, rn);
10000 val = (insn >> 5) & 0x3e;
10001 tcg_gen_addi_i32(addr, addr, val);
10003 if (insn & (1 << 11)) {
10005 tmp = tcg_temp_new_i32();
10006 gen_aa32_ld16u(tmp, addr, IS_USER(s));
10007 store_reg(s, rd, tmp);
10010 tmp = load_reg(s, rd);
10011 gen_aa32_st16(tmp, addr, IS_USER(s));
10012 tcg_temp_free_i32(tmp);
10014 tcg_temp_free_i32(addr);
10018 /* load/store from stack */
10019 rd = (insn >> 8) & 7;
10020 addr = load_reg(s, 13);
10021 val = (insn & 0xff) * 4;
10022 tcg_gen_addi_i32(addr, addr, val);
10024 if (insn & (1 << 11)) {
10026 tmp = tcg_temp_new_i32();
10027 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10028 store_reg(s, rd, tmp);
10031 tmp = load_reg(s, rd);
10032 gen_aa32_st32(tmp, addr, IS_USER(s));
10033 tcg_temp_free_i32(tmp);
10035 tcg_temp_free_i32(addr);
10039 /* add to high reg */
10040 rd = (insn >> 8) & 7;
10041 if (insn & (1 << 11)) {
10043 tmp = load_reg(s, 13);
10045 /* PC. bit 1 is ignored. */
10046 tmp = tcg_temp_new_i32();
10047 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10049 val = (insn & 0xff) * 4;
10050 tcg_gen_addi_i32(tmp, tmp, val);
10051 store_reg(s, rd, tmp);
10056 op = (insn >> 8) & 0xf;
10059 /* adjust stack pointer */
10060 tmp = load_reg(s, 13);
10061 val = (insn & 0x7f) * 4;
10062 if (insn & (1 << 7))
10063 val = -(int32_t)val;
10064 tcg_gen_addi_i32(tmp, tmp, val);
10065 store_reg(s, 13, tmp);
10068 case 2: /* sign/zero extend. */
10071 rm = (insn >> 3) & 7;
10072 tmp = load_reg(s, rm);
10073 switch ((insn >> 6) & 3) {
10074 case 0: gen_sxth(tmp); break;
10075 case 1: gen_sxtb(tmp); break;
10076 case 2: gen_uxth(tmp); break;
10077 case 3: gen_uxtb(tmp); break;
10079 store_reg(s, rd, tmp);
10081 case 4: case 5: case 0xc: case 0xd:
10083 addr = load_reg(s, 13);
10084 if (insn & (1 << 8))
10088 for (i = 0; i < 8; i++) {
10089 if (insn & (1 << i))
10092 if ((insn & (1 << 11)) == 0) {
10093 tcg_gen_addi_i32(addr, addr, -offset);
10095 for (i = 0; i < 8; i++) {
10096 if (insn & (1 << i)) {
10097 if (insn & (1 << 11)) {
10099 tmp = tcg_temp_new_i32();
10100 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10101 store_reg(s, i, tmp);
10104 tmp = load_reg(s, i);
10105 gen_aa32_st32(tmp, addr, IS_USER(s));
10106 tcg_temp_free_i32(tmp);
10108 /* advance to the next address. */
10109 tcg_gen_addi_i32(addr, addr, 4);
10112 TCGV_UNUSED_I32(tmp);
10113 if (insn & (1 << 8)) {
10114 if (insn & (1 << 11)) {
10116 tmp = tcg_temp_new_i32();
10117 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10118 /* don't set the pc until the rest of the instruction
10122 tmp = load_reg(s, 14);
10123 gen_aa32_st32(tmp, addr, IS_USER(s));
10124 tcg_temp_free_i32(tmp);
10126 tcg_gen_addi_i32(addr, addr, 4);
10128 if ((insn & (1 << 11)) == 0) {
10129 tcg_gen_addi_i32(addr, addr, -offset);
10131 /* write back the new stack pointer */
10132 store_reg(s, 13, addr);
10133 /* set the new PC value */
10134 if ((insn & 0x0900) == 0x0900) {
10135 store_reg_from_load(env, s, 15, tmp);
10139 case 1: case 3: case 9: case 11: /* czb */
10141 tmp = load_reg(s, rm);
10142 s->condlabel = gen_new_label();
10144 if (insn & (1 << 11))
10145 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10147 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10148 tcg_temp_free_i32(tmp);
10149 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10150 val = (uint32_t)s->pc + 2;
10155 case 15: /* IT, nop-hint. */
10156 if ((insn & 0xf) == 0) {
10157 gen_nop_hint(s, (insn >> 4) & 0xf);
10161 s->condexec_cond = (insn >> 4) & 0xe;
10162 s->condexec_mask = insn & 0x1f;
10163 /* No actual code generated for this insn, just setup state. */
10166 case 0xe: /* bkpt */
10168 gen_exception_insn(s, 2, EXCP_BKPT);
10171 case 0xa: /* rev */
10173 rn = (insn >> 3) & 0x7;
10175 tmp = load_reg(s, rn);
10176 switch ((insn >> 6) & 3) {
10177 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10178 case 1: gen_rev16(tmp); break;
10179 case 3: gen_revsh(tmp); break;
10180 default: goto illegal_op;
10182 store_reg(s, rd, tmp);
10186 switch ((insn >> 5) & 7) {
10190 if (((insn >> 3) & 1) != s->bswap_code) {
10191 /* Dynamic endianness switching not implemented. */
10192 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10203 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10206 addr = tcg_const_i32(19);
10207 gen_helper_v7m_msr(cpu_env, addr, tmp);
10208 tcg_temp_free_i32(addr);
10212 addr = tcg_const_i32(16);
10213 gen_helper_v7m_msr(cpu_env, addr, tmp);
10214 tcg_temp_free_i32(addr);
10216 tcg_temp_free_i32(tmp);
10219 if (insn & (1 << 4)) {
10220 shift = CPSR_A | CPSR_I | CPSR_F;
10224 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10239 /* load/store multiple */
10240 TCGv_i32 loaded_var;
10241 TCGV_UNUSED_I32(loaded_var);
10242 rn = (insn >> 8) & 0x7;
10243 addr = load_reg(s, rn);
10244 for (i = 0; i < 8; i++) {
10245 if (insn & (1 << i)) {
10246 if (insn & (1 << 11)) {
10248 tmp = tcg_temp_new_i32();
10249 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10253 store_reg(s, i, tmp);
10257 tmp = load_reg(s, i);
10258 gen_aa32_st32(tmp, addr, IS_USER(s));
10259 tcg_temp_free_i32(tmp);
10261 /* advance to the next address */
10262 tcg_gen_addi_i32(addr, addr, 4);
10265 if ((insn & (1 << rn)) == 0) {
10266 /* base reg not in list: base register writeback */
10267 store_reg(s, rn, addr);
10269 /* base reg in list: if load, complete it now */
10270 if (insn & (1 << 11)) {
10271 store_reg(s, rn, loaded_var);
10273 tcg_temp_free_i32(addr);
10278 /* conditional branch or swi */
10279 cond = (insn >> 8) & 0xf;
10285 gen_set_pc_im(s, s->pc);
10286 s->is_jmp = DISAS_SWI;
10289 /* generate a conditional jump to next instruction */
10290 s->condlabel = gen_new_label();
10291 arm_gen_test_cc(cond ^ 1, s->condlabel);
10294 /* jump to the offset */
10295 val = (uint32_t)s->pc + 2;
10296 offset = ((int32_t)insn << 24) >> 24;
10297 val += offset << 1;
10302 if (insn & (1 << 11)) {
10303 if (disas_thumb2_insn(env, s, insn))
10307 /* unconditional branch */
10308 val = (uint32_t)s->pc;
10309 offset = ((int32_t)insn << 21) >> 21;
10310 val += (offset << 1) + 2;
10315 if (disas_thumb2_insn(env, s, insn))
10321 gen_exception_insn(s, 4, EXCP_UDEF);
10325 gen_exception_insn(s, 2, EXCP_UDEF);
10328 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10329 basic block 'tb'. If search_pc is TRUE, also generate PC
10330 information for each intermediate instruction. */
10331 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10332 TranslationBlock *tb,
10335 CPUState *cs = CPU(cpu);
10336 CPUARMState *env = &cpu->env;
10337 DisasContext dc1, *dc = &dc1;
10339 uint16_t *gen_opc_end;
10341 target_ulong pc_start;
10342 target_ulong next_page_start;
10346 /* generate intermediate code */
10348 /* The A64 decoder has its own top level loop, because it doesn't need
10349 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10351 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10352 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10360 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10362 dc->is_jmp = DISAS_NEXT;
10364 dc->singlestep_enabled = cs->singlestep_enabled;
10368 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10369 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10370 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10371 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10372 #if !defined(CONFIG_USER_ONLY)
10373 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10375 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10376 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10377 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10378 dc->cp_regs = cpu->cp_regs;
10379 dc->current_pl = arm_current_pl(env);
10381 cpu_F0s = tcg_temp_new_i32();
10382 cpu_F1s = tcg_temp_new_i32();
10383 cpu_F0d = tcg_temp_new_i64();
10384 cpu_F1d = tcg_temp_new_i64();
10387 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10388 cpu_M0 = tcg_temp_new_i64();
10389 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10392 max_insns = tb->cflags & CF_COUNT_MASK;
10393 if (max_insns == 0)
10394 max_insns = CF_COUNT_MASK;
10398 tcg_clear_temp_count();
10400 /* A note on handling of the condexec (IT) bits:
10402 * We want to avoid the overhead of having to write the updated condexec
10403 * bits back to the CPUARMState for every instruction in an IT block. So:
10404 * (1) if the condexec bits are not already zero then we write
10405 * zero back into the CPUARMState now. This avoids complications trying
10406 * to do it at the end of the block. (For example if we don't do this
10407 * it's hard to identify whether we can safely skip writing condexec
10408 * at the end of the TB, which we definitely want to do for the case
10409 * where a TB doesn't do anything with the IT state at all.)
10410 * (2) if we are going to leave the TB then we call gen_set_condexec()
10411 * which will write the correct value into CPUARMState if zero is wrong.
10412 * This is done both for leaving the TB at the end, and for leaving
10413 * it because of an exception we know will happen, which is done in
10414 * gen_exception_insn(). The latter is necessary because we need to
10415 * leave the TB with the PC/IT state just prior to execution of the
10416 * instruction which caused the exception.
10417 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10418 * then the CPUARMState will be wrong and we need to reset it.
10419 * This is handled in the same way as restoration of the
10420 * PC in these situations: we will be called again with search_pc=1
10421 * and generate a mapping of the condexec bits for each PC in
10422 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10423 * this to restore the condexec bits.
10425 * Note that there are no instructions which can read the condexec
10426 * bits, and none which can write non-static values to them, so
10427 * we don't need to care about whether CPUARMState is correct in the
10431 /* Reset the conditional execution bits immediately. This avoids
10432 complications trying to do it at the end of the block. */
10433 if (dc->condexec_mask || dc->condexec_cond)
10435 TCGv_i32 tmp = tcg_temp_new_i32();
10436 tcg_gen_movi_i32(tmp, 0);
10437 store_cpu_field(tmp, condexec_bits);
10440 #ifdef CONFIG_USER_ONLY
10441 /* Intercept jump to the magic kernel page. */
10442 if (dc->pc >= 0xffff0000) {
10443 /* We always get here via a jump, so know we are not in a
10444 conditional execution block. */
10445 gen_exception(EXCP_KERNEL_TRAP);
10446 dc->is_jmp = DISAS_UPDATE;
10450 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10451 /* We always get here via a jump, so know we are not in a
10452 conditional execution block. */
10453 gen_exception(EXCP_EXCEPTION_EXIT);
10454 dc->is_jmp = DISAS_UPDATE;
10459 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10460 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10461 if (bp->pc == dc->pc) {
10462 gen_exception_insn(dc, 0, EXCP_DEBUG);
10463 /* Advance PC so that clearing the breakpoint will
10464 invalidate this TB. */
10466 goto done_generating;
10471 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10475 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10477 tcg_ctx.gen_opc_pc[lj] = dc->pc;
10478 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10479 tcg_ctx.gen_opc_instr_start[lj] = 1;
10480 tcg_ctx.gen_opc_icount[lj] = num_insns;
10483 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10486 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10487 tcg_gen_debug_insn_start(dc->pc);
10491 disas_thumb_insn(env, dc);
10492 if (dc->condexec_mask) {
10493 dc->condexec_cond = (dc->condexec_cond & 0xe)
10494 | ((dc->condexec_mask >> 4) & 1);
10495 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10496 if (dc->condexec_mask == 0) {
10497 dc->condexec_cond = 0;
10501 disas_arm_insn(env, dc);
10504 if (dc->condjmp && !dc->is_jmp) {
10505 gen_set_label(dc->condlabel);
10509 if (tcg_check_temp_count()) {
10510 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10514 /* Translation stops when a conditional branch is encountered.
10515 * Otherwise the subsequent code could get translated several times.
10516 * Also stop translation when a page boundary is reached. This
10517 * ensures prefetch aborts occur at the right place. */
10519 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10520 !cs->singlestep_enabled &&
10522 dc->pc < next_page_start &&
10523 num_insns < max_insns);
10525 if (tb->cflags & CF_LAST_IO) {
10527 /* FIXME: This can theoretically happen with self-modifying
10529 cpu_abort(env, "IO on conditional branch instruction");
10534 /* At this stage dc->condjmp will only be set when the skipped
10535 instruction was a conditional branch or trap, and the PC has
10536 already been written. */
10537 if (unlikely(cs->singlestep_enabled)) {
10538 /* Make sure the pc is updated, and raise a debug exception. */
10540 gen_set_condexec(dc);
10541 if (dc->is_jmp == DISAS_SWI) {
10542 gen_exception(EXCP_SWI);
10544 gen_exception(EXCP_DEBUG);
10546 gen_set_label(dc->condlabel);
10548 if (dc->condjmp || !dc->is_jmp) {
10549 gen_set_pc_im(dc, dc->pc);
10552 gen_set_condexec(dc);
10553 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10554 gen_exception(EXCP_SWI);
10556 /* FIXME: Single stepping a WFI insn will not halt
10558 gen_exception(EXCP_DEBUG);
10561 /* While branches must always occur at the end of an IT block,
10562 there are a few other things that can cause us to terminate
10563 the TB in the middle of an IT block:
10564 - Exception generating instructions (bkpt, swi, undefined).
10566 - Hardware watchpoints.
10567 Hardware breakpoints have already been handled and skip this code.
10569 gen_set_condexec(dc);
10570 switch(dc->is_jmp) {
10572 gen_goto_tb(dc, 1, dc->pc);
10577 /* indicate that the hash table must be used to find the next TB */
10578 tcg_gen_exit_tb(0);
10580 case DISAS_TB_JUMP:
10581 /* nothing more to generate */
10584 gen_helper_wfi(cpu_env);
10587 gen_exception(EXCP_SWI);
10591 gen_set_label(dc->condlabel);
10592 gen_set_condexec(dc);
10593 gen_goto_tb(dc, 1, dc->pc);
10599 gen_tb_end(tb, num_insns);
10600 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
10603 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10604 qemu_log("----------------\n");
10605 qemu_log("IN: %s\n", lookup_symbol(pc_start));
10606 log_target_disas(env, pc_start, dc->pc - pc_start,
10607 dc->thumb | (dc->bswap_code << 1));
10612 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10615 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10617 tb->size = dc->pc - pc_start;
10618 tb->icount = num_insns;
10622 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10624 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10627 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10629 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10632 static const char *cpu_mode_names[16] = {
10633 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10634 "???", "???", "???", "und", "???", "???", "???", "sys"
10637 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10640 ARMCPU *cpu = ARM_CPU(cs);
10641 CPUARMState *env = &cpu->env;
10645 for(i=0;i<16;i++) {
10646 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10648 cpu_fprintf(f, "\n");
10650 cpu_fprintf(f, " ");
10652 psr = cpsr_read(env);
10653 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10655 psr & (1 << 31) ? 'N' : '-',
10656 psr & (1 << 30) ? 'Z' : '-',
10657 psr & (1 << 29) ? 'C' : '-',
10658 psr & (1 << 28) ? 'V' : '-',
10659 psr & CPSR_T ? 'T' : 'A',
10660 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10662 if (flags & CPU_DUMP_FPU) {
10663 int numvfpregs = 0;
10664 if (arm_feature(env, ARM_FEATURE_VFP)) {
10667 if (arm_feature(env, ARM_FEATURE_VFP3)) {
10670 for (i = 0; i < numvfpregs; i++) {
10671 uint64_t v = float64_val(env->vfp.regs[i]);
10672 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10673 i * 2, (uint32_t)v,
10674 i * 2 + 1, (uint32_t)(v >> 32),
10677 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10681 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10684 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10685 env->condexec_bits = 0;
10687 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10688 env->condexec_bits = gen_opc_condexec_bits[pc_pos];