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 "internals.h"
29 #include "disas/disas.h"
32 #include "qemu/bitops.h"
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.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_internal(int excp)
187 TCGv_i32 tcg_excp = tcg_const_i32(excp);
189 assert(excp_is_internal(excp));
190 gen_helper_exception_internal(cpu_env, tcg_excp);
191 tcg_temp_free_i32(tcg_excp);
194 static void gen_exception(int excp, uint32_t syndrome)
196 TCGv_i32 tcg_excp = tcg_const_i32(excp);
197 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
199 gen_helper_exception_with_syndrome(cpu_env, tcg_excp, tcg_syn);
200 tcg_temp_free_i32(tcg_syn);
201 tcg_temp_free_i32(tcg_excp);
204 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
206 TCGv_i32 tmp1 = tcg_temp_new_i32();
207 TCGv_i32 tmp2 = tcg_temp_new_i32();
208 tcg_gen_ext16s_i32(tmp1, a);
209 tcg_gen_ext16s_i32(tmp2, b);
210 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
211 tcg_temp_free_i32(tmp2);
212 tcg_gen_sari_i32(a, a, 16);
213 tcg_gen_sari_i32(b, b, 16);
214 tcg_gen_mul_i32(b, b, a);
215 tcg_gen_mov_i32(a, tmp1);
216 tcg_temp_free_i32(tmp1);
219 /* Byteswap each halfword. */
220 static void gen_rev16(TCGv_i32 var)
222 TCGv_i32 tmp = tcg_temp_new_i32();
223 tcg_gen_shri_i32(tmp, var, 8);
224 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
225 tcg_gen_shli_i32(var, var, 8);
226 tcg_gen_andi_i32(var, var, 0xff00ff00);
227 tcg_gen_or_i32(var, var, tmp);
228 tcg_temp_free_i32(tmp);
231 /* Byteswap low halfword and sign extend. */
232 static void gen_revsh(TCGv_i32 var)
234 tcg_gen_ext16u_i32(var, var);
235 tcg_gen_bswap16_i32(var, var);
236 tcg_gen_ext16s_i32(var, var);
239 /* Unsigned bitfield extract. */
240 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
243 tcg_gen_shri_i32(var, var, shift);
244 tcg_gen_andi_i32(var, var, mask);
247 /* Signed bitfield extract. */
248 static void gen_sbfx(TCGv_i32 var, int shift, int width)
253 tcg_gen_sari_i32(var, var, shift);
254 if (shift + width < 32) {
255 signbit = 1u << (width - 1);
256 tcg_gen_andi_i32(var, var, (1u << width) - 1);
257 tcg_gen_xori_i32(var, var, signbit);
258 tcg_gen_subi_i32(var, var, signbit);
262 /* Return (b << 32) + a. Mark inputs as dead */
263 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
265 TCGv_i64 tmp64 = tcg_temp_new_i64();
267 tcg_gen_extu_i32_i64(tmp64, b);
268 tcg_temp_free_i32(b);
269 tcg_gen_shli_i64(tmp64, tmp64, 32);
270 tcg_gen_add_i64(a, tmp64, a);
272 tcg_temp_free_i64(tmp64);
276 /* Return (b << 32) - a. Mark inputs as dead. */
277 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
279 TCGv_i64 tmp64 = tcg_temp_new_i64();
281 tcg_gen_extu_i32_i64(tmp64, b);
282 tcg_temp_free_i32(b);
283 tcg_gen_shli_i64(tmp64, tmp64, 32);
284 tcg_gen_sub_i64(a, tmp64, a);
286 tcg_temp_free_i64(tmp64);
290 /* 32x32->64 multiply. Marks inputs as dead. */
291 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
293 TCGv_i32 lo = tcg_temp_new_i32();
294 TCGv_i32 hi = tcg_temp_new_i32();
297 tcg_gen_mulu2_i32(lo, hi, a, b);
298 tcg_temp_free_i32(a);
299 tcg_temp_free_i32(b);
301 ret = tcg_temp_new_i64();
302 tcg_gen_concat_i32_i64(ret, lo, hi);
303 tcg_temp_free_i32(lo);
304 tcg_temp_free_i32(hi);
309 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
311 TCGv_i32 lo = tcg_temp_new_i32();
312 TCGv_i32 hi = tcg_temp_new_i32();
315 tcg_gen_muls2_i32(lo, hi, a, b);
316 tcg_temp_free_i32(a);
317 tcg_temp_free_i32(b);
319 ret = tcg_temp_new_i64();
320 tcg_gen_concat_i32_i64(ret, lo, hi);
321 tcg_temp_free_i32(lo);
322 tcg_temp_free_i32(hi);
327 /* Swap low and high halfwords. */
328 static void gen_swap_half(TCGv_i32 var)
330 TCGv_i32 tmp = tcg_temp_new_i32();
331 tcg_gen_shri_i32(tmp, var, 16);
332 tcg_gen_shli_i32(var, var, 16);
333 tcg_gen_or_i32(var, var, tmp);
334 tcg_temp_free_i32(tmp);
337 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
338 tmp = (t0 ^ t1) & 0x8000;
341 t0 = (t0 + t1) ^ tmp;
344 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
346 TCGv_i32 tmp = tcg_temp_new_i32();
347 tcg_gen_xor_i32(tmp, t0, t1);
348 tcg_gen_andi_i32(tmp, tmp, 0x8000);
349 tcg_gen_andi_i32(t0, t0, ~0x8000);
350 tcg_gen_andi_i32(t1, t1, ~0x8000);
351 tcg_gen_add_i32(t0, t0, t1);
352 tcg_gen_xor_i32(t0, t0, tmp);
353 tcg_temp_free_i32(tmp);
354 tcg_temp_free_i32(t1);
357 /* Set CF to the top bit of var. */
358 static void gen_set_CF_bit31(TCGv_i32 var)
360 tcg_gen_shri_i32(cpu_CF, var, 31);
363 /* Set N and Z flags from var. */
364 static inline void gen_logic_CC(TCGv_i32 var)
366 tcg_gen_mov_i32(cpu_NF, var);
367 tcg_gen_mov_i32(cpu_ZF, var);
371 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
373 tcg_gen_add_i32(t0, t0, t1);
374 tcg_gen_add_i32(t0, t0, cpu_CF);
377 /* dest = T0 + T1 + CF. */
378 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
380 tcg_gen_add_i32(dest, t0, t1);
381 tcg_gen_add_i32(dest, dest, cpu_CF);
384 /* dest = T0 - T1 + CF - 1. */
385 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
387 tcg_gen_sub_i32(dest, t0, t1);
388 tcg_gen_add_i32(dest, dest, cpu_CF);
389 tcg_gen_subi_i32(dest, dest, 1);
392 /* dest = T0 + T1. Compute C, N, V and Z flags */
393 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
395 TCGv_i32 tmp = tcg_temp_new_i32();
396 tcg_gen_movi_i32(tmp, 0);
397 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
398 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
399 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
400 tcg_gen_xor_i32(tmp, t0, t1);
401 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
402 tcg_temp_free_i32(tmp);
403 tcg_gen_mov_i32(dest, cpu_NF);
406 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
407 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
409 TCGv_i32 tmp = tcg_temp_new_i32();
410 if (TCG_TARGET_HAS_add2_i32) {
411 tcg_gen_movi_i32(tmp, 0);
412 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
413 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
415 TCGv_i64 q0 = tcg_temp_new_i64();
416 TCGv_i64 q1 = tcg_temp_new_i64();
417 tcg_gen_extu_i32_i64(q0, t0);
418 tcg_gen_extu_i32_i64(q1, t1);
419 tcg_gen_add_i64(q0, q0, q1);
420 tcg_gen_extu_i32_i64(q1, cpu_CF);
421 tcg_gen_add_i64(q0, q0, q1);
422 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
423 tcg_temp_free_i64(q0);
424 tcg_temp_free_i64(q1);
426 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
427 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
428 tcg_gen_xor_i32(tmp, t0, t1);
429 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
430 tcg_temp_free_i32(tmp);
431 tcg_gen_mov_i32(dest, cpu_NF);
434 /* dest = T0 - T1. Compute C, N, V and Z flags */
435 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
438 tcg_gen_sub_i32(cpu_NF, t0, t1);
439 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
440 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
441 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
442 tmp = tcg_temp_new_i32();
443 tcg_gen_xor_i32(tmp, t0, t1);
444 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
445 tcg_temp_free_i32(tmp);
446 tcg_gen_mov_i32(dest, cpu_NF);
449 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
450 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
452 TCGv_i32 tmp = tcg_temp_new_i32();
453 tcg_gen_not_i32(tmp, t1);
454 gen_adc_CC(dest, t0, tmp);
455 tcg_temp_free_i32(tmp);
458 #define GEN_SHIFT(name) \
459 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
461 TCGv_i32 tmp1, tmp2, tmp3; \
462 tmp1 = tcg_temp_new_i32(); \
463 tcg_gen_andi_i32(tmp1, t1, 0xff); \
464 tmp2 = tcg_const_i32(0); \
465 tmp3 = tcg_const_i32(0x1f); \
466 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
467 tcg_temp_free_i32(tmp3); \
468 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
469 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
470 tcg_temp_free_i32(tmp2); \
471 tcg_temp_free_i32(tmp1); \
477 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
480 tmp1 = tcg_temp_new_i32();
481 tcg_gen_andi_i32(tmp1, t1, 0xff);
482 tmp2 = tcg_const_i32(0x1f);
483 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
484 tcg_temp_free_i32(tmp2);
485 tcg_gen_sar_i32(dest, t0, tmp1);
486 tcg_temp_free_i32(tmp1);
489 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
491 TCGv_i32 c0 = tcg_const_i32(0);
492 TCGv_i32 tmp = tcg_temp_new_i32();
493 tcg_gen_neg_i32(tmp, src);
494 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
495 tcg_temp_free_i32(c0);
496 tcg_temp_free_i32(tmp);
499 static void shifter_out_im(TCGv_i32 var, int shift)
502 tcg_gen_andi_i32(cpu_CF, var, 1);
504 tcg_gen_shri_i32(cpu_CF, var, shift);
506 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
511 /* Shift by immediate. Includes special handling for shift == 0. */
512 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
513 int shift, int flags)
519 shifter_out_im(var, 32 - shift);
520 tcg_gen_shli_i32(var, var, shift);
526 tcg_gen_shri_i32(cpu_CF, var, 31);
528 tcg_gen_movi_i32(var, 0);
531 shifter_out_im(var, shift - 1);
532 tcg_gen_shri_i32(var, var, shift);
539 shifter_out_im(var, shift - 1);
542 tcg_gen_sari_i32(var, var, shift);
544 case 3: /* ROR/RRX */
547 shifter_out_im(var, shift - 1);
548 tcg_gen_rotri_i32(var, var, shift); break;
550 TCGv_i32 tmp = tcg_temp_new_i32();
551 tcg_gen_shli_i32(tmp, cpu_CF, 31);
553 shifter_out_im(var, 0);
554 tcg_gen_shri_i32(var, var, 1);
555 tcg_gen_or_i32(var, var, tmp);
556 tcg_temp_free_i32(tmp);
561 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
562 TCGv_i32 shift, int flags)
566 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
567 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
568 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
569 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
574 gen_shl(var, var, shift);
577 gen_shr(var, var, shift);
580 gen_sar(var, var, shift);
582 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
583 tcg_gen_rotr_i32(var, var, shift); break;
586 tcg_temp_free_i32(shift);
589 #define PAS_OP(pfx) \
591 case 0: gen_pas_helper(glue(pfx,add16)); break; \
592 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
593 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
594 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
595 case 4: gen_pas_helper(glue(pfx,add8)); break; \
596 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
598 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
603 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
605 tmp = tcg_temp_new_ptr();
606 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
608 tcg_temp_free_ptr(tmp);
611 tmp = tcg_temp_new_ptr();
612 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
614 tcg_temp_free_ptr(tmp);
616 #undef gen_pas_helper
617 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
630 #undef gen_pas_helper
635 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
636 #define PAS_OP(pfx) \
638 case 0: gen_pas_helper(glue(pfx,add8)); break; \
639 case 1: gen_pas_helper(glue(pfx,add16)); break; \
640 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
641 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
642 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
643 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
645 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
650 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
652 tmp = tcg_temp_new_ptr();
653 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
655 tcg_temp_free_ptr(tmp);
658 tmp = tcg_temp_new_ptr();
659 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
661 tcg_temp_free_ptr(tmp);
663 #undef gen_pas_helper
664 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
677 #undef gen_pas_helper
683 * generate a conditional branch based on ARM condition code cc.
684 * This is common between ARM and Aarch64 targets.
686 void arm_gen_test_cc(int cc, int label)
693 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
696 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
699 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
702 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
705 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
708 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
711 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
714 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
716 case 8: /* hi: C && !Z */
717 inv = gen_new_label();
718 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
719 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
722 case 9: /* ls: !C || Z */
723 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
724 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
726 case 10: /* ge: N == V -> N ^ V == 0 */
727 tmp = tcg_temp_new_i32();
728 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
729 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
730 tcg_temp_free_i32(tmp);
732 case 11: /* lt: N != V -> N ^ V != 0 */
733 tmp = tcg_temp_new_i32();
734 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
735 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
736 tcg_temp_free_i32(tmp);
738 case 12: /* gt: !Z && N == V */
739 inv = gen_new_label();
740 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
741 tmp = tcg_temp_new_i32();
742 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
743 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
744 tcg_temp_free_i32(tmp);
747 case 13: /* le: Z || N != V */
748 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
749 tmp = tcg_temp_new_i32();
750 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
751 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
752 tcg_temp_free_i32(tmp);
755 fprintf(stderr, "Bad condition code 0x%x\n", cc);
760 static const uint8_t table_logic_cc[16] = {
779 /* Set PC and Thumb state from an immediate address. */
780 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
784 s->is_jmp = DISAS_UPDATE;
785 if (s->thumb != (addr & 1)) {
786 tmp = tcg_temp_new_i32();
787 tcg_gen_movi_i32(tmp, addr & 1);
788 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
789 tcg_temp_free_i32(tmp);
791 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
794 /* Set PC and Thumb state from var. var is marked as dead. */
795 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
797 s->is_jmp = DISAS_UPDATE;
798 tcg_gen_andi_i32(cpu_R[15], var, ~1);
799 tcg_gen_andi_i32(var, var, 1);
800 store_cpu_field(var, thumb);
803 /* Variant of store_reg which uses branch&exchange logic when storing
804 to r15 in ARM architecture v7 and above. The source must be a temporary
805 and will be marked as dead. */
806 static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
807 int reg, TCGv_i32 var)
809 if (reg == 15 && ENABLE_ARCH_7) {
812 store_reg(s, reg, var);
816 /* Variant of store_reg which uses branch&exchange logic when storing
817 * to r15 in ARM architecture v5T and above. This is used for storing
818 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
819 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
820 static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
821 int reg, TCGv_i32 var)
823 if (reg == 15 && ENABLE_ARCH_5) {
826 store_reg(s, reg, var);
830 /* Abstractions of "generate code to do a guest load/store for
831 * AArch32", where a vaddr is always 32 bits (and is zero
832 * extended if we're a 64 bit core) and data is also
833 * 32 bits unless specifically doing a 64 bit access.
834 * These functions work like tcg_gen_qemu_{ld,st}* except
835 * that the address argument is TCGv_i32 rather than TCGv.
837 #if TARGET_LONG_BITS == 32
839 #define DO_GEN_LD(SUFF, OPC) \
840 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
842 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
845 #define DO_GEN_ST(SUFF, OPC) \
846 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
848 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
851 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
853 tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
856 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
858 tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
863 #define DO_GEN_LD(SUFF, OPC) \
864 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
866 TCGv addr64 = tcg_temp_new(); \
867 tcg_gen_extu_i32_i64(addr64, addr); \
868 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
869 tcg_temp_free(addr64); \
872 #define DO_GEN_ST(SUFF, OPC) \
873 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
875 TCGv addr64 = tcg_temp_new(); \
876 tcg_gen_extu_i32_i64(addr64, addr); \
877 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
878 tcg_temp_free(addr64); \
881 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
883 TCGv addr64 = tcg_temp_new();
884 tcg_gen_extu_i32_i64(addr64, addr);
885 tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
886 tcg_temp_free(addr64);
889 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
891 TCGv addr64 = tcg_temp_new();
892 tcg_gen_extu_i32_i64(addr64, addr);
893 tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
894 tcg_temp_free(addr64);
901 DO_GEN_LD(16s, MO_TESW)
902 DO_GEN_LD(16u, MO_TEUW)
903 DO_GEN_LD(32u, MO_TEUL)
905 DO_GEN_ST(16, MO_TEUW)
906 DO_GEN_ST(32, MO_TEUL)
908 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
910 tcg_gen_movi_i32(cpu_R[15], val);
914 gen_set_condexec (DisasContext *s)
916 if (s->condexec_mask) {
917 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
918 TCGv_i32 tmp = tcg_temp_new_i32();
919 tcg_gen_movi_i32(tmp, val);
920 store_cpu_field(tmp, condexec_bits);
924 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
927 gen_set_pc_im(s, s->pc - offset);
928 gen_exception_internal(excp);
929 s->is_jmp = DISAS_JUMP;
932 static void gen_exception_insn(DisasContext *s, int offset, int excp, int syn)
935 gen_set_pc_im(s, s->pc - offset);
936 gen_exception(excp, syn);
937 s->is_jmp = DISAS_JUMP;
940 /* Force a TB lookup after an instruction that changes the CPU state. */
941 static inline void gen_lookup_tb(DisasContext *s)
943 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
944 s->is_jmp = DISAS_UPDATE;
947 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
950 int val, rm, shift, shiftop;
953 if (!(insn & (1 << 25))) {
956 if (!(insn & (1 << 23)))
959 tcg_gen_addi_i32(var, var, val);
963 shift = (insn >> 7) & 0x1f;
964 shiftop = (insn >> 5) & 3;
965 offset = load_reg(s, rm);
966 gen_arm_shift_im(offset, shiftop, shift, 0);
967 if (!(insn & (1 << 23)))
968 tcg_gen_sub_i32(var, var, offset);
970 tcg_gen_add_i32(var, var, offset);
971 tcg_temp_free_i32(offset);
975 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
976 int extra, TCGv_i32 var)
981 if (insn & (1 << 22)) {
983 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
984 if (!(insn & (1 << 23)))
988 tcg_gen_addi_i32(var, var, val);
992 tcg_gen_addi_i32(var, var, extra);
994 offset = load_reg(s, rm);
995 if (!(insn & (1 << 23)))
996 tcg_gen_sub_i32(var, var, offset);
998 tcg_gen_add_i32(var, var, offset);
999 tcg_temp_free_i32(offset);
1003 static TCGv_ptr get_fpstatus_ptr(int neon)
1005 TCGv_ptr statusptr = tcg_temp_new_ptr();
1008 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1010 offset = offsetof(CPUARMState, vfp.fp_status);
1012 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1016 #define VFP_OP2(name) \
1017 static inline void gen_vfp_##name(int dp) \
1019 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1021 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1023 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1025 tcg_temp_free_ptr(fpst); \
1035 static inline void gen_vfp_F1_mul(int dp)
1037 /* Like gen_vfp_mul() but put result in F1 */
1038 TCGv_ptr fpst = get_fpstatus_ptr(0);
1040 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1042 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1044 tcg_temp_free_ptr(fpst);
1047 static inline void gen_vfp_F1_neg(int dp)
1049 /* Like gen_vfp_neg() but put result in F1 */
1051 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1053 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1057 static inline void gen_vfp_abs(int dp)
1060 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1062 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1065 static inline void gen_vfp_neg(int dp)
1068 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1070 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1073 static inline void gen_vfp_sqrt(int dp)
1076 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1078 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1081 static inline void gen_vfp_cmp(int dp)
1084 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1086 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1089 static inline void gen_vfp_cmpe(int dp)
1092 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1094 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1097 static inline void gen_vfp_F1_ld0(int dp)
1100 tcg_gen_movi_i64(cpu_F1d, 0);
1102 tcg_gen_movi_i32(cpu_F1s, 0);
1105 #define VFP_GEN_ITOF(name) \
1106 static inline void gen_vfp_##name(int dp, int neon) \
1108 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1110 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1112 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1114 tcg_temp_free_ptr(statusptr); \
1121 #define VFP_GEN_FTOI(name) \
1122 static inline void gen_vfp_##name(int dp, int neon) \
1124 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1126 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1128 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1130 tcg_temp_free_ptr(statusptr); \
1139 #define VFP_GEN_FIX(name, round) \
1140 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1142 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1143 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1145 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1148 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1151 tcg_temp_free_i32(tmp_shift); \
1152 tcg_temp_free_ptr(statusptr); \
1154 VFP_GEN_FIX(tosh, _round_to_zero)
1155 VFP_GEN_FIX(tosl, _round_to_zero)
1156 VFP_GEN_FIX(touh, _round_to_zero)
1157 VFP_GEN_FIX(toul, _round_to_zero)
1164 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1167 gen_aa32_ld64(cpu_F0d, addr, get_mem_index(s));
1169 gen_aa32_ld32u(cpu_F0s, addr, get_mem_index(s));
1173 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1176 gen_aa32_st64(cpu_F0d, addr, get_mem_index(s));
1178 gen_aa32_st32(cpu_F0s, addr, get_mem_index(s));
1183 vfp_reg_offset (int dp, int reg)
1186 return offsetof(CPUARMState, vfp.regs[reg]);
1188 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1189 + offsetof(CPU_DoubleU, l.upper);
1191 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1192 + offsetof(CPU_DoubleU, l.lower);
1196 /* Return the offset of a 32-bit piece of a NEON register.
1197 zero is the least significant end of the register. */
1199 neon_reg_offset (int reg, int n)
1203 return vfp_reg_offset(0, sreg);
1206 static TCGv_i32 neon_load_reg(int reg, int pass)
1208 TCGv_i32 tmp = tcg_temp_new_i32();
1209 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1213 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1215 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1216 tcg_temp_free_i32(var);
1219 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1221 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1224 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1226 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1229 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1230 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1231 #define tcg_gen_st_f32 tcg_gen_st_i32
1232 #define tcg_gen_st_f64 tcg_gen_st_i64
1234 static inline void gen_mov_F0_vreg(int dp, int reg)
1237 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1239 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1242 static inline void gen_mov_F1_vreg(int dp, int reg)
1245 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1247 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1250 static inline void gen_mov_vreg_F0(int dp, int reg)
1253 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1255 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1258 #define ARM_CP_RW_BIT (1 << 20)
1260 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1262 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1265 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1267 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1270 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1272 TCGv_i32 var = tcg_temp_new_i32();
1273 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1277 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1279 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1280 tcg_temp_free_i32(var);
1283 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1285 iwmmxt_store_reg(cpu_M0, rn);
1288 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1290 iwmmxt_load_reg(cpu_M0, rn);
1293 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1295 iwmmxt_load_reg(cpu_V1, rn);
1296 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1299 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1301 iwmmxt_load_reg(cpu_V1, rn);
1302 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1305 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1307 iwmmxt_load_reg(cpu_V1, rn);
1308 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1311 #define IWMMXT_OP(name) \
1312 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1314 iwmmxt_load_reg(cpu_V1, rn); \
1315 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1318 #define IWMMXT_OP_ENV(name) \
1319 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1321 iwmmxt_load_reg(cpu_V1, rn); \
1322 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1325 #define IWMMXT_OP_ENV_SIZE(name) \
1326 IWMMXT_OP_ENV(name##b) \
1327 IWMMXT_OP_ENV(name##w) \
1328 IWMMXT_OP_ENV(name##l)
1330 #define IWMMXT_OP_ENV1(name) \
1331 static inline void gen_op_iwmmxt_##name##_M0(void) \
1333 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1347 IWMMXT_OP_ENV_SIZE(unpackl)
1348 IWMMXT_OP_ENV_SIZE(unpackh)
1350 IWMMXT_OP_ENV1(unpacklub)
1351 IWMMXT_OP_ENV1(unpackluw)
1352 IWMMXT_OP_ENV1(unpacklul)
1353 IWMMXT_OP_ENV1(unpackhub)
1354 IWMMXT_OP_ENV1(unpackhuw)
1355 IWMMXT_OP_ENV1(unpackhul)
1356 IWMMXT_OP_ENV1(unpacklsb)
1357 IWMMXT_OP_ENV1(unpacklsw)
1358 IWMMXT_OP_ENV1(unpacklsl)
1359 IWMMXT_OP_ENV1(unpackhsb)
1360 IWMMXT_OP_ENV1(unpackhsw)
1361 IWMMXT_OP_ENV1(unpackhsl)
1363 IWMMXT_OP_ENV_SIZE(cmpeq)
1364 IWMMXT_OP_ENV_SIZE(cmpgtu)
1365 IWMMXT_OP_ENV_SIZE(cmpgts)
1367 IWMMXT_OP_ENV_SIZE(mins)
1368 IWMMXT_OP_ENV_SIZE(minu)
1369 IWMMXT_OP_ENV_SIZE(maxs)
1370 IWMMXT_OP_ENV_SIZE(maxu)
1372 IWMMXT_OP_ENV_SIZE(subn)
1373 IWMMXT_OP_ENV_SIZE(addn)
1374 IWMMXT_OP_ENV_SIZE(subu)
1375 IWMMXT_OP_ENV_SIZE(addu)
1376 IWMMXT_OP_ENV_SIZE(subs)
1377 IWMMXT_OP_ENV_SIZE(adds)
1379 IWMMXT_OP_ENV(avgb0)
1380 IWMMXT_OP_ENV(avgb1)
1381 IWMMXT_OP_ENV(avgw0)
1382 IWMMXT_OP_ENV(avgw1)
1386 IWMMXT_OP_ENV(packuw)
1387 IWMMXT_OP_ENV(packul)
1388 IWMMXT_OP_ENV(packuq)
1389 IWMMXT_OP_ENV(packsw)
1390 IWMMXT_OP_ENV(packsl)
1391 IWMMXT_OP_ENV(packsq)
1393 static void gen_op_iwmmxt_set_mup(void)
1396 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1397 tcg_gen_ori_i32(tmp, tmp, 2);
1398 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1401 static void gen_op_iwmmxt_set_cup(void)
1404 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1405 tcg_gen_ori_i32(tmp, tmp, 1);
1406 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1409 static void gen_op_iwmmxt_setpsr_nz(void)
1411 TCGv_i32 tmp = tcg_temp_new_i32();
1412 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1413 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1416 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1418 iwmmxt_load_reg(cpu_V1, rn);
1419 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1420 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1423 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1430 rd = (insn >> 16) & 0xf;
1431 tmp = load_reg(s, rd);
1433 offset = (insn & 0xff) << ((insn >> 7) & 2);
1434 if (insn & (1 << 24)) {
1436 if (insn & (1 << 23))
1437 tcg_gen_addi_i32(tmp, tmp, offset);
1439 tcg_gen_addi_i32(tmp, tmp, -offset);
1440 tcg_gen_mov_i32(dest, tmp);
1441 if (insn & (1 << 21))
1442 store_reg(s, rd, tmp);
1444 tcg_temp_free_i32(tmp);
1445 } else if (insn & (1 << 21)) {
1447 tcg_gen_mov_i32(dest, tmp);
1448 if (insn & (1 << 23))
1449 tcg_gen_addi_i32(tmp, tmp, offset);
1451 tcg_gen_addi_i32(tmp, tmp, -offset);
1452 store_reg(s, rd, tmp);
1453 } else if (!(insn & (1 << 23)))
1458 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1460 int rd = (insn >> 0) & 0xf;
1463 if (insn & (1 << 8)) {
1464 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1467 tmp = iwmmxt_load_creg(rd);
1470 tmp = tcg_temp_new_i32();
1471 iwmmxt_load_reg(cpu_V0, rd);
1472 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1474 tcg_gen_andi_i32(tmp, tmp, mask);
1475 tcg_gen_mov_i32(dest, tmp);
1476 tcg_temp_free_i32(tmp);
1480 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1481 (ie. an undefined instruction). */
1482 static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1485 int rdhi, rdlo, rd0, rd1, i;
1487 TCGv_i32 tmp, tmp2, tmp3;
1489 if ((insn & 0x0e000e00) == 0x0c000000) {
1490 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1492 rdlo = (insn >> 12) & 0xf;
1493 rdhi = (insn >> 16) & 0xf;
1494 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1495 iwmmxt_load_reg(cpu_V0, wrd);
1496 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1497 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1498 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1499 } else { /* TMCRR */
1500 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1501 iwmmxt_store_reg(cpu_V0, wrd);
1502 gen_op_iwmmxt_set_mup();
1507 wrd = (insn >> 12) & 0xf;
1508 addr = tcg_temp_new_i32();
1509 if (gen_iwmmxt_address(s, insn, addr)) {
1510 tcg_temp_free_i32(addr);
1513 if (insn & ARM_CP_RW_BIT) {
1514 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1515 tmp = tcg_temp_new_i32();
1516 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
1517 iwmmxt_store_creg(wrd, tmp);
1520 if (insn & (1 << 8)) {
1521 if (insn & (1 << 22)) { /* WLDRD */
1522 gen_aa32_ld64(cpu_M0, addr, get_mem_index(s));
1524 } else { /* WLDRW wRd */
1525 tmp = tcg_temp_new_i32();
1526 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
1529 tmp = tcg_temp_new_i32();
1530 if (insn & (1 << 22)) { /* WLDRH */
1531 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
1532 } else { /* WLDRB */
1533 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
1537 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1538 tcg_temp_free_i32(tmp);
1540 gen_op_iwmmxt_movq_wRn_M0(wrd);
1543 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1544 tmp = iwmmxt_load_creg(wrd);
1545 gen_aa32_st32(tmp, addr, get_mem_index(s));
1547 gen_op_iwmmxt_movq_M0_wRn(wrd);
1548 tmp = tcg_temp_new_i32();
1549 if (insn & (1 << 8)) {
1550 if (insn & (1 << 22)) { /* WSTRD */
1551 gen_aa32_st64(cpu_M0, addr, get_mem_index(s));
1552 } else { /* WSTRW wRd */
1553 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1554 gen_aa32_st32(tmp, addr, get_mem_index(s));
1557 if (insn & (1 << 22)) { /* WSTRH */
1558 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1559 gen_aa32_st16(tmp, addr, get_mem_index(s));
1560 } else { /* WSTRB */
1561 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1562 gen_aa32_st8(tmp, addr, get_mem_index(s));
1566 tcg_temp_free_i32(tmp);
1568 tcg_temp_free_i32(addr);
1572 if ((insn & 0x0f000000) != 0x0e000000)
1575 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1576 case 0x000: /* WOR */
1577 wrd = (insn >> 12) & 0xf;
1578 rd0 = (insn >> 0) & 0xf;
1579 rd1 = (insn >> 16) & 0xf;
1580 gen_op_iwmmxt_movq_M0_wRn(rd0);
1581 gen_op_iwmmxt_orq_M0_wRn(rd1);
1582 gen_op_iwmmxt_setpsr_nz();
1583 gen_op_iwmmxt_movq_wRn_M0(wrd);
1584 gen_op_iwmmxt_set_mup();
1585 gen_op_iwmmxt_set_cup();
1587 case 0x011: /* TMCR */
1590 rd = (insn >> 12) & 0xf;
1591 wrd = (insn >> 16) & 0xf;
1593 case ARM_IWMMXT_wCID:
1594 case ARM_IWMMXT_wCASF:
1596 case ARM_IWMMXT_wCon:
1597 gen_op_iwmmxt_set_cup();
1599 case ARM_IWMMXT_wCSSF:
1600 tmp = iwmmxt_load_creg(wrd);
1601 tmp2 = load_reg(s, rd);
1602 tcg_gen_andc_i32(tmp, tmp, tmp2);
1603 tcg_temp_free_i32(tmp2);
1604 iwmmxt_store_creg(wrd, tmp);
1606 case ARM_IWMMXT_wCGR0:
1607 case ARM_IWMMXT_wCGR1:
1608 case ARM_IWMMXT_wCGR2:
1609 case ARM_IWMMXT_wCGR3:
1610 gen_op_iwmmxt_set_cup();
1611 tmp = load_reg(s, rd);
1612 iwmmxt_store_creg(wrd, tmp);
1618 case 0x100: /* WXOR */
1619 wrd = (insn >> 12) & 0xf;
1620 rd0 = (insn >> 0) & 0xf;
1621 rd1 = (insn >> 16) & 0xf;
1622 gen_op_iwmmxt_movq_M0_wRn(rd0);
1623 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1624 gen_op_iwmmxt_setpsr_nz();
1625 gen_op_iwmmxt_movq_wRn_M0(wrd);
1626 gen_op_iwmmxt_set_mup();
1627 gen_op_iwmmxt_set_cup();
1629 case 0x111: /* TMRC */
1632 rd = (insn >> 12) & 0xf;
1633 wrd = (insn >> 16) & 0xf;
1634 tmp = iwmmxt_load_creg(wrd);
1635 store_reg(s, rd, tmp);
1637 case 0x300: /* WANDN */
1638 wrd = (insn >> 12) & 0xf;
1639 rd0 = (insn >> 0) & 0xf;
1640 rd1 = (insn >> 16) & 0xf;
1641 gen_op_iwmmxt_movq_M0_wRn(rd0);
1642 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1643 gen_op_iwmmxt_andq_M0_wRn(rd1);
1644 gen_op_iwmmxt_setpsr_nz();
1645 gen_op_iwmmxt_movq_wRn_M0(wrd);
1646 gen_op_iwmmxt_set_mup();
1647 gen_op_iwmmxt_set_cup();
1649 case 0x200: /* WAND */
1650 wrd = (insn >> 12) & 0xf;
1651 rd0 = (insn >> 0) & 0xf;
1652 rd1 = (insn >> 16) & 0xf;
1653 gen_op_iwmmxt_movq_M0_wRn(rd0);
1654 gen_op_iwmmxt_andq_M0_wRn(rd1);
1655 gen_op_iwmmxt_setpsr_nz();
1656 gen_op_iwmmxt_movq_wRn_M0(wrd);
1657 gen_op_iwmmxt_set_mup();
1658 gen_op_iwmmxt_set_cup();
1660 case 0x810: case 0xa10: /* WMADD */
1661 wrd = (insn >> 12) & 0xf;
1662 rd0 = (insn >> 0) & 0xf;
1663 rd1 = (insn >> 16) & 0xf;
1664 gen_op_iwmmxt_movq_M0_wRn(rd0);
1665 if (insn & (1 << 21))
1666 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1668 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1669 gen_op_iwmmxt_movq_wRn_M0(wrd);
1670 gen_op_iwmmxt_set_mup();
1672 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1673 wrd = (insn >> 12) & 0xf;
1674 rd0 = (insn >> 16) & 0xf;
1675 rd1 = (insn >> 0) & 0xf;
1676 gen_op_iwmmxt_movq_M0_wRn(rd0);
1677 switch ((insn >> 22) & 3) {
1679 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1682 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1685 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1690 gen_op_iwmmxt_movq_wRn_M0(wrd);
1691 gen_op_iwmmxt_set_mup();
1692 gen_op_iwmmxt_set_cup();
1694 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1695 wrd = (insn >> 12) & 0xf;
1696 rd0 = (insn >> 16) & 0xf;
1697 rd1 = (insn >> 0) & 0xf;
1698 gen_op_iwmmxt_movq_M0_wRn(rd0);
1699 switch ((insn >> 22) & 3) {
1701 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1704 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1707 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1712 gen_op_iwmmxt_movq_wRn_M0(wrd);
1713 gen_op_iwmmxt_set_mup();
1714 gen_op_iwmmxt_set_cup();
1716 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1717 wrd = (insn >> 12) & 0xf;
1718 rd0 = (insn >> 16) & 0xf;
1719 rd1 = (insn >> 0) & 0xf;
1720 gen_op_iwmmxt_movq_M0_wRn(rd0);
1721 if (insn & (1 << 22))
1722 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1724 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1725 if (!(insn & (1 << 20)))
1726 gen_op_iwmmxt_addl_M0_wRn(wrd);
1727 gen_op_iwmmxt_movq_wRn_M0(wrd);
1728 gen_op_iwmmxt_set_mup();
1730 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1731 wrd = (insn >> 12) & 0xf;
1732 rd0 = (insn >> 16) & 0xf;
1733 rd1 = (insn >> 0) & 0xf;
1734 gen_op_iwmmxt_movq_M0_wRn(rd0);
1735 if (insn & (1 << 21)) {
1736 if (insn & (1 << 20))
1737 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1739 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1741 if (insn & (1 << 20))
1742 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1744 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1746 gen_op_iwmmxt_movq_wRn_M0(wrd);
1747 gen_op_iwmmxt_set_mup();
1749 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
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 << 21))
1755 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1757 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1758 if (!(insn & (1 << 20))) {
1759 iwmmxt_load_reg(cpu_V1, wrd);
1760 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1762 gen_op_iwmmxt_movq_wRn_M0(wrd);
1763 gen_op_iwmmxt_set_mup();
1765 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1766 wrd = (insn >> 12) & 0xf;
1767 rd0 = (insn >> 16) & 0xf;
1768 rd1 = (insn >> 0) & 0xf;
1769 gen_op_iwmmxt_movq_M0_wRn(rd0);
1770 switch ((insn >> 22) & 3) {
1772 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1775 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1778 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1783 gen_op_iwmmxt_movq_wRn_M0(wrd);
1784 gen_op_iwmmxt_set_mup();
1785 gen_op_iwmmxt_set_cup();
1787 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1788 wrd = (insn >> 12) & 0xf;
1789 rd0 = (insn >> 16) & 0xf;
1790 rd1 = (insn >> 0) & 0xf;
1791 gen_op_iwmmxt_movq_M0_wRn(rd0);
1792 if (insn & (1 << 22)) {
1793 if (insn & (1 << 20))
1794 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1796 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1798 if (insn & (1 << 20))
1799 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1801 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1803 gen_op_iwmmxt_movq_wRn_M0(wrd);
1804 gen_op_iwmmxt_set_mup();
1805 gen_op_iwmmxt_set_cup();
1807 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1808 wrd = (insn >> 12) & 0xf;
1809 rd0 = (insn >> 16) & 0xf;
1810 rd1 = (insn >> 0) & 0xf;
1811 gen_op_iwmmxt_movq_M0_wRn(rd0);
1812 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1813 tcg_gen_andi_i32(tmp, tmp, 7);
1814 iwmmxt_load_reg(cpu_V1, rd1);
1815 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1816 tcg_temp_free_i32(tmp);
1817 gen_op_iwmmxt_movq_wRn_M0(wrd);
1818 gen_op_iwmmxt_set_mup();
1820 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1821 if (((insn >> 6) & 3) == 3)
1823 rd = (insn >> 12) & 0xf;
1824 wrd = (insn >> 16) & 0xf;
1825 tmp = load_reg(s, rd);
1826 gen_op_iwmmxt_movq_M0_wRn(wrd);
1827 switch ((insn >> 6) & 3) {
1829 tmp2 = tcg_const_i32(0xff);
1830 tmp3 = tcg_const_i32((insn & 7) << 3);
1833 tmp2 = tcg_const_i32(0xffff);
1834 tmp3 = tcg_const_i32((insn & 3) << 4);
1837 tmp2 = tcg_const_i32(0xffffffff);
1838 tmp3 = tcg_const_i32((insn & 1) << 5);
1841 TCGV_UNUSED_I32(tmp2);
1842 TCGV_UNUSED_I32(tmp3);
1844 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1845 tcg_temp_free_i32(tmp3);
1846 tcg_temp_free_i32(tmp2);
1847 tcg_temp_free_i32(tmp);
1848 gen_op_iwmmxt_movq_wRn_M0(wrd);
1849 gen_op_iwmmxt_set_mup();
1851 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1852 rd = (insn >> 12) & 0xf;
1853 wrd = (insn >> 16) & 0xf;
1854 if (rd == 15 || ((insn >> 22) & 3) == 3)
1856 gen_op_iwmmxt_movq_M0_wRn(wrd);
1857 tmp = tcg_temp_new_i32();
1858 switch ((insn >> 22) & 3) {
1860 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1861 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1863 tcg_gen_ext8s_i32(tmp, tmp);
1865 tcg_gen_andi_i32(tmp, tmp, 0xff);
1869 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1870 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1872 tcg_gen_ext16s_i32(tmp, tmp);
1874 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1878 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1879 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1882 store_reg(s, rd, tmp);
1884 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1885 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1887 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1888 switch ((insn >> 22) & 3) {
1890 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1893 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1896 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1899 tcg_gen_shli_i32(tmp, tmp, 28);
1901 tcg_temp_free_i32(tmp);
1903 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1904 if (((insn >> 6) & 3) == 3)
1906 rd = (insn >> 12) & 0xf;
1907 wrd = (insn >> 16) & 0xf;
1908 tmp = load_reg(s, rd);
1909 switch ((insn >> 6) & 3) {
1911 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1914 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1917 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1920 tcg_temp_free_i32(tmp);
1921 gen_op_iwmmxt_movq_wRn_M0(wrd);
1922 gen_op_iwmmxt_set_mup();
1924 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1925 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1927 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1928 tmp2 = tcg_temp_new_i32();
1929 tcg_gen_mov_i32(tmp2, tmp);
1930 switch ((insn >> 22) & 3) {
1932 for (i = 0; i < 7; i ++) {
1933 tcg_gen_shli_i32(tmp2, tmp2, 4);
1934 tcg_gen_and_i32(tmp, tmp, tmp2);
1938 for (i = 0; i < 3; i ++) {
1939 tcg_gen_shli_i32(tmp2, tmp2, 8);
1940 tcg_gen_and_i32(tmp, tmp, tmp2);
1944 tcg_gen_shli_i32(tmp2, tmp2, 16);
1945 tcg_gen_and_i32(tmp, tmp, tmp2);
1949 tcg_temp_free_i32(tmp2);
1950 tcg_temp_free_i32(tmp);
1952 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1953 wrd = (insn >> 12) & 0xf;
1954 rd0 = (insn >> 16) & 0xf;
1955 gen_op_iwmmxt_movq_M0_wRn(rd0);
1956 switch ((insn >> 22) & 3) {
1958 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1961 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1964 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1969 gen_op_iwmmxt_movq_wRn_M0(wrd);
1970 gen_op_iwmmxt_set_mup();
1972 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1973 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1975 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1976 tmp2 = tcg_temp_new_i32();
1977 tcg_gen_mov_i32(tmp2, tmp);
1978 switch ((insn >> 22) & 3) {
1980 for (i = 0; i < 7; i ++) {
1981 tcg_gen_shli_i32(tmp2, tmp2, 4);
1982 tcg_gen_or_i32(tmp, tmp, tmp2);
1986 for (i = 0; i < 3; i ++) {
1987 tcg_gen_shli_i32(tmp2, tmp2, 8);
1988 tcg_gen_or_i32(tmp, tmp, tmp2);
1992 tcg_gen_shli_i32(tmp2, tmp2, 16);
1993 tcg_gen_or_i32(tmp, tmp, tmp2);
1997 tcg_temp_free_i32(tmp2);
1998 tcg_temp_free_i32(tmp);
2000 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2001 rd = (insn >> 12) & 0xf;
2002 rd0 = (insn >> 16) & 0xf;
2003 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2005 gen_op_iwmmxt_movq_M0_wRn(rd0);
2006 tmp = tcg_temp_new_i32();
2007 switch ((insn >> 22) & 3) {
2009 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2012 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2015 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2018 store_reg(s, rd, tmp);
2020 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2021 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2022 wrd = (insn >> 12) & 0xf;
2023 rd0 = (insn >> 16) & 0xf;
2024 rd1 = (insn >> 0) & 0xf;
2025 gen_op_iwmmxt_movq_M0_wRn(rd0);
2026 switch ((insn >> 22) & 3) {
2028 if (insn & (1 << 21))
2029 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2031 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2034 if (insn & (1 << 21))
2035 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2037 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2040 if (insn & (1 << 21))
2041 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2043 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2048 gen_op_iwmmxt_movq_wRn_M0(wrd);
2049 gen_op_iwmmxt_set_mup();
2050 gen_op_iwmmxt_set_cup();
2052 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2053 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2054 wrd = (insn >> 12) & 0xf;
2055 rd0 = (insn >> 16) & 0xf;
2056 gen_op_iwmmxt_movq_M0_wRn(rd0);
2057 switch ((insn >> 22) & 3) {
2059 if (insn & (1 << 21))
2060 gen_op_iwmmxt_unpacklsb_M0();
2062 gen_op_iwmmxt_unpacklub_M0();
2065 if (insn & (1 << 21))
2066 gen_op_iwmmxt_unpacklsw_M0();
2068 gen_op_iwmmxt_unpackluw_M0();
2071 if (insn & (1 << 21))
2072 gen_op_iwmmxt_unpacklsl_M0();
2074 gen_op_iwmmxt_unpacklul_M0();
2079 gen_op_iwmmxt_movq_wRn_M0(wrd);
2080 gen_op_iwmmxt_set_mup();
2081 gen_op_iwmmxt_set_cup();
2083 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2084 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2085 wrd = (insn >> 12) & 0xf;
2086 rd0 = (insn >> 16) & 0xf;
2087 gen_op_iwmmxt_movq_M0_wRn(rd0);
2088 switch ((insn >> 22) & 3) {
2090 if (insn & (1 << 21))
2091 gen_op_iwmmxt_unpackhsb_M0();
2093 gen_op_iwmmxt_unpackhub_M0();
2096 if (insn & (1 << 21))
2097 gen_op_iwmmxt_unpackhsw_M0();
2099 gen_op_iwmmxt_unpackhuw_M0();
2102 if (insn & (1 << 21))
2103 gen_op_iwmmxt_unpackhsl_M0();
2105 gen_op_iwmmxt_unpackhul_M0();
2110 gen_op_iwmmxt_movq_wRn_M0(wrd);
2111 gen_op_iwmmxt_set_mup();
2112 gen_op_iwmmxt_set_cup();
2114 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2115 case 0x214: case 0x614: case 0xa14: case 0xe14:
2116 if (((insn >> 22) & 3) == 0)
2118 wrd = (insn >> 12) & 0xf;
2119 rd0 = (insn >> 16) & 0xf;
2120 gen_op_iwmmxt_movq_M0_wRn(rd0);
2121 tmp = tcg_temp_new_i32();
2122 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2123 tcg_temp_free_i32(tmp);
2126 switch ((insn >> 22) & 3) {
2128 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2131 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2134 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2137 tcg_temp_free_i32(tmp);
2138 gen_op_iwmmxt_movq_wRn_M0(wrd);
2139 gen_op_iwmmxt_set_mup();
2140 gen_op_iwmmxt_set_cup();
2142 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2143 case 0x014: case 0x414: case 0x814: case 0xc14:
2144 if (((insn >> 22) & 3) == 0)
2146 wrd = (insn >> 12) & 0xf;
2147 rd0 = (insn >> 16) & 0xf;
2148 gen_op_iwmmxt_movq_M0_wRn(rd0);
2149 tmp = tcg_temp_new_i32();
2150 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2151 tcg_temp_free_i32(tmp);
2154 switch ((insn >> 22) & 3) {
2156 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2159 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2162 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2165 tcg_temp_free_i32(tmp);
2166 gen_op_iwmmxt_movq_wRn_M0(wrd);
2167 gen_op_iwmmxt_set_mup();
2168 gen_op_iwmmxt_set_cup();
2170 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2171 case 0x114: case 0x514: case 0x914: case 0xd14:
2172 if (((insn >> 22) & 3) == 0)
2174 wrd = (insn >> 12) & 0xf;
2175 rd0 = (insn >> 16) & 0xf;
2176 gen_op_iwmmxt_movq_M0_wRn(rd0);
2177 tmp = tcg_temp_new_i32();
2178 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2179 tcg_temp_free_i32(tmp);
2182 switch ((insn >> 22) & 3) {
2184 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2187 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2190 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2193 tcg_temp_free_i32(tmp);
2194 gen_op_iwmmxt_movq_wRn_M0(wrd);
2195 gen_op_iwmmxt_set_mup();
2196 gen_op_iwmmxt_set_cup();
2198 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2199 case 0x314: case 0x714: case 0xb14: case 0xf14:
2200 if (((insn >> 22) & 3) == 0)
2202 wrd = (insn >> 12) & 0xf;
2203 rd0 = (insn >> 16) & 0xf;
2204 gen_op_iwmmxt_movq_M0_wRn(rd0);
2205 tmp = tcg_temp_new_i32();
2206 switch ((insn >> 22) & 3) {
2208 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2209 tcg_temp_free_i32(tmp);
2212 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2215 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2216 tcg_temp_free_i32(tmp);
2219 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2222 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2223 tcg_temp_free_i32(tmp);
2226 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2229 tcg_temp_free_i32(tmp);
2230 gen_op_iwmmxt_movq_wRn_M0(wrd);
2231 gen_op_iwmmxt_set_mup();
2232 gen_op_iwmmxt_set_cup();
2234 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2235 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2236 wrd = (insn >> 12) & 0xf;
2237 rd0 = (insn >> 16) & 0xf;
2238 rd1 = (insn >> 0) & 0xf;
2239 gen_op_iwmmxt_movq_M0_wRn(rd0);
2240 switch ((insn >> 22) & 3) {
2242 if (insn & (1 << 21))
2243 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2245 gen_op_iwmmxt_minub_M0_wRn(rd1);
2248 if (insn & (1 << 21))
2249 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2251 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2254 if (insn & (1 << 21))
2255 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2257 gen_op_iwmmxt_minul_M0_wRn(rd1);
2262 gen_op_iwmmxt_movq_wRn_M0(wrd);
2263 gen_op_iwmmxt_set_mup();
2265 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2266 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2267 wrd = (insn >> 12) & 0xf;
2268 rd0 = (insn >> 16) & 0xf;
2269 rd1 = (insn >> 0) & 0xf;
2270 gen_op_iwmmxt_movq_M0_wRn(rd0);
2271 switch ((insn >> 22) & 3) {
2273 if (insn & (1 << 21))
2274 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2276 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2279 if (insn & (1 << 21))
2280 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2282 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2285 if (insn & (1 << 21))
2286 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2288 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2293 gen_op_iwmmxt_movq_wRn_M0(wrd);
2294 gen_op_iwmmxt_set_mup();
2296 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2297 case 0x402: case 0x502: case 0x602: case 0x702:
2298 wrd = (insn >> 12) & 0xf;
2299 rd0 = (insn >> 16) & 0xf;
2300 rd1 = (insn >> 0) & 0xf;
2301 gen_op_iwmmxt_movq_M0_wRn(rd0);
2302 tmp = tcg_const_i32((insn >> 20) & 3);
2303 iwmmxt_load_reg(cpu_V1, rd1);
2304 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2305 tcg_temp_free_i32(tmp);
2306 gen_op_iwmmxt_movq_wRn_M0(wrd);
2307 gen_op_iwmmxt_set_mup();
2309 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2310 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2311 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2312 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2313 wrd = (insn >> 12) & 0xf;
2314 rd0 = (insn >> 16) & 0xf;
2315 rd1 = (insn >> 0) & 0xf;
2316 gen_op_iwmmxt_movq_M0_wRn(rd0);
2317 switch ((insn >> 20) & 0xf) {
2319 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2322 gen_op_iwmmxt_subub_M0_wRn(rd1);
2325 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2328 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2331 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2334 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2337 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2340 gen_op_iwmmxt_subul_M0_wRn(rd1);
2343 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2348 gen_op_iwmmxt_movq_wRn_M0(wrd);
2349 gen_op_iwmmxt_set_mup();
2350 gen_op_iwmmxt_set_cup();
2352 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2353 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2354 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2355 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2356 wrd = (insn >> 12) & 0xf;
2357 rd0 = (insn >> 16) & 0xf;
2358 gen_op_iwmmxt_movq_M0_wRn(rd0);
2359 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2360 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2361 tcg_temp_free_i32(tmp);
2362 gen_op_iwmmxt_movq_wRn_M0(wrd);
2363 gen_op_iwmmxt_set_mup();
2364 gen_op_iwmmxt_set_cup();
2366 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2367 case 0x418: case 0x518: case 0x618: case 0x718:
2368 case 0x818: case 0x918: case 0xa18: case 0xb18:
2369 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2370 wrd = (insn >> 12) & 0xf;
2371 rd0 = (insn >> 16) & 0xf;
2372 rd1 = (insn >> 0) & 0xf;
2373 gen_op_iwmmxt_movq_M0_wRn(rd0);
2374 switch ((insn >> 20) & 0xf) {
2376 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2379 gen_op_iwmmxt_addub_M0_wRn(rd1);
2382 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2385 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2388 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2391 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2394 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2397 gen_op_iwmmxt_addul_M0_wRn(rd1);
2400 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2405 gen_op_iwmmxt_movq_wRn_M0(wrd);
2406 gen_op_iwmmxt_set_mup();
2407 gen_op_iwmmxt_set_cup();
2409 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2410 case 0x408: case 0x508: case 0x608: case 0x708:
2411 case 0x808: case 0x908: case 0xa08: case 0xb08:
2412 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2413 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2415 wrd = (insn >> 12) & 0xf;
2416 rd0 = (insn >> 16) & 0xf;
2417 rd1 = (insn >> 0) & 0xf;
2418 gen_op_iwmmxt_movq_M0_wRn(rd0);
2419 switch ((insn >> 22) & 3) {
2421 if (insn & (1 << 21))
2422 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2424 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2427 if (insn & (1 << 21))
2428 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2430 gen_op_iwmmxt_packul_M0_wRn(rd1);
2433 if (insn & (1 << 21))
2434 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2436 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2439 gen_op_iwmmxt_movq_wRn_M0(wrd);
2440 gen_op_iwmmxt_set_mup();
2441 gen_op_iwmmxt_set_cup();
2443 case 0x201: case 0x203: case 0x205: case 0x207:
2444 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2445 case 0x211: case 0x213: case 0x215: case 0x217:
2446 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2447 wrd = (insn >> 5) & 0xf;
2448 rd0 = (insn >> 12) & 0xf;
2449 rd1 = (insn >> 0) & 0xf;
2450 if (rd0 == 0xf || rd1 == 0xf)
2452 gen_op_iwmmxt_movq_M0_wRn(wrd);
2453 tmp = load_reg(s, rd0);
2454 tmp2 = load_reg(s, rd1);
2455 switch ((insn >> 16) & 0xf) {
2456 case 0x0: /* TMIA */
2457 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2459 case 0x8: /* TMIAPH */
2460 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2462 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2463 if (insn & (1 << 16))
2464 tcg_gen_shri_i32(tmp, tmp, 16);
2465 if (insn & (1 << 17))
2466 tcg_gen_shri_i32(tmp2, tmp2, 16);
2467 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2470 tcg_temp_free_i32(tmp2);
2471 tcg_temp_free_i32(tmp);
2474 tcg_temp_free_i32(tmp2);
2475 tcg_temp_free_i32(tmp);
2476 gen_op_iwmmxt_movq_wRn_M0(wrd);
2477 gen_op_iwmmxt_set_mup();
2486 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2487 (ie. an undefined instruction). */
2488 static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2490 int acc, rd0, rd1, rdhi, rdlo;
2493 if ((insn & 0x0ff00f10) == 0x0e200010) {
2494 /* Multiply with Internal Accumulate Format */
2495 rd0 = (insn >> 12) & 0xf;
2497 acc = (insn >> 5) & 7;
2502 tmp = load_reg(s, rd0);
2503 tmp2 = load_reg(s, rd1);
2504 switch ((insn >> 16) & 0xf) {
2506 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2508 case 0x8: /* MIAPH */
2509 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2511 case 0xc: /* MIABB */
2512 case 0xd: /* MIABT */
2513 case 0xe: /* MIATB */
2514 case 0xf: /* MIATT */
2515 if (insn & (1 << 16))
2516 tcg_gen_shri_i32(tmp, tmp, 16);
2517 if (insn & (1 << 17))
2518 tcg_gen_shri_i32(tmp2, tmp2, 16);
2519 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2524 tcg_temp_free_i32(tmp2);
2525 tcg_temp_free_i32(tmp);
2527 gen_op_iwmmxt_movq_wRn_M0(acc);
2531 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2532 /* Internal Accumulator Access Format */
2533 rdhi = (insn >> 16) & 0xf;
2534 rdlo = (insn >> 12) & 0xf;
2540 if (insn & ARM_CP_RW_BIT) { /* MRA */
2541 iwmmxt_load_reg(cpu_V0, acc);
2542 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2543 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2544 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2545 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2547 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2548 iwmmxt_store_reg(cpu_V0, acc);
2556 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2557 #define VFP_SREG(insn, bigbit, smallbit) \
2558 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2559 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2560 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2561 reg = (((insn) >> (bigbit)) & 0x0f) \
2562 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2564 if (insn & (1 << (smallbit))) \
2566 reg = ((insn) >> (bigbit)) & 0x0f; \
2569 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2570 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2571 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2572 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2573 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2574 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2576 /* Move between integer and VFP cores. */
2577 static TCGv_i32 gen_vfp_mrs(void)
2579 TCGv_i32 tmp = tcg_temp_new_i32();
2580 tcg_gen_mov_i32(tmp, cpu_F0s);
2584 static void gen_vfp_msr(TCGv_i32 tmp)
2586 tcg_gen_mov_i32(cpu_F0s, tmp);
2587 tcg_temp_free_i32(tmp);
2590 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2592 TCGv_i32 tmp = tcg_temp_new_i32();
2594 tcg_gen_shri_i32(var, var, shift);
2595 tcg_gen_ext8u_i32(var, var);
2596 tcg_gen_shli_i32(tmp, var, 8);
2597 tcg_gen_or_i32(var, var, tmp);
2598 tcg_gen_shli_i32(tmp, var, 16);
2599 tcg_gen_or_i32(var, var, tmp);
2600 tcg_temp_free_i32(tmp);
2603 static void gen_neon_dup_low16(TCGv_i32 var)
2605 TCGv_i32 tmp = tcg_temp_new_i32();
2606 tcg_gen_ext16u_i32(var, var);
2607 tcg_gen_shli_i32(tmp, var, 16);
2608 tcg_gen_or_i32(var, var, tmp);
2609 tcg_temp_free_i32(tmp);
2612 static void gen_neon_dup_high16(TCGv_i32 var)
2614 TCGv_i32 tmp = tcg_temp_new_i32();
2615 tcg_gen_andi_i32(var, var, 0xffff0000);
2616 tcg_gen_shri_i32(tmp, var, 16);
2617 tcg_gen_or_i32(var, var, tmp);
2618 tcg_temp_free_i32(tmp);
2621 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2623 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2624 TCGv_i32 tmp = tcg_temp_new_i32();
2627 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
2628 gen_neon_dup_u8(tmp, 0);
2631 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
2632 gen_neon_dup_low16(tmp);
2635 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
2637 default: /* Avoid compiler warnings. */
2643 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2646 uint32_t cc = extract32(insn, 20, 2);
2649 TCGv_i64 frn, frm, dest;
2650 TCGv_i64 tmp, zero, zf, nf, vf;
2652 zero = tcg_const_i64(0);
2654 frn = tcg_temp_new_i64();
2655 frm = tcg_temp_new_i64();
2656 dest = tcg_temp_new_i64();
2658 zf = tcg_temp_new_i64();
2659 nf = tcg_temp_new_i64();
2660 vf = tcg_temp_new_i64();
2662 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2663 tcg_gen_ext_i32_i64(nf, cpu_NF);
2664 tcg_gen_ext_i32_i64(vf, cpu_VF);
2666 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2667 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2670 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2674 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2677 case 2: /* ge: N == V -> N ^ V == 0 */
2678 tmp = tcg_temp_new_i64();
2679 tcg_gen_xor_i64(tmp, vf, nf);
2680 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2682 tcg_temp_free_i64(tmp);
2684 case 3: /* gt: !Z && N == V */
2685 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2687 tmp = tcg_temp_new_i64();
2688 tcg_gen_xor_i64(tmp, vf, nf);
2689 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2691 tcg_temp_free_i64(tmp);
2694 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2695 tcg_temp_free_i64(frn);
2696 tcg_temp_free_i64(frm);
2697 tcg_temp_free_i64(dest);
2699 tcg_temp_free_i64(zf);
2700 tcg_temp_free_i64(nf);
2701 tcg_temp_free_i64(vf);
2703 tcg_temp_free_i64(zero);
2705 TCGv_i32 frn, frm, dest;
2708 zero = tcg_const_i32(0);
2710 frn = tcg_temp_new_i32();
2711 frm = tcg_temp_new_i32();
2712 dest = tcg_temp_new_i32();
2713 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2714 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2717 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2721 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2724 case 2: /* ge: N == V -> N ^ V == 0 */
2725 tmp = tcg_temp_new_i32();
2726 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2727 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2729 tcg_temp_free_i32(tmp);
2731 case 3: /* gt: !Z && N == V */
2732 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2734 tmp = tcg_temp_new_i32();
2735 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2736 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2738 tcg_temp_free_i32(tmp);
2741 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2742 tcg_temp_free_i32(frn);
2743 tcg_temp_free_i32(frm);
2744 tcg_temp_free_i32(dest);
2746 tcg_temp_free_i32(zero);
2752 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2753 uint32_t rm, uint32_t dp)
2755 uint32_t vmin = extract32(insn, 6, 1);
2756 TCGv_ptr fpst = get_fpstatus_ptr(0);
2759 TCGv_i64 frn, frm, dest;
2761 frn = tcg_temp_new_i64();
2762 frm = tcg_temp_new_i64();
2763 dest = tcg_temp_new_i64();
2765 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2766 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2768 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2770 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2772 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2773 tcg_temp_free_i64(frn);
2774 tcg_temp_free_i64(frm);
2775 tcg_temp_free_i64(dest);
2777 TCGv_i32 frn, frm, dest;
2779 frn = tcg_temp_new_i32();
2780 frm = tcg_temp_new_i32();
2781 dest = tcg_temp_new_i32();
2783 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2784 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2786 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2788 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2790 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2791 tcg_temp_free_i32(frn);
2792 tcg_temp_free_i32(frm);
2793 tcg_temp_free_i32(dest);
2796 tcg_temp_free_ptr(fpst);
2800 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2803 TCGv_ptr fpst = get_fpstatus_ptr(0);
2806 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2807 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2812 tcg_op = tcg_temp_new_i64();
2813 tcg_res = tcg_temp_new_i64();
2814 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2815 gen_helper_rintd(tcg_res, tcg_op, fpst);
2816 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2817 tcg_temp_free_i64(tcg_op);
2818 tcg_temp_free_i64(tcg_res);
2822 tcg_op = tcg_temp_new_i32();
2823 tcg_res = tcg_temp_new_i32();
2824 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2825 gen_helper_rints(tcg_res, tcg_op, fpst);
2826 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2827 tcg_temp_free_i32(tcg_op);
2828 tcg_temp_free_i32(tcg_res);
2831 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2832 tcg_temp_free_i32(tcg_rmode);
2834 tcg_temp_free_ptr(fpst);
2838 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2841 bool is_signed = extract32(insn, 7, 1);
2842 TCGv_ptr fpst = get_fpstatus_ptr(0);
2843 TCGv_i32 tcg_rmode, tcg_shift;
2845 tcg_shift = tcg_const_i32(0);
2847 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2848 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2851 TCGv_i64 tcg_double, tcg_res;
2853 /* Rd is encoded as a single precision register even when the source
2854 * is double precision.
2856 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
2857 tcg_double = tcg_temp_new_i64();
2858 tcg_res = tcg_temp_new_i64();
2859 tcg_tmp = tcg_temp_new_i32();
2860 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
2862 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
2864 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
2866 tcg_gen_trunc_i64_i32(tcg_tmp, tcg_res);
2867 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
2868 tcg_temp_free_i32(tcg_tmp);
2869 tcg_temp_free_i64(tcg_res);
2870 tcg_temp_free_i64(tcg_double);
2872 TCGv_i32 tcg_single, tcg_res;
2873 tcg_single = tcg_temp_new_i32();
2874 tcg_res = tcg_temp_new_i32();
2875 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
2877 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
2879 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
2881 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
2882 tcg_temp_free_i32(tcg_res);
2883 tcg_temp_free_i32(tcg_single);
2886 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2887 tcg_temp_free_i32(tcg_rmode);
2889 tcg_temp_free_i32(tcg_shift);
2891 tcg_temp_free_ptr(fpst);
2896 /* Table for converting the most common AArch32 encoding of
2897 * rounding mode to arm_fprounding order (which matches the
2898 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2900 static const uint8_t fp_decode_rm[] = {
2907 static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2909 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2911 if (!arm_feature(env, ARM_FEATURE_V8)) {
2916 VFP_DREG_D(rd, insn);
2917 VFP_DREG_N(rn, insn);
2918 VFP_DREG_M(rm, insn);
2920 rd = VFP_SREG_D(insn);
2921 rn = VFP_SREG_N(insn);
2922 rm = VFP_SREG_M(insn);
2925 if ((insn & 0x0f800e50) == 0x0e000a00) {
2926 return handle_vsel(insn, rd, rn, rm, dp);
2927 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2928 return handle_vminmaxnm(insn, rd, rn, rm, dp);
2929 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
2930 /* VRINTA, VRINTN, VRINTP, VRINTM */
2931 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2932 return handle_vrint(insn, rd, rm, dp, rounding);
2933 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
2934 /* VCVTA, VCVTN, VCVTP, VCVTM */
2935 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2936 return handle_vcvt(insn, rd, rm, dp, rounding);
2941 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2942 (ie. an undefined instruction). */
2943 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2945 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2951 if (!arm_feature(env, ARM_FEATURE_VFP))
2954 /* FIXME: this access check should not take precedence over UNDEF
2955 * for invalid encodings; we will generate incorrect syndrome information
2956 * for attempts to execute invalid vfp/neon encodings with FP disabled.
2958 if (!s->cpacr_fpen) {
2959 gen_exception_insn(s, 4, EXCP_UDEF,
2960 syn_fp_access_trap(1, 0xe, s->thumb));
2964 if (!s->vfp_enabled) {
2965 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2966 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2968 rn = (insn >> 16) & 0xf;
2969 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
2970 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
2975 if (extract32(insn, 28, 4) == 0xf) {
2976 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2977 * only used in v8 and above.
2979 return disas_vfp_v8_insn(env, s, insn);
2982 dp = ((insn & 0xf00) == 0xb00);
2983 switch ((insn >> 24) & 0xf) {
2985 if (insn & (1 << 4)) {
2986 /* single register transfer */
2987 rd = (insn >> 12) & 0xf;
2992 VFP_DREG_N(rn, insn);
2995 if (insn & 0x00c00060
2996 && !arm_feature(env, ARM_FEATURE_NEON))
2999 pass = (insn >> 21) & 1;
3000 if (insn & (1 << 22)) {
3002 offset = ((insn >> 5) & 3) * 8;
3003 } else if (insn & (1 << 5)) {
3005 offset = (insn & (1 << 6)) ? 16 : 0;
3010 if (insn & ARM_CP_RW_BIT) {
3012 tmp = neon_load_reg(rn, pass);
3016 tcg_gen_shri_i32(tmp, tmp, offset);
3017 if (insn & (1 << 23))
3023 if (insn & (1 << 23)) {
3025 tcg_gen_shri_i32(tmp, tmp, 16);
3031 tcg_gen_sari_i32(tmp, tmp, 16);
3040 store_reg(s, rd, tmp);
3043 tmp = load_reg(s, rd);
3044 if (insn & (1 << 23)) {
3047 gen_neon_dup_u8(tmp, 0);
3048 } else if (size == 1) {
3049 gen_neon_dup_low16(tmp);
3051 for (n = 0; n <= pass * 2; n++) {
3052 tmp2 = tcg_temp_new_i32();
3053 tcg_gen_mov_i32(tmp2, tmp);
3054 neon_store_reg(rn, n, tmp2);
3056 neon_store_reg(rn, n, tmp);
3061 tmp2 = neon_load_reg(rn, pass);
3062 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3063 tcg_temp_free_i32(tmp2);
3066 tmp2 = neon_load_reg(rn, pass);
3067 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3068 tcg_temp_free_i32(tmp2);
3073 neon_store_reg(rn, pass, tmp);
3077 if ((insn & 0x6f) != 0x00)
3079 rn = VFP_SREG_N(insn);
3080 if (insn & ARM_CP_RW_BIT) {
3082 if (insn & (1 << 21)) {
3083 /* system register */
3088 /* VFP2 allows access to FSID from userspace.
3089 VFP3 restricts all id registers to privileged
3092 && arm_feature(env, ARM_FEATURE_VFP3))
3094 tmp = load_cpu_field(vfp.xregs[rn]);
3099 tmp = load_cpu_field(vfp.xregs[rn]);
3101 case ARM_VFP_FPINST:
3102 case ARM_VFP_FPINST2:
3103 /* Not present in VFP3. */
3105 || arm_feature(env, ARM_FEATURE_VFP3))
3107 tmp = load_cpu_field(vfp.xregs[rn]);
3111 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3112 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3114 tmp = tcg_temp_new_i32();
3115 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3119 if (!arm_feature(env, ARM_FEATURE_V8)) {
3126 || !arm_feature(env, ARM_FEATURE_MVFR))
3128 tmp = load_cpu_field(vfp.xregs[rn]);
3134 gen_mov_F0_vreg(0, rn);
3135 tmp = gen_vfp_mrs();
3138 /* Set the 4 flag bits in the CPSR. */
3140 tcg_temp_free_i32(tmp);
3142 store_reg(s, rd, tmp);
3146 if (insn & (1 << 21)) {
3148 /* system register */
3153 /* Writes are ignored. */
3156 tmp = load_reg(s, rd);
3157 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3158 tcg_temp_free_i32(tmp);
3164 /* TODO: VFP subarchitecture support.
3165 * For now, keep the EN bit only */
3166 tmp = load_reg(s, rd);
3167 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3168 store_cpu_field(tmp, vfp.xregs[rn]);
3171 case ARM_VFP_FPINST:
3172 case ARM_VFP_FPINST2:
3173 tmp = load_reg(s, rd);
3174 store_cpu_field(tmp, vfp.xregs[rn]);
3180 tmp = load_reg(s, rd);
3182 gen_mov_vreg_F0(0, rn);
3187 /* data processing */
3188 /* The opcode is in bits 23, 21, 20 and 6. */
3189 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3193 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3195 /* rn is register number */
3196 VFP_DREG_N(rn, insn);
3199 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3200 ((rn & 0x1e) == 0x6))) {
3201 /* Integer or single/half precision destination. */
3202 rd = VFP_SREG_D(insn);
3204 VFP_DREG_D(rd, insn);
3207 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3208 ((rn & 0x1e) == 0x4))) {
3209 /* VCVT from int or half precision is always from S reg
3210 * regardless of dp bit. VCVT with immediate frac_bits
3211 * has same format as SREG_M.
3213 rm = VFP_SREG_M(insn);
3215 VFP_DREG_M(rm, insn);
3218 rn = VFP_SREG_N(insn);
3219 if (op == 15 && rn == 15) {
3220 /* Double precision destination. */
3221 VFP_DREG_D(rd, insn);
3223 rd = VFP_SREG_D(insn);
3225 /* NB that we implicitly rely on the encoding for the frac_bits
3226 * in VCVT of fixed to float being the same as that of an SREG_M
3228 rm = VFP_SREG_M(insn);
3231 veclen = s->vec_len;
3232 if (op == 15 && rn > 3)
3235 /* Shut up compiler warnings. */
3246 /* Figure out what type of vector operation this is. */
3247 if ((rd & bank_mask) == 0) {
3252 delta_d = (s->vec_stride >> 1) + 1;
3254 delta_d = s->vec_stride + 1;
3256 if ((rm & bank_mask) == 0) {
3257 /* mixed scalar/vector */
3266 /* Load the initial operands. */
3271 /* Integer source */
3272 gen_mov_F0_vreg(0, rm);
3277 gen_mov_F0_vreg(dp, rd);
3278 gen_mov_F1_vreg(dp, rm);
3282 /* Compare with zero */
3283 gen_mov_F0_vreg(dp, rd);
3294 /* Source and destination the same. */
3295 gen_mov_F0_vreg(dp, rd);
3301 /* VCVTB, VCVTT: only present with the halfprec extension
3302 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3303 * (we choose to UNDEF)
3305 if ((dp && !arm_feature(env, ARM_FEATURE_V8)) ||
3306 !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3309 if (!extract32(rn, 1, 1)) {
3310 /* Half precision source. */
3311 gen_mov_F0_vreg(0, rm);
3314 /* Otherwise fall through */
3316 /* One source operand. */
3317 gen_mov_F0_vreg(dp, rm);
3321 /* Two source operands. */
3322 gen_mov_F0_vreg(dp, rn);
3323 gen_mov_F1_vreg(dp, rm);
3327 /* Perform the calculation. */
3329 case 0: /* VMLA: fd + (fn * fm) */
3330 /* Note that order of inputs to the add matters for NaNs */
3332 gen_mov_F0_vreg(dp, rd);
3335 case 1: /* VMLS: fd + -(fn * fm) */
3338 gen_mov_F0_vreg(dp, rd);
3341 case 2: /* VNMLS: -fd + (fn * fm) */
3342 /* Note that it isn't valid to replace (-A + B) with (B - A)
3343 * or similar plausible looking simplifications
3344 * because this will give wrong results for NaNs.
3347 gen_mov_F0_vreg(dp, rd);
3351 case 3: /* VNMLA: -fd + -(fn * fm) */
3354 gen_mov_F0_vreg(dp, rd);
3358 case 4: /* mul: fn * fm */
3361 case 5: /* nmul: -(fn * fm) */
3365 case 6: /* add: fn + fm */
3368 case 7: /* sub: fn - fm */
3371 case 8: /* div: fn / fm */
3374 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3375 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3376 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3377 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3378 /* These are fused multiply-add, and must be done as one
3379 * floating point operation with no rounding between the
3380 * multiplication and addition steps.
3381 * NB that doing the negations here as separate steps is
3382 * correct : an input NaN should come out with its sign bit
3383 * flipped if it is a negated-input.
3385 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3393 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3395 frd = tcg_temp_new_i64();
3396 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3399 gen_helper_vfp_negd(frd, frd);
3401 fpst = get_fpstatus_ptr(0);
3402 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3403 cpu_F1d, frd, fpst);
3404 tcg_temp_free_ptr(fpst);
3405 tcg_temp_free_i64(frd);
3411 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3413 frd = tcg_temp_new_i32();
3414 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3416 gen_helper_vfp_negs(frd, frd);
3418 fpst = get_fpstatus_ptr(0);
3419 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3420 cpu_F1s, frd, fpst);
3421 tcg_temp_free_ptr(fpst);
3422 tcg_temp_free_i32(frd);
3425 case 14: /* fconst */
3426 if (!arm_feature(env, ARM_FEATURE_VFP3))
3429 n = (insn << 12) & 0x80000000;
3430 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3437 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3444 tcg_gen_movi_i32(cpu_F0s, n);
3447 case 15: /* extension space */
3461 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3462 tmp = gen_vfp_mrs();
3463 tcg_gen_ext16u_i32(tmp, tmp);
3465 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3468 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3471 tcg_temp_free_i32(tmp);
3473 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3474 tmp = gen_vfp_mrs();
3475 tcg_gen_shri_i32(tmp, tmp, 16);
3477 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3480 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3483 tcg_temp_free_i32(tmp);
3485 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3486 tmp = tcg_temp_new_i32();
3488 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3491 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3494 gen_mov_F0_vreg(0, rd);
3495 tmp2 = gen_vfp_mrs();
3496 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3497 tcg_gen_or_i32(tmp, tmp, tmp2);
3498 tcg_temp_free_i32(tmp2);
3501 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3502 tmp = tcg_temp_new_i32();
3504 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3507 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3510 tcg_gen_shli_i32(tmp, tmp, 16);
3511 gen_mov_F0_vreg(0, rd);
3512 tmp2 = gen_vfp_mrs();
3513 tcg_gen_ext16u_i32(tmp2, tmp2);
3514 tcg_gen_or_i32(tmp, tmp, tmp2);
3515 tcg_temp_free_i32(tmp2);
3527 case 11: /* cmpez */
3531 case 12: /* vrintr */
3533 TCGv_ptr fpst = get_fpstatus_ptr(0);
3535 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3537 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3539 tcg_temp_free_ptr(fpst);
3542 case 13: /* vrintz */
3544 TCGv_ptr fpst = get_fpstatus_ptr(0);
3546 tcg_rmode = tcg_const_i32(float_round_to_zero);
3547 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3549 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3551 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3553 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3554 tcg_temp_free_i32(tcg_rmode);
3555 tcg_temp_free_ptr(fpst);
3558 case 14: /* vrintx */
3560 TCGv_ptr fpst = get_fpstatus_ptr(0);
3562 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3564 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3566 tcg_temp_free_ptr(fpst);
3569 case 15: /* single<->double conversion */
3571 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3573 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3575 case 16: /* fuito */
3576 gen_vfp_uito(dp, 0);
3578 case 17: /* fsito */
3579 gen_vfp_sito(dp, 0);
3581 case 20: /* fshto */
3582 if (!arm_feature(env, ARM_FEATURE_VFP3))
3584 gen_vfp_shto(dp, 16 - rm, 0);
3586 case 21: /* fslto */
3587 if (!arm_feature(env, ARM_FEATURE_VFP3))
3589 gen_vfp_slto(dp, 32 - rm, 0);
3591 case 22: /* fuhto */
3592 if (!arm_feature(env, ARM_FEATURE_VFP3))
3594 gen_vfp_uhto(dp, 16 - rm, 0);
3596 case 23: /* fulto */
3597 if (!arm_feature(env, ARM_FEATURE_VFP3))
3599 gen_vfp_ulto(dp, 32 - rm, 0);
3601 case 24: /* ftoui */
3602 gen_vfp_toui(dp, 0);
3604 case 25: /* ftouiz */
3605 gen_vfp_touiz(dp, 0);
3607 case 26: /* ftosi */
3608 gen_vfp_tosi(dp, 0);
3610 case 27: /* ftosiz */
3611 gen_vfp_tosiz(dp, 0);
3613 case 28: /* ftosh */
3614 if (!arm_feature(env, ARM_FEATURE_VFP3))
3616 gen_vfp_tosh(dp, 16 - rm, 0);
3618 case 29: /* ftosl */
3619 if (!arm_feature(env, ARM_FEATURE_VFP3))
3621 gen_vfp_tosl(dp, 32 - rm, 0);
3623 case 30: /* ftouh */
3624 if (!arm_feature(env, ARM_FEATURE_VFP3))
3626 gen_vfp_touh(dp, 16 - rm, 0);
3628 case 31: /* ftoul */
3629 if (!arm_feature(env, ARM_FEATURE_VFP3))
3631 gen_vfp_toul(dp, 32 - rm, 0);
3633 default: /* undefined */
3637 default: /* undefined */
3641 /* Write back the result. */
3642 if (op == 15 && (rn >= 8 && rn <= 11)) {
3643 /* Comparison, do nothing. */
3644 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3645 (rn & 0x1e) == 0x6)) {
3646 /* VCVT double to int: always integer result.
3647 * VCVT double to half precision is always a single
3650 gen_mov_vreg_F0(0, rd);
3651 } else if (op == 15 && rn == 15) {
3653 gen_mov_vreg_F0(!dp, rd);
3655 gen_mov_vreg_F0(dp, rd);
3658 /* break out of the loop if we have finished */
3662 if (op == 15 && delta_m == 0) {
3663 /* single source one-many */
3665 rd = ((rd + delta_d) & (bank_mask - 1))
3667 gen_mov_vreg_F0(dp, rd);
3671 /* Setup the next operands. */
3673 rd = ((rd + delta_d) & (bank_mask - 1))
3677 /* One source operand. */
3678 rm = ((rm + delta_m) & (bank_mask - 1))
3680 gen_mov_F0_vreg(dp, rm);
3682 /* Two source operands. */
3683 rn = ((rn + delta_d) & (bank_mask - 1))
3685 gen_mov_F0_vreg(dp, rn);
3687 rm = ((rm + delta_m) & (bank_mask - 1))
3689 gen_mov_F1_vreg(dp, rm);
3697 if ((insn & 0x03e00000) == 0x00400000) {
3698 /* two-register transfer */
3699 rn = (insn >> 16) & 0xf;
3700 rd = (insn >> 12) & 0xf;
3702 VFP_DREG_M(rm, insn);
3704 rm = VFP_SREG_M(insn);
3707 if (insn & ARM_CP_RW_BIT) {
3710 gen_mov_F0_vreg(0, rm * 2);
3711 tmp = gen_vfp_mrs();
3712 store_reg(s, rd, tmp);
3713 gen_mov_F0_vreg(0, rm * 2 + 1);
3714 tmp = gen_vfp_mrs();
3715 store_reg(s, rn, tmp);
3717 gen_mov_F0_vreg(0, rm);
3718 tmp = gen_vfp_mrs();
3719 store_reg(s, rd, tmp);
3720 gen_mov_F0_vreg(0, rm + 1);
3721 tmp = gen_vfp_mrs();
3722 store_reg(s, rn, tmp);
3727 tmp = load_reg(s, rd);
3729 gen_mov_vreg_F0(0, rm * 2);
3730 tmp = load_reg(s, rn);
3732 gen_mov_vreg_F0(0, rm * 2 + 1);
3734 tmp = load_reg(s, rd);
3736 gen_mov_vreg_F0(0, rm);
3737 tmp = load_reg(s, rn);
3739 gen_mov_vreg_F0(0, rm + 1);
3744 rn = (insn >> 16) & 0xf;
3746 VFP_DREG_D(rd, insn);
3748 rd = VFP_SREG_D(insn);
3749 if ((insn & 0x01200000) == 0x01000000) {
3750 /* Single load/store */
3751 offset = (insn & 0xff) << 2;
3752 if ((insn & (1 << 23)) == 0)
3754 if (s->thumb && rn == 15) {
3755 /* This is actually UNPREDICTABLE */
3756 addr = tcg_temp_new_i32();
3757 tcg_gen_movi_i32(addr, s->pc & ~2);
3759 addr = load_reg(s, rn);
3761 tcg_gen_addi_i32(addr, addr, offset);
3762 if (insn & (1 << 20)) {
3763 gen_vfp_ld(s, dp, addr);
3764 gen_mov_vreg_F0(dp, rd);
3766 gen_mov_F0_vreg(dp, rd);
3767 gen_vfp_st(s, dp, addr);
3769 tcg_temp_free_i32(addr);
3771 /* load/store multiple */
3772 int w = insn & (1 << 21);
3774 n = (insn >> 1) & 0x7f;
3778 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3779 /* P == U , W == 1 => UNDEF */
3782 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3783 /* UNPREDICTABLE cases for bad immediates: we choose to
3784 * UNDEF to avoid generating huge numbers of TCG ops
3788 if (rn == 15 && w) {
3789 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3793 if (s->thumb && rn == 15) {
3794 /* This is actually UNPREDICTABLE */
3795 addr = tcg_temp_new_i32();
3796 tcg_gen_movi_i32(addr, s->pc & ~2);
3798 addr = load_reg(s, rn);
3800 if (insn & (1 << 24)) /* pre-decrement */
3801 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3807 for (i = 0; i < n; i++) {
3808 if (insn & ARM_CP_RW_BIT) {
3810 gen_vfp_ld(s, dp, addr);
3811 gen_mov_vreg_F0(dp, rd + i);
3814 gen_mov_F0_vreg(dp, rd + i);
3815 gen_vfp_st(s, dp, addr);
3817 tcg_gen_addi_i32(addr, addr, offset);
3821 if (insn & (1 << 24))
3822 offset = -offset * n;
3823 else if (dp && (insn & 1))
3829 tcg_gen_addi_i32(addr, addr, offset);
3830 store_reg(s, rn, addr);
3832 tcg_temp_free_i32(addr);
3838 /* Should never happen. */
3844 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3846 TranslationBlock *tb;
3849 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3851 gen_set_pc_im(s, dest);
3852 tcg_gen_exit_tb((uintptr_t)tb + n);
3854 gen_set_pc_im(s, dest);
3859 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3861 if (unlikely(s->singlestep_enabled)) {
3862 /* An indirect jump so that we still trigger the debug exception. */
3867 gen_goto_tb(s, 0, dest);
3868 s->is_jmp = DISAS_TB_JUMP;
3872 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3875 tcg_gen_sari_i32(t0, t0, 16);
3879 tcg_gen_sari_i32(t1, t1, 16);
3882 tcg_gen_mul_i32(t0, t0, t1);
3885 /* Return the mask of PSR bits set by a MSR instruction. */
3886 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3890 if (flags & (1 << 0))
3892 if (flags & (1 << 1))
3894 if (flags & (1 << 2))
3896 if (flags & (1 << 3))
3899 /* Mask out undefined bits. */
3900 mask &= ~CPSR_RESERVED;
3901 if (!arm_feature(env, ARM_FEATURE_V4T))
3903 if (!arm_feature(env, ARM_FEATURE_V5))
3904 mask &= ~CPSR_Q; /* V5TE in reality*/
3905 if (!arm_feature(env, ARM_FEATURE_V6))
3906 mask &= ~(CPSR_E | CPSR_GE);
3907 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3909 /* Mask out execution state bits. */
3912 /* Mask out privileged bits. */
3918 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3919 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3923 /* ??? This is also undefined in system mode. */
3927 tmp = load_cpu_field(spsr);
3928 tcg_gen_andi_i32(tmp, tmp, ~mask);
3929 tcg_gen_andi_i32(t0, t0, mask);
3930 tcg_gen_or_i32(tmp, tmp, t0);
3931 store_cpu_field(tmp, spsr);
3933 gen_set_cpsr(t0, mask);
3935 tcg_temp_free_i32(t0);
3940 /* Returns nonzero if access to the PSR is not permitted. */
3941 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3944 tmp = tcg_temp_new_i32();
3945 tcg_gen_movi_i32(tmp, val);
3946 return gen_set_psr(s, mask, spsr, tmp);
3949 /* Generate an old-style exception return. Marks pc as dead. */
3950 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3953 store_reg(s, 15, pc);
3954 tmp = load_cpu_field(spsr);
3955 gen_set_cpsr(tmp, 0xffffffff);
3956 tcg_temp_free_i32(tmp);
3957 s->is_jmp = DISAS_UPDATE;
3960 /* Generate a v6 exception return. Marks both values as dead. */
3961 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3963 gen_set_cpsr(cpsr, 0xffffffff);
3964 tcg_temp_free_i32(cpsr);
3965 store_reg(s, 15, pc);
3966 s->is_jmp = DISAS_UPDATE;
3969 static void gen_nop_hint(DisasContext *s, int val)
3973 gen_set_pc_im(s, s->pc);
3974 s->is_jmp = DISAS_WFI;
3977 gen_set_pc_im(s, s->pc);
3978 s->is_jmp = DISAS_WFE;
3982 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3988 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3990 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3993 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3994 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3995 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4000 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4003 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4004 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4005 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4010 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4011 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4012 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4013 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4014 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4016 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4017 switch ((size << 1) | u) { \
4019 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4022 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4025 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4028 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4031 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4034 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4036 default: return 1; \
4039 #define GEN_NEON_INTEGER_OP(name) do { \
4040 switch ((size << 1) | u) { \
4042 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4045 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4048 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4051 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4054 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4057 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4059 default: return 1; \
4062 static TCGv_i32 neon_load_scratch(int scratch)
4064 TCGv_i32 tmp = tcg_temp_new_i32();
4065 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4069 static void neon_store_scratch(int scratch, TCGv_i32 var)
4071 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4072 tcg_temp_free_i32(var);
4075 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4079 tmp = neon_load_reg(reg & 7, reg >> 4);
4081 gen_neon_dup_high16(tmp);
4083 gen_neon_dup_low16(tmp);
4086 tmp = neon_load_reg(reg & 15, reg >> 4);
4091 static int gen_neon_unzip(int rd, int rm, int size, int q)
4094 if (!q && size == 2) {
4097 tmp = tcg_const_i32(rd);
4098 tmp2 = tcg_const_i32(rm);
4102 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4105 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4108 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4116 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4119 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4125 tcg_temp_free_i32(tmp);
4126 tcg_temp_free_i32(tmp2);
4130 static int gen_neon_zip(int rd, int rm, int size, int q)
4133 if (!q && size == 2) {
4136 tmp = tcg_const_i32(rd);
4137 tmp2 = tcg_const_i32(rm);
4141 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4144 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4147 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4155 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4158 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4164 tcg_temp_free_i32(tmp);
4165 tcg_temp_free_i32(tmp2);
4169 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4173 rd = tcg_temp_new_i32();
4174 tmp = tcg_temp_new_i32();
4176 tcg_gen_shli_i32(rd, t0, 8);
4177 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4178 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4179 tcg_gen_or_i32(rd, rd, tmp);
4181 tcg_gen_shri_i32(t1, t1, 8);
4182 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4183 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4184 tcg_gen_or_i32(t1, t1, tmp);
4185 tcg_gen_mov_i32(t0, rd);
4187 tcg_temp_free_i32(tmp);
4188 tcg_temp_free_i32(rd);
4191 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4195 rd = tcg_temp_new_i32();
4196 tmp = tcg_temp_new_i32();
4198 tcg_gen_shli_i32(rd, t0, 16);
4199 tcg_gen_andi_i32(tmp, t1, 0xffff);
4200 tcg_gen_or_i32(rd, rd, tmp);
4201 tcg_gen_shri_i32(t1, t1, 16);
4202 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4203 tcg_gen_or_i32(t1, t1, tmp);
4204 tcg_gen_mov_i32(t0, rd);
4206 tcg_temp_free_i32(tmp);
4207 tcg_temp_free_i32(rd);
4215 } neon_ls_element_type[11] = {
4229 /* Translate a NEON load/store element instruction. Return nonzero if the
4230 instruction is invalid. */
4231 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4250 /* FIXME: this access check should not take precedence over UNDEF
4251 * for invalid encodings; we will generate incorrect syndrome information
4252 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4254 if (!s->cpacr_fpen) {
4255 gen_exception_insn(s, 4, EXCP_UDEF,
4256 syn_fp_access_trap(1, 0xe, s->thumb));
4260 if (!s->vfp_enabled)
4262 VFP_DREG_D(rd, insn);
4263 rn = (insn >> 16) & 0xf;
4265 load = (insn & (1 << 21)) != 0;
4266 if ((insn & (1 << 23)) == 0) {
4267 /* Load store all elements. */
4268 op = (insn >> 8) & 0xf;
4269 size = (insn >> 6) & 3;
4272 /* Catch UNDEF cases for bad values of align field */
4275 if (((insn >> 5) & 1) == 1) {
4280 if (((insn >> 4) & 3) == 3) {
4287 nregs = neon_ls_element_type[op].nregs;
4288 interleave = neon_ls_element_type[op].interleave;
4289 spacing = neon_ls_element_type[op].spacing;
4290 if (size == 3 && (interleave | spacing) != 1)
4292 addr = tcg_temp_new_i32();
4293 load_reg_var(s, addr, rn);
4294 stride = (1 << size) * interleave;
4295 for (reg = 0; reg < nregs; reg++) {
4296 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4297 load_reg_var(s, addr, rn);
4298 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4299 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4300 load_reg_var(s, addr, rn);
4301 tcg_gen_addi_i32(addr, addr, 1 << size);
4304 tmp64 = tcg_temp_new_i64();
4306 gen_aa32_ld64(tmp64, addr, get_mem_index(s));
4307 neon_store_reg64(tmp64, rd);
4309 neon_load_reg64(tmp64, rd);
4310 gen_aa32_st64(tmp64, addr, get_mem_index(s));
4312 tcg_temp_free_i64(tmp64);
4313 tcg_gen_addi_i32(addr, addr, stride);
4315 for (pass = 0; pass < 2; pass++) {
4318 tmp = tcg_temp_new_i32();
4319 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
4320 neon_store_reg(rd, pass, tmp);
4322 tmp = neon_load_reg(rd, pass);
4323 gen_aa32_st32(tmp, addr, get_mem_index(s));
4324 tcg_temp_free_i32(tmp);
4326 tcg_gen_addi_i32(addr, addr, stride);
4327 } else if (size == 1) {
4329 tmp = tcg_temp_new_i32();
4330 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
4331 tcg_gen_addi_i32(addr, addr, stride);
4332 tmp2 = tcg_temp_new_i32();
4333 gen_aa32_ld16u(tmp2, addr, get_mem_index(s));
4334 tcg_gen_addi_i32(addr, addr, stride);
4335 tcg_gen_shli_i32(tmp2, tmp2, 16);
4336 tcg_gen_or_i32(tmp, tmp, tmp2);
4337 tcg_temp_free_i32(tmp2);
4338 neon_store_reg(rd, pass, tmp);
4340 tmp = neon_load_reg(rd, pass);
4341 tmp2 = tcg_temp_new_i32();
4342 tcg_gen_shri_i32(tmp2, tmp, 16);
4343 gen_aa32_st16(tmp, addr, get_mem_index(s));
4344 tcg_temp_free_i32(tmp);
4345 tcg_gen_addi_i32(addr, addr, stride);
4346 gen_aa32_st16(tmp2, addr, get_mem_index(s));
4347 tcg_temp_free_i32(tmp2);
4348 tcg_gen_addi_i32(addr, addr, stride);
4350 } else /* size == 0 */ {
4352 TCGV_UNUSED_I32(tmp2);
4353 for (n = 0; n < 4; n++) {
4354 tmp = tcg_temp_new_i32();
4355 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
4356 tcg_gen_addi_i32(addr, addr, stride);
4360 tcg_gen_shli_i32(tmp, tmp, n * 8);
4361 tcg_gen_or_i32(tmp2, tmp2, tmp);
4362 tcg_temp_free_i32(tmp);
4365 neon_store_reg(rd, pass, tmp2);
4367 tmp2 = neon_load_reg(rd, pass);
4368 for (n = 0; n < 4; n++) {
4369 tmp = tcg_temp_new_i32();
4371 tcg_gen_mov_i32(tmp, tmp2);
4373 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4375 gen_aa32_st8(tmp, addr, get_mem_index(s));
4376 tcg_temp_free_i32(tmp);
4377 tcg_gen_addi_i32(addr, addr, stride);
4379 tcg_temp_free_i32(tmp2);
4386 tcg_temp_free_i32(addr);
4389 size = (insn >> 10) & 3;
4391 /* Load single element to all lanes. */
4392 int a = (insn >> 4) & 1;
4396 size = (insn >> 6) & 3;
4397 nregs = ((insn >> 8) & 3) + 1;
4400 if (nregs != 4 || a == 0) {
4403 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4406 if (nregs == 1 && a == 1 && size == 0) {
4409 if (nregs == 3 && a == 1) {
4412 addr = tcg_temp_new_i32();
4413 load_reg_var(s, addr, rn);
4415 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4416 tmp = gen_load_and_replicate(s, addr, size);
4417 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4418 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4419 if (insn & (1 << 5)) {
4420 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4421 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4423 tcg_temp_free_i32(tmp);
4425 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4426 stride = (insn & (1 << 5)) ? 2 : 1;
4427 for (reg = 0; reg < nregs; reg++) {
4428 tmp = gen_load_and_replicate(s, addr, size);
4429 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4430 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4431 tcg_temp_free_i32(tmp);
4432 tcg_gen_addi_i32(addr, addr, 1 << size);
4436 tcg_temp_free_i32(addr);
4437 stride = (1 << size) * nregs;
4439 /* Single element. */
4440 int idx = (insn >> 4) & 0xf;
4441 pass = (insn >> 7) & 1;
4444 shift = ((insn >> 5) & 3) * 8;
4448 shift = ((insn >> 6) & 1) * 16;
4449 stride = (insn & (1 << 5)) ? 2 : 1;
4453 stride = (insn & (1 << 6)) ? 2 : 1;
4458 nregs = ((insn >> 8) & 3) + 1;
4459 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4462 if (((idx & (1 << size)) != 0) ||
4463 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4468 if ((idx & 1) != 0) {
4473 if (size == 2 && (idx & 2) != 0) {
4478 if ((size == 2) && ((idx & 3) == 3)) {
4485 if ((rd + stride * (nregs - 1)) > 31) {
4486 /* Attempts to write off the end of the register file
4487 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4488 * the neon_load_reg() would write off the end of the array.
4492 addr = tcg_temp_new_i32();
4493 load_reg_var(s, addr, rn);
4494 for (reg = 0; reg < nregs; reg++) {
4496 tmp = tcg_temp_new_i32();
4499 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
4502 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
4505 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
4507 default: /* Avoid compiler warnings. */
4511 tmp2 = neon_load_reg(rd, pass);
4512 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4513 shift, size ? 16 : 8);
4514 tcg_temp_free_i32(tmp2);
4516 neon_store_reg(rd, pass, tmp);
4517 } else { /* Store */
4518 tmp = neon_load_reg(rd, pass);
4520 tcg_gen_shri_i32(tmp, tmp, shift);
4523 gen_aa32_st8(tmp, addr, get_mem_index(s));
4526 gen_aa32_st16(tmp, addr, get_mem_index(s));
4529 gen_aa32_st32(tmp, addr, get_mem_index(s));
4532 tcg_temp_free_i32(tmp);
4535 tcg_gen_addi_i32(addr, addr, 1 << size);
4537 tcg_temp_free_i32(addr);
4538 stride = nregs * (1 << size);
4544 base = load_reg(s, rn);
4546 tcg_gen_addi_i32(base, base, stride);
4549 index = load_reg(s, rm);
4550 tcg_gen_add_i32(base, base, index);
4551 tcg_temp_free_i32(index);
4553 store_reg(s, rn, base);
4558 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4559 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4561 tcg_gen_and_i32(t, t, c);
4562 tcg_gen_andc_i32(f, f, c);
4563 tcg_gen_or_i32(dest, t, f);
4566 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4569 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4570 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4571 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4576 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4579 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4580 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4581 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4586 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4589 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4590 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4591 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4596 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4599 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4600 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4601 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4606 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4612 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4613 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4618 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4619 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4626 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4627 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4632 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4633 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4640 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4644 case 0: gen_helper_neon_widen_u8(dest, src); break;
4645 case 1: gen_helper_neon_widen_u16(dest, src); break;
4646 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4651 case 0: gen_helper_neon_widen_s8(dest, src); break;
4652 case 1: gen_helper_neon_widen_s16(dest, src); break;
4653 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4657 tcg_temp_free_i32(src);
4660 static inline void gen_neon_addl(int size)
4663 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4664 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4665 case 2: tcg_gen_add_i64(CPU_V001); break;
4670 static inline void gen_neon_subl(int size)
4673 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4674 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4675 case 2: tcg_gen_sub_i64(CPU_V001); break;
4680 static inline void gen_neon_negl(TCGv_i64 var, int size)
4683 case 0: gen_helper_neon_negl_u16(var, var); break;
4684 case 1: gen_helper_neon_negl_u32(var, var); break;
4686 tcg_gen_neg_i64(var, var);
4692 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4695 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4696 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4701 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4706 switch ((size << 1) | u) {
4707 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4708 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4709 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4710 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4712 tmp = gen_muls_i64_i32(a, b);
4713 tcg_gen_mov_i64(dest, tmp);
4714 tcg_temp_free_i64(tmp);
4717 tmp = gen_mulu_i64_i32(a, b);
4718 tcg_gen_mov_i64(dest, tmp);
4719 tcg_temp_free_i64(tmp);
4724 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4725 Don't forget to clean them now. */
4727 tcg_temp_free_i32(a);
4728 tcg_temp_free_i32(b);
4732 static void gen_neon_narrow_op(int op, int u, int size,
4733 TCGv_i32 dest, TCGv_i64 src)
4737 gen_neon_unarrow_sats(size, dest, src);
4739 gen_neon_narrow(size, dest, src);
4743 gen_neon_narrow_satu(size, dest, src);
4745 gen_neon_narrow_sats(size, dest, src);
4750 /* Symbolic constants for op fields for Neon 3-register same-length.
4751 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4754 #define NEON_3R_VHADD 0
4755 #define NEON_3R_VQADD 1
4756 #define NEON_3R_VRHADD 2
4757 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4758 #define NEON_3R_VHSUB 4
4759 #define NEON_3R_VQSUB 5
4760 #define NEON_3R_VCGT 6
4761 #define NEON_3R_VCGE 7
4762 #define NEON_3R_VSHL 8
4763 #define NEON_3R_VQSHL 9
4764 #define NEON_3R_VRSHL 10
4765 #define NEON_3R_VQRSHL 11
4766 #define NEON_3R_VMAX 12
4767 #define NEON_3R_VMIN 13
4768 #define NEON_3R_VABD 14
4769 #define NEON_3R_VABA 15
4770 #define NEON_3R_VADD_VSUB 16
4771 #define NEON_3R_VTST_VCEQ 17
4772 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4773 #define NEON_3R_VMUL 19
4774 #define NEON_3R_VPMAX 20
4775 #define NEON_3R_VPMIN 21
4776 #define NEON_3R_VQDMULH_VQRDMULH 22
4777 #define NEON_3R_VPADD 23
4778 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4779 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4780 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4781 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4782 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4783 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4784 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4786 static const uint8_t neon_3r_sizes[] = {
4787 [NEON_3R_VHADD] = 0x7,
4788 [NEON_3R_VQADD] = 0xf,
4789 [NEON_3R_VRHADD] = 0x7,
4790 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4791 [NEON_3R_VHSUB] = 0x7,
4792 [NEON_3R_VQSUB] = 0xf,
4793 [NEON_3R_VCGT] = 0x7,
4794 [NEON_3R_VCGE] = 0x7,
4795 [NEON_3R_VSHL] = 0xf,
4796 [NEON_3R_VQSHL] = 0xf,
4797 [NEON_3R_VRSHL] = 0xf,
4798 [NEON_3R_VQRSHL] = 0xf,
4799 [NEON_3R_VMAX] = 0x7,
4800 [NEON_3R_VMIN] = 0x7,
4801 [NEON_3R_VABD] = 0x7,
4802 [NEON_3R_VABA] = 0x7,
4803 [NEON_3R_VADD_VSUB] = 0xf,
4804 [NEON_3R_VTST_VCEQ] = 0x7,
4805 [NEON_3R_VML] = 0x7,
4806 [NEON_3R_VMUL] = 0x7,
4807 [NEON_3R_VPMAX] = 0x7,
4808 [NEON_3R_VPMIN] = 0x7,
4809 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4810 [NEON_3R_VPADD] = 0x7,
4811 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4812 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4813 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4814 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4815 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4816 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4817 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4820 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4821 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4824 #define NEON_2RM_VREV64 0
4825 #define NEON_2RM_VREV32 1
4826 #define NEON_2RM_VREV16 2
4827 #define NEON_2RM_VPADDL 4
4828 #define NEON_2RM_VPADDL_U 5
4829 #define NEON_2RM_AESE 6 /* Includes AESD */
4830 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4831 #define NEON_2RM_VCLS 8
4832 #define NEON_2RM_VCLZ 9
4833 #define NEON_2RM_VCNT 10
4834 #define NEON_2RM_VMVN 11
4835 #define NEON_2RM_VPADAL 12
4836 #define NEON_2RM_VPADAL_U 13
4837 #define NEON_2RM_VQABS 14
4838 #define NEON_2RM_VQNEG 15
4839 #define NEON_2RM_VCGT0 16
4840 #define NEON_2RM_VCGE0 17
4841 #define NEON_2RM_VCEQ0 18
4842 #define NEON_2RM_VCLE0 19
4843 #define NEON_2RM_VCLT0 20
4844 #define NEON_2RM_VABS 22
4845 #define NEON_2RM_VNEG 23
4846 #define NEON_2RM_VCGT0_F 24
4847 #define NEON_2RM_VCGE0_F 25
4848 #define NEON_2RM_VCEQ0_F 26
4849 #define NEON_2RM_VCLE0_F 27
4850 #define NEON_2RM_VCLT0_F 28
4851 #define NEON_2RM_VABS_F 30
4852 #define NEON_2RM_VNEG_F 31
4853 #define NEON_2RM_VSWP 32
4854 #define NEON_2RM_VTRN 33
4855 #define NEON_2RM_VUZP 34
4856 #define NEON_2RM_VZIP 35
4857 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4858 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4859 #define NEON_2RM_VSHLL 38
4860 #define NEON_2RM_VRINTN 40
4861 #define NEON_2RM_VRINTX 41
4862 #define NEON_2RM_VRINTA 42
4863 #define NEON_2RM_VRINTZ 43
4864 #define NEON_2RM_VCVT_F16_F32 44
4865 #define NEON_2RM_VRINTM 45
4866 #define NEON_2RM_VCVT_F32_F16 46
4867 #define NEON_2RM_VRINTP 47
4868 #define NEON_2RM_VCVTAU 48
4869 #define NEON_2RM_VCVTAS 49
4870 #define NEON_2RM_VCVTNU 50
4871 #define NEON_2RM_VCVTNS 51
4872 #define NEON_2RM_VCVTPU 52
4873 #define NEON_2RM_VCVTPS 53
4874 #define NEON_2RM_VCVTMU 54
4875 #define NEON_2RM_VCVTMS 55
4876 #define NEON_2RM_VRECPE 56
4877 #define NEON_2RM_VRSQRTE 57
4878 #define NEON_2RM_VRECPE_F 58
4879 #define NEON_2RM_VRSQRTE_F 59
4880 #define NEON_2RM_VCVT_FS 60
4881 #define NEON_2RM_VCVT_FU 61
4882 #define NEON_2RM_VCVT_SF 62
4883 #define NEON_2RM_VCVT_UF 63
4885 static int neon_2rm_is_float_op(int op)
4887 /* Return true if this neon 2reg-misc op is float-to-float */
4888 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4889 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
4890 op == NEON_2RM_VRINTM ||
4891 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
4892 op >= NEON_2RM_VRECPE_F);
4895 /* Each entry in this array has bit n set if the insn allows
4896 * size value n (otherwise it will UNDEF). Since unallocated
4897 * op values will have no bits set they always UNDEF.
4899 static const uint8_t neon_2rm_sizes[] = {
4900 [NEON_2RM_VREV64] = 0x7,
4901 [NEON_2RM_VREV32] = 0x3,
4902 [NEON_2RM_VREV16] = 0x1,
4903 [NEON_2RM_VPADDL] = 0x7,
4904 [NEON_2RM_VPADDL_U] = 0x7,
4905 [NEON_2RM_AESE] = 0x1,
4906 [NEON_2RM_AESMC] = 0x1,
4907 [NEON_2RM_VCLS] = 0x7,
4908 [NEON_2RM_VCLZ] = 0x7,
4909 [NEON_2RM_VCNT] = 0x1,
4910 [NEON_2RM_VMVN] = 0x1,
4911 [NEON_2RM_VPADAL] = 0x7,
4912 [NEON_2RM_VPADAL_U] = 0x7,
4913 [NEON_2RM_VQABS] = 0x7,
4914 [NEON_2RM_VQNEG] = 0x7,
4915 [NEON_2RM_VCGT0] = 0x7,
4916 [NEON_2RM_VCGE0] = 0x7,
4917 [NEON_2RM_VCEQ0] = 0x7,
4918 [NEON_2RM_VCLE0] = 0x7,
4919 [NEON_2RM_VCLT0] = 0x7,
4920 [NEON_2RM_VABS] = 0x7,
4921 [NEON_2RM_VNEG] = 0x7,
4922 [NEON_2RM_VCGT0_F] = 0x4,
4923 [NEON_2RM_VCGE0_F] = 0x4,
4924 [NEON_2RM_VCEQ0_F] = 0x4,
4925 [NEON_2RM_VCLE0_F] = 0x4,
4926 [NEON_2RM_VCLT0_F] = 0x4,
4927 [NEON_2RM_VABS_F] = 0x4,
4928 [NEON_2RM_VNEG_F] = 0x4,
4929 [NEON_2RM_VSWP] = 0x1,
4930 [NEON_2RM_VTRN] = 0x7,
4931 [NEON_2RM_VUZP] = 0x7,
4932 [NEON_2RM_VZIP] = 0x7,
4933 [NEON_2RM_VMOVN] = 0x7,
4934 [NEON_2RM_VQMOVN] = 0x7,
4935 [NEON_2RM_VSHLL] = 0x7,
4936 [NEON_2RM_VRINTN] = 0x4,
4937 [NEON_2RM_VRINTX] = 0x4,
4938 [NEON_2RM_VRINTA] = 0x4,
4939 [NEON_2RM_VRINTZ] = 0x4,
4940 [NEON_2RM_VCVT_F16_F32] = 0x2,
4941 [NEON_2RM_VRINTM] = 0x4,
4942 [NEON_2RM_VCVT_F32_F16] = 0x2,
4943 [NEON_2RM_VRINTP] = 0x4,
4944 [NEON_2RM_VCVTAU] = 0x4,
4945 [NEON_2RM_VCVTAS] = 0x4,
4946 [NEON_2RM_VCVTNU] = 0x4,
4947 [NEON_2RM_VCVTNS] = 0x4,
4948 [NEON_2RM_VCVTPU] = 0x4,
4949 [NEON_2RM_VCVTPS] = 0x4,
4950 [NEON_2RM_VCVTMU] = 0x4,
4951 [NEON_2RM_VCVTMS] = 0x4,
4952 [NEON_2RM_VRECPE] = 0x4,
4953 [NEON_2RM_VRSQRTE] = 0x4,
4954 [NEON_2RM_VRECPE_F] = 0x4,
4955 [NEON_2RM_VRSQRTE_F] = 0x4,
4956 [NEON_2RM_VCVT_FS] = 0x4,
4957 [NEON_2RM_VCVT_FU] = 0x4,
4958 [NEON_2RM_VCVT_SF] = 0x4,
4959 [NEON_2RM_VCVT_UF] = 0x4,
4962 /* Translate a NEON data processing instruction. Return nonzero if the
4963 instruction is invalid.
4964 We process data in a mixture of 32-bit and 64-bit chunks.
4965 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4967 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4979 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4982 /* FIXME: this access check should not take precedence over UNDEF
4983 * for invalid encodings; we will generate incorrect syndrome information
4984 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4986 if (!s->cpacr_fpen) {
4987 gen_exception_insn(s, 4, EXCP_UDEF,
4988 syn_fp_access_trap(1, 0xe, s->thumb));
4992 if (!s->vfp_enabled)
4994 q = (insn & (1 << 6)) != 0;
4995 u = (insn >> 24) & 1;
4996 VFP_DREG_D(rd, insn);
4997 VFP_DREG_N(rn, insn);
4998 VFP_DREG_M(rm, insn);
4999 size = (insn >> 20) & 3;
5000 if ((insn & (1 << 23)) == 0) {
5001 /* Three register same length. */
5002 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5003 /* Catch invalid op and bad size combinations: UNDEF */
5004 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5007 /* All insns of this form UNDEF for either this condition or the
5008 * superset of cases "Q==1"; we catch the latter later.
5010 if (q && ((rd | rn | rm) & 1)) {
5013 if (size == 3 && op != NEON_3R_LOGIC) {
5014 /* 64-bit element instructions. */
5015 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5016 neon_load_reg64(cpu_V0, rn + pass);
5017 neon_load_reg64(cpu_V1, rm + pass);
5021 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5024 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5030 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5033 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5039 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5041 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5046 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5049 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5055 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5057 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5060 case NEON_3R_VQRSHL:
5062 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5065 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5069 case NEON_3R_VADD_VSUB:
5071 tcg_gen_sub_i64(CPU_V001);
5073 tcg_gen_add_i64(CPU_V001);
5079 neon_store_reg64(cpu_V0, rd + pass);
5088 case NEON_3R_VQRSHL:
5091 /* Shift instruction operands are reversed. */
5106 case NEON_3R_FLOAT_ARITH:
5107 pairwise = (u && size < 2); /* if VPADD (float) */
5109 case NEON_3R_FLOAT_MINMAX:
5110 pairwise = u; /* if VPMIN/VPMAX (float) */
5112 case NEON_3R_FLOAT_CMP:
5114 /* no encoding for U=0 C=1x */
5118 case NEON_3R_FLOAT_ACMP:
5123 case NEON_3R_FLOAT_MISC:
5124 /* VMAXNM/VMINNM in ARMv8 */
5125 if (u && !arm_feature(env, ARM_FEATURE_V8)) {
5130 if (u && (size != 0)) {
5131 /* UNDEF on invalid size for polynomial subcase */
5136 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
5144 if (pairwise && q) {
5145 /* All the pairwise insns UNDEF if Q is set */
5149 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5154 tmp = neon_load_reg(rn, 0);
5155 tmp2 = neon_load_reg(rn, 1);
5157 tmp = neon_load_reg(rm, 0);
5158 tmp2 = neon_load_reg(rm, 1);
5162 tmp = neon_load_reg(rn, pass);
5163 tmp2 = neon_load_reg(rm, pass);
5167 GEN_NEON_INTEGER_OP(hadd);
5170 GEN_NEON_INTEGER_OP_ENV(qadd);
5172 case NEON_3R_VRHADD:
5173 GEN_NEON_INTEGER_OP(rhadd);
5175 case NEON_3R_LOGIC: /* Logic ops. */
5176 switch ((u << 2) | size) {
5178 tcg_gen_and_i32(tmp, tmp, tmp2);
5181 tcg_gen_andc_i32(tmp, tmp, tmp2);
5184 tcg_gen_or_i32(tmp, tmp, tmp2);
5187 tcg_gen_orc_i32(tmp, tmp, tmp2);
5190 tcg_gen_xor_i32(tmp, tmp, tmp2);
5193 tmp3 = neon_load_reg(rd, pass);
5194 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5195 tcg_temp_free_i32(tmp3);
5198 tmp3 = neon_load_reg(rd, pass);
5199 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5200 tcg_temp_free_i32(tmp3);
5203 tmp3 = neon_load_reg(rd, pass);
5204 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5205 tcg_temp_free_i32(tmp3);
5210 GEN_NEON_INTEGER_OP(hsub);
5213 GEN_NEON_INTEGER_OP_ENV(qsub);
5216 GEN_NEON_INTEGER_OP(cgt);
5219 GEN_NEON_INTEGER_OP(cge);
5222 GEN_NEON_INTEGER_OP(shl);
5225 GEN_NEON_INTEGER_OP_ENV(qshl);
5228 GEN_NEON_INTEGER_OP(rshl);
5230 case NEON_3R_VQRSHL:
5231 GEN_NEON_INTEGER_OP_ENV(qrshl);
5234 GEN_NEON_INTEGER_OP(max);
5237 GEN_NEON_INTEGER_OP(min);
5240 GEN_NEON_INTEGER_OP(abd);
5243 GEN_NEON_INTEGER_OP(abd);
5244 tcg_temp_free_i32(tmp2);
5245 tmp2 = neon_load_reg(rd, pass);
5246 gen_neon_add(size, tmp, tmp2);
5248 case NEON_3R_VADD_VSUB:
5249 if (!u) { /* VADD */
5250 gen_neon_add(size, tmp, tmp2);
5253 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5254 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5255 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5260 case NEON_3R_VTST_VCEQ:
5261 if (!u) { /* VTST */
5263 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5264 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5265 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5270 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5271 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5272 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5277 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5279 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5280 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5281 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5284 tcg_temp_free_i32(tmp2);
5285 tmp2 = neon_load_reg(rd, pass);
5287 gen_neon_rsb(size, tmp, tmp2);
5289 gen_neon_add(size, tmp, tmp2);
5293 if (u) { /* polynomial */
5294 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5295 } else { /* Integer */
5297 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5298 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5299 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5305 GEN_NEON_INTEGER_OP(pmax);
5308 GEN_NEON_INTEGER_OP(pmin);
5310 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5311 if (!u) { /* VQDMULH */
5314 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5317 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5321 } else { /* VQRDMULH */
5324 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5327 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5335 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5336 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5337 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5341 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5343 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5344 switch ((u << 2) | size) {
5347 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5350 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5353 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5358 tcg_temp_free_ptr(fpstatus);
5361 case NEON_3R_FLOAT_MULTIPLY:
5363 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5364 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5366 tcg_temp_free_i32(tmp2);
5367 tmp2 = neon_load_reg(rd, pass);
5369 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5371 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5374 tcg_temp_free_ptr(fpstatus);
5377 case NEON_3R_FLOAT_CMP:
5379 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5381 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5384 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5386 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5389 tcg_temp_free_ptr(fpstatus);
5392 case NEON_3R_FLOAT_ACMP:
5394 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5396 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5398 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5400 tcg_temp_free_ptr(fpstatus);
5403 case NEON_3R_FLOAT_MINMAX:
5405 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5407 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5409 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5411 tcg_temp_free_ptr(fpstatus);
5414 case NEON_3R_FLOAT_MISC:
5417 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5419 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5421 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5423 tcg_temp_free_ptr(fpstatus);
5426 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5428 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5434 /* VFMA, VFMS: fused multiply-add */
5435 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5436 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5439 gen_helper_vfp_negs(tmp, tmp);
5441 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5442 tcg_temp_free_i32(tmp3);
5443 tcg_temp_free_ptr(fpstatus);
5449 tcg_temp_free_i32(tmp2);
5451 /* Save the result. For elementwise operations we can put it
5452 straight into the destination register. For pairwise operations
5453 we have to be careful to avoid clobbering the source operands. */
5454 if (pairwise && rd == rm) {
5455 neon_store_scratch(pass, tmp);
5457 neon_store_reg(rd, pass, tmp);
5461 if (pairwise && rd == rm) {
5462 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5463 tmp = neon_load_scratch(pass);
5464 neon_store_reg(rd, pass, tmp);
5467 /* End of 3 register same size operations. */
5468 } else if (insn & (1 << 4)) {
5469 if ((insn & 0x00380080) != 0) {
5470 /* Two registers and shift. */
5471 op = (insn >> 8) & 0xf;
5472 if (insn & (1 << 7)) {
5480 while ((insn & (1 << (size + 19))) == 0)
5483 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5484 /* To avoid excessive duplication of ops we implement shift
5485 by immediate using the variable shift operations. */
5487 /* Shift by immediate:
5488 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5489 if (q && ((rd | rm) & 1)) {
5492 if (!u && (op == 4 || op == 6)) {
5495 /* Right shifts are encoded as N - shift, where N is the
5496 element size in bits. */
5498 shift = shift - (1 << (size + 3));
5506 imm = (uint8_t) shift;
5511 imm = (uint16_t) shift;
5522 for (pass = 0; pass < count; pass++) {
5524 neon_load_reg64(cpu_V0, rm + pass);
5525 tcg_gen_movi_i64(cpu_V1, imm);
5530 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5532 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5537 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5539 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5542 case 5: /* VSHL, VSLI */
5543 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5545 case 6: /* VQSHLU */
5546 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5551 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5554 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5559 if (op == 1 || op == 3) {
5561 neon_load_reg64(cpu_V1, rd + pass);
5562 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5563 } else if (op == 4 || (op == 5 && u)) {
5565 neon_load_reg64(cpu_V1, rd + pass);
5567 if (shift < -63 || shift > 63) {
5571 mask = 0xffffffffffffffffull >> -shift;
5573 mask = 0xffffffffffffffffull << shift;
5576 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5577 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5579 neon_store_reg64(cpu_V0, rd + pass);
5580 } else { /* size < 3 */
5581 /* Operands in T0 and T1. */
5582 tmp = neon_load_reg(rm, pass);
5583 tmp2 = tcg_temp_new_i32();
5584 tcg_gen_movi_i32(tmp2, imm);
5588 GEN_NEON_INTEGER_OP(shl);
5592 GEN_NEON_INTEGER_OP(rshl);
5595 case 5: /* VSHL, VSLI */
5597 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5598 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5599 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5603 case 6: /* VQSHLU */
5606 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5610 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5614 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5622 GEN_NEON_INTEGER_OP_ENV(qshl);
5625 tcg_temp_free_i32(tmp2);
5627 if (op == 1 || op == 3) {
5629 tmp2 = neon_load_reg(rd, pass);
5630 gen_neon_add(size, tmp, tmp2);
5631 tcg_temp_free_i32(tmp2);
5632 } else if (op == 4 || (op == 5 && u)) {
5637 mask = 0xff >> -shift;
5639 mask = (uint8_t)(0xff << shift);
5645 mask = 0xffff >> -shift;
5647 mask = (uint16_t)(0xffff << shift);
5651 if (shift < -31 || shift > 31) {
5655 mask = 0xffffffffu >> -shift;
5657 mask = 0xffffffffu << shift;
5663 tmp2 = neon_load_reg(rd, pass);
5664 tcg_gen_andi_i32(tmp, tmp, mask);
5665 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5666 tcg_gen_or_i32(tmp, tmp, tmp2);
5667 tcg_temp_free_i32(tmp2);
5669 neon_store_reg(rd, pass, tmp);
5672 } else if (op < 10) {
5673 /* Shift by immediate and narrow:
5674 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5675 int input_unsigned = (op == 8) ? !u : u;
5679 shift = shift - (1 << (size + 3));
5682 tmp64 = tcg_const_i64(shift);
5683 neon_load_reg64(cpu_V0, rm);
5684 neon_load_reg64(cpu_V1, rm + 1);
5685 for (pass = 0; pass < 2; pass++) {
5693 if (input_unsigned) {
5694 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5696 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5699 if (input_unsigned) {
5700 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5702 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5705 tmp = tcg_temp_new_i32();
5706 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5707 neon_store_reg(rd, pass, tmp);
5709 tcg_temp_free_i64(tmp64);
5712 imm = (uint16_t)shift;
5716 imm = (uint32_t)shift;
5718 tmp2 = tcg_const_i32(imm);
5719 tmp4 = neon_load_reg(rm + 1, 0);
5720 tmp5 = neon_load_reg(rm + 1, 1);
5721 for (pass = 0; pass < 2; pass++) {
5723 tmp = neon_load_reg(rm, 0);
5727 gen_neon_shift_narrow(size, tmp, tmp2, q,
5730 tmp3 = neon_load_reg(rm, 1);
5734 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5736 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5737 tcg_temp_free_i32(tmp);
5738 tcg_temp_free_i32(tmp3);
5739 tmp = tcg_temp_new_i32();
5740 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5741 neon_store_reg(rd, pass, tmp);
5743 tcg_temp_free_i32(tmp2);
5745 } else if (op == 10) {
5747 if (q || (rd & 1)) {
5750 tmp = neon_load_reg(rm, 0);
5751 tmp2 = neon_load_reg(rm, 1);
5752 for (pass = 0; pass < 2; pass++) {
5756 gen_neon_widen(cpu_V0, tmp, size, u);
5759 /* The shift is less than the width of the source
5760 type, so we can just shift the whole register. */
5761 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5762 /* Widen the result of shift: we need to clear
5763 * the potential overflow bits resulting from
5764 * left bits of the narrow input appearing as
5765 * right bits of left the neighbour narrow
5767 if (size < 2 || !u) {
5770 imm = (0xffu >> (8 - shift));
5772 } else if (size == 1) {
5773 imm = 0xffff >> (16 - shift);
5776 imm = 0xffffffff >> (32 - shift);
5779 imm64 = imm | (((uint64_t)imm) << 32);
5783 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5786 neon_store_reg64(cpu_V0, rd + pass);
5788 } else if (op >= 14) {
5789 /* VCVT fixed-point. */
5790 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5793 /* We have already masked out the must-be-1 top bit of imm6,
5794 * hence this 32-shift where the ARM ARM has 64-imm6.
5797 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5798 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5801 gen_vfp_ulto(0, shift, 1);
5803 gen_vfp_slto(0, shift, 1);
5806 gen_vfp_toul(0, shift, 1);
5808 gen_vfp_tosl(0, shift, 1);
5810 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5815 } else { /* (insn & 0x00380080) == 0 */
5817 if (q && (rd & 1)) {
5821 op = (insn >> 8) & 0xf;
5822 /* One register and immediate. */
5823 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5824 invert = (insn & (1 << 5)) != 0;
5825 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5826 * We choose to not special-case this and will behave as if a
5827 * valid constant encoding of 0 had been given.
5846 imm = (imm << 8) | (imm << 24);
5849 imm = (imm << 8) | 0xff;
5852 imm = (imm << 16) | 0xffff;
5855 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5863 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5864 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5870 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5871 if (op & 1 && op < 12) {
5872 tmp = neon_load_reg(rd, pass);
5874 /* The immediate value has already been inverted, so
5876 tcg_gen_andi_i32(tmp, tmp, imm);
5878 tcg_gen_ori_i32(tmp, tmp, imm);
5882 tmp = tcg_temp_new_i32();
5883 if (op == 14 && invert) {
5887 for (n = 0; n < 4; n++) {
5888 if (imm & (1 << (n + (pass & 1) * 4)))
5889 val |= 0xff << (n * 8);
5891 tcg_gen_movi_i32(tmp, val);
5893 tcg_gen_movi_i32(tmp, imm);
5896 neon_store_reg(rd, pass, tmp);
5899 } else { /* (insn & 0x00800010 == 0x00800000) */
5901 op = (insn >> 8) & 0xf;
5902 if ((insn & (1 << 6)) == 0) {
5903 /* Three registers of different lengths. */
5907 /* undefreq: bit 0 : UNDEF if size != 0
5908 * bit 1 : UNDEF if size == 0
5909 * bit 2 : UNDEF if U == 1
5910 * Note that [1:0] set implies 'always UNDEF'
5913 /* prewiden, src1_wide, src2_wide, undefreq */
5914 static const int neon_3reg_wide[16][4] = {
5915 {1, 0, 0, 0}, /* VADDL */
5916 {1, 1, 0, 0}, /* VADDW */
5917 {1, 0, 0, 0}, /* VSUBL */
5918 {1, 1, 0, 0}, /* VSUBW */
5919 {0, 1, 1, 0}, /* VADDHN */
5920 {0, 0, 0, 0}, /* VABAL */
5921 {0, 1, 1, 0}, /* VSUBHN */
5922 {0, 0, 0, 0}, /* VABDL */
5923 {0, 0, 0, 0}, /* VMLAL */
5924 {0, 0, 0, 6}, /* VQDMLAL */
5925 {0, 0, 0, 0}, /* VMLSL */
5926 {0, 0, 0, 6}, /* VQDMLSL */
5927 {0, 0, 0, 0}, /* Integer VMULL */
5928 {0, 0, 0, 2}, /* VQDMULL */
5929 {0, 0, 0, 5}, /* Polynomial VMULL */
5930 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5933 prewiden = neon_3reg_wide[op][0];
5934 src1_wide = neon_3reg_wide[op][1];
5935 src2_wide = neon_3reg_wide[op][2];
5936 undefreq = neon_3reg_wide[op][3];
5938 if (((undefreq & 1) && (size != 0)) ||
5939 ((undefreq & 2) && (size == 0)) ||
5940 ((undefreq & 4) && u)) {
5943 if ((src1_wide && (rn & 1)) ||
5944 (src2_wide && (rm & 1)) ||
5945 (!src2_wide && (rd & 1))) {
5949 /* Avoid overlapping operands. Wide source operands are
5950 always aligned so will never overlap with wide
5951 destinations in problematic ways. */
5952 if (rd == rm && !src2_wide) {
5953 tmp = neon_load_reg(rm, 1);
5954 neon_store_scratch(2, tmp);
5955 } else if (rd == rn && !src1_wide) {
5956 tmp = neon_load_reg(rn, 1);
5957 neon_store_scratch(2, tmp);
5959 TCGV_UNUSED_I32(tmp3);
5960 for (pass = 0; pass < 2; pass++) {
5962 neon_load_reg64(cpu_V0, rn + pass);
5963 TCGV_UNUSED_I32(tmp);
5965 if (pass == 1 && rd == rn) {
5966 tmp = neon_load_scratch(2);
5968 tmp = neon_load_reg(rn, pass);
5971 gen_neon_widen(cpu_V0, tmp, size, u);
5975 neon_load_reg64(cpu_V1, rm + pass);
5976 TCGV_UNUSED_I32(tmp2);
5978 if (pass == 1 && rd == rm) {
5979 tmp2 = neon_load_scratch(2);
5981 tmp2 = neon_load_reg(rm, pass);
5984 gen_neon_widen(cpu_V1, tmp2, size, u);
5988 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5989 gen_neon_addl(size);
5991 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5992 gen_neon_subl(size);
5994 case 5: case 7: /* VABAL, VABDL */
5995 switch ((size << 1) | u) {
5997 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6000 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6003 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6006 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6009 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6012 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6016 tcg_temp_free_i32(tmp2);
6017 tcg_temp_free_i32(tmp);
6019 case 8: case 9: case 10: case 11: case 12: case 13:
6020 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6021 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6023 case 14: /* Polynomial VMULL */
6024 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6025 tcg_temp_free_i32(tmp2);
6026 tcg_temp_free_i32(tmp);
6028 default: /* 15 is RESERVED: caught earlier */
6033 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6034 neon_store_reg64(cpu_V0, rd + pass);
6035 } else if (op == 5 || (op >= 8 && op <= 11)) {
6037 neon_load_reg64(cpu_V1, rd + pass);
6039 case 10: /* VMLSL */
6040 gen_neon_negl(cpu_V0, size);
6042 case 5: case 8: /* VABAL, VMLAL */
6043 gen_neon_addl(size);
6045 case 9: case 11: /* VQDMLAL, VQDMLSL */
6046 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6048 gen_neon_negl(cpu_V0, size);
6050 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6055 neon_store_reg64(cpu_V0, rd + pass);
6056 } else if (op == 4 || op == 6) {
6057 /* Narrowing operation. */
6058 tmp = tcg_temp_new_i32();
6062 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6065 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6068 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6069 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6076 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6079 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6082 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6083 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6084 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6092 neon_store_reg(rd, 0, tmp3);
6093 neon_store_reg(rd, 1, tmp);
6096 /* Write back the result. */
6097 neon_store_reg64(cpu_V0, rd + pass);
6101 /* Two registers and a scalar. NB that for ops of this form
6102 * the ARM ARM labels bit 24 as Q, but it is in our variable
6109 case 1: /* Float VMLA scalar */
6110 case 5: /* Floating point VMLS scalar */
6111 case 9: /* Floating point VMUL scalar */
6116 case 0: /* Integer VMLA scalar */
6117 case 4: /* Integer VMLS scalar */
6118 case 8: /* Integer VMUL scalar */
6119 case 12: /* VQDMULH scalar */
6120 case 13: /* VQRDMULH scalar */
6121 if (u && ((rd | rn) & 1)) {
6124 tmp = neon_get_scalar(size, rm);
6125 neon_store_scratch(0, tmp);
6126 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6127 tmp = neon_load_scratch(0);
6128 tmp2 = neon_load_reg(rn, pass);
6131 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6133 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6135 } else if (op == 13) {
6137 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6139 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6141 } else if (op & 1) {
6142 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6143 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6144 tcg_temp_free_ptr(fpstatus);
6147 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6148 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6149 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6153 tcg_temp_free_i32(tmp2);
6156 tmp2 = neon_load_reg(rd, pass);
6159 gen_neon_add(size, tmp, tmp2);
6163 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6164 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6165 tcg_temp_free_ptr(fpstatus);
6169 gen_neon_rsb(size, tmp, tmp2);
6173 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6174 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6175 tcg_temp_free_ptr(fpstatus);
6181 tcg_temp_free_i32(tmp2);
6183 neon_store_reg(rd, pass, tmp);
6186 case 3: /* VQDMLAL scalar */
6187 case 7: /* VQDMLSL scalar */
6188 case 11: /* VQDMULL scalar */
6193 case 2: /* VMLAL sclar */
6194 case 6: /* VMLSL scalar */
6195 case 10: /* VMULL scalar */
6199 tmp2 = neon_get_scalar(size, rm);
6200 /* We need a copy of tmp2 because gen_neon_mull
6201 * deletes it during pass 0. */
6202 tmp4 = tcg_temp_new_i32();
6203 tcg_gen_mov_i32(tmp4, tmp2);
6204 tmp3 = neon_load_reg(rn, 1);
6206 for (pass = 0; pass < 2; pass++) {
6208 tmp = neon_load_reg(rn, 0);
6213 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6215 neon_load_reg64(cpu_V1, rd + pass);
6219 gen_neon_negl(cpu_V0, size);
6222 gen_neon_addl(size);
6225 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6227 gen_neon_negl(cpu_V0, size);
6229 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6235 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6240 neon_store_reg64(cpu_V0, rd + pass);
6245 default: /* 14 and 15 are RESERVED */
6249 } else { /* size == 3 */
6252 imm = (insn >> 8) & 0xf;
6257 if (q && ((rd | rn | rm) & 1)) {
6262 neon_load_reg64(cpu_V0, rn);
6264 neon_load_reg64(cpu_V1, rn + 1);
6266 } else if (imm == 8) {
6267 neon_load_reg64(cpu_V0, rn + 1);
6269 neon_load_reg64(cpu_V1, rm);
6272 tmp64 = tcg_temp_new_i64();
6274 neon_load_reg64(cpu_V0, rn);
6275 neon_load_reg64(tmp64, rn + 1);
6277 neon_load_reg64(cpu_V0, rn + 1);
6278 neon_load_reg64(tmp64, rm);
6280 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6281 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6282 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6284 neon_load_reg64(cpu_V1, rm);
6286 neon_load_reg64(cpu_V1, rm + 1);
6289 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6290 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6291 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6292 tcg_temp_free_i64(tmp64);
6295 neon_load_reg64(cpu_V0, rn);
6296 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6297 neon_load_reg64(cpu_V1, rm);
6298 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6299 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6301 neon_store_reg64(cpu_V0, rd);
6303 neon_store_reg64(cpu_V1, rd + 1);
6305 } else if ((insn & (1 << 11)) == 0) {
6306 /* Two register misc. */
6307 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6308 size = (insn >> 18) & 3;
6309 /* UNDEF for unknown op values and bad op-size combinations */
6310 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6313 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6314 q && ((rm | rd) & 1)) {
6318 case NEON_2RM_VREV64:
6319 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6320 tmp = neon_load_reg(rm, pass * 2);
6321 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6323 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6324 case 1: gen_swap_half(tmp); break;
6325 case 2: /* no-op */ break;
6328 neon_store_reg(rd, pass * 2 + 1, tmp);
6330 neon_store_reg(rd, pass * 2, tmp2);
6333 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6334 case 1: gen_swap_half(tmp2); break;
6337 neon_store_reg(rd, pass * 2, tmp2);
6341 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6342 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6343 for (pass = 0; pass < q + 1; pass++) {
6344 tmp = neon_load_reg(rm, pass * 2);
6345 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6346 tmp = neon_load_reg(rm, pass * 2 + 1);
6347 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6349 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6350 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6351 case 2: tcg_gen_add_i64(CPU_V001); break;
6354 if (op >= NEON_2RM_VPADAL) {
6356 neon_load_reg64(cpu_V1, rd + pass);
6357 gen_neon_addl(size);
6359 neon_store_reg64(cpu_V0, rd + pass);
6365 for (n = 0; n < (q ? 4 : 2); n += 2) {
6366 tmp = neon_load_reg(rm, n);
6367 tmp2 = neon_load_reg(rd, n + 1);
6368 neon_store_reg(rm, n, tmp2);
6369 neon_store_reg(rd, n + 1, tmp);
6376 if (gen_neon_unzip(rd, rm, size, q)) {
6381 if (gen_neon_zip(rd, rm, size, q)) {
6385 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6386 /* also VQMOVUN; op field and mnemonics don't line up */
6390 TCGV_UNUSED_I32(tmp2);
6391 for (pass = 0; pass < 2; pass++) {
6392 neon_load_reg64(cpu_V0, rm + pass);
6393 tmp = tcg_temp_new_i32();
6394 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6399 neon_store_reg(rd, 0, tmp2);
6400 neon_store_reg(rd, 1, tmp);
6404 case NEON_2RM_VSHLL:
6405 if (q || (rd & 1)) {
6408 tmp = neon_load_reg(rm, 0);
6409 tmp2 = neon_load_reg(rm, 1);
6410 for (pass = 0; pass < 2; pass++) {
6413 gen_neon_widen(cpu_V0, tmp, size, 1);
6414 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6415 neon_store_reg64(cpu_V0, rd + pass);
6418 case NEON_2RM_VCVT_F16_F32:
6419 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6423 tmp = tcg_temp_new_i32();
6424 tmp2 = tcg_temp_new_i32();
6425 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6426 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6427 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6428 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6429 tcg_gen_shli_i32(tmp2, tmp2, 16);
6430 tcg_gen_or_i32(tmp2, tmp2, tmp);
6431 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6432 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6433 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6434 neon_store_reg(rd, 0, tmp2);
6435 tmp2 = tcg_temp_new_i32();
6436 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6437 tcg_gen_shli_i32(tmp2, tmp2, 16);
6438 tcg_gen_or_i32(tmp2, tmp2, tmp);
6439 neon_store_reg(rd, 1, tmp2);
6440 tcg_temp_free_i32(tmp);
6442 case NEON_2RM_VCVT_F32_F16:
6443 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6447 tmp3 = tcg_temp_new_i32();
6448 tmp = neon_load_reg(rm, 0);
6449 tmp2 = neon_load_reg(rm, 1);
6450 tcg_gen_ext16u_i32(tmp3, tmp);
6451 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6452 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6453 tcg_gen_shri_i32(tmp3, tmp, 16);
6454 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6455 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6456 tcg_temp_free_i32(tmp);
6457 tcg_gen_ext16u_i32(tmp3, tmp2);
6458 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6459 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6460 tcg_gen_shri_i32(tmp3, tmp2, 16);
6461 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6462 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6463 tcg_temp_free_i32(tmp2);
6464 tcg_temp_free_i32(tmp3);
6466 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6467 if (!arm_feature(env, ARM_FEATURE_V8_AES)
6468 || ((rm | rd) & 1)) {
6471 tmp = tcg_const_i32(rd);
6472 tmp2 = tcg_const_i32(rm);
6474 /* Bit 6 is the lowest opcode bit; it distinguishes between
6475 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6477 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6479 if (op == NEON_2RM_AESE) {
6480 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6482 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6484 tcg_temp_free_i32(tmp);
6485 tcg_temp_free_i32(tmp2);
6486 tcg_temp_free_i32(tmp3);
6490 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6491 if (neon_2rm_is_float_op(op)) {
6492 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6493 neon_reg_offset(rm, pass));
6494 TCGV_UNUSED_I32(tmp);
6496 tmp = neon_load_reg(rm, pass);
6499 case NEON_2RM_VREV32:
6501 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6502 case 1: gen_swap_half(tmp); break;
6506 case NEON_2RM_VREV16:
6511 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6512 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6513 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6519 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6520 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6521 case 2: gen_helper_clz(tmp, tmp); break;
6526 gen_helper_neon_cnt_u8(tmp, tmp);
6529 tcg_gen_not_i32(tmp, tmp);
6531 case NEON_2RM_VQABS:
6534 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6537 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6540 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6545 case NEON_2RM_VQNEG:
6548 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6551 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6554 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6559 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6560 tmp2 = tcg_const_i32(0);
6562 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6563 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6564 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6567 tcg_temp_free_i32(tmp2);
6568 if (op == NEON_2RM_VCLE0) {
6569 tcg_gen_not_i32(tmp, tmp);
6572 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6573 tmp2 = tcg_const_i32(0);
6575 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6576 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6577 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6580 tcg_temp_free_i32(tmp2);
6581 if (op == NEON_2RM_VCLT0) {
6582 tcg_gen_not_i32(tmp, tmp);
6585 case NEON_2RM_VCEQ0:
6586 tmp2 = tcg_const_i32(0);
6588 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6589 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6590 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6593 tcg_temp_free_i32(tmp2);
6597 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6598 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6599 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6604 tmp2 = tcg_const_i32(0);
6605 gen_neon_rsb(size, tmp, tmp2);
6606 tcg_temp_free_i32(tmp2);
6608 case NEON_2RM_VCGT0_F:
6610 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6611 tmp2 = tcg_const_i32(0);
6612 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6613 tcg_temp_free_i32(tmp2);
6614 tcg_temp_free_ptr(fpstatus);
6617 case NEON_2RM_VCGE0_F:
6619 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6620 tmp2 = tcg_const_i32(0);
6621 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6622 tcg_temp_free_i32(tmp2);
6623 tcg_temp_free_ptr(fpstatus);
6626 case NEON_2RM_VCEQ0_F:
6628 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6629 tmp2 = tcg_const_i32(0);
6630 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6631 tcg_temp_free_i32(tmp2);
6632 tcg_temp_free_ptr(fpstatus);
6635 case NEON_2RM_VCLE0_F:
6637 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6638 tmp2 = tcg_const_i32(0);
6639 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6640 tcg_temp_free_i32(tmp2);
6641 tcg_temp_free_ptr(fpstatus);
6644 case NEON_2RM_VCLT0_F:
6646 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6647 tmp2 = tcg_const_i32(0);
6648 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6649 tcg_temp_free_i32(tmp2);
6650 tcg_temp_free_ptr(fpstatus);
6653 case NEON_2RM_VABS_F:
6656 case NEON_2RM_VNEG_F:
6660 tmp2 = neon_load_reg(rd, pass);
6661 neon_store_reg(rm, pass, tmp2);
6664 tmp2 = neon_load_reg(rd, pass);
6666 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6667 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6670 neon_store_reg(rm, pass, tmp2);
6672 case NEON_2RM_VRINTN:
6673 case NEON_2RM_VRINTA:
6674 case NEON_2RM_VRINTM:
6675 case NEON_2RM_VRINTP:
6676 case NEON_2RM_VRINTZ:
6679 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6682 if (op == NEON_2RM_VRINTZ) {
6683 rmode = FPROUNDING_ZERO;
6685 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6688 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6689 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6691 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
6692 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6694 tcg_temp_free_ptr(fpstatus);
6695 tcg_temp_free_i32(tcg_rmode);
6698 case NEON_2RM_VRINTX:
6700 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6701 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
6702 tcg_temp_free_ptr(fpstatus);
6705 case NEON_2RM_VCVTAU:
6706 case NEON_2RM_VCVTAS:
6707 case NEON_2RM_VCVTNU:
6708 case NEON_2RM_VCVTNS:
6709 case NEON_2RM_VCVTPU:
6710 case NEON_2RM_VCVTPS:
6711 case NEON_2RM_VCVTMU:
6712 case NEON_2RM_VCVTMS:
6714 bool is_signed = !extract32(insn, 7, 1);
6715 TCGv_ptr fpst = get_fpstatus_ptr(1);
6716 TCGv_i32 tcg_rmode, tcg_shift;
6717 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6719 tcg_shift = tcg_const_i32(0);
6720 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6721 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6725 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
6728 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
6732 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6734 tcg_temp_free_i32(tcg_rmode);
6735 tcg_temp_free_i32(tcg_shift);
6736 tcg_temp_free_ptr(fpst);
6739 case NEON_2RM_VRECPE:
6741 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6742 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6743 tcg_temp_free_ptr(fpstatus);
6746 case NEON_2RM_VRSQRTE:
6748 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6749 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6750 tcg_temp_free_ptr(fpstatus);
6753 case NEON_2RM_VRECPE_F:
6755 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6756 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
6757 tcg_temp_free_ptr(fpstatus);
6760 case NEON_2RM_VRSQRTE_F:
6762 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6763 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
6764 tcg_temp_free_ptr(fpstatus);
6767 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6770 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6773 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6774 gen_vfp_tosiz(0, 1);
6776 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6777 gen_vfp_touiz(0, 1);
6780 /* Reserved op values were caught by the
6781 * neon_2rm_sizes[] check earlier.
6785 if (neon_2rm_is_float_op(op)) {
6786 tcg_gen_st_f32(cpu_F0s, cpu_env,
6787 neon_reg_offset(rd, pass));
6789 neon_store_reg(rd, pass, tmp);
6794 } else if ((insn & (1 << 10)) == 0) {
6796 int n = ((insn >> 8) & 3) + 1;
6797 if ((rn + n) > 32) {
6798 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6799 * helper function running off the end of the register file.
6804 if (insn & (1 << 6)) {
6805 tmp = neon_load_reg(rd, 0);
6807 tmp = tcg_temp_new_i32();
6808 tcg_gen_movi_i32(tmp, 0);
6810 tmp2 = neon_load_reg(rm, 0);
6811 tmp4 = tcg_const_i32(rn);
6812 tmp5 = tcg_const_i32(n);
6813 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6814 tcg_temp_free_i32(tmp);
6815 if (insn & (1 << 6)) {
6816 tmp = neon_load_reg(rd, 1);
6818 tmp = tcg_temp_new_i32();
6819 tcg_gen_movi_i32(tmp, 0);
6821 tmp3 = neon_load_reg(rm, 1);
6822 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6823 tcg_temp_free_i32(tmp5);
6824 tcg_temp_free_i32(tmp4);
6825 neon_store_reg(rd, 0, tmp2);
6826 neon_store_reg(rd, 1, tmp3);
6827 tcg_temp_free_i32(tmp);
6828 } else if ((insn & 0x380) == 0) {
6830 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6833 if (insn & (1 << 19)) {
6834 tmp = neon_load_reg(rm, 1);
6836 tmp = neon_load_reg(rm, 0);
6838 if (insn & (1 << 16)) {
6839 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6840 } else if (insn & (1 << 17)) {
6841 if ((insn >> 18) & 1)
6842 gen_neon_dup_high16(tmp);
6844 gen_neon_dup_low16(tmp);
6846 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6847 tmp2 = tcg_temp_new_i32();
6848 tcg_gen_mov_i32(tmp2, tmp);
6849 neon_store_reg(rd, pass, tmp2);
6851 tcg_temp_free_i32(tmp);
6860 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6862 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6863 const ARMCPRegInfo *ri;
6865 cpnum = (insn >> 8) & 0xf;
6866 if (arm_feature(env, ARM_FEATURE_XSCALE)
6867 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6870 /* First check for coprocessor space used for actual instructions */
6874 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6875 return disas_iwmmxt_insn(env, s, insn);
6876 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6877 return disas_dsp_insn(env, s, insn);
6884 /* Otherwise treat as a generic register access */
6885 is64 = (insn & (1 << 25)) == 0;
6886 if (!is64 && ((insn & (1 << 4)) == 0)) {
6894 opc1 = (insn >> 4) & 0xf;
6896 rt2 = (insn >> 16) & 0xf;
6898 crn = (insn >> 16) & 0xf;
6899 opc1 = (insn >> 21) & 7;
6900 opc2 = (insn >> 5) & 7;
6903 isread = (insn >> 20) & 1;
6904 rt = (insn >> 12) & 0xf;
6906 ri = get_arm_cp_reginfo(s->cp_regs,
6907 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6909 /* Check access permissions */
6910 if (!cp_access_ok(s->current_pl, ri, isread)) {
6915 /* Emit code to perform further access permissions checks at
6916 * runtime; this may result in an exception.
6922 /* Note that since we are an implementation which takes an
6923 * exception on a trapped conditional instruction only if the
6924 * instruction passes its condition code check, we can take
6925 * advantage of the clause in the ARM ARM that allows us to set
6926 * the COND field in the instruction to 0xE in all cases.
6927 * We could fish the actual condition out of the insn (ARM)
6928 * or the condexec bits (Thumb) but it isn't necessary.
6933 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
6936 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
6937 rt, isread, s->thumb);
6942 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
6945 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
6946 rt, isread, s->thumb);
6950 /* ARMv8 defines that only coprocessors 14 and 15 exist,
6951 * so this can only happen if this is an ARMv7 or earlier CPU,
6952 * in which case the syndrome information won't actually be
6955 assert(!arm_feature(env, ARM_FEATURE_V8));
6956 syndrome = syn_uncategorized();
6960 gen_set_pc_im(s, s->pc);
6961 tmpptr = tcg_const_ptr(ri);
6962 tcg_syn = tcg_const_i32(syndrome);
6963 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
6964 tcg_temp_free_ptr(tmpptr);
6965 tcg_temp_free_i32(tcg_syn);
6968 /* Handle special cases first */
6969 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6976 gen_set_pc_im(s, s->pc);
6977 s->is_jmp = DISAS_WFI;
6983 if (use_icount && (ri->type & ARM_CP_IO)) {
6992 if (ri->type & ARM_CP_CONST) {
6993 tmp64 = tcg_const_i64(ri->resetvalue);
6994 } else if (ri->readfn) {
6996 tmp64 = tcg_temp_new_i64();
6997 tmpptr = tcg_const_ptr(ri);
6998 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6999 tcg_temp_free_ptr(tmpptr);
7001 tmp64 = tcg_temp_new_i64();
7002 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7004 tmp = tcg_temp_new_i32();
7005 tcg_gen_trunc_i64_i32(tmp, tmp64);
7006 store_reg(s, rt, tmp);
7007 tcg_gen_shri_i64(tmp64, tmp64, 32);
7008 tmp = tcg_temp_new_i32();
7009 tcg_gen_trunc_i64_i32(tmp, tmp64);
7010 tcg_temp_free_i64(tmp64);
7011 store_reg(s, rt2, tmp);
7014 if (ri->type & ARM_CP_CONST) {
7015 tmp = tcg_const_i32(ri->resetvalue);
7016 } else if (ri->readfn) {
7018 tmp = tcg_temp_new_i32();
7019 tmpptr = tcg_const_ptr(ri);
7020 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7021 tcg_temp_free_ptr(tmpptr);
7023 tmp = load_cpu_offset(ri->fieldoffset);
7026 /* Destination register of r15 for 32 bit loads sets
7027 * the condition codes from the high 4 bits of the value
7030 tcg_temp_free_i32(tmp);
7032 store_reg(s, rt, tmp);
7037 if (ri->type & ARM_CP_CONST) {
7038 /* If not forbidden by access permissions, treat as WI */
7043 TCGv_i32 tmplo, tmphi;
7044 TCGv_i64 tmp64 = tcg_temp_new_i64();
7045 tmplo = load_reg(s, rt);
7046 tmphi = load_reg(s, rt2);
7047 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7048 tcg_temp_free_i32(tmplo);
7049 tcg_temp_free_i32(tmphi);
7051 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7052 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7053 tcg_temp_free_ptr(tmpptr);
7055 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7057 tcg_temp_free_i64(tmp64);
7062 tmp = load_reg(s, rt);
7063 tmpptr = tcg_const_ptr(ri);
7064 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7065 tcg_temp_free_ptr(tmpptr);
7066 tcg_temp_free_i32(tmp);
7068 TCGv_i32 tmp = load_reg(s, rt);
7069 store_cpu_offset(tmp, ri->fieldoffset);
7074 if (use_icount && (ri->type & ARM_CP_IO)) {
7075 /* I/O operations must end the TB here (whether read or write) */
7078 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7079 /* We default to ending the TB on a coprocessor register write,
7080 * but allow this to be suppressed by the register definition
7081 * (usually only necessary to work around guest bugs).
7089 /* Unknown register; this might be a guest error or a QEMU
7090 * unimplemented feature.
7093 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7094 "64 bit system register cp:%d opc1: %d crm:%d\n",
7095 isread ? "read" : "write", cpnum, opc1, crm);
7097 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7098 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7099 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
7106 /* Store a 64-bit value to a register pair. Clobbers val. */
7107 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7110 tmp = tcg_temp_new_i32();
7111 tcg_gen_trunc_i64_i32(tmp, val);
7112 store_reg(s, rlow, tmp);
7113 tmp = tcg_temp_new_i32();
7114 tcg_gen_shri_i64(val, val, 32);
7115 tcg_gen_trunc_i64_i32(tmp, val);
7116 store_reg(s, rhigh, tmp);
7119 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7120 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7125 /* Load value and extend to 64 bits. */
7126 tmp = tcg_temp_new_i64();
7127 tmp2 = load_reg(s, rlow);
7128 tcg_gen_extu_i32_i64(tmp, tmp2);
7129 tcg_temp_free_i32(tmp2);
7130 tcg_gen_add_i64(val, val, tmp);
7131 tcg_temp_free_i64(tmp);
7134 /* load and add a 64-bit value from a register pair. */
7135 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7141 /* Load 64-bit value rd:rn. */
7142 tmpl = load_reg(s, rlow);
7143 tmph = load_reg(s, rhigh);
7144 tmp = tcg_temp_new_i64();
7145 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7146 tcg_temp_free_i32(tmpl);
7147 tcg_temp_free_i32(tmph);
7148 tcg_gen_add_i64(val, val, tmp);
7149 tcg_temp_free_i64(tmp);
7152 /* Set N and Z flags from hi|lo. */
7153 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7155 tcg_gen_mov_i32(cpu_NF, hi);
7156 tcg_gen_or_i32(cpu_ZF, lo, hi);
7159 /* Load/Store exclusive instructions are implemented by remembering
7160 the value/address loaded, and seeing if these are the same
7161 when the store is performed. This should be sufficient to implement
7162 the architecturally mandated semantics, and avoids having to monitor
7165 In system emulation mode only one CPU will be running at once, so
7166 this sequence is effectively atomic. In user emulation mode we
7167 throw an exception and handle the atomic operation elsewhere. */
7168 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7169 TCGv_i32 addr, int size)
7171 TCGv_i32 tmp = tcg_temp_new_i32();
7175 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
7178 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
7182 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7189 TCGv_i32 tmp2 = tcg_temp_new_i32();
7190 TCGv_i32 tmp3 = tcg_temp_new_i32();
7192 tcg_gen_addi_i32(tmp2, addr, 4);
7193 gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s));
7194 tcg_temp_free_i32(tmp2);
7195 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7196 store_reg(s, rt2, tmp3);
7198 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7201 store_reg(s, rt, tmp);
7202 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7205 static void gen_clrex(DisasContext *s)
7207 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7210 #ifdef CONFIG_USER_ONLY
7211 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7212 TCGv_i32 addr, int size)
7214 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7215 tcg_gen_movi_i32(cpu_exclusive_info,
7216 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7217 gen_exception_internal_insn(s, 4, EXCP_STREX);
7220 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7221 TCGv_i32 addr, int size)
7224 TCGv_i64 val64, extaddr;
7228 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7234 fail_label = gen_new_label();
7235 done_label = gen_new_label();
7236 extaddr = tcg_temp_new_i64();
7237 tcg_gen_extu_i32_i64(extaddr, addr);
7238 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7239 tcg_temp_free_i64(extaddr);
7241 tmp = tcg_temp_new_i32();
7244 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
7247 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
7251 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7257 val64 = tcg_temp_new_i64();
7259 TCGv_i32 tmp2 = tcg_temp_new_i32();
7260 TCGv_i32 tmp3 = tcg_temp_new_i32();
7261 tcg_gen_addi_i32(tmp2, addr, 4);
7262 gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s));
7263 tcg_temp_free_i32(tmp2);
7264 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7265 tcg_temp_free_i32(tmp3);
7267 tcg_gen_extu_i32_i64(val64, tmp);
7269 tcg_temp_free_i32(tmp);
7271 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7272 tcg_temp_free_i64(val64);
7274 tmp = load_reg(s, rt);
7277 gen_aa32_st8(tmp, addr, get_mem_index(s));
7280 gen_aa32_st16(tmp, addr, get_mem_index(s));
7284 gen_aa32_st32(tmp, addr, get_mem_index(s));
7289 tcg_temp_free_i32(tmp);
7291 tcg_gen_addi_i32(addr, addr, 4);
7292 tmp = load_reg(s, rt2);
7293 gen_aa32_st32(tmp, addr, get_mem_index(s));
7294 tcg_temp_free_i32(tmp);
7296 tcg_gen_movi_i32(cpu_R[rd], 0);
7297 tcg_gen_br(done_label);
7298 gen_set_label(fail_label);
7299 tcg_gen_movi_i32(cpu_R[rd], 1);
7300 gen_set_label(done_label);
7301 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7308 * @mode: mode field from insn (which stack to store to)
7309 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7310 * @writeback: true if writeback bit set
7312 * Generate code for the SRS (Store Return State) insn.
7314 static void gen_srs(DisasContext *s,
7315 uint32_t mode, uint32_t amode, bool writeback)
7318 TCGv_i32 addr = tcg_temp_new_i32();
7319 TCGv_i32 tmp = tcg_const_i32(mode);
7320 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7321 tcg_temp_free_i32(tmp);
7338 tcg_gen_addi_i32(addr, addr, offset);
7339 tmp = load_reg(s, 14);
7340 gen_aa32_st32(tmp, addr, get_mem_index(s));
7341 tcg_temp_free_i32(tmp);
7342 tmp = load_cpu_field(spsr);
7343 tcg_gen_addi_i32(addr, addr, 4);
7344 gen_aa32_st32(tmp, addr, get_mem_index(s));
7345 tcg_temp_free_i32(tmp);
7363 tcg_gen_addi_i32(addr, addr, offset);
7364 tmp = tcg_const_i32(mode);
7365 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7366 tcg_temp_free_i32(tmp);
7368 tcg_temp_free_i32(addr);
7371 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
7373 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
7380 insn = arm_ldl_code(env, s->pc, s->bswap_code);
7383 /* M variants do not implement ARM mode. */
7388 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7389 * choose to UNDEF. In ARMv5 and above the space is used
7390 * for miscellaneous unconditional instructions.
7394 /* Unconditional instructions. */
7395 if (((insn >> 25) & 7) == 1) {
7396 /* NEON Data processing. */
7397 if (!arm_feature(env, ARM_FEATURE_NEON))
7400 if (disas_neon_data_insn(env, s, insn))
7404 if ((insn & 0x0f100000) == 0x04000000) {
7405 /* NEON load/store. */
7406 if (!arm_feature(env, ARM_FEATURE_NEON))
7409 if (disas_neon_ls_insn(env, s, insn))
7413 if ((insn & 0x0f000e10) == 0x0e000a00) {
7415 if (disas_vfp_insn(env, s, insn)) {
7420 if (((insn & 0x0f30f000) == 0x0510f000) ||
7421 ((insn & 0x0f30f010) == 0x0710f000)) {
7422 if ((insn & (1 << 22)) == 0) {
7424 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7428 /* Otherwise PLD; v5TE+ */
7432 if (((insn & 0x0f70f000) == 0x0450f000) ||
7433 ((insn & 0x0f70f010) == 0x0650f000)) {
7435 return; /* PLI; V7 */
7437 if (((insn & 0x0f700000) == 0x04100000) ||
7438 ((insn & 0x0f700010) == 0x06100000)) {
7439 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7442 return; /* v7MP: Unallocated memory hint: must NOP */
7445 if ((insn & 0x0ffffdff) == 0x01010000) {
7448 if (((insn >> 9) & 1) != s->bswap_code) {
7449 /* Dynamic endianness switching not implemented. */
7450 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7454 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7455 switch ((insn >> 4) & 0xf) {
7464 /* We don't emulate caches so these are a no-op. */
7469 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7475 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7477 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7483 rn = (insn >> 16) & 0xf;
7484 addr = load_reg(s, rn);
7485 i = (insn >> 23) & 3;
7487 case 0: offset = -4; break; /* DA */
7488 case 1: offset = 0; break; /* IA */
7489 case 2: offset = -8; break; /* DB */
7490 case 3: offset = 4; break; /* IB */
7494 tcg_gen_addi_i32(addr, addr, offset);
7495 /* Load PC into tmp and CPSR into tmp2. */
7496 tmp = tcg_temp_new_i32();
7497 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7498 tcg_gen_addi_i32(addr, addr, 4);
7499 tmp2 = tcg_temp_new_i32();
7500 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
7501 if (insn & (1 << 21)) {
7502 /* Base writeback. */
7504 case 0: offset = -8; break;
7505 case 1: offset = 4; break;
7506 case 2: offset = -4; break;
7507 case 3: offset = 0; break;
7511 tcg_gen_addi_i32(addr, addr, offset);
7512 store_reg(s, rn, addr);
7514 tcg_temp_free_i32(addr);
7516 gen_rfe(s, tmp, tmp2);
7518 } else if ((insn & 0x0e000000) == 0x0a000000) {
7519 /* branch link and change to thumb (blx <offset>) */
7522 val = (uint32_t)s->pc;
7523 tmp = tcg_temp_new_i32();
7524 tcg_gen_movi_i32(tmp, val);
7525 store_reg(s, 14, tmp);
7526 /* Sign-extend the 24-bit offset */
7527 offset = (((int32_t)insn) << 8) >> 8;
7528 /* offset * 4 + bit24 * 2 + (thumb bit) */
7529 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7530 /* pipeline offset */
7532 /* protected by ARCH(5); above, near the start of uncond block */
7535 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7536 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7537 /* iWMMXt register transfer. */
7538 if (env->cp15.c15_cpar & (1 << 1))
7539 if (!disas_iwmmxt_insn(env, s, insn))
7542 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7543 /* Coprocessor double register transfer. */
7545 } else if ((insn & 0x0f000010) == 0x0e000010) {
7546 /* Additional coprocessor register transfer. */
7547 } else if ((insn & 0x0ff10020) == 0x01000000) {
7550 /* cps (privileged) */
7554 if (insn & (1 << 19)) {
7555 if (insn & (1 << 8))
7557 if (insn & (1 << 7))
7559 if (insn & (1 << 6))
7561 if (insn & (1 << 18))
7564 if (insn & (1 << 17)) {
7566 val |= (insn & 0x1f);
7569 gen_set_psr_im(s, mask, 0, val);
7576 /* if not always execute, we generate a conditional jump to
7578 s->condlabel = gen_new_label();
7579 arm_gen_test_cc(cond ^ 1, s->condlabel);
7582 if ((insn & 0x0f900000) == 0x03000000) {
7583 if ((insn & (1 << 21)) == 0) {
7585 rd = (insn >> 12) & 0xf;
7586 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7587 if ((insn & (1 << 22)) == 0) {
7589 tmp = tcg_temp_new_i32();
7590 tcg_gen_movi_i32(tmp, val);
7593 tmp = load_reg(s, rd);
7594 tcg_gen_ext16u_i32(tmp, tmp);
7595 tcg_gen_ori_i32(tmp, tmp, val << 16);
7597 store_reg(s, rd, tmp);
7599 if (((insn >> 12) & 0xf) != 0xf)
7601 if (((insn >> 16) & 0xf) == 0) {
7602 gen_nop_hint(s, insn & 0xff);
7604 /* CPSR = immediate */
7606 shift = ((insn >> 8) & 0xf) * 2;
7608 val = (val >> shift) | (val << (32 - shift));
7609 i = ((insn & (1 << 22)) != 0);
7610 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7614 } else if ((insn & 0x0f900000) == 0x01000000
7615 && (insn & 0x00000090) != 0x00000090) {
7616 /* miscellaneous instructions */
7617 op1 = (insn >> 21) & 3;
7618 sh = (insn >> 4) & 0xf;
7621 case 0x0: /* move program status register */
7624 tmp = load_reg(s, rm);
7625 i = ((op1 & 2) != 0);
7626 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7630 rd = (insn >> 12) & 0xf;
7634 tmp = load_cpu_field(spsr);
7636 tmp = tcg_temp_new_i32();
7637 gen_helper_cpsr_read(tmp, cpu_env);
7639 store_reg(s, rd, tmp);
7644 /* branch/exchange thumb (bx). */
7646 tmp = load_reg(s, rm);
7648 } else if (op1 == 3) {
7651 rd = (insn >> 12) & 0xf;
7652 tmp = load_reg(s, rm);
7653 gen_helper_clz(tmp, tmp);
7654 store_reg(s, rd, tmp);
7662 /* Trivial implementation equivalent to bx. */
7663 tmp = load_reg(s, rm);
7674 /* branch link/exchange thumb (blx) */
7675 tmp = load_reg(s, rm);
7676 tmp2 = tcg_temp_new_i32();
7677 tcg_gen_movi_i32(tmp2, s->pc);
7678 store_reg(s, 14, tmp2);
7684 uint32_t c = extract32(insn, 8, 4);
7686 /* Check this CPU supports ARMv8 CRC instructions.
7687 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7688 * Bits 8, 10 and 11 should be zero.
7690 if (!arm_feature(env, ARM_FEATURE_CRC) || op1 == 0x3 ||
7695 rn = extract32(insn, 16, 4);
7696 rd = extract32(insn, 12, 4);
7698 tmp = load_reg(s, rn);
7699 tmp2 = load_reg(s, rm);
7700 tmp3 = tcg_const_i32(1 << op1);
7702 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
7704 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
7706 tcg_temp_free_i32(tmp2);
7707 tcg_temp_free_i32(tmp3);
7708 store_reg(s, rd, tmp);
7711 case 0x5: /* saturating add/subtract */
7713 rd = (insn >> 12) & 0xf;
7714 rn = (insn >> 16) & 0xf;
7715 tmp = load_reg(s, rm);
7716 tmp2 = load_reg(s, rn);
7718 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7720 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7722 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7723 tcg_temp_free_i32(tmp2);
7724 store_reg(s, rd, tmp);
7728 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
7729 /* SMC instruction (op1 == 3)
7730 and undefined instructions (op1 == 0 || op1 == 2)
7737 gen_exception_insn(s, 4, EXCP_BKPT, syn_aa32_bkpt(imm16, false));
7740 case 0x8: /* signed multiply */
7745 rs = (insn >> 8) & 0xf;
7746 rn = (insn >> 12) & 0xf;
7747 rd = (insn >> 16) & 0xf;
7749 /* (32 * 16) >> 16 */
7750 tmp = load_reg(s, rm);
7751 tmp2 = load_reg(s, rs);
7753 tcg_gen_sari_i32(tmp2, tmp2, 16);
7756 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7757 tcg_gen_shri_i64(tmp64, tmp64, 16);
7758 tmp = tcg_temp_new_i32();
7759 tcg_gen_trunc_i64_i32(tmp, tmp64);
7760 tcg_temp_free_i64(tmp64);
7761 if ((sh & 2) == 0) {
7762 tmp2 = load_reg(s, rn);
7763 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7764 tcg_temp_free_i32(tmp2);
7766 store_reg(s, rd, tmp);
7769 tmp = load_reg(s, rm);
7770 tmp2 = load_reg(s, rs);
7771 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7772 tcg_temp_free_i32(tmp2);
7774 tmp64 = tcg_temp_new_i64();
7775 tcg_gen_ext_i32_i64(tmp64, tmp);
7776 tcg_temp_free_i32(tmp);
7777 gen_addq(s, tmp64, rn, rd);
7778 gen_storeq_reg(s, rn, rd, tmp64);
7779 tcg_temp_free_i64(tmp64);
7782 tmp2 = load_reg(s, rn);
7783 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7784 tcg_temp_free_i32(tmp2);
7786 store_reg(s, rd, tmp);
7793 } else if (((insn & 0x0e000000) == 0 &&
7794 (insn & 0x00000090) != 0x90) ||
7795 ((insn & 0x0e000000) == (1 << 25))) {
7796 int set_cc, logic_cc, shiftop;
7798 op1 = (insn >> 21) & 0xf;
7799 set_cc = (insn >> 20) & 1;
7800 logic_cc = table_logic_cc[op1] & set_cc;
7802 /* data processing instruction */
7803 if (insn & (1 << 25)) {
7804 /* immediate operand */
7806 shift = ((insn >> 8) & 0xf) * 2;
7808 val = (val >> shift) | (val << (32 - shift));
7810 tmp2 = tcg_temp_new_i32();
7811 tcg_gen_movi_i32(tmp2, val);
7812 if (logic_cc && shift) {
7813 gen_set_CF_bit31(tmp2);
7818 tmp2 = load_reg(s, rm);
7819 shiftop = (insn >> 5) & 3;
7820 if (!(insn & (1 << 4))) {
7821 shift = (insn >> 7) & 0x1f;
7822 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7824 rs = (insn >> 8) & 0xf;
7825 tmp = load_reg(s, rs);
7826 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7829 if (op1 != 0x0f && op1 != 0x0d) {
7830 rn = (insn >> 16) & 0xf;
7831 tmp = load_reg(s, rn);
7833 TCGV_UNUSED_I32(tmp);
7835 rd = (insn >> 12) & 0xf;
7838 tcg_gen_and_i32(tmp, tmp, tmp2);
7842 store_reg_bx(env, s, rd, tmp);
7845 tcg_gen_xor_i32(tmp, tmp, tmp2);
7849 store_reg_bx(env, s, rd, tmp);
7852 if (set_cc && rd == 15) {
7853 /* SUBS r15, ... is used for exception return. */
7857 gen_sub_CC(tmp, tmp, tmp2);
7858 gen_exception_return(s, tmp);
7861 gen_sub_CC(tmp, tmp, tmp2);
7863 tcg_gen_sub_i32(tmp, tmp, tmp2);
7865 store_reg_bx(env, s, rd, tmp);
7870 gen_sub_CC(tmp, tmp2, tmp);
7872 tcg_gen_sub_i32(tmp, tmp2, tmp);
7874 store_reg_bx(env, s, rd, tmp);
7878 gen_add_CC(tmp, tmp, tmp2);
7880 tcg_gen_add_i32(tmp, tmp, tmp2);
7882 store_reg_bx(env, s, rd, tmp);
7886 gen_adc_CC(tmp, tmp, tmp2);
7888 gen_add_carry(tmp, tmp, tmp2);
7890 store_reg_bx(env, s, rd, tmp);
7894 gen_sbc_CC(tmp, tmp, tmp2);
7896 gen_sub_carry(tmp, tmp, tmp2);
7898 store_reg_bx(env, s, rd, tmp);
7902 gen_sbc_CC(tmp, tmp2, tmp);
7904 gen_sub_carry(tmp, tmp2, tmp);
7906 store_reg_bx(env, s, rd, tmp);
7910 tcg_gen_and_i32(tmp, tmp, tmp2);
7913 tcg_temp_free_i32(tmp);
7917 tcg_gen_xor_i32(tmp, tmp, tmp2);
7920 tcg_temp_free_i32(tmp);
7924 gen_sub_CC(tmp, tmp, tmp2);
7926 tcg_temp_free_i32(tmp);
7930 gen_add_CC(tmp, tmp, tmp2);
7932 tcg_temp_free_i32(tmp);
7935 tcg_gen_or_i32(tmp, tmp, tmp2);
7939 store_reg_bx(env, s, rd, tmp);
7942 if (logic_cc && rd == 15) {
7943 /* MOVS r15, ... is used for exception return. */
7947 gen_exception_return(s, tmp2);
7952 store_reg_bx(env, s, rd, tmp2);
7956 tcg_gen_andc_i32(tmp, tmp, tmp2);
7960 store_reg_bx(env, s, rd, tmp);
7964 tcg_gen_not_i32(tmp2, tmp2);
7968 store_reg_bx(env, s, rd, tmp2);
7971 if (op1 != 0x0f && op1 != 0x0d) {
7972 tcg_temp_free_i32(tmp2);
7975 /* other instructions */
7976 op1 = (insn >> 24) & 0xf;
7980 /* multiplies, extra load/stores */
7981 sh = (insn >> 5) & 3;
7984 rd = (insn >> 16) & 0xf;
7985 rn = (insn >> 12) & 0xf;
7986 rs = (insn >> 8) & 0xf;
7988 op1 = (insn >> 20) & 0xf;
7990 case 0: case 1: case 2: case 3: case 6:
7992 tmp = load_reg(s, rs);
7993 tmp2 = load_reg(s, rm);
7994 tcg_gen_mul_i32(tmp, tmp, tmp2);
7995 tcg_temp_free_i32(tmp2);
7996 if (insn & (1 << 22)) {
7997 /* Subtract (mls) */
7999 tmp2 = load_reg(s, rn);
8000 tcg_gen_sub_i32(tmp, tmp2, tmp);
8001 tcg_temp_free_i32(tmp2);
8002 } else if (insn & (1 << 21)) {
8004 tmp2 = load_reg(s, rn);
8005 tcg_gen_add_i32(tmp, tmp, tmp2);
8006 tcg_temp_free_i32(tmp2);
8008 if (insn & (1 << 20))
8010 store_reg(s, rd, tmp);
8013 /* 64 bit mul double accumulate (UMAAL) */
8015 tmp = load_reg(s, rs);
8016 tmp2 = load_reg(s, rm);
8017 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8018 gen_addq_lo(s, tmp64, rn);
8019 gen_addq_lo(s, tmp64, rd);
8020 gen_storeq_reg(s, rn, rd, tmp64);
8021 tcg_temp_free_i64(tmp64);
8023 case 8: case 9: case 10: case 11:
8024 case 12: case 13: case 14: case 15:
8025 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8026 tmp = load_reg(s, rs);
8027 tmp2 = load_reg(s, rm);
8028 if (insn & (1 << 22)) {
8029 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8031 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8033 if (insn & (1 << 21)) { /* mult accumulate */
8034 TCGv_i32 al = load_reg(s, rn);
8035 TCGv_i32 ah = load_reg(s, rd);
8036 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8037 tcg_temp_free_i32(al);
8038 tcg_temp_free_i32(ah);
8040 if (insn & (1 << 20)) {
8041 gen_logicq_cc(tmp, tmp2);
8043 store_reg(s, rn, tmp);
8044 store_reg(s, rd, tmp2);
8050 rn = (insn >> 16) & 0xf;
8051 rd = (insn >> 12) & 0xf;
8052 if (insn & (1 << 23)) {
8053 /* load/store exclusive */
8054 int op2 = (insn >> 8) & 3;
8055 op1 = (insn >> 21) & 0x3;
8058 case 0: /* lda/stl */
8064 case 1: /* reserved */
8066 case 2: /* ldaex/stlex */
8069 case 3: /* ldrex/strex */
8078 addr = tcg_temp_local_new_i32();
8079 load_reg_var(s, addr, rn);
8081 /* Since the emulation does not have barriers,
8082 the acquire/release semantics need no special
8085 if (insn & (1 << 20)) {
8086 tmp = tcg_temp_new_i32();
8089 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8092 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
8095 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
8100 store_reg(s, rd, tmp);
8103 tmp = load_reg(s, rm);
8106 gen_aa32_st32(tmp, addr, get_mem_index(s));
8109 gen_aa32_st8(tmp, addr, get_mem_index(s));
8112 gen_aa32_st16(tmp, addr, get_mem_index(s));
8117 tcg_temp_free_i32(tmp);
8119 } else if (insn & (1 << 20)) {
8122 gen_load_exclusive(s, rd, 15, addr, 2);
8124 case 1: /* ldrexd */
8125 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8127 case 2: /* ldrexb */
8128 gen_load_exclusive(s, rd, 15, addr, 0);
8130 case 3: /* ldrexh */
8131 gen_load_exclusive(s, rd, 15, addr, 1);
8140 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8142 case 1: /* strexd */
8143 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8145 case 2: /* strexb */
8146 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8148 case 3: /* strexh */
8149 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8155 tcg_temp_free_i32(addr);
8157 /* SWP instruction */
8160 /* ??? This is not really atomic. However we know
8161 we never have multiple CPUs running in parallel,
8162 so it is good enough. */
8163 addr = load_reg(s, rn);
8164 tmp = load_reg(s, rm);
8165 tmp2 = tcg_temp_new_i32();
8166 if (insn & (1 << 22)) {
8167 gen_aa32_ld8u(tmp2, addr, get_mem_index(s));
8168 gen_aa32_st8(tmp, addr, get_mem_index(s));
8170 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
8171 gen_aa32_st32(tmp, addr, get_mem_index(s));
8173 tcg_temp_free_i32(tmp);
8174 tcg_temp_free_i32(addr);
8175 store_reg(s, rd, tmp2);
8181 /* Misc load/store */
8182 rn = (insn >> 16) & 0xf;
8183 rd = (insn >> 12) & 0xf;
8184 addr = load_reg(s, rn);
8185 if (insn & (1 << 24))
8186 gen_add_datah_offset(s, insn, 0, addr);
8188 if (insn & (1 << 20)) {
8190 tmp = tcg_temp_new_i32();
8193 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
8196 gen_aa32_ld8s(tmp, addr, get_mem_index(s));
8200 gen_aa32_ld16s(tmp, addr, get_mem_index(s));
8204 } else if (sh & 2) {
8209 tmp = load_reg(s, rd);
8210 gen_aa32_st32(tmp, addr, get_mem_index(s));
8211 tcg_temp_free_i32(tmp);
8212 tcg_gen_addi_i32(addr, addr, 4);
8213 tmp = load_reg(s, rd + 1);
8214 gen_aa32_st32(tmp, addr, get_mem_index(s));
8215 tcg_temp_free_i32(tmp);
8219 tmp = tcg_temp_new_i32();
8220 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8221 store_reg(s, rd, tmp);
8222 tcg_gen_addi_i32(addr, addr, 4);
8223 tmp = tcg_temp_new_i32();
8224 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8228 address_offset = -4;
8231 tmp = load_reg(s, rd);
8232 gen_aa32_st16(tmp, addr, get_mem_index(s));
8233 tcg_temp_free_i32(tmp);
8236 /* Perform base writeback before the loaded value to
8237 ensure correct behavior with overlapping index registers.
8238 ldrd with base writeback is is undefined if the
8239 destination and index registers overlap. */
8240 if (!(insn & (1 << 24))) {
8241 gen_add_datah_offset(s, insn, address_offset, addr);
8242 store_reg(s, rn, addr);
8243 } else if (insn & (1 << 21)) {
8245 tcg_gen_addi_i32(addr, addr, address_offset);
8246 store_reg(s, rn, addr);
8248 tcg_temp_free_i32(addr);
8251 /* Complete the load. */
8252 store_reg(s, rd, tmp);
8261 if (insn & (1 << 4)) {
8263 /* Armv6 Media instructions. */
8265 rn = (insn >> 16) & 0xf;
8266 rd = (insn >> 12) & 0xf;
8267 rs = (insn >> 8) & 0xf;
8268 switch ((insn >> 23) & 3) {
8269 case 0: /* Parallel add/subtract. */
8270 op1 = (insn >> 20) & 7;
8271 tmp = load_reg(s, rn);
8272 tmp2 = load_reg(s, rm);
8273 sh = (insn >> 5) & 7;
8274 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8276 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8277 tcg_temp_free_i32(tmp2);
8278 store_reg(s, rd, tmp);
8281 if ((insn & 0x00700020) == 0) {
8282 /* Halfword pack. */
8283 tmp = load_reg(s, rn);
8284 tmp2 = load_reg(s, rm);
8285 shift = (insn >> 7) & 0x1f;
8286 if (insn & (1 << 6)) {
8290 tcg_gen_sari_i32(tmp2, tmp2, shift);
8291 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8292 tcg_gen_ext16u_i32(tmp2, tmp2);
8296 tcg_gen_shli_i32(tmp2, tmp2, shift);
8297 tcg_gen_ext16u_i32(tmp, tmp);
8298 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8300 tcg_gen_or_i32(tmp, tmp, tmp2);
8301 tcg_temp_free_i32(tmp2);
8302 store_reg(s, rd, tmp);
8303 } else if ((insn & 0x00200020) == 0x00200000) {
8305 tmp = load_reg(s, rm);
8306 shift = (insn >> 7) & 0x1f;
8307 if (insn & (1 << 6)) {
8310 tcg_gen_sari_i32(tmp, tmp, shift);
8312 tcg_gen_shli_i32(tmp, tmp, shift);
8314 sh = (insn >> 16) & 0x1f;
8315 tmp2 = tcg_const_i32(sh);
8316 if (insn & (1 << 22))
8317 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8319 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8320 tcg_temp_free_i32(tmp2);
8321 store_reg(s, rd, tmp);
8322 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8324 tmp = load_reg(s, rm);
8325 sh = (insn >> 16) & 0x1f;
8326 tmp2 = tcg_const_i32(sh);
8327 if (insn & (1 << 22))
8328 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8330 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8331 tcg_temp_free_i32(tmp2);
8332 store_reg(s, rd, tmp);
8333 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8335 tmp = load_reg(s, rn);
8336 tmp2 = load_reg(s, rm);
8337 tmp3 = tcg_temp_new_i32();
8338 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8339 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8340 tcg_temp_free_i32(tmp3);
8341 tcg_temp_free_i32(tmp2);
8342 store_reg(s, rd, tmp);
8343 } else if ((insn & 0x000003e0) == 0x00000060) {
8344 tmp = load_reg(s, rm);
8345 shift = (insn >> 10) & 3;
8346 /* ??? In many cases it's not necessary to do a
8347 rotate, a shift is sufficient. */
8349 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8350 op1 = (insn >> 20) & 7;
8352 case 0: gen_sxtb16(tmp); break;
8353 case 2: gen_sxtb(tmp); break;
8354 case 3: gen_sxth(tmp); break;
8355 case 4: gen_uxtb16(tmp); break;
8356 case 6: gen_uxtb(tmp); break;
8357 case 7: gen_uxth(tmp); break;
8358 default: goto illegal_op;
8361 tmp2 = load_reg(s, rn);
8362 if ((op1 & 3) == 0) {
8363 gen_add16(tmp, tmp2);
8365 tcg_gen_add_i32(tmp, tmp, tmp2);
8366 tcg_temp_free_i32(tmp2);
8369 store_reg(s, rd, tmp);
8370 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8372 tmp = load_reg(s, rm);
8373 if (insn & (1 << 22)) {
8374 if (insn & (1 << 7)) {
8378 gen_helper_rbit(tmp, tmp);
8381 if (insn & (1 << 7))
8384 tcg_gen_bswap32_i32(tmp, tmp);
8386 store_reg(s, rd, tmp);
8391 case 2: /* Multiplies (Type 3). */
8392 switch ((insn >> 20) & 0x7) {
8394 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8395 /* op2 not 00x or 11x : UNDEF */
8398 /* Signed multiply most significant [accumulate].
8399 (SMMUL, SMMLA, SMMLS) */
8400 tmp = load_reg(s, rm);
8401 tmp2 = load_reg(s, rs);
8402 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8405 tmp = load_reg(s, rd);
8406 if (insn & (1 << 6)) {
8407 tmp64 = gen_subq_msw(tmp64, tmp);
8409 tmp64 = gen_addq_msw(tmp64, tmp);
8412 if (insn & (1 << 5)) {
8413 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8415 tcg_gen_shri_i64(tmp64, tmp64, 32);
8416 tmp = tcg_temp_new_i32();
8417 tcg_gen_trunc_i64_i32(tmp, tmp64);
8418 tcg_temp_free_i64(tmp64);
8419 store_reg(s, rn, tmp);
8423 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8424 if (insn & (1 << 7)) {
8427 tmp = load_reg(s, rm);
8428 tmp2 = load_reg(s, rs);
8429 if (insn & (1 << 5))
8430 gen_swap_half(tmp2);
8431 gen_smul_dual(tmp, tmp2);
8432 if (insn & (1 << 22)) {
8433 /* smlald, smlsld */
8436 tmp64 = tcg_temp_new_i64();
8437 tmp64_2 = tcg_temp_new_i64();
8438 tcg_gen_ext_i32_i64(tmp64, tmp);
8439 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8440 tcg_temp_free_i32(tmp);
8441 tcg_temp_free_i32(tmp2);
8442 if (insn & (1 << 6)) {
8443 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8445 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8447 tcg_temp_free_i64(tmp64_2);
8448 gen_addq(s, tmp64, rd, rn);
8449 gen_storeq_reg(s, rd, rn, tmp64);
8450 tcg_temp_free_i64(tmp64);
8452 /* smuad, smusd, smlad, smlsd */
8453 if (insn & (1 << 6)) {
8454 /* This subtraction cannot overflow. */
8455 tcg_gen_sub_i32(tmp, tmp, tmp2);
8457 /* This addition cannot overflow 32 bits;
8458 * however it may overflow considered as a
8459 * signed operation, in which case we must set
8462 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8464 tcg_temp_free_i32(tmp2);
8467 tmp2 = load_reg(s, rd);
8468 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8469 tcg_temp_free_i32(tmp2);
8471 store_reg(s, rn, tmp);
8477 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8480 if (((insn >> 5) & 7) || (rd != 15)) {
8483 tmp = load_reg(s, rm);
8484 tmp2 = load_reg(s, rs);
8485 if (insn & (1 << 21)) {
8486 gen_helper_udiv(tmp, tmp, tmp2);
8488 gen_helper_sdiv(tmp, tmp, tmp2);
8490 tcg_temp_free_i32(tmp2);
8491 store_reg(s, rn, tmp);
8498 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8500 case 0: /* Unsigned sum of absolute differences. */
8502 tmp = load_reg(s, rm);
8503 tmp2 = load_reg(s, rs);
8504 gen_helper_usad8(tmp, tmp, tmp2);
8505 tcg_temp_free_i32(tmp2);
8507 tmp2 = load_reg(s, rd);
8508 tcg_gen_add_i32(tmp, tmp, tmp2);
8509 tcg_temp_free_i32(tmp2);
8511 store_reg(s, rn, tmp);
8513 case 0x20: case 0x24: case 0x28: case 0x2c:
8514 /* Bitfield insert/clear. */
8516 shift = (insn >> 7) & 0x1f;
8517 i = (insn >> 16) & 0x1f;
8520 tmp = tcg_temp_new_i32();
8521 tcg_gen_movi_i32(tmp, 0);
8523 tmp = load_reg(s, rm);
8526 tmp2 = load_reg(s, rd);
8527 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8528 tcg_temp_free_i32(tmp2);
8530 store_reg(s, rd, tmp);
8532 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8533 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8535 tmp = load_reg(s, rm);
8536 shift = (insn >> 7) & 0x1f;
8537 i = ((insn >> 16) & 0x1f) + 1;
8542 gen_ubfx(tmp, shift, (1u << i) - 1);
8544 gen_sbfx(tmp, shift, i);
8547 store_reg(s, rd, tmp);
8557 /* Check for undefined extension instructions
8558 * per the ARM Bible IE:
8559 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8561 sh = (0xf << 20) | (0xf << 4);
8562 if (op1 == 0x7 && ((insn & sh) == sh))
8566 /* load/store byte/word */
8567 rn = (insn >> 16) & 0xf;
8568 rd = (insn >> 12) & 0xf;
8569 tmp2 = load_reg(s, rn);
8570 if ((insn & 0x01200000) == 0x00200000) {
8574 i = get_mem_index(s);
8576 if (insn & (1 << 24))
8577 gen_add_data_offset(s, insn, tmp2);
8578 if (insn & (1 << 20)) {
8580 tmp = tcg_temp_new_i32();
8581 if (insn & (1 << 22)) {
8582 gen_aa32_ld8u(tmp, tmp2, i);
8584 gen_aa32_ld32u(tmp, tmp2, i);
8588 tmp = load_reg(s, rd);
8589 if (insn & (1 << 22)) {
8590 gen_aa32_st8(tmp, tmp2, i);
8592 gen_aa32_st32(tmp, tmp2, i);
8594 tcg_temp_free_i32(tmp);
8596 if (!(insn & (1 << 24))) {
8597 gen_add_data_offset(s, insn, tmp2);
8598 store_reg(s, rn, tmp2);
8599 } else if (insn & (1 << 21)) {
8600 store_reg(s, rn, tmp2);
8602 tcg_temp_free_i32(tmp2);
8604 if (insn & (1 << 20)) {
8605 /* Complete the load. */
8606 store_reg_from_load(env, s, rd, tmp);
8612 int j, n, user, loaded_base;
8613 TCGv_i32 loaded_var;
8614 /* load/store multiple words */
8615 /* XXX: store correct base if write back */
8617 if (insn & (1 << 22)) {
8619 goto illegal_op; /* only usable in supervisor mode */
8621 if ((insn & (1 << 15)) == 0)
8624 rn = (insn >> 16) & 0xf;
8625 addr = load_reg(s, rn);
8627 /* compute total size */
8629 TCGV_UNUSED_I32(loaded_var);
8632 if (insn & (1 << i))
8635 /* XXX: test invalid n == 0 case ? */
8636 if (insn & (1 << 23)) {
8637 if (insn & (1 << 24)) {
8639 tcg_gen_addi_i32(addr, addr, 4);
8641 /* post increment */
8644 if (insn & (1 << 24)) {
8646 tcg_gen_addi_i32(addr, addr, -(n * 4));
8648 /* post decrement */
8650 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8655 if (insn & (1 << i)) {
8656 if (insn & (1 << 20)) {
8658 tmp = tcg_temp_new_i32();
8659 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8661 tmp2 = tcg_const_i32(i);
8662 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8663 tcg_temp_free_i32(tmp2);
8664 tcg_temp_free_i32(tmp);
8665 } else if (i == rn) {
8669 store_reg_from_load(env, s, i, tmp);
8674 /* special case: r15 = PC + 8 */
8675 val = (long)s->pc + 4;
8676 tmp = tcg_temp_new_i32();
8677 tcg_gen_movi_i32(tmp, val);
8679 tmp = tcg_temp_new_i32();
8680 tmp2 = tcg_const_i32(i);
8681 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8682 tcg_temp_free_i32(tmp2);
8684 tmp = load_reg(s, i);
8686 gen_aa32_st32(tmp, addr, get_mem_index(s));
8687 tcg_temp_free_i32(tmp);
8690 /* no need to add after the last transfer */
8692 tcg_gen_addi_i32(addr, addr, 4);
8695 if (insn & (1 << 21)) {
8697 if (insn & (1 << 23)) {
8698 if (insn & (1 << 24)) {
8701 /* post increment */
8702 tcg_gen_addi_i32(addr, addr, 4);
8705 if (insn & (1 << 24)) {
8708 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8710 /* post decrement */
8711 tcg_gen_addi_i32(addr, addr, -(n * 4));
8714 store_reg(s, rn, addr);
8716 tcg_temp_free_i32(addr);
8719 store_reg(s, rn, loaded_var);
8721 if ((insn & (1 << 22)) && !user) {
8722 /* Restore CPSR from SPSR. */
8723 tmp = load_cpu_field(spsr);
8724 gen_set_cpsr(tmp, 0xffffffff);
8725 tcg_temp_free_i32(tmp);
8726 s->is_jmp = DISAS_UPDATE;
8735 /* branch (and link) */
8736 val = (int32_t)s->pc;
8737 if (insn & (1 << 24)) {
8738 tmp = tcg_temp_new_i32();
8739 tcg_gen_movi_i32(tmp, val);
8740 store_reg(s, 14, tmp);
8742 offset = sextract32(insn << 2, 0, 26);
8750 if (((insn >> 8) & 0xe) == 10) {
8752 if (disas_vfp_insn(env, s, insn)) {
8755 } else if (disas_coproc_insn(env, s, insn)) {
8762 gen_set_pc_im(s, s->pc);
8763 s->svc_imm = extract32(insn, 0, 24);
8764 s->is_jmp = DISAS_SWI;
8768 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
8774 /* Return true if this is a Thumb-2 logical op. */
8776 thumb2_logic_op(int op)
8781 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8782 then set condition code flags based on the result of the operation.
8783 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8784 to the high bit of T1.
8785 Returns zero if the opcode is valid. */
8788 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8789 TCGv_i32 t0, TCGv_i32 t1)
8796 tcg_gen_and_i32(t0, t0, t1);
8800 tcg_gen_andc_i32(t0, t0, t1);
8804 tcg_gen_or_i32(t0, t0, t1);
8808 tcg_gen_orc_i32(t0, t0, t1);
8812 tcg_gen_xor_i32(t0, t0, t1);
8817 gen_add_CC(t0, t0, t1);
8819 tcg_gen_add_i32(t0, t0, t1);
8823 gen_adc_CC(t0, t0, t1);
8829 gen_sbc_CC(t0, t0, t1);
8831 gen_sub_carry(t0, t0, t1);
8836 gen_sub_CC(t0, t0, t1);
8838 tcg_gen_sub_i32(t0, t0, t1);
8842 gen_sub_CC(t0, t1, t0);
8844 tcg_gen_sub_i32(t0, t1, t0);
8846 default: /* 5, 6, 7, 9, 12, 15. */
8852 gen_set_CF_bit31(t1);
8857 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8859 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8861 uint32_t insn, imm, shift, offset;
8862 uint32_t rd, rn, rm, rs;
8873 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8874 || arm_feature (env, ARM_FEATURE_M))) {
8875 /* Thumb-1 cores may need to treat bl and blx as a pair of
8876 16-bit instructions to get correct prefetch abort behavior. */
8878 if ((insn & (1 << 12)) == 0) {
8880 /* Second half of blx. */
8881 offset = ((insn & 0x7ff) << 1);
8882 tmp = load_reg(s, 14);
8883 tcg_gen_addi_i32(tmp, tmp, offset);
8884 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8886 tmp2 = tcg_temp_new_i32();
8887 tcg_gen_movi_i32(tmp2, s->pc | 1);
8888 store_reg(s, 14, tmp2);
8892 if (insn & (1 << 11)) {
8893 /* Second half of bl. */
8894 offset = ((insn & 0x7ff) << 1) | 1;
8895 tmp = load_reg(s, 14);
8896 tcg_gen_addi_i32(tmp, tmp, offset);
8898 tmp2 = tcg_temp_new_i32();
8899 tcg_gen_movi_i32(tmp2, s->pc | 1);
8900 store_reg(s, 14, tmp2);
8904 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8905 /* Instruction spans a page boundary. Implement it as two
8906 16-bit instructions in case the second half causes an
8908 offset = ((int32_t)insn << 21) >> 9;
8909 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8912 /* Fall through to 32-bit decode. */
8915 insn = arm_lduw_code(env, s->pc, s->bswap_code);
8917 insn |= (uint32_t)insn_hw1 << 16;
8919 if ((insn & 0xf800e800) != 0xf000e800) {
8923 rn = (insn >> 16) & 0xf;
8924 rs = (insn >> 12) & 0xf;
8925 rd = (insn >> 8) & 0xf;
8927 switch ((insn >> 25) & 0xf) {
8928 case 0: case 1: case 2: case 3:
8929 /* 16-bit instructions. Should never happen. */
8932 if (insn & (1 << 22)) {
8933 /* Other load/store, table branch. */
8934 if (insn & 0x01200000) {
8935 /* Load/store doubleword. */
8937 addr = tcg_temp_new_i32();
8938 tcg_gen_movi_i32(addr, s->pc & ~3);
8940 addr = load_reg(s, rn);
8942 offset = (insn & 0xff) * 4;
8943 if ((insn & (1 << 23)) == 0)
8945 if (insn & (1 << 24)) {
8946 tcg_gen_addi_i32(addr, addr, offset);
8949 if (insn & (1 << 20)) {
8951 tmp = tcg_temp_new_i32();
8952 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8953 store_reg(s, rs, tmp);
8954 tcg_gen_addi_i32(addr, addr, 4);
8955 tmp = tcg_temp_new_i32();
8956 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8957 store_reg(s, rd, tmp);
8960 tmp = load_reg(s, rs);
8961 gen_aa32_st32(tmp, addr, get_mem_index(s));
8962 tcg_temp_free_i32(tmp);
8963 tcg_gen_addi_i32(addr, addr, 4);
8964 tmp = load_reg(s, rd);
8965 gen_aa32_st32(tmp, addr, get_mem_index(s));
8966 tcg_temp_free_i32(tmp);
8968 if (insn & (1 << 21)) {
8969 /* Base writeback. */
8972 tcg_gen_addi_i32(addr, addr, offset - 4);
8973 store_reg(s, rn, addr);
8975 tcg_temp_free_i32(addr);
8977 } else if ((insn & (1 << 23)) == 0) {
8978 /* Load/store exclusive word. */
8979 addr = tcg_temp_local_new_i32();
8980 load_reg_var(s, addr, rn);
8981 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8982 if (insn & (1 << 20)) {
8983 gen_load_exclusive(s, rs, 15, addr, 2);
8985 gen_store_exclusive(s, rd, rs, 15, addr, 2);
8987 tcg_temp_free_i32(addr);
8988 } else if ((insn & (7 << 5)) == 0) {
8991 addr = tcg_temp_new_i32();
8992 tcg_gen_movi_i32(addr, s->pc);
8994 addr = load_reg(s, rn);
8996 tmp = load_reg(s, rm);
8997 tcg_gen_add_i32(addr, addr, tmp);
8998 if (insn & (1 << 4)) {
9000 tcg_gen_add_i32(addr, addr, tmp);
9001 tcg_temp_free_i32(tmp);
9002 tmp = tcg_temp_new_i32();
9003 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
9005 tcg_temp_free_i32(tmp);
9006 tmp = tcg_temp_new_i32();
9007 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
9009 tcg_temp_free_i32(addr);
9010 tcg_gen_shli_i32(tmp, tmp, 1);
9011 tcg_gen_addi_i32(tmp, tmp, s->pc);
9012 store_reg(s, 15, tmp);
9014 int op2 = (insn >> 6) & 0x3;
9015 op = (insn >> 4) & 0x3;
9020 /* Load/store exclusive byte/halfword/doubleword */
9027 /* Load-acquire/store-release */
9033 /* Load-acquire/store-release exclusive */
9037 addr = tcg_temp_local_new_i32();
9038 load_reg_var(s, addr, rn);
9040 if (insn & (1 << 20)) {
9041 tmp = tcg_temp_new_i32();
9044 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
9047 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
9050 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9055 store_reg(s, rs, tmp);
9057 tmp = load_reg(s, rs);
9060 gen_aa32_st8(tmp, addr, get_mem_index(s));
9063 gen_aa32_st16(tmp, addr, get_mem_index(s));
9066 gen_aa32_st32(tmp, addr, get_mem_index(s));
9071 tcg_temp_free_i32(tmp);
9073 } else if (insn & (1 << 20)) {
9074 gen_load_exclusive(s, rs, rd, addr, op);
9076 gen_store_exclusive(s, rm, rs, rd, addr, op);
9078 tcg_temp_free_i32(addr);
9081 /* Load/store multiple, RFE, SRS. */
9082 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9083 /* RFE, SRS: not available in user mode or on M profile */
9084 if (IS_USER(s) || IS_M(env)) {
9087 if (insn & (1 << 20)) {
9089 addr = load_reg(s, rn);
9090 if ((insn & (1 << 24)) == 0)
9091 tcg_gen_addi_i32(addr, addr, -8);
9092 /* Load PC into tmp and CPSR into tmp2. */
9093 tmp = tcg_temp_new_i32();
9094 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9095 tcg_gen_addi_i32(addr, addr, 4);
9096 tmp2 = tcg_temp_new_i32();
9097 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
9098 if (insn & (1 << 21)) {
9099 /* Base writeback. */
9100 if (insn & (1 << 24)) {
9101 tcg_gen_addi_i32(addr, addr, 4);
9103 tcg_gen_addi_i32(addr, addr, -4);
9105 store_reg(s, rn, addr);
9107 tcg_temp_free_i32(addr);
9109 gen_rfe(s, tmp, tmp2);
9112 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9116 int i, loaded_base = 0;
9117 TCGv_i32 loaded_var;
9118 /* Load/store multiple. */
9119 addr = load_reg(s, rn);
9121 for (i = 0; i < 16; i++) {
9122 if (insn & (1 << i))
9125 if (insn & (1 << 24)) {
9126 tcg_gen_addi_i32(addr, addr, -offset);
9129 TCGV_UNUSED_I32(loaded_var);
9130 for (i = 0; i < 16; i++) {
9131 if ((insn & (1 << i)) == 0)
9133 if (insn & (1 << 20)) {
9135 tmp = tcg_temp_new_i32();
9136 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9139 } else if (i == rn) {
9143 store_reg(s, i, tmp);
9147 tmp = load_reg(s, i);
9148 gen_aa32_st32(tmp, addr, get_mem_index(s));
9149 tcg_temp_free_i32(tmp);
9151 tcg_gen_addi_i32(addr, addr, 4);
9154 store_reg(s, rn, loaded_var);
9156 if (insn & (1 << 21)) {
9157 /* Base register writeback. */
9158 if (insn & (1 << 24)) {
9159 tcg_gen_addi_i32(addr, addr, -offset);
9161 /* Fault if writeback register is in register list. */
9162 if (insn & (1 << rn))
9164 store_reg(s, rn, addr);
9166 tcg_temp_free_i32(addr);
9173 op = (insn >> 21) & 0xf;
9175 /* Halfword pack. */
9176 tmp = load_reg(s, rn);
9177 tmp2 = load_reg(s, rm);
9178 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9179 if (insn & (1 << 5)) {
9183 tcg_gen_sari_i32(tmp2, tmp2, shift);
9184 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9185 tcg_gen_ext16u_i32(tmp2, tmp2);
9189 tcg_gen_shli_i32(tmp2, tmp2, shift);
9190 tcg_gen_ext16u_i32(tmp, tmp);
9191 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9193 tcg_gen_or_i32(tmp, tmp, tmp2);
9194 tcg_temp_free_i32(tmp2);
9195 store_reg(s, rd, tmp);
9197 /* Data processing register constant shift. */
9199 tmp = tcg_temp_new_i32();
9200 tcg_gen_movi_i32(tmp, 0);
9202 tmp = load_reg(s, rn);
9204 tmp2 = load_reg(s, rm);
9206 shiftop = (insn >> 4) & 3;
9207 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9208 conds = (insn & (1 << 20)) != 0;
9209 logic_cc = (conds && thumb2_logic_op(op));
9210 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9211 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9213 tcg_temp_free_i32(tmp2);
9215 store_reg(s, rd, tmp);
9217 tcg_temp_free_i32(tmp);
9221 case 13: /* Misc data processing. */
9222 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9223 if (op < 4 && (insn & 0xf000) != 0xf000)
9226 case 0: /* Register controlled shift. */
9227 tmp = load_reg(s, rn);
9228 tmp2 = load_reg(s, rm);
9229 if ((insn & 0x70) != 0)
9231 op = (insn >> 21) & 3;
9232 logic_cc = (insn & (1 << 20)) != 0;
9233 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9236 store_reg_bx(env, s, rd, tmp);
9238 case 1: /* Sign/zero extend. */
9239 tmp = load_reg(s, rm);
9240 shift = (insn >> 4) & 3;
9241 /* ??? In many cases it's not necessary to do a
9242 rotate, a shift is sufficient. */
9244 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9245 op = (insn >> 20) & 7;
9247 case 0: gen_sxth(tmp); break;
9248 case 1: gen_uxth(tmp); break;
9249 case 2: gen_sxtb16(tmp); break;
9250 case 3: gen_uxtb16(tmp); break;
9251 case 4: gen_sxtb(tmp); break;
9252 case 5: gen_uxtb(tmp); break;
9253 default: goto illegal_op;
9256 tmp2 = load_reg(s, rn);
9257 if ((op >> 1) == 1) {
9258 gen_add16(tmp, tmp2);
9260 tcg_gen_add_i32(tmp, tmp, tmp2);
9261 tcg_temp_free_i32(tmp2);
9264 store_reg(s, rd, tmp);
9266 case 2: /* SIMD add/subtract. */
9267 op = (insn >> 20) & 7;
9268 shift = (insn >> 4) & 7;
9269 if ((op & 3) == 3 || (shift & 3) == 3)
9271 tmp = load_reg(s, rn);
9272 tmp2 = load_reg(s, rm);
9273 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9274 tcg_temp_free_i32(tmp2);
9275 store_reg(s, rd, tmp);
9277 case 3: /* Other data processing. */
9278 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9280 /* Saturating add/subtract. */
9281 tmp = load_reg(s, rn);
9282 tmp2 = load_reg(s, rm);
9284 gen_helper_double_saturate(tmp, cpu_env, tmp);
9286 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9288 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9289 tcg_temp_free_i32(tmp2);
9291 tmp = load_reg(s, rn);
9293 case 0x0a: /* rbit */
9294 gen_helper_rbit(tmp, tmp);
9296 case 0x08: /* rev */
9297 tcg_gen_bswap32_i32(tmp, tmp);
9299 case 0x09: /* rev16 */
9302 case 0x0b: /* revsh */
9305 case 0x10: /* sel */
9306 tmp2 = load_reg(s, rm);
9307 tmp3 = tcg_temp_new_i32();
9308 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9309 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9310 tcg_temp_free_i32(tmp3);
9311 tcg_temp_free_i32(tmp2);
9313 case 0x18: /* clz */
9314 gen_helper_clz(tmp, tmp);
9324 uint32_t sz = op & 0x3;
9325 uint32_t c = op & 0x8;
9327 if (!arm_feature(env, ARM_FEATURE_CRC)) {
9331 tmp2 = load_reg(s, rm);
9332 tmp3 = tcg_const_i32(1 << sz);
9334 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9336 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9338 tcg_temp_free_i32(tmp2);
9339 tcg_temp_free_i32(tmp3);
9346 store_reg(s, rd, tmp);
9348 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9349 op = (insn >> 4) & 0xf;
9350 tmp = load_reg(s, rn);
9351 tmp2 = load_reg(s, rm);
9352 switch ((insn >> 20) & 7) {
9353 case 0: /* 32 x 32 -> 32 */
9354 tcg_gen_mul_i32(tmp, tmp, tmp2);
9355 tcg_temp_free_i32(tmp2);
9357 tmp2 = load_reg(s, rs);
9359 tcg_gen_sub_i32(tmp, tmp2, tmp);
9361 tcg_gen_add_i32(tmp, tmp, tmp2);
9362 tcg_temp_free_i32(tmp2);
9365 case 1: /* 16 x 16 -> 32 */
9366 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9367 tcg_temp_free_i32(tmp2);
9369 tmp2 = load_reg(s, rs);
9370 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9371 tcg_temp_free_i32(tmp2);
9374 case 2: /* Dual multiply add. */
9375 case 4: /* Dual multiply subtract. */
9377 gen_swap_half(tmp2);
9378 gen_smul_dual(tmp, tmp2);
9379 if (insn & (1 << 22)) {
9380 /* This subtraction cannot overflow. */
9381 tcg_gen_sub_i32(tmp, tmp, tmp2);
9383 /* This addition cannot overflow 32 bits;
9384 * however it may overflow considered as a signed
9385 * operation, in which case we must set the Q flag.
9387 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9389 tcg_temp_free_i32(tmp2);
9392 tmp2 = load_reg(s, rs);
9393 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9394 tcg_temp_free_i32(tmp2);
9397 case 3: /* 32 * 16 -> 32msb */
9399 tcg_gen_sari_i32(tmp2, tmp2, 16);
9402 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9403 tcg_gen_shri_i64(tmp64, tmp64, 16);
9404 tmp = tcg_temp_new_i32();
9405 tcg_gen_trunc_i64_i32(tmp, tmp64);
9406 tcg_temp_free_i64(tmp64);
9409 tmp2 = load_reg(s, rs);
9410 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9411 tcg_temp_free_i32(tmp2);
9414 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9415 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9417 tmp = load_reg(s, rs);
9418 if (insn & (1 << 20)) {
9419 tmp64 = gen_addq_msw(tmp64, tmp);
9421 tmp64 = gen_subq_msw(tmp64, tmp);
9424 if (insn & (1 << 4)) {
9425 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9427 tcg_gen_shri_i64(tmp64, tmp64, 32);
9428 tmp = tcg_temp_new_i32();
9429 tcg_gen_trunc_i64_i32(tmp, tmp64);
9430 tcg_temp_free_i64(tmp64);
9432 case 7: /* Unsigned sum of absolute differences. */
9433 gen_helper_usad8(tmp, tmp, tmp2);
9434 tcg_temp_free_i32(tmp2);
9436 tmp2 = load_reg(s, rs);
9437 tcg_gen_add_i32(tmp, tmp, tmp2);
9438 tcg_temp_free_i32(tmp2);
9442 store_reg(s, rd, tmp);
9444 case 6: case 7: /* 64-bit multiply, Divide. */
9445 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9446 tmp = load_reg(s, rn);
9447 tmp2 = load_reg(s, rm);
9448 if ((op & 0x50) == 0x10) {
9450 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
9454 gen_helper_udiv(tmp, tmp, tmp2);
9456 gen_helper_sdiv(tmp, tmp, tmp2);
9457 tcg_temp_free_i32(tmp2);
9458 store_reg(s, rd, tmp);
9459 } else if ((op & 0xe) == 0xc) {
9460 /* Dual multiply accumulate long. */
9462 gen_swap_half(tmp2);
9463 gen_smul_dual(tmp, tmp2);
9465 tcg_gen_sub_i32(tmp, tmp, tmp2);
9467 tcg_gen_add_i32(tmp, tmp, tmp2);
9469 tcg_temp_free_i32(tmp2);
9471 tmp64 = tcg_temp_new_i64();
9472 tcg_gen_ext_i32_i64(tmp64, tmp);
9473 tcg_temp_free_i32(tmp);
9474 gen_addq(s, tmp64, rs, rd);
9475 gen_storeq_reg(s, rs, rd, tmp64);
9476 tcg_temp_free_i64(tmp64);
9479 /* Unsigned 64-bit multiply */
9480 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9484 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9485 tcg_temp_free_i32(tmp2);
9486 tmp64 = tcg_temp_new_i64();
9487 tcg_gen_ext_i32_i64(tmp64, tmp);
9488 tcg_temp_free_i32(tmp);
9490 /* Signed 64-bit multiply */
9491 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9496 gen_addq_lo(s, tmp64, rs);
9497 gen_addq_lo(s, tmp64, rd);
9498 } else if (op & 0x40) {
9499 /* 64-bit accumulate. */
9500 gen_addq(s, tmp64, rs, rd);
9502 gen_storeq_reg(s, rs, rd, tmp64);
9503 tcg_temp_free_i64(tmp64);
9508 case 6: case 7: case 14: case 15:
9510 if (((insn >> 24) & 3) == 3) {
9511 /* Translate into the equivalent ARM encoding. */
9512 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9513 if (disas_neon_data_insn(env, s, insn))
9515 } else if (((insn >> 8) & 0xe) == 10) {
9516 if (disas_vfp_insn(env, s, insn)) {
9520 if (insn & (1 << 28))
9522 if (disas_coproc_insn (env, s, insn))
9526 case 8: case 9: case 10: case 11:
9527 if (insn & (1 << 15)) {
9528 /* Branches, misc control. */
9529 if (insn & 0x5000) {
9530 /* Unconditional branch. */
9531 /* signextend(hw1[10:0]) -> offset[:12]. */
9532 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9533 /* hw1[10:0] -> offset[11:1]. */
9534 offset |= (insn & 0x7ff) << 1;
9535 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9536 offset[24:22] already have the same value because of the
9537 sign extension above. */
9538 offset ^= ((~insn) & (1 << 13)) << 10;
9539 offset ^= ((~insn) & (1 << 11)) << 11;
9541 if (insn & (1 << 14)) {
9542 /* Branch and link. */
9543 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9547 if (insn & (1 << 12)) {
9552 offset &= ~(uint32_t)2;
9553 /* thumb2 bx, no need to check */
9554 gen_bx_im(s, offset);
9556 } else if (((insn >> 23) & 7) == 7) {
9558 if (insn & (1 << 13))
9561 if (insn & (1 << 26)) {
9562 /* Secure monitor call (v6Z) */
9563 qemu_log_mask(LOG_UNIMP,
9564 "arm: unimplemented secure monitor call\n");
9565 goto illegal_op; /* not implemented. */
9567 op = (insn >> 20) & 7;
9569 case 0: /* msr cpsr. */
9571 tmp = load_reg(s, rn);
9572 addr = tcg_const_i32(insn & 0xff);
9573 gen_helper_v7m_msr(cpu_env, addr, tmp);
9574 tcg_temp_free_i32(addr);
9575 tcg_temp_free_i32(tmp);
9580 case 1: /* msr spsr. */
9583 tmp = load_reg(s, rn);
9585 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9589 case 2: /* cps, nop-hint. */
9590 if (((insn >> 8) & 7) == 0) {
9591 gen_nop_hint(s, insn & 0xff);
9593 /* Implemented as NOP in user mode. */
9598 if (insn & (1 << 10)) {
9599 if (insn & (1 << 7))
9601 if (insn & (1 << 6))
9603 if (insn & (1 << 5))
9605 if (insn & (1 << 9))
9606 imm = CPSR_A | CPSR_I | CPSR_F;
9608 if (insn & (1 << 8)) {
9610 imm |= (insn & 0x1f);
9613 gen_set_psr_im(s, offset, 0, imm);
9616 case 3: /* Special control operations. */
9618 op = (insn >> 4) & 0xf;
9626 /* These execute as NOPs. */
9633 /* Trivial implementation equivalent to bx. */
9634 tmp = load_reg(s, rn);
9637 case 5: /* Exception return. */
9641 if (rn != 14 || rd != 15) {
9644 tmp = load_reg(s, rn);
9645 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9646 gen_exception_return(s, tmp);
9648 case 6: /* mrs cpsr. */
9649 tmp = tcg_temp_new_i32();
9651 addr = tcg_const_i32(insn & 0xff);
9652 gen_helper_v7m_mrs(tmp, cpu_env, addr);
9653 tcg_temp_free_i32(addr);
9655 gen_helper_cpsr_read(tmp, cpu_env);
9657 store_reg(s, rd, tmp);
9659 case 7: /* mrs spsr. */
9660 /* Not accessible in user mode. */
9661 if (IS_USER(s) || IS_M(env))
9663 tmp = load_cpu_field(spsr);
9664 store_reg(s, rd, tmp);
9669 /* Conditional branch. */
9670 op = (insn >> 22) & 0xf;
9671 /* Generate a conditional jump to next instruction. */
9672 s->condlabel = gen_new_label();
9673 arm_gen_test_cc(op ^ 1, s->condlabel);
9676 /* offset[11:1] = insn[10:0] */
9677 offset = (insn & 0x7ff) << 1;
9678 /* offset[17:12] = insn[21:16]. */
9679 offset |= (insn & 0x003f0000) >> 4;
9680 /* offset[31:20] = insn[26]. */
9681 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9682 /* offset[18] = insn[13]. */
9683 offset |= (insn & (1 << 13)) << 5;
9684 /* offset[19] = insn[11]. */
9685 offset |= (insn & (1 << 11)) << 8;
9687 /* jump to the offset */
9688 gen_jmp(s, s->pc + offset);
9691 /* Data processing immediate. */
9692 if (insn & (1 << 25)) {
9693 if (insn & (1 << 24)) {
9694 if (insn & (1 << 20))
9696 /* Bitfield/Saturate. */
9697 op = (insn >> 21) & 7;
9699 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9701 tmp = tcg_temp_new_i32();
9702 tcg_gen_movi_i32(tmp, 0);
9704 tmp = load_reg(s, rn);
9707 case 2: /* Signed bitfield extract. */
9709 if (shift + imm > 32)
9712 gen_sbfx(tmp, shift, imm);
9714 case 6: /* Unsigned bitfield extract. */
9716 if (shift + imm > 32)
9719 gen_ubfx(tmp, shift, (1u << imm) - 1);
9721 case 3: /* Bitfield insert/clear. */
9724 imm = imm + 1 - shift;
9726 tmp2 = load_reg(s, rd);
9727 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9728 tcg_temp_free_i32(tmp2);
9733 default: /* Saturate. */
9736 tcg_gen_sari_i32(tmp, tmp, shift);
9738 tcg_gen_shli_i32(tmp, tmp, shift);
9740 tmp2 = tcg_const_i32(imm);
9743 if ((op & 1) && shift == 0)
9744 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9746 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9749 if ((op & 1) && shift == 0)
9750 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9752 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9754 tcg_temp_free_i32(tmp2);
9757 store_reg(s, rd, tmp);
9759 imm = ((insn & 0x04000000) >> 15)
9760 | ((insn & 0x7000) >> 4) | (insn & 0xff);
9761 if (insn & (1 << 22)) {
9762 /* 16-bit immediate. */
9763 imm |= (insn >> 4) & 0xf000;
9764 if (insn & (1 << 23)) {
9766 tmp = load_reg(s, rd);
9767 tcg_gen_ext16u_i32(tmp, tmp);
9768 tcg_gen_ori_i32(tmp, tmp, imm << 16);
9771 tmp = tcg_temp_new_i32();
9772 tcg_gen_movi_i32(tmp, imm);
9775 /* Add/sub 12-bit immediate. */
9777 offset = s->pc & ~(uint32_t)3;
9778 if (insn & (1 << 23))
9782 tmp = tcg_temp_new_i32();
9783 tcg_gen_movi_i32(tmp, offset);
9785 tmp = load_reg(s, rn);
9786 if (insn & (1 << 23))
9787 tcg_gen_subi_i32(tmp, tmp, imm);
9789 tcg_gen_addi_i32(tmp, tmp, imm);
9792 store_reg(s, rd, tmp);
9795 int shifter_out = 0;
9796 /* modified 12-bit immediate. */
9797 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9798 imm = (insn & 0xff);
9801 /* Nothing to do. */
9803 case 1: /* 00XY00XY */
9806 case 2: /* XY00XY00 */
9810 case 3: /* XYXYXYXY */
9814 default: /* Rotated constant. */
9815 shift = (shift << 1) | (imm >> 7);
9817 imm = imm << (32 - shift);
9821 tmp2 = tcg_temp_new_i32();
9822 tcg_gen_movi_i32(tmp2, imm);
9823 rn = (insn >> 16) & 0xf;
9825 tmp = tcg_temp_new_i32();
9826 tcg_gen_movi_i32(tmp, 0);
9828 tmp = load_reg(s, rn);
9830 op = (insn >> 21) & 0xf;
9831 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9832 shifter_out, tmp, tmp2))
9834 tcg_temp_free_i32(tmp2);
9835 rd = (insn >> 8) & 0xf;
9837 store_reg(s, rd, tmp);
9839 tcg_temp_free_i32(tmp);
9844 case 12: /* Load/store single data item. */
9849 if ((insn & 0x01100000) == 0x01000000) {
9850 if (disas_neon_ls_insn(env, s, insn))
9854 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9856 if (!(insn & (1 << 20))) {
9860 /* Byte or halfword load space with dest == r15 : memory hints.
9861 * Catch them early so we don't emit pointless addressing code.
9862 * This space is a mix of:
9863 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9864 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9866 * unallocated hints, which must be treated as NOPs
9867 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9868 * which is easiest for the decoding logic
9869 * Some space which must UNDEF
9871 int op1 = (insn >> 23) & 3;
9872 int op2 = (insn >> 6) & 0x3f;
9877 /* UNPREDICTABLE, unallocated hint or
9878 * PLD/PLDW/PLI (literal)
9883 return 0; /* PLD/PLDW/PLI or unallocated hint */
9885 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9886 return 0; /* PLD/PLDW/PLI or unallocated hint */
9888 /* UNDEF space, or an UNPREDICTABLE */
9892 memidx = get_mem_index(s);
9894 addr = tcg_temp_new_i32();
9896 /* s->pc has already been incremented by 4. */
9897 imm = s->pc & 0xfffffffc;
9898 if (insn & (1 << 23))
9899 imm += insn & 0xfff;
9901 imm -= insn & 0xfff;
9902 tcg_gen_movi_i32(addr, imm);
9904 addr = load_reg(s, rn);
9905 if (insn & (1 << 23)) {
9906 /* Positive offset. */
9908 tcg_gen_addi_i32(addr, addr, imm);
9911 switch ((insn >> 8) & 0xf) {
9912 case 0x0: /* Shifted Register. */
9913 shift = (insn >> 4) & 0xf;
9915 tcg_temp_free_i32(addr);
9918 tmp = load_reg(s, rm);
9920 tcg_gen_shli_i32(tmp, tmp, shift);
9921 tcg_gen_add_i32(addr, addr, tmp);
9922 tcg_temp_free_i32(tmp);
9924 case 0xc: /* Negative offset. */
9925 tcg_gen_addi_i32(addr, addr, -imm);
9927 case 0xe: /* User privilege. */
9928 tcg_gen_addi_i32(addr, addr, imm);
9929 memidx = MMU_USER_IDX;
9931 case 0x9: /* Post-decrement. */
9934 case 0xb: /* Post-increment. */
9938 case 0xd: /* Pre-decrement. */
9941 case 0xf: /* Pre-increment. */
9942 tcg_gen_addi_i32(addr, addr, imm);
9946 tcg_temp_free_i32(addr);
9951 if (insn & (1 << 20)) {
9953 tmp = tcg_temp_new_i32();
9956 gen_aa32_ld8u(tmp, addr, memidx);
9959 gen_aa32_ld8s(tmp, addr, memidx);
9962 gen_aa32_ld16u(tmp, addr, memidx);
9965 gen_aa32_ld16s(tmp, addr, memidx);
9968 gen_aa32_ld32u(tmp, addr, memidx);
9971 tcg_temp_free_i32(tmp);
9972 tcg_temp_free_i32(addr);
9978 store_reg(s, rs, tmp);
9982 tmp = load_reg(s, rs);
9985 gen_aa32_st8(tmp, addr, memidx);
9988 gen_aa32_st16(tmp, addr, memidx);
9991 gen_aa32_st32(tmp, addr, memidx);
9994 tcg_temp_free_i32(tmp);
9995 tcg_temp_free_i32(addr);
9998 tcg_temp_free_i32(tmp);
10001 tcg_gen_addi_i32(addr, addr, imm);
10003 store_reg(s, rn, addr);
10005 tcg_temp_free_i32(addr);
10017 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
10019 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10026 if (s->condexec_mask) {
10027 cond = s->condexec_cond;
10028 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10029 s->condlabel = gen_new_label();
10030 arm_gen_test_cc(cond ^ 1, s->condlabel);
10035 insn = arm_lduw_code(env, s->pc, s->bswap_code);
10038 switch (insn >> 12) {
10042 op = (insn >> 11) & 3;
10045 rn = (insn >> 3) & 7;
10046 tmp = load_reg(s, rn);
10047 if (insn & (1 << 10)) {
10049 tmp2 = tcg_temp_new_i32();
10050 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10053 rm = (insn >> 6) & 7;
10054 tmp2 = load_reg(s, rm);
10056 if (insn & (1 << 9)) {
10057 if (s->condexec_mask)
10058 tcg_gen_sub_i32(tmp, tmp, tmp2);
10060 gen_sub_CC(tmp, tmp, tmp2);
10062 if (s->condexec_mask)
10063 tcg_gen_add_i32(tmp, tmp, tmp2);
10065 gen_add_CC(tmp, tmp, tmp2);
10067 tcg_temp_free_i32(tmp2);
10068 store_reg(s, rd, tmp);
10070 /* shift immediate */
10071 rm = (insn >> 3) & 7;
10072 shift = (insn >> 6) & 0x1f;
10073 tmp = load_reg(s, rm);
10074 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10075 if (!s->condexec_mask)
10077 store_reg(s, rd, tmp);
10081 /* arithmetic large immediate */
10082 op = (insn >> 11) & 3;
10083 rd = (insn >> 8) & 0x7;
10084 if (op == 0) { /* mov */
10085 tmp = tcg_temp_new_i32();
10086 tcg_gen_movi_i32(tmp, insn & 0xff);
10087 if (!s->condexec_mask)
10089 store_reg(s, rd, tmp);
10091 tmp = load_reg(s, rd);
10092 tmp2 = tcg_temp_new_i32();
10093 tcg_gen_movi_i32(tmp2, insn & 0xff);
10096 gen_sub_CC(tmp, tmp, tmp2);
10097 tcg_temp_free_i32(tmp);
10098 tcg_temp_free_i32(tmp2);
10101 if (s->condexec_mask)
10102 tcg_gen_add_i32(tmp, tmp, tmp2);
10104 gen_add_CC(tmp, tmp, tmp2);
10105 tcg_temp_free_i32(tmp2);
10106 store_reg(s, rd, tmp);
10109 if (s->condexec_mask)
10110 tcg_gen_sub_i32(tmp, tmp, tmp2);
10112 gen_sub_CC(tmp, tmp, tmp2);
10113 tcg_temp_free_i32(tmp2);
10114 store_reg(s, rd, tmp);
10120 if (insn & (1 << 11)) {
10121 rd = (insn >> 8) & 7;
10122 /* load pc-relative. Bit 1 of PC is ignored. */
10123 val = s->pc + 2 + ((insn & 0xff) * 4);
10124 val &= ~(uint32_t)2;
10125 addr = tcg_temp_new_i32();
10126 tcg_gen_movi_i32(addr, val);
10127 tmp = tcg_temp_new_i32();
10128 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10129 tcg_temp_free_i32(addr);
10130 store_reg(s, rd, tmp);
10133 if (insn & (1 << 10)) {
10134 /* data processing extended or blx */
10135 rd = (insn & 7) | ((insn >> 4) & 8);
10136 rm = (insn >> 3) & 0xf;
10137 op = (insn >> 8) & 3;
10140 tmp = load_reg(s, rd);
10141 tmp2 = load_reg(s, rm);
10142 tcg_gen_add_i32(tmp, tmp, tmp2);
10143 tcg_temp_free_i32(tmp2);
10144 store_reg(s, rd, tmp);
10147 tmp = load_reg(s, rd);
10148 tmp2 = load_reg(s, rm);
10149 gen_sub_CC(tmp, tmp, tmp2);
10150 tcg_temp_free_i32(tmp2);
10151 tcg_temp_free_i32(tmp);
10153 case 2: /* mov/cpy */
10154 tmp = load_reg(s, rm);
10155 store_reg(s, rd, tmp);
10157 case 3:/* branch [and link] exchange thumb register */
10158 tmp = load_reg(s, rm);
10159 if (insn & (1 << 7)) {
10161 val = (uint32_t)s->pc | 1;
10162 tmp2 = tcg_temp_new_i32();
10163 tcg_gen_movi_i32(tmp2, val);
10164 store_reg(s, 14, tmp2);
10166 /* already thumb, no need to check */
10173 /* data processing register */
10175 rm = (insn >> 3) & 7;
10176 op = (insn >> 6) & 0xf;
10177 if (op == 2 || op == 3 || op == 4 || op == 7) {
10178 /* the shift/rotate ops want the operands backwards */
10187 if (op == 9) { /* neg */
10188 tmp = tcg_temp_new_i32();
10189 tcg_gen_movi_i32(tmp, 0);
10190 } else if (op != 0xf) { /* mvn doesn't read its first operand */
10191 tmp = load_reg(s, rd);
10193 TCGV_UNUSED_I32(tmp);
10196 tmp2 = load_reg(s, rm);
10198 case 0x0: /* and */
10199 tcg_gen_and_i32(tmp, tmp, tmp2);
10200 if (!s->condexec_mask)
10203 case 0x1: /* eor */
10204 tcg_gen_xor_i32(tmp, tmp, tmp2);
10205 if (!s->condexec_mask)
10208 case 0x2: /* lsl */
10209 if (s->condexec_mask) {
10210 gen_shl(tmp2, tmp2, tmp);
10212 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
10213 gen_logic_CC(tmp2);
10216 case 0x3: /* lsr */
10217 if (s->condexec_mask) {
10218 gen_shr(tmp2, tmp2, tmp);
10220 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
10221 gen_logic_CC(tmp2);
10224 case 0x4: /* asr */
10225 if (s->condexec_mask) {
10226 gen_sar(tmp2, tmp2, tmp);
10228 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
10229 gen_logic_CC(tmp2);
10232 case 0x5: /* adc */
10233 if (s->condexec_mask) {
10234 gen_adc(tmp, tmp2);
10236 gen_adc_CC(tmp, tmp, tmp2);
10239 case 0x6: /* sbc */
10240 if (s->condexec_mask) {
10241 gen_sub_carry(tmp, tmp, tmp2);
10243 gen_sbc_CC(tmp, tmp, tmp2);
10246 case 0x7: /* ror */
10247 if (s->condexec_mask) {
10248 tcg_gen_andi_i32(tmp, tmp, 0x1f);
10249 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
10251 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
10252 gen_logic_CC(tmp2);
10255 case 0x8: /* tst */
10256 tcg_gen_and_i32(tmp, tmp, tmp2);
10260 case 0x9: /* neg */
10261 if (s->condexec_mask)
10262 tcg_gen_neg_i32(tmp, tmp2);
10264 gen_sub_CC(tmp, tmp, tmp2);
10266 case 0xa: /* cmp */
10267 gen_sub_CC(tmp, tmp, tmp2);
10270 case 0xb: /* cmn */
10271 gen_add_CC(tmp, tmp, tmp2);
10274 case 0xc: /* orr */
10275 tcg_gen_or_i32(tmp, tmp, tmp2);
10276 if (!s->condexec_mask)
10279 case 0xd: /* mul */
10280 tcg_gen_mul_i32(tmp, tmp, tmp2);
10281 if (!s->condexec_mask)
10284 case 0xe: /* bic */
10285 tcg_gen_andc_i32(tmp, tmp, tmp2);
10286 if (!s->condexec_mask)
10289 case 0xf: /* mvn */
10290 tcg_gen_not_i32(tmp2, tmp2);
10291 if (!s->condexec_mask)
10292 gen_logic_CC(tmp2);
10299 store_reg(s, rm, tmp2);
10301 tcg_temp_free_i32(tmp);
10303 store_reg(s, rd, tmp);
10304 tcg_temp_free_i32(tmp2);
10307 tcg_temp_free_i32(tmp);
10308 tcg_temp_free_i32(tmp2);
10313 /* load/store register offset. */
10315 rn = (insn >> 3) & 7;
10316 rm = (insn >> 6) & 7;
10317 op = (insn >> 9) & 7;
10318 addr = load_reg(s, rn);
10319 tmp = load_reg(s, rm);
10320 tcg_gen_add_i32(addr, addr, tmp);
10321 tcg_temp_free_i32(tmp);
10323 if (op < 3) { /* store */
10324 tmp = load_reg(s, rd);
10326 tmp = tcg_temp_new_i32();
10331 gen_aa32_st32(tmp, addr, get_mem_index(s));
10334 gen_aa32_st16(tmp, addr, get_mem_index(s));
10337 gen_aa32_st8(tmp, addr, get_mem_index(s));
10339 case 3: /* ldrsb */
10340 gen_aa32_ld8s(tmp, addr, get_mem_index(s));
10343 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10346 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
10349 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
10351 case 7: /* ldrsh */
10352 gen_aa32_ld16s(tmp, addr, get_mem_index(s));
10355 if (op >= 3) { /* load */
10356 store_reg(s, rd, tmp);
10358 tcg_temp_free_i32(tmp);
10360 tcg_temp_free_i32(addr);
10364 /* load/store word immediate offset */
10366 rn = (insn >> 3) & 7;
10367 addr = load_reg(s, rn);
10368 val = (insn >> 4) & 0x7c;
10369 tcg_gen_addi_i32(addr, addr, val);
10371 if (insn & (1 << 11)) {
10373 tmp = tcg_temp_new_i32();
10374 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10375 store_reg(s, rd, tmp);
10378 tmp = load_reg(s, rd);
10379 gen_aa32_st32(tmp, addr, get_mem_index(s));
10380 tcg_temp_free_i32(tmp);
10382 tcg_temp_free_i32(addr);
10386 /* load/store byte immediate offset */
10388 rn = (insn >> 3) & 7;
10389 addr = load_reg(s, rn);
10390 val = (insn >> 6) & 0x1f;
10391 tcg_gen_addi_i32(addr, addr, val);
10393 if (insn & (1 << 11)) {
10395 tmp = tcg_temp_new_i32();
10396 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
10397 store_reg(s, rd, tmp);
10400 tmp = load_reg(s, rd);
10401 gen_aa32_st8(tmp, addr, get_mem_index(s));
10402 tcg_temp_free_i32(tmp);
10404 tcg_temp_free_i32(addr);
10408 /* load/store halfword immediate offset */
10410 rn = (insn >> 3) & 7;
10411 addr = load_reg(s, rn);
10412 val = (insn >> 5) & 0x3e;
10413 tcg_gen_addi_i32(addr, addr, val);
10415 if (insn & (1 << 11)) {
10417 tmp = tcg_temp_new_i32();
10418 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
10419 store_reg(s, rd, tmp);
10422 tmp = load_reg(s, rd);
10423 gen_aa32_st16(tmp, addr, get_mem_index(s));
10424 tcg_temp_free_i32(tmp);
10426 tcg_temp_free_i32(addr);
10430 /* load/store from stack */
10431 rd = (insn >> 8) & 7;
10432 addr = load_reg(s, 13);
10433 val = (insn & 0xff) * 4;
10434 tcg_gen_addi_i32(addr, addr, val);
10436 if (insn & (1 << 11)) {
10438 tmp = tcg_temp_new_i32();
10439 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10440 store_reg(s, rd, tmp);
10443 tmp = load_reg(s, rd);
10444 gen_aa32_st32(tmp, addr, get_mem_index(s));
10445 tcg_temp_free_i32(tmp);
10447 tcg_temp_free_i32(addr);
10451 /* add to high reg */
10452 rd = (insn >> 8) & 7;
10453 if (insn & (1 << 11)) {
10455 tmp = load_reg(s, 13);
10457 /* PC. bit 1 is ignored. */
10458 tmp = tcg_temp_new_i32();
10459 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10461 val = (insn & 0xff) * 4;
10462 tcg_gen_addi_i32(tmp, tmp, val);
10463 store_reg(s, rd, tmp);
10468 op = (insn >> 8) & 0xf;
10471 /* adjust stack pointer */
10472 tmp = load_reg(s, 13);
10473 val = (insn & 0x7f) * 4;
10474 if (insn & (1 << 7))
10475 val = -(int32_t)val;
10476 tcg_gen_addi_i32(tmp, tmp, val);
10477 store_reg(s, 13, tmp);
10480 case 2: /* sign/zero extend. */
10483 rm = (insn >> 3) & 7;
10484 tmp = load_reg(s, rm);
10485 switch ((insn >> 6) & 3) {
10486 case 0: gen_sxth(tmp); break;
10487 case 1: gen_sxtb(tmp); break;
10488 case 2: gen_uxth(tmp); break;
10489 case 3: gen_uxtb(tmp); break;
10491 store_reg(s, rd, tmp);
10493 case 4: case 5: case 0xc: case 0xd:
10495 addr = load_reg(s, 13);
10496 if (insn & (1 << 8))
10500 for (i = 0; i < 8; i++) {
10501 if (insn & (1 << i))
10504 if ((insn & (1 << 11)) == 0) {
10505 tcg_gen_addi_i32(addr, addr, -offset);
10507 for (i = 0; i < 8; i++) {
10508 if (insn & (1 << i)) {
10509 if (insn & (1 << 11)) {
10511 tmp = tcg_temp_new_i32();
10512 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10513 store_reg(s, i, tmp);
10516 tmp = load_reg(s, i);
10517 gen_aa32_st32(tmp, addr, get_mem_index(s));
10518 tcg_temp_free_i32(tmp);
10520 /* advance to the next address. */
10521 tcg_gen_addi_i32(addr, addr, 4);
10524 TCGV_UNUSED_I32(tmp);
10525 if (insn & (1 << 8)) {
10526 if (insn & (1 << 11)) {
10528 tmp = tcg_temp_new_i32();
10529 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10530 /* don't set the pc until the rest of the instruction
10534 tmp = load_reg(s, 14);
10535 gen_aa32_st32(tmp, addr, get_mem_index(s));
10536 tcg_temp_free_i32(tmp);
10538 tcg_gen_addi_i32(addr, addr, 4);
10540 if ((insn & (1 << 11)) == 0) {
10541 tcg_gen_addi_i32(addr, addr, -offset);
10543 /* write back the new stack pointer */
10544 store_reg(s, 13, addr);
10545 /* set the new PC value */
10546 if ((insn & 0x0900) == 0x0900) {
10547 store_reg_from_load(env, s, 15, tmp);
10551 case 1: case 3: case 9: case 11: /* czb */
10553 tmp = load_reg(s, rm);
10554 s->condlabel = gen_new_label();
10556 if (insn & (1 << 11))
10557 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10559 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10560 tcg_temp_free_i32(tmp);
10561 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10562 val = (uint32_t)s->pc + 2;
10567 case 15: /* IT, nop-hint. */
10568 if ((insn & 0xf) == 0) {
10569 gen_nop_hint(s, (insn >> 4) & 0xf);
10573 s->condexec_cond = (insn >> 4) & 0xe;
10574 s->condexec_mask = insn & 0x1f;
10575 /* No actual code generated for this insn, just setup state. */
10578 case 0xe: /* bkpt */
10580 int imm8 = extract32(insn, 0, 8);
10582 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true));
10586 case 0xa: /* rev */
10588 rn = (insn >> 3) & 0x7;
10590 tmp = load_reg(s, rn);
10591 switch ((insn >> 6) & 3) {
10592 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10593 case 1: gen_rev16(tmp); break;
10594 case 3: gen_revsh(tmp); break;
10595 default: goto illegal_op;
10597 store_reg(s, rd, tmp);
10601 switch ((insn >> 5) & 7) {
10605 if (((insn >> 3) & 1) != s->bswap_code) {
10606 /* Dynamic endianness switching not implemented. */
10607 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10618 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10621 addr = tcg_const_i32(19);
10622 gen_helper_v7m_msr(cpu_env, addr, tmp);
10623 tcg_temp_free_i32(addr);
10627 addr = tcg_const_i32(16);
10628 gen_helper_v7m_msr(cpu_env, addr, tmp);
10629 tcg_temp_free_i32(addr);
10631 tcg_temp_free_i32(tmp);
10634 if (insn & (1 << 4)) {
10635 shift = CPSR_A | CPSR_I | CPSR_F;
10639 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10654 /* load/store multiple */
10655 TCGv_i32 loaded_var;
10656 TCGV_UNUSED_I32(loaded_var);
10657 rn = (insn >> 8) & 0x7;
10658 addr = load_reg(s, rn);
10659 for (i = 0; i < 8; i++) {
10660 if (insn & (1 << i)) {
10661 if (insn & (1 << 11)) {
10663 tmp = tcg_temp_new_i32();
10664 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10668 store_reg(s, i, tmp);
10672 tmp = load_reg(s, i);
10673 gen_aa32_st32(tmp, addr, get_mem_index(s));
10674 tcg_temp_free_i32(tmp);
10676 /* advance to the next address */
10677 tcg_gen_addi_i32(addr, addr, 4);
10680 if ((insn & (1 << rn)) == 0) {
10681 /* base reg not in list: base register writeback */
10682 store_reg(s, rn, addr);
10684 /* base reg in list: if load, complete it now */
10685 if (insn & (1 << 11)) {
10686 store_reg(s, rn, loaded_var);
10688 tcg_temp_free_i32(addr);
10693 /* conditional branch or swi */
10694 cond = (insn >> 8) & 0xf;
10700 gen_set_pc_im(s, s->pc);
10701 s->svc_imm = extract32(insn, 0, 8);
10702 s->is_jmp = DISAS_SWI;
10705 /* generate a conditional jump to next instruction */
10706 s->condlabel = gen_new_label();
10707 arm_gen_test_cc(cond ^ 1, s->condlabel);
10710 /* jump to the offset */
10711 val = (uint32_t)s->pc + 2;
10712 offset = ((int32_t)insn << 24) >> 24;
10713 val += offset << 1;
10718 if (insn & (1 << 11)) {
10719 if (disas_thumb2_insn(env, s, insn))
10723 /* unconditional branch */
10724 val = (uint32_t)s->pc;
10725 offset = ((int32_t)insn << 21) >> 21;
10726 val += (offset << 1) + 2;
10731 if (disas_thumb2_insn(env, s, insn))
10737 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
10741 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized());
10744 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10745 basic block 'tb'. If search_pc is TRUE, also generate PC
10746 information for each intermediate instruction. */
10747 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10748 TranslationBlock *tb,
10751 CPUState *cs = CPU(cpu);
10752 CPUARMState *env = &cpu->env;
10753 DisasContext dc1, *dc = &dc1;
10755 uint16_t *gen_opc_end;
10757 target_ulong pc_start;
10758 target_ulong next_page_start;
10762 /* generate intermediate code */
10764 /* The A64 decoder has its own top level loop, because it doesn't need
10765 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10767 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10768 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10776 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10778 dc->is_jmp = DISAS_NEXT;
10780 dc->singlestep_enabled = cs->singlestep_enabled;
10784 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10785 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10786 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10787 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10788 #if !defined(CONFIG_USER_ONLY)
10789 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10791 dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
10792 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10793 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10794 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10795 dc->cp_regs = cpu->cp_regs;
10796 dc->current_pl = arm_current_pl(env);
10797 dc->features = env->features;
10799 cpu_F0s = tcg_temp_new_i32();
10800 cpu_F1s = tcg_temp_new_i32();
10801 cpu_F0d = tcg_temp_new_i64();
10802 cpu_F1d = tcg_temp_new_i64();
10805 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10806 cpu_M0 = tcg_temp_new_i64();
10807 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10810 max_insns = tb->cflags & CF_COUNT_MASK;
10811 if (max_insns == 0)
10812 max_insns = CF_COUNT_MASK;
10816 tcg_clear_temp_count();
10818 /* A note on handling of the condexec (IT) bits:
10820 * We want to avoid the overhead of having to write the updated condexec
10821 * bits back to the CPUARMState for every instruction in an IT block. So:
10822 * (1) if the condexec bits are not already zero then we write
10823 * zero back into the CPUARMState now. This avoids complications trying
10824 * to do it at the end of the block. (For example if we don't do this
10825 * it's hard to identify whether we can safely skip writing condexec
10826 * at the end of the TB, which we definitely want to do for the case
10827 * where a TB doesn't do anything with the IT state at all.)
10828 * (2) if we are going to leave the TB then we call gen_set_condexec()
10829 * which will write the correct value into CPUARMState if zero is wrong.
10830 * This is done both for leaving the TB at the end, and for leaving
10831 * it because of an exception we know will happen, which is done in
10832 * gen_exception_insn(). The latter is necessary because we need to
10833 * leave the TB with the PC/IT state just prior to execution of the
10834 * instruction which caused the exception.
10835 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10836 * then the CPUARMState will be wrong and we need to reset it.
10837 * This is handled in the same way as restoration of the
10838 * PC in these situations: we will be called again with search_pc=1
10839 * and generate a mapping of the condexec bits for each PC in
10840 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10841 * this to restore the condexec bits.
10843 * Note that there are no instructions which can read the condexec
10844 * bits, and none which can write non-static values to them, so
10845 * we don't need to care about whether CPUARMState is correct in the
10849 /* Reset the conditional execution bits immediately. This avoids
10850 complications trying to do it at the end of the block. */
10851 if (dc->condexec_mask || dc->condexec_cond)
10853 TCGv_i32 tmp = tcg_temp_new_i32();
10854 tcg_gen_movi_i32(tmp, 0);
10855 store_cpu_field(tmp, condexec_bits);
10858 #ifdef CONFIG_USER_ONLY
10859 /* Intercept jump to the magic kernel page. */
10860 if (dc->pc >= 0xffff0000) {
10861 /* We always get here via a jump, so know we are not in a
10862 conditional execution block. */
10863 gen_exception_internal(EXCP_KERNEL_TRAP);
10864 dc->is_jmp = DISAS_UPDATE;
10868 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10869 /* We always get here via a jump, so know we are not in a
10870 conditional execution block. */
10871 gen_exception_internal(EXCP_EXCEPTION_EXIT);
10872 dc->is_jmp = DISAS_UPDATE;
10877 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
10878 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
10879 if (bp->pc == dc->pc) {
10880 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
10881 /* Advance PC so that clearing the breakpoint will
10882 invalidate this TB. */
10884 goto done_generating;
10889 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10893 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10895 tcg_ctx.gen_opc_pc[lj] = dc->pc;
10896 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10897 tcg_ctx.gen_opc_instr_start[lj] = 1;
10898 tcg_ctx.gen_opc_icount[lj] = num_insns;
10901 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10904 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10905 tcg_gen_debug_insn_start(dc->pc);
10909 disas_thumb_insn(env, dc);
10910 if (dc->condexec_mask) {
10911 dc->condexec_cond = (dc->condexec_cond & 0xe)
10912 | ((dc->condexec_mask >> 4) & 1);
10913 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10914 if (dc->condexec_mask == 0) {
10915 dc->condexec_cond = 0;
10919 disas_arm_insn(env, dc);
10922 if (dc->condjmp && !dc->is_jmp) {
10923 gen_set_label(dc->condlabel);
10927 if (tcg_check_temp_count()) {
10928 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10932 /* Translation stops when a conditional branch is encountered.
10933 * Otherwise the subsequent code could get translated several times.
10934 * Also stop translation when a page boundary is reached. This
10935 * ensures prefetch aborts occur at the right place. */
10937 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10938 !cs->singlestep_enabled &&
10940 dc->pc < next_page_start &&
10941 num_insns < max_insns);
10943 if (tb->cflags & CF_LAST_IO) {
10945 /* FIXME: This can theoretically happen with self-modifying
10947 cpu_abort(cs, "IO on conditional branch instruction");
10952 /* At this stage dc->condjmp will only be set when the skipped
10953 instruction was a conditional branch or trap, and the PC has
10954 already been written. */
10955 if (unlikely(cs->singlestep_enabled)) {
10956 /* Make sure the pc is updated, and raise a debug exception. */
10958 gen_set_condexec(dc);
10959 if (dc->is_jmp == DISAS_SWI) {
10960 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
10962 gen_exception_internal(EXCP_DEBUG);
10964 gen_set_label(dc->condlabel);
10966 if (dc->condjmp || !dc->is_jmp) {
10967 gen_set_pc_im(dc, dc->pc);
10970 gen_set_condexec(dc);
10971 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10972 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
10974 /* FIXME: Single stepping a WFI insn will not halt
10976 gen_exception_internal(EXCP_DEBUG);
10979 /* While branches must always occur at the end of an IT block,
10980 there are a few other things that can cause us to terminate
10981 the TB in the middle of an IT block:
10982 - Exception generating instructions (bkpt, swi, undefined).
10984 - Hardware watchpoints.
10985 Hardware breakpoints have already been handled and skip this code.
10987 gen_set_condexec(dc);
10988 switch(dc->is_jmp) {
10990 gen_goto_tb(dc, 1, dc->pc);
10995 /* indicate that the hash table must be used to find the next TB */
10996 tcg_gen_exit_tb(0);
10998 case DISAS_TB_JUMP:
10999 /* nothing more to generate */
11002 gen_helper_wfi(cpu_env);
11005 gen_helper_wfe(cpu_env);
11008 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11012 gen_set_label(dc->condlabel);
11013 gen_set_condexec(dc);
11014 gen_goto_tb(dc, 1, dc->pc);
11020 gen_tb_end(tb, num_insns);
11021 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
11024 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
11025 qemu_log("----------------\n");
11026 qemu_log("IN: %s\n", lookup_symbol(pc_start));
11027 log_target_disas(env, pc_start, dc->pc - pc_start,
11028 dc->thumb | (dc->bswap_code << 1));
11033 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
11036 tcg_ctx.gen_opc_instr_start[lj++] = 0;
11038 tb->size = dc->pc - pc_start;
11039 tb->icount = num_insns;
11043 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11045 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
11048 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
11050 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
11053 static const char *cpu_mode_names[16] = {
11054 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11055 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11058 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11061 ARMCPU *cpu = ARM_CPU(cs);
11062 CPUARMState *env = &cpu->env;
11067 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
11071 for(i=0;i<16;i++) {
11072 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
11074 cpu_fprintf(f, "\n");
11076 cpu_fprintf(f, " ");
11078 psr = cpsr_read(env);
11079 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
11081 psr & (1 << 31) ? 'N' : '-',
11082 psr & (1 << 30) ? 'Z' : '-',
11083 psr & (1 << 29) ? 'C' : '-',
11084 psr & (1 << 28) ? 'V' : '-',
11085 psr & CPSR_T ? 'T' : 'A',
11086 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
11088 if (flags & CPU_DUMP_FPU) {
11089 int numvfpregs = 0;
11090 if (arm_feature(env, ARM_FEATURE_VFP)) {
11093 if (arm_feature(env, ARM_FEATURE_VFP3)) {
11096 for (i = 0; i < numvfpregs; i++) {
11097 uint64_t v = float64_val(env->vfp.regs[i]);
11098 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
11099 i * 2, (uint32_t)v,
11100 i * 2 + 1, (uint32_t)(v >> 32),
11103 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
11107 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
11110 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
11111 env->condexec_bits = 0;
11113 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
11114 env->condexec_bits = gen_opc_condexec_bits[pc_pos];